# HG changeset patch # User Mark Doliner # Date 1231099855 0 # Node ID 88b963749feacb30f44701b195c87a032bd41647 # Parent 5a435e953bc61cdbde2aba6f335370051f582118# Parent 115a2e9ea8b3e59c44f8396af0b84febb0c8246c merge of '2ec56f8fe4fa8959fcac15d674b339c112802a49' and 'd221fa27ec6a8f0ab246208650e5c26658127ed4' diff -r 5a435e953bc6 -r 88b963749fea AUTHORS --- a/AUTHORS Mon Dec 29 03:49:33 2008 +0000 +++ b/AUTHORS Sun Jan 04 20:10:55 2009 +0000 @@ -35,6 +35,7 @@ Crazy Patch Writers: ------------------- +Paul Aurich Felipe 'shx' Contreras Marcus 'malu' Lundblad Dennis 'EvilDennisR' Ristuccia diff -r 5a435e953bc6 -r 88b963749fea COPYRIGHT --- a/COPYRIGHT Mon Dec 29 03:49:33 2008 +0000 +++ b/COPYRIGHT Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea ChangeLog --- a/ChangeLog Mon Dec 29 03:49:33 2008 +0000 +++ b/ChangeLog Sun Jan 04 20:10:55 2009 +0000 @@ -8,9 +8,20 @@ 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: diff -r 5a435e953bc6 -r 88b963749fea doc/pidgin.1.in --- a/doc/pidgin.1.in Mon Dec 29 03:49:33 2008 +0000 +++ b/doc/pidgin.1.in Sun Jan 04 20:10:55 2009 +0000 @@ -641,6 +641,8 @@ Our crazy patch writers include: .br + Paul Aurich +.br Felipe 'shx' Contreras .br Marcus 'malu' Lundblad diff -r 5a435e953bc6 -r 88b963749fea finch/finch.c --- a/finch/finch.c Mon Dec 29 03:49:33 2008 +0000 +++ b/finch/finch.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea finch/gntdebug.c --- a/finch/gntdebug.c Mon Dec 29 03:49:33 2008 +0000 +++ b/finch/gntdebug.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/core.c --- a/libpurple/core.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/core.c Sun Jan 04 20:10:55 2009 +0000 @@ -137,7 +137,7 @@ * subsystem right away too. */ purple_plugins_init(); - + /* Initialize all static protocols. */ static_proto_init(); @@ -213,12 +213,12 @@ purple_accounts_uninit(); purple_savedstatuses_uninit(); purple_status_uninit(); - purple_prefs_uninit(); purple_sound_uninit(); purple_xfers_uninit(); purple_proxy_uninit(); purple_dnsquery_uninit(); purple_imgstore_uninit(); + purple_network_uninit(); purple_debug_info("main", "Unloading all plugins\n"); purple_plugins_destroy_all(); @@ -243,6 +243,7 @@ #ifdef _WIN32 wpurple_cleanup(); #endif + purple_prefs_uninit(); _core = NULL; } diff -r 5a435e953bc6 -r 88b963749fea libpurple/network.c --- a/libpurple/network.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/network.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/prefs.c --- a/libpurple/prefs.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/prefs.c Sun Jan 04 20:10:55 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 { @@ -711,7 +714,8 @@ name = pref_full_name(pref); - purple_debug_info("prefs", "removing pref %s\n", name); + if (prefs_loaded) + purple_debug_info("prefs", "removing pref %s\n", name); g_hash_table_remove(prefs_hash, name); g_free(name); @@ -1451,5 +1455,9 @@ sync_prefs(); } - purple_prefs_disconnect_by_handle(purple_prefs_get_handle()); + prefs_loaded = FALSE; + purple_prefs_destroy(); + g_hash_table_destroy(prefs_hash); + prefs_hash = NULL; + } diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/bonjour/mdns_win32.c --- a/libpurple/protocols/bonjour/mdns_win32.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sun Jan 04 20:10:55 2009 +0000 @@ -351,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 */ diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/jabber/message.c --- a/libpurple/protocols/jabber/message.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/jabber/message.c Sun Jan 04 20:10:55 2009 +0000 @@ -290,7 +290,7 @@ PurpleBuddy *buddy; PurpleAccount *account; PurpleConversation *c; - char *username, *str; + char *username; /* Delayed buzz MUST NOT be accepted */ if(jm->delayed) @@ -314,7 +314,6 @@ purple_prpl_got_attention(jm->js->gc, username, 0); g_free(username); - g_free(str); } /* used internally by the functions below */ diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/myspace/myspace.c Sun Jan 04 20:10:55 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); } @@ -2731,9 +2729,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; + } } /** @@ -2823,6 +2827,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. @@ -3039,7 +3050,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 5a435e953bc6 -r 88b963749fea libpurple/protocols/myspace/user.c --- a/libpurple/protocols/myspace/user.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/myspace/user.c Sun Jan 04 20:10:55 2009 +0000 @@ -55,10 +55,9 @@ if (!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; } @@ -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. */ diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/myspace/user.h --- a/libpurple/protocols/myspace/user.h Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/myspace/user.h Sun Jan 04 20:10:55 2009 +0000 @@ -47,6 +47,7 @@ typedef void (*MSIM_USER_LOOKUP_CB)(MsimSession *session, const MsimMessage *userinfo, gpointer data); 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 5a435e953bc6 -r 88b963749fea libpurple/protocols/qq/ChangeLog --- a/libpurple/protocols/qq/ChangeLog Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/qq/ChangeLog Sun Jan 04 20:10:55 2009 +0000 @@ -1,3 +1,9 @@ +2008.12.28 - flos + * Fixes #7908 + +2008.12.28 - flos + * References #7908 + 2008.12.25 - flos * References #7821 * Updated authors diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/qq/qq_network.c --- a/libpurple/protocols/qq/qq_network.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/qq/qq_network.c Sun Jan 04 20:10:55 2009 +0000 @@ -174,14 +174,16 @@ * Please conside tcp_pending and udp_pending */ gboolean qq_connect_later(gpointer data) { - PurpleConnection *gc = (PurpleConnection *) data; - qq_data *qd; - char *server; + PurpleConnection *gc; + char *tmp_server; int port; gchar **segments; + qq_data *qd; + gc = (PurpleConnection *) data; g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, FALSE); qd = (qq_data *) gc->proto_data; + tmp_server = NULL; if (qd->check_watcher > 0) { purple_timeout_remove(qd->check_watcher); @@ -191,9 +193,11 @@ if (qd->redirect_ip.s_addr != 0) { /* redirect to new server */ - server = g_strdup_printf("%s:%d", inet_ntoa(qd->redirect_ip), qd->redirect_port); - qd->servers = g_list_append(qd->servers, server); - qd->curr_server = server; + tmp_server = g_strdup_printf("%s:%d", inet_ntoa(qd->redirect_ip), qd->redirect_port); + qd->servers = g_list_append(qd->servers, tmp_server); + + qd->curr_server = tmp_server; + tmp_server = NULL; qd->redirect_ip.s_addr = 0; qd->redirect_port = 0; @@ -211,21 +215,30 @@ } segments = g_strsplit_set(qd->curr_server, ":", 0); - server = g_strdup(segments[0]); - port = atoi(segments[1]); - if (port <= 0) { - purple_debug_info("QQ", "Port not define in %s\n", qd->curr_server); + tmp_server = g_strdup(segments[0]); + if (NULL != segments[1]) { + port = atoi(segments[1]); + if (port <= 0) { + purple_debug_info("QQ", "Port not define in %s, use default.\n", qd->curr_server); + port = QQ_DEFAULT_PORT; + } + } else { + purple_debug_info("QQ", "Error splitting server string: %s, setting port to default.\n", qd->curr_server); port = QQ_DEFAULT_PORT; } + g_strfreev(segments); qd->connect_retry--; - if ( !connect_to_server(gc, server, port) ) { + if ( !connect_to_server(gc, tmp_server, port) ) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect.")); } + g_free(tmp_server); + tmp_server = NULL; + qd->check_watcher = purple_timeout_add_seconds(QQ_CONNECT_CHECK, connect_check, gc); return FALSE; /* timeout callback stops */ } diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/simple/simple.c --- a/libpurple/protocols/simple/simple.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/simple/simple.c Sun Jan 04 20:10:55 2009 +0000 @@ -1942,8 +1942,7 @@ if (userserver[1] == NULL || userserver[1][0] == '\0') { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, - _("Unable to connect to server. Please enter the " - "address of the server you wish to connect to.")); + _("SIP connect server not specified")); return; } diff -r 5a435e953bc6 -r 88b963749fea libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/proxy.c --- a/libpurple/proxy.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/proxy.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/purple-url-handler --- a/libpurple/purple-url-handler Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/purple-url-handler Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/value.c --- a/libpurple/value.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/value.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea libpurple/win32/libc_interface.c --- a/libpurple/win32/libc_interface.c Mon Dec 29 03:49:33 2008 +0000 +++ b/libpurple/win32/libc_interface.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Mon Dec 29 03:49:33 2008 +0000 +++ b/pidgin/gtkaccount.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea pidgin/gtkblist.c --- a/pidgin/gtkblist.c Mon Dec 29 03:49:33 2008 +0000 +++ b/pidgin/gtkblist.c Sun Jan 04 20:10:55 2009 +0000 @@ -7655,6 +7655,7 @@ GtkAccelGroup *accel_group = NULL; GList *l = NULL, *accounts = NULL; gboolean disabled_accounts = FALSE; + gboolean enabled_accounts = FALSE; if (accountmenu == NULL) return; @@ -7708,10 +7709,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; @@ -7723,67 +7730,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 5a435e953bc6 -r 88b963749fea pidgin/gtkdialogs.c --- a/pidgin/gtkdialogs.c Mon Dec 29 03:49:33 2008 +0000 +++ b/pidgin/gtkdialogs.c Sun Jan 04 20:10:55 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 5a435e953bc6 -r 88b963749fea po/de.po --- a/po/de.po Mon Dec 29 03:49:33 2008 +0000 +++ b/po/de.po Sun Jan 04 20:10:55 2009 +0000 @@ -11,15 +11,15 @@ msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-12-18 23:08+0100\n" -"PO-Revision-Date: 2008-12-18 20:11+0100\n" -"Last-Translator: Bjoern Voigt \n" -"Language-Team: Deutsch \n" +"POT-Creation-Date: 2009-01-04 12:29+0100\n" +"PO-Revision-Date: 2009-01-04 12:29+0100\n" +"Last-Translator: Jochen Kemnade \n" +"Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: KBabel 1.11.4\n" +"X-Generator: Lokalize 0.2\n" #. Translators may want to transliterate the name. #. It is not to be translated. @@ -4168,6 +4168,9 @@ msgid "Re-initializing Stream" msgstr "Initialisiere Stream nochmal" +msgid "Server doesn't support blocking" +msgstr "Server unterstützt kein Blockieren" + msgid "Not Authorized" msgstr "Nicht autorisiert" @@ -9263,6 +9266,9 @@ msgid "SIP usernames may not contain whitespaces or @ symbols" msgstr "SIP-Benutzernamen dürfen keine Leerzeichen oder @-Symbole enthalten" +msgid "SIP connect server not specified" +msgstr "SIP-Verbindungsserver nicht angegeben" + #. *< type #. *< ui_requirement #. *< flags