# HG changeset patch # User Paul Aurich # Date 1230924422 0 # Node ID ae544623840b045a6c4fb41d39be9ea3ef2aecac # Parent 6eecd6ba286260a43cc3f581a817eac5b6a63f17# Parent b26e8a41a9378e5a5631fed428768630fc20f15a propagate from branch 'im.pidgin.pidgin' (head f018e11a7ea08e07f22667e6daca2ec7e64f9710) to branch 'org.darkrain42.pidgin.buddy-add' (head e4fae922272cfd510a1f55595c374c2b9f665767) diff -r 6eecd6ba2862 -r ae544623840b AUTHORS --- a/AUTHORS Mon Dec 22 19:40:05 2008 +0000 +++ b/AUTHORS Fri Jan 02 19:27:02 2009 +0000 @@ -35,6 +35,7 @@ Crazy Patch Writers: ------------------- +Paul Aurich Felipe 'shx' Contreras Marcus 'malu' Lundblad Dennis 'EvilDennisR' Ristuccia diff -r 6eecd6ba2862 -r ae544623840b COPYRIGHT --- a/COPYRIGHT Mon Dec 22 19:40:05 2008 +0000 +++ b/COPYRIGHT Fri Jan 02 19:27:02 2009 +0000 @@ -63,6 +63,7 @@ Damien Carbery Michael Carlson Keegan Carruthers-Smith +Ludovico Cavedon Steve Cavilia Julien Cegarra Cerulean Studios, LLC @@ -228,6 +229,7 @@ Steve Láposi Daniel Larsson Peter Lawler +Vadim Lebedev Ho-seok Lee Jean-Yves Lefort Moses Lei diff -r 6eecd6ba2862 -r ae544623840b ChangeLog --- a/ChangeLog Mon Dec 22 19:40:05 2008 +0000 +++ b/ChangeLog Fri Jan 02 19:27:02 2009 +0000 @@ -6,6 +6,22 @@ Rosinski) * Don't ignore namespace information when parsing XMPP data. (Michal Witkowski) + * Fix a crash that occurred when retrieving certain Offline Messages + on MSN. + * Extended purple-url-handler to handle "gtalk" URI's. (Paul Aurich) + * Fix the hang on exit in Network Location Awareness for Windows XP + and Windows Vista. (Paul Aurich) + + XMPP: + * Support for XEP-0191 blocking. (Vijay Raghunathan) + * Don't put SASL PLAIN or IQ Auth passwords in debug logs. (Paul Aurich) + + Pidgin: + * Fix a crash in the Add Account dialog when changing protocols under + certain circumstances. + + Finch: + * Redirect stderr outputs to the debug window. version 2.5.3 (12/20/2008): libpurple: @@ -127,7 +143,7 @@ if no custom smilies have previously been added using the smiley manager. * Improved support for some message formatting in conversations. - * Allow focusing the coversation history or userlist with F6. + * Allow focusing the conversation history or userlist with F6. * Fixed the Send Button plugin to avoid duplicate buttons in a single conversation. * Double-clicking a saved status will now activate it and close the diff -r 6eecd6ba2862 -r ae544623840b doc/pidgin.1.in --- a/doc/pidgin.1.in Mon Dec 22 19:40:05 2008 +0000 +++ b/doc/pidgin.1.in Fri Jan 02 19:27:02 2009 +0000 @@ -641,6 +641,8 @@ Our crazy patch writers include: .br + Paul Aurich +.br Felipe 'shx' Contreras .br Marcus 'malu' Lundblad diff -r 6eecd6ba2862 -r ae544623840b finch/finch.c --- a/finch/finch.c Mon Dec 22 19:40:05 2008 +0000 +++ b/finch/finch.c Fri Jan 02 19:27:02 2009 +0000 @@ -229,7 +229,6 @@ gboolean opt_nologin = FALSE; gboolean opt_version = FALSE; char *opt_config_dir_arg = NULL; - char *opt_session_arg = NULL; gboolean debug_enabled = FALSE; struct option long_options[] = { @@ -237,7 +236,6 @@ {"debug", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {"nologin", no_argument, NULL, 'n'}, - {"session", required_argument, NULL, 's'}, {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0} }; @@ -256,7 +254,7 @@ opterr = 1; while ((opt = getopt_long(argc, argv, #ifndef _WIN32 - "c:dhn::s:v", + "c:dhn::v", #else "c:dhn::v", #endif @@ -275,10 +273,6 @@ case 'n': /* no autologin */ opt_nologin = TRUE; break; - case 's': /* use existing session ID */ - g_free(opt_session_arg); - opt_session_arg = g_strdup(optarg); - break; case 'v': /* version */ opt_version = TRUE; break; diff -r 6eecd6ba2862 -r ae544623840b finch/gntdebug.c --- a/finch/gntdebug.c Mon Dec 22 19:40:05 2008 +0000 +++ b/finch/gntdebug.c Fri Jan 02 19:27:02 2009 +0000 @@ -43,6 +43,48 @@ #define PREF_ROOT "/finch/debug" +static gboolean +handle_fprintf_stderr_cb(GIOChannel *source, GIOCondition cond, gpointer null) +{ + gssize size; + char message[1024]; + + size = read(g_io_channel_unix_get_fd(source), message, sizeof(message) - 1); + if (size <= 0) { + /* Something bad probably happened elsewhere ... let's ignore */ + } else { + message[size] = '\0'; + g_log("stderr", G_LOG_LEVEL_WARNING, "%s", message); + } + + return TRUE; +} + +static void +handle_fprintf_stderr(gboolean stop) +{ + GIOChannel *stderrch; + static int readhandle = -1; + int pipes[2]; + + if (stop) { + if (readhandle >= 0) { + g_source_remove(readhandle); + readhandle = -1; + } + return; + } + pipe(pipes); + dup2(pipes[1], STDERR_FILENO); + + stderrch = g_io_channel_unix_new(pipes[0]); + g_io_channel_set_close_on_unref(stderrch, TRUE); + readhandle = g_io_add_watch_full(stderrch, G_PRIORITY_HIGH, + G_IO_IN | G_IO_ERR | G_IO_PRI, + handle_fprintf_stderr_cb, NULL, NULL); + g_io_channel_unref(stderrch); +} + static struct { GntWidget *window; @@ -143,10 +185,6 @@ } static void -suppress_error_messages(const char *message) -{} - -static void toggle_pause(GntWidget *w, gpointer n) { debug.paused = !debug.paused; @@ -348,10 +386,11 @@ #ifdef USE_GSTREAMER REGISTER_G_LOG_HANDLER("GStreamer"); #endif + REGISTER_G_LOG_HANDLER("stderr"); g_set_print_handler(print_stderr); /* Redirect the debug messages to stderr */ if (!purple_debug_is_enabled()) - g_set_printerr_handler(suppress_error_messages); + handle_fprintf_stderr(FALSE); purple_prefs_add_none(PREF_ROOT); purple_prefs_add_string(PREF_ROOT "/filter", ""); @@ -365,5 +404,6 @@ void finch_debug_uninit() { + handle_fprintf_stderr(TRUE); } diff -r 6eecd6ba2862 -r ae544623840b libpurple/blist.c --- a/libpurple/blist.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/blist.c Fri Jan 02 19:27:02 2009 +0000 @@ -1029,7 +1029,7 @@ return; dest = purple_find_group(new_name); - if (dest != NULL) { + if (dest != NULL && purple_utf8_strcasecmp(source->name, dest->name) != 0) { /* We're merging two groups */ PurpleBlistNode *prev, *child, *next; diff -r 6eecd6ba2862 -r ae544623840b libpurple/core.c --- a/libpurple/core.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/core.c Fri Jan 02 19:27:02 2009 +0000 @@ -219,6 +219,7 @@ purple_proxy_uninit(); purple_dnsquery_uninit(); purple_imgstore_uninit(); + purple_network_uninit(); purple_debug_info("main", "Unloading all plugins\n"); purple_plugins_destroy_all(); diff -r 6eecd6ba2862 -r ae544623840b libpurple/network.c --- a/libpurple/network.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/network.c Fri Jan 02 19:27:02 2009 +0000 @@ -71,6 +71,11 @@ #elif defined _WIN32 static int current_network_count; + +/* Mutex for the other global vars */ +static GStaticMutex mutex = G_STATIC_MUTEX_INIT; +static gboolean network_initialized; +static HANDLE network_change_handle; #endif struct _PurpleNetworkListenData { @@ -535,8 +540,8 @@ static gpointer wpurple_network_change_thread(gpointer data) { - HANDLE h; WSAQUERYSET qs; + WSAEVENT *nla_event; time_t last_trigger = time(NULL); int (WSAAPI *MyWSANSPIoctl) ( @@ -549,23 +554,47 @@ return NULL; } + if ((nla_event = WSACreateEvent()) == WSA_INVALID_EVENT) { + int errorid = WSAGetLastError(); + gchar *msg = g_win32_error_message(errorid); + purple_debug_warning("network", "Couldn't create WSA event. " + "Message: %s (%d).\n", msg, errorid); + g_free(msg); + g_thread_exit(NULL); + return NULL; + } + while (TRUE) { int retval; DWORD retLen = 0; + WSACOMPLETION completion; + WSAOVERLAPPED overlapped; + + g_static_mutex_lock(&mutex); + if (network_initialized == FALSE) { + /* purple_network_uninit has been called */ + WSACloseEvent(nla_event); + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + return NULL; + } memset(&qs, 0, sizeof(WSAQUERYSET)); qs.dwSize = sizeof(WSAQUERYSET); qs.dwNameSpace = NS_NLA; - if (WSALookupServiceBegin(&qs, 0, &h) == SOCKET_ERROR) { + if (WSALookupServiceBegin(&qs, 0, &network_change_handle) == SOCKET_ERROR) { int errorid = WSAGetLastError(); gchar *msg = g_win32_error_message(errorid); purple_debug_warning("network", "Couldn't retrieve NLA SP lookup handle. " "NLA service is probably not running. Message: %s (%d).\n", msg, errorid); g_free(msg); + WSACloseEvent(nla_event); + g_static_mutex_unlock(&mutex); g_thread_exit(NULL); return NULL; } + g_static_mutex_unlock(&mutex); /* Make sure at least 30 seconds have elapsed since the last * notification so we don't peg the cpu if this keeps changing. */ @@ -574,19 +603,40 @@ last_trigger = time(NULL); - /* This will block until there is a network change */ - if (MyWSANSPIoctl(h, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &retLen, NULL) == SOCKET_ERROR) { + memset(&completion, 0, sizeof(WSACOMPLETION)); + completion.Type = NSP_NOTIFY_EVENT; + overlapped.hEvent = nla_event; + completion.Parameters.Event.lpOverlapped = &overlapped; + + if (MyWSANSPIoctl(network_change_handle, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &retLen, &completion) == SOCKET_ERROR) { int errorid = WSAGetLastError(); - gchar *msg = g_win32_error_message(errorid); - purple_debug_warning("network", "Unable to wait for changes. Message: %s (%d).\n", - msg, errorid); - g_free(msg); + /* WSA_IO_PENDING indicates successful async notification will happen */ + if (errorid != WSA_IO_PENDING) { + gchar *msg = g_win32_error_message(errorid); + purple_debug_warning("network", "Unable to wait for changes. Message: %s (%d).\n", + msg, errorid); + g_free(msg); + } } - retval = WSALookupServiceEnd(h); + /* This will block until NLA notifies us */ + retval = WaitForSingleObjectEx(nla_event, WSA_INFINITE, TRUE); + + g_static_mutex_lock(&mutex); + if (network_initialized == FALSE) { + /* Time to die */ + WSACloseEvent(nla_event); + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + return NULL; + } + + retval = WSALookupServiceEnd(network_change_handle); + network_change_handle = NULL; + WSAResetEvent(nla_event); + g_static_mutex_unlock(&mutex); purple_timeout_add(0, wpurple_network_change_thread_cb, NULL); - } g_thread_exit(NULL); @@ -714,6 +764,7 @@ GError *err = NULL; gint cnt = wpurple_get_connected_network_count(); + network_initialized = TRUE; if (cnt < 0) /* Assume there is a network */ current_network_count = 1; /* Don't listen for network changes if we can't tell anyway */ @@ -782,6 +833,25 @@ dbus_g_connection_unref(nm_conn); #endif +#ifdef _WIN32 + g_static_mutex_lock(&mutex); + network_initialized = FALSE; + if (network_change_handle != NULL) { + int retval; + /* Trigger the NLA thread to stop waiting for network changes. Not + * doing this can cause hangs on WSACleanup. */ + purple_debug_warning("network", "Terminating the NLA thread\n"); + if ((retval = WSALookupServiceEnd(network_change_handle)) == SOCKET_ERROR) { + int errorid = WSAGetLastError(); + gchar *msg = g_win32_error_message(errorid); + purple_debug_warning("network", "Unable to kill NLA thread. Message: %s (%d).\n", + msg, errorid); + g_free(msg); + } + } + g_static_mutex_unlock(&mutex); + +#endif purple_signal_unregister(purple_network_get_handle(), "network-configuration-changed"); } diff -r 6eecd6ba2862 -r ae544623840b libpurple/prefs.c --- a/libpurple/prefs.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/prefs.c Fri Jan 02 19:27:02 2009 +0000 @@ -693,12 +693,15 @@ char *name; GSList *l; - if(!pref || pref == &prefs) + if(!pref) return; while(pref->first_child) remove_pref(pref->first_child); + if(pref == &prefs) + return; + if(pref->parent->first_child == pref) { pref->parent->first_child = pref->sibling; } else { @@ -1452,4 +1455,8 @@ } purple_prefs_disconnect_by_handle(purple_prefs_get_handle()); + purple_prefs_destroy(); + g_hash_table_destroy(prefs_hash); + prefs_hash = NULL; + } diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/bonjour/mdns_win32.c --- a/libpurple/protocols/bonjour/mdns_win32.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Fri Jan 02 19:27:02 2009 +0000 @@ -167,7 +167,11 @@ ResolveCallbackArgs *args = (ResolveCallbackArgs*) data; Win32BuddyImplData *idata = args->bb->mdns_impl_data; gboolean delete_buddy = FALSE; - PurpleBuddy *pb; + PurpleBuddy *pb = NULL; + + /* Make sure that the BonjourBuddy associated with this request is still around */ + if (g_slist_find(pending_buddies, args->bb) == NULL) + goto cleanup; if ((pb = purple_find_buddy(args->account, args->bb->name))) if (pb->proto_data != args->bb) @@ -209,6 +213,8 @@ } + cleanup: + /* free the hosts list*/ while (hosts != NULL) { hosts = g_slist_remove(hosts, hosts->data); diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/gg/buddylist.c --- a/libpurple/protocols/gg/buddylist.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/gg/buddylist.c Fri Jan 02 19:27:02 2009 +0000 @@ -216,13 +216,14 @@ PurpleBlistNode *gnode, *cnode, *bnode; PurpleGroup *group; PurpleBuddy *buddy; - - char *buddylist = g_strdup(""); + GString *buddylist; char *ptr; if ((blist = purple_get_blist()) == NULL) return NULL; + buddylist = g_string_sized_new(1024); + for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { if (!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; @@ -247,19 +248,16 @@ alias = buddy->alias ? buddy->alias : buddy->name; gname = group->name; - ptr = buddylist; - buddylist = g_strdup_printf( - "%s%s;%s;%s;%s;%s;%s;%s;%s%s\r\n", - ptr, alias, alias, alias, alias, + g_string_append_printf(buddylist, + "%s;%s;%s;%s;%s;%s;%s;%s%s\r\n", + alias, alias, alias, alias, "", gname, name, "", ""); - - g_free(ptr); } } } - ptr = charset_convert(buddylist, "UTF-8", "CP1250"); - g_free(buddylist); + ptr = charset_convert(buddylist->str, "UTF-8", "CP1250"); + g_string_free(buddylist, TRUE); return ptr; } /* }}} */ diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/jabber/disco.c --- a/libpurple/protocols/jabber/disco.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/jabber/disco.c Fri Jan 02 19:27:02 2009 +0000 @@ -355,6 +355,11 @@ jabber_adhoc_server_get_list(js); } + /* If the server supports blocking, request the block list */ + if (js->server_caps & JABBER_CAP_BLOCKING) { + jabber_request_block_list(js); + } + /* If there are manually specified bytestream proxies, query them */ ft_proxies = purple_account_get_string(js->gc->account, "ft_proxies", NULL); if (ft_proxies) { @@ -454,6 +459,8 @@ jabber_google_roster_init(js); } else if (!strcmp("http://jabber.org/protocol/commands", var)) { js->server_caps |= JABBER_CAP_ADHOC; + } else if (!strcmp("urn:xmpp:blocking", var)) { + js->server_caps |= JABBER_CAP_BLOCKING; } } diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Fri Jan 02 19:27:02 2009 +0000 @@ -31,6 +31,7 @@ #include "message.h" #include "notify.h" #include "pluginpref.h" +#include "privacy.h" #include "proxy.h" #include "prpl.h" #include "request.h" @@ -150,7 +151,7 @@ char hostname[256]; /* current hostname */ /* Empty resource == don't send any */ - if (*input == '\0') + if (input == NULL || *input == '\0') return NULL; if (strstr(input, "__HOSTNAME__") == NULL) @@ -350,9 +351,33 @@ { /* because printing a tab to debug every minute gets old */ - if(strcmp(data, "\t")) - purple_debug(PURPLE_DEBUG_MISC, "jabber", "Sending%s: %s\n", - js->gsc ? " (ssl)" : "", data); + if(strcmp(data, "\t")) { + char *text = NULL, *last_part = NULL, *tag_start = NULL; + + /* Because debug logs with plaintext passwords make me sad */ + if(js->state != JABBER_STREAM_CONNECTED && + /* Either or ... */ + (((tag_start = strstr(data, "") && + (tag_start = strstr(tag_start, ""))))) { + char *data_start, *tag_end = strchr(tag_start, '>'); + text = g_strdup(data); + + data_start = text + (tag_end - data) + 1; + + last_part = strchr(data_start, '<'); + *data_start = '\0'; + } + + purple_debug(PURPLE_DEBUG_MISC, "jabber", "Sending%s: %s%s%s\n", + js->gsc ? " (ssl)" : "", text ? text : data, + last_part ? "password removed" : "", + last_part ? last_part : ""); + + g_free(text); + } /* If we've got a security layer, we need to encode the data, * splitting it on the maximum buffer length negotiated */ @@ -1454,6 +1479,106 @@ js->idle = idle ? time(NULL) - idle : idle; } +static void jabber_blocklist_parse(JabberStream *js, xmlnode *packet, gpointer data) +{ + xmlnode *blocklist, *item; + PurpleAccount *account; + + blocklist = xmlnode_get_child_with_namespace(packet, + "blocklist", "urn:xmpp:blocking"); + account = purple_connection_get_account(js->gc); + + if (blocklist == NULL) + return; + + item = xmlnode_get_child(blocklist, "item"); + while (item != NULL) { + const char *jid = xmlnode_get_attrib(item, "jid"); + + purple_privacy_deny_add(account, jid, TRUE); + item = xmlnode_get_next_twin(item); + } +} + +void jabber_request_block_list(JabberStream *js) +{ + JabberIq *iq; + xmlnode *blocklist; + + iq = jabber_iq_new(js, JABBER_IQ_GET); + + blocklist = xmlnode_new_child(iq->node, "blocklist"); + xmlnode_set_namespace(blocklist, "urn:xmpp:blocking"); + + jabber_iq_set_callback(iq, jabber_blocklist_parse, NULL); + + jabber_iq_send(iq); +} + +void jabber_add_deny(PurpleConnection *gc, const char *who) +{ + JabberStream *js; + JabberIq *iq; + xmlnode *block, *item; + + js = gc->proto_data; + if (js == NULL) + return; + + if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + { + jabber_google_roster_add_deny(gc, who); + return; + } + + if (!(js->server_caps & JABBER_CAP_BLOCKING)) + { + purple_notify_error(NULL, _("Server doesn't support blocking"), + _("Server doesn't support blocking"), NULL); + return; + } + + iq = jabber_iq_new(js, JABBER_IQ_SET); + + block = xmlnode_new_child(iq->node, "block"); + xmlnode_set_namespace(block, "urn:xmpp:blocking"); + + item = xmlnode_new_child(block, "item"); + xmlnode_set_attrib(item, "jid", who); + + jabber_iq_send(iq); +} + +void jabber_rem_deny(PurpleConnection *gc, const char *who) +{ + JabberStream *js; + JabberIq *iq; + xmlnode *unblock, *item; + + js = gc->proto_data; + if (js == NULL) + return; + + if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + { + jabber_google_roster_rem_deny(gc, who); + return; + } + + if (!(js->server_caps & JABBER_CAP_BLOCKING)) + return; + + iq = jabber_iq_new(js, JABBER_IQ_SET); + + unblock = xmlnode_new_child(iq->node, "unblock"); + xmlnode_set_namespace(unblock, "urn:xmpp:blocking"); + + item = xmlnode_new_child(unblock, "item"); + xmlnode_set_attrib(item, "jid", who); + + jabber_iq_send(iq); +} + void jabber_add_feature(const char *shortname, const char *namespace, JabberFeatureEnabled cb) { JabberFeature *feat; diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/jabber/jabber.h --- a/libpurple/protocols/jabber/jabber.h Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.h Fri Jan 02 19:27:02 2009 +0000 @@ -42,7 +42,8 @@ JABBER_CAP_PING = 1 << 11, JABBER_CAP_ADHOC = 1 << 12, - + JABBER_CAP_BLOCKING = 1 << 13, + JABBER_CAP_RETRIEVED = 1 << 31 } JabberCapabilities; @@ -294,6 +295,9 @@ void jabber_login(PurpleAccount *account); void jabber_close(PurpleConnection *gc); void jabber_idle_set(PurpleConnection *gc, int idle); +void jabber_request_block_list(JabberStream *js); +void jabber_add_deny(PurpleConnection *gc, const char *who); +void jabber_rem_deny(PurpleConnection *gc, const char *who); void jabber_keepalive(PurpleConnection *gc); void jabber_register_gateway(JabberStream *js, const char *gateway); void jabber_register_account(PurpleAccount *account); diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Fri Jan 02 19:27:02 2009 +0000 @@ -77,9 +77,9 @@ jabber_roster_remove_buddy, /* remove_buddy */ NULL, /* remove_buddies */ NULL, /* add_permit */ - jabber_google_roster_add_deny, /* add_deny */ + jabber_add_deny, /* add_deny */ NULL, /* rem_permit */ - jabber_google_roster_rem_deny, /* rem_deny */ + jabber_rem_deny, /* rem_deny */ NULL, /* set_permit_deny */ jabber_chat_join, /* join_chat */ NULL, /* reject_chat */ diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/jabber/message.c --- a/libpurple/protocols/jabber/message.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/jabber/message.c Fri Jan 02 19:27:02 2009 +0000 @@ -291,27 +291,28 @@ PurpleAccount *account; PurpleConversation *c; char *username, *str; - + /* Delayed buzz MUST NOT be accepted */ if(jm->delayed) return; - + /* Reject buzz when it's not enabled */ if(!jm->js->allowBuzz) return; - + account = purple_connection_get_account(jm->js->gc); - - if ((buddy = purple_find_buddy(account, jm->from)) != NULL) - username = g_markup_escape_text(purple_buddy_get_alias(buddy), -1); - else + + if ((buddy = purple_find_buddy(account, jm->from)) == NULL) return; /* Do not accept buzzes from unknown people */ - c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, jm->from); + c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, jm->from, account); + if (c == NULL) + c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, jm->from); - str = g_strdup_printf(_("%s has buzzed you!"), username); - - purple_conversation_write(c, NULL, str, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL)); + username = g_markup_escape_text(purple_buddy_get_alias(buddy), -1); + /* xmpp only has 1 attention type, so index is 0 */ + purple_prpl_got_attention(jm->js->gc, username, 0); + g_free(username); g_free(str); } diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/msn/error.c --- a/libpurple/protocols/msn/error.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/msn/error.c Fri Jan 02 19:27:02 2009 +0000 @@ -27,191 +27,178 @@ const char * msn_error_get_text(unsigned int type, gboolean *debug) { - static char msg[MSN_BUF_LEN]; + static char msg[256]; + const char *result; *debug = FALSE; switch (type) { case 0: - g_snprintf(msg, sizeof(msg), - _("Unable to parse message")); + result = _("Unable to parse message"); *debug = TRUE; break; case 200: - g_snprintf(msg, sizeof(msg), - _("Syntax Error (probably a client bug)")); + result = _("Syntax Error (probably a client bug)"); *debug = TRUE; break; case 201: - g_snprintf(msg, sizeof(msg), - _("Invalid email address")); + result = _("Invalid email address"); break; case 205: - g_snprintf(msg, sizeof(msg), _("User does not exist")); + result = _("User does not exist"); break; case 206: - g_snprintf(msg, sizeof(msg), - _("Fully qualified domain name missing")); + result = _("Fully qualified domain name missing"); break; case 207: - g_snprintf(msg, sizeof(msg), _("Already logged in")); + result = _("Already logged in"); break; case 208: - g_snprintf(msg, sizeof(msg), _("Invalid username")); + result = _("Invalid username"); break; case 209: - g_snprintf(msg, sizeof(msg), _("Invalid friendly name")); + result = _("Invalid friendly name"); break; case 210: - g_snprintf(msg, sizeof(msg), _("List full")); + result = _("List full"); break; case 215: - g_snprintf(msg, sizeof(msg), _("Already there")); + result = _("Already there"); *debug = TRUE; break; case 216: - g_snprintf(msg, sizeof(msg), _("Not on list")); + result = _("Not on list"); break; case 217: - g_snprintf(msg, sizeof(msg), _("User is offline")); + result = _("User is offline"); break; case 218: - g_snprintf(msg, sizeof(msg), _("Already in the mode")); + result = _("Already in the mode"); *debug = TRUE; break; case 219: - g_snprintf(msg, sizeof(msg), _("Already in opposite list")); + result = _("Already in opposite list"); *debug = TRUE; break; case 223: - g_snprintf(msg, sizeof(msg), _("Too many groups")); + result = _("Too many groups"); break; case 224: - g_snprintf(msg, sizeof(msg), _("Invalid group")); + result = _("Invalid group"); break; case 225: - g_snprintf(msg, sizeof(msg), _("User not in group")); + result = _("User not in group"); break; case 229: - g_snprintf(msg, sizeof(msg), _("Group name too long")); + result = _("Group name too long"); break; case 230: - g_snprintf(msg, sizeof(msg), _("Cannot remove group zero")); + result = _("Cannot remove group zero"); *debug = TRUE; break; case 231: - g_snprintf(msg, sizeof(msg), - _("Tried to add a user to a group " - "that doesn't exist")); + result = _("Tried to add a user to a group that doesn't exist"); break; case 280: - g_snprintf(msg, sizeof(msg), _("Switchboard failed")); + result = _("Switchboard failed"); *debug = TRUE; break; case 281: - g_snprintf(msg, sizeof(msg), _("Notify transfer failed")); + result = _("Notify transfer failed"); *debug = TRUE; break; case 300: - g_snprintf(msg, sizeof(msg), _("Required fields missing")); + result = _("Required fields missing"); *debug = TRUE; break; case 301: - g_snprintf(msg, sizeof(msg), _("Too many hits to a FND")); + result = _("Too many hits to a FND"); *debug = TRUE; break; case 302: - g_snprintf(msg, sizeof(msg), _("Not logged in")); + result = _("Not logged in"); break; case 500: - g_snprintf(msg, sizeof(msg), - _("Service temporarily unavailable")); + result = _("Service temporarily unavailable"); break; case 501: - g_snprintf(msg, sizeof(msg), _("Database server error")); + result = _("Database server error"); *debug = TRUE; break; case 502: - g_snprintf(msg, sizeof(msg), _("Command disabled")); + result = _("Command disabled"); *debug = TRUE; break; case 510: - g_snprintf(msg, sizeof(msg), _("File operation error")); + result = _("File operation error"); *debug = TRUE; break; case 520: - g_snprintf(msg, sizeof(msg), _("Memory allocation error")); + result = _("Memory allocation error"); *debug = TRUE; break; case 540: - g_snprintf(msg, sizeof(msg), - _("Wrong CHL value sent to server")); + result = _("Wrong CHL value sent to server"); *debug = TRUE; break; case 600: - g_snprintf(msg, sizeof(msg), _("Server busy")); + result = _("Server busy"); break; case 601: - g_snprintf(msg, sizeof(msg), _("Server unavailable")); + result = _("Server unavailable"); break; case 602: - g_snprintf(msg, sizeof(msg), - _("Peer notification server down")); + result = _("Peer notification server down"); *debug = TRUE; break; case 603: - g_snprintf(msg, sizeof(msg), _("Database connect error")); + result = _("Database connect error"); *debug = TRUE; break; case 604: - g_snprintf(msg, sizeof(msg), - _("Server is going down (abandon ship)")); + result = _("Server is going down (abandon ship)"); break; case 605: - g_snprintf(msg, sizeof(msg), _("Server unavailable")); + result = _("Server unavailable"); break; case 707: - g_snprintf(msg, sizeof(msg), - _("Error creating connection")); + result = _("Error creating connection"); *debug = TRUE; break; case 710: - g_snprintf(msg, sizeof(msg), - _("CVR parameters are either unknown " - "or not allowed")); + result = _("CVR parameters are either unknown or not allowed"); *debug = TRUE; break; case 711: - g_snprintf(msg, sizeof(msg), _("Unable to write")); + result = _("Unable to write"); break; case 712: - g_snprintf(msg, sizeof(msg), _("Session overload")); + result = _("Session overload"); *debug = TRUE; break; case 713: - g_snprintf(msg, sizeof(msg), _("User is too active")); + result = _("User is too active"); break; case 714: - g_snprintf(msg, sizeof(msg), _("Too many sessions")); + result = _("Too many sessions"); break; case 715: - g_snprintf(msg, sizeof(msg), _("Passport not verified")); + result = _("Passport not verified"); break; case 717: - g_snprintf(msg, sizeof(msg), _("Bad friend file")); + result = _("Bad friend file"); *debug = TRUE; break; case 731: - g_snprintf(msg, sizeof(msg), _("Not expected")); + result = _("Not expected"); *debug = TRUE; break; case 800: - g_snprintf(msg, sizeof(msg), - _("Friendly name changes too rapidly")); + result = _("Friendly name changes too rapidly"); break; case 910: @@ -220,37 +207,34 @@ case 919: case 921: case 922: - g_snprintf(msg, sizeof(msg), _("Server too busy")); + result = _("Server too busy"); break; case 911: case 917: - g_snprintf(msg, sizeof(msg), _("Authentication failed")); + result = _("Authentication failed"); break; case 913: - g_snprintf(msg, sizeof(msg), _("Not allowed when offline")); + result = _("Not allowed when offline"); break; case 914: case 915: case 916: - g_snprintf(msg, sizeof(msg), _("Server unavailable")); + result = _("Server unavailable"); break; case 920: - g_snprintf(msg, sizeof(msg), _("Not accepting new users")); + result = _("Not accepting new users"); break; case 923: - g_snprintf(msg, sizeof(msg), - _("Kids Passport without parental consent")); + result = _("Kids Passport without parental consent"); break; case 924: - g_snprintf(msg, sizeof(msg), - _("Passport account not yet verified")); + result = _("Passport account not yet verified"); break; case 927: - g_snprintf(msg, sizeof(msg), - _("Passport account suspended")); + result = _("Passport account suspended"); break; case 928: - g_snprintf(msg, sizeof(msg), _("Bad ticket")); + result = _("Bad ticket"); *debug = TRUE; break; @@ -258,23 +242,25 @@ g_snprintf(msg, sizeof(msg), _("Unknown Error Code %d"), type); *debug = TRUE; + result = msg; break; } - return msg; + return result; } void msn_error_handle(MsnSession *session, unsigned int type) { - char buf[MSN_BUF_LEN]; + char *buf; gboolean debug; - g_snprintf(buf, sizeof(buf), _("MSN Error: %s\n"), - msn_error_get_text(type, &debug)); + buf = g_strdup_printf(_("MSN Error: %s\n"), + msn_error_get_text(type, &debug)); if (debug) purple_debug_warning("msn", "error %d: %s\n", type, buf); else purple_notify_error(session->account->gc, NULL, buf, NULL); + g_free(buf); } diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/msn/oim.c --- a/libpurple/protocols/msn/oim.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/msn/oim.c Fri Jan 02 19:27:02 2009 +0000 @@ -596,6 +596,7 @@ MsnMessage *message; const char *date; const char *from; + const char *boundary; char *decode_msg = NULL; gsize body_len; char **tokens; @@ -608,27 +609,14 @@ MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM); purple_debug_info("msn", "oim body:{%s}\n", message->body); - if (!strcmp(msn_message_get_attr(message, "X-OIMProxy"), "MOSMS")) { - char *boundary; + boundary = msn_message_get_attr(message, "boundary"); + + if (boundary != NULL) { + char *bounds; char **part; - from = msn_message_get_attr(message, "X-OIM-originatingSource"); - - /* Match number to user's mobile number, FROM is a phone number - if the other side pages you using your phone number */ - if (!strncmp(from, "tel:+", 5)) { - MsnUser *user = msn_userlist_find_user_with_mobile_phone( - rdata->oim->session->userlist, from + 4); - - if (user && user->passport) - passport = g_strdup(user->passport); - } - if (passport == NULL) - passport = g_strdup(from); - - boundary = g_strdup_printf("--%s" MSG_OIM_LINE_DEM, - msn_message_get_attr(message, "boundary")); - tokens = g_strsplit(message->body, boundary, 0); + bounds = g_strdup_printf("--%s" MSG_OIM_LINE_DEM, boundary); + tokens = g_strsplit(message->body, bounds, 0); /* tokens+1 to skip the "This is a multipart message..." text */ for (part = tokens+1; *part != NULL; part++) { @@ -648,18 +636,33 @@ } g_strfreev(tokens); - g_free(boundary); + g_free(bounds); if (decode_msg == NULL) { purple_debug_error("msn", "Couldn't find text/plain OIM message.\n"); - g_free(passport); + msn_message_destroy(message); return; } } else { + decode_msg = (char *)purple_base64_decode(message->body, &body_len); + } + + from = msn_message_get_attr(message, "X-OIM-originatingSource"); + + /* Match number to user's mobile number, FROM is a phone number + if the other side pages you using your phone number */ + if (!strncmp(from, "tel:+", 5)) { + MsnUser *user = msn_userlist_find_user_with_mobile_phone( + rdata->oim->session->userlist, from + 4); + + if (user && user->passport) + passport = g_strdup(user->passport); + } + + if (passport == NULL) { char *start, *end; from = msn_message_get_attr(message, "From"); - decode_msg = (char *)purple_base64_decode(message->body, &body_len); tokens = g_strsplit(from, " ", 2); if (tokens[1] != NULL) @@ -687,6 +690,7 @@ g_free(passport); g_free(decode_msg); + msn_message_destroy(message); } /* Parse the XML data, diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/myspace/myspace.c Fri Jan 02 19:27:02 2009 +0000 @@ -211,7 +211,6 @@ /* Don't have uid offhand - need to ask for it, and wait until hear back before sending. */ purple_debug_info("msim", ">>> msim_postprocess_outgoing: couldn't find username %s in blist\n", username ? username : "(NULL)"); - /* TODO: where is cloned message freed? Should be in _cb. */ msim_lookup_user(session, username, msim_postprocess_outgoing_cb, msim_msg_clone(msg)); return TRUE; /* not sure of status yet - haven't sent! */ } @@ -1923,8 +1922,7 @@ msim_process(session, msg); - /* TODO: Free copy cloned from msim_preprocess_incoming(). */ - /* msim_msg_free(msg); */ + msim_msg_free(msg); msim_msg_free(body); } @@ -2735,9 +2733,15 @@ * doesn't seem like it would be necessary, but the official client * does it) */ - if (!msim_update_blocklist_for_buddy(session, buddy->name, FALSE, FALSE)) + if (!msim_update_blocklist_for_buddy(session, buddy->name, FALSE, FALSE)) { purple_notify_error(NULL, NULL, _("Failed to remove buddy"), _("blocklist command failed")); + return; + } + if (buddy->proto_data) { + msim_user_free(buddy->proto_data); + buddy->proto_data = NULL; + } } /** @@ -2827,6 +2831,13 @@ msim_update_blocklist_for_buddy(session, name, FALSE, FALSE); } +static void +msim_buddy_free(PurpleBuddy *buddy) +{ + msim_user_free(buddy->proto_data); + buddy->proto_data = NULL; +} + /** * Returns a string of a username in canonical form. Basically removes all the * spaces, lowercases the string, and looks up user IDs to usernames. @@ -3043,7 +3054,7 @@ NULL, /* alias_buddy */ NULL, /* group_buddy */ NULL, /* rename_group */ - NULL, /* buddy_free */ + msim_buddy_free, /* buddy_free */ NULL, /* convo_closed */ msim_normalize, /* normalize */ NULL, /* set_buddy_icon */ diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/myspace/session.h --- a/libpurple/protocols/myspace/session.h Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/myspace/session.h Fri Jan 02 19:27:02 2009 +0000 @@ -35,7 +35,7 @@ guint userid; /**< This user's numeric user ID */ gchar *username; /**< This user's unique username */ gboolean show_only_to_list; - int privacy_mode; + int privacy_mode; /**< This is a bitmask */ int offline_message_mode; gint fd; /**< File descriptor to/from server */ diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/myspace/user.c --- a/libpurple/protocols/myspace/user.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/myspace/user.c Fri Jan 02 19:27:02 2009 +0000 @@ -55,10 +55,9 @@ if (create && !buddy->proto_data) { /* No MsimUser for this buddy; make one. */ - /* TODO: where is this freed? */ user = g_new0(MsimUser, 1); user->buddy = buddy; - user->id = purple_blist_node_get_int(&buddy->node, "UserID"); + user->id = purple_blist_node_get_int((PurpleBlistNode*)buddy, "UserID"); buddy->proto_data = (gpointer)user; } else { user = (MsimUser *)(buddy->proto_data); @@ -67,6 +66,23 @@ return user; } +void msim_user_free(MsimUser *user) +{ + if (!user) + return; + + g_free(user->client_info); + g_free(user->gender); + g_free(user->location); + g_free(user->headline); + g_free(user->display_name); + g_free(user->username); + g_free(user->band_name); + g_free(user->song_name); + g_free(user->image_url); + g_free(user); +} + /** * Find and return an MsimUser * representing a user on the buddy list, or NULL. */ @@ -406,10 +422,11 @@ } if (msim_msg_get_integer(msg, "dsn") == MG_OWN_IM_INFO_DSN && - msim_msg_get_integer(msg, "lid") == MG_OWN_IM_INFO_LID) { + msim_msg_get_integer(msg, "lid") == MG_OWN_IM_INFO_LID) + { /* * Some of this info will be available on the buddy list if the - * has themselves as their own buddy. + * user has themselves as their own buddy. * * Much of the info is already available in MsimSession, * stored in msim_we_are_logged_on(). @@ -431,7 +448,7 @@ "idlist", MSIM_TYPE_STRING, g_strdup_printf("w%d|c%d", session->show_only_to_list ? 1 : 0, - session->privacy_mode), + session->privacy_mode & 1), NULL); } else if (msim_msg_get_integer(msg, "dsn") == MG_OWN_MYSPACE_INFO_DSN && msim_msg_get_integer(msg, "lid") == MG_OWN_MYSPACE_INFO_LID) { diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/myspace/user.h --- a/libpurple/protocols/myspace/user.h Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/myspace/user.h Fri Jan 02 19:27:02 2009 +0000 @@ -46,7 +46,8 @@ * initiated from a user lookup. */ typedef void (*MSIM_USER_LOOKUP_CB)(MsimSession *session, const MsimMessage *userinfo, gpointer data); -MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy, gboolean create); +MsimUser *msim_get_user_from_buddy(PurpleBuddy *buddy); +void msim_user_free(MsimUser *user); MsimUser *msim_find_user(MsimSession *session, const gchar *username); void msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full); gboolean msim_store_user_info(MsimSession *session, const MsimMessage *msg, MsimUser *user); diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/oscar/odc.c --- a/libpurple/protocols/oscar/odc.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/oscar/odc.c Fri Jan 02 19:27:02 2009 +0000 @@ -567,6 +567,7 @@ { purple_debug_info("oscar", "Unknown ODC frame type 0x%04hx, " "subtype 0x%04hx.\n", frame->type, frame->subtype); + g_free(frame); return; } @@ -607,6 +608,7 @@ g_free(tmp); peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL); + g_free(frame); return; } diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/AUTHORS --- a/libpurple/protocols/qq/AUTHORS Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/AUTHORS Fri Jan 02 19:27:02 2009 +0000 @@ -1,7 +1,7 @@ Code Contributors ========= puzzlebird : original author -gfhuang : patches for libpurple 2.0.0beta2, maintainer +gfhuang(poppyer): patches for libpurple 2.0.0beta2, maintainer Yuan Qingyun : patches for libpurple 1.5.0, maintainer henryouly : file transfer, udp sock5 proxy and qq_show, maintainer hzhr : maintainer diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/ChangeLog --- a/libpurple/protocols/qq/ChangeLog Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/ChangeLog Fri Jan 02 19:27:02 2009 +0000 @@ -1,3 +1,10 @@ +2008.12.25 - flos + * References #7821 + * Updated authors + +2008.12.17 - flos + * Minor fixed in buddy_info.c + 2008.12.06 - flos * Removed version checking script in Makefiles since our developers all migrated to monotone * Use our development revision as OPENQ_VERSION in qq.c diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/buddy_info.c --- a/libpurple/protocols/qq/buddy_info.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/buddy_info.c Fri Jan 02 19:27:02 2009 +0000 @@ -790,7 +790,7 @@ bytes += qq_get32(&onlineTime, data + bytes); bytes += qq_get16(&level, data + bytes); bytes += qq_get16(&timeRemainder, data + bytes); - purple_debug_info("QQ", "level: %d, uid %d, tmOnline: %d, tmRemainder: %d\n", + purple_debug_info("QQ", "level: %d, uid %u, tmOnline: %d, tmRemainder: %d\n", level, uid, onlineTime, timeRemainder); bd = qq_buddy_data_find(gc, uid); @@ -825,12 +825,12 @@ bytes += qq_get32(&onlineTime, data + bytes); bytes += qq_get16(&level, data + bytes); bytes += qq_get16(&timeRemainder, data + bytes); - purple_debug_info("QQ", "level: %d, uid %d, tmOnline: %d, tmRemainder: %d\n", + purple_debug_info("QQ", "level: %d, uid %u, tmOnline: %d, tmRemainder: %d\n", level, uid, onlineTime, timeRemainder); bd = qq_buddy_data_find(gc, uid); if (bd == NULL) { - purple_debug_error("QQ", "Got levels of %d not in my buddy list\n", uid); + purple_debug_error("QQ", "Got levels of %u not in my buddy list\n", uid); return; } diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/group_internal.c --- a/libpurple/protocols/qq/group_internal.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/group_internal.c Fri Jan 02 19:27:02 2009 +0000 @@ -30,7 +30,7 @@ #include "group_internal.h" #include "utils.h" -static qq_room_data *room_data_new(guint32 id, guint32 ext_id, gchar *title) +static qq_room_data *room_data_new(guint32 id, guint32 ext_id, const gchar *title) { qq_room_data *rmd; @@ -62,9 +62,9 @@ value = g_hash_table_lookup(data, QQ_ROOM_KEY_INTERNAL_ID); id = value ? strtoul(value, NULL, 10) : 0; - value= g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID); + value = g_hash_table_lookup(data, QQ_ROOM_KEY_EXTERNAL_ID); ext_id = value ? strtoul(value, NULL, 10) : 0; - value = g_strdup(g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8)); + value = g_hash_table_lookup(data, QQ_ROOM_KEY_TITLE_UTF8); rmd = room_data_new(id, ext_id, value); rmd->my_role = QQ_ROOM_ROLE_YES; diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/group_opt.c --- a/libpurple/protocols/qq/group_opt.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/group_opt.c Fri Jan 02 19:27:02 2009 +0000 @@ -416,11 +416,6 @@ bytes += qq_get_vstr(&reason, QQ_CHARSET_DEFAULT, data + bytes); - add_req = g_new0(qq_room_req, 1); - add_req->gc = gc; - add_req->id = id; - add_req->member = member_id; - purple_debug_info("QQ", "%u requested to join room, ext id %u\n", member_id, ext_id); rmd = qq_room_data_find(gc, id); @@ -442,6 +437,11 @@ who = uid_to_purple_name(member_id); msg = g_strdup_printf(_("%u request to join Qun %u"), member_id, ext_id); + add_req = g_new0(qq_room_req, 1); + add_req->gc = gc; + add_req->id = id; + add_req->member = member_id; + purple_request_action(gc, _("QQ Qun Operation"), msg, reason, PURPLE_DEFAULT_ACTION_NONE, diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/qq.c --- a/libpurple/protocols/qq/qq.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/qq.c Fri Jan 02 19:27:02 2009 +0000 @@ -626,7 +626,7 @@ g_string_append(info, "puzzlebird
\n"); g_string_append(info, "
\n"); g_string_append(info, _("

Code Contributors:
\n")); - g_string_append(info, "gfhuang : patches for libpurple 2.0.0beta2, maintainer
\n"); + g_string_append(info, "gfhuang(poppyer) : patches for libpurple 2.0.0beta2, maintainer
\n"); g_string_append(info, "Yuan Qingyun : patches for libpurple 1.5.0, maintainer
\n"); g_string_append(info, "henryouly : file transfer, udp sock5 proxy and qq_show, maintainer
\n"); g_string_append(info, "hzhr : maintainer
\n"); diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/qq/qq_network.c --- a/libpurple/protocols/qq/qq_network.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/qq/qq_network.c Fri Jan 02 19:27:02 2009 +0000 @@ -468,7 +468,7 @@ static void udp_pending(gpointer data, gint source, PurpleInputCondition cond) { - PurpleConnection *gc = (PurpleConnection *) data; + PurpleConnection *gc = NULL; qq_data *qd; guint8 *buf; gint buf_len; diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/sametime/sametime.c --- a/libpurple/protocols/sametime/sametime.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/sametime/sametime.c Fri Jan 02 19:27:02 2009 +0000 @@ -3724,7 +3724,6 @@ gc->flags |= PURPLE_CONNECTION_NO_IMAGES; user = g_strdup(purple_account_get_username(account)); - pass = g_strdup(purple_account_get_password(account)); host = strrchr(user, ':'); if(host) { @@ -3741,10 +3740,12 @@ if(! host || ! *host) { /* somehow, we don't have a host to connect to. Well, we need one to actually continue, so let's ask the user directly. */ + g_free(user); prompt_host(gc); return; } + pass = g_strdup(purple_account_get_password(account)); port = purple_account_get_int(account, MW_KEY_PORT, MW_PLUGIN_DEFAULT_PORT); DEBUG_INFO("user: '%s'\n", user); diff -r 6eecd6ba2862 -r ae544623840b libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Fri Jan 02 19:27:02 2009 +0000 @@ -4167,8 +4167,7 @@ "Trying to join %s \n", args[0]); comp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - g_hash_table_replace(comp, g_strdup("room"), - g_strdup_printf("%s", g_ascii_strdown(args[0], strlen(args[0])))); + g_hash_table_replace(comp, g_strdup("room"), g_ascii_strdown(args[0], -1)); g_hash_table_replace(comp, g_strdup("type"), g_strdup("Chat")); yahoo_c_join(gc, comp); diff -r 6eecd6ba2862 -r ae544623840b libpurple/proxy.c --- a/libpurple/proxy.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/proxy.c Fri Jan 02 19:27:02 2009 +0000 @@ -621,7 +621,7 @@ if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) return; - purple_debug_info("proxy", "Connected to %s:%d.\n", + purple_debug_info("proxy", "Connecting to %s:%d.\n", connect_data->host, connect_data->port); /* diff -r 6eecd6ba2862 -r ae544623840b libpurple/purple-url-handler --- a/libpurple/purple-url-handler Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/purple-url-handler Fri Jan 02 19:27:02 2009 +0000 @@ -299,6 +299,31 @@ else: goim(account, screenname) +def gtalk(uri): + protocol = "prpl-jabber" + match = re.match(r"^gtalk:([^?]*)(\?(.*))", uri) + if not match: + print "Invalid gtalk URI: %s" % uri + return + + command = urllib.unquote_plus(match.group(1)) + paramstring = match.group(3) + params = {} + if paramstring: + for param in paramstring.split("&"): + key, value = extendlist(param.split("=", 1), 2, "") + params[key] = urllib.unquote_plus(value) + accountname = params.get("from_jid", "") + jid = params.get("jid", "") + + account = findaccount(protocol, accountname) + + if command.lower() == "chat": + goim(account, jid) + elif command.lower() == "call": + # XXX V&V prompt to establish call + goim(account, jid) + def ymsgr(uri): protocol = "prpl-yahoo" match = re.match(r"^ymsgr:([^?]*)(\?([^&]*)(&(.*))?)", uri) @@ -355,6 +380,8 @@ sip(uri) elif type == "xmpp": xmpp(uri) + elif type == "gtalk": + gtalk(uri) elif type == "ymsgr": ymsgr(uri) else: diff -r 6eecd6ba2862 -r ae544623840b libpurple/server.c --- a/libpurple/server.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/server.c Fri Jan 02 19:27:02 2009 +0000 @@ -804,7 +804,7 @@ { PurpleAccount *account; char buf2[BUF_LONG]; - struct chat_invite_data *cid = g_new0(struct chat_invite_data, 1); + struct chat_invite_data *cid; int plugin_return; account = purple_connection_get_account(gc); @@ -817,6 +817,8 @@ } } + cid = g_new0(struct chat_invite_data, 1); + plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( purple_conversations_get_handle(), "chat-invited", account, who, name, message, data)); diff -r 6eecd6ba2862 -r ae544623840b libpurple/util.c --- a/libpurple/util.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/util.c Fri Jan 02 19:27:02 2009 +0000 @@ -1676,20 +1676,18 @@ size = "xx-small"; break; case 2: - size = "x-small"; + size = "small"; break; case 3: - size = "small"; + size = "medium"; break; case 4: - size = "medium"; + size = "large"; break; case 5: - size = "large"; + size = "x-large"; break; case 6: - size = "x-large"; - break; case 7: size = "xx-large"; break; diff -r 6eecd6ba2862 -r ae544623840b libpurple/value.c --- a/libpurple/value.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/value.c Fri Jan 02 19:27:02 2009 +0000 @@ -320,6 +320,7 @@ purple_value_set_string(PurpleValue *value, const char *data) { g_return_if_fail(value != NULL); + g_return_if_fail(data == NULL || g_utf8_validate(data, -1, NULL)); g_free(value->data.string_data); value->data.string_data = g_strdup(data); diff -r 6eecd6ba2862 -r ae544623840b libpurple/win32/libc_interface.c --- a/libpurple/win32/libc_interface.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/win32/libc_interface.c Fri Jan 02 19:27:02 2009 +0000 @@ -31,13 +31,7 @@ #include "config.h" #include "debug.h" #include "libc_internal.h" -#if GLIB_CHECK_VERSION(2,6,0) -# include -#else -#define g_remove remove -#define g_rename rename -#define g_stat stat -#endif +#include #ifdef ENABLE_NLS # include @@ -58,6 +52,9 @@ # define dngettext(Domain, Singular, Plural, Number) ((Number == 1) ? ((const char *)Singular) : ((const char *)Plural)) #endif +#ifndef S_ISDIR +# define S_ISDIR(m) (((m)&S_IFDIR)==S_IFDIR) +#endif static char errbuf[1024]; diff -r 6eecd6ba2862 -r ae544623840b libpurple/xmlnode.c --- a/libpurple/xmlnode.c Mon Dec 22 19:40:05 2008 +0000 +++ b/libpurple/xmlnode.c Fri Jan 02 19:27:02 2009 +0000 @@ -662,7 +662,7 @@ vsnprintf(errmsg, sizeof(errmsg), msg, args); va_end(args); - purple_debug_error("xmlnode", "Error parsing xml file: %s\n", errmsg); + purple_debug_error("xmlnode", "Error parsing xml file: %s", errmsg); } static xmlSAXHandler xmlnode_parser_libxml = { diff -r 6eecd6ba2862 -r ae544623840b pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Mon Dec 22 19:40:05 2008 +0000 +++ b/pidgin/gtkaccount.c Fri Jan 02 19:27:02 2009 +0000 @@ -286,25 +286,27 @@ screenname_nofocus_cb(GtkWidget *widget, GdkEventFocus *event, AccountPrefsDialog *dialog) { GdkColor color = {0, 34952, 35466, 34181}; - GHashTable *table; - const char *label; - - table = dialog->prpl_info->get_account_text_table(NULL); - label = g_hash_table_lookup(table, "login_label"); - - if (*gtk_entry_get_text(GTK_ENTRY(widget)) == '\0') { - /* We have to avoid hitting the screenname_changed_cb function - * because it enables buttons we don't want enabled yet ;) - */ - g_signal_handlers_block_by_func(widget, G_CALLBACK(screenname_changed_cb), dialog); - gtk_entry_set_text(GTK_ENTRY(widget), label); - /* Make sure we can hit it again */ - g_signal_handlers_unblock_by_func(widget, G_CALLBACK(screenname_changed_cb), dialog); - gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &color); + GHashTable *table = NULL; + const char *label = NULL; + + if(PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(dialog->prpl_info, get_account_text_table)) { + table = dialog->prpl_info->get_account_text_table(NULL); + label = g_hash_table_lookup(table, "login_label"); + + if (*gtk_entry_get_text(GTK_ENTRY(widget)) == '\0') { + /* We have to avoid hitting the screenname_changed_cb function + * because it enables buttons we don't want enabled yet ;) + */ + g_signal_handlers_block_by_func(widget, G_CALLBACK(screenname_changed_cb), dialog); + gtk_entry_set_text(GTK_ENTRY(widget), label); + /* Make sure we can hit it again */ + g_signal_handlers_unblock_by_func(widget, G_CALLBACK(screenname_changed_cb), dialog); + gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &color); + } + + g_hash_table_destroy(table); } - g_hash_table_destroy(table); - return FALSE; } diff -r 6eecd6ba2862 -r ae544623840b pidgin/gtkblist.c --- a/pidgin/gtkblist.c Mon Dec 22 19:40:05 2008 +0000 +++ b/pidgin/gtkblist.c Fri Jan 02 19:27:02 2009 +0000 @@ -602,7 +602,7 @@ break; case PURPLE_BLIST_GROUP_NODE: dest = purple_find_group(arg2); - if (dest != NULL && strcmp(arg2, ((PurpleGroup*) node)->name)) { + if (dest != NULL && purple_utf8_strcasecmp(arg2, ((PurpleGroup*) node)->name)) { pidgin_dialogs_merge_groups((PurpleGroup*) node, arg2); } else purple_blist_rename_group((PurpleGroup*)node, arg2); @@ -7668,6 +7668,7 @@ GtkAccelGroup *accel_group = NULL; GList *l = NULL, *accounts = NULL; gboolean disabled_accounts = FALSE; + gboolean enabled_accounts = FALSE; if (accountmenu == NULL) return; @@ -7721,10 +7722,16 @@ G_CALLBACK(enable_account_cb), account); gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); gtk_widget_show(menuitem); + } else { + enabled_accounts = TRUE; } } + if (!enabled_accounts) + return; + pidgin_separator(accountmenu); + accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu)); for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) { char *buf = NULL; @@ -7736,67 +7743,63 @@ PurplePlugin *plugin = NULL; account = accounts->data; - accel_group = gtk_menu_get_accel_group(GTK_MENU(accountmenu)); - - if(purple_account_get_enabled(account, PIDGIN_UI)) { - buf = g_strconcat(purple_account_get_username(account), " (", - purple_account_get_protocol_name(account), ")", NULL); - menuitem = gtk_image_menu_item_new_with_label(buf); - accel_path_buf = g_strconcat(N_("/Accounts/"), buf, NULL); - g_free(buf); - pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); - if (pixbuf != NULL) - { - if (!purple_account_is_connected(account)) - gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, - 0.0, FALSE); - image = gtk_image_new_from_pixbuf(pixbuf); - g_object_unref(G_OBJECT(pixbuf)); - gtk_widget_show(image); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); - } - gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem); + + if (!purple_account_get_enabled(account, PIDGIN_UI)) + continue; + + buf = g_strconcat(purple_account_get_username(account), " (", + purple_account_get_protocol_name(account), ")", NULL); + menuitem = gtk_image_menu_item_new_with_label(buf); + accel_path_buf = g_strconcat(N_("/Accounts/"), buf, NULL); + g_free(buf); + pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + if (pixbuf != NULL) { + if (!purple_account_is_connected(account)) + gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, + 0.0, FALSE); + image = gtk_image_new_from_pixbuf(pixbuf); + g_object_unref(G_OBJECT(pixbuf)); + gtk_widget_show(image); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); + } + gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem); + gtk_widget_show(menuitem); + + submenu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); + gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf); + g_free(accel_path_buf); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_widget_show(submenu); + + + menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account")); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(modify_account_cb), account); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_show(menuitem); + + pidgin_separator(submenu); + + gc = purple_account_get_connection(account); + plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL; + if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) { + build_plugin_actions(submenu, plugin, gc); + } else { + menuitem = gtk_menu_item_new_with_label(_("No actions available")); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_set_sensitive(menuitem, FALSE); gtk_widget_show(menuitem); - - submenu = gtk_menu_new(); - gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); - gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path_buf); - g_free(accel_path_buf); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - gtk_widget_show(submenu); - - - menuitem = gtk_menu_item_new_with_mnemonic(_("_Edit Account")); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(modify_account_cb), account); - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_show(menuitem); - - pidgin_separator(submenu); - - gc = purple_account_get_connection(account); - plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL; - if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) { - build_plugin_actions(submenu, plugin, gc); - } else { - menuitem = gtk_menu_item_new_with_label(_("No actions available")); - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_set_sensitive(menuitem, FALSE); - gtk_widget_show(menuitem); - } - - pidgin_separator(submenu); - - menuitem = gtk_menu_item_new_with_mnemonic(_("_Disable")); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(disable_account_cb), account); - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); - gtk_widget_show(menuitem); - } else { - disabled_accounts = TRUE; } - } - + + pidgin_separator(submenu); + + menuitem = gtk_menu_item_new_with_mnemonic(_("_Disable")); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(disable_account_cb), account); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_show(menuitem); + } } static GList *plugin_submenus = NULL; diff -r 6eecd6ba2862 -r ae544623840b pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Mon Dec 22 19:40:05 2008 +0000 +++ b/pidgin/gtkdialogs.c Fri Jan 02 19:27:02 2009 +0000 @@ -100,6 +100,7 @@ /* Order: Alphabetical by Last Name */ static const struct developer patch_writers[] = { + {"Paul Aurich", NULL, NULL }, {"Marcus 'malu' Lundblad", NULL, NULL}, {"Dennis 'EvilDennisR' Ristuccia", N_("Senior Contributor/QA"), NULL}, {"Peter 'Fmoo' Ruibal", NULL, NULL}, diff -r 6eecd6ba2862 -r ae544623840b pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Mon Dec 22 19:40:05 2008 +0000 +++ b/pidgin/gtkimhtml.c Fri Jan 02 19:27:02 2009 +0000 @@ -3117,15 +3117,15 @@ else if (g_ascii_strcasecmp(size, "smaller") == 0 || g_ascii_strcasecmp(size, "x-small") == 0) font->size = 2; - else if (g_ascii_strcasecmp(size, "larger") == 0 - || g_ascii_strcasecmp(size, "medium") == 0) + else if (g_ascii_strcasecmp(size, "medium") == 0) + font->size = 3; + else if (g_ascii_strcasecmp(size, "large") == 0 + || g_ascii_strcasecmp(size, "larger") == 0) font->size = 4; - else if (g_ascii_strcasecmp(size, "large") == 0) + else if (g_ascii_strcasecmp(size, "x-large") == 0) font->size = 5; - else if (g_ascii_strcasecmp(size, "x-large") == 0) + else if (g_ascii_strcasecmp(size, "xx-large") == 0) font->size = 6; - else if (g_ascii_strcasecmp(size, "xx-large") == 0) - font->size = 7; /* * TODO: Handle other values, like percentages, or diff -r 6eecd6ba2862 -r ae544623840b po/fr.po --- a/po/fr.po Mon Dec 22 19:40:05 2008 +0000 +++ b/po/fr.po Fri Jan 02 19:27:02 2009 +0000 @@ -4964,7 +4964,7 @@ msgstr "Erreur MSN : %s\n" msgid "Other Contacts" -msgstr "AUtres contacts" +msgstr "Autres contacts" msgid "Non-IM Contacts" msgstr "Contacts non instantanés"