From: <rl...@us...> - 2006-06-19 17:52:55
|
Revision: 16293 Author: rlaager Date: 2006-06-19 10:52:52 -0700 (Mon, 19 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16293&view=rev Log Message: ----------- Merging the GAIM_CMD_P_VERYHIGH -> GAIM_CMD_P_VERY_HIGH change Modified Paths: -------------- branches/v2_0_0/plugins/ChangeLog.API branches/v2_0_0/src/cmds.h Modified: branches/v2_0_0/plugins/ChangeLog.API =================================================================== --- branches/v2_0_0/plugins/ChangeLog.API 2006-06-19 17:49:43 UTC (rev 16292) +++ branches/v2_0_0/plugins/ChangeLog.API 2006-06-19 17:52:52 UTC (rev 16293) @@ -114,6 +114,7 @@ gaim_proxy_connect() and gaim_network_listen*(). * gaim_gtk_create_imhtml(): Added sw_ret() parameter * gaim_account_get_log(): Added create parameter + * GAIM_CMD_P_VERYHIGH is now GAIM_CMD_P_VERY_HIGH Removed: * gaim_gtk_sound_{get,set}_mute() (replaced by the /gaim/gtk/sound/mute Modified: branches/v2_0_0/src/cmds.h =================================================================== --- branches/v2_0_0/src/cmds.h 2006-06-19 17:49:43 UTC (rev 16292) +++ branches/v2_0_0/src/cmds.h 2006-06-19 17:52:52 UTC (rev 16293) @@ -56,14 +56,14 @@ typedef guint GaimCmdId; enum _GaimCmdPriority { - GAIM_CMD_P_VERY_LOW = -1000, - GAIM_CMD_P_LOW = 0, - GAIM_CMD_P_DEFAULT = 1000, - GAIM_CMD_P_PRPL = 2000, - GAIM_CMD_P_PLUGIN = 3000, - GAIM_CMD_P_ALIAS = 4000, - GAIM_CMD_P_HIGH = 5000, - GAIM_CMD_P_VERYHIGH = 6000, + GAIM_CMD_P_VERY_LOW = -1000, + GAIM_CMD_P_LOW = 0, + GAIM_CMD_P_DEFAULT = 1000, + GAIM_CMD_P_PRPL = 2000, + GAIM_CMD_P_PLUGIN = 3000, + GAIM_CMD_P_ALIAS = 4000, + GAIM_CMD_P_HIGH = 5000, + GAIM_CMD_P_VERY_HIGH = 6000, }; enum _GaimCmdFlag { @@ -111,11 +111,11 @@ * @param f These are the flags. You need to at least pass one of GAIM_CMD_FLAG_IM or * GAIM_CMD_FLAG_CHAT (can may pass both) in order for the command to ever actually * be called. - * @param prpl_id This is the prpl's id string. This is only meaningful is the proper flag is set. + * @param prpl_id This is the prpl's id string. This is only meaningful if the proper flag is set. * @param func This is the function to call when someone enters this command. * @param helpstr This is a whitespace sensitive, UTF-8, HTML string describing how to use the command. * The preferred format of this string shall be the commands name, followed by a space - * and any arguments it accpets (if it takes any arguments, otherwise no space), follow + * and any arguments it accepts (if it takes any arguments, otherwise no space), followed * by a colon, two spaces, and a description of the command in sentence form. No slash * before the command name. * @param data User defined data to pass to the GaimCmdFunc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-06-20 08:19:02
|
Revision: 16296 Author: thekingant Date: 2006-06-20 01:18:55 -0700 (Tue, 20 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16296&view=rev Log Message: ----------- Backport revision 16295 from HEAD to the v2_0_0 branch of Subversion. Original commit message: Hopefully improve the typing notification code so it's a lot easier to understand. This also creates a distinction between the signals emitted when receiving GAIM_TYPED and GAIM_NOT_TYPING messages (by adding a gaim-typed signal). And the gaim-not-typing signal should work in all cases. Most of this is stuff I changed last week during work, thanks to Meebo ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16295&view=rev Modified Paths: -------------- branches/v2_0_0/plugins/perl/common/Conversation.xs branches/v2_0_0/plugins/perl/common/Server.xs branches/v2_0_0/src/conversation.c branches/v2_0_0/src/conversation.h branches/v2_0_0/src/gtkconv.c branches/v2_0_0/src/gtkpounce.c branches/v2_0_0/src/pounce.c branches/v2_0_0/src/pounce.h branches/v2_0_0/src/protocols/jabber/message.c branches/v2_0_0/src/protocols/jabber/message.h branches/v2_0_0/src/protocols/msn/msn.c branches/v2_0_0/src/protocols/novell/novell.c branches/v2_0_0/src/protocols/oscar/oscar.c branches/v2_0_0/src/protocols/sametime/sametime.c branches/v2_0_0/src/protocols/simple/simple.c branches/v2_0_0/src/protocols/yahoo/yahoo.c branches/v2_0_0/src/protocols/zephyr/zephyr.c branches/v2_0_0/src/prpl.h branches/v2_0_0/src/server.c branches/v2_0_0/src/server.h Modified: branches/v2_0_0/plugins/perl/common/Conversation.xs =================================================================== --- branches/v2_0_0/plugins/perl/common/Conversation.xs 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/plugins/perl/common/Conversation.xs 2006-06-20 08:18:55 UTC (rev 16296) @@ -179,15 +179,15 @@ Gaim::Conversation::IM im void -gaim_conv_im_start_type_again_timeout(im) +gaim_conv_im_start_send_typed_timeout(im) Gaim::Conversation::IM im void -gaim_conv_im_stop_type_again_timeout(im) +gaim_conv_im_stop_send_typed_timeout(im) Gaim::Conversation::IM im guint -gaim_conv_im_get_type_again_timeout(im) +gaim_conv_im_get_send_typed_timeout(im) Gaim::Conversation::IM im void Modified: branches/v2_0_0/plugins/perl/common/Server.xs =================================================================== --- branches/v2_0_0/plugins/perl/common/Server.xs 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/plugins/perl/common/Server.xs 2006-06-20 08:18:55 UTC (rev 16296) @@ -200,10 +200,10 @@ Gaim::MessageFlags flags int -serv_send_typing(con, a, b) +serv_send_typing(con, a, state) Gaim::Connection con const char * a - int b + Gaim::TypingState state void serv_set_buddyicon(gc, filename) Modified: branches/v2_0_0/src/conversation.c =================================================================== --- branches/v2_0_0/src/conversation.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/conversation.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -46,39 +46,44 @@ } static gboolean -reset_typing(gpointer data) +reset_typing_cb(gpointer data) { GaimConversation *c = (GaimConversation *)data; GaimConvIm *im; - if (!g_list_find(conversations, c)) - return FALSE; - im = GAIM_CONV_IM(c); gaim_conv_im_set_typing_state(im, GAIM_NOT_TYPING); gaim_conv_im_update_typing(im); gaim_conv_im_stop_typing_timeout(im); + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing-stopped", c); + return FALSE; } static gboolean -send_typed(gpointer data) +send_typed_cb(gpointer data) { GaimConversation *conv = (GaimConversation *)data; GaimConnection *gc; const char *name; g_return_val_if_fail(conv != NULL, FALSE); - + gc = gaim_conversation_get_gc(conv); name = gaim_conversation_get_name(conv); if (gc != NULL && name != NULL) { - gaim_conv_im_set_type_again(GAIM_CONV_IM(conv), TRUE); + /* We set this to 1 so that GAIM_TYPING will be sent + * if the Gaim user types anything else. + */ + gaim_conv_im_set_type_again(GAIM_CONV_IM(conv), 1); serv_send_typing(gc, name, GAIM_TYPED); + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typed", conv); gaim_debug(GAIM_DEBUG_MISC, "conversation", "typed...\n"); } @@ -420,7 +425,7 @@ if (conv->type == GAIM_CONV_TYPE_IM) { gaim_conv_im_stop_typing_timeout(conv->u.im); - gaim_conv_im_stop_type_again_timeout(conv->u.im); + gaim_conv_im_stop_send_typed_timeout(conv->u.im); if (conv->u.im->icon != NULL) gaim_buddy_icon_unref(conv->u.im->icon); @@ -986,9 +991,14 @@ gaim_signal_emit(gaim_conversations_get_handle(), "buddy-typing", im->conv->account, im->conv->name); } - else + else if (state == GAIM_TYPED) { gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typed", im->conv->account, im->conv->name); + } + else if (state == GAIM_NOT_TYPING) + { + gaim_signal_emit(gaim_conversations_get_handle(), "buddy-typing-stopped", im->conv->account, im->conv->name); } } @@ -1016,7 +1026,7 @@ conv = gaim_conv_im_get_conversation(im); name = gaim_conversation_get_name(conv); - im->typing_timeout = gaim_timeout_add(timeout * 1000, reset_typing, conv); + im->typing_timeout = gaim_timeout_add(timeout * 1000, reset_typing_cb, conv); } void @@ -1040,11 +1050,14 @@ } void -gaim_conv_im_set_type_again(GaimConvIm *im, time_t val) +gaim_conv_im_set_type_again(GaimConvIm *im, unsigned int val) { g_return_if_fail(im != NULL); - im->type_again = val; + if (val == 0) + im->type_again = 0; + else + im->type_again = time(NULL) + val; } time_t @@ -1056,32 +1069,32 @@ } void -gaim_conv_im_start_type_again_timeout(GaimConvIm *im) +gaim_conv_im_start_send_typed_timeout(GaimConvIm *im) { g_return_if_fail(im != NULL); - im->type_again_timeout = gaim_timeout_add(SEND_TYPED_TIMEOUT, send_typed, + im->send_typed_timeout = gaim_timeout_add(SEND_TYPED_TIMEOUT, send_typed_cb, gaim_conv_im_get_conversation(im)); } void -gaim_conv_im_stop_type_again_timeout(GaimConvIm *im) +gaim_conv_im_stop_send_typed_timeout(GaimConvIm *im) { g_return_if_fail(im != NULL); - if (im->type_again_timeout == 0) + if (im->send_typed_timeout == 0) return; - gaim_timeout_remove(im->type_again_timeout); - im->type_again_timeout = 0; + gaim_timeout_remove(im->send_typed_timeout); + im->send_typed_timeout = 0; } guint -gaim_conv_im_get_type_again_timeout(const GaimConvIm *im) +gaim_conv_im_get_send_typed_timeout(const GaimConvIm *im) { g_return_val_if_fail(im != NULL, 0); - return im->type_again_timeout; + return im->send_typed_timeout; } void @@ -2090,6 +2103,12 @@ GAIM_SUBTYPE_ACCOUNT), gaim_value_new(GAIM_TYPE_STRING)); + gaim_signal_register(handle, "buddy-typed", + gaim_marshal_VOID__POINTER_POINTER, NULL, 2, + gaim_value_new(GAIM_TYPE_SUBTYPE, + GAIM_SUBTYPE_ACCOUNT), + gaim_value_new(GAIM_TYPE_STRING)); + gaim_signal_register(handle, "buddy-typing-stopped", gaim_marshal_VOID__POINTER_POINTER, NULL, 2, gaim_value_new(GAIM_TYPE_SUBTYPE, Modified: branches/v2_0_0/src/conversation.h =================================================================== --- branches/v2_0_0/src/conversation.h 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/conversation.h 2006-06-20 08:18:55 UTC (rev 16296) @@ -186,7 +186,7 @@ GaimTypingState typing_state; /**< The current typing state. */ guint typing_timeout; /**< The typing timer handle. */ time_t type_again; /**< The type again time. */ - guint type_again_timeout; /**< The type again timer handle. */ + guint send_typed_timeout; /**< The type again timer handle. */ GaimBuddyIcon *icon; /**< The buddy icon. */ }; @@ -666,19 +666,25 @@ guint gaim_conv_im_get_typing_timeout(const GaimConvIm *im); /** - * Sets the IM's time until it should send another typing notification. + * Sets the quiet-time when no GAIM_TYPING messages will be sent. + * Few protocols need this (maybe only MSN). If the user is still + * typing after this quiet-period, then another GAIM_TYPING message + * will be sent. * * @param im The IM. - * @param val The time. + * @param val The number of seconds to wait before allowing another + * GAIM_TYPING message to be sent to the user. Or 0 to + * not send another GAIM_TYPING message. */ -void gaim_conv_im_set_type_again(GaimConvIm *im, time_t val); +void gaim_conv_im_set_type_again(GaimConvIm *im, unsigned int val); /** - * Returns the IM's time until it should send another typing notification. + * Returns the time after which another GAIM_TYPING message should be sent. * * @param im The IM. * - * @return The time. + * @return The time in seconds since the epoch. Or 0 if no additional + * GAIM_TYPING message should be sent. */ time_t gaim_conv_im_get_type_again(const GaimConvIm *im); @@ -687,14 +693,14 @@ * * @param im The IM. */ -void gaim_conv_im_start_type_again_timeout(GaimConvIm *im); +void gaim_conv_im_start_send_typed_timeout(GaimConvIm *im); /** * Stops the IM's type again timeout. * * @param im The IM. */ -void gaim_conv_im_stop_type_again_timeout(GaimConvIm *im); +void gaim_conv_im_stop_send_typed_timeout(GaimConvIm *im); /** * Returns the IM's type again timeout interval. @@ -703,7 +709,7 @@ * * @return The type again timeout interval. */ -guint gaim_conv_im_get_type_again_timeout(const GaimConvIm *im); +guint gaim_conv_im_get_send_typed_timeout(const GaimConvIm *im); /** * Updates the visual typing notification for an IM conversation. Modified: branches/v2_0_0/src/gtkconv.c =================================================================== --- branches/v2_0_0/src/gtkconv.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/gtkconv.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -2168,8 +2168,7 @@ if (gtk_text_iter_is_start(start_pos) && gtk_text_iter_is_end(end_pos)) { /* We deleted all the text, so turn off typing. */ - if (gaim_conv_im_get_type_again_timeout(im)) - gaim_conv_im_stop_type_again_timeout(im); + gaim_conv_im_stop_send_typed_timeout(im); serv_send_typing(gaim_conversation_get_gc(conv), gaim_conversation_get_name(conv), @@ -2913,22 +2912,18 @@ im = GAIM_CONV_IM(conv); - if (gaim_conv_im_get_type_again_timeout(im)) - gaim_conv_im_stop_type_again_timeout(im); + gaim_conv_im_stop_send_typed_timeout(im); + gaim_conv_im_start_send_typed_timeout(im); - gaim_conv_im_start_type_again_timeout(im); - + /* Check if we need to send another GAIM_TYPING message */ if (first || (gaim_conv_im_get_type_again(im) != 0 && - time(NULL) > gaim_conv_im_get_type_again(im))) { - - int timeout = serv_send_typing(gaim_conversation_get_gc(conv), - (char *)gaim_conversation_get_name(conv), - GAIM_TYPING); - - if (timeout) - gaim_conv_im_set_type_again(im, time(NULL) + timeout); - else - gaim_conv_im_set_type_again(im, 0); + time(NULL) > gaim_conv_im_get_type_again(im))) + { + unsigned int timeout; + timeout = serv_send_typing(gaim_conversation_get_gc(conv), + gaim_conversation_get_name(conv), + GAIM_TYPING); + gaim_conv_im_set_type_again(im, timeout); } } Modified: branches/v2_0_0/src/gtkpounce.c =================================================================== --- branches/v2_0_0/src/gtkpounce.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/gtkpounce.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -81,6 +81,7 @@ GtkWidget *idle; GtkWidget *idle_return; GtkWidget *typing; + GtkWidget *typed; GtkWidget *stop_typing; GtkWidget *message_recv; @@ -278,6 +279,9 @@ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->typing))) events |= GAIM_POUNCE_TYPING; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->typed))) + events |= GAIM_POUNCE_TYPED; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->stop_typing))) events |= GAIM_POUNCE_TYPING_STOPPED; @@ -564,7 +568,7 @@ /* Create the "Pounce When Buddy..." frame. */ frame = gaim_gtk_make_frame(vbox2, _("Pounce When Buddy...")); - table = gtk_table_new(2, 4, FALSE); + table = gtk_table_new(5, 2, FALSE); gtk_container_add(GTK_CONTAINER(frame), table); gtk_table_set_col_spacings(GTK_TABLE(table), GAIM_HIG_BORDER); gtk_widget_show(table); @@ -583,29 +587,33 @@ gtk_check_button_new_with_mnemonic(_("Is no longer i_dle")); dialog->typing = gtk_check_button_new_with_mnemonic(_("Starts _typing")); + dialog->typed = + gtk_check_button_new_with_mnemonic(_("P_auses while typing")); dialog->stop_typing = gtk_check_button_new_with_mnemonic(_("Stops t_yping")); dialog->message_recv = gtk_check_button_new_with_mnemonic(_("Sends a _message")); - gtk_table_attach(GTK_TABLE(table), dialog->signon, 0, 1, 0, 1, + gtk_table_attach(GTK_TABLE(table), dialog->message_recv, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->signoff, 1, 2, 0, 1, + gtk_table_attach(GTK_TABLE(table), dialog->signon, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->away, 0, 1, 1, 2, + gtk_table_attach(GTK_TABLE(table), dialog->signoff, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->away_return, 1, 2, 1, 2, + gtk_table_attach(GTK_TABLE(table), dialog->away, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->idle, 0, 1, 2, 3, + gtk_table_attach(GTK_TABLE(table), dialog->away_return, 0, 1, 4, 5, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->idle_return, 1, 2, 2, 3, + gtk_table_attach(GTK_TABLE(table), dialog->idle, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->typing, 0, 1, 3, 4, + gtk_table_attach(GTK_TABLE(table), dialog->idle_return, 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->stop_typing, 1, 2, 3, 4, + gtk_table_attach(GTK_TABLE(table), dialog->typing, 1, 2, 2, 3, GTK_FILL, 0, 0, 0); - gtk_table_attach(GTK_TABLE(table), dialog->message_recv, 0, 1, 4, 5, + gtk_table_attach(GTK_TABLE(table), dialog->typed, 1, 2, 3, 4, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), dialog->stop_typing, 1, 2, 4, 5, + GTK_FILL, 0, 0, 0); gtk_widget_show(dialog->signon); gtk_widget_show(dialog->signoff); @@ -614,6 +622,7 @@ gtk_widget_show(dialog->idle); gtk_widget_show(dialog->idle_return); gtk_widget_show(dialog->typing); + gtk_widget_show(dialog->typed); gtk_widget_show(dialog->stop_typing); gtk_widget_show(dialog->message_recv); @@ -845,6 +854,8 @@ (events & GAIM_POUNCE_IDLE_RETURN)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->typing), (events & GAIM_POUNCE_TYPING)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->typed), + (events & GAIM_POUNCE_TYPED)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->stop_typing), (events & GAIM_POUNCE_TYPING_STOPPED)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->message_recv), @@ -1429,6 +1440,8 @@ tmp = g_strdup_printf( (events & GAIM_POUNCE_TYPING) ? _("%s has started typing to you (%s)") : + (events & GAIM_POUNCE_TYPED) ? + _("%s has paused while typing to you (%s)") : (events & GAIM_POUNCE_SIGNON) ? _("%s has signed on (%s)") : (events & GAIM_POUNCE_IDLE_RETURN) ? Modified: branches/v2_0_0/src/pounce.c =================================================================== --- branches/v2_0_0/src/pounce.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/pounce.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -206,6 +206,8 @@ add_event_to_xmlnode(child, "return-from-idle"); if (events & GAIM_POUNCE_TYPING) add_event_to_xmlnode(child, "start-typing"); + if (events & GAIM_POUNCE_TYPED) + add_event_to_xmlnode(child, "typed"); if (events & GAIM_POUNCE_TYPING_STOPPED) add_event_to_xmlnode(child, "stop-typing"); if (events & GAIM_POUNCE_MESSAGE_RECEIVED) @@ -411,7 +413,7 @@ else if (!strcmp(element_name, "option")) { if (!strcmp(data->option_type, "on-away")) data->options |= GAIM_POUNCE_OPTION_AWAY; - + g_free(data->option_type); data->option_type = NULL; } @@ -430,6 +432,8 @@ data->events |= GAIM_POUNCE_IDLE_RETURN; else if (!strcmp(data->event_type, "start-typing")) data->events |= GAIM_POUNCE_TYPING; + else if (!strcmp(data->event_type, "typed")) + data->events |= GAIM_POUNCE_TYPED; else if (!strcmp(data->event_type, "stop-typing")) data->events |= GAIM_POUNCE_TYPING_STOPPED; else if (!strcmp(data->event_type, "message-received")) @@ -1059,10 +1063,16 @@ conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, name, account); if (conv != NULL) { + GaimTypingState state; GaimPounceEvent event; - event = (gaim_conv_im_get_typing_state(GAIM_CONV_IM(conv)) == GAIM_TYPING - ? GAIM_POUNCE_TYPING : GAIM_POUNCE_TYPING_STOPPED); + state = gaim_conv_im_get_typing_state(GAIM_CONV_IM(conv)); + if (state == GAIM_TYPED) + event = GAIM_POUNCE_TYPED; + else if (state == GAIM_NOT_TYPING) + event = GAIM_POUNCE_TYPING_STOPPED; + else + event = GAIM_POUNCE_TYPING; gaim_pounce_execute(account, name, event); } @@ -1105,6 +1115,8 @@ gaim_signal_connect(conv_handle, "buddy-typing", handle, GAIM_CALLBACK(buddy_typing_cb), NULL); + gaim_signal_connect(conv_handle, "buddy-typed", + handle, GAIM_CALLBACK(buddy_typing_cb), NULL); gaim_signal_connect(conv_handle, "buddy-typing-stopped", handle, GAIM_CALLBACK(buddy_typing_cb), NULL); Modified: branches/v2_0_0/src/pounce.h =================================================================== --- branches/v2_0_0/src/pounce.h 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/pounce.h 2006-06-20 08:18:55 UTC (rev 16296) @@ -35,16 +35,17 @@ */ typedef enum { - GAIM_POUNCE_NONE = 0x00, /**< No events. */ - GAIM_POUNCE_SIGNON = 0x01, /**< The buddy signed on. */ - GAIM_POUNCE_SIGNOFF = 0x02, /**< The buddy signed off. */ - GAIM_POUNCE_AWAY = 0x04, /**< The buddy went away. */ - GAIM_POUNCE_AWAY_RETURN = 0x08, /**< The buddy returned from away. */ - GAIM_POUNCE_IDLE = 0x10, /**< The buddy became idle. */ - GAIM_POUNCE_IDLE_RETURN = 0x20, /**< The buddy is no longer idle. */ - GAIM_POUNCE_TYPING = 0x40, /**< The buddy started typing. */ - GAIM_POUNCE_TYPING_STOPPED = 0x80, /**< The buddy stopped typing. */ - GAIM_POUNCE_MESSAGE_RECEIVED = 0x100 /**< The buddy sent a message */ + GAIM_POUNCE_NONE = 0x000, /**< No events. */ + GAIM_POUNCE_SIGNON = 0x001, /**< The buddy signed on. */ + GAIM_POUNCE_SIGNOFF = 0x002, /**< The buddy signed off. */ + GAIM_POUNCE_AWAY = 0x004, /**< The buddy went away. */ + GAIM_POUNCE_AWAY_RETURN = 0x008, /**< The buddy returned from away. */ + GAIM_POUNCE_IDLE = 0x010, /**< The buddy became idle. */ + GAIM_POUNCE_IDLE_RETURN = 0x020, /**< The buddy is no longer idle. */ + GAIM_POUNCE_TYPING = 0x040, /**< The buddy started typing. */ + GAIM_POUNCE_TYPED = 0x080, /**< The buddy has entered text. */ + GAIM_POUNCE_TYPING_STOPPED = 0x100, /**< The buddy stopped typing. */ + GAIM_POUNCE_MESSAGE_RECEIVED = 0x200 /**< The buddy sent a message */ } GaimPounceEvent; Modified: branches/v2_0_0/src/protocols/jabber/message.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/message.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/jabber/message.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -589,7 +589,7 @@ return 1; } -int jabber_send_typing(GaimConnection *gc, const char *who, int typing) +unsigned int jabber_send_typing(GaimConnection *gc, const char *who, GaimTypingState state) { JabberMessage *jm; JabberBuddy *jb; @@ -611,9 +611,9 @@ jm->to = g_strdup(who); jm->id = jabber_get_next_id(jm->js); - if(GAIM_TYPING == typing) + if(GAIM_TYPING == state) jm->chat_state = JM_STATE_COMPOSING; - else if(GAIM_TYPED == typing) + else if(GAIM_TYPED == state) jm->chat_state = JM_STATE_PAUSED; else jm->chat_state = JM_STATE_ACTIVE; Modified: branches/v2_0_0/src/protocols/jabber/message.h =================================================================== --- branches/v2_0_0/src/protocols/jabber/message.h 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/jabber/message.h 2006-06-20 08:18:55 UTC (rev 16296) @@ -71,7 +71,7 @@ GaimMessageFlags flags); int jabber_message_send_chat(GaimConnection *gc, int id, const char *message, GaimMessageFlags flags); -int jabber_send_typing(GaimConnection *gc, const char *who, int typing); +unsigned int jabber_send_typing(GaimConnection *gc, const char *who, GaimTypingState state); #endif /* _GAIM_JABBER_MESSAGE_H_ */ Modified: branches/v2_0_0/src/protocols/msn/msn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/msn.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/msn/msn.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -836,8 +836,8 @@ return 1; } -static int -msn_send_typing(GaimConnection *gc, const char *who, int typing) +static unsigned int +msn_send_typing(GaimConnection *gc, const char *who, GaimTypingState state) { GaimAccount *account; MsnSession *session; @@ -847,7 +847,12 @@ account = gaim_connection_get_account(gc); session = gc->proto_data; - if (!typing) + /* + * TODO: I feel like this should be "if (state != GAIM_TYPING)" + * but this is how it was before, and I don't want to break + * anything. --KingAnt + */ + if (state == GAIM_NOT_TYPING) return 0; if (!g_ascii_strcasecmp(who, gaim_account_get_username(account))) Modified: branches/v2_0_0/src/protocols/novell/novell.c =================================================================== --- branches/v2_0_0/src/protocols/novell/novell.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/novell/novell.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -2303,8 +2303,8 @@ return 1; } -static int -novell_send_typing(GaimConnection * gc, const char *name, int typing) +static unsigned int +novell_send_typing(GaimConnection * gc, const char *name, GaimTypingState state) { NMConference *conf = NULL; NMUser *user; @@ -2312,11 +2312,11 @@ NMERR_T rc = NM_OK; if (gc == NULL || name == NULL) - return -1; + return 0; user = gc->proto_data; if (user == NULL) - return -1; + return 0; /* Need to get the DN for the buddy so we can look up the convo */ dn = nm_lookup_dn(user, name); @@ -2327,7 +2327,7 @@ if (conf) { rc = nm_send_typing(user, conf, - ((typing == GAIM_TYPING) ? TRUE : FALSE), NULL); + ((state == GAIM_TYPING) ? TRUE : FALSE), NULL); _check_for_disconnect(user, rc); } Modified: branches/v2_0_0/src/protocols/oscar/oscar.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/oscar/oscar.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -3944,8 +3944,8 @@ flap_connection_send_keepalive(od, conn); } -static int -oscar_send_typing(GaimConnection *gc, const char *name, int typing) +static unsigned int +oscar_send_typing(GaimConnection *gc, const char *name, GaimTypingState state) { OscarData *od; PeerConnection *conn; @@ -3955,7 +3955,7 @@ if ((conn != NULL) && (conn->ready)) { - peer_odc_send_typing(conn, typing); + peer_odc_send_typing(conn, state); } else { /* Don't send if this turkey is in our deny list */ @@ -3964,9 +3964,9 @@ if (!list) { struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, name)); if (bi && bi->typingnot) { - if (typing == GAIM_TYPING) + if (state == GAIM_TYPING) aim_im_sendmtn(od, 0x0001, name, 0x0002); - else if (typing == GAIM_TYPED) + else if (state == GAIM_TYPED) aim_im_sendmtn(od, 0x0001, name, 0x0001); else aim_im_sendmtn(od, 0x0001, name, 0x0000); Modified: branches/v2_0_0/src/protocols/sametime/sametime.c =================================================================== --- branches/v2_0_0/src/protocols/sametime/sametime.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/sametime/sametime.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -3965,14 +3965,14 @@ } -static int mw_prpl_send_typing(GaimConnection *gc, const char *name, - int typing) { +static unsigned int mw_prpl_send_typing(GaimConnection *gc, const char *name, + GaimTypingState state) { struct mwGaimPluginData *pd; struct mwIdBlock who = { (char *) name, NULL }; struct mwConversation *conv; - gpointer t = GINT_TO_POINTER(!! typing); + gpointer t = GINT_TO_POINTER(!! state); g_return_val_if_fail(gc != NULL, 0); pd = gc->proto_data; @@ -3984,7 +3984,7 @@ if(mwConversation_isOpen(conv)) return ! mwConversation_send(conv, mwImSend_TYPING, t); - if(typing) { + if ((state == GAIM_TYPING) || (state == GAIM_TYPED)) { /* let's only open a channel for typing, not for not-typing. Otherwise two users in psychic mode will continually open conversations to each other, never able to get rid of them, as @@ -3996,6 +3996,11 @@ mwConversation_open(conv); } + /* + * TODO: This should probably be "0." When it's set to 1, the Gaim + * core will call serv_send_typing(gc, who, GAIM_TYPING) once + * every second until the Gaim user stops typing. --KingAnt + */ return 1; } Modified: branches/v2_0_0/src/protocols/simple/simple.c =================================================================== --- branches/v2_0_0/src/protocols/simple/simple.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/simple/simple.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -1053,7 +1053,7 @@ send_sip_response(sip->gc, msg, 200, "OK", NULL); } -static int simple_typing(GaimConnection *gc, const char *name, int typing) { +static unsigned int simple_typing(GaimConnection *gc, const char *name, GaimTypingState state) { struct simple_account_data *sip = gc->proto_data; gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" @@ -1065,16 +1065,22 @@ "<refresh>60</refresh>\n" "</isComposing>"; gchar *recv = g_strdup(name); - if(typing == GAIM_TYPING) { + if(state == GAIM_TYPING) { gchar *msg = g_strdup_printf(xml, "active"); simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); g_free(msg); - } else { + } else /* TODO: Only if (state == GAIM_TYPED) ? */ { gchar *msg = g_strdup_printf(xml, "idle"); simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); g_free(msg); } g_free(recv); + /* + * TODO: Is this right? It will cause the core to call + * serv_send_typing(gc, who, GAIM_TYPING) once every second + * until the user stops typing. If that's not desired, + * then return 0 instead. + */ return 1; } Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -3131,12 +3131,12 @@ return ret; } -static int yahoo_send_typing(GaimConnection *gc, const char *who, int typ) +static unsigned int yahoo_send_typing(GaimConnection *gc, const char *who, GaimTypingState state) { struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, gaim_connection_get_display_name(gc), - 14, " ", 13, typ == GAIM_TYPING ? "1" : "0", + 14, " ", 13, state == GAIM_TYPING ? "1" : "0", 5, who, 1002, "1"); yahoo_packet_send_and_free(pkt, yd); Modified: branches/v2_0_0/src/protocols/zephyr/zephyr.c =================================================================== --- branches/v2_0_0/src/protocols/zephyr/zephyr.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/protocols/zephyr/zephyr.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -2450,14 +2450,15 @@ return "zephyr"; } -static int zephyr_send_typing(GaimConnection *gc, const char *who, int typing) { +static unsigned int zephyr_send_typing(GaimConnection *gc, const char *who, GaimTypingState state) { gchar *recipient; zephyr_account *zephyr = gc->proto_data; if (use_tzc(zephyr)) return 0; - if (!typing) + if (state == GAIM_NOT_TYPING) return 0; + /* XXX We probably should care if this fails. Or maybe we don't want to */ if (!who) { gaim_debug_info("zephyr", "who is null\n"); @@ -2476,6 +2477,12 @@ gaim_debug_info("zephyr","about to send typing notification to %s\n",recipient); zephyr_send_message(zephyr,"MESSAGE","PERSONAL",recipient,"","","PING"); gaim_debug_info("zephyr","sent typing notification\n"); + + /* + * TODO: Is this correct? It means we will call + * serv_send_typing(gc, who, GAIM_TYPING) once every 15 seconds + * until the Gaim user stops typing. + */ return ZEPHYR_TYPING_SEND_TIMEOUT; } Modified: branches/v2_0_0/src/prpl.h =================================================================== --- branches/v2_0_0/src/prpl.h 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/prpl.h 2006-06-20 08:18:55 UTC (rev 16296) @@ -224,7 +224,7 @@ GaimMessageFlags flags); void (*set_info)(GaimConnection *, const char *info); - int (*send_typing)(GaimConnection *, const char *name, int typing); + unsigned int (*send_typing)(GaimConnection *, const char *name, GaimTypingState state); void (*get_info)(GaimConnection *, const char *who); void (*set_status)(GaimAccount *account, GaimStatus *status); Modified: branches/v2_0_0/src/server.c =================================================================== --- branches/v2_0_0/src/server.c 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/server.c 2006-06-20 08:18:55 UTC (rev 16296) @@ -38,18 +38,16 @@ #define SECS_BEFORE_RESENDING_AUTORESPONSE 600 #define SEX_BEFORE_RESENDING_AUTORESPONSE "Only after you're married" -/* This should return the elapsed time in seconds in which Gaim will not send - * typing notifications. - * if it returns zero, it will not send any more typing notifications - * typing is a flag - TRUE for typing, FALSE for stopped typing */ -int serv_send_typing(GaimConnection *g, const char *name, int typing) { +unsigned int +serv_send_typing(GaimConnection *gc, const char *name, GaimTypingState state) +{ GaimPluginProtocolInfo *prpl_info = NULL; - if (g != NULL && g->prpl != NULL) - prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(g->prpl); + if (gc != NULL && gc->prpl != NULL) + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); - if (g && prpl_info && prpl_info->send_typing) - return prpl_info->send_typing(g, name, typing); + if (prpl_info && prpl_info->send_typing) + return prpl_info->send_typing(gc, name, state); return 0; } @@ -150,8 +148,8 @@ lar->sent = time(NULL); } - if (conv && gaim_conv_im_get_type_again_timeout(GAIM_CONV_IM(conv))) - gaim_conv_im_stop_type_again_timeout(GAIM_CONV_IM(conv)); + if (conv && gaim_conv_im_get_send_typed_timeout(GAIM_CONV_IM(conv))) + gaim_conv_im_stop_send_typed_timeout(GAIM_CONV_IM(conv)); return val; } @@ -593,7 +591,7 @@ else { gaim_signal_emit(gaim_conversations_get_handle(), - "buddy-typing-stopped", gc->account, name); + "buddy-typed", gc->account, name); } } @@ -618,6 +616,11 @@ gaim_conv_im_set_typing_state(im, GAIM_NOT_TYPING); gaim_conv_im_update_typing(im); } + else + { + gaim_signal_emit(gaim_conversations_get_handle(), + "buddy-typing-stopped", gc->account, name); + } gaim_signal_emit(gaim_conversations_get_handle(), "buddy-typing-stopped", gc->account, name); Modified: branches/v2_0_0/src/server.h =================================================================== --- branches/v2_0_0/src/server.h 2006-06-20 08:17:49 UTC (rev 16295) +++ branches/v2_0_0/src/server.h 2006-06-20 08:18:55 UTC (rev 16296) @@ -33,11 +33,27 @@ extern "C" { #endif +/** + * Send a typing message to a given user over a given connection. + * + * TODO: Could probably move this into the conversation API. + * + * @param typing One of GAIM_TYPING, GAIM_TYPED, or GAIM_NOT_TYPING. + * @return A quiet-period, specified in seconds, where Gaim will not + * send any additional typing notification messages. Most + * protocols should return 0, which means that no additional + * GAIM_TYPING messages need to be sent. If this is 5, for + * example, then Gaim will wait five seconds, and if the Gaim + * user is still typing then Gaim will send another GAIM_TYPING + * message. + */ +unsigned int serv_send_typing(GaimConnection *gc, const char *name, GaimTypingState state); + +void serv_move_buddy(GaimBuddy *, GaimGroup *, GaimGroup *); int serv_send_im(GaimConnection *, const char *, const char *, GaimMessageFlags flags); void serv_get_info(GaimConnection *, const char *); void serv_set_info(GaimConnection *, const char *); -int serv_send_typing(GaimConnection *, const char *, int); -void serv_move_buddy(GaimBuddy *, GaimGroup *, GaimGroup *); + void serv_add_permit(GaimConnection *, const char *); void serv_add_deny(GaimConnection *, const char *); void serv_rem_permit(GaimConnection *, const char *); @@ -51,12 +67,31 @@ int serv_chat_send(GaimConnection *, int, const char *, GaimMessageFlags flags); void serv_alias_buddy(GaimBuddy *); void serv_got_alias(GaimConnection *gc, const char *who, const char *alias); + +/** + * Receive a typing message from a remote user. Either GAIM_TYPING + * or GAIM_TYPED. If the user has stopped typing then use + * serv_got_typing_stopped instead. + * + * TODO: Could probably move this into the conversation API. + * + * @param timeout If this is a number greater than 0, then + * Gaim will wait this number of seconds and then + * set this buddy to the GAIM_NOT_TYPING state. This + * is used by protocols that send repeated typing messages + * while the user is composing the message. + */ void serv_got_typing(GaimConnection *gc, const char *name, int timeout, GaimTypingState state); -void serv_set_buddyicon(GaimConnection *gc, const char *filename); + +/** + * TODO: Could probably move this into the conversation API. + */ void serv_got_typing_stopped(GaimConnection *gc, const char *name); + void serv_got_im(GaimConnection *gc, const char *who, const char *msg, GaimMessageFlags flags, time_t mtime); +void serv_set_buddyicon(GaimConnection *gc, const char *filename); void serv_got_chat_invite(GaimConnection *gc, const char *name, const char *who, const char *message, GHashTable *data); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-06-29 08:14:59
|
Revision: 16373 Author: thekingant Date: 2006-06-29 01:14:51 -0700 (Thu, 29 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16373&view=rev Log Message: ----------- Backport SVN revision #16372 from HEAD to v2_0_0 Original commit message: Some comments changes, and: 1. Don't buddy icons in Jabber 2. When clearing your buddy icon in oscar, do it the same way that WinAIM does it ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16372&view=rev Modified Paths: -------------- branches/v2_0_0/src/blist.h branches/v2_0_0/src/protocols/jabber/presence.c branches/v2_0_0/src/protocols/oscar/family_feedbag.c branches/v2_0_0/src/protocols/oscar/family_oservice.c branches/v2_0_0/src/protocols/oscar/oscar.h Modified: branches/v2_0_0/src/blist.h =================================================================== --- branches/v2_0_0/src/blist.h 2006-06-29 08:14:29 UTC (rev 16372) +++ branches/v2_0_0/src/blist.h 2006-06-29 08:14:51 UTC (rev 16373) @@ -288,6 +288,7 @@ /** * Sets the server-sent alias of a buddy in the buddy list. + * PRPLs should call serv_got_alias() instead of this. * * @param buddy The buddy whose alias will be changed. * @param alias The buddy's "official" alias. Modified: branches/v2_0_0/src/protocols/jabber/presence.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/presence.c 2006-06-29 08:14:29 UTC (rev 16372) +++ branches/v2_0_0/src/protocols/jabber/presence.c 2006-06-29 08:14:51 UTC (rev 16373) @@ -256,13 +256,14 @@ char hash[41], *p; int i; - gaim_cipher_digest_region("sha1", (guchar *)data, size, + gaim_cipher_digest_region("sha1", data, size, sizeof(hashval), hashval, NULL); p = hash; for(i=0; i<20; i++, p+=2) snprintf(p, 3, "%02x", hashval[i]); gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash); } + g_free(data); g_free(text); } } Modified: branches/v2_0_0/src/protocols/oscar/family_feedbag.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/family_feedbag.c 2006-06-29 08:14:29 UTC (rev 16372) +++ branches/v2_0_0/src/protocols/oscar/family_feedbag.c 2006-06-29 08:14:51 UTC (rev 16373) @@ -1089,7 +1089,7 @@ * @param iconcsumlen Length of the MD5 checksum given above. Should be 0x10 bytes. * @return Return 0 if no errors, otherwise return the error number. */ -int aim_ssi_seticon(OscarData *od, guint8 *iconsum, guint16 iconsumlen) +int aim_ssi_seticon(OscarData *od, const guint8 *iconsum, guint16 iconsumlen) { struct aim_ssi_item *tmp; guint8 *csumdata; @@ -1099,13 +1099,12 @@ /* Find the ICONINFO item, or add it if it does not exist */ if (!(tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) { - tmp = aim_ssi_itemlist_add(&od->ssi.local, "1", 0x0000, 0x51F4, AIM_SSI_TYPE_ICONINFO, NULL); + tmp = aim_ssi_itemlist_add(&od->ssi.local, "1", 0x0000, 0xFFFF, AIM_SSI_TYPE_ICONINFO, NULL); } /* Need to add the 0x00d5 TLV to the TLV chain */ csumdata = (guint8 *)malloc((iconsumlen+2)*sizeof(guint8)); - csumdata[0] = 0x00; - csumdata[1] = 0x10; + aimutil_put16(&csumdata[0], iconsumlen); memcpy(&csumdata[2], iconsum, iconsumlen); aim_tlvlist_replace_raw(&tmp->data, 0x00d5, (iconsumlen+2) * sizeof(guint8), csumdata); free(csumdata); @@ -1122,23 +1121,17 @@ * Remove a reference to a server stored buddy icon. This will make your * icon stop showing up to other people. * - * @param od The oscar odion. + * Really this function just sets the icon to a dummy value. It's weird... + * but I think the dummy value basically means "I don't have an icon!" + * + * @param od The oscar session. * @return Return 0 if no errors, otherwise return the error number. */ int aim_ssi_delicon(OscarData *od) { - struct aim_ssi_item *tmp; + const guint8 csumdata[] = {0x02, 0x01, 0xd2, 0x04, 0x72}; - if (!od) - return -EINVAL; - - /* Find the ICONINFO item and delete it if it exists*/ - if ((tmp = aim_ssi_itemlist_finditem(od->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) - aim_ssi_itemlist_del(&od->ssi.local, tmp); - - /* Sync our local list with the server list */ - aim_ssi_sync(od); - return 0; + return aim_ssi_seticon(od, csumdata, 5); } /** Modified: branches/v2_0_0/src/protocols/oscar/family_oservice.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/family_oservice.c 2006-06-29 08:14:29 UTC (rev 16372) +++ branches/v2_0_0/src/protocols/oscar/family_oservice.c 2006-06-29 08:14:51 UTC (rev 16373) @@ -1064,6 +1064,11 @@ flags = byte_stream_get8(bs); length = byte_stream_get8(bs); + /* + * A flag of 0x01 could mean "this is the checksum we have for you" + * A flag of 0x40 could mean "I don't have your icon, upload it" + */ + if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) { switch (type) { case 0x0000: Modified: branches/v2_0_0/src/protocols/oscar/oscar.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.h 2006-06-29 08:14:29 UTC (rev 16372) +++ branches/v2_0_0/src/protocols/oscar/oscar.h 2006-06-29 08:14:51 UTC (rev 16373) @@ -1161,7 +1161,7 @@ int aim_ssi_deletelist(OscarData *od); int aim_ssi_setpermdeny(OscarData *od, guint8 permdeny, guint32 vismask); int aim_ssi_setpresence(OscarData *od, guint32 presence); -int aim_ssi_seticon(OscarData *od, guint8 *iconsum, guint16 iconsumlen); +int aim_ssi_seticon(OscarData *od, const guint8 *iconsum, guint16 iconsumlen); int aim_ssi_delicon(OscarData *od); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-06-30 06:58:40
|
Revision: 16378 Author: thekingant Date: 2006-06-29 23:58:38 -0700 (Thu, 29 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16378&view=rev Log Message: ----------- Backport SVN revision #16377 from HEAD to v2_0_0 Original commit message: Fix a crash bug pointed out by Alexander Sashnov: There is another segfault (on today SVN trunk version). Steps for reproduce: 1. Create jabber account with incorrect params, check it for connect on start up; 2. run Gaim again. It will not connect and see error message in bottom of users list; 3. Open 'accounts' dialog and deselect this account..... segfault :-) ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16377&view=rev Modified Paths: -------------- branches/v2_0_0/src/dnssrv.c branches/v2_0_0/src/protocols/jabber/jabber.c Modified: branches/v2_0_0/src/dnssrv.c =================================================================== --- branches/v2_0_0/src/dnssrv.c 2006-06-30 06:58:17 UTC (rev 16377) +++ branches/v2_0_0/src/dnssrv.c 2006-06-30 06:58:38 UTC (rev 16378) @@ -275,6 +275,12 @@ #endif +/* + * TODO: It would be really good if this returned some sort of handle + * that we could use to cancel the DNS query. As it is now, + * each callback has to check to make sure gc is still valid. + * And that is ugly. + */ void gaim_srv_resolve(const char *protocol, const char *transport, const char *domain, GaimSRVCallback cb, gpointer extradata) { char *query = g_strdup_printf("_%s._%s.%s",protocol, transport, domain); struct resdata *rdata; Modified: branches/v2_0_0/src/protocols/jabber/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.c 2006-06-30 06:58:17 UTC (rev 16377) +++ branches/v2_0_0/src/protocols/jabber/jabber.c 2006-06-30 06:58:38 UTC (rev 16378) @@ -481,8 +481,19 @@ static void srv_resolved_cb(GaimSrvResponse *resp, int results, gpointer data) { - JabberStream *js = (JabberStream*)data; + GaimConnection *gc; + JabberStream *js; + gc = data; + if (!g_list_find(gaim_connections_get_all(), gc)) + { + /* This connection has been closed */ + g_free(resp); + return; + } + + js = (JabberStream*)gc->proto_data; + if(results) { jabber_login_connect(js, resp->hostname, resp->port); g_free(resp); @@ -561,7 +572,7 @@ if(connect_server[0]) { jabber_login_connect(js, connect_server, gaim_account_get_int(account, "port", 5222)); } else { - gaim_srv_resolve("xmpp-client", "tcp", js->user->domain, srv_resolved_cb, js); + gaim_srv_resolve("xmpp-client", "tcp", js->user->domain, srv_resolved_cb, gc); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-03 20:39:44
|
Revision: 16415 Author: thekingant Date: 2006-07-03 13:39:41 -0700 (Mon, 03 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16415&view=rev Log Message: ----------- Backport SVN revision #16414 from HEAD to v2_0_0 Original commit message: First stab at trying to fix the MSN http connect method. It still doesn't work, and I'm not sure why, but it gets a lot farther in the signon process now. For those unfamiliar with the issue, the MSN http connect method stopped working after all the non-blocking I/O changes. The http connect method is apparently used by lots of people behind silly firewalls and stuff, and therefore we really shouldn't release Gaim 2.0.0 without it working, because people will complain. The two main problems were 1. The outgoing message queue was removed in favor of buffering all data to one large buffer. This sounds good in theory... but apparently each message sent to and from the server has a "SessionID" in the HTTP header. Every message we send should use the same SessionID as the last packet we received from the server. So basically you can't put two messages into the outgoing buffer at the same time because you don't have the correct SessionID to use for the second message. You have to wait until you get the reply from the server. 2. There were some strange buffer problems with using the wrong variable when trying to combine the header+body into one buffer before sending the message. I also fixed a small memleak or two, added some comments, and tried to clean up the code a little. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16414&view=rev Modified Paths: -------------- branches/v2_0_0/src/connection.c branches/v2_0_0/src/connection.h branches/v2_0_0/src/protocols/msn/httpconn.c branches/v2_0_0/src/protocols/msn/httpconn.h branches/v2_0_0/src/protocols/msn/msn.c Modified: branches/v2_0_0/src/connection.c =================================================================== --- branches/v2_0_0/src/connection.c 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/connection.c 2006-07-03 20:39:41 UTC (rev 16415) @@ -217,12 +217,9 @@ gaim_account_set_connection(account, NULL); - if (gc->password != NULL) - g_free(gc->password); + g_free(gc->password); + g_free(gc->display_name); - if (gc->display_name != NULL) - g_free(gc->display_name); - if (gc->disconnect_timeout) gaim_timeout_remove(gc->disconnect_timeout); Modified: branches/v2_0_0/src/connection.h =================================================================== --- branches/v2_0_0/src/connection.h 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/connection.h 2006-07-03 20:39:41 UTC (rev 16415) @@ -130,12 +130,12 @@ const char *password); /** + * Disconnects and destroys a GaimConnection. + * * This function should only be called by gaim_account_disconnect() - * in account.c. If you're trying to sign on an account, use that + * in account.c. If you're trying to sign off an account, use that * function instead. * - * Disconnects and destroys a GaimConnection. - * * @param gc The gaim connection to destroy. */ void gaim_connection_destroy(GaimConnection *gc); Modified: branches/v2_0_0/src/protocols/msn/httpconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.c 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/protocols/msn/httpconn.c 2006-07-03 20:39:41 UTC (rev 16415) @@ -25,317 +25,242 @@ #include "debug.h" #include "httpconn.h" -static void read_cb(gpointer data, gint source, GaimInputCondition cond); -gboolean msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, - size_t size, char **ret_buf, size_t *ret_size, - gboolean *error); - -MsnHttpConn * -msn_httpconn_new(MsnServConn *servconn) +typedef struct { MsnHttpConn *httpconn; + char *body; + size_t body_len; +} MsnHttpQueueData; - g_return_val_if_fail(servconn != NULL, NULL); +static void +msn_httpconn_process_queue(MsnHttpConn *httpconn) +{ + httpconn->waiting_response = FALSE; - httpconn = g_new0(MsnHttpConn, 1); + if (httpconn->queue != NULL) + { + MsnHttpQueueData *queue_data; - gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); + queue_data = (MsnHttpQueueData *)httpconn->queue->data; - /* TODO: Remove this */ - httpconn->session = servconn->session; + httpconn->queue = g_list_remove(httpconn->queue, queue_data); - httpconn->servconn = servconn; + msn_httpconn_write(queue_data->httpconn, + queue_data->body, + queue_data->body_len); - httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); - httpconn->tx_handler = 0; - - return httpconn; + g_free(queue_data->body); + g_free(queue_data); + } } -void -msn_httpconn_destroy(MsnHttpConn *httpconn) +static gboolean +msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, + size_t size, char **ret_buf, size_t *ret_size, + gboolean *error) { - g_return_if_fail(httpconn != NULL); + const char *s, *c; + char *header, *body; + const char *body_start; + char *tmp; + size_t body_len = 0; + gboolean wasted = FALSE; - gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); + g_return_val_if_fail(httpconn != NULL, FALSE); + g_return_val_if_fail(buf != NULL, FALSE); + g_return_val_if_fail(size > 0, FALSE); + g_return_val_if_fail(ret_buf != NULL, FALSE); + g_return_val_if_fail(ret_size != NULL, FALSE); + g_return_val_if_fail(error != NULL, FALSE); - if (httpconn->connected) - msn_httpconn_disconnect(httpconn); +#if 0 + gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); +#endif - g_free(httpconn->full_session_id); + /* Healthy defaults. */ + body = NULL; - g_free(httpconn->session_id); + *ret_buf = NULL; + *ret_size = 0; + *error = FALSE; - g_free(httpconn->host); + /* First, some tests to see if we have a full block of stuff. */ + if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && + (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && + ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && + (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) + { + *error = TRUE; - gaim_circ_buffer_destroy(httpconn->tx_buf); - if (httpconn->tx_handler > 0) - gaim_input_remove(httpconn->tx_handler); - - g_free(httpconn); -} - -static char * -msn_httpconn_proxy_auth(MsnHttpConn *httpconn) -{ - GaimAccount *account; - GaimProxyInfo *gpi; - const char *username, *password; - char *auth = NULL; - - account = httpconn->session->account; - - if (gaim_account_get_proxy_info(account) == NULL) - gpi = gaim_global_proxy_get_info(); - else - gpi = gaim_account_get_proxy_info(account); - - if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || - gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) - return NULL; - - username = gaim_proxy_info_get_username(gpi); - password = gaim_proxy_info_get_password(gpi); - - if (username != NULL) { - char *tmp; - auth = g_strdup_printf("%s:%s", username, password ? password : ""); - tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); - g_free(auth); - auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); - g_free(tmp); + return FALSE; } - return auth; -} + if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) + { + if ((s = strstr(buf, "\r\n\r\n")) == NULL) + return FALSE; -static void -httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnHttpConn *httpconn = data; - int ret, writelen; + s += 4; - if (httpconn->waiting_response) - return; + if (*s == '\0') + { + *ret_buf = g_strdup(""); + *ret_size = 0; - writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); + msn_httpconn_process_queue(httpconn); - if (writelen == 0) { - httpconn->waiting_response = TRUE; - gaim_input_remove(httpconn->tx_handler); - httpconn->tx_handler = 0; - return; - } + return TRUE; + } - ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); - - if (ret < 0 && errno == EAGAIN) - return; - else if (ret <= 0) { - msn_servconn_got_error(httpconn->servconn, - MSN_SERVCONN_ERROR_WRITE); - return; + buf = s; + size -= (s - buf); } - gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); + if ((s = strstr(buf, "\r\n\r\n")) == NULL) + /* Need to wait for the full HTTP header to arrive */ + return FALSE; - if (ret == writelen) - httpconn_write_cb(data, source, cond); -} + s += 4; /* Skip \r\n */ + header = g_strndup(buf, s - buf); + body_start = s; + body_len = size - (body_start - buf); -static ssize_t -write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) -{ - ssize_t res; /* result of the write operation */ - -#ifdef MSN_DEBUG_HTTP - gaim_debug_misc("msn", "Writing HTTP (header): {%s}\n", header); -#endif - - - if (httpconn->tx_handler == 0 && !httpconn->waiting_response) - res = write(httpconn->fd, data, data_len); - else + if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) { - res = -1; - errno = EAGAIN; - } + int tmp_len; - if (res <= 0 && errno != EAGAIN) - { - msn_servconn_got_error(httpconn->servconn, - MSN_SERVCONN_ERROR_WRITE); - return -1; - } else if (res < 0 || res < data_len) { - if (res < 0) - res = 0; - if (httpconn->tx_handler == 0 && httpconn->fd) - httpconn->tx_handler = gaim_input_add(httpconn->fd, - GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); - gaim_circ_buffer_append(httpconn->tx_buf, data + res, - data_len - res); - } + s += strlen("Content-Length: "); - return res; -} + if ((c = strchr(s, '\r')) == NULL) + { + g_free(header); -static void -msn_httpconn_poll(MsnHttpConn *httpconn) -{ - char *header; - char *auth; - int r; + return FALSE; + } - g_return_if_fail(httpconn != NULL); + tmp = g_strndup(s, c - s); + tmp_len = atoi(tmp); + g_free(tmp); - if (httpconn->waiting_response || - httpconn->tx_handler > 0) - { - return; - } + if (body_len != tmp_len) + { + /* Need to wait for the full packet to arrive */ - /* It is OK if this is buffered because it will only be buffered if - nothing else is in the buffer */ + g_free(header); - auth = msn_httpconn_proxy_auth(httpconn); +#if 0 + gaim_debug_warning("msn", + "body length (%d) != content length (%d)\n", + body_len, tmp_len); +#endif - header = g_strdup_printf( - "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" - "Accept: */*\r\n" - "Accept-Language: en-us\r\n" - "User-Agent: MSMSGS\r\n" - "Host: %s\r\n" - "Proxy-Connection: Keep-Alive\r\n" - "%s" /* Proxy auth */ - "Connection: Keep-Alive\r\n" - "Pragma: no-cache\r\n" - "Content-Type: application/x-msn-messenger\r\n" - "Content-Length: 0\r\n\r\n", - httpconn->host, - httpconn->full_session_id, - httpconn->host, - auth ? auth : ""); - - g_free(auth); - - r = write_raw(httpconn, header, strlen(header)); - - g_free(header); - - if (r >= 0) - { - httpconn->waiting_response = TRUE; - httpconn->dirty = FALSE; + return FALSE; + } } -} -static gboolean -do_poll(gpointer data) -{ - MsnHttpConn *httpconn; + body = g_malloc0(body_len + 1); + memcpy(body, body_start, body_len); - httpconn = data; - - g_return_val_if_fail(httpconn != NULL, TRUE); - -#if 0 - gaim_debug_info("msn", "polling from %s\n", httpconn->session_id); +#ifdef MSN_DEBUG_HTTP + gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", + header); #endif - if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) + /* Now we should be able to process the data. */ + if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) { - gaim_debug_warning("msn", "Attempted HTTP poll before session is established\n"); - return TRUE; - } + char *full_session_id, *gw_ip, *session_action; + char *t, *session_id; + char **elems, **cur, **tokens; - if (httpconn->dirty) - msn_httpconn_poll(httpconn); + full_session_id = gw_ip = session_action = NULL; - return TRUE; -} + s += strlen("X-MSN-Messenger: "); -static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) -{ - MsnHttpConn *httpconn = data; + if ((c = strchr(s, '\r')) == NULL) + { + msn_session_set_error(httpconn->session, + MSN_ERROR_HTTP_MALFORMED, NULL); + gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", + buf); - httpconn->fd = source; + g_free(body); + return FALSE; + } - if (source > 0) - { - httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, - read_cb, data); + tmp = g_strndup(s, c - s); - httpconn->timer = gaim_timeout_add(2000, do_poll, httpconn); + elems = g_strsplit(tmp, "; ", 0); - httpconn->waiting_response = FALSE; - if (httpconn->tx_handler > 0) - gaim_input_remove(httpconn->tx_handler); + for (cur = elems; *cur != NULL; cur++) + { + tokens = g_strsplit(*cur, "=", 2); - httpconn->tx_handler = gaim_input_add(source, - GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); + if (strcmp(tokens[0], "SessionID") == 0) + full_session_id = tokens[1]; + else if (strcmp(tokens[0], "GW-IP") == 0) + gw_ip = tokens[1]; + else if (strcmp(tokens[0], "Session") == 0) + session_action = tokens[1]; + else + g_free(tokens[1]); - httpconn_write_cb(httpconn, source, GAIM_INPUT_WRITE); - } - else - { - gaim_debug_error("msn", "HTTP: Connection error\n"); - msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); - } -} + g_free(tokens[0]); + /* Don't free each of the tokens, only the array. */ + g_free(tokens); + } -gboolean -msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) -{ - int r; + g_strfreev(elems); - g_return_val_if_fail(httpconn != NULL, FALSE); - g_return_val_if_fail(host != NULL, FALSE); - g_return_val_if_fail(port > 0, FALSE); + g_free(tmp); - if (httpconn->connected) - msn_httpconn_disconnect(httpconn); + if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) + wasted = TRUE; - r = gaim_proxy_connect(httpconn->session->account, - "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); + g_free(session_action); - if (r == 0) - { - httpconn->waiting_response = TRUE; - httpconn->connected = TRUE; - } + t = strchr(full_session_id, '.'); + session_id = g_strndup(full_session_id, t - full_session_id); - return httpconn->connected; -} + if (!wasted) + { + g_free(httpconn->full_session_id); + httpconn->full_session_id = full_session_id; -void -msn_httpconn_disconnect(MsnHttpConn *httpconn) -{ - g_return_if_fail(httpconn != NULL); + g_free(httpconn->session_id); + httpconn->session_id = session_id; - if (!httpconn->connected) - return; + g_free(httpconn->host); + httpconn->host = gw_ip; + } + else + { + MsnServConn *servconn; - if (httpconn->timer) - gaim_timeout_remove(httpconn->timer); + /* It's going to die. */ + /* poor thing */ - httpconn->timer = 0; + servconn = httpconn->servconn; - if (httpconn->inpa > 0) - { - gaim_input_remove(httpconn->inpa); - httpconn->inpa = 0; + /* I'll be honest, I don't fully understand all this, but this + * causes crashes, Stu. */ + /* if (servconn != NULL) + servconn->wasted = TRUE; */ + + g_free(full_session_id); + g_free(session_id); + g_free(gw_ip); + } } - close(httpconn->fd); + g_free(header); - g_free(httpconn->rx_buf); - httpconn->rx_buf = NULL; - httpconn->rx_len = 0; + *ret_buf = body; + *ret_size = body_len; - httpconn->connected = FALSE; + msn_httpconn_process_queue(httpconn); - /* msn_servconn_disconnect(httpconn->servconn); */ + return TRUE; } static void @@ -376,7 +301,7 @@ if (!msn_httpconn_parse_data(httpconn, httpconn->rx_buf, httpconn->rx_len, &result_msg, &result_len, &error)) { - /* We must wait for more input, or something went wrong */ + /* Either we must wait for more input, or something went wrong */ if (error) msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_READ); @@ -472,15 +397,169 @@ g_free(old_rx_buf); } +static void +httpconn_write_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnHttpConn *httpconn; + int ret, writelen; + + httpconn = data; + writelen = gaim_circ_buffer_get_max_read(httpconn->tx_buf); + + if (writelen == 0) + { + gaim_input_remove(httpconn->tx_handler); + httpconn->tx_handler = 0; + return; + } + + ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen); + if (ret <= 0) + { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) + /* No worries */ + return; + + /* Error! */ + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); + return; + } + + gaim_circ_buffer_mark_read(httpconn->tx_buf, ret); + + /* TODO: I don't think these 2 lines are needed. Remove them? */ + if (ret == writelen) + httpconn_write_cb(data, source, cond); +} + +static gboolean +write_raw(MsnHttpConn *httpconn, const char *data, size_t data_len) +{ + ssize_t res; /* result of the write operation */ + + if (httpconn->tx_handler == 0) + res = write(httpconn->fd, data, data_len); + else + { + res = -1; + errno = EAGAIN; + } + + if ((res <= 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK))) + { + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_WRITE); + return FALSE; + } + + if (res < 0 || res < data_len) + { + if (res < 0) + res = 0; + if (httpconn->tx_handler == 0 && httpconn->fd) + httpconn->tx_handler = gaim_input_add(httpconn->fd, + GAIM_INPUT_WRITE, httpconn_write_cb, httpconn); + gaim_circ_buffer_append(httpconn->tx_buf, data + res, + data_len - res); + } + + return TRUE; +} + +static char * +msn_httpconn_proxy_auth(MsnHttpConn *httpconn) +{ + GaimAccount *account; + GaimProxyInfo *gpi; + const char *username, *password; + char *auth = NULL; + + account = httpconn->session->account; + + if (gaim_account_get_proxy_info(account) == NULL) + gpi = gaim_global_proxy_get_info(); + else + gpi = gaim_account_get_proxy_info(account); + + if (gpi == NULL || !(gaim_proxy_info_get_type(gpi) == GAIM_PROXY_HTTP || + gaim_proxy_info_get_type(gpi) == GAIM_PROXY_USE_ENVVAR)) + return NULL; + + username = gaim_proxy_info_get_username(gpi); + password = gaim_proxy_info_get_password(gpi); + + if (username != NULL) { + char *tmp; + auth = g_strdup_printf("%s:%s", username, password ? password : ""); + tmp = gaim_base64_encode((const guchar *)auth, strlen(auth)); + g_free(auth); + auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp); + g_free(tmp); + } + + return auth; +} + +static gboolean +msn_httpconn_poll(gpointer data) +{ + MsnHttpConn *httpconn; + char *header; + char *auth; + + data = httpconn; + + g_return_val_if_fail(httpconn != NULL, FALSE); + + if ((httpconn->host == NULL) || (httpconn->full_session_id == NULL)) + { + /* There's no need to poll if the session is not fully established */ + return TRUE; + } + + if (httpconn->waiting_response) + { + /* There's no need to poll if we're already waiting for a response */ + return TRUE; + } + + auth = msn_httpconn_proxy_auth(httpconn); + + header = g_strdup_printf( + "POST http://%s/gateway/gateway.dll?Action=poll&SessionID=%s HTTP/1.1\r\n" + "Accept: */*\r\n" + "Accept-Language: en-us\r\n" + "User-Agent: MSMSGS\r\n" + "Host: %s\r\n" + "Proxy-Connection: Keep-Alive\r\n" + "%s" /* Proxy auth */ + "Connection: Keep-Alive\r\n" + "Pragma: no-cache\r\n" + "Content-Type: application/x-msn-messenger\r\n" + "Content-Length: 0\r\n\r\n", + httpconn->host, + httpconn->full_session_id, + httpconn->host, + auth ? auth : ""); + + g_free(auth); + + if (write_raw(httpconn, header, strlen(header))) + httpconn->waiting_response = TRUE; + + g_free(header); + + return TRUE; +} + ssize_t -msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t size) +msn_httpconn_write(MsnHttpConn *httpconn, const char *body, size_t body_len) { char *params; char *data; + int header_len; char *auth; const char *server_types[] = { "NS", "SB" }; const char *server_type; - ssize_t r; /* result of the write operation */ char *host; MsnServConn *servconn; @@ -488,10 +567,23 @@ g_return_val_if_fail(httpconn != NULL, 0); g_return_val_if_fail(body != NULL, 0); - g_return_val_if_fail(size > 0, 0); + g_return_val_if_fail(body_len > 0, 0); servconn = httpconn->servconn; + if (httpconn->waiting_response) + { + MsnHttpQueueData *queue_data = g_new0(MsnHttpQueueData, 1); + + queue_data->httpconn = httpconn; + queue_data->body = g_memdup(body, body_len); + queue_data->body_len = body_len; + + httpconn->queue = g_list_append(httpconn->queue, queue_data); + + return body_len; + } + server_type = server_types[servconn->type]; if (httpconn->virgin) @@ -532,245 +624,158 @@ "Connection: Keep-Alive\r\n" "Pragma: no-cache\r\n" "Content-Type: application/x-msn-messenger\r\n" - "Content-Length: %d\r\n\r\n" - "%s", + "Content-Length: %d\r\n\r\n", host, params, host, auth ? auth : "", - (int) size, - body ? body : ""); + (int) body_len); - g_free(params); g_free(auth); - r = write_raw(httpconn, data, strlen(data)); + header_len = strlen(data); + data = g_realloc(data, header_len + body_len); + memcpy(data + header_len, body, body_len); + if (write_raw(httpconn, data, header_len + body_len)) + httpconn->waiting_response = TRUE; + g_free(data); - if (r >= 0) - { - httpconn->waiting_response = TRUE; - httpconn->dirty = FALSE; - } - - return r; + return body_len; } -gboolean -msn_httpconn_parse_data(MsnHttpConn *httpconn, const char *buf, - size_t size, char **ret_buf, size_t *ret_size, - gboolean *error) +MsnHttpConn * +msn_httpconn_new(MsnServConn *servconn) { - const char *s, *c; - char *header, *body; - const char *body_start; - char *tmp; - size_t body_len = 0; - gboolean wasted = FALSE; + MsnHttpConn *httpconn; - g_return_val_if_fail(httpconn != NULL, FALSE); - g_return_val_if_fail(buf != NULL, FALSE); - g_return_val_if_fail(size > 0, FALSE); - g_return_val_if_fail(ret_buf != NULL, FALSE); - g_return_val_if_fail(ret_size != NULL, FALSE); - g_return_val_if_fail(error != NULL, FALSE); + g_return_val_if_fail(servconn != NULL, NULL); -#if 0 - gaim_debug_info("msn", "HTTP: parsing data {%s}\n", buf); -#endif + httpconn = g_new0(MsnHttpConn, 1); - httpconn->waiting_response = FALSE; + gaim_debug_info("msn", "new httpconn (%p)\n", httpconn); - /* Healthy defaults. */ - body = NULL; + /* TODO: Remove this */ + httpconn->session = servconn->session; - *ret_buf = NULL; - *ret_size = 0; - *error = FALSE; + httpconn->servconn = servconn; - /* First, some tests to see if we have a full block of stuff. */ - if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && - (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0)) && - ((strncmp(buf, "HTTP/1.0 200 OK\r\n", 17) != 0) && - (strncmp(buf, "HTTP/1.0 100 Continue\r\n", 23) != 0))) - { - *error = TRUE; + httpconn->tx_buf = gaim_circ_buffer_new(MSN_BUF_LEN); + httpconn->tx_handler = 0; - return FALSE; - } + return httpconn; +} - if (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) == 0) - { - if ((s = strstr(buf, "\r\n\r\n")) == NULL) - return FALSE; +void +msn_httpconn_destroy(MsnHttpConn *httpconn) +{ + g_return_if_fail(httpconn != NULL); - s += 4; + gaim_debug_info("msn", "destroy httpconn (%p)\n", httpconn); - if (*s == '\0') - { - *ret_buf = g_strdup(""); - *ret_size = 0; + if (httpconn->connected) + msn_httpconn_disconnect(httpconn); - if (httpconn->tx_handler > 0) - httpconn_write_cb(httpconn, httpconn->fd, - GAIM_INPUT_WRITE); - else - httpconn->dirty = TRUE; + g_free(httpconn->full_session_id); - return TRUE; - } + g_free(httpconn->session_id); - buf = s; - size -= (s - buf); - } + g_free(httpconn->host); - if ((s = strstr(buf, "\r\n\r\n")) == NULL) - return FALSE; + gaim_circ_buffer_destroy(httpconn->tx_buf); + if (httpconn->tx_handler > 0) + gaim_input_remove(httpconn->tx_handler); - s += 4; /* Skip \r\n */ - header = g_strndup(buf, s - buf); - body_start = s; - body_len = size - (body_start - buf); + g_free(httpconn); +} - if ((s = gaim_strcasestr(header, "Content-Length: ")) != NULL) +static void +connect_cb(gpointer data, gint source, GaimInputCondition cond) +{ + MsnHttpConn *httpconn = data; + + /* + TODO: Need to do this in case the account is disabled while connecting + if (!g_list_find(gaim_connections_get_all(), gc)) { - int tmp_len; + if (source >= 0) + close(source); + destroy_new_conn_data(new_conn_data); + return; + } + */ - s += strlen("Content-Length: "); + httpconn->fd = source; - if ((c = strchr(s, '\r')) == NULL) - { - g_free(header); + if (source >= 0) + { + httpconn->inpa = gaim_input_add(httpconn->fd, GAIM_INPUT_READ, + read_cb, data); - return FALSE; - } + httpconn->timer = gaim_timeout_add(2000, msn_httpconn_poll, httpconn); - tmp = g_strndup(s, c - s); - tmp_len = atoi(tmp); - g_free(tmp); - - if (body_len != tmp_len) - { - g_free(header); - -#if 0 - gaim_debug_warning("msn", - "body length (%d) != content length (%d)\n", - body_len, tmp_len); -#endif - - return FALSE; - } + msn_httpconn_process_queue(httpconn); } - - body = g_malloc0(body_len + 1); - memcpy(body, body_start, body_len); - -#ifdef MSN_DEBUG_HTTP - gaim_debug_misc("msn", "Incoming HTTP buffer (header): {%s\r\n}\n", - header); -#endif - - /* Now we should be able to process the data. */ - if ((s = gaim_strcasestr(header, "X-MSN-Messenger: ")) != NULL) + else { - char *full_session_id, *gw_ip, *session_action; - char *t, *session_id; - char **elems, **cur, **tokens; + gaim_debug_error("msn", "HTTP: Connection error\n"); + msn_servconn_got_error(httpconn->servconn, MSN_SERVCONN_ERROR_CONNECT); + } +} - full_session_id = gw_ip = session_action = NULL; +gboolean +msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) +{ + int r; - s += strlen("X-MSN-Messenger: "); + g_return_val_if_fail(httpconn != NULL, FALSE); + g_return_val_if_fail(host != NULL, FALSE); + g_return_val_if_fail(port > 0, FALSE); - if ((c = strchr(s, '\r')) == NULL) - { - msn_session_set_error(httpconn->session, - MSN_ERROR_HTTP_MALFORMED, NULL); - gaim_debug_error("msn", "Malformed X-MSN-Messenger field.\n{%s}", - buf); + if (httpconn->connected) + msn_httpconn_disconnect(httpconn); - g_free(body); - return FALSE; - } + r = gaim_proxy_connect(httpconn->session->account, + "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); - tmp = g_strndup(s, c - s); + if (r == 0) + { + httpconn->waiting_response = TRUE; + httpconn->connected = TRUE; + } - elems = g_strsplit(tmp, "; ", 0); + return httpconn->connected; +} - for (cur = elems; *cur != NULL; cur++) - { - tokens = g_strsplit(*cur, "=", 2); +void +msn_httpconn_disconnect(MsnHttpConn *httpconn) +{ + g_return_if_fail(httpconn != NULL); - if (strcmp(tokens[0], "SessionID") == 0) - full_session_id = tokens[1]; - else if (strcmp(tokens[0], "GW-IP") == 0) - gw_ip = tokens[1]; - else if (strcmp(tokens[0], "Session") == 0) - session_action = tokens[1]; + if (!httpconn->connected) + return; - g_free(tokens[0]); - /* Don't free each of the tokens, only the array. */ - g_free(tokens); - } + if (httpconn->timer) + gaim_timeout_remove(httpconn->timer); - g_strfreev(elems); + httpconn->timer = 0; - g_free(tmp); - - if ((session_action != NULL) && (strcmp(session_action, "close") == 0)) - wasted = TRUE; - - g_free(session_action); - - t = strchr(full_session_id, '.'); - session_id = g_strndup(full_session_id, t - full_session_id); - - if (!wasted) - { - g_free(httpconn->full_session_id); - - httpconn->full_session_id = full_session_id; - - g_free(httpconn->session_id); - - httpconn->session_id = session_id; - - g_free(httpconn->host); - - httpconn->host = gw_ip; - } - else - { - MsnServConn *servconn; - - /* It's going to die. */ - /* poor thing */ - - servconn = httpconn->servconn; - - /* I'll be honest, I don't fully understand all this, but this - * causes crashes, Stu. */ - /* if (servconn != NULL) - servconn->wasted = TRUE; */ - - g_free(full_session_id); - g_free(session_id); - g_free(gw_ip); - } + if (httpconn->inpa > 0) + { + gaim_input_remove(httpconn->inpa); + httpconn->inpa = 0; } - g_free(header); + close(httpconn->fd); - *ret_buf = body; - *ret_size = body_len; + g_free(httpconn->rx_buf); + httpconn->rx_buf = NULL; + httpconn->rx_len = 0; - if (httpconn->tx_handler > 0) - httpconn_write_cb(httpconn, httpconn->fd, GAIM_INPUT_WRITE); - else - httpconn->dirty = TRUE; + httpconn->connected = FALSE; - return TRUE; + /* msn_servconn_disconnect(httpconn->servconn); */ } Modified: branches/v2_0_0/src/protocols/msn/httpconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.h 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/protocols/msn/httpconn.h 2006-07-03 20:39:41 UTC (rev 16415) @@ -44,13 +44,13 @@ gboolean waiting_response; /**< The flag that states if we are waiting a response from the server. */ - gboolean dirty; /**< The flag that states if we should poll. */ gboolean connected; /**< The flag that states if the connection is on. */ gboolean virgin; /**< The flag that states if this connection should specify the host (not gateway) to connect to. */ char *host; /**< The HTTP gateway host. */ + GList *queue; /**< The queue of data chunks to write. */ int fd; /**< The connection's file descriptor. */ guint inpa; /**< The connection's input handler. */ @@ -83,11 +83,11 @@ * * @param servconn The server connection. * @param data The data to write. - * @param size The size of the data to write. + * @param data_len The size of the data to write. * * @return The number of bytes written. */ -ssize_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t size); +ssize_t msn_httpconn_write(MsnHttpConn *httpconn, const char *data, size_t data_len); /** * Connects the HTTP connection object to a host. Modified: branches/v2_0_0/src/protocols/msn/msn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/msn.c 2006-07-03 20:39:04 UTC (rev 16414) +++ branches/v2_0_0/src/protocols/msn/msn.c 2006-07-03 20:39:41 UTC (rev 16415) @@ -731,8 +731,7 @@ return; } - if (gaim_account_get_bool(account, "http_method", FALSE)) - http_method = TRUE; + http_method = gaim_account_get_bool(account, "http_method", FALSE); host = gaim_account_get_string(account, "server", MSN_SERVER); port = gaim_account_get_int(account, "port", MSN_PORT); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-06 08:11:53
|
Revision: 16441 Author: thekingant Date: 2006-07-06 01:11:47 -0700 (Thu, 06 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16441&view=rev Log Message: ----------- Minor odds and ends Modified Paths: -------------- branches/v2_0_0/plugins/ssl/ssl-gnutls.c branches/v2_0_0/src/conversation.c branches/v2_0_0/src/gtkprefs.c branches/v2_0_0/src/server.c branches/v2_0_0/src/util.c Modified: branches/v2_0_0/plugins/ssl/ssl-gnutls.c =================================================================== --- branches/v2_0_0/plugins/ssl/ssl-gnutls.c 2006-07-06 08:11:41 UTC (rev 16440) +++ branches/v2_0_0/plugins/ssl/ssl-gnutls.c 2006-07-06 08:11:47 UTC (rev 16441) @@ -106,6 +106,11 @@ GaimSslGnutlsData *gnutls_data; static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 }; + /* + * TODO: Uh, this needs to somehow check to make sure that gsc is + * still valid before actually doing anything. + */ + if(source < 0) { if(gsc->error_cb != NULL) gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); Modified: branches/v2_0_0/src/conversation.c =================================================================== --- branches/v2_0_0/src/conversation.c 2006-07-06 08:11:41 UTC (rev 16440) +++ branches/v2_0_0/src/conversation.c 2006-07-06 08:11:47 UTC (rev 16441) @@ -57,9 +57,6 @@ gaim_conv_im_update_typing(im); gaim_conv_im_stop_typing_timeout(im); - gaim_signal_emit(gaim_conversations_get_handle(), - "buddy-typing-stopped", c->account, c->name); - return FALSE; } Modified: branches/v2_0_0/src/gtkprefs.c =================================================================== --- branches/v2_0_0/src/gtkprefs.c 2006-07-06 08:11:41 UTC (rev 16440) +++ branches/v2_0_0/src/gtkprefs.c 2006-07-06 08:11:47 UTC (rev 16441) @@ -1818,7 +1818,7 @@ } /* Signon status stuff */ - vbox = gaim_gtk_make_frame(ret, _("Status at startup")); + vbox = gaim_gtk_make_frame(ret, _("Status at Startup")); button = gaim_gtk_prefs_checkbox(_("Use status from last _exit at startup"), "/core/savedstatus/startup_current_status", vbox); Modified: branches/v2_0_0/src/server.c =================================================================== --- branches/v2_0_0/src/server.c 2006-07-06 08:11:41 UTC (rev 16440) +++ branches/v2_0_0/src/server.c 2006-07-06 08:11:47 UTC (rev 16441) @@ -621,9 +621,6 @@ gaim_signal_emit(gaim_conversations_get_handle(), "buddy-typing-stopped", gc->account, name); } - - gaim_signal_emit(gaim_conversations_get_handle(), - "buddy-typing-stopped", gc->account, name); } struct chat_invite_data { Modified: branches/v2_0_0/src/util.c =================================================================== --- branches/v2_0_0/src/util.c 2006-07-06 08:11:41 UTC (rev 16440) +++ branches/v2_0_0/src/util.c 2006-07-06 08:11:47 UTC (rev 16441) @@ -2521,7 +2521,7 @@ } } else { gaim_debug(GAIM_DEBUG_ERROR, "gaim_mkstemp", - "g_get_tmp_dir() failed!"); + "g_get_tmp_dir() failed!\n"); } return fp; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-06 09:22:20
|
Revision: 16446 Author: thekingant Date: 2006-07-06 02:22:18 -0700 (Thu, 06 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16446&view=rev Log Message: ----------- Backport SVN revision #16445 from HEAD to v2_0_0 Original commit message: Fix a crash bug on some systems (mostly amd64) caused by using a va_list twice. My bad! Thanks to Kevin Stange and Vincent Ho for noticing this and suggesting the cause. Vincent's IRC handle reminds me of a Harvey Danger song. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16445&view=rev Modified Paths: -------------- branches/v2_0_0/src/debug.c branches/v2_0_0/src/debug.h branches/v2_0_0/src/gtkdebug.c Modified: branches/v2_0_0/src/debug.c =================================================================== --- branches/v2_0_0/src/debug.c 2006-07-06 09:21:57 UTC (rev 16445) +++ branches/v2_0_0/src/debug.c 2006-07-06 09:22:18 UTC (rev 16446) @@ -46,15 +46,21 @@ const char *format, va_list args) { GaimDebugUiOps *ops; + char *arg_s = NULL; g_return_if_fail(level != GAIM_DEBUG_ALL); g_return_if_fail(format != NULL); + ops = gaim_debug_get_ui_ops(); + + if (!debug_enabled && ((ops == NULL) || (ops->print == NULL))) + return; + + arg_s = g_strdup_vprintf(format, args); + if (debug_enabled) { - gchar *arg_s, *ts_s; + gchar *ts_s; - arg_s = g_strdup_vprintf(format, args); - if ((category != NULL) && (gaim_prefs_exists("/core/debug/timestamps")) && (gaim_prefs_get_bool("/core/debug/timestamps"))) { @@ -72,14 +78,13 @@ else g_print("%s%s: %s", ts_s, category, arg_s); - g_free(arg_s); g_free(ts_s); } - ops = gaim_debug_get_ui_ops(); + if (ops != NULL && ops->print != NULL) + ops->print(level, category, arg_s); - if (ops != NULL && ops->print != NULL) - ops->print(level, category, format, args); + g_free(arg_s); } void Modified: branches/v2_0_0/src/debug.h =================================================================== --- branches/v2_0_0/src/debug.h 2006-07-06 09:21:57 UTC (rev 16445) +++ branches/v2_0_0/src/debug.h 2006-07-06 09:22:18 UTC (rev 16446) @@ -48,7 +48,7 @@ typedef struct { void (*print)(GaimDebugLevel level, const char *category, - const char *format, va_list args); + const char *arg_s); } GaimDebugUiOps; #ifdef __cplusplus Modified: branches/v2_0_0/src/gtkdebug.c =================================================================== --- branches/v2_0_0/src/gtkdebug.c 2006-07-06 09:21:57 UTC (rev 16445) +++ branches/v2_0_0/src/gtkdebug.c 2006-07-06 09:22:18 UTC (rev 16446) @@ -931,13 +931,13 @@ static void gaim_gtk_debug_print(GaimDebugLevel level, const char *category, - const char *format, va_list args) + const char *arg_s) { #ifdef HAVE_REGEX_H GtkTreeIter iter; #endif /* HAVE_REGEX_H */ gboolean timestamps; - gchar *arg_s, *ts_s; + gchar *ts_s; gchar *esc_s, *cat_s, *tmp, *s; if (!gaim_prefs_get_bool("/gaim/gtk/debug/enabled") || @@ -948,8 +948,6 @@ timestamps = gaim_prefs_get_bool("/core/debug/timestamps"); - arg_s = g_strdup_vprintf(format, args); - /* * For some reason we only print the timestamp if category is * not NULL. Why the hell do we do that? --Mark @@ -971,8 +969,6 @@ esc_s = g_markup_escape_text(arg_s, -1); - g_free(arg_s); - s = g_strdup_printf("<font color=\"%s\">%s%s%s</font>", debug_fg_colors[level], ts_s, cat_s, esc_s); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-16 19:09:14
|
Revision: 16497 Author: thekingant Date: 2006-07-16 12:09:06 -0700 (Sun, 16 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16497&view=rev Log Message: ----------- Backport SVN revision #16496 from HEAD to v2_0_0 Original commit message: Rename gaim_buffer.c and .h to circbuffer.c and .h ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16496&view=rev Modified Paths: -------------- branches/v2_0_0/src/Makefile.am branches/v2_0_0/src/Makefile.mingw branches/v2_0_0/src/protocols/irc/irc.h branches/v2_0_0/src/protocols/jabber/jabber.h branches/v2_0_0/src/protocols/msn/httpconn.h branches/v2_0_0/src/protocols/oscar/oscar.h branches/v2_0_0/src/protocols/sametime/sametime.c branches/v2_0_0/src/protocols/simple/simple.h branches/v2_0_0/src/protocols/yahoo/yahoo.h Added Paths: ----------- branches/v2_0_0/src/circbuffer.c branches/v2_0_0/src/circbuffer.h Removed Paths: ------------- branches/v2_0_0/src/gaim_buffer.c branches/v2_0_0/src/gaim_buffer.h Modified: branches/v2_0_0/src/Makefile.am =================================================================== --- branches/v2_0_0/src/Makefile.am 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/Makefile.am 2006-07-16 19:09:06 UTC (rev 16497) @@ -70,6 +70,7 @@ blist.c \ buddyicon.c \ cipher.c \ + circbuffer.c \ cmds.c \ connection.c \ conversation.c \ @@ -78,7 +79,6 @@ desktopitem.c \ eventloop.c \ ft.c \ - gaim_buffer.c \ idle.c \ imgstore.c \ log.c \ @@ -117,6 +117,7 @@ blist.h \ buddyicon.h \ cipher.h \ + circbuffer.h \ cmds.h \ connection.h \ conversation.h \ @@ -126,7 +127,6 @@ desktopitem.h \ eventloop.h \ ft.h \ - gaim_buffer.h \ idle.h \ imgstore.h \ log.h \ Modified: branches/v2_0_0/src/Makefile.mingw =================================================================== --- branches/v2_0_0/src/Makefile.mingw 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/Makefile.mingw 2006-07-16 19:09:06 UTC (rev 16497) @@ -89,6 +89,7 @@ blist.c \ buddyicon.c \ cipher.c \ + circbuffer.c \ cmds.c \ connection.c \ conversation.c \ @@ -97,7 +98,6 @@ dnssrv.c \ eventloop.c \ ft.c \ - gaim_buffer.c \ gtkaccount.c \ gtkblist.c \ gtkconn.c \ Copied: branches/v2_0_0/src/circbuffer.c (from rev 16491, branches/v2_0_0/src/gaim_buffer.c) =================================================================== --- branches/v2_0_0/src/circbuffer.c (rev 0) +++ branches/v2_0_0/src/circbuffer.c 2006-07-16 19:09:06 UTC (rev 16497) @@ -0,0 +1,141 @@ +/* + * @file circbuffer.h Buffer Utility Functions + * @ingroup core + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "internal.h" + +#include "circbuffer.h" + +#define DEFAULT_BUF_SIZE 256 + +GaimCircBuffer * +gaim_circ_buffer_new(gsize growsize) { + GaimCircBuffer *buf = g_new0(GaimCircBuffer, 1); + buf->growsize = growsize ? growsize : DEFAULT_BUF_SIZE; + return buf; +} + +void gaim_circ_buffer_destroy(GaimCircBuffer *buf) { + g_free(buf->buffer); + g_free(buf); +} + +static void grow_circ_buffer(GaimCircBuffer *buf, gsize len) { + int in_offset = 0, out_offset = 0; + int start_buflen = buf->buflen; + + while ((buf->buflen - buf->bufused) < len) + buf->buflen += buf->growsize; + + if (buf->inptr != NULL) { + in_offset = buf->inptr - buf->buffer; + out_offset = buf->outptr - buf->buffer; + } + buf->buffer = g_realloc(buf->buffer, buf->buflen); + + /* adjust the fill and remove pointer locations */ + if (buf->inptr == NULL) { + buf->inptr = buf->outptr = buf->buffer; + } else { + buf->inptr = buf->buffer + in_offset; + buf->outptr = buf->buffer + out_offset; + } + + /* If the fill pointer is wrapped to before the remove + * pointer, we need to shift the data */ + if (in_offset < out_offset) { + int shift_n = MIN(buf->buflen - start_buflen, + in_offset); + memcpy(buf->buffer + start_buflen, buf->buffer, + shift_n); + + /* If we couldn't fit the wrapped read buffer + * at the end */ + if (shift_n < in_offset) { + memmove(buf->buffer, + buf->buffer + shift_n, + in_offset - shift_n); + buf->inptr = buf->buffer + + (in_offset - shift_n); + } else { + buf->inptr = buf->buffer + + start_buflen + in_offset; + } + } +} + +void gaim_circ_buffer_append(GaimCircBuffer *buf, gconstpointer src, gsize len) { + + int len_stored; + + /* Grow the buffer, if necessary */ + if ((buf->buflen - buf->bufused) < len) + grow_circ_buffer(buf, len); + + /* If there is not enough room to copy all of src before hitting + * the end of the buffer then we will need to do two copies. + * One copy from inptr to the end of the buffer, and the + * second copy from the start of the buffer to the end of src. */ + if (buf->inptr >= buf->outptr) + len_stored = MIN(len, buf->buflen + - (buf->inptr - buf->buffer)); + else + len_stored = len; + + memcpy(buf->inptr, src, len_stored); + + if (len_stored < len) { + memcpy(buf->buffer, src + len_stored, len - len_stored); + buf->inptr = buf->buffer + (len - len_stored); + } else if ((buf->buffer - buf->inptr) == len_stored) { + buf->inptr = buf->buffer; + } else { + buf->inptr += len_stored; + } + + buf->bufused += len; +} + +gsize gaim_circ_buffer_get_max_read(GaimCircBuffer *buf) { + int max_read; + + if (buf->bufused == 0) + max_read = 0; + else if ((buf->outptr - buf->inptr) >= 0) + max_read = buf->buflen - (buf->outptr - buf->buffer); + else + max_read = buf->inptr - buf->outptr; + + return max_read; +} + +gboolean gaim_circ_buffer_mark_read(GaimCircBuffer *buf, gsize len) { + g_return_val_if_fail(gaim_circ_buffer_get_max_read(buf) >= len, FALSE); + + buf->outptr += len; + buf->bufused -= len; + /* wrap to the start if we're at the end */ + if ((buf->outptr - buf->buffer) == buf->buflen) + buf->outptr = buf->buffer; + + return TRUE; +} + Property changes on: branches/v2_0_0/src/circbuffer.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Copied: branches/v2_0_0/src/circbuffer.h (from rev 16491, branches/v2_0_0/src/gaim_buffer.h) =================================================================== --- branches/v2_0_0/src/circbuffer.h (rev 0) +++ branches/v2_0_0/src/circbuffer.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -0,0 +1,117 @@ +/* + * @file circbuffer.h Buffer Utility Functions + * @ingroup core + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _CIRCBUFFER_H +#define _CIRCBUFFER_H + +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _GaimCircBuffer { + + /** A pointer to the starting address of our chunk of memory. */ + gchar *buffer; + + /** The incremental amount to increase this buffer by when + * the buffer is not big enough to hold incoming data, in bytes. */ + gsize growsize; + + /** The length of this buffer, in bytes. */ + gsize buflen; + + /** The number of bytes of this buffer that contain unread data. */ + gsize bufused; + + /** A pointer to the next byte where new incoming data is + * buffered to. */ + gchar *inptr; + + /** A pointer to the next byte of buffered data that should be + * read by the consumer. */ + gchar *outptr; + +} GaimCircBuffer; + +/** + * Creates a new circular buffer. This will not allocate any memory for the + * actual buffer until data is appended to it. + * + * @param growsize The amount that the buffer should grow the first time data + * is appended and every time more space is needed. Pass in + * "0" to use the default of 256 bytes. + * + * @return The new GaimCircBuffer. This should be freed with + * gaim_circ_buffer_destroy when you are done with it + */ +GaimCircBuffer *gaim_circ_buffer_new(gsize growsize); + +/** + * Dispose of the GaimCircBuffer and free any memory used by it (including any + * memory used by the internal buffer). + * + * @param buf The GaimCircBuffer to free + */ +void gaim_circ_buffer_destroy(GaimCircBuffer *buf); + +/** + * Append data to the GaimCircBuffer. This will grow the internal + * buffer to fit the added data, if needed. + * + * @param buf The GaimCircBuffer to which to append the data + * @param src pointer to the data to copy into the buffer + * @param len number of bytes to copy into the buffer + */ +void gaim_circ_buffer_append(GaimCircBuffer *buf, gconstpointer src, gsize len); + +/** + * Determine the maximum number of contiguous bytes that can be read from the + * GaimCircBuffer. + * Note: This may not be the total number of bytes that are buffered - a + * subsequent call after calling gaim_circ_buffer_mark_read() may indicate more + * data is available to read. + * + * @param buf the GaimCircBuffer for which to determine the maximum contiguous + * bytes that can be read. + * + * @return the number of bytes that can be read from the GaimCircBuffer + */ +gsize gaim_circ_buffer_get_max_read(GaimCircBuffer *buf); + +/** + * Mark the number of bytes that have been read from the buffer. + * + * @param buf The GaimCircBuffer to mark bytes read from + * @param len The number of bytes to mark as read + * + * @return TRUE if we successfully marked the bytes as having been read, FALSE + * otherwise. + */ +gboolean gaim_circ_buffer_mark_read(GaimCircBuffer *buf, gsize len); + +#ifdef __cplusplus +} +#endif + +#endif /* _CIRCBUFFER_H */ Property changes on: branches/v2_0_0/src/circbuffer.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Deleted: branches/v2_0_0/src/gaim_buffer.c =================================================================== --- branches/v2_0_0/src/gaim_buffer.c 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/gaim_buffer.c 2006-07-16 19:09:06 UTC (rev 16497) @@ -1,141 +0,0 @@ -/* - * @file gaim_buffer.h Buffer Utility Functions - * @ingroup core - * - * Gaim is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include "internal.h" - -#include "gaim_buffer.h" - -#define DEFAULT_BUF_SIZE 256 - -GaimCircBuffer * -gaim_circ_buffer_new(gsize growsize) { - GaimCircBuffer *buf = g_new0(GaimCircBuffer, 1); - buf->growsize = growsize ? growsize : DEFAULT_BUF_SIZE; - return buf; -} - -void gaim_circ_buffer_destroy(GaimCircBuffer *buf) { - g_free(buf->buffer); - g_free(buf); -} - -static void grow_circ_buffer(GaimCircBuffer *buf, gsize len) { - int in_offset = 0, out_offset = 0; - int start_buflen = buf->buflen; - - while ((buf->buflen - buf->bufused) < len) - buf->buflen += buf->growsize; - - if (buf->inptr != NULL) { - in_offset = buf->inptr - buf->buffer; - out_offset = buf->outptr - buf->buffer; - } - buf->buffer = g_realloc(buf->buffer, buf->buflen); - - /* adjust the fill and remove pointer locations */ - if (buf->inptr == NULL) { - buf->inptr = buf->outptr = buf->buffer; - } else { - buf->inptr = buf->buffer + in_offset; - buf->outptr = buf->buffer + out_offset; - } - - /* If the fill pointer is wrapped to before the remove - * pointer, we need to shift the data */ - if (in_offset < out_offset) { - int shift_n = MIN(buf->buflen - start_buflen, - in_offset); - memcpy(buf->buffer + start_buflen, buf->buffer, - shift_n); - - /* If we couldn't fit the wrapped read buffer - * at the end */ - if (shift_n < in_offset) { - memmove(buf->buffer, - buf->buffer + shift_n, - in_offset - shift_n); - buf->inptr = buf->buffer + - (in_offset - shift_n); - } else { - buf->inptr = buf->buffer + - start_buflen + in_offset; - } - } -} - -void gaim_circ_buffer_append(GaimCircBuffer *buf, gconstpointer src, gsize len) { - - int len_stored; - - /* Grow the buffer, if necessary */ - if ((buf->buflen - buf->bufused) < len) - grow_circ_buffer(buf, len); - - /* If there is not enough room to copy all of src before hitting - * the end of the buffer then we will need to do two copies. - * One copy from inptr to the end of the buffer, and the - * second copy from the start of the buffer to the end of src. */ - if (buf->inptr >= buf->outptr) - len_stored = MIN(len, buf->buflen - - (buf->inptr - buf->buffer)); - else - len_stored = len; - - memcpy(buf->inptr, src, len_stored); - - if (len_stored < len) { - memcpy(buf->buffer, src + len_stored, len - len_stored); - buf->inptr = buf->buffer + (len - len_stored); - } else if ((buf->buffer - buf->inptr) == len_stored) { - buf->inptr = buf->buffer; - } else { - buf->inptr += len_stored; - } - - buf->bufused += len; -} - -gsize gaim_circ_buffer_get_max_read(GaimCircBuffer *buf) { - int max_read; - - if (buf->bufused == 0) - max_read = 0; - else if ((buf->outptr - buf->inptr) >= 0) - max_read = buf->buflen - (buf->outptr - buf->buffer); - else - max_read = buf->inptr - buf->outptr; - - return max_read; -} - -gboolean gaim_circ_buffer_mark_read(GaimCircBuffer *buf, gsize len) { - g_return_val_if_fail(gaim_circ_buffer_get_max_read(buf) >= len, FALSE); - - buf->outptr += len; - buf->bufused -= len; - /* wrap to the start if we're at the end */ - if ((buf->outptr - buf->buffer) == buf->buflen) - buf->outptr = buf->buffer; - - return TRUE; -} - Deleted: branches/v2_0_0/src/gaim_buffer.h =================================================================== --- branches/v2_0_0/src/gaim_buffer.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/gaim_buffer.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -1,115 +0,0 @@ -/* - * @file gaim_buffer.h Buffer Utility Functions - * @ingroup core - * - * Gaim is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _GAIM_BUFFER_H -#define _GAIM_BUFFER_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _GaimCircBuffer { - - /** A pointer to the starting address of our chunk of memory. */ - gchar *buffer; - - /** The incremental amount to increase this buffer by when - * the buffer is not big enough to hold incoming data, in bytes. */ - gsize growsize; - - /** The length of this buffer, in bytes. */ - gsize buflen; - - /** The number of bytes of this buffer that contain unread data. */ - gsize bufused; - - /** A pointer to the next byte where new incoming data is - * buffered to. */ - gchar *inptr; - - /** A pointer to the next byte of buffered data that should be - * read by the consumer. */ - gchar *outptr; - -} GaimCircBuffer; - -/** - * Creates a new circular buffer. This will not allocate any memory for the - * actual buffer until data is appended to it. - * - * @param growsize The amount that the buffer should grow the first time data - * is appended and every time more space is needed. Pass in - * "0" to use the default of 256 bytes. - * - * @return The new GaimCircBuffer. This should be freed with - * gaim_circ_buffer_destroy when you are done with it - */ -GaimCircBuffer *gaim_circ_buffer_new(gsize growsize); - -/** - * Dispose of the GaimCircBuffer and free any memory used by it (including any - * memory used by the internal buffer). - * - * @param buf The GaimCircBuffer to free - */ -void gaim_circ_buffer_destroy(GaimCircBuffer *buf); - -/** - * Append data to the GaimCircBuffer. This will grow the internal - * buffer to fit the added data, if needed. - * - * @param buf The GaimCircBuffer to which to append the data - * @param src pointer to the data to copy into the buffer - * @param len number of bytes to copy into the buffer - */ -void gaim_circ_buffer_append(GaimCircBuffer *buf, gconstpointer src, gsize len); - -/** - * Determine the maximum number of contiguous bytes that can be read from the - * GaimCircBuffer. - * Note: This may not be the total number of bytes that are buffered - a - * subsequent call after calling gaim_circ_buffer_mark_read() may indicate more - * data is available to read. - * - * @param buf the GaimCircBuffer for which to determine the maximum contiguous - * bytes that can be read. - * - * @return the number of bytes that can be read from the GaimCircBuffer - */ -gsize gaim_circ_buffer_get_max_read(GaimCircBuffer *buf); - -/** - * Mark the number of bytes that have been read from the buffer. - * - * @param buf The GaimCircBuffer to mark bytes read from - * @param len The number of bytes to mark as read - * - * @return TRUE if we successfully marked the bytes as having been read, FALSE - * otherwise. - */ -gboolean gaim_circ_buffer_mark_read(GaimCircBuffer *buf, gsize len); - -#ifdef __cplusplus -} -#endif - -#endif /* _GAIM_BUFFER_H */ Modified: branches/v2_0_0/src/protocols/irc/irc.h =================================================================== --- branches/v2_0_0/src/protocols/irc/irc.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/irc/irc.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -25,8 +25,8 @@ #include <glib.h> +#include "circbuffer.h" #include "ft.h" -#include "gaim_buffer.h" #include "roomlist.h" #include "sslconn.h" Modified: branches/v2_0_0/src/protocols/jabber/jabber.h =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/jabber/jabber.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -26,10 +26,10 @@ #include <libxml/parser.h> #endif #include <glib.h> +#include "circbuffer.h" #include "connection.h" #include "roomlist.h" #include "sslconn.h" -#include "gaim_buffer.h" #include "jutil.h" #include "xmlnode.h" Modified: branches/v2_0_0/src/protocols/msn/httpconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/msn/httpconn.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -26,8 +26,8 @@ typedef struct _MsnHttpConn MsnHttpConn; +#include "circbuffer.h" #include "servconn.h" -#include "gaim_buffer.h" /** * An HTTP Connection. Modified: branches/v2_0_0/src/protocols/oscar/oscar.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/oscar/oscar.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -29,9 +29,9 @@ #ifndef _OSCAR_H_ #define _OSCAR_H_ +#include "circbuffer.h" #include "debug.h" #include "eventloop.h" -#include "gaim_buffer.h" #include "internal.h" #include <stdio.h> Modified: branches/v2_0_0/src/protocols/sametime/sametime.c =================================================================== --- branches/v2_0_0/src/protocols/sametime/sametime.c 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/sametime/sametime.c 2006-07-16 19:09:06 UTC (rev 16497) @@ -32,25 +32,25 @@ #include <glib/glist.h> /* gaim includes */ -#include <internal.h> -#include <gaim.h> -#include <config.h> +#include "internal.h" +#include "gaim.h" +#include "config.h" -#include <account.h> -#include <accountopt.h> -#include <conversation.h> -#include <debug.h> -#include <ft.h> -#include <gaim_buffer.h> -#include <imgstore.h> -#include <mime.h> -#include <notify.h> -#include <plugin.h> -#include <privacy.h> -#include <prpl.h> -#include <request.h> -#include <util.h> -#include <version.h> +#include "account.h" +#include "accountopt.h" +#include "circbuffer.h" +#include "conversation.h" +#include "debug.h" +#include "ft.h" +#include "imgstore.h" +#include "mime.h" +#include "notify.h" +#include "plugin.h" +#include "privacy.h" +#include "prpl.h" +#include "request.h" +#include "util.h" +#include "version.h" /* meanwhile includes */ #include <mw_cipher.h> Modified: branches/v2_0_0/src/protocols/simple/simple.h =================================================================== --- branches/v2_0_0/src/protocols/simple/simple.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/simple/simple.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -26,9 +26,9 @@ #include <glib.h> #include <time.h> -#include <cipher.h> -#include <gaim_buffer.h> -#include <prpl.h> +#include "cipher.h" +#include "circbuffer.h" +#include "prpl.h" #include "sipmsg.h" Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.h =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.h 2006-07-16 19:08:31 UTC (rev 16496) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.h 2006-07-16 19:09:06 UTC (rev 16497) @@ -25,8 +25,8 @@ #ifndef _YAHOO_H_ #define _YAHOO_H_ +#include "circbuffer.h" #include "prpl.h" -#include "gaim_buffer.h" #define YAHOO_PAGER_HOST "scs.msg.yahoo.com" #define YAHOO_PAGER_PORT 5050 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-17 05:50:54
|
Revision: 16504 Author: thekingant Date: 2006-07-16 22:50:49 -0700 (Sun, 16 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16504&view=rev Log Message: ----------- Backport SVN revision #16503 from HEAD to v2_0_0 Original commit message: Get rid of an assertion failure when trying to load our D-BUS example plugin if the D-BUS subsystem is not initialized for whatever reason. Not only that, the plugin gracefully fails to load and prints an error message. These error messages could be improved. If you're familiar with how D-BUS works then go for it. Also, do we need to be uninitializing any of the D-BUS stuff? ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16503&view=rev Modified Paths: -------------- branches/v2_0_0/plugins/dbus-example.c branches/v2_0_0/src/core.c branches/v2_0_0/src/dbus-server.c branches/v2_0_0/src/dbus-server.h branches/v2_0_0/src/plugin.c Modified: branches/v2_0_0/plugins/dbus-example.c =================================================================== --- branches/v2_0_0/plugins/dbus-example.c 2006-07-17 05:50:28 UTC (rev 16503) +++ branches/v2_0_0/plugins/dbus-example.c 2006-07-17 05:50:49 UTC (rev 16504) @@ -37,8 +37,9 @@ #include "internal.h" +#include "blist.h" +#include "notify.h" #include "plugin.h" -#include "blist.h" #include "version.h" #include <stdio.h> @@ -108,6 +109,17 @@ static gboolean plugin_load(GaimPlugin *plugin) { + const char *dbus_init_error; + + dbus_init_error = gaim_dbus_get_init_error(); + if (dbus_init_error != NULL) + { + gaim_notify_error(NULL, _("Unable to Load Plugin"), + _("Gaim's D-BUS server is not running for the reason listed below"), + _(dbus_init_error)); + return FALSE; + } + /* First, we have to register our four exported functions with the main gaim dbus loop. Without this statement, the gaim dbus code wouldn't know about our functions. */ Modified: branches/v2_0_0/src/core.c =================================================================== --- branches/v2_0_0/src/core.c 2006-07-17 05:50:28 UTC (rev 16503) +++ branches/v2_0_0/src/core.c 2006-07-17 05:50:49 UTC (rev 16504) @@ -99,7 +99,6 @@ gaim_dbus_init(); #endif - /* Initialize all static protocols. */ static_proto_init(); @@ -193,6 +192,10 @@ gaim_plugins_uninit(); gaim_signals_uninit(); +#ifdef HAVE_DBUS + gaim_dbus_uninit(); +#endif + if (core->ui != NULL) { g_free(core->ui); core->ui = NULL; Modified: branches/v2_0_0/src/dbus-server.c =================================================================== --- branches/v2_0_0/src/dbus-server.c 2006-07-17 05:50:28 UTC (rev 16503) +++ branches/v2_0_0/src/dbus-server.c 2006-07-17 05:50:49 UTC (rev 16504) @@ -36,6 +36,7 @@ #include "dbus-bindings.h" #include "debug.h" #include "core.h" +#include "internal.h" #include "savedstatuses.h" #include "value.h" @@ -59,7 +60,9 @@ static GHashTable *map_id_node; static GHashTable *map_id_type; +static gchar *init_error; + /* This function initializes the pointer-id traslation system. It creates the three above hashtables and defines parents of some types. */ @@ -229,7 +232,7 @@ DBusMessageIter *sub; sub = va_arg (var_args, DBusMessageIter*); dbus_message_iter_recurse(iter, sub); - g_print("subiter %i:%i\n", (int) sub, * (int*) sub); + gaim_debug_info("dbus", "subiter %p:%p\n", sub, * (gpointer*) sub); break; /* for testing only! */ } @@ -383,12 +386,6 @@ #include "dbus-bindings.c" -void *gaim_dbus_get_handle(void) { - static int handle; - - return &handle; -} - static gboolean gaim_dbus_dispatch_cb(DBusConnection *connection, DBusMessage *message, @@ -437,7 +434,7 @@ } -static const char *gettext(const char **ptr) { +static const char *dbus_gettext(const char **ptr) { const char *text = *ptr; *ptr += strlen(text) + 1; return text; @@ -478,9 +475,9 @@ while (*text) { const char *name, *direction, *type; - direction = gettext(&text); - type = gettext(&text); - name = gettext(&text); + direction = dbus_gettext(&text); + type = dbus_gettext(&text); + name = dbus_gettext(&text); g_string_append_printf(str, "<arg name='%s' type='%s' direction='%s'/>\n", @@ -539,7 +536,7 @@ -static gboolean gaim_dbus_dispatch_init(void) +static void gaim_dbus_dispatch_init(void) { static DBusObjectPathVTable vtable = {NULL, &gaim_dbus_dispatch, NULL, NULL, NULL, NULL}; @@ -550,17 +547,17 @@ gaim_dbus_connection = dbus_bus_get (DBUS_BUS_STARTER, &error); if (gaim_dbus_connection == NULL) { - gaim_debug_error("dbus", "Failed to get connection\n"); + init_error = g_strdup_printf(N_("Failed to get connection: %s"), error.message); dbus_error_free(&error); - return FALSE; + return; } if (!dbus_connection_register_object_path (gaim_dbus_connection, DBUS_PATH_GAIM, &vtable, NULL)) { - gaim_debug_error("dbus", "Failed to get name: %s\n", error.name); + init_error = g_strdup_printf(N_("Failed to get name: %s"), error.name); dbus_error_free(&error); - return FALSE; + return; } @@ -571,8 +568,8 @@ dbus_connection_unref(gaim_dbus_connection); dbus_error_free(&error); gaim_dbus_connection = NULL; - gaim_debug_error("dbus", "Failed to get serv name: %s\n", error.name); - return FALSE; + init_error = g_strdup_printf(N_("Failed to get serv name: %s"), error.name); + return; } dbus_connection_setup_with_g_main(gaim_dbus_connection, NULL); @@ -590,8 +587,6 @@ gaim_value_new_outgoing(GAIM_TYPE_POINTER)); GAIM_DBUS_REGISTER_BINDINGS(gaim_dbus_get_handle()); - - return TRUE; } @@ -709,15 +704,37 @@ dbus_message_unref(signal); } +const char * +gaim_dbus_get_init_error(void) +{ + return init_error; +} +void * +gaim_dbus_get_handle(void) +{ + static int handle; + return &handle; +} - - -gboolean gaim_dbus_init(void) +void +gaim_dbus_init(void) { gaim_dbus_init_ids(); - return gaim_dbus_dispatch_init() ; + + g_free(init_error); + init_error = NULL; + gaim_dbus_dispatch_init(); + if (init_error != NULL) + gaim_debug_error("dbus", "%s\n", init_error); } +void +gaim_dbus_uninit(void) +{ + /* Surely we must do SOME kind of uninitialization? */ + g_free(init_error); + init_error = NULL; +} Modified: branches/v2_0_0/src/dbus-server.h =================================================================== --- branches/v2_0_0/src/dbus-server.h 2006-07-17 05:50:28 UTC (rev 16503) +++ branches/v2_0_0/src/dbus-server.h 2006-07-17 05:50:49 UTC (rev 16504) @@ -135,14 +135,20 @@ GaimValue **values, va_list vargs); /** - * Starts the gaim DBUS server. It is responsible for handling DBUS - * requests from other applications. + * Returns whether Gaim's D-BUS subsystem is up and running. If it's + * NOT running then gaim_dbus_dispatch_init() failed for some reason, + * and a message should have been gaim_debug_error()'ed. * - * @return TRUE if successful, FALSE otherwise. + * This function should be called by any DBUS plugin before trying + * to use the DBUS API. See plugins/dbus-example.c for usage. + * + * @return If the D-BUS subsystem started with no problems then this + * will return NULL and everything will be hunky dory. If + * there was an error initializing the D-BUS subsystem then + * this will return an error message explaining why. */ -gboolean gaim_dbus_init(void); +const char *gaim_dbus_get_init_error(void); - /** * Returns the dbus subsystem handle. * @@ -151,7 +157,18 @@ void *gaim_dbus_get_handle(void); /** + * Starts Gaim's D-BUS server. It is responsible for handling DBUS + * requests from other applications. + */ +void gaim_dbus_init(void); +/** + * Uninitializes Gaim's D-BUS server. + */ +void gaim_dbus_uninit(void); + +/** + Macro #DBUS_EXPORT expands to nothing. It is used to indicate to the dbus-analize-functions.py script that the given function should be available to other applications through DBUS. If Modified: branches/v2_0_0/src/plugin.c =================================================================== --- branches/v2_0_0/src/plugin.c 2006-07-17 05:50:28 UTC (rev 16503) +++ branches/v2_0_0/src/plugin.c 2006-07-17 05:50:49 UTC (rev 16504) @@ -843,8 +843,8 @@ } } - if (plugin->path != NULL) g_free(plugin->path); - if (plugin->error != NULL) g_free(plugin->error); + g_free(plugin->path); + g_free(plugin->error); GAIM_DBUS_UNREGISTER_POINTER(plugin); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-17 06:22:12
|
Revision: 16506 Author: thekingant Date: 2006-07-16 23:22:09 -0700 (Sun, 16 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16506&view=rev Log Message: ----------- Backport SVN revision #16505 from HEAD to v2_0_0 Original commit message: Change the music messaging plugin to not try to load if our D-BUS stuff is not initialized. Also extracted the gaim_notify_error() message code to a #define in src/dbus-server.c And print a debug warning if something tries to register a callback for a signal using a handle that we don't have any registered signals for ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16505&view=rev Modified Paths: -------------- branches/v2_0_0/plugins/dbus-example.c branches/v2_0_0/plugins/musicmessaging/musicmessaging.c branches/v2_0_0/src/dbus-server.h branches/v2_0_0/src/signals.c Modified: branches/v2_0_0/plugins/dbus-example.c =================================================================== --- branches/v2_0_0/plugins/dbus-example.c 2006-07-17 06:21:53 UTC (rev 16505) +++ branches/v2_0_0/plugins/dbus-example.c 2006-07-17 06:22:09 UTC (rev 16506) @@ -109,17 +109,8 @@ static gboolean plugin_load(GaimPlugin *plugin) { - const char *dbus_init_error; + GAIM_DBUS_RETURN_FALSE_IF_DISABLED(plugin); - dbus_init_error = gaim_dbus_get_init_error(); - if (dbus_init_error != NULL) - { - gaim_notify_error(NULL, _("Unable to Load Plugin"), - _("Gaim's D-BUS server is not running for the reason listed below"), - _(dbus_init_error)); - return FALSE; - } - /* First, we have to register our four exported functions with the main gaim dbus loop. Without this statement, the gaim dbus code wouldn't know about our functions. */ Modified: branches/v2_0_0/plugins/musicmessaging/musicmessaging.c =================================================================== --- branches/v2_0_0/plugins/musicmessaging/musicmessaging.c 2006-07-17 06:21:53 UTC (rev 16505) +++ branches/v2_0_0/plugins/musicmessaging/musicmessaging.c 2006-07-17 06:22:09 UTC (rev 16506) @@ -259,6 +259,8 @@ plugin_load(GaimPlugin *plugin) { void *conv_list_handle; + GAIM_DBUS_RETURN_FALSE_IF_DISABLED(plugin); + /* First, we have to register our four exported functions with the main gaim dbus loop. Without this statement, the gaim dbus code wouldn't know about our functions. */ Modified: branches/v2_0_0/src/dbus-server.h =================================================================== --- branches/v2_0_0/src/dbus-server.h 2006-07-17 06:21:53 UTC (rev 16505) +++ branches/v2_0_0/src/dbus-server.h 2006-07-17 06:22:09 UTC (rev 16506) @@ -74,6 +74,17 @@ #define GAIM_DBUS_DEFINE_INHERITING_TYPE(type, parent) \ GaimDBusType GAIM_DBUS_TYPE_##type = { GAIM_DBUS_TYPE(parent) }; +#define GAIM_DBUS_RETURN_FALSE_IF_DISABLED(plugin) \ + if (gaim_dbus_get_init_error() != NULL) \ + { \ + gchar *title; \ + title = g_strdup_printf("Unable to Load %s Plugin", plugin->info->name); \ + gaim_notify_error(NULL, title, \ + _("Gaim's D-BUS server is not running for the reason listed below"), \ + _(gaim_dbus_get_init_error())); \ + g_free(title); \ + return FALSE; \ + } /** Initializes gaim dbus pointer registration engine. @@ -139,8 +150,9 @@ * NOT running then gaim_dbus_dispatch_init() failed for some reason, * and a message should have been gaim_debug_error()'ed. * - * This function should be called by any DBUS plugin before trying - * to use the DBUS API. See plugins/dbus-example.c for usage. + * Gaim plugins that use D-BUS should use the + * GAIM_DBUS_RETURN_FALSE_IF_DISABLED macro to short-circuit + * initialization if Gaim's D-BUS subsystem is not running. * * @return If the D-BUS subsystem started with no problems then this * will return NULL and everything will be hunky dory. If Modified: branches/v2_0_0/src/signals.c =================================================================== --- branches/v2_0_0/src/signals.c 2006-07-17 06:21:53 UTC (rev 16505) +++ branches/v2_0_0/src/signals.c 2006-07-17 06:22:09 UTC (rev 16506) @@ -267,7 +267,13 @@ instance_data = (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); - g_return_val_if_fail(instance_data != NULL, 0); + if (instance_data == NULL) + { + gaim_debug_warning("signals", "Something tried to register a callback " + "for the '%s' signal, but we do not have any signals " + "registered with the given handle\n", signal); + g_return_val_if_reached(0); + } /* Get the signal data */ signal_data = This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-18 06:34:10
|
Revision: 16516 Author: thekingant Date: 2006-07-17 23:34:06 -0700 (Mon, 17 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16516&view=rev Log Message: ----------- Backport SVN revision #16515 from HEAD to v2_0_0 Original commit message: Fix a tiny and rare memleak when unloading a plugin that was designed for an older version of Gaim. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16515&view=rev Modified Paths: -------------- branches/v2_0_0/plugins/dbus-example.c branches/v2_0_0/src/plugin.c branches/v2_0_0/src/protocols/msn/user.c Modified: branches/v2_0_0/plugins/dbus-example.c =================================================================== --- branches/v2_0_0/plugins/dbus-example.c 2006-07-18 06:33:36 UTC (rev 16515) +++ branches/v2_0_0/plugins/dbus-example.c 2006-07-18 06:34:06 UTC (rev 16516) @@ -152,7 +152,7 @@ GAIM_PRIORITY_DEFAULT, /**< priority */ "dbus-example", /**< id */ - N_("DBus"), /**< name */ + N_("DBus Example"), /**< name */ VERSION, /**< version */ /** summary */ N_("DBus Plugin Example"), Modified: branches/v2_0_0/src/plugin.c =================================================================== --- branches/v2_0_0/src/plugin.c 2006-07-18 06:33:36 UTC (rev 16515) +++ branches/v2_0_0/src/plugin.c 2006-07-18 06:34:06 UTC (rev 16516) @@ -772,12 +772,16 @@ * mismatch, but it's a lot better than trying to free something * we shouldn't, and crashing while trying to load an old plugin */ if(plugin->info == NULL || plugin->info->magic != GAIM_PLUGIN_MAGIC || - plugin->info->major_version != GAIM_MAJOR_VERSION) { + plugin->info->major_version != GAIM_MAJOR_VERSION) + { if(plugin->handle) g_module_close(plugin->handle); + g_free(plugin->path); + g_free(plugin->error); + GAIM_DBUS_UNREGISTER_POINTER(plugin); - + g_free(plugin); return; } Modified: branches/v2_0_0/src/protocols/msn/user.c =================================================================== --- branches/v2_0_0/src/protocols/msn/user.c 2006-07-18 06:33:36 UTC (rev 16515) +++ branches/v2_0_0/src/protocols/msn/user.c 2006-07-18 06:34:06 UTC (rev 16516) @@ -55,6 +55,12 @@ { g_return_if_fail(user != NULL); + /* + * TODO: If any GaimBuddy->proto_data pointers point to this + * MsnUser then set them to NULL. Or possibly even better, + * don't set GaimBuddy->proto_data in the first place. + */ + if (user->clientcaps != NULL) g_hash_table_destroy(user->clientcaps); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-20 08:12:23
|
Revision: 16526 Author: thekingant Date: 2006-07-20 01:12:17 -0700 (Thu, 20 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16526&view=rev Log Message: ----------- Backport SVN revision #16525 from HEAD to v2_0_0 Original commit message: A bunch of little things * Use GAIM_CONNECTION_IS_VALID(gc) in a lot of places where we were doing g_list_find(gaim_connections_get_all(), gc) * Get rid of a lot of places where we were doing g_list_find(gaim_connections_get_all(), gc). The handle used by the request API ensures that the ok and cancel callback functions won't be called if the gc is destroyed. However, GAIM_CONNECTION_IS_VALID(gc) is still very important for callback functions where we can't cancel the request. For example, gaim_proxy_connect() callback functions. * "Added" a function to Yahoo! that should help us notice when our buddies change their buddy icon/display picture * Some comments in a few places * Changed GAIM_CONNECTION_IS_VALID(gc) to only look through the list of "all" connections and not the list of "connecting" connections. Some time ago we changed how this was done so that the list of "all" connections now includes the "connection" connections. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16525&view=rev Modified Paths: -------------- branches/v2_0_0/src/buddyicon.h branches/v2_0_0/src/connection.h branches/v2_0_0/src/gtkblist.c branches/v2_0_0/src/protocols/jabber/jabber.c branches/v2_0_0/src/protocols/jabber/presence.c branches/v2_0_0/src/protocols/jabber/roster.c branches/v2_0_0/src/protocols/msn/dialog.c branches/v2_0_0/src/protocols/msn/userlist.c branches/v2_0_0/src/protocols/oscar/family_icbm.c branches/v2_0_0/src/protocols/oscar/oscar.c branches/v2_0_0/src/protocols/oscar/peer.c branches/v2_0_0/src/protocols/oscar/peer_proxy.c branches/v2_0_0/src/protocols/silc/silc.c branches/v2_0_0/src/protocols/yahoo/yahoo.c branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c branches/v2_0_0/src/protocols/yahoo/yahoo_picture.h branches/v2_0_0/src/proxy.c branches/v2_0_0/src/util.h Modified: branches/v2_0_0/src/buddyicon.h =================================================================== --- branches/v2_0_0/src/buddyicon.h 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/buddyicon.h 2006-07-20 08:12:17 UTC (rev 16526) @@ -42,6 +42,10 @@ int ref_count; /**< The buddy icon reference count. */ }; +#ifdef __cplusplus +extern "C" { +#endif + /**************************************************************************/ /** @name Buddy Icon API */ /**************************************************************************/ @@ -281,4 +285,8 @@ /*@}*/ +#ifdef __cplusplus +} +#endif + #endif /* _GAIM_BUDDYICON_H_ */ Modified: branches/v2_0_0/src/connection.h =================================================================== --- branches/v2_0_0/src/connection.h 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/connection.h 2006-07-20 08:12:17 UTC (rev 16526) @@ -271,7 +271,7 @@ * * @return @c TRUE if gc is valid. */ -#define GAIM_CONNECTION_IS_VALID(gc) (g_list_find(gaim_connections_get_all(), (gc)) || g_list_find(gaim_connections_get_connecting(), (gc))) +#define GAIM_CONNECTION_IS_VALID(gc) (g_list_find(gaim_connections_get_all(), (gc))) /*@}*/ Modified: branches/v2_0_0/src/gtkblist.c =================================================================== --- branches/v2_0_0/src/gtkblist.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/gtkblist.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -3419,6 +3419,13 @@ PangoLogAttr *log_attrs; gchar *word; + if (strcasecmp(key, "Global Thermonuclear War") == 0) + { + gaim_notify_info(NULL, "WOPR", + "Wouldn't you prefer a nice game of chess?", NULL); + return FALSE; + } + gtk_tree_model_get(model, iter, column, &withmarkup, -1); tmp = g_utf8_normalize(key, -1, G_NORMALIZE_DEFAULT); Modified: branches/v2_0_0/src/protocols/jabber/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/jabber/jabber.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -344,7 +344,8 @@ int len; static char buf[4096]; - if(!g_list_find(gaim_connections_get_all(), gc)) { + /* TODO: It should be possible to make this check unnecessary */ + if(!GAIM_CONNECTION_IS_VALID(gc)) { gaim_ssl_close(gsc); return; } Modified: branches/v2_0_0/src/protocols/jabber/presence.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/presence.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/jabber/presence.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -182,32 +182,30 @@ static void authorize_add_cb(struct _jabber_add_permit *jap) { - if(g_list_find(gaim_connections_get_all(), jap->gc)) { - GaimBuddy *buddy = NULL; + GaimBuddy *buddy = NULL; - jabber_presence_subscription_set(jap->gc->proto_data, jap->who, - "subscribed"); + jabber_presence_subscription_set(jap->gc->proto_data, jap->who, + "subscribed"); - buddy = gaim_find_buddy(jap->gc->account, jap->who); + buddy = gaim_find_buddy(jap->gc->account, jap->who); - if (buddy) { - JabberBuddy *jb = NULL; + if (buddy) { + JabberBuddy *jb = NULL; - jb = jabber_buddy_find(jap->js, jap->who, TRUE); + jb = jabber_buddy_find(jap->js, jap->who, TRUE); - if ((jb->subscription & JABBER_SUB_TO) == 0) { - gaim_account_request_add(jap->gc->account, + if ((jb->subscription & JABBER_SUB_TO) == 0) { + gaim_account_request_add(jap->gc->account, jap->who, NULL, - NULL, NULL); - } else { - gaim_account_notify_added(jap->gc->account, - jap->who, NULL, - NULL, NULL); - } + NULL, NULL); } else { - gaim_account_request_add(jap->gc->account, jap->who, - NULL, NULL, NULL); + gaim_account_notify_added(jap->gc->account, + jap->who, NULL, + NULL, NULL); } + } else { + gaim_account_request_add(jap->gc->account, jap->who, + NULL, NULL, NULL); } g_free(jap->who); @@ -216,10 +214,8 @@ static void deny_add_cb(struct _jabber_add_permit *jap) { - if(g_list_find(gaim_connections_get_all(), jap->gc)) { - jabber_presence_subscription_set(jap->gc->proto_data, jap->who, - "unsubscribed"); - } + jabber_presence_subscription_set(jap->gc->proto_data, jap->who, + "unsubscribed"); g_free(jap->who); g_free(jap); Modified: branches/v2_0_0/src/protocols/jabber/roster.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/roster.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/jabber/roster.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -104,7 +104,6 @@ gaim_blist_add_buddy(b, NULL, g, NULL); gaim_blist_alias_buddy(b, alias); - /* If we just learned about ourself, then fake our status, * because we won't be receiving a normal presence message * about ourself. */ @@ -117,8 +116,6 @@ jabber_presence_fake_to_self(js, status); } - - g_free(g2->data); g2 = g_slist_delete_link(g2, g2); } Modified: branches/v2_0_0/src/protocols/msn/dialog.c =================================================================== --- branches/v2_0_0/src/protocols/msn/dialog.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/msn/dialog.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -37,16 +37,12 @@ static void msn_add_cb(MsnAddRemData *data) { - if (g_list_find(gaim_connections_get_all(), data->gc) != NULL) - { - MsnSession *session = data->gc->proto_data; - MsnUserList *userlist = session->userlist; + MsnSession *session = data->gc->proto_data; + MsnUserList *userlist = session->userlist; - msn_userlist_add_buddy(userlist, data->who, MSN_LIST_FL, data->group); - } + msn_userlist_add_buddy(userlist, data->who, MSN_LIST_FL, data->group); - if (data->group != NULL) - g_free(data->group); + g_free(data->group); g_free(data->who); g_free(data); @@ -55,16 +51,12 @@ static void msn_rem_cb(MsnAddRemData *data) { - if (g_list_find(gaim_connections_get_all(), data->gc) != NULL) - { - MsnSession *session = data->gc->proto_data; - MsnUserList *userlist = session->userlist; + MsnSession *session = data->gc->proto_data; + MsnUserList *userlist = session->userlist; - msn_userlist_rem_buddy(userlist, data->who, MSN_LIST_FL, data->group); - } + msn_userlist_rem_buddy(userlist, data->who, MSN_LIST_FL, data->group); - if (data->group != NULL) - g_free(data->group); + g_free(data->group); g_free(data->who); g_free(data); Modified: branches/v2_0_0/src/protocols/msn/userlist.c =================================================================== --- branches/v2_0_0/src/protocols/msn/userlist.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/msn/userlist.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -40,23 +40,20 @@ static void msn_accept_add_cb(MsnPermitAdd *pa) { - if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL) - { - MsnSession *session = pa->gc->proto_data; - MsnUserList *userlist = session->userlist; - GaimBuddy *buddy; + MsnSession *session = pa->gc->proto_data; + MsnUserList *userlist = session->userlist; + GaimBuddy *buddy; - msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_AL, NULL); + msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_AL, NULL); - buddy = gaim_find_buddy(pa->gc->account, pa->who); + buddy = gaim_find_buddy(pa->gc->account, pa->who); - if (buddy != NULL) - gaim_account_notify_added(pa->gc->account, pa->who, - NULL, pa->friendly, NULL); - else - gaim_account_request_add(pa->gc->account, pa->who, - NULL, pa->friendly, NULL); - } + if (buddy != NULL) + gaim_account_notify_added(pa->gc->account, pa->who, + NULL, pa->friendly, NULL); + else + gaim_account_request_add(pa->gc->account, pa->who, + NULL, pa->friendly, NULL); g_free(pa->who); g_free(pa->friendly); @@ -66,13 +63,10 @@ static void msn_cancel_add_cb(MsnPermitAdd *pa) { - if (g_list_find(gaim_connections_get_all(), pa->gc) != NULL) - { - MsnSession *session = pa->gc->proto_data; - MsnUserList *userlist = session->userlist; + MsnSession *session = pa->gc->proto_data; + MsnUserList *userlist = session->userlist; - msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_BL, NULL); - } + msn_userlist_add_buddy(userlist, pa->who, MSN_LIST_BL, NULL); g_free(pa->who); g_free(pa->friendly); Modified: branches/v2_0_0/src/protocols/oscar/family_icbm.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/family_icbm.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/oscar/family_icbm.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -1718,9 +1718,9 @@ return ret; } -static void incomingim_ch2_buddylist(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) +static void +incomingim_ch2_buddylist(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) { - /* * This goes like this... * @@ -1740,7 +1740,8 @@ * ... * ... */ - while (servdata && byte_stream_empty(servdata)) { + while (byte_stream_empty(servdata)) + { guint16 gnlen, numb; int i; char *gn; @@ -1767,51 +1768,49 @@ return; } -static void incomingim_ch2_buddyicon_free(OscarData *od, IcbmArgsCh2 *args) +static void +incomingim_ch2_buddyicon_free(OscarData *od, IcbmArgsCh2 *args) { - free(args->info.icon.icon); return; } -static void incomingim_ch2_buddyicon(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) +static void +incomingim_ch2_buddyicon(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) { + args->info.icon.checksum = byte_stream_get32(servdata); + args->info.icon.length = byte_stream_get32(servdata); + args->info.icon.timestamp = byte_stream_get32(servdata); + args->info.icon.icon = byte_stream_getraw(servdata, args->info.icon.length); - if (servdata) { - args->info.icon.checksum = byte_stream_get32(servdata); - args->info.icon.length = byte_stream_get32(servdata); - args->info.icon.timestamp = byte_stream_get32(servdata); - args->info.icon.icon = byte_stream_getraw(servdata, args->info.icon.length); - } - args->destructor = (void *)incomingim_ch2_buddyicon_free; return; } -static void incomingim_ch2_chat_free(OscarData *od, IcbmArgsCh2 *args) +static void +incomingim_ch2_chat_free(OscarData *od, IcbmArgsCh2 *args) { - /* XXX - aim_chat_roominfo_free() */ free(args->info.chat.roominfo.name); return; } -static void incomingim_ch2_chat(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) +static void +incomingim_ch2_chat(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) { - /* * Chat room info. */ - if (servdata) - aim_chat_readroominfo(servdata, &args->info.chat.roominfo); + aim_chat_readroominfo(servdata, &args->info.chat.roominfo); args->destructor = (void *)incomingim_ch2_chat_free; } -static void incomingim_ch2_icqserverrelay_free(OscarData *od, IcbmArgsCh2 *args) +static void +incomingim_ch2_icqserverrelay_free(OscarData *od, IcbmArgsCh2 *args) { free((char *)args->info.rtfmsg.rtfmsg); } @@ -1824,12 +1823,13 @@ * Note that this is all little-endian. Cringe. * */ -static void incomingim_ch2_icqserverrelay(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) +static void +incomingim_ch2_icqserverrelay(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) { guint16 hdrlen, anslen, msglen; - if (servdata == NULL) - /* Odd... Oh well. */ + if (byte_stream_empty(servdata) < 24) + /* Someone sent us a short server relay ICBM. Weird. (Maybe?) */ return; hdrlen = byte_stream_getle16(servdata); @@ -1855,48 +1855,47 @@ args->destructor = (void *)incomingim_ch2_icqserverrelay_free; } -static void incomingim_ch2_sendfile_free(OscarData *od, IcbmArgsCh2 *args) +static void +incomingim_ch2_sendfile_free(OscarData *od, IcbmArgsCh2 *args) { free(args->info.sendfile.filename); } -static void incomingim_ch2_sendfile(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) +/* Someone is sending us a file */ +static void +incomingim_ch2_sendfile(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, aim_userinfo_t *userinfo, IcbmArgsCh2 *args, ByteStream *servdata) { + int flen; args->destructor = (void *)incomingim_ch2_sendfile_free; /* Maybe there is a better way to tell what kind of sendfile * this is? Maybe TLV t(000a)? */ - if (servdata) { /* Someone is sending us a file */ - int flen; - /* subtype is one of AIM_OFT_SUBTYPE_* */ - args->info.sendfile.subtype = byte_stream_get16(servdata); - args->info.sendfile.totfiles = byte_stream_get16(servdata); - args->info.sendfile.totsize = byte_stream_get32(servdata); + /* subtype is one of AIM_OFT_SUBTYPE_* */ + args->info.sendfile.subtype = byte_stream_get16(servdata); + args->info.sendfile.totfiles = byte_stream_get16(servdata); + args->info.sendfile.totsize = byte_stream_get32(servdata); - /* - * I hope to God I'm right when I guess that there is a - * 32 char max filename length for single files. I think - * OFT tends to do that. Gotta love inconsistency. I saw - * a 26 byte filename? - */ - /* AAA - create an byte_stream_getnullstr function (don't anymore)(maybe) */ - /* Use an inelegant way of getting the null-terminated filename, - * since there's no easy bstream routine. */ - for (flen = 0; byte_stream_get8(servdata); flen++); - byte_stream_advance(servdata, -flen -1); - args->info.sendfile.filename = byte_stream_getstr(servdata, flen); + /* + * I hope to God I'm right when I guess that there is a + * 32 char max filename length for single files. I think + * OFT tends to do that. Gotta love inconsistency. I saw + * a 26 byte filename? + */ + /* AAA - create an byte_stream_getnullstr function (don't anymore)(maybe) */ + /* Use an inelegant way of getting the null-terminated filename, + * since there's no easy bstream routine. */ + for (flen = 0; byte_stream_get8(servdata); flen++); + byte_stream_advance(servdata, -flen -1); + args->info.sendfile.filename = byte_stream_getstr(servdata, flen); - /* There is sometimes more after the null-terminated filename, - * but I'm unsure of its format. */ - /* I don't believe him. */ - /* There is sometimes a null byte inside a unicode filename, - * but as far as I can tell the filename is the last - * piece of data that will be in this message. --Jonathan */ - } - - return; + /* There is sometimes more after the null-terminated filename, + * but I'm unsure of its format. */ + /* I don't believe him. */ + /* There is sometimes a null byte inside a unicode filename, + * but as far as I can tell the filename is the last + * piece of data that will be in this message. --Jonathan */ } typedef void (*ch2_args_destructor_t)(OscarData *od, IcbmArgsCh2 *args); @@ -2071,24 +2070,24 @@ byte_stream_init(&sdbs, servdatatlv->value, servdatatlv->length); sdbsptr = &sdbs; + + /* + * The rest of the handling depends on what type it is. + * + * Not all of them have special handling (yet). + */ + if (args.type & OSCAR_CAPABILITY_BUDDYICON) + incomingim_ch2_buddyicon(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); + else if (args.type & OSCAR_CAPABILITY_SENDBUDDYLIST) + incomingim_ch2_buddylist(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); + else if (args.type & OSCAR_CAPABILITY_CHAT) + incomingim_ch2_chat(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); + else if (args.type & OSCAR_CAPABILITY_ICQSERVERRELAY) + incomingim_ch2_icqserverrelay(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); + else if (args.type & OSCAR_CAPABILITY_SENDFILE) + incomingim_ch2_sendfile(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); } - /* - * The rest of the handling depends on what type it is. - * - * Not all of them have special handling (yet). - */ - if (args.type & OSCAR_CAPABILITY_BUDDYICON) - incomingim_ch2_buddyicon(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); - else if (args.type & OSCAR_CAPABILITY_SENDBUDDYLIST) - incomingim_ch2_buddylist(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); - else if (args.type & OSCAR_CAPABILITY_CHAT) - incomingim_ch2_chat(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); - else if (args.type & OSCAR_CAPABILITY_ICQSERVERRELAY) - incomingim_ch2_icqserverrelay(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); - else if (args.type & OSCAR_CAPABILITY_SENDFILE) - incomingim_ch2_sendfile(od, conn, mod, frame, snac, userinfo, &args, sdbsptr); - if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, channel, userinfo, &args); Modified: branches/v2_0_0/src/protocols/oscar/oscar.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/oscar/oscar.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -954,7 +954,7 @@ new_conn_data = data; gc = new_conn_data->gc; - if (!g_list_find(gaim_connections_get_all(), gc)) + if (!GAIM_CONNECTION_IS_VALID(gc)) { if (source >= 0) close(source); @@ -2181,12 +2181,10 @@ gaim_auth_dontrequest(struct name_data *data) { GaimConnection *gc = data->gc; + GaimBuddy *b = gaim_find_buddy(gaim_connection_get_account(gc), data->name); - if (g_list_find(gaim_connections_get_all(), gc)) { - /* Remove from local list */ - GaimBuddy *b = gaim_find_buddy(gaim_connection_get_account(gc), data->name); - gaim_blist_remove_buddy(b); - } + /* Remove from local list */ + gaim_blist_remove_buddy(b); oscar_free_name_data(data); } @@ -2239,11 +2237,9 @@ gaim_auth_grant(struct name_data *data) { GaimConnection *gc = data->gc; + OscarData *od = gc->proto_data; - if (g_list_find(gaim_connections_get_all(), gc)) { - OscarData *od = gc->proto_data; - aim_ssi_sendauthreply(od, data->name, 0x01, NULL); - } + aim_ssi_sendauthreply(od, data->name, 0x01, NULL); oscar_free_name_data(data); } @@ -2253,11 +2249,9 @@ gaim_auth_dontgrant(struct name_data *data, char *msg) { GaimConnection *gc = data->gc; + OscarData *od = gc->proto_data; - if (g_list_find(gaim_connections_get_all(), gc)) { - OscarData *od = gc->proto_data; - aim_ssi_sendauthreply(od, data->name, 0x00, msg ? msg : _("No reason given.")); - } + aim_ssi_sendauthreply(od, data->name, 0x00, msg ? msg : _("No reason given.")); } static void @@ -2276,9 +2270,7 @@ { GaimConnection *gc = data->gc; - if (g_list_find(gaim_connections_get_all(), gc)) { - gaim_blist_request_add_buddy(gaim_connection_get_account(gc), data->name, NULL, data->nick); - } + gaim_blist_request_add_buddy(gaim_connection_get_account(gc), data->name, NULL, data->nick); oscar_free_name_data(data); } @@ -2779,7 +2771,11 @@ } break; default: { - gaim_debug_error("oscar", "Received unknown typing notification message from %s. Type1 is 0x%04x and type2 is 0x%04hx.\n", sn, type1, type2); + /* + * It looks like iChat sometimes sends typing notification + * with type1=0x0001 and type2=0x000f. Not sure why. + */ + gaim_debug_info("oscar", "Received unknown typing notification message from %s. Type1 is 0x%04x and type2 is 0x%04hx.\n", sn, type1, type2); } break; } Modified: branches/v2_0_0/src/protocols/oscar/peer.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/oscar/peer.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -481,7 +481,7 @@ conn = new_conn_data->conn; g_free(new_conn_data); - if (!g_list_find(gaim_connections_get_all(), gc)) + if (!GAIM_CONNECTION_IS_VALID(gc)) { if (source >= 0) close(source); @@ -573,7 +573,7 @@ conn = new_conn_data->conn; g_free(new_conn_data); - if (!g_list_find(gaim_connections_get_all(), gc)) + if (!GAIM_CONNECTION_IS_VALID(gc)) { if (listenerfd != -1) close(listenerfd); Modified: branches/v2_0_0/src/protocols/oscar/peer_proxy.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -337,7 +337,7 @@ conn = new_conn_data->conn; g_free(new_conn_data); - if (!g_list_find(gaim_connections_get_all(), gc)) + if (!GAIM_CONNECTION_IS_VALID(gc)) { if (source >= 0) close(source); Modified: branches/v2_0_0/src/protocols/silc/silc.c =================================================================== --- branches/v2_0_0/src/protocols/silc/silc.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/silc/silc.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -152,28 +152,24 @@ const char *dfile; g_return_if_fail(gc != NULL); - sg = gc->proto_data; + if (!GAIM_CONNECTION_IS_VALID(gc)) { + close(source); + return; + } + if (source < 0) { gaim_connection_error(gc, _("Connection failed")); return; } + sg = gc->proto_data; if (sg == NULL) return; client = sg->client; account = sg->account; - if (!g_list_find(gaim_connections_get_all(), gc)) { - close(source); - g_source_remove(sg->scheduler); - silc_client_stop(sg->client); - silc_client_free(sg->client); - silc_free(sg); - return; - } - /* Get session detachment data, if available */ memset(¶ms, 0, sizeof(params)); dfile = silcgaim_session_file(gaim_account_get_username(sg->account)); Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -810,6 +810,7 @@ if (!msg || !g_utf8_validate(msg, -1, NULL)) return; + /* TODO: Does this really need to be escaped? It seems like it doesn't. */ escmsg = g_markup_escape_text(msg, -1); prim = g_strdup_printf(_("Yahoo! system message for %s:"), @@ -2132,6 +2133,9 @@ case YAHOO_SERVICE_PICTURE_UPLOAD: yahoo_process_picture_upload(gc, pkt); break; + case YAHOO_SERVICE_AVATAR_UPDATE: + yahoo_process_avatar_update(gc, pkt); + break; case YAHOO_SERVICE_AUDIBLE: yahoo_process_audible(gc, pkt); break; @@ -2234,7 +2238,7 @@ struct yahoo_data *yd; struct yahoo_packet *pkt; - if (!g_list_find(gaim_connections_get_all(), gc)) { + if (!GAIM_CONNECTION_IS_VALID(gc)) { close(source); return; } @@ -2261,7 +2265,7 @@ struct yahoo_data *yd; struct yahoo_packet *pkt; - if (!g_list_find(gaim_connections_get_all(), gc)) { + if (!GAIM_CONNECTION_IS_VALID(gc)) { close(source); return; } Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -225,6 +225,50 @@ } } +void yahoo_process_avatar_update(GaimConnection *gc, struct yahoo_packet *pkt) +{ + GSList *l = pkt->hash; + char *who = NULL; + int avatar = 0; + + while (l) { + struct yahoo_pair *pair = l->data; + + switch (pair->key) { + case 4: + who = pair->value; + break; + case 5: + /* us */ + break; + case 206: + /* + * 0 - No icon or avatar + * 1 - Using an avatar + * 2 - Using an icon + */ + avatar = strtol(pair->value, NULL, 10); + break; + } + l = l->next; + } + + if (who) { + if (avatar == 2) + yahoo_send_picture_request(gc, who); + else if ((avatar == 0) || (avatar == 1)) { + GaimBuddy *b = gaim_find_buddy(gc->account, who); + YahooFriend *f; + gaim_buddy_icons_set_for_user(gc->account, who, NULL, 0); + if (b) + gaim_blist_node_remove_setting((GaimBlistNode *)b, YAHOO_ICON_CHECKSUM_KEY); + if ((f = yahoo_friend_find(gc, who))) + yahoo_friend_set_buddy_icon_need_request(f, TRUE); + gaim_debug_misc("yahoo", "Setting user %s's icon to NULL.\n", who); + } + } +} + void yahoo_send_picture_info(GaimConnection *gc, const char *who) { struct yahoo_data *yd = gc->proto_data; Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_picture.h =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_picture.h 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_picture.h 2006-07-20 08:12:17 UTC (rev 16526) @@ -35,6 +35,8 @@ void yahoo_process_picture_checksum(GaimConnection *gc, struct yahoo_packet *pkt); void yahoo_process_picture_upload(GaimConnection *gc, struct yahoo_packet *pkt); +void yahoo_process_avatar_update(GaimConnection *gc, struct yahoo_packet *pkt); + void yahoo_set_buddy_icon(GaimConnection *gc, const char *iconfile); void yahoo_buddy_icon_upload(GaimConnection *gc, struct yahoo_buddy_icon_upload_data *d); void yahoo_buddy_icon_upload_data_free(struct yahoo_buddy_icon_upload_data *d); Modified: branches/v2_0_0/src/proxy.c =================================================================== --- branches/v2_0_0/src/proxy.c 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/proxy.c 2006-07-20 08:12:17 UTC (rev 16526) @@ -86,9 +86,9 @@ { g_return_if_fail(info != NULL); - if (info->host != NULL) g_free(info->host); - if (info->username != NULL) g_free(info->username); - if (info->password != NULL) g_free(info->password); + g_free(info->host); + g_free(info->username); + g_free(info->password); g_free(info); } @@ -106,8 +106,7 @@ { g_return_if_fail(info != NULL); - if (info->host != NULL) - g_free(info->host); + g_free(info->host); info->host = (host == NULL ? NULL : g_strdup(host)); } @@ -125,8 +124,7 @@ { g_return_if_fail(info != NULL); - if (info->username != NULL) - g_free(info->username); + g_free(info->username); info->username = (username == NULL ? NULL : g_strdup(username)); } @@ -136,8 +134,7 @@ { g_return_if_fail(info != NULL); - if (info->password != NULL) - g_free(info->password); + g_free(info->password); info->password = (password == NULL ? NULL : g_strdup(password)); } @@ -303,7 +300,7 @@ trap_gdb_bug() { const char *message = - "Gaim's DNS child got a SIGTRAP signal. \n" + "Gaim's DNS child got a SIGTRAP signal.\n" "This can be caused by trying to run gaim inside gdb.\n" "There is a known gdb bug which prevents this. Supposedly gaim\n" "should have detected you were using gdb and used an ugly hack,\n" @@ -2318,6 +2315,12 @@ return gpi; } +/* + * TODO: It would be really good if this returned some sort of handle + * that we could use to cancel the connection. As it is now, + * each callback has to check to make sure gc is still valid. + * And that is ugly. + */ int gaim_proxy_connect(GaimAccount *account, const char *host, int port, GaimInputFunction func, gpointer data) Modified: branches/v2_0_0/src/util.h =================================================================== --- branches/v2_0_0/src/util.h 2006-07-20 08:11:54 UTC (rev 16525) +++ branches/v2_0_0/src/util.h 2006-07-20 08:12:17 UTC (rev 16526) @@ -343,11 +343,12 @@ * in a GData hash table. The names of the attributes are lower-cased * in the hash table, and the name of the tag is case insensitive. * - * @param needle the name of the tag - * @param haystack the null-delimited string to search in - * @param start a pointer to the start of the tag if found - * @param end a pointer to the end of the tag if found - * @param attributes the attributes, if the tag was found + * @param needle The name of the tag + * @param haystack The null-delimited string to search in + * @param start A pointer to the start of the tag if found + * @param end A pointer to the end of the tag if found + * @param attributes The attributes, if the tag was found. This should + * be freed with g_datalist_clear(). * @return TRUE if the tag was found */ gboolean gaim_markup_find_tag(const char *needle, const char *haystack, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-24 04:31:28
|
Revision: 16557 Author: thekingant Date: 2006-07-23 21:31:25 -0700 (Sun, 23 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16557&view=rev Log Message: ----------- Backport SVN revision #16556 from HEAD to v2_0_0 Original commit message: Fix a minor case of accessing something that had been free'd in oscar, and some other minor cleanup. FYI "0" is a valid file descriptor, but it will pretty much always be STDOUT, STDERR or STDIN. But I like to check for -1 anyway, because I'm weird. ViewCVS Links: ------------- http://svn.sourceforge.net/gaim/?rev=16556&view=rev Modified Paths: -------------- branches/v2_0_0/src/protocols/oscar/flap_connection.c branches/v2_0_0/src/protocols/oscar/odc.c branches/v2_0_0/src/protocols/oscar/oscar.h branches/v2_0_0/src/sslconn.c Modified: branches/v2_0_0/src/protocols/oscar/flap_connection.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/flap_connection.c 2006-07-24 04:27:42 UTC (rev 16556) +++ branches/v2_0_0/src/protocols/oscar/flap_connection.c 2006-07-24 04:31:25 UTC (rev 16557) @@ -205,7 +205,6 @@ flap_connection_destroy_rates(conn->rates); od->oscar_connections = g_list_remove(od->oscar_connections, conn); - g_free(conn); account = gaim_connection_get_account(od->gc); @@ -227,12 +226,18 @@ else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) tmp = _("Could not establish a connection with the server."); else + /* + * We shouldn't print a message for some disconnect_reasons. + * Like OSCAR_DISCONNECT_LOCAL_CLOSED. + */ tmp = NULL; if (tmp != NULL) gaim_connection_error(od->gc, tmp); } + g_free(conn); + return FALSE; } Modified: branches/v2_0_0/src/protocols/oscar/odc.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/odc.c 2006-07-24 04:27:42 UTC (rev 16556) +++ branches/v2_0_0/src/protocols/oscar/odc.c 2006-07-24 04:31:25 UTC (rev 16557) @@ -37,25 +37,15 @@ const gchar *tmp; if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_CLOSED) - { tmp = _("The remote user has closed the connection."); - } else if (conn->disconnect_reason == OSCAR_DISCONNECT_REMOTE_REFUSED) - { tmp = _("The remote user has declined your request."); - } else if (conn->disconnect_reason == OSCAR_DISCONNECT_LOST_CONNECTION) - { tmp = _("Lost connection with the remote user for an unknown reason."); - } else if (conn->disconnect_reason == OSCAR_DISCONNECT_INVALID_DATA) - { tmp = _("Received invalid data on connection with remote user."); - } else if (conn->disconnect_reason == OSCAR_DISCONNECT_COULD_NOT_CONNECT) - { tmp = _("Could not establish a connection with the remote user."); - } else /* * We shouldn't print a message for some disconnect_reasons. Modified: branches/v2_0_0/src/protocols/oscar/oscar.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.h 2006-07-24 04:27:42 UTC (rev 16556) +++ branches/v2_0_0/src/protocols/oscar/oscar.h 2006-07-24 04:31:25 UTC (rev 16557) @@ -287,14 +287,14 @@ typedef enum { - OSCAR_DISCONNECT_DONE, - OSCAR_DISCONNECT_LOCAL_CLOSED, + OSCAR_DISCONNECT_DONE, /* not considered an error */ + OSCAR_DISCONNECT_LOCAL_CLOSED, /* peer connections only, not considered an error */ OSCAR_DISCONNECT_REMOTE_CLOSED, - OSCAR_DISCONNECT_REMOTE_REFUSED, + OSCAR_DISCONNECT_REMOTE_REFUSED, /* peer connections only */ OSCAR_DISCONNECT_LOST_CONNECTION, OSCAR_DISCONNECT_INVALID_DATA, OSCAR_DISCONNECT_COULD_NOT_CONNECT, - OSCAR_DISCONNECT_RETRYING + OSCAR_DISCONNECT_RETRYING /* peer connections only */ } OscarDisconnectReason; typedef enum Modified: branches/v2_0_0/src/sslconn.c =================================================================== --- branches/v2_0_0/src/sslconn.c 2006-07-24 04:27:42 UTC (rev 16556) +++ branches/v2_0_0/src/sslconn.c 2006-07-24 04:31:25 UTC (rev 16557) @@ -137,7 +137,7 @@ GaimSslConnection *gsc; GaimSslOps *ops; - g_return_val_if_fail(fd > 0, NULL); + g_return_val_if_fail(fd != -1, NULL); g_return_val_if_fail(func != NULL, NULL); g_return_val_if_fail(gaim_ssl_is_supported(), NULL); @@ -178,12 +178,10 @@ if (ops != NULL && ops->close != NULL) (ops->close)(gsc); - if (gsc->fd) + if (gsc->fd != -1) close(gsc->fd); - if (gsc->host != NULL) - g_free(gsc->host); - + g_free(gsc->host); g_free(gsc); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-07-25 17:47:09
|
Revision: 16574 Author: seanegan Date: 2006-07-25 10:46:58 -0700 (Tue, 25 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16574&view=rev Log Message: ----------- Backport to 2.0.0 Modified Paths: -------------- branches/v2_0_0/src/gtkconv.c branches/v2_0_0/src/gtkconv.h branches/v2_0_0/src/log.c Modified: branches/v2_0_0/src/gtkconv.c =================================================================== --- branches/v2_0_0/src/gtkconv.c 2006-07-25 17:34:29 UTC (rev 16573) +++ branches/v2_0_0/src/gtkconv.c 2006-07-25 17:46:58 UTC (rev 16574) @@ -3811,10 +3811,9 @@ GtkWidget *vbox, *hbox, *frame; GtkWidget *imhtml_sw; GtkPolicyType imhtml_sw_hscroll; - GtkWidget *lbox, *bbox; + GtkWidget *lbox; GtkWidget *label; GtkWidget *list; - GtkWidget *button; GtkWidget *sw; GtkListStore *ls; GtkCellRenderer *rend; @@ -3963,48 +3962,6 @@ gtk_container_add(GTK_CONTAINER(sw), list); - /* Setup the user list toolbar. */ - bbox = gtk_hbox_new(TRUE, GAIM_HIG_BOX_SPACE); - gtk_box_pack_start(GTK_BOX(lbox), bbox, FALSE, FALSE, 0); - gtk_widget_show(bbox); - - /* IM */ - button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_IM, - GAIM_BUTTON_VERTICAL); - gtkchat->userlist_im = button; - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(gtkconv->tooltips, button, _("IM the user"), NULL); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(chat_im_button_cb), gtkconv); - - gtk_widget_show(button); - - /* Ignore */ - button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_IGNORE, - GAIM_BUTTON_VERTICAL); - gtkchat->userlist_ignore = button; - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(gtkconv->tooltips, button, - _("Ignore the user"), NULL); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(ignore_cb), gtkconv); - gtk_widget_show(button); - - /* Info */ - button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_INFO, - GAIM_BUTTON_VERTICAL); - gtkchat->userlist_info = button; - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_tooltips_set_tip(gtkconv->tooltips, button, - _("Get the user's information"), NULL); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(info_cb), gtkconv); - - gtk_widget_show(button); - /* Setup the bottom half of the conversation window */ vbox = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, TRUE); @@ -5518,13 +5475,7 @@ (gaim_blist_find_chat(account, gaim_conversation_get_name(conv)) != NULL)); } - /* Deal with chat userlist buttons */ - if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) - { - gtk_widget_set_sensitive(gtkconv->u.chat->userlist_im, TRUE); - gtk_widget_set_sensitive(gtkconv->u.chat->userlist_ignore, TRUE); - gtk_widget_set_sensitive(gtkconv->u.chat->userlist_info, (prpl_info->get_info != NULL)); - } + } else { /* Account is offline */ /* Or it's a chat that we've left. */ @@ -5540,14 +5491,6 @@ gtk_widget_set_sensitive(win->menu.remove, FALSE); gtk_widget_set_sensitive(win->menu.insert_link, TRUE); gtk_widget_set_sensitive(win->menu.insert_image, FALSE); - - /* Deal with chat userlist buttons */ - if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) - { - gtk_widget_set_sensitive(gtkconv->u.chat->userlist_im, FALSE); - gtk_widget_set_sensitive(gtkconv->u.chat->userlist_ignore, FALSE); - gtk_widget_set_sensitive(gtkconv->u.chat->userlist_info, FALSE); - } } /* @@ -6507,7 +6450,13 @@ "GaimGtkWindow *")); gaim_signal_register(handle, "conversation-timestamp", - gaim_marshal_POINTER__POINTER_POINTER, +#if SIZEOF_TIME_T == 4 + gaim_marshal_POINTER__POINTER_INT, +#elif SIZEOF_TIME_T == 8 + gaim_marshal_POINTER__POINTER_INT64, +#else +#error Unkown size of time_t +#endif gaim_value_new(GAIM_TYPE_POINTER), 2, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONVERSATION), Modified: branches/v2_0_0/src/gtkconv.h =================================================================== --- branches/v2_0_0/src/gtkconv.h 2006-07-25 17:34:29 UTC (rev 16573) +++ branches/v2_0_0/src/gtkconv.h 2006-07-25 17:46:58 UTC (rev 16574) @@ -102,9 +102,6 @@ GtkWidget *count; GtkWidget *list; GtkWidget *topic_text; - GtkWidget *userlist_im; - GtkWidget *userlist_ignore; - GtkWidget *userlist_info; }; /** Modified: branches/v2_0_0/src/log.c =================================================================== --- branches/v2_0_0/src/log.c 2006-07-25 17:34:29 UTC (rev 16573) +++ branches/v2_0_0/src/log.c 2006-07-25 17:46:58 UTC (rev 16574) @@ -593,7 +593,13 @@ gaim_log_logger_add(old_logger); gaim_signal_register(handle, "log-timestamp", - gaim_marshal_POINTER__POINTER_POINTER, +#if SIZEOF_TIME_T == 4 + gaim_marshal_POINTER__POINTER_INT, +#elif SIZEOF_TIME_T == 8 + gaim_marshal_POINTER__POINTER_INT64, +#else +#error Unknown size of time_t +#endif gaim_value_new(GAIM_TYPE_POINTER), 2, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_LOG), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-07-28 02:00:15
|
Revision: 16581 Author: thekingant Date: 2006-07-25 23:42:59 -0700 (Tue, 25 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16581&view=rev Log Message: ----------- Make v2_0_0 compile by reverting two changes Sean just made Modified Paths: -------------- branches/v2_0_0/src/gtkconv.c branches/v2_0_0/src/log.c Modified: branches/v2_0_0/src/gtkconv.c =================================================================== --- branches/v2_0_0/src/gtkconv.c 2006-07-26 04:03:34 UTC (rev 16580) +++ branches/v2_0_0/src/gtkconv.c 2006-07-26 06:42:59 UTC (rev 16581) @@ -6450,13 +6450,7 @@ "GaimGtkWindow *")); gaim_signal_register(handle, "conversation-timestamp", -#if SIZEOF_TIME_T == 4 - gaim_marshal_POINTER__POINTER_INT, -#elif SIZEOF_TIME_T == 8 - gaim_marshal_POINTER__POINTER_INT64, -#else -#error Unkown size of time_t -#endif + gaim_marshal_POINTER__POINTER_POINTER, gaim_value_new(GAIM_TYPE_POINTER), 2, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_CONVERSATION), Modified: branches/v2_0_0/src/log.c =================================================================== --- branches/v2_0_0/src/log.c 2006-07-26 04:03:34 UTC (rev 16580) +++ branches/v2_0_0/src/log.c 2006-07-26 06:42:59 UTC (rev 16581) @@ -593,13 +593,7 @@ gaim_log_logger_add(old_logger); gaim_signal_register(handle, "log-timestamp", -#if SIZEOF_TIME_T == 4 - gaim_marshal_POINTER__POINTER_INT, -#elif SIZEOF_TIME_T == 8 - gaim_marshal_POINTER__POINTER_INT64, -#else -#error Unknown size of time_t -#endif + gaim_marshal_POINTER__POINTER_POINTER, gaim_value_new(GAIM_TYPE_POINTER), 2, gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_LOG), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-03 07:26:51
|
Revision: 16623 Author: thekingant Date: 2006-08-03 00:26:47 -0700 (Thu, 03 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16623&view=rev Log Message: ----------- Backport SVN revisions 16521, 16527 and 16554 from HEAD to v2_0_0 These are aaronsheldon's chat speed improvements Original commit messages: Merges soc-2006-chat-speed into trunk. (r16371:r16435) Joining large chat rooms, like IRC rooms, is much quicker. Additional improvment should be seen when using >=GTK+-2.6. Sadrul sent me this patch to look over and then commit. It fixes a PRPL leak in Yahoo's chat and fixes a few other memory leaks that were mostly my fault. Updating the API changelog to reflect the chat-speed merge changes. Modified Paths: -------------- branches/v2_0_0/plugins/ChangeLog.API branches/v2_0_0/src/conversation.c branches/v2_0_0/src/conversation.h branches/v2_0_0/src/gtkconv.c branches/v2_0_0/src/gtkconv.h branches/v2_0_0/src/protocols/yahoo/yahoochat.c Modified: branches/v2_0_0/plugins/ChangeLog.API =================================================================== --- branches/v2_0_0/plugins/ChangeLog.API 2006-08-03 07:16:35 UTC (rev 16622) +++ branches/v2_0_0/plugins/ChangeLog.API 2006-08-03 07:26:47 UTC (rev 16623) @@ -43,9 +43,11 @@ const char *name, const char *alias * gaim_conv_chat_add_users(), added extra_msgs and new_arrivals (pass NULL and FALSE respectively, to get the same behavior as before) - * chat_add_users in GaimConversationUiOps, added flags, aliases, - and new_arrivals + * chat_add_users in GaimConversationUiOps, added cbuddies and + new_arrivals and removed buddies. * chat_rename_user in GaimConversationUiOps, added new_alias + * gaim_conv_chat_cb_new(), added alias. (pass NULL to get the same + behavior as before). * GaimConversation.log became GList * GaimConversation.logs, so that a conversation can have multiple logs at once * gaim_conv_chat_add_user, added extra_msgs Modified: branches/v2_0_0/src/conversation.c =================================================================== --- branches/v2_0_0/src/conversation.c 2006-08-03 07:16:35 UTC (rev 16622) +++ branches/v2_0_0/src/conversation.c 2006-08-03 07:26:47 UTC (rev 16623) @@ -38,7 +38,6 @@ static GList *chats = NULL; static GaimConversationUiOps *default_ops = NULL; - void gaim_conversations_set_ui_ops(GaimConversationUiOps *ops) { @@ -1441,17 +1440,56 @@ g_list_free(flags2); } +int +gaim_conv_chat_cb_compare(GaimConvChatBuddy *a, GaimConvChatBuddy *b) +{ + GaimConvChatBuddyFlags f1 = 0, f2 = 0; + char *user1 = NULL, *user2 = NULL; + gint ret = 0; + + + if (a) { + f1 = a->flags; + if (a->alias_key) + user1 = a->alias_key; + else if (a->name) + user1 = a->name; + } + + if (b) { + f2 = b->flags; + if (b->alias_key) + user2 = b->alias_key; + else if (b->name) + user2 = b->name; + } + + if (user1 == NULL || user2 == NULL) { + if (!(user1 == NULL && user2 == NULL)) + ret = (user1 == NULL) ? -1: 1; + } else if (f1 != f2) { + /* sort more important users first */ + ret = (f1 > f2) ? -1 : 1; + } else if (a->buddy != b->buddy) { + ret = a->buddy ? -1 : 1; + } else { + ret = strcasecmp(user1, user2); + } + + return ret; +} + void gaim_conv_chat_add_users(GaimConvChat *chat, GList *users, GList *extra_msgs, GList *flags, gboolean new_arrivals) { GaimConversation *conv; GaimConversationUiOps *ops; - GaimConvChatBuddy *cb; + GaimConvChatBuddy *cbuddy; GaimConnection *gc; GaimPluginProtocolInfo *prpl_info; GList *ul, *fl; - GList *aliases = NULL; + GList *cbuddies = NULL; g_return_if_fail(chat != NULL); g_return_if_fail(users != NULL); @@ -1470,7 +1508,7 @@ const char *user = (const char *)ul->data; const char *alias = user; gboolean quiet; - GaimConvChatBuddyFlags flags = GPOINTER_TO_INT(fl->data); + GaimConvChatBuddyFlags flag = GPOINTER_TO_INT(fl->data); const char *extra_msg = (extra_msgs ? extra_msgs->data : NULL); if (!strcmp(chat->nick, gaim_normalize(conv->account, user))) { @@ -1490,15 +1528,16 @@ } quiet = GPOINTER_TO_INT(gaim_signal_emit_return_1(gaim_conversations_get_handle(), - "chat-buddy-joining", conv, user, flags)) | + "chat-buddy-joining", conv, user, flag)) | gaim_conv_chat_is_user_ignored(chat, user); - cb = gaim_conv_chat_cb_new(user, flags); + cbuddy = gaim_conv_chat_cb_new(user, alias, flag); + /* This seems dumb. Why should we set users thousands of times? */ gaim_conv_chat_set_users(chat, - g_list_prepend(gaim_conv_chat_get_users(chat), cb)); - /* We reverse this later to keep it in the same order as users. */ - aliases = g_list_prepend(aliases, (char *)alias); + g_list_prepend(gaim_conv_chat_get_users(chat), cbuddy)); + cbuddies = g_list_prepend(cbuddies, cbuddy); + if (!quiet && new_arrivals) { char *escaped = g_markup_escape_text(alias, -1); char *tmp; @@ -1518,21 +1557,19 @@ } gaim_signal_emit(gaim_conversations_get_handle(), - "chat-buddy-joined", conv, user, flags, new_arrivals); + "chat-buddy-joined", conv, user, flag, new_arrivals); ul = ul->next; fl = fl->next; if (extra_msgs != NULL) extra_msgs = extra_msgs->next; } - /* This needs to be in the same order as users, but it's faster - * to prepend, so we do that above. */ - aliases = g_list_reverse(aliases); - + cbuddies = g_list_sort(cbuddies, (GCompareFunc)gaim_conv_chat_cb_compare); + if (ops != NULL && ops->chat_add_users != NULL) - ops->chat_add_users(conv, users, flags, aliases, new_arrivals); + ops->chat_add_users(conv, cbuddies, new_arrivals); - g_list_free(aliases); + g_list_free(cbuddies); } void @@ -1562,7 +1599,7 @@ g_return_if_fail(prpl_info != NULL); flags = gaim_conv_chat_user_get_flags(chat, old_user); - cb = gaim_conv_chat_cb_new(new_user, flags); + cb = gaim_conv_chat_cb_new(new_user, NULL, flags); gaim_conv_chat_set_users(chat, g_list_prepend(gaim_conv_chat_get_users(chat), cb)); @@ -1873,9 +1910,8 @@ return chat->left; } - GaimConvChatBuddy * -gaim_conv_chat_cb_new(const char *name, GaimConvChatBuddyFlags flags) +gaim_conv_chat_cb_new(const char *name, const char *alias, GaimConvChatBuddyFlags flags) { GaimConvChatBuddy *cb; @@ -1884,6 +1920,10 @@ cb = g_new0(GaimConvChatBuddy, 1); cb->name = g_strdup(name); cb->flags = flags; + if (alias) + cb->alias = g_strdup(alias); + else + cb->alias = NULL; GAIM_DBUS_REGISTER_POINTER(cb, GaimConvChatBuddy); return cb; Modified: branches/v2_0_0/src/conversation.h =================================================================== --- branches/v2_0_0/src/conversation.h 2006-08-03 07:16:35 UTC (rev 16622) +++ branches/v2_0_0/src/conversation.h 2006-08-03 07:26:47 UTC (rev 16623) @@ -158,8 +158,8 @@ const char *message, GaimMessageFlags flags, time_t mtime); - void (*chat_add_users)(GaimConversation *conv, GList *users, - GList *flags, GList *aliases, gboolean new_arrivals); + void (*chat_add_users)(GaimConversation *conv, GList *cbuddies, gboolean new_arrivals); + void (*chat_rename_user)(GaimConversation *conv, const char *old_name, const char *new_name, const char *new_alias); void (*chat_remove_users)(GaimConversation *conv, GList *users); @@ -214,6 +214,9 @@ struct _GaimConvChatBuddy { char *name; /**< The name */ + char *alias; /**< The alias */ + char *alias_key; /**< The alias key */ + gboolean buddy; /**< ChatBuddy is on the blist */ GaimConvChatBuddyFlags flags; /**< Flags (ops, voice etc.) */ }; @@ -1133,11 +1136,12 @@ * Creates a new chat buddy * * @param name The name. + * @param alias The alias. * @param flags The flags. * * @return The new chat buddy */ -GaimConvChatBuddy *gaim_conv_chat_cb_new(const char *name, +GaimConvChatBuddy *gaim_conv_chat_cb_new(const char *name, const char *alias, GaimConvChatBuddyFlags flags); /** Modified: branches/v2_0_0/src/gtkconv.c =================================================================== --- branches/v2_0_0/src/gtkconv.c 2006-08-03 07:16:35 UTC (rev 16622) +++ branches/v2_0_0/src/gtkconv.c 2006-08-03 07:26:47 UTC (rev 16623) @@ -154,8 +154,7 @@ static void got_typing_keypress(GaimGtkConversation *gtkconv, gboolean first); static void gray_stuff_out(GaimGtkConversation *gtkconv); static GList *generate_invite_user_names(GaimConnection *gc); -static void add_chat_buddy_common(GaimConversation *conv, const char *name, - GaimConvChatBuddyFlags flags, const char *alias, const char *old_name); +static void add_chat_buddy_common(GaimConversation *conv, GaimConvChatBuddy *cb, const char *old_name); static gboolean tab_complete(GaimConversation *conv); static void gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type); static void gtkconv_set_unseen(GaimGtkConversation *gtkconv, GaimUnseenState state); @@ -1394,6 +1393,7 @@ { GaimConversation *conv = gtkconv->active_conv; GaimGtkChatPane *gtkchat; + GaimConvChatBuddy *cbuddy; GaimConvChat *chat; GaimConvChatBuddyFlags flags; GtkTreeIter iter; @@ -1424,7 +1424,9 @@ else gaim_conv_chat_ignore(chat, name); - add_chat_buddy_common(conv, name, flags, alias, NULL); + cbuddy = gaim_conv_chat_cb_new(name, alias, flags); + + add_chat_buddy_common(conv, cbuddy, NULL); g_free(name); g_free(alias); } @@ -3288,7 +3290,7 @@ } static void -add_chat_buddy_common(GaimConversation *conv, const char *name, GaimConvChatBuddyFlags flags, const char *alias, const char *old_name) +add_chat_buddy_common(GaimConversation *conv, GaimConvChatBuddy *cb, const char *old_name) { GaimGtkConversation *gtkconv; GaimGtkChatPane *gtkchat; @@ -3300,6 +3302,12 @@ GtkTreeIter iter; gboolean is_me = FALSE; gboolean is_buddy; + gchar *alias_key, *name, *alias; + int flags; + + alias = cb->alias; + name = cb->name; + flags = GPOINTER_TO_INT(cb->flags); chat = GAIM_CONV_CHAT(conv); gtkconv = GAIM_GTK_CONVERSATION(conv); @@ -3318,36 +3326,79 @@ is_buddy = (gaim_find_buddy(conv->account, name) != NULL); - gtk_list_store_append(ls, &iter); + alias_key = g_utf8_collate_key(alias, strlen(alias)); if (is_me) { GdkColor send_color; gdk_color_parse(SEND_COLOR, &send_color); - + +#if GTK_CHECK_VERSION(2,6,0) + gtk_list_store_insert_with_values + (ls, + &iter, +/* + * The GTK docs are mute about the effects of the "row" value for performance. + * X-Chat hardcodes their value to 0 (prepend) and -1 (append), so we will too. + * It *might* be faster to search the gtk_list_store and set row accurately, + * but no one in #gtk+ seems to know anything about it either. + * Inserting in the "wrong" location has no visible ill effects. - F.P. + */ + -1, /* "row" */ + CHAT_USERS_ICON_COLUMN, pixbuf, + CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, + CHAT_USERS_NAME_COLUMN, name, + CHAT_USERS_FLAGS_COLUMN, flags, + CHAT_USERS_COLOR_COLUMN, &send_color, + CHAT_USERS_BUDDY_COLUMN, is_buddy, + -1); + } + else { + gtk_list_store_insert_with_values + (ls, + &iter, + -1, /* "row" */ + CHAT_USERS_ICON_COLUMN, pixbuf, + CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, + CHAT_USERS_NAME_COLUMN, name, + CHAT_USERS_FLAGS_COLUMN, flags, + CHAT_USERS_COLOR_COLUMN, get_nick_color(gtkconv, name), + CHAT_USERS_BUDDY_COLUMN, is_buddy, + -1); + +#else + gtk_list_store_append(ls, &iter); gtk_list_store_set(ls, &iter, CHAT_USERS_ICON_COLUMN, pixbuf, CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, CHAT_USERS_NAME_COLUMN, name, CHAT_USERS_FLAGS_COLUMN, flags, CHAT_USERS_COLOR_COLUMN, &send_color, CHAT_USERS_BUDDY_COLUMN, is_buddy, -1); } - else - { + + else { + + gtk_list_store_append(ls, &iter); gtk_list_store_set(ls, &iter, CHAT_USERS_ICON_COLUMN, pixbuf, CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, CHAT_USERS_NAME_COLUMN, name, CHAT_USERS_FLAGS_COLUMN, flags, CHAT_USERS_COLOR_COLUMN, get_nick_color(gtkconv, name), CHAT_USERS_BUDDY_COLUMN, is_buddy, -1); +#endif } if (pixbuf) g_object_unref(pixbuf); + g_free(alias_key); } static void @@ -3601,12 +3652,12 @@ gint ret = 0; gtk_tree_model_get(model, a, - CHAT_USERS_ALIAS_COLUMN, &user1, + CHAT_USERS_ALIAS_KEY_COLUMN, &user1, CHAT_USERS_FLAGS_COLUMN, &f1, CHAT_USERS_BUDDY_COLUMN, &buddy1, -1); gtk_tree_model_get(model, b, - CHAT_USERS_ALIAS_COLUMN, &user2, + CHAT_USERS_ALIAS_KEY_COLUMN, &user2, CHAT_USERS_FLAGS_COLUMN, &f2, CHAT_USERS_BUDDY_COLUMN, &buddy2, -1); @@ -3620,7 +3671,7 @@ } else if (buddy1 != buddy2) { ret = buddy1 ? -1 : 1; } else { - ret = gaim_utf8_strcasecmp(user1, user2); + ret = strcasecmp(user1, user2); } g_free(user1); @@ -3657,17 +3708,23 @@ if (!strcmp(normalized_name, gaim_normalize(conv->account, name))) { const char *alias = name; + char *alias_key = NULL; GaimBuddy *buddy2; if (strcmp(chat->nick, gaim_normalize(conv->account, name))) { /* This user is not me, so look into updating the alias. */ - if ((buddy2 = gaim_find_buddy(conv->account, name)) != NULL) + if ((buddy2 = gaim_find_buddy(conv->account, name)) != NULL) { alias = gaim_buddy_get_contact_alias(buddy2); + } + alias_key = g_utf8_collate_key(alias, strlen(alias)); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, - CHAT_USERS_ALIAS_COLUMN, alias, - -1); + CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, + -1); + g_free(alias_key); } g_free(name); break; @@ -3907,11 +3964,10 @@ gtk_widget_show(sw); ls = gtk_list_store_new(CHAT_USERS_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_INT, GDK_TYPE_COLOR, G_TYPE_BOOLEAN); - gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(ls), CHAT_USERS_ALIAS_COLUMN, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, + GDK_TYPE_COLOR, G_TYPE_BOOLEAN); + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(ls), CHAT_USERS_ALIAS_KEY_COLUMN, sort_chat_users, NULL, NULL); - gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), CHAT_USERS_ALIAS_COLUMN, - GTK_SORT_ASCENDING); list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ls)); @@ -4926,16 +4982,15 @@ account, name, message, conv, flags); g_free(displaying); } - static void -gaim_gtkconv_chat_add_users(GaimConversation *conv, GList *users, GList *flags, GList *aliases, gboolean new_arrivals) +gaim_gtkconv_chat_add_users(GaimConversation *conv, GList *cbuddies, gboolean new_arrivals) { GaimConvChat *chat; GaimGtkConversation *gtkconv; GaimGtkChatPane *gtkchat; + GtkListStore *ls; GList *l; - GList *ll; - GList *lll; + char tmp[BUF_LONG]; int num_users; @@ -4952,15 +5007,22 @@ gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); - l = users; - ll = flags; - lll = aliases; - while (l != NULL && ll != NULL && lll != NULL) { - add_chat_buddy_common(conv, (const char *)l->data, GPOINTER_TO_INT(ll->data), (const char *)lll->data, NULL); + ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list))); + + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, + GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID); + + l = cbuddies; + while (l != NULL) { + add_chat_buddy_common(conv, (GaimConvChatBuddy *)l->data, NULL); l = l->next; - ll = ll->next; - lll = lll->next; } + + /* Currently GTK+ maintains our sorted list after it's in the tree. + * This may change if it turns out we can manage it faster ourselves. + */ + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), CHAT_USERS_ALIAS_KEY_COLUMN, + GTK_SORT_ASCENDING); } static void @@ -4971,6 +5033,7 @@ GaimGtkConversation *gtkconv; GaimGtkChatPane *gtkchat; GaimConvChatBuddyFlags flags; + GaimConvChatBuddy *cbuddy; GtkTreeIter iter; GtkTreeModel *model; int f = 1; @@ -5005,7 +5068,9 @@ g_return_if_fail(new_alias != NULL); - add_chat_buddy_common(conv, new_name, flags, new_alias, old_name); + cbuddy = gaim_conv_chat_cb_new(new_name, new_alias, flags); + + add_chat_buddy_common(conv, cbuddy, old_name); } static void @@ -5066,6 +5131,7 @@ { GaimConvChat *chat; GaimConvChatBuddyFlags flags; + GaimConvChatBuddy *cbuddy; GaimGtkConversation *gtkconv; GaimGtkChatPane *gtkchat; GtkTreeIter iter; @@ -5109,7 +5175,9 @@ flags = gaim_conv_chat_user_get_flags(chat, user); - add_chat_buddy_common(conv, user, flags, alias, NULL); + cbuddy = gaim_conv_chat_cb_new(user, alias, flags); + + add_chat_buddy_common(conv, cbuddy, NULL); g_free(alias); } Modified: branches/v2_0_0/src/gtkconv.h =================================================================== --- branches/v2_0_0/src/gtkconv.h 2006-08-03 07:16:35 UTC (rev 16622) +++ branches/v2_0_0/src/gtkconv.h 2006-08-03 07:26:47 UTC (rev 16623) @@ -44,6 +44,7 @@ enum { CHAT_USERS_ICON_COLUMN, CHAT_USERS_ALIAS_COLUMN, + CHAT_USERS_ALIAS_KEY_COLUMN, CHAT_USERS_NAME_COLUMN, CHAT_USERS_FLAGS_COLUMN, CHAT_USERS_COLOR_COLUMN, Modified: branches/v2_0_0/src/protocols/yahoo/yahoochat.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-03 07:16:35 UTC (rev 16622) +++ branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-03 07:26:47 UTC (rev 16623) @@ -460,6 +460,7 @@ yd->chat_name = g_strdup(room); gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members, NULL, flags, FALSE); } + g_list_free(flags); } else if (c) { yahoo_chat_add_users(GAIM_CONV_CHAT(c), members); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-05 10:05:13
|
Revision: 16646 Author: thekingant Date: 2006-08-05 03:05:07 -0700 (Sat, 05 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16646&view=rev Log Message: ----------- Backport SVN revisions 16530, 16533 and 16534 from HEAD to v2_0_0 These are memleak fixes from sadrul Modified Paths: -------------- branches/v2_0_0/src/gtkconv.c branches/v2_0_0/src/gtknotify.c branches/v2_0_0/src/notify.c Modified: branches/v2_0_0/src/gtkconv.c =================================================================== --- branches/v2_0_0/src/gtkconv.c 2006-08-05 09:54:33 UTC (rev 16645) +++ branches/v2_0_0/src/gtkconv.c 2006-08-05 10:05:07 UTC (rev 16646) @@ -411,6 +411,7 @@ g_string_append_printf(s, "%s, ", (char *)l->data); else g_string_append_printf(s, "%s.", (char *)l->data); + g_list_free(text); } gaim_conversation_write(conv, NULL, s->str, GAIM_MESSAGE_NO_LOG, time(NULL)); Modified: branches/v2_0_0/src/gtknotify.c =================================================================== --- branches/v2_0_0/src/gtknotify.c 2006-08-05 09:54:33 UTC (rev 16645) +++ branches/v2_0_0/src/gtknotify.c 2006-08-05 10:05:07 UTC (rev 16646) @@ -53,6 +53,7 @@ GtkWidget *treeview; GtkWidget *window; gpointer user_data; + GaimNotifySearchResults *results; } GaimNotifySearchResultsData; @@ -115,7 +116,7 @@ if (id == GTK_RESPONSE_YES) { GtkTreeSelection *selection; - + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); if (gtk_tree_selection_get_selected(selection, NULL, &iter)) @@ -191,6 +192,8 @@ button = bd->button; button->callback(gaim_account_get_connection(data->account), row, data->user_data); + g_list_foreach(row, (GFunc)g_free, NULL); + g_list_free(row); } static void * @@ -682,6 +685,7 @@ data = g_malloc(sizeof(GaimNotifySearchResultsData)); data->user_data = user_data; + data->results = results; /* Create the window */ window = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -758,7 +762,7 @@ gaim_notify_searchresults_column_get_title(results, i-1), renderer, "text", i, NULL); } - + /* Setup the button area */ button_area = gtk_hbutton_box_new(); gtk_box_pack_start(GTK_BOX(vbox), button_area, FALSE, FALSE, 0); @@ -810,6 +814,8 @@ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(searchresults_callback_wrapper_cb), bd); + g_signal_connect_swapped(G_OBJECT(button), "destroy", + G_CALLBACK(g_free), bd); } } @@ -862,6 +868,7 @@ GaimNotifySearchResultsData *data = (GaimNotifySearchResultsData *)ui_handle; gtk_widget_destroy(data->window); + gaim_notify_searchresults_free(data->results); g_free(data); } Modified: branches/v2_0_0/src/notify.c =================================================================== --- branches/v2_0_0/src/notify.c 2006-08-05 09:54:33 UTC (rev 16645) +++ branches/v2_0_0/src/notify.c 2006-08-05 10:05:07 UTC (rev 16646) @@ -200,6 +200,7 @@ for (l = results->buttons; l; l = g_list_delete_link(l, l)) { GaimNotifySearchButton *button = l->data; + g_free(button->label); g_free(button); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-11 08:13:44
|
Revision: 16706 Author: thekingant Date: 2006-08-11 01:13:38 -0700 (Fri, 11 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16706&view=rev Log Message: ----------- Backport SVN revisions 16703 through 16705 from HEAD to v2_0_0 Original commit messages: Don't use the same callback for both gaim_proxy_connect() and gaim_input_add(). Aside from being a little confusing, it's hindering some changes I want to make to gaim_proxy_connect(). #if 0 some of the MSN listen-for-connection code for file transfers. It wasn't being used Modified Paths: -------------- branches/v2_0_0/src/protocols/msn/directconn.c branches/v2_0_0/src/protocols/msn/directconn.h branches/v2_0_0/src/protocols/yahoo/yahoo.c branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c branches/v2_0_0/src/protocols/yahoo/yahoochat.c branches/v2_0_0/src/util.c Modified: branches/v2_0_0/src/protocols/msn/directconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/directconn.c 2006-08-11 08:08:19 UTC (rev 16705) +++ branches/v2_0_0/src/protocols/msn/directconn.c 2006-08-11 08:13:38 UTC (rev 16706) @@ -76,6 +76,7 @@ * Connection Functions **************************************************************************/ +#if 0 static int create_listener(int port) { @@ -159,6 +160,7 @@ return fd; } +#endif static size_t msn_directconn_write(MsnDirectConn *directconn, @@ -447,6 +449,7 @@ return FALSE; } +#if 0 void msn_directconn_listen(MsnDirectConn *directconn) { @@ -466,6 +469,7 @@ directconn->port = port; directconn->c = 0; } +#endif MsnDirectConn* msn_directconn_new(MsnSlpLink *slplink) Modified: branches/v2_0_0/src/protocols/msn/directconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/directconn.h 2006-08-11 08:08:19 UTC (rev 16705) +++ branches/v2_0_0/src/protocols/msn/directconn.h 2006-08-11 08:13:38 UTC (rev 16706) @@ -50,7 +50,9 @@ MsnDirectConn *msn_directconn_new(MsnSlpLink *slplink); gboolean msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port); +#if 0 void msn_directconn_listen(MsnDirectConn *directconn); +#endif void msn_directconn_send_msg(MsnDirectConn *directconn, MsnMessage *msg); void msn_directconn_parse_nonce(MsnDirectConn *directconn, const char *nonce); void msn_directconn_destroy(MsnDirectConn *directconn); Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-11 08:08:19 UTC (rev 16705) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-11 08:13:38 UTC (rev 16706) @@ -2354,19 +2354,17 @@ } } -static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_cookies_send_cb(gpointer data, gint source, GaimInputCondition cond) { - GaimConnection *gc = data; - struct yahoo_data *yd = gc->proto_data; - int written, total_len; + GaimConnection *gc; + struct yahoo_data *yd; + int written, remaining; - if (source < 0) { - gaim_connection_error(gc, _("Unable to connect.")); - return; - } + gc = data; + yd = gc->proto_data; - total_len = strlen(yd->auth) - yd->auth_written; - written = write(source, yd->auth + yd->auth_written, total_len); + remaining = strlen(yd->auth) - yd->auth_written; + written = write(source, yd->auth + yd->auth_written, remaining); if (written < 0 && errno == EAGAIN) written = 0; @@ -2380,22 +2378,35 @@ return; } - if (written < total_len) { + if (written < remaining) { yd->auth_written += written; - if (!gc->inpa) - gc->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, - yahoo_got_cookies, gc); return; } g_free(yd->auth); yd->auth = NULL; yd->auth_written = 0; - if (gc->inpa) - gaim_input_remove(gc->inpa); + gaim_input_remove(gc->inpa); gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc); } +static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond) +{ + GaimConnection *gc = data; + + if (source < 0) { + gaim_connection_error(gc, _("Unable to connect.")); + return; + } + + if (gc->inpa == 0) + { + gc->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, + yahoo_got_cookies_send_cb, gc); + yahoo_got_cookies_send_cb(gc, source, GAIM_INPUT_WRITE); + } +} + static void yahoo_login_page_hash_iter(const char *key, const char *val, GString *url) { if (!strcmp(key, "passwd")) Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c 2006-08-11 08:08:19 UTC (rev 16705) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c 2006-08-11 08:13:38 UTC (rev 16706) @@ -57,11 +57,45 @@ g_free(xd); } +static void yahoo_receivefile_send_cb(gpointer data, gint source, GaimInputCondition condition) +{ + GaimXfer *xfer; + struct yahoo_xfer_data *xd; + int remaining, written; + + xfer = data; + xd = xfer->data; + + remaining = xd->txbuflen - xd->txbuf_written; + written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining); + + if (written < 0 && errno == EAGAIN) + written = 0; + else if (written <= 0) { + gaim_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno); + gaim_xfer_cancel_remote(xfer); + return; + } + + if (written < remaining) { + xd->txbuf_written += written; + return; + } + + gaim_input_remove(xd->tx_handler); + xd->tx_handler = 0; + g_free(xd->txbuf); + xd->txbuf = NULL; + xd->txbuflen = 0; + + gaim_xfer_start(xfer, source, NULL, 0); + +} + static void yahoo_receivefile_connected(gpointer data, gint source, GaimInputCondition condition) { GaimXfer *xfer; struct yahoo_xfer_data *xd; - int total_len, written; gaim_debug(GAIM_DEBUG_INFO, "yahoo", "AAA - in yahoo_receivefile_connected\n"); @@ -76,6 +110,8 @@ return; } + xfer->fd = source; + /* The first time we get here, assemble the tx buffer */ if (xd->txbuflen == 0) { xd->txbuf = g_strdup_printf("GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", @@ -84,12 +120,26 @@ xd->txbuf_written = 0; } - total_len = xd->txbuflen - xd->txbuf_written; + if (!xd->tx_handler) + { + xd->tx_handler = gaim_input_add(source, GAIM_INPUT_WRITE, + yahoo_receivefile_send_cb, xfer); + yahoo_receivefile_send_cb(xfer, source, GAIM_INPUT_WRITE); + } +} - xfer->fd = source; +static void yahoo_sendfile_send_cb(gpointer data, gint source, GaimInputCondition condition) +{ + GaimXfer *xfer; + struct yahoo_xfer_data *xd; + int written, remaining; - written = write(xfer->fd, xd->txbuf + xd->txbuf_written, total_len); + xfer = data; + xd = xfer->data; + remaining = xd->txbuflen - xd->txbuf_written; + written = write(xfer->fd, xd->txbuf + xd->txbuf_written, remaining); + if (written < 0 && errno == EAGAIN) written = 0; else if (written <= 0) { @@ -98,31 +148,33 @@ return; } - if (written < total_len) { - if (!xd->tx_handler) - xd->tx_handler = gaim_input_add(source, GAIM_INPUT_WRITE, - yahoo_receivefile_connected, xfer); + if (written < remaining) { xd->txbuf_written += written; return; } - if (xd->tx_handler) - gaim_input_remove(xd->tx_handler); + gaim_input_remove(xd->tx_handler); xd->tx_handler = 0; g_free(xd->txbuf); xd->txbuf = NULL; xd->txbuflen = 0; gaim_xfer_start(xfer, source, NULL, 0); - } - static void yahoo_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) { GaimXfer *xfer; struct yahoo_xfer_data *xd; - int written, total_len; + struct yahoo_packet *pkt; + gchar *size, *filename, *encoded_filename, *header; + guchar *pkt_buf; + const char *host; + int port; + size_t content_length, header_len, pkt_buf_len; + GaimConnection *gc; + GaimAccount *account; + struct yahoo_data *yd; gaim_debug(GAIM_DEBUG_INFO, "yahoo", "AAA - in yahoo_sendfile_connected\n"); @@ -131,7 +183,6 @@ if (!(xd = xfer->data)) return; - if (source < 0) { gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer), xfer->who, _("Unable to connect.")); @@ -139,96 +190,61 @@ return; } - /* The first time we get here, assemble the tx buffer */ - if (xd->txbuflen == 0) { - struct yahoo_packet *pkt; - gchar *size, *filename, *encoded_filename, *header; - guchar *pkt_buf; - const char *host; - int port; - size_t content_length, header_len, pkt_buf_len; - GaimConnection *gc; - GaimAccount *account; - struct yahoo_data *yd; + xfer->fd = source; - gc = xd->gc; - account = gaim_connection_get_account(gc); - yd = gc->proto_data; + /* Assemble the tx buffer */ + gc = xd->gc; + account = gaim_connection_get_account(gc); + yd = gc->proto_data; - pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, - YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, + YAHOO_STATUS_AVAILABLE, yd->session_id); - size = g_strdup_printf("%" G_GSIZE_FORMAT, gaim_xfer_get_size(xfer)); - filename = g_path_get_basename(gaim_xfer_get_local_filename(xfer)); - encoded_filename = yahoo_string_encode(gc, filename, NULL); + size = g_strdup_printf("%" G_GSIZE_FORMAT, gaim_xfer_get_size(xfer)); + filename = g_path_get_basename(gaim_xfer_get_local_filename(xfer)); + encoded_filename = yahoo_string_encode(gc, filename, NULL); - yahoo_packet_hash(pkt, "sssss", 0, gaim_connection_get_display_name(gc), - 5, xfer->who, 14, "", 27, encoded_filename, 28, size); - g_free(size); - g_free(encoded_filename); - g_free(filename); + yahoo_packet_hash(pkt, "sssss", 0, gaim_connection_get_display_name(gc), + 5, xfer->who, 14, "", 27, encoded_filename, 28, size); + g_free(size); + g_free(encoded_filename); + g_free(filename); - content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); + content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); - pkt_buf_len = yahoo_packet_build(pkt, 8, FALSE, &pkt_buf); - yahoo_packet_free(pkt); + pkt_buf_len = yahoo_packet_build(pkt, 8, FALSE, &pkt_buf); + yahoo_packet_free(pkt); - host = gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST); - port = gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT); - header = g_strdup_printf( - "POST http://%s:%d/notifyft HTTP/1.0\r\n" - "Content-length: %" G_GSIZE_FORMAT "\r\n" - "Host: %s:%d\r\n" - "Cookie: Y=%s; T=%s\r\n" - "\r\n", - host, port, content_length + 4 + gaim_xfer_get_size(xfer), - host, port, yd->cookie_y, yd->cookie_t); + host = gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST); + port = gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT); + header = g_strdup_printf( + "POST http://%s:%d/notifyft HTTP/1.0\r\n" + "Content-length: %" G_GSIZE_FORMAT "\r\n" + "Host: %s:%d\r\n" + "Cookie: Y=%s; T=%s\r\n" + "\r\n", + host, port, content_length + 4 + gaim_xfer_get_size(xfer), + host, port, yd->cookie_y, yd->cookie_t); + header_len = strlen(header); - header_len = strlen(header); + xd->txbuflen = header_len + pkt_buf_len + 4; + xd->txbuf = g_malloc(xd->txbuflen); - xd->txbuflen = header_len + pkt_buf_len + 4; - xd->txbuf = g_malloc(xd->txbuflen); + memcpy(xd->txbuf, header, header_len); + g_free(header); + memcpy(xd->txbuf + header_len, pkt_buf, pkt_buf_len); + g_free(pkt_buf); + memcpy(xd->txbuf + header_len + pkt_buf_len, "29\xc0\x80", 4); - memcpy(xd->txbuf, header, header_len); - g_free(header); - memcpy(xd->txbuf + header_len, pkt_buf, pkt_buf_len); - g_free(pkt_buf); - memcpy(xd->txbuf + header_len + pkt_buf_len, "29\xc0\x80", 4); + xd->txbuf_written = 0; - xd->txbuf_written = 0; + if (xd->tx_handler == 0) + { + xd->tx_handler = gaim_input_add(source, GAIM_INPUT_WRITE, + yahoo_sendfile_send_cb, xfer); + yahoo_sendfile_send_cb(xfer, source, GAIM_INPUT_WRITE); } - - total_len = xd->txbuflen - xd->txbuf_written; - - xfer->fd = source; - - written = write(xfer->fd, xd->txbuf + xd->txbuf_written, total_len); - - if (written < 0 && errno == EAGAIN) - written = 0; - else if (written <= 0) { - gaim_debug_error("yahoo", "Unable to write in order to start ft errno = %d\n", errno); - gaim_xfer_cancel_remote(xfer); - return; - } - - if (written < total_len) { - if (!xd->tx_handler) - xd->tx_handler = gaim_input_add(source, GAIM_INPUT_WRITE, - yahoo_sendfile_connected, xfer); - xd->txbuf_written += written; - return; - } - - if (xd->tx_handler) - gaim_input_remove(xd->tx_handler); - xd->tx_handler = 0; - g_free(xd->txbuf); - xd->txbuf = NULL; - xd->txbuflen = 0; - - gaim_xfer_start(xfer, source, NULL, 0); } static void yahoo_xfer_init(GaimXfer *xfer) Modified: branches/v2_0_0/src/protocols/yahoo/yahoochat.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-11 08:08:19 UTC (rev 16705) +++ branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-11 08:13:38 UTC (rev 16706) @@ -1335,38 +1335,22 @@ yrl->rxlen = 0; } -static void yahoo_roomlist_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_roomlist_send_cb(gpointer data, gint source, GaimInputCondition cond) { - struct yahoo_roomlist *yrl = data; - GaimRoomlist *list = yrl->list; - struct yahoo_data *yd = gaim_account_get_connection(list->account)->proto_data; - int written, total_len; + struct yahoo_roomlist *yrl; + GaimRoomlist *list; + int written, remaining; - if (source < 0) { - gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed.")); - yahoo_roomlist_cleanup(list, yrl); - return; - } + yrl = data; + list = yrl->list; - if (yrl->txbuf == NULL) { - yrl->fd = source; + remaining = strlen(yrl->txbuf) - yrl->tx_written; + written = write(yrl->fd, yrl->txbuf + yrl->tx_written, remaining); - yrl->txbuf = g_strdup_printf( - "GET http://%s/%s HTTP/1.0\r\n" - "Host: %s\r\n" - "Cookie: Y=%s; T=%s\r\n\r\n", - yrl->host, yrl->path, yrl->host, yd->cookie_y, - yd->cookie_t); - } - - total_len = strlen(yrl->txbuf) - yrl->tx_written; - written = write(yrl->fd, yrl->txbuf + yrl->tx_written, total_len); - if (written < 0 && errno == EAGAIN) written = 0; else if (written <= 0) { - if (yrl->inpa) - gaim_input_remove(yrl->inpa); + gaim_input_remove(yrl->inpa); yrl->inpa = 0; g_free(yrl->txbuf); yrl->txbuf = NULL; @@ -1375,24 +1359,47 @@ return; } - if (written < total_len) { - if (!yrl->inpa) - yrl->inpa = gaim_input_add(yrl->fd, - GAIM_INPUT_WRITE, yahoo_roomlist_got_connected, - yrl); + if (written < remaining) { yrl->tx_written += written; return; } g_free(yrl->txbuf); yrl->txbuf = NULL; - if (yrl->inpa) - gaim_input_remove(yrl->inpa); + + gaim_input_remove(yrl->inpa); yrl->inpa = gaim_input_add(yrl->fd, GAIM_INPUT_READ, - yahoo_roomlist_pending, yrl); + yahoo_roomlist_pending, yrl); } +static void yahoo_roomlist_got_connected(gpointer data, gint source, GaimInputCondition cond) +{ + struct yahoo_roomlist *yrl = data; + GaimRoomlist *list = yrl->list; + struct yahoo_data *yd = gaim_account_get_connection(list->account)->proto_data; + + if (source < 0) { + gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Unable to connect"), _("Fetching the room list failed.")); + yahoo_roomlist_cleanup(list, yrl); + return; + } + + yrl->fd = source; + + yrl->txbuf = g_strdup_printf( + "GET http://%s/%s HTTP/1.0\r\n" + "Host: %s\r\n" + "Cookie: Y=%s; T=%s\r\n\r\n", + yrl->host, yrl->path, yrl->host, yd->cookie_y, + yd->cookie_t); + + + yrl->inpa = gaim_input_add(yrl->fd, GAIM_INPUT_WRITE, + yahoo_roomlist_send_cb, yrl); + yahoo_roomlist_send_cb(yrl, yrl->fd, GAIM_INPUT_WRITE); +} + GaimRoomlist *yahoo_roomlist_get_list(GaimConnection *gc) { struct yahoo_roomlist *yrl; Modified: branches/v2_0_0/src/util.c =================================================================== --- branches/v2_0_0/src/util.c 2006-08-11 08:08:19 UTC (rev 16705) +++ branches/v2_0_0/src/util.c 2006-08-11 08:13:38 UTC (rev 16706) @@ -3202,7 +3202,7 @@ static void -url_fetched_cb(gpointer url_data, gint sock, GaimInputCondition cond) +url_fetch_recv_cb(gpointer url_data, gint source, GaimInputCondition cond) { GaimFetchUrlData *gfud = url_data; int len; @@ -3210,7 +3210,7 @@ char *data_cursor; gboolean got_eof = FALSE; - while((len = read(sock, buf, sizeof(buf))) > 0) { + while((len = read(source, buf, sizeof(buf))) > 0) { /* If we've filled up our butfer, make it bigger */ if((gfud->len + len) >= gfud->data_len) { while((gfud->len + len) >= gfud->data_len) @@ -3240,7 +3240,7 @@ header_len, gfud->webdata); /* See if we can find a redirect. */ - if(parse_redirect(gfud->webdata, header_len, sock, gfud)) + if(parse_redirect(gfud->webdata, header_len, source, gfud)) return; gfud->got_headers = TRUE; @@ -3273,7 +3273,7 @@ gaim_debug_error("gaim_url_fetch", "Failed to allocate %u bytes: %s\n", content_len, strerror(errno)); gaim_input_remove(gfud->inpa); - close(sock); + close(source); gfud->callback(gfud->user_data, NULL, 0); destroy_fetch_url_data(gfud); @@ -3310,7 +3310,7 @@ got_eof = TRUE; } else { gaim_input_remove(gfud->inpa); - close(sock); + close(source); gfud->callback(gfud->user_data, NULL, 0); @@ -3326,7 +3326,7 @@ /* gaim_debug_misc("gaim_url_fetch", "Received: '%s'\n", gfud->webdata); */ gaim_input_remove(gfud->inpa); - close(sock); + close(source); gfud->callback(gfud->user_data, gfud->webdata, gfud->len); destroy_fetch_url_data(gfud); @@ -3334,17 +3334,54 @@ } static void -url_fetch_connect_cb(gpointer url_data, gint sock, GaimInputCondition cond) { - GaimFetchUrlData *gfud = url_data; +url_fetch_send_cb(gpointer data, gint source, GaimInputCondition cond) +{ + GaimFetchUrlData *gfud; int len, total_len; - if(sock == -1) { + gfud = data; + + total_len = strlen(gfud->request); + + len = write(source, gfud->request + gfud->request_written, + total_len - gfud->request_written); + + if(len < 0 && errno == EAGAIN) + return; + else if(len < 0) { + gaim_input_remove(gfud->inpa); + close(source); gfud->callback(gfud->user_data, NULL, 0); destroy_fetch_url_data(gfud); return; } + gfud->request_written += len; - if (!gfud->request) { + if(gfud->request_written != total_len) + return; + + /* We're done writing, now start reading */ + gaim_input_remove(gfud->inpa); + gfud->inpa = gaim_input_add(source, GAIM_INPUT_READ, url_fetch_recv_cb, + gfud); +} + +static void +url_fetch_connect_cb(gpointer url_data, gint source, GaimInputCondition cond) +{ + GaimFetchUrlData *gfud; + + gfud = url_data; + + if (source == -1) + { + gfud->callback(gfud->user_data, NULL, 0); + destroy_fetch_url_data(gfud); + return; + } + + if (!gfud->request) + { if (gfud->user_agent) { /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 * clients must know how to handle the "chunked" transfer encoding. @@ -3374,33 +3411,9 @@ gaim_debug_misc("gaim_url_fetch", "Request: '%s'\n", gfud->request); - if(!gfud->inpa) - gfud->inpa = gaim_input_add(sock, GAIM_INPUT_WRITE, - url_fetch_connect_cb, gfud); - - total_len = strlen(gfud->request); - - len = write(sock, gfud->request + gfud->request_written, - total_len - gfud->request_written); - - if(len < 0 && errno == EAGAIN) - return; - else if(len < 0) { - gaim_input_remove(gfud->inpa); - close(sock); - gfud->callback(gfud->user_data, NULL, 0); - destroy_fetch_url_data(gfud); - return; - } - gfud->request_written += len; - - if(gfud->request_written != total_len) - return; - - gaim_input_remove(gfud->inpa); - - gfud->inpa = gaim_input_add(sock, GAIM_INPUT_READ, url_fetched_cb, - gfud); + gfud->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, + url_fetch_send_cb, gfud); + url_fetch_send_cb(gfud, source, GAIM_INPUT_WRITE); } void This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dat...@us...> - 2006-08-11 13:35:52
|
Revision: 16707 Author: datallah Date: 2006-08-11 06:35:26 -0700 (Fri, 11 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16707&view=rev Log Message: ----------- Merge of the changes I made yesterday in trunk (16687:16701) Modified Paths: -------------- branches/v2_0_0/plugins/log_reader.c branches/v2_0_0/src/account.c branches/v2_0_0/src/gtkblist.c branches/v2_0_0/src/plugin.c branches/v2_0_0/src/protocols/jabber/buddy.c branches/v2_0_0/src/protocols/jabber/jabber.c branches/v2_0_0/src/protocols/msn/nexus.c branches/v2_0_0/src/protocols/oscar/family_oservice.c branches/v2_0_0/src/protocols/simple/simple.c branches/v2_0_0/src/protocols/simple/simple.h branches/v2_0_0/src/protocols/simple/sipmsg.c branches/v2_0_0/src/protocols/simple/sipmsg.h branches/v2_0_0/src/protocols/yahoo/yahoo.c Modified: branches/v2_0_0/plugins/log_reader.c =================================================================== --- branches/v2_0_0/plugins/log_reader.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/plugins/log_reader.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -790,6 +790,7 @@ time_t time_unix; struct tm *tm_new; char *timestamp; + char *tmp; const char *style; new_session_id = xmlnode_get_attrib(message, "SessionID"); @@ -900,7 +901,7 @@ !isalnum(*(from_name + alias_length))); - to_name_matches = (gaim_str_has_prefix( + to_name_matches = to_name && (gaim_str_has_prefix( to_name, alias) && !isalnum(*(to_name + alias_length))); @@ -982,16 +983,18 @@ style = xmlnode_get_attrib(text_node, "Style"); + tmp = xmlnode_get_data(text_node); if (style && *style) { text = g_string_append(text, "<span style=\""); text = g_string_append(text, style); text = g_string_append(text, "\">"); - text = g_string_append(text, xmlnode_get_data(text_node)); + text = g_string_append(text, tmp); text = g_string_append(text, "</span>\n"); } else { - text = g_string_append(text, xmlnode_get_data(text_node)); + text = g_string_append(text, tmp); text = g_string_append(text, "\n"); } + g_free(tmp); } data->text = text; @@ -1462,7 +1465,7 @@ g_string_append(formatted, "<span style=\"color: #ff0000;\">"); - + if (gaim_str_has_prefix(line, "Your previous message has not been sent. " "Reason: Maximum length exceeded.")) { @@ -1682,10 +1685,11 @@ char buffer[1024] = ""; DWORD size = (sizeof(buffer) - 1); DWORD type; + gboolean found = FALSE; path = NULL; /* TODO: Test this after removing the trailing "\\". */ - if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "Trillian.SkinZip\\shell\\Add\\command\\", + if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "Trillian.SkinZip\\shell\\Add\\command\\", 0, KEY_QUERY_VALUE, &hKey)) { if(ERROR_SUCCESS == RegQueryValueEx(hKey, "", NULL, &type, (LPBYTE)buffer, &size)) { @@ -1720,20 +1724,18 @@ if (!path) { char *folder = wgaim_get_special_folder(CSIDL_PROGRAM_FILES); - if (folder) + if (folder) { path = g_build_filename(folder, "Trillian", "users", "default", "talk.ini", NULL); g_free(folder); } } - gboolean found = FALSE; - if (path) { /* Read talk.ini file to find the log directory. */ GError *error = NULL; -#if 0 && GTK_CHECK_VERSION(2,6,0) /* FIXME: Not tested yet. */ +#if 0 && GLIB_CHECK_VERSION(2,6,0) /* FIXME: Not tested yet. */ GKeyFile *key_file; gaim_debug(GAIM_DEBUG_INFO, "Trillian talk.ini read", @@ -1760,9 +1762,9 @@ g_key_file_free(key_file); } -#else /* !GTK_CHECK_VERSION(2,6,0) */ - GError *error = NULL; +#else /* !GLIB_CHECK_VERSION(2,6,0) */ gsize length; + gchar *contents = NULL; gaim_debug(GAIM_DEBUG_INFO, "Trillian talk.ini read", "Reading %s\n", path); Modified: branches/v2_0_0/src/account.c =================================================================== --- branches/v2_0_0/src/account.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/account.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -696,14 +696,14 @@ if ((protocol_id == NULL) || (name == NULL)) { - free(protocol_id); - free(name); + g_free(protocol_id); + g_free(name); return NULL; } ret = gaim_account_new(name, protocol_id); - free(name); - free(protocol_id); + g_free(name); + g_free(protocol_id); /* Read the password */ child = xmlnode_get_child(node, "password"); Modified: branches/v2_0_0/src/gtkblist.c =================================================================== --- branches/v2_0_0/src/gtkblist.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/gtkblist.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -2989,10 +2989,8 @@ else { text = g_strdup_printf("%s\n" - "<span color='%s' size='smaller'>%s%s%s</span>", + "<span color='%s' size='smaller'>%s</span>", esc, dim_grey(), - idletime != NULL ? idletime : "", - (idletime != NULL && statustext != NULL) ? " - " : "", statustext != NULL ? statustext : ""); } } @@ -3584,8 +3582,8 @@ hbox = gtk_hbox_new(FALSE, 0); /* Create the icon */ - status_type = gaim_account_get_status_type_with_primitive(account, - GAIM_STATUS_OFFLINE); + if ((status_type = gaim_account_get_status_type_with_primitive(account, + GAIM_STATUS_OFFLINE))) { pixbuf = gaim_gtk_create_prpl_icon_with_status(account, status_type, 0.5); if (pixbuf != NULL) { image = gtk_image_new_from_pixbuf(pixbuf); @@ -3594,6 +3592,7 @@ gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, GAIM_HIG_BOX_SPACE); } + } /* Create the text */ label = gtk_label_new(""); Modified: branches/v2_0_0/src/plugin.c =================================================================== --- branches/v2_0_0/src/plugin.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/plugin.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -1232,7 +1232,7 @@ plugin->path); gaim_plugin_load(plugin); } - else if ((plugin = gaim_plugins_find_with_basename(basename)) != NULL) + else if (basename && (plugin = gaim_plugins_find_with_basename(basename)) != NULL) { gaim_debug_info("plugins", "Loading saved plugin %s\n", plugin->path); Modified: branches/v2_0_0/src/protocols/jabber/buddy.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/buddy.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/jabber/buddy.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -532,8 +532,8 @@ GaimRequestFieldGroup *group; GaimRequestField *field; const struct vcard_template *vc_tp; - char *user_info; - char *cdata; + const char *user_info; + char *cdata = NULL; xmlnode *x_vc_data = NULL; fields = gaim_request_fields_new(); @@ -543,10 +543,8 @@ /* * Get existing, XML-formatted, user info */ - if((user_info = g_strdup(gaim_account_get_user_info(gc->account))) != NULL) + if((user_info = gaim_account_get_user_info(gc->account)) != NULL) x_vc_data = xmlnode_from_str(user_info, -1); - else - user_info = g_strdup(""); /* * Set up GSLists for edit with labels from "template," data from user info @@ -555,17 +553,18 @@ xmlnode *data_node; if((vc_tp->label)[0] == '\0') continue; - if(vc_tp->ptag == NULL) { - data_node = xmlnode_get_child(x_vc_data, vc_tp->tag); - } else { - gchar *tag = g_strdup_printf("%s/%s", vc_tp->ptag, vc_tp->tag); - data_node = xmlnode_get_child(x_vc_data, tag); - g_free(tag); + + if (x_vc_data != NULL) { + if(vc_tp->ptag == NULL) { + data_node = xmlnode_get_child(x_vc_data, vc_tp->tag); + } else { + gchar *tag = g_strdup_printf("%s/%s", vc_tp->ptag, vc_tp->tag); + data_node = xmlnode_get_child(x_vc_data, tag); + g_free(tag); + } + if(data_node) + cdata = xmlnode_get_data(data_node); } - if(data_node) - cdata = xmlnode_get_data(data_node); - else - cdata = NULL; if(strcmp(vc_tp->tag, "DESC") == 0) { field = gaim_request_field_string_new(vc_tp->tag, @@ -577,14 +576,15 @@ FALSE); } + g_free(cdata); + cdata = NULL; + gaim_request_field_group_add_field(group, field); } if(x_vc_data != NULL) xmlnode_free(x_vc_data); - g_free(user_info); - gaim_request_fields(gc, _("Edit Jabber vCard"), _("Edit Jabber vCard"), _("All items below are optional. Enter only the " @@ -724,8 +724,7 @@ static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data) { - const char *type, *id, *from; - JabberBuddy *jb; + const char *id, *from; GString *info_text; char *bare_jid; char *text; @@ -734,18 +733,17 @@ JabberBuddyInfo *jbi = data; from = xmlnode_get_attrib(packet, "from"); - type = xmlnode_get_attrib(packet, "type"); id = xmlnode_get_attrib(packet, "id"); - jabber_buddy_info_remove_id(jbi, id); - if(!jbi) return; + jabber_buddy_info_remove_id(jbi, id); + if(!from) return; - if(!(jb = jabber_buddy_find(js, from, TRUE))) + if(!jabber_buddy_find(js, from, FALSE)) return; /* XXX: handle the error case */ Modified: branches/v2_0_0/src/protocols/jabber/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/jabber/jabber.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -838,6 +838,8 @@ _("Register New Jabber Account"), instructions, fields, _("Register"), G_CALLBACK(jabber_register_cb), _("Cancel"), G_CALLBACK(jabber_register_cancel_cb), js); + + g_free(instructions); } } Modified: branches/v2_0_0/src/protocols/msn/nexus.c =================================================================== --- branches/v2_0_0/src/protocols/msn/nexus.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/msn/nexus.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -422,8 +422,8 @@ if ((da_login = strstr(base, "DALogin=")) != NULL) { - if ((da_login = strchr(da_login, '=')) != NULL) - da_login++; + /* skip over "DALogin=" */ + da_login += 8; if ((c = strchr(da_login, ',')) != NULL) *c = '\0'; Modified: branches/v2_0_0/src/protocols/oscar/family_oservice.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/family_oservice.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/oscar/family_oservice.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -1028,13 +1028,6 @@ byte_stream_put32(&frame->data, 0xa46d3b39); #endif - } else if ((offset == 0x00001000) && (len == 0x00000000)) { - - byte_stream_put32(&frame->data, 0xd41d8cd9); - byte_stream_put32(&frame->data, 0x8f00b204); - byte_stream_put32(&frame->data, 0xe9800998); - byte_stream_put32(&frame->data, 0xecf8427e); - } else gaim_debug_warning("oscar", "sendmemblock: unknown hash request\n"); Modified: branches/v2_0_0/src/protocols/simple/simple.c =================================================================== --- branches/v2_0_0/src/protocols/simple/simple.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/simple/simple.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -130,7 +130,8 @@ return NULL; } -static struct simple_watcher *watcher_find(struct simple_account_data *sip, gchar *name) { +static struct simple_watcher *watcher_find(struct simple_account_data *sip, + const gchar *name) { struct simple_watcher *watcher; GSList *entry = sip->watcher; while(entry) { @@ -141,7 +142,9 @@ return NULL; } -static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag, int needsxpidf) { +static struct simple_watcher *watcher_create(struct simple_account_data *sip, + const gchar *name, const gchar *callid, const gchar *ourtag, + const gchar *theirtag, gboolean needsxpidf) { struct simple_watcher *watcher = g_new0(struct simple_watcher, 1); watcher->name = g_strdup(name); watcher->dialog.callid = g_strdup(callid); @@ -152,7 +155,7 @@ return watcher; } -static void watcher_remove(struct simple_account_data *sip, gchar *name) { +static void watcher_remove(struct simple_account_data *sip, const gchar *name) { struct simple_watcher *watcher = watcher_find(sip, name); sip->watcher = g_slist_remove(sip->watcher, watcher); g_free(watcher->name); @@ -299,8 +302,9 @@ return ret; } -static char *parse_attribute(const char *attrname, char *source) { - char *tmp, *tmp2, *retval = NULL; +static char *parse_attribute(const char *attrname, const char *source) { + const char *tmp, *tmp2; + char *retval = NULL; int len = strlen(attrname); if(!strncmp(source, attrname, len)) { @@ -524,7 +528,8 @@ g_string_free(outstr, TRUE); } -static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code, char *text, char *body) { +static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code, + const char *text, const char *body) { GSList *tmp = msg->headers; gchar *name; gchar *value; @@ -560,7 +565,7 @@ g_free(trans); } -static void transactions_add_buf(struct simple_account_data *sip, gchar *buf, void *callback) { +static void transactions_add_buf(struct simple_account_data *sip, const gchar *buf, void *callback) { struct transaction *trans = g_new0(struct transaction, 1); trans->time = time(NULL); trans->msg = sipmsg_parse_msg(buf); @@ -593,6 +598,7 @@ char *auth = ""; const char *addh = ""; gchar *branch = genbranch(); + gchar *tag = NULL; char *buf; if(!strcmp(method, "REGISTER")) { @@ -618,6 +624,9 @@ gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); } + if (!dialog) + tag = gentag(); + buf = g_strdup_printf("%s %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s:%d;branch=%s\r\n" /* Don't know what epid is, but LCS wants it */ @@ -637,7 +646,7 @@ branch, sip->username, sip->servername, - dialog ? dialog->ourtag : gentag(), + dialog ? dialog->ourtag : tag, to, dialog ? ";tag=" : "", dialog ? dialog->theirtag : "", @@ -648,6 +657,9 @@ addh, strlen(body), body); + + g_free(tag); + g_free(auth); g_free(branch); g_free(callid); @@ -691,30 +703,30 @@ do_register_exp(sip, sip->registerexpire); } -static gchar *parse_from(gchar *hdr) { - gchar *from = hdr; - gchar *tmp; +static gchar *parse_from(const gchar *hdr) { + gchar *from; + const gchar *tmp, *tmp2 = hdr; - if(!from) return NULL; - gaim_debug_info("simple", "parsing address out of %s\n", from); - tmp = strchr(from, '<'); + if(!hdr) return NULL; + gaim_debug_info("simple", "parsing address out of %s\n", hdr); + tmp = strchr(hdr, '<'); /* i hate the different SIP UA behaviours... */ if(tmp) { /* sip address in <...> */ - from = tmp+1; - tmp = strchr(from, '>'); + tmp2 = tmp + 1; + tmp = strchr(tmp2, '>'); if(tmp) { - from = g_strndup(from, tmp-from); + from = g_strndup(tmp2, tmp - tmp2); } else { gaim_debug_info("simple", "found < without > in From\n"); return NULL; } } else { - tmp = strchr(from, ';'); + tmp = strchr(tmp2, ';'); if(tmp) { - from = g_strndup(from, tmp-from); + from = g_strndup(tmp2, tmp - tmp2); } else { - from = g_strdup(from); + from = g_strdup(tmp2); } } gaim_debug_info("simple", "got %s\n", from); @@ -722,12 +734,14 @@ } static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { - gchar *to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */ + gchar *to; if(msg->response == 200 || msg->response == 202) { return TRUE; } + to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */ + /* we can not subscribe -> user is offline (TODO unknown status?) */ gaim_prpl_got_user_status(sip->account, to, "offline", NULL); @@ -740,7 +754,7 @@ gchar *to; gchar *tmp; - if(strstr(buddy->name,"sip:")) + if(strstr(buddy->name, "sip:")) to = g_strdup(buddy->name); else to = g_strdup_printf("sip:%s", buddy->name); @@ -768,43 +782,50 @@ xmlnode *item, *group, *isc; const char *name_group; GaimBuddy *b; - GaimGroup *g; + GaimGroup *g = NULL; struct simple_buddy *bs; int len = msg->bodylen; tmp = sipmsg_find_header(msg, "Event"); - if(tmp && !strncmp(tmp,"vnd-microsoft-roaming-contacts",30)){ + if(tmp && !strncmp(tmp, "vnd-microsoft-roaming-contacts", 30)){ - gaim_debug_info("simple","simple_add_lcs_contacts->%s-%d\n",msg->body, len); + gaim_debug_info("simple", "simple_add_lcs_contacts->%s-%d\n", msg->body, len); /*Convert the contact from XML to Gaim Buddies*/ - isc = xmlnode_from_str(msg->body, len); + isc = xmlnode_from_str(msg->body, len); /* ToDo. Find for all groups */ - group = xmlnode_get_child(isc, "group"); - name_group = xmlnode_get_attrib(group, "name"); - gaim_debug_info("simple","name_group->%s\n",name_group); - g = gaim_find_group(name_group); - if(!g) { + if ((group = xmlnode_get_child(isc, "group"))) { + name_group = xmlnode_get_attrib(group, "name"); + gaim_debug_info("simple", "name_group->%s\n", name_group); + g = gaim_find_group(name_group); + if(!g) + g = gaim_group_new(name_group); + } + + if (!g) { g = gaim_find_group("Buddies"); - if(!g){ + if(!g) g = gaim_group_new("Buddies"); - } - }else{ - g = gaim_group_new(name_group); } for(item = xmlnode_get_child(isc, "contact"); item; item = xmlnode_get_next_twin(item)) { const char *uri, *name, *groups; + char *buddy_name; uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "name"); groups = xmlnode_get_attrib(item, "groups"); - gaim_debug_info("simple","URI->%s\n",uri); - b = gaim_find_buddy(sip->account, g_strdup_printf("sip:%s",uri)); + gaim_debug_info("simple", "URI->%s\n", uri); + + buddy_name = g_strdup_printf("sip:%s", uri); + + b = gaim_find_buddy(sip->account, buddy_name); if(!b){ - b = gaim_buddy_new(sip->account, g_strdup_printf("sip:%s",uri), uri); + b = gaim_buddy_new(sip->account, buddy_name, uri); } + g_free(buddy_name); + gaim_blist_add_buddy(b, NULL, g, NULL); gaim_blist_alias_buddy(b, uri); bs = g_new0(struct simple_buddy, 1); @@ -821,14 +842,14 @@ gchar *to; gchar *tmp; to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); - + tmp = get_contact(sip); - + contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp); g_free(tmp); - - send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, simple_add_lcs_contacts); + send_sip_request(sip->gc, "SUBSCRIBE", to, to, contact, "", NULL, simple_add_lcs_contacts); + g_free(to); g_free(contact); } @@ -946,6 +967,7 @@ if(!state) { gaim_debug_info("simple", "process_incoming_message: no state found\n"); + xmlnode_free(isc); return; } @@ -953,6 +975,8 @@ if(statedata) { if(strstr(statedata, "active")) serv_got_typing(sip->gc, from, 0, GAIM_TYPING); else serv_got_typing_stopped(sip->gc, from); + + g_free(statedata); } xmlnode_free(isc); send_sip_response(sip->gc, msg, 200, "OK", NULL); @@ -984,7 +1008,7 @@ subscribe_timeout(sip); tmp = sipmsg_find_header(msg, "Allow-Events"); - if(tmp && strstr(tmp,"vnd-microsoft-provisioning")){ + if(tmp && strstr(tmp, "vnd-microsoft-provisioning")){ simple_subscribe_buddylist(sip); } @@ -1012,7 +1036,7 @@ gchar *fromhdr; gchar *tmp2; xmlnode *pidf; - xmlnode *basicstatus; + xmlnode *basicstatus = NULL, *tuple, *status; gboolean isonline = FALSE; fromhdr = sipmsg_find_header(msg, "From"); @@ -1026,10 +1050,13 @@ return; } - basicstatus = xmlnode_get_child(xmlnode_get_child(xmlnode_get_child(pidf, "tuple"), "status"), "basic"); + if ((tuple = xmlnode_get_child(pidf, "tuple"))) + if ((status = xmlnode_get_child(tuple, "status"))) + basicstatus = xmlnode_get_child(status, "basic"); if(!basicstatus) { gaim_debug_info("simple", "process_incoming_notify: no basic found\n"); + xmlnode_free(pidf); return; } @@ -1037,6 +1064,7 @@ if(!tmp2) { gaim_debug_info("simple", "process_incoming_notify: no basic data found\n"); + xmlnode_free(pidf); return; } @@ -1044,6 +1072,8 @@ isonline = TRUE; } + g_free(tmp2); + if(isonline) gaim_prpl_got_user_status(sip->account, from, "available", NULL); else gaim_prpl_got_user_status(sip->account, from, "offline", NULL); @@ -1084,16 +1114,13 @@ return 1; } -static gchar *find_tag(gchar *hdr) { - gchar *tmp = strstr(hdr, ";tag="); - gchar *tmp2; +static gchar *find_tag(const gchar *hdr) { + const gchar *tmp = strstr(hdr, ";tag="), *tmp2; + if(!tmp) return NULL; tmp += 5; if((tmp2 = strchr(tmp, ';'))) { - tmp2[0] = '\0'; - tmp = g_strdup(tmp); - tmp2[0] = ';'; - return tmp; + return g_strndup(tmp, tmp2 - tmp); } return g_strdup(tmp); } @@ -1162,12 +1189,14 @@ "Content-Type: application/pidf+xml\r\n", doc, NULL, process_publish_response); sip->republish = time(NULL) + 500; + g_free(uri); g_free(doc); } static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) { - gchar *from = parse_from(sipmsg_find_header(msg, "From")); - gchar *theirtag = find_tag(sipmsg_find_header(msg, "From")); + const char *from_hdr = sipmsg_find_header(msg, "From"); + gchar *from = parse_from(from_hdr); + gchar *theirtag = find_tag(from_hdr); gchar *ourtag = find_tag(sipmsg_find_header(msg, "To")); gboolean tagadded = FALSE; gchar *callid = sipmsg_find_header(msg, "Call-ID"); @@ -1180,22 +1209,22 @@ } if(!watcher) { /* new subscription */ gchar *acceptheader = sipmsg_find_header(msg, "Accept"); - int needsxpidf = 0; + gboolean needsxpidf = FALSE; if(!gaim_privacy_check(sip->account, from)) { send_sip_response(sip->gc, msg, 202, "Ok", NULL); goto privend; } if(acceptheader) { gchar *tmp = acceptheader; - int foundpidf = 0; - int foundxpidf = 0; + gboolean foundpidf = FALSE; + gboolean foundxpidf = FALSE; while(tmp && tmp < acceptheader + strlen(acceptheader)) { gchar *tmp2 = strchr(tmp, ','); if(tmp2) *tmp2 = '\0'; - if(!strcmp("application/pidf+xml",tmp)) - foundpidf = 1; - if(!strcmp("application/xpidf+xml",tmp)) - foundxpidf = 1; + if(!strcmp("application/pidf+xml", tmp)) + foundpidf = TRUE; + if(!strcmp("application/xpidf+xml", tmp)) + foundxpidf = TRUE; if(tmp2) { *tmp2 = ','; tmp = tmp2; @@ -1203,7 +1232,7 @@ } else tmp = 0; } - if(!foundpidf && foundxpidf) needsxpidf = 1; + if(!foundpidf && foundxpidf) needsxpidf = TRUE; g_free(acceptheader); } watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf); @@ -1212,6 +1241,7 @@ gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag); sipmsg_remove_header(msg, "To"); sipmsg_add_header(msg, "To", to); + g_free(to); } if(expire) watcher->expire = time(NULL) + strtol(expire, NULL, 10); @@ -1221,7 +1251,7 @@ tmp = get_contact(sip); sipmsg_add_header(msg, "Contact", tmp); g_free(tmp); - gaim_debug_info("simple","got subscribe: name %s ourtag %s theirtag %s callid %s\n", watcher->name, watcher->dialog.ourtag, watcher->dialog.theirtag, watcher->dialog.callid); + gaim_debug_info("simple", "got subscribe: name %s ourtag %s theirtag %s callid %s\n", watcher->name, watcher->dialog.ourtag, watcher->dialog.theirtag, watcher->dialog.callid); send_sip_response(sip->gc, msg, 200, "Ok", NULL); send_notify(sip, watcher); privend: @@ -1274,7 +1304,7 @@ gaim_debug_info("simple", "got trying response\n"); } else { sip->proxy.retries = 0; - if(!strcmp(trans->msg->method,"REGISTER")) { + if(!strcmp(trans->msg->method, "REGISTER")) { if(msg->response == 401) sip->registrar.retries++; else sip->registrar.retries = 0; } else { @@ -1327,7 +1357,7 @@ cur++; } if(cur != conn->inbuf) { - memmove(conn->inbuf, cur, conn->inbufused-(cur-conn->inbuf)); + memmove(conn->inbuf, cur, conn->inbufused - (cur - conn->inbuf)); conn->inbufused = strlen(conn->inbuf); } @@ -1340,7 +1370,7 @@ msg = sipmsg_parse_header(conn->inbuf); cur[0] = '\r'; cur += 2; - restlen = conn->inbufused - (cur-conn->inbuf); + restlen = conn->inbufused - (cur - conn->inbuf); if(restlen >= msg->bodylen) { dummy = g_malloc(msg->bodylen + 1); memcpy(dummy, cur, msg->bodylen); Modified: branches/v2_0_0/src/protocols/simple/simple.h =================================================================== --- branches/v2_0_0/src/protocols/simple/simple.h 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/simple/simple.h 2006-08-11 13:35:26 UTC (rev 16707) @@ -44,7 +44,7 @@ gchar *name; time_t expire; struct sip_dialog dialog; - int needsxpidf; + gboolean needsxpidf; }; struct simple_buddy { Modified: branches/v2_0_0/src/protocols/simple/sipmsg.c =================================================================== --- branches/v2_0_0/src/protocols/simple/sipmsg.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/simple/sipmsg.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -35,18 +35,23 @@ #include "simple.h" #include "sipmsg.h" -struct sipmsg *sipmsg_parse_msg(gchar *msg) { - char *tmp = strstr(msg, "\r\n\r\n"); +struct sipmsg *sipmsg_parse_msg(const gchar *msg) { + const char *tmp = strstr(msg, "\r\n\r\n"); + char *line; struct sipmsg *smsg; + if(!tmp) return NULL; - tmp[0]=0; - smsg = sipmsg_parse_header(msg); - tmp[0]='\r'; - smsg->body = g_strdup(tmp+4); + + line = g_strndup(msg, tmp - msg); + + smsg = sipmsg_parse_header(line); + smsg->body = g_strdup(tmp + 4); + + g_free(line); return smsg; } -struct sipmsg *sipmsg_parse_header(gchar *header) { +struct sipmsg *sipmsg_parse_header(const gchar *header) { struct sipmsg *msg = g_new0(struct sipmsg,1); gchar **lines = g_strsplit(header,"\r\n",0); gchar **parts; @@ -110,7 +115,7 @@ return msg; } -void sipmsg_print(struct sipmsg *msg) { +void sipmsg_print(const struct sipmsg *msg) { GSList *cur; struct siphdrelement *elem; gaim_debug(GAIM_DEBUG_MISC, "simple", "SIP MSG\n"); @@ -124,7 +129,7 @@ } } -char *sipmsg_to_string(struct sipmsg *msg) { +char *sipmsg_to_string(const struct sipmsg *msg) { GSList *cur; GString *outstr = g_string_new(""); struct siphdrelement *elem; @@ -148,7 +153,7 @@ return g_string_free(outstr, FALSE); } -void sipmsg_add_header(struct sipmsg *msg, gchar *name, gchar *value) { +void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value) { struct siphdrelement *element = g_new0(struct siphdrelement,1); element->name = g_strdup(name); element->value = g_strdup(value); @@ -170,13 +175,16 @@ g_free(msg); } -void sipmsg_remove_header(struct sipmsg *msg, gchar *name) { +void sipmsg_remove_header(struct sipmsg *msg, const gchar *name) { struct siphdrelement *elem; GSList *tmp = msg->headers; while(tmp) { elem = tmp->data; if(strcmp(elem->name, name)==0) { msg->headers = g_slist_remove(msg->headers, elem); + g_free(elem->name); + g_free(elem->value); + g_free(elem); return; } tmp = g_slist_next(tmp); @@ -184,7 +192,7 @@ return; } -gchar *sipmsg_find_header(struct sipmsg *msg, gchar *name) { +gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name) { GSList *tmp; struct siphdrelement *elem; tmp = msg->headers; Modified: branches/v2_0_0/src/protocols/simple/sipmsg.h =================================================================== --- branches/v2_0_0/src/protocols/simple/sipmsg.h 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/simple/sipmsg.h 2006-08-11 13:35:26 UTC (rev 16707) @@ -39,12 +39,12 @@ gchar *value; }; -struct sipmsg *sipmsg_parse_msg(gchar *msg); -struct sipmsg *sipmsg_parse_header(gchar *header); -void sipmsg_add_header(struct sipmsg *msg, gchar *name, gchar *value); +struct sipmsg *sipmsg_parse_msg(const gchar *msg); +struct sipmsg *sipmsg_parse_header(const gchar *header); +void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value); void sipmsg_free(struct sipmsg *msg); -gchar *sipmsg_find_header(struct sipmsg *msg, gchar *name); -void sipmsg_remove_header(struct sipmsg *msg, gchar *name); -void sipmsg_print(struct sipmsg *msg); -char *sipmsg_to_string(struct sipmsg *msg); +gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name); +void sipmsg_remove_header(struct sipmsg *msg, const gchar *name); +void sipmsg_print(const struct sipmsg *msg); +char *sipmsg_to_string(const struct sipmsg *msg); #endif /* _GAIM_SIMPLE_H */ Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-11 08:13:38 UTC (rev 16706) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-11 13:35:26 UTC (rev 16707) @@ -350,7 +350,7 @@ break; yahoo_friend_set_buddy_icon_need_request(f, FALSE); - if (cksum != gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)) + if (b && cksum != gaim_blist_node_get_int((GaimBlistNode*)b, YAHOO_ICON_CHECKSUM_KEY)) yahoo_send_picture_request(gc, name); break; @@ -3407,7 +3407,7 @@ if (foo) group = foo->name; if (!group) { - g = gaim_buddy_get_group(gaim_find_buddy(gc->account, buddy->name)); + g = gaim_buddy_get_group(buddy); if (g) group = g->name; else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-12 10:26:53
|
Revision: 16714 Author: thekingant Date: 2006-08-12 03:26:45 -0700 (Sat, 12 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16714&view=rev Log Message: ----------- Backport SVN revisions 16711 to 16713 from HEAD to v2_0_0 Original commit messages: 16711: Get rid of an assert when editing an account that has no icon 16712: Pretty large commit here. Basically I got sick of having to verify that gc is still valid on all the callback functions for gaim_proxy_connect(). The fix for this for gaim_proxy_connect() to return something that allows the connection attempt to be canceled. It's not quite there yet, but this is a good first step. I changed gaim_proxy_connect() to return a reference to a new GaimProxyConnectInfo (this used to be called PHB). Eventually this can be passed to a function that'll cancel the connection attempt. I also decided to add an error_cb instead of using connect_cb and passing a file descriptor of -1. And proxy.c will also pass an error message to callers which should explain the reason that the connection attempt failed. Oh, and proxy.c now never calls gaim_connection_error() 16713: Rename struct PHB to struct _GaimProxyConnectInfo Modified Paths: -------------- branches/v2_0_0/src/ft.c branches/v2_0_0/src/gtkaccount.c branches/v2_0_0/src/protocols/irc/irc.c branches/v2_0_0/src/protocols/jabber/jabber.c branches/v2_0_0/src/protocols/jabber/si.c branches/v2_0_0/src/protocols/msn/directconn.c branches/v2_0_0/src/protocols/msn/httpconn.c branches/v2_0_0/src/protocols/msn/servconn.c branches/v2_0_0/src/protocols/oscar/oscar.c branches/v2_0_0/src/protocols/oscar/peer.c branches/v2_0_0/src/protocols/oscar/peer.h branches/v2_0_0/src/protocols/oscar/peer_proxy.c branches/v2_0_0/src/protocols/sametime/sametime.c branches/v2_0_0/src/protocols/silc/silc.c branches/v2_0_0/src/protocols/simple/simple.c branches/v2_0_0/src/protocols/yahoo/yahoo.c branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c branches/v2_0_0/src/protocols/yahoo/yahoochat.c branches/v2_0_0/src/protocols/yahoo/ycht.c branches/v2_0_0/src/proxy.c branches/v2_0_0/src/proxy.h branches/v2_0_0/src/sslconn.c branches/v2_0_0/src/upnp.c branches/v2_0_0/src/util.c Modified: branches/v2_0_0/src/ft.c =================================================================== --- branches/v2_0_0/src/ft.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/ft.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -911,13 +911,13 @@ } static void -connect_cb(gpointer data, gint source, GaimInputCondition condition) +connect_cb(gpointer data, gint source) { GaimXfer *xfer = (GaimXfer *)data; xfer->fd = source; - begin_transfer(xfer, condition); + begin_transfer(xfer, GAIM_INPUT_READ); } void @@ -946,7 +946,7 @@ /* Establish a file descriptor. */ gaim_proxy_connect(xfer->account, xfer->remote_ip, - xfer->remote_port, connect_cb, xfer); + xfer->remote_port, connect_cb, NULL, xfer); return; } Modified: branches/v2_0_0/src/gtkaccount.c =================================================================== --- branches/v2_0_0/src/gtkaccount.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/gtkaccount.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -210,7 +210,8 @@ } gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_entry), pixbuf); - g_object_unref(G_OBJECT(pixbuf)); + if (pixbuf != NULL) + g_object_unref(G_OBJECT(pixbuf)); g_free(filename); } Modified: branches/v2_0_0/src/protocols/irc/irc.c =================================================================== --- branches/v2_0_0/src/protocols/irc/irc.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/irc/irc.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -46,7 +46,7 @@ /* static GList *irc_chat_info(GaimConnection *gc); */ static void irc_login(GaimAccount *account); static void irc_login_cb_ssl(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond); -static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond); +static void irc_login_cb(gpointer data, gint source); static void irc_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, gpointer data); static void irc_close(GaimConnection *gc); static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags); @@ -283,7 +283,7 @@ struct irc_conn *irc; char **userparts; const char *username = gaim_account_get_username(account); - int err; + GaimProxyConnectInfo *connect_info; gc = gaim_account_get_connection(account); gc->flags |= GAIM_CONNECTION_NO_NEWLINES; @@ -325,11 +325,11 @@ if (!irc->gsc) { - err = gaim_proxy_connect(account, irc->server, + connect_info = gaim_proxy_connect(account, irc->server, gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), - irc_login_cb, gc); + irc_login_cb, NULL, gc); - if (err || !gaim_account_get_connection(account)) { + if (!connect_info || !gaim_account_get_connection(account)) { gaim_connection_error(gc, _("Couldn't create socket")); return; } @@ -394,7 +394,7 @@ } } -static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond) +static void irc_login_cb(gpointer data, gint source) { GaimConnection *gc = data; struct irc_conn *irc = gc->proto_data; Modified: branches/v2_0_0/src/protocols/jabber/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/jabber/jabber.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -418,7 +418,7 @@ static void -jabber_login_callback(gpointer data, gint source, GaimInputCondition cond) +jabber_login_callback(gpointer data, gint source) { GaimConnection *gc = data; JabberStream *js = gc->proto_data; @@ -471,12 +471,12 @@ static void jabber_login_connect(JabberStream *js, const char *server, int port) { - int rc; + GaimProxyConnectInfo *connect_info; - rc = gaim_proxy_connect(js->gc->account, server, - port, jabber_login_callback, js->gc); + connect_info = gaim_proxy_connect(js->gc->account, server, + port, jabber_login_callback, NULL, js->gc); - if (rc != 0) + if (connect_info == NULL) gaim_connection_error(js->gc, _("Unable to create socket")); } @@ -859,7 +859,7 @@ const char *connect_server = gaim_account_get_string(account, "connect_server", ""); const char *server; - int rc; + GaimProxyConnectInfo *connect_info; js = gc->proto_data = g_new0(JabberStream, 1); js->gc = gc; @@ -909,11 +909,11 @@ } if(!js->gsc) { - rc = gaim_proxy_connect(account, server, + connect_info = gaim_proxy_connect(account, server, gaim_account_get_int(account, "port", 5222), - jabber_login_callback, gc); + jabber_login_callback, NULL, gc); - if (rc != 0) + if (connect_info == NULL) gaim_connection_error(gc, _("Unable to create socket")); } } Modified: branches/v2_0_0/src/protocols/jabber/si.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/si.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/jabber/si.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -88,7 +88,7 @@ static void jabber_si_bytestreams_attempt_connect(GaimXfer *xfer); -static void jabber_si_bytestreams_connect_cb(gpointer data, gint source, GaimInputCondition cond) +static void jabber_si_bytestreams_connect_cb(gpointer data, gint source) { GaimXfer *xfer = data; JabberSIXfer *jsx = xfer->data; @@ -167,7 +167,7 @@ for(i=0; i<20; i++, p+=2) snprintf(p, 3, "%02x", hashval[i]); - gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, xfer); + gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, NULL, xfer); g_free(dstaddr); } Modified: branches/v2_0_0/src/protocols/msn/directconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/directconn.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/msn/directconn.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -368,12 +368,12 @@ } static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) +connect_cb(gpointer data, gint source) { MsnDirectConn* directconn; int fd; - gaim_debug_misc("msn", "directconn: connect_cb: %d, %d.\n", source, cond); + gaim_debug_misc("msn", "directconn: connect_cb: %d\n", source); directconn = data; @@ -423,7 +423,7 @@ msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port) { MsnSession *session; - int r; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(directconn != NULL, FALSE); g_return_val_if_fail(host != NULL, TRUE); @@ -438,10 +438,10 @@ } #endif - r = gaim_proxy_connect(session->account, host, port, connect_cb, - directconn); + connect_info = gaim_proxy_connect(session->account, host, port, + connect_cb, NULL, directconn); - if (r == 0) + if (connect_info != NULL) { return TRUE; } Modified: branches/v2_0_0/src/protocols/msn/httpconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/msn/httpconn.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -693,7 +693,7 @@ } static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) +connect_cb(gpointer data, gint source) { MsnHttpConn *httpconn = data; @@ -729,7 +729,7 @@ gboolean msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) { - int r; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(httpconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); @@ -738,10 +738,10 @@ if (httpconn->connected) msn_httpconn_disconnect(httpconn); - r = gaim_proxy_connect(httpconn->session->account, - "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); + connect_info = gaim_proxy_connect(httpconn->session->account, + "gateway.messenger.hotmail.com", 80, connect_cb, NULL, httpconn); - if (r == 0) + if (connect_info != NULL) { httpconn->waiting_response = TRUE; httpconn->connected = TRUE; Modified: branches/v2_0_0/src/protocols/msn/servconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/servconn.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/msn/servconn.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -166,7 +166,7 @@ **************************************************************************/ static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) +connect_cb(gpointer data, gint source) { MsnServConn *servconn = data; @@ -199,7 +199,7 @@ msn_servconn_connect(MsnServConn *servconn, const char *host, int port) { MsnSession *session; - int r; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(servconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); @@ -232,10 +232,10 @@ return TRUE; } - r = gaim_proxy_connect(session->account, host, port, connect_cb, - servconn); + connect_info = gaim_proxy_connect(session->account, host, port, + connect_cb, NULL, servconn); - if (r == 0) + if (connect_info != NULL) { servconn->processing = TRUE; return TRUE; Modified: branches/v2_0_0/src/protocols/oscar/oscar.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/oscar/oscar.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -943,7 +943,7 @@ * on the type of host, we do a few different things here. */ static void -connection_established_cb(gpointer data, gint source, GaimInputCondition cond) +connection_established_cb(gpointer data, gint source) { NewFlapConnectionData *new_conn_data; GaimConnection *gc; @@ -1250,7 +1250,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", OSCAR_DEFAULT_LOGIN_SERVER), gaim_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT), - connection_established_cb, new_conn_data) < 0) + connection_established_cb, NULL, new_conn_data) == NULL) { gaim_connection_error(gc, _("Couldn't connect to host")); return; @@ -1294,7 +1294,8 @@ GaimConnection *gc = od->gc; GaimAccount *account = gc->account; char *host; int port; - int i, rc; + int i; + GaimProxyConnectInfo *connect_info; NewFlapConnectionData *new_conn_data; va_list ap; struct aim_authresp_info *info; @@ -1366,9 +1367,10 @@ new_conn_data->cookielen = info->cookielen; new_conn_data->cookie = g_memdup(info->cookie, info->cookielen); new_conn_data->data = NULL; - rc = gaim_proxy_connect(gc->account, host, port, connection_established_cb, new_conn_data); + connect_info = gaim_proxy_connect(gc->account, host, port, + connection_established_cb, NULL, new_conn_data); g_free(host); - if (rc < 0) { + if (connect_info == NULL) { gaim_connection_error(gc, _("Could Not Connect")); od->killme = TRUE; return 0; @@ -1479,7 +1481,9 @@ g_free(pos); } -static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond) { +static void +straight_to_hell(gpointer data, gint source) +{ struct pieceofcrap *pos = data; gchar *buf; @@ -1569,7 +1573,8 @@ pos->len = len; pos->modname = g_strdup(modname); - if (gaim_proxy_connect(pos->gc->account, "gaim.sourceforge.net", 80, straight_to_hell, pos) != 0) + if (gaim_proxy_connect(pos->gc->account, "gaim.sourceforge.net", 80, + straight_to_hell, NULL, pos) == NULL) { char buf[256]; if (pos->modname) @@ -1660,7 +1665,7 @@ new_conn_data->data = NULL; } - if (gaim_proxy_connect(account, host, port, connection_established_cb, new_conn_data) != 0) + if (gaim_proxy_connect(account, host, port, connection_established_cb, NULL, new_conn_data) == NULL) { flap_connection_schedule_destroy(new_conn_data->conn, OSCAR_DISCONNECT_COULD_NOT_CONNECT); Modified: branches/v2_0_0/src/protocols/oscar/peer.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/oscar/peer.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -470,7 +470,7 @@ * either connected or failed to connect. */ static void -peer_connection_established_cb(gpointer data, gint source, GaimInputCondition cond) +peer_connection_established_cb(gpointer data, gint source) { NewPeerConnectionData *new_conn_data; GaimConnection *gc; @@ -668,7 +668,7 @@ } if (gaim_proxy_connect(account, conn->verifiedip, conn->port, - peer_connection_established_cb, new_conn_data) == 0) + peer_connection_established_cb, NULL, new_conn_data) != NULL) { /* Connecting... */ return; @@ -699,7 +699,7 @@ } if (gaim_proxy_connect(account, conn->clientip, conn->port, - peer_connection_established_cb, new_conn_data) == 0) + peer_connection_established_cb, NULL, new_conn_data) != NULL) { /* Connecting... */ return; @@ -760,7 +760,7 @@ if (gaim_proxy_connect(account, (conn->proxyip != NULL) ? conn->proxyip : PEER_PROXY_SERVER, PEER_PROXY_PORT, - peer_proxy_connection_established_cb, new_conn_data) == 0) + peer_proxy_connection_established_cb, NULL, new_conn_data) != NULL) { /* Connecting... */ return; Modified: branches/v2_0_0/src/protocols/oscar/peer.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.h 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/oscar/peer.h 2006-08-12 10:26:45 UTC (rev 16714) @@ -254,7 +254,7 @@ /* * For peer proxying */ -void peer_proxy_connection_established_cb(gpointer data, gint source, GaimInputCondition cond); +void peer_proxy_connection_established_cb(gpointer data, gint source); #if 0 int peer_oft_sendheader(OscarData *od, guint16 type, PeerConnection *peer_connection); Modified: branches/v2_0_0/src/protocols/oscar/peer_proxy.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -326,7 +326,7 @@ * either connected or failed to connect. */ void -peer_proxy_connection_established_cb(gpointer data, gint source, GaimInputCondition cond) +peer_proxy_connection_established_cb(gpointer data, gint source) { NewPeerConnectionData *new_conn_data; GaimConnection *gc; Modified: branches/v2_0_0/src/protocols/sametime/sametime.c =================================================================== --- branches/v2_0_0/src/protocols/sametime/sametime.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/sametime/sametime.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -310,7 +310,7 @@ /* connection functions */ -static void connect_cb(gpointer data, gint source, GaimInputCondition cond); +static void connect_cb(gpointer data, gint source); /* ----- session ------ */ @@ -1409,7 +1409,7 @@ port = gaim_account_get_int(account, MW_KEY_PORT, MW_PLUGIN_DEFAULT_PORT); if(gaim_account_get_bool(account, MW_KEY_FORCE, FALSE) || - gaim_proxy_connect(account, host, port, connect_cb, pd)) { + (gaim_proxy_connect(account, host, port, connect_cb, NULL, pd) == NULL)) { mwSession_forceLogin(session); } @@ -1669,8 +1669,7 @@ /** Callback passed to gaim_proxy_connect when an account is logged in, and if the session logging in receives a redirect message */ -static void connect_cb(gpointer data, gint source, - GaimInputCondition cond) { +static void connect_cb(gpointer data, gint source) { struct mwGaimPluginData *pd = data; GaimConnection *gc = pd->gc; @@ -3684,7 +3683,7 @@ gaim_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS); - if(gaim_proxy_connect(account, host, port, connect_cb, pd)) { + if(gaim_proxy_connect(account, host, port, connect_cb, NULL, pd) == NULL) { gaim_connection_error(gc, _("Unable to connect to host")); } } Modified: branches/v2_0_0/src/protocols/silc/silc.c =================================================================== --- branches/v2_0_0/src/protocols/silc/silc.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/silc/silc.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -141,7 +141,7 @@ } static void -silcgaim_login_connected(gpointer data, gint source, GaimInputCondition cond) +silcgaim_login_connected(gpointer data, gint source) { GaimConnection *gc = data; SilcGaim sg; @@ -367,7 +367,8 @@ gaim_account_get_string(account, "server", "silc.silcnet.org"), gaim_account_get_int(account, "port", 706), - silcgaim_login_connected, gc)) { + silcgaim_login_connected, NULL, gc) == NULL) + { gaim_connection_error(gc, _("Unable to create connection")); return; } Modified: branches/v2_0_0/src/protocols/simple/simple.c =================================================================== --- branches/v2_0_0/src/protocols/simple/simple.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/simple/simple.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -421,7 +421,7 @@ static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); -static void send_later_cb(gpointer data, gint source, GaimInputCondition cond) { +static void send_later_cb(gpointer data, gint source) { GaimConnection *gc = data; struct simple_account_data *sip = gc->proto_data; struct sip_connection *conn; @@ -448,11 +448,12 @@ static void sendlater(GaimConnection *gc, const char *buf) { struct simple_account_data *sip = gc->proto_data; - int error = 0; + GaimProxyConnectInfo *connect_info; + if(!sip->connecting) { gaim_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport); - error = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, gc); - if(error) { + connect_info = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, NULL, gc); + if(connect_info == NULL) { gaim_connection_error(gc, _("Couldn't create socket")); } sip->connecting = TRUE; @@ -1452,7 +1453,7 @@ conn->inputhandler = gaim_input_add(newfd, GAIM_INPUT_READ, simple_input_cb, gc); } -static void login_cb(gpointer data, gint source, GaimInputCondition cond) { +static void login_cb(gpointer data, gint source) { GaimConnection *gc = data; struct simple_account_data *sip = gc->proto_data; struct sip_connection *conn; @@ -1536,7 +1537,7 @@ static void simple_tcp_connect_listen_cb(int listenfd, gpointer data) { struct simple_account_data *sip = (struct simple_account_data*) data; - int error = 0; + GaimProxyConnectInfo *connect_info; sip->listenfd = listenfd; if(sip->listenfd == -1) { @@ -1551,9 +1552,9 @@ gaim_debug_info("simple", "connecting to %s port %d\n", sip->realhostname, sip->realport); /* open tcp connection to the server */ - error = gaim_proxy_connect(sip->account, sip->realhostname, - sip->realport, login_cb, sip->gc); - if(error) { + connect_info = gaim_proxy_connect(sip->account, sip->realhostname, + sip->realport, login_cb, NULL, sip->gc); + if(connect_info == NULL) { gaim_connection_error(sip->gc, _("Couldn't create socket")); } } Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -2239,7 +2239,7 @@ } } -static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_connected(gpointer data, gint source) { GaimConnection *gc = data; struct yahoo_data *yd; @@ -2266,7 +2266,7 @@ gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); } -static void yahoo_got_web_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_web_connected(gpointer data, gint source) { GaimConnection *gc = data; struct yahoo_data *yd; @@ -2348,7 +2348,7 @@ /* Now we have our cookies to login with. I'll go get the milk. */ if (gaim_proxy_connect(account, "wcs2.msg.dcn.yahoo.com", gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_web_connected, gc) != 0) { + yahoo_got_web_connected, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; } @@ -2390,7 +2390,7 @@ gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc); } -static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_cookies(gpointer data, gint source) { GaimConnection *gc = data; @@ -2516,7 +2516,7 @@ "Host: login.yahoo.com\r\n\r\n"); g_hash_table_destroy(hash); yd->auth = g_string_free(url, FALSE); - if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) { + if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; } @@ -2618,7 +2618,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST), gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_connected, gc) != 0) + yahoo_got_connected, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; @@ -2628,7 +2628,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_connected, gc) != 0) + yahoo_got_connected, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -92,7 +92,7 @@ } -static void yahoo_receivefile_connected(gpointer data, gint source, GaimInputCondition condition) +static void yahoo_receivefile_connected(gpointer data, gint source) { GaimXfer *xfer; struct yahoo_xfer_data *xd; @@ -162,7 +162,7 @@ gaim_xfer_start(xfer, source, NULL, 0); } -static void yahoo_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) +static void yahoo_sendfile_connected(gpointer data, gint source) { GaimXfer *xfer; struct yahoo_xfer_data *xd; @@ -263,7 +263,7 @@ if (yd->jp) { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_sendfile_connected, xfer) == -1) + yahoo_sendfile_connected, NULL, xfer) == NULL) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); @@ -272,7 +272,7 @@ } else { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_sendfile_connected, xfer) == -1) + yahoo_sendfile_connected, NULL, xfer) == NULL) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); @@ -280,8 +280,12 @@ } } } else { - xfer->fd = gaim_proxy_connect(account, xfer_data->host, xfer_data->port, - yahoo_receivefile_connected, xfer); + /* TODO: Using xfer->fd like this is probably a bad thing... */ + if (gaim_proxy_connect(account, xfer_data->host, xfer_data->port, + yahoo_receivefile_connected, NULL, xfer) == NULL) + xfer->fd = -1; + else + xfer->fd = 0; if (xfer->fd == -1) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -406,7 +406,7 @@ } } -static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, GaimInputCondition condition) +static void yahoo_buddy_icon_upload_connected(gpointer data, gint source) { struct yahoo_buddy_icon_upload_data *d = data; struct yahoo_packet *pkt; @@ -484,7 +484,7 @@ if (yd->jp) { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, d) == -1) + yahoo_buddy_icon_upload_connected, NULL, d) == NULL) { gaim_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); yahoo_buddy_icon_upload_data_free(d); @@ -492,7 +492,7 @@ } else { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, d) == -1) + yahoo_buddy_icon_upload_connected, NULL, d) == NULL) { gaim_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); yahoo_buddy_icon_upload_data_free(d); Modified: branches/v2_0_0/src/protocols/yahoo/yahoochat.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -1373,7 +1373,7 @@ } -static void yahoo_roomlist_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_roomlist_got_connected(gpointer data, gint source) { struct yahoo_roomlist *yrl = data; GaimRoomlist *list = yrl->list; @@ -1449,8 +1449,8 @@ gaim_roomlist_set_fields(rl, fields); - if (gaim_proxy_connect(gaim_connection_get_account(gc), - yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0) + if (gaim_proxy_connect(gaim_connection_get_account(gc), yrl->host, 80, + yahoo_roomlist_got_connected, NULL, yrl) == NULL) { gaim_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list.")); yahoo_roomlist_cleanup(rl, yrl); @@ -1518,8 +1518,8 @@ yrl->ucat = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat); gaim_roomlist_room_add(list, yrl->ucat); - if (gaim_proxy_connect(list->account, - yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0) + if (gaim_proxy_connect(list->account, yrl->host, 80, + yahoo_roomlist_got_connected, NULL, yrl) == NULL) { gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Connection problem"), _("Unable to fetch room list.")); Modified: branches/v2_0_0/src/protocols/yahoo/ycht.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/ycht.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/protocols/yahoo/ycht.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -528,7 +528,7 @@ } } -static void ycht_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void ycht_got_connected(gpointer data, gint source) { YchtConn *ycht = data; GaimConnection *gc = ycht->gc; @@ -571,7 +571,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "ycht-server", YAHOO_YCHT_HOST), gaim_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT), - ycht_got_connected, ycht) != 0) + ycht_got_connected, NULL, ycht) == NULL) { ycht_connection_error(ycht, _("Connection problem")); return; Modified: branches/v2_0_0/src/proxy.c =================================================================== --- branches/v2_0_0/src/proxy.c 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/proxy.c 2006-08-12 10:26:45 UTC (rev 16714) @@ -38,16 +38,15 @@ #include "proxy.h" #include "util.h" -static GaimProxyInfo *global_proxy_info = NULL; - -struct PHB { - GaimInputFunction func; +/* Does anyone know what PHB stands for? */ +struct _GaimProxyConnectInfo { + GaimProxyConnectFunction connect_cb; + GaimProxyErrorFunction error_cb; gpointer data; char *host; int port; - gint inpa; + guint inpa; GaimProxyInfo *gpi; - GaimAccount *account; GSList *hosts; guchar *write_buffer; gsize write_buf_len; @@ -58,8 +57,6 @@ gsize read_len; }; -static void try_connect(struct PHB *); - static const char *socks5errors[] = { "succeeded\n", "general SOCKS server failure\n", @@ -72,6 +69,11 @@ "Address type not supported\n" }; +static GaimProxyInfo *global_proxy_info = NULL; +static GSList *phbs = NULL; + +static void try_connect(struct _GaimProxyConnectInfo *); + /************************************************************************** * Proxy structure API **************************************************************************/ @@ -255,6 +257,63 @@ * Proxy API **************************************************************************/ +static void +gaim_proxy_phb_destroy(struct _GaimProxyConnectInfo *phb) +{ + phbs = g_slist_remove(phbs, phb); + + if (phb->inpa > 0) + gaim_input_remove(phb->inpa); + + while (phb->hosts != NULL) + { + /* Discard the length... */ + phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); + /* Free the address... */ + g_free(phb->hosts->data); + phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); + } + + g_free(phb->host); + g_free(phb->write_buffer); + g_free(phb->read_buffer); + g_free(phb); +} + +static void +gaim_proxy_phb_connected(struct _GaimProxyConnectInfo *phb, int fd) +{ + phb->connect_cb(phb->data, fd); + gaim_proxy_phb_destroy(phb); +} + +/** + * @param error An error message explaining why the connection + * failed. This will be passed to the callback function + * specified in the call to gaim_proxy_connect(). + */ +static void +gaim_proxy_phb_error(struct _GaimProxyConnectInfo *phb, const gchar *error_message) +{ + if (phb->error_cb == NULL) + { + /* + * TODO + * While we're transitioning to the new gaim_proxy_connect() + * code, not all callers supply an error_cb. If this is the + * case then they're expecting connect_cb to be called with + * an fd of -1 in the case of an error. Once all callers have + * been changed this whole if statement should be removed. + */ + phb->connect_cb(phb->data, -1); + gaim_proxy_phb_destroy(phb); + return; + } + + phb->error_cb(phb->data, error_message); + gaim_proxy_phb_destroy(phb); +} + #if defined(__unix__) || defined(__APPLE__) /* @@ -264,9 +323,9 @@ typedef struct { char *host; int port; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; gpointer data; - gint inpa; + guint inpa; int fd_in, fd_out; pid_t dns_pid; } pending_dns_request_t; @@ -285,7 +344,7 @@ typedef struct { dns_params_t params; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; gpointer data; } queued_dns_request_t; @@ -694,7 +753,7 @@ */ int -gaim_gethostbyname_async(const char *hostname, int port, dns_callback_t callback, gpointer data) +gaim_gethostbyname_async(const char *hostname, int port, GaimProxyDnsConnectFunction callback, gpointer data) { pending_dns_request_t *req = NULL; dns_params_t dns_params; @@ -767,7 +826,7 @@ typedef struct _dns_tdata { char *hostname; int port; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; gpointer data; GSList *hosts; char *errmsg; @@ -843,7 +902,7 @@ int gaim_gethostbyname_async(const char *hostname, int port, - dns_callback_t callback, gpointer data) + GaimProxyDnsConnectFunction callback, gpointer data) { dns_tdata *td; struct sockaddr_in sin; @@ -882,7 +941,7 @@ gpointer data; size_t addrlen; struct sockaddr *addr; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; } pending_dns_request_t; static gboolean host_resolved(gpointer data) @@ -898,7 +957,7 @@ int gaim_gethostbyname_async(const char *hostname, int port, - dns_callback_t callback, gpointer data) + GaimProxyDnsConnectFunction callback, gpointer data) { struct sockaddr_in sin; pending_dns_request_t *req; @@ -932,7 +991,7 @@ static void no_one_calls(gpointer data, gint source, GaimInputCondition cond) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; socklen_t len; int error=0, ret; @@ -955,9 +1014,11 @@ if (ret == 0 && error == EINPROGRESS) return; /* we'll be called again later */ if (ret < 0 || error != 0) { - if(ret!=0) error = errno; + if (ret!=0) + error = errno; close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; gaim_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", strerror(error)); @@ -967,36 +1028,23 @@ } gaim_input_remove(phb->inpa); + phb->inpa = 0; - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, source, GAIM_INPUT_READ); - } - - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, source); } static gboolean clean_connect(gpointer data) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { + gaim_proxy_phb_connected(phb, phb->port); - phb->func(phb->data, phb->port, GAIM_INPUT_READ); - } - - g_free(phb->host); - g_free(phb); - return FALSE; } static int -proxy_connect_none(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +proxy_connect_none(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; @@ -1015,8 +1063,9 @@ if (connect(fd, (struct sockaddr *)addr, addrlen) < 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { - gaim_debug_warning("proxy", - "Connect would have blocked.\n"); + /* This just confuses people. */ + /* gaim_debug_warning("proxy", + "Connect would have blocked.\n"); */ phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); } else { @@ -1036,8 +1085,9 @@ close(fd); return -1; } + /* TODO: Why is the following line so strange? */ phb->port = fd; /* bleh */ - gaim_timeout_add(50, clean_connect, phb); /* we do this because we never + gaim_timeout_add(10, clean_connect, phb); /* we do this because we never want to call our callback before we return. */ } @@ -1048,7 +1098,7 @@ static void proxy_do_write(gpointer data, gint source, GaimInputCondition cond) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; const guchar *request = phb->write_buffer + phb->written_len; gsize request_len = phb->write_buf_len - phb->written_len; @@ -1058,6 +1108,7 @@ return; else if(ret < 0) { gaim_input_remove(phb->inpa); + phb->inpa = 0; close(source); g_free(phb->write_buffer); phb->write_buffer = NULL; @@ -1079,27 +1130,16 @@ #define HTTP_GOODSTRING "HTTP/1.0 200" #define HTTP_GOODSTRING2 "HTTP/1.1 200" -static void -http_complete(struct PHB *phb, gint source) -{ - gaim_debug_info("http proxy", "proxy connection established\n"); - if(!phb->account || phb->account->gc) { - phb->func(phb->data, source, GAIM_INPUT_READ); - } - g_free(phb->host); - g_free(phb); -} - - /* read the response to the CONNECT request, if we are requesting a non-port-80 tunnel */ static void http_canread(gpointer data, gint source, GaimInputCondition cond) { int len, headers_len, status = 0; gboolean error; - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; guchar *p; gsize max_read; + gchar *msg; if(phb->read_buffer == NULL) { phb->read_buf_len = 8192; @@ -1115,12 +1155,7 @@ return; else if(len <= 0) { close(source); - source = -1; - g_free(phb->read_buffer); - phb->read_buffer = NULL; - gaim_input_remove(phb->inpa); - phb->inpa = 0; - http_complete(phb, source); + gaim_proxy_phb_error(phb, _("Lost connection with server for an unknown reason.")); return; } else { phb->read_len += len; @@ -1136,7 +1171,8 @@ return; error = strncmp((const char *)phb->read_buffer, "HTTP/", 5) != 0; - if(!error) { + if (!error) + { int major; p = phb->read_buffer + 5; major = strtol((const char *)p, (char **)&p, 10); @@ -1156,7 +1192,8 @@ /* Read the contents */ p = (guchar *)g_strrstr((const gchar *)phb->read_buffer, "Content-Length: "); - if(p != NULL) { + if (p != NULL) + { gchar *tmp; int len = 0; char tmpc; @@ -1179,25 +1216,22 @@ } } - if(error) { - gaim_debug_error("proxy", - "Unable to parse proxy's response: %s\n", + if (error) + { + close(source); + msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n", phb->read_buffer); - close(source); - source = -1; - g_free(phb->read_buffer); - phb->read_buffer = NULL; - gaim_input_remove(phb->inpa); - phb->inpa = 0; - http_complete(phb, source); + gaim_proxy_phb_error(phb, msg); + g_free(msg); return; - } else if(status != 200) { + } + else if (status != 200) + { gaim_debug_error("proxy", "Proxy server replied with:\n%s\n", phb->read_buffer); - /* XXX: why in the hell are we calling gaim_connection_error() here? */ if(status == 407 /* Proxy Auth */) { gchar *ntlm; if((ntlm = g_strrstr((const gchar *)phb->read_buffer, "Proxy-Authenticate: NTLM "))) { /* Check for Type-2 */ @@ -1207,19 +1241,13 @@ gchar *username; gchar *request; gchar *response; - if(!(username = strchr(domain, '\\'))) { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); + username = strchr(domain, '\\'); + if (username == NULL) + { close(source); - source = -1; - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); return; } *username = '\0'; @@ -1263,19 +1291,13 @@ gchar *domain = (gchar*) gaim_proxy_info_get_username(phb->gpi); gchar *username; int request_len; - if(!(username = strchr(domain, '\\'))) { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); + username = strchr(domain, '\\'); + if (username == NULL) + { close(source); - source = -1; - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); return; } *username = '\0'; @@ -1312,49 +1334,29 @@ proxy_do_write(phb, source, cond); return; } else { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); close(source); - source = -1; - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); return; } } if(status == 403 /* Forbidden */ ) { - gchar *msg = g_strdup_printf(_("Access denied: proxy server forbids port %d tunnelling."), phb->port); - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("Access denied: HTTP proxy server forbids port %d tunnelling."), phb->port); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); } else { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); } } else { gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; - http_complete(phb, source); + gaim_debug_info("proxy", "HTTP proxy connection established\n"); + gaim_proxy_phb_connected(phb, source); return; } } @@ -1366,14 +1368,17 @@ { char request[8192]; int request_len = 0; - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; socklen_t len; int error = ETIMEDOUT; gaim_debug_info("http proxy", "Connected.\n"); if (phb->inpa > 0) + { gaim_input_remove(phb->inpa); + phb->inpa = 0; + } len = sizeof(error); @@ -1426,7 +1431,7 @@ } static int -proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +proxy_connect_http(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; @@ -1455,7 +1460,8 @@ phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); } else { - http_complete(phb, fd); + gaim_debug_info("proxy", "HTTP proxy connection established\n"); + gaim_proxy_phb_connected(phb, fd); } } else { close(fd); @@ -1484,7 +1490,7 @@ static void s4_canread(gpointer data, gint source, GaimInputCondition cond) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; guchar *buf; int len, max_read; @@ -1506,21 +1512,13 @@ return; else if (len + phb->read_len >= 4) { if (phb->read_buffer[1] == 90) { - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, source, GAIM_INPUT_READ); - } - - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, source); return; } } gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; @@ -1534,14 +1532,17 @@ { unsigned char packet[9]; struct hostent *hp; - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; socklen_t len; int error = ETIMEDOUT; gaim_debug_info("socks4 proxy", "Connected.\n"); if (phb->inpa > 0) + { gaim_input_remove(phb->inpa); + phb->inpa = 0; + } len = sizeof(error); @@ -1588,7 +1589,7 @@ } static int -proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +proxy_connect_socks4(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; @@ -1640,7 +1641,7 @@ s5_canread_again(gpointer data, gint source, GaimInputCondition cond) { guchar *dest, *buf; - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; int len; if (phb->read_buffer == NULL) { @@ -1661,6 +1662,7 @@ gaim_debug_warning("socks5 proxy", "or not...\n"); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1678,6 +1680,7 @@ gaim_debug_error("socks5 proxy", "Bad data.\n"); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1714,22 +1717,13 @@ /* Skip past BND.PORT */ buf += 2; - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, source, GAIM_INPUT_READ); - } - - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, source); } static void -s5_sendconnect(gpointer data, gint source) +s5_sendconnect(gpointer data, int source) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; int hlen = strlen(phb->host); phb->write_buf_len = 5 + hlen + 2; phb->write_buffer = g_malloc(phb->write_buf_len); @@ -1748,13 +1742,12 @@ phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, phb); proxy_do_write(phb, source, GAIM_INPUT_WRITE); - } static void s5_readauth(gpointer data, gint source, GaimInputCondition cond) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; int len; if (phb->read_buffer == NULL) { @@ -1772,6 +1765,7 @@ else if(len <= 0) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1783,6 +1777,7 @@ return; gaim_input_remove(phb->inpa); + phb->inpa = 0; if ((phb->read_buffer[0] != 0x01) || (phb->read_buffer[1] != 0x00)) { close(source); @@ -1845,7 +1840,7 @@ s5_readchap(gpointer data, gint source, GaimInputCondition cond) { guchar *cmdbuf, *buf; - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; int len, navas, currentav; gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n"); @@ -1864,6 +1859,7 @@ else if(len <= 0) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1879,6 +1875,7 @@ if (*cmdbuf != 0x01) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1900,6 +1897,7 @@ /* Did auth work? */ if (buf[0] == 0x00) { gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; /* Success */ @@ -1912,6 +1910,7 @@ "failed. Disconnecting..."); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1956,6 +1955,7 @@ "Disconnecting..."); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1973,7 +1973,7 @@ static void s5_canread(gpointer data, gint source, GaimInputCondition cond) { - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; int len; if (phb->read_buffer == NULL) { @@ -1991,6 +1991,7 @@ else if(len <= 0) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -2002,6 +2003,7 @@ return; gaim_input_remove(phb->inpa); + phb->inpa = 0; if ((phb->read_buffer[0] != 0x05) || (phb->read_buffer[1] == 0xff)) { close(source); @@ -2086,14 +2088,17 @@ { unsigned char buf[5]; int i; - struct PHB *phb = data; + struct _GaimProxyConnectInfo *phb = data; socklen_t len; int error = ETIMEDOUT; gaim_debug_info("socks5 proxy", "Connected.\n"); if (phb->inpa > 0) + { gaim_input_remove(phb->inpa); + phb->inpa = 0; + } len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { @@ -2130,7 +2135,7 @@ } static int -proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +proxy_connect_socks5(struct _GaimProxyConnectInfo *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; @@ -2180,7 +2185,7 @@ return fd; } -static void try_connect(struct PHB *phb) +static void try_connect(struct _GaimProxyConnectInfo *phb) { size_t addrlen; struct sockaddr *addr; @@ -2224,14 +2229,7 @@ } if (ret < 0) { - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, -1, GAIM_INPUT_READ); - } - - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_error(phb, _("TODO")); } } @@ -2239,7 +2237,7 @@ connection_host_resolved(GSList *hosts, gpointer data, const char *error_message) { - struct PHB *phb = (struct PHB*)data; + struct _GaimProxyConnectInfo *phb = (struct _GaimProxyConnectInfo*)data; phb->hosts = hosts; @@ -2312,31 +2310,26 @@ return gpi; } -/* - * TODO: It would be really good if this returned some sort of handle - * that we could use to cancel the connection. As it is now, - * each callback has to check to make sure gc is still valid. - * And that is ugly. - */ -int +GaimProxyConnectInfo * gaim_proxy_connect(GaimAccount *account, const char *host, int port, - GaimInputFunction func, gpointer data) + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data) { const char *connecthost = host; int connectport = port; - struct PHB *phb; + struct _GaimProxyConnectInfo *phb; - g_return_val_if_fail(host != NULL, -1); - g_return_val_if_fail(port != 0 && port != -1, -1); - g_return_val_if_fail(func != NULL, -1); + g_return_val_if_fail(host != NULL, NULL); + g_return_val_if_fail(port > 0, NULL); + g_return_val_if_fail(connect_cb != NULL, NULL); + /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ - phb = g_new0(struct PHB, 1); - - phb->func = func; + phb = g_new0(struct _GaimProxyConnectInfo, 1); + phb->connect_cb = connect_cb; + phb->error_cb = error_cb; phb->data = data; phb->host = g_strdup(host); phb->port = port; - phb->account = account; phb->gpi = gaim_proxy_get_setup(account); if ((gaim_proxy_info_get_type(phb->gpi) != GAIM_PROXY_NONE) && @@ -2344,9 +2337,8 @@ gaim_proxy_info_get_port(phb->gpi) <= 0)) { gaim_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid.")); - g_free(phb->host); - g_free(phb); - return -1; + gaim_proxy_phb_destroy(phb); + return NULL; } switch (gaim_proxy_info_get_type(phb->gpi)) @@ -2363,30 +2355,55 @@ break; default: - g_free(phb->host); - g_free(phb); - return -1; + gaim_proxy_phb_destroy(phb); + return NULL; } - return gaim_gethostbyname_async(connecthost, connectport, - connection_host_resolved, phb); + if (gaim_gethostbyname_async(connecthost, + connectport, connection_host_resolved, phb) != 0) + { + gaim_proxy_phb_destroy(phb); + return NULL; + } + + phbs = g_slist_prepend(phbs, phb); + + return phb; } -int +/* + * Combine some of this code with gaim_proxy_connect() + */ +GaimProxyConnectInfo * gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, - GaimInputFunction func, gpointer data) + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data) { - struct PHB *phb; + struct _GaimProxyConnectInfo *phb; - phb = g_new0(struct PHB, 1); - phb->gpi = gpi; - phb->func = func; + g_return_val_if_fail(host != NULL, NULL); + g_return_val_if_fail(port > 0, NULL); + g_return_val_if_fail(connect_cb != NULL, NULL); + /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ + + phb = g_new0(struct _GaimProxyConnectInfo, 1); + phb->connect_cb = connect_cb; + phb->error_cb = error_cb; phb->data = data; phb->host = g_strdup(host); phb->port = port; + phb->gpi = gpi; - return gaim_gethostbyname_async(gaim_proxy_info_get_host(gpi), - gaim_proxy_info_get_port(gpi), connection_host_resolved, phb); + if (gaim_gethostbyname_async(gaim_proxy_info_get_host(gpi), + gaim_proxy_info_get_port(gpi), connection_host_resolved, phb) != 0) + { + gaim_proxy_phb_destroy(phb); + return NULL; + } + + phbs = g_slist_prepend(phbs, phb); + + return phb; } @@ -2424,6 +2441,14 @@ gaim_proxy_info_set_password(info, value); } +void * +gaim_proxy_get_handle() +{ + static int handle; + + return &handle; +} + void gaim_proxy_init(void) { @@ -2458,10 +2483,9 @@ #endif } -void * -gaim_proxy_get_handle() +void +gaim_proxy_uninit(void) { - static int handle; - - return &handle; + while (phbs != NULL) + gaim_proxy_phb_destroy(phbs->data); } Modified: branches/v2_0_0/src/proxy.h =================================================================== --- branches/v2_0_0/src/proxy.h 2006-08-12 10:20:19 UTC (rev 16713) +++ branches/v2_0_0/src/proxy.h 2006-08-12 10:26:45 UTC (rev 16714) @@ -56,7 +56,18 @@ } GaimProxyInfo; +typedef struct _GaimProxyConnectInfo GaimProxyConnectInfo; +typedef void (*GaimProxyConnectFunction)(gpointer data, gint source); +typedef void (*GaimProxyErrorFunction)(gpointer dat, const gchar *error_message); + +/** + * The "hosts" parameter is a linked list containing pairs of + * one size_t addrlen and one struct sockaddr *addr. + */ +typedef void (*GaimProxyDnsConnectFunction)(GSList *hosts, gpointer data, const char *error_message); + + #include "account.h" #ifdef __cplusplus @@ -69,13 +80,6 @@ /*@{*/ /** - * Get the handle for the proxy system. - * - * @return the handle to the proxy system - */ -void *gaim_proxy_get_handle(void); - -/** * Creates a proxy information structure. * * @return The proxy information structure. @@ -196,11 +200,23 @@ /*@{*/ /** + * Returns the proxy subsystem handle. + * + * @return The proxy subsystem handle. + */ +void *gaim_proxy_get_handle(void); + +/** * Initializes the proxy subsystem. */ void gaim_proxy_init(void); /** + * Uninitializes the proxy subsystem. + */ +void gaim_proxy_uninit(void); + +/** * Returns configuration of a proxy. * * @param account The account for which the configuration is needed. @@ -210,35 +226,50 @@ GaimProxyInfo *gaim_proxy_get_setup(GaimAccount *account); /** - * Makes a connection to the specified host and port. + * Makes a connection to the specified host and port. Note that this + * function name can be misleading--although it is called "proxy + * connect," it is used for establishing any outgoing TCP connection, + * whether through a proxy or not. * - * @param account The account making the connection. - * @param host The destination host. - * @param port The destination port. - * @param func The input handler function. - * @param data User-defined data. + * @param account The account making the connection. + * @param host The destination host. + * @param port The destination port. + * @param connect_cb The function to call when the connection is + * established. + * @param error_cb The function to call if there is an error while + * establishing the connection. + * @param data User-defined data. * - * @return Zero indicates the connection is pending. Any other value indicates failure. + * @return NULL if there was an error, or a reference to a data + * structure that can be used to cancel the pending + * connection, if needed. */ -int gaim_proxy_connect(GaimAccount *account, const char *host, int port, - GaimInputFunction func, gpointer data); +GaimProxyConnectInfo *gaim_proxy_connect(GaimAccount *account, + const char *host, int port, + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data); /** * Makes a connection through a SOCKS5 proxy. * - * @param gpi The GaimProxyInfo specifying the proxy settings - * @param host The destination host. - * @param port The destination port. - * @param func The input handler function. - * @param data User-defined data. + * @param gpi The GaimProxyInfo specifying the proxy settings + * @param host The destination host. + * @param port The destination port. + * @param connect_cb The function to call when the connection is + * established. + * @param error_cb The function to call if there is an error while + * establishing the connection. + * @param data User-defined data. * - * @return Zero indicates the connection is pending. Any other value indicates failure. + * @return NULL if there was an error, or a reference to a data + * structure that can be used to cancel the pending + * connection, if needed. */ -int gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, - GaimInputFunction func, gpointer data); +GaimProxyConnectInfo *gaim_proxy_connect_socks5(GaimProxyInfo *gpi, + const char *host, int port, + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data); -typedef void (*dns_callback_t)(GSList *hosts, gpointer data, - const char *error_message); /** * Do an async dns query * @@ -249,7 +280,7 @@ * * @return Zero indicates the connection is pending. Any other value indicates failure. */ -int gaim_gethostbyname_async(const char *hostname, int port, dns_callback_t callback, gpointer data); +int gaim_gethostbyname_async(const char *hostname, int port, GaimProxyDnsConnectFunction callback, gpointer data); /*@}*/ Modified: branches/v2_0_0/src/sslconn.c =====================================================... [truncated message content] |
From: <the...@us...> - 2006-08-13 08:45:14
|
Revision: 16736 Author: thekingant Date: 2006-08-13 01:45:09 -0700 (Sun, 13 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16736&view=rev Log Message: ----------- Backport a few SVN revisions from HEAD to v2_0_0 Original commit messages: 16730 (from datallah): Fix the documentation to indicate that the result of xmlnode_get_data() needs to be g_free'd 16731: Uh, I THINK this is what was intended...? 16732: Jabber crashed when getting info from someone on your buddy list if the JID consists only of the domain identifer. For example, add "quser.alpha.qunu.com" to your buddy list then get their info. This fixes the crashing. I'm not really sure if the fix is correct. Can someone familiar with Jabber please look over this? 16734: gaim_proxy_connect()ion attemps can now be canceled. So there is no longer a need to do that GAIM_CONNECTION_IS_VALID() crap at the top of gaim_proxy_connect() callback functions. All of the callers of gaim_proxy_connect() still need to be updated, though. 16735: Oscar peer connections now use the proxy_connect_cancel() function, so they don't need to use GAIM_CONNECTION_IS_VALID() anymore. Also, peer connection attempts will time out after 15 seconds. Yay. Modified Paths: -------------- branches/v2_0_0/src/protocols/jabber/JEPS branches/v2_0_0/src/protocols/jabber/buddy.c branches/v2_0_0/src/protocols/oscar/peer.c branches/v2_0_0/src/protocols/oscar/peer.h branches/v2_0_0/src/protocols/oscar/peer_proxy.c branches/v2_0_0/src/proxy.c branches/v2_0_0/src/proxy.h branches/v2_0_0/src/xmlnode.h Modified: branches/v2_0_0/src/protocols/jabber/JEPS =================================================================== --- branches/v2_0_0/src/protocols/jabber/JEPS 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/protocols/jabber/JEPS 2006-08-13 08:45:09 UTC (rev 16736) @@ -22,6 +22,6 @@ Gateway Interaction (Transports) 0115: WATCH Client Capabilities -0017: NEED - Advanced IM Protocol Suite +0117: NEED + Intermediate IM Protocol Suite Modified: branches/v2_0_0/src/protocols/jabber/buddy.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/buddy.c 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/protocols/jabber/buddy.c 2006-08-13 08:45:09 UTC (rev 16736) @@ -1119,15 +1119,20 @@ for(resources = jb->resources; resources; resources = resources->next) { JabberBuddyResource *jbr = resources->data; - JabberBuddyInfoResource *jbir = g_new0(JabberBuddyInfoResource, 1); + JabberBuddyInfoResource *jbir; char *full_jid; - if(strrchr(jid, '/')) { + + if ((strchr(jid, '/') == NULL) && (jbr->name != NULL)) { + full_jid = g_strdup_printf("%s/%s", jid, jbr->name); + } else { full_jid = g_strdup(jid); - } else { - full_jid = g_strdup_printf("%s/%s", jid, jbr->name); } - g_hash_table_insert(jbi->resources, g_strdup(jbr->name), jbir); + if (jbr->name != NULL) + { + jbir = g_new0(JabberBuddyInfoResource, 1); + g_hash_table_insert(jbi->resources, g_strdup(jbr->name), jbir); + } if(!jbr->client.name) { iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:version"); Modified: branches/v2_0_0/src/protocols/oscar/peer.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.c 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/protocols/oscar/peer.c 2006-08-13 08:45:09 UTC (rev 16736) @@ -139,6 +139,18 @@ else if (conn->type == OSCAR_CAPABILITY_SENDFILE) peer_oft_close(conn); + if (conn->connect_info != NULL) + { + gaim_proxy_connect_cancel(conn->connect_info); + conn->connect_info = NULL; + } + + if (conn->connect_timeout_timer != 0) + { + gaim_timeout_remove(conn->connect_timeout_timer); + conn->connect_timeout_timer = 0; + } + if (conn->watcher_incoming != 0) { gaim_input_remove(conn->watcher_incoming); @@ -472,21 +484,13 @@ static void peer_connection_established_cb(gpointer data, gint source) { - NewPeerConnectionData *new_conn_data; - GaimConnection *gc; PeerConnection *conn; - new_conn_data = data; - gc = new_conn_data->gc; - conn = new_conn_data->conn; - g_free(new_conn_data); + conn = data; - if (!GAIM_CONNECTION_IS_VALID(gc)) - { - if (source >= 0) - close(source); - return; - } + conn->connect_info = NULL; + gaim_timeout_remove(conn->connect_timeout_timer); + conn->connect_timeout_timer = 0; if (source < 0) { @@ -627,21 +631,54 @@ } /** + * This is a callback function used when we're connecting to a peer + * using either the client IP or the verified IP and the connection + * took longer than 15 seconds to complete. We do this because + * waiting for the OS to time out the connection attempt is not + * practical--the default timeout on many OSes can be 3 minutes or + * more, and users are impatient. + * + * Worst case scenario: the user is connected to the Internet using + * a modem with severe lag. The peer connections fail and Gaim falls + * back to using a proxied connection. The lower bandwidth + * limitations imposed by the proxied connection won't matter because + * the user is using a modem. + * + * I suppose this line of thinking is discriminatory against people + * with very high lag but decent throughput who are transferring + * large files. But we don't care about those people. + */ +static gboolean +peer_connection_tooktoolong(gpointer data) +{ + PeerConnection *conn; + + conn = data; + + gaim_debug_info("oscar", "Peer connection timed out after 15 seconds. " + "Trying next method...\n"); + + gaim_proxy_connect_cancel(conn->connect_info); + conn->connect_info = NULL; + conn->connect_timeout_timer = 0; + + peer_connection_trynext(conn); + + /* Cancel this timer. It'll be added again, if needed. */ + return FALSE; +} + +/** * Try to establish the given PeerConnection using a defined * sequence of steps. */ void peer_connection_trynext(PeerConnection *conn) { - NewPeerConnectionData *new_conn_data; GaimAccount *account; - new_conn_data = g_new(NewPeerConnectionData, 1); - new_conn_data->gc = conn->od->gc; - new_conn_data->conn = conn; + account = gaim_connection_get_account(conn->od->gc); - account = gaim_connection_get_account(new_conn_data->gc); - /* * Close any remnants of a previous failed connection attempt. */ @@ -667,10 +704,14 @@ g_free(tmp); } - if (gaim_proxy_connect(account, conn->verifiedip, conn->port, - peer_connection_established_cb, NULL, new_conn_data) != NULL) + conn->connect_info = gaim_proxy_connect(account, + conn->verifiedip, conn->port, + peer_connection_established_cb, NULL, conn); + if (conn->connect_info != NULL) { /* Connecting... */ + conn->connect_timeout_timer = gaim_timeout_add(15000, + peer_connection_tooktoolong, conn); return; } } @@ -698,10 +739,14 @@ g_free(tmp); } - if (gaim_proxy_connect(account, conn->clientip, conn->port, - peer_connection_established_cb, NULL, new_conn_data) != NULL) + conn->connect_info = gaim_proxy_connect(account, + conn->clientip, conn->port, + peer_connection_established_cb, NULL, conn); + if (conn->connect_info != NULL) { /* Connecting... */ + conn->connect_timeout_timer = gaim_timeout_add(15000, + peer_connection_tooktoolong, conn); return; } } @@ -714,6 +759,12 @@ if (!(conn->flags & PEER_CONNECTION_FLAG_TRIED_INCOMING) && (!conn->use_proxy)) { + NewPeerConnectionData *new_conn_data; + + new_conn_data = g_new(NewPeerConnectionData, 1); + new_conn_data->gc = conn->od->gc; + new_conn_data->conn = conn; + conn->flags |= PEER_CONNECTION_FLAG_TRIED_INCOMING; /* @@ -728,6 +779,8 @@ /* Opening listener socket... */ return; } + + g_free(new_conn_data); } /* @@ -757,18 +810,17 @@ g_free(tmp); } - if (gaim_proxy_connect(account, + conn->connect_info = gaim_proxy_connect(account, (conn->proxyip != NULL) ? conn->proxyip : PEER_PROXY_SERVER, PEER_PROXY_PORT, - peer_proxy_connection_established_cb, NULL, new_conn_data) != NULL) + peer_proxy_connection_established_cb, NULL, conn); + if (conn->connect_info != NULL) { /* Connecting... */ return; } } - g_free(new_conn_data); - /* Give up! */ peer_connection_destroy(conn, OSCAR_DISCONNECT_COULD_NOT_CONNECT); } Modified: branches/v2_0_0/src/protocols/oscar/peer.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.h 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/protocols/oscar/peer.h 2006-08-13 08:45:09 UTC (rev 16736) @@ -159,10 +159,21 @@ gpointer frame; /** + * This is only used when the peer connection is being established. + */ + GaimProxyConnectInfo *connect_info; + + /** + * This is only used when the peer connection is being established. + */ + guint connect_timeout_timer; + + /** * This is only used while the remote user is attempting to * connect to us. */ int listenerfd; + int fd; guint watcher_incoming; Modified: branches/v2_0_0/src/protocols/oscar/peer_proxy.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-08-13 08:45:09 UTC (rev 16736) @@ -328,21 +328,11 @@ void peer_proxy_connection_established_cb(gpointer data, gint source) { - NewPeerConnectionData *new_conn_data; - GaimConnection *gc; PeerConnection *conn; - new_conn_data = data; - gc = new_conn_data->gc; - conn = new_conn_data->conn; - g_free(new_conn_data); + conn = data; - if (!GAIM_CONNECTION_IS_VALID(gc)) - { - if (source >= 0) - close(source); - return; - } + conn->connect_info = NULL; if (source < 0) { Modified: branches/v2_0_0/src/proxy.c =================================================================== --- branches/v2_0_0/src/proxy.c 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/proxy.c 2006-08-13 08:45:09 UTC (rev 16736) @@ -44,6 +44,7 @@ gpointer data; char *host; int port; + int fd; guint inpa; GaimProxyInfo *gpi; @@ -53,6 +54,10 @@ */ GSList *hosts; + /* + * All of the following variables are used when establishing a + * connection through a proxy. + */ guchar *write_buffer; gsize write_buf_len; gsize written_len; @@ -75,9 +80,15 @@ }; static GaimProxyInfo *global_proxy_info = NULL; + +/* + * TODO: Once all callers of gaim_proxy_connect() are keeping track + * of the return value from that function this linked list + * will no longer be needed. + */ static GSList *connect_infos = NULL; -static void try_connect(GaimProxyConnectInfo *); +static void try_connect(GaimProxyConnectInfo *connect_info); /************************************************************************** * Proxy structure API @@ -262,14 +273,41 @@ * Proxy API **************************************************************************/ +/* + * This is used when the connection attempt to one particular IP + * address fails. We close the socket, remove the watcher and get + * rid of input and output buffers. Normally try_connect() will + * be called immediately after this. + */ static void +gaim_proxy_connect_info_disconnect(GaimProxyConnectInfo *connect_info) +{ + if (connect_info->inpa > 0) + { + gaim_input_remove(connect_info->inpa); + connect_info->inpa = 0; + } + + if (connect_info->fd >= 0) + { + close(connect_info->fd); + connect_info->fd = -1; + } + + g_free(connect_info->write_buffer); + connect_info->write_buffer = NULL; + + g_free(connect_info->read_buffer); + connect_info->read_buffer = NULL; +} + +static void gaim_proxy_connect_info_destroy(GaimProxyConnectInfo *connect_info) { + gaim_proxy_connect_info_disconnect(connect_info); + connect_infos = g_slist_remove(connect_infos, connect_info); - if (connect_info->inpa > 0) - gaim_input_remove(connect_info->inpa); - while (connect_info->hosts != NULL) { /* Discard the length... */ @@ -280,15 +318,21 @@ } g_free(connect_info->host); - g_free(connect_info->write_buffer); - g_free(connect_info->read_buffer); g_free(connect_info); } static void -gaim_proxy_connect_info_connected(GaimProxyConnectInfo *connect_info, int fd) +gaim_proxy_connect_info_connected(GaimProxyConnectInfo *connect_info) { - connect_info->connect_cb(connect_info->data, fd); + connect_info->connect_cb(connect_info->data, connect_info->fd); + + /* + * We've passed the file descriptor to the protocol, so it's no longer + * our responsibility, and we should be careful not to free it when + * we destroy the connect_info. + */ + connect_info->fd = -1; + gaim_proxy_connect_info_destroy(connect_info); } @@ -1019,19 +1063,17 @@ * be overly optimistic sometimes. select is just a hint that you might be * able to do something.) */ - ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); + ret = getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len); if (ret == 0 && error == EINPROGRESS) return; /* we'll be called again later */ if (ret < 0 || error != 0) { if (ret!=0) error = errno; - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; gaim_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", strerror(error)); + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1039,71 +1081,77 @@ gaim_input_remove(connect_info->inpa); connect_info->inpa = 0; - gaim_proxy_connect_info_connected(connect_info, source); + gaim_proxy_connect_info_connected(connect_info); } -static gboolean clean_connect(gpointer data) +static gboolean +clean_connect(gpointer data) { - GaimProxyConnectInfo *connect_info = data; + GaimProxyConnectInfo *connect_info; - gaim_proxy_connect_info_connected(connect_info, connect_info->port); + connect_info = data; + gaim_proxy_connect_info_connected(connect_info); return FALSE; } - static int proxy_connect_none(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) { - int fd = -1; + gaim_debug_info("proxy", "Connecting to %s:%d with no proxy\n", + connect_info->host, connect_info->port); - gaim_debug_info("proxy", - "Connecting to %s:%d with no proxy\n", connect_info->host, connect_info->port); - - if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { + connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); + if (connect_info->fd < 0) + { gaim_debug_error("proxy", "Unable to create socket: %s\n", strerror(errno)); return -1; } - fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); #ifndef _WIN32 - fcntl(fd, F_SETFD, FD_CLOEXEC); + fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); #endif - if (connect(fd, (struct sockaddr *)addr, addrlen) != 0) + if (connect(connect_info->fd, (struct sockaddr *)addr, addrlen) != 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { - /* This just confuses people. */ - /* gaim_debug_warning("proxy", - "Connect would have blocked.\n"); */ - connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, connect_info); + gaim_debug_info("proxy", "Connection in progress\n"); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, no_one_calls, connect_info); } else { gaim_debug_error("proxy", "Connect failed: %s\n", strerror(errno)); - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } } - else { + else + { + /* + * The connection happened IMMEDIATELY... strange, but whatever. + */ socklen_t len; int error = ETIMEDOUT; - gaim_debug_misc("proxy", "Connect didn't block.\n"); + gaim_debug_info("proxy", "Connected immediately.\n"); len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { gaim_debug_error("proxy", "getsockopt failed.\n"); - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } - /* TODO: Why is the following line so strange? */ - connect_info->port = fd; /* bleh */ - gaim_timeout_add(10, clean_connect, connect_info); /* we do this because we never - want to call our callback - before we return. */ + + /* + * We want to call the "connected" callback eventually, but we + * don't want to call it before we return, just in case. + */ + gaim_timeout_add(10, clean_connect, connect_info); } - return fd; + return connect_info->fd; } static void @@ -1113,16 +1161,12 @@ const guchar *request = connect_info->write_buffer + connect_info->written_len; gsize request_len = connect_info->write_buf_len - connect_info->written_len; - int ret = write(source, request, request_len); + int ret = write(connect_info->fd, request, request_len); if(ret < 0 && errno == EAGAIN) return; else if(ret < 0) { - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - close(source); - g_free(connect_info->write_buffer); - connect_info->write_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } else if (ret < request_len) { @@ -1135,7 +1179,7 @@ connect_info->write_buffer = NULL; /* register the response handler for the response */ - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_READ, connect_info->read_cb, connect_info); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_READ, connect_info->read_cb, connect_info); } #define HTTP_GOODSTRING "HTTP/1.0 200" @@ -1161,11 +1205,10 @@ p = connect_info->read_buffer + connect_info->read_len; max_read = connect_info->read_buf_len - connect_info->read_len - 1; - len = read(source, p, max_read); + len = read(connect_info->fd, p, max_read); if(len < 0 && errno == EAGAIN) return; else if(len <= 0) { - close(source); gaim_proxy_connect_info_error(connect_info, _("Lost connection with server for an unknown reason.")); return; } else { @@ -1222,14 +1265,13 @@ complaining / breaking since we don't read the whole page */ while(len--) { /* TODO: deal with EAGAIN (and other errors) better */ - if (read(source, &tmpc, 1) < 0 && errno != EAGAIN) + if (read(connect_info->fd, &tmpc, 1) < 0 && errno != EAGAIN) break; } } if (error) { - close(source); msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n", connect_info->read_buffer); gaim_proxy_connect_info_error(connect_info, msg); @@ -1255,7 +1297,6 @@ username = strchr(domain, '\\'); if (username == NULL) { - close(source); msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); gaim_proxy_connect_info_error(connect_info, msg); g_free(msg); @@ -1292,10 +1333,10 @@ connect_info->read_cb = http_canread; - connect_info->inpa = gaim_input_add(source, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, cond); + proxy_do_write(connect_info, connect_info->fd, cond); return; } else if((ntlm = g_strrstr((const char *)connect_info->read_buffer, "Proxy-Authenticate: NTLM"))) { /* Empty message */ gchar request[2048]; @@ -1305,7 +1346,6 @@ username = strchr(domain, '\\'); if (username == NULL) { - close(source); msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); gaim_proxy_connect_info_error(connect_info, msg); g_free(msg); @@ -1339,13 +1379,12 @@ connect_info->read_cb = http_canread; - connect_info->inpa = gaim_input_add(source, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, cond); + proxy_do_write(connect_info, connect_info->fd, cond); return; } else { - close(source); msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); gaim_proxy_connect_info_error(connect_info, msg); g_free(msg); @@ -1367,7 +1406,7 @@ g_free(connect_info->read_buffer); connect_info->read_buffer = NULL; gaim_debug_info("proxy", "HTTP proxy connection established\n"); - gaim_proxy_connect_info_connected(connect_info, source); + gaim_proxy_connect_info_connected(connect_info); return; } } @@ -1393,9 +1432,8 @@ len = sizeof(error); - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - close(source); - + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1435,48 +1473,46 @@ connect_info->read_cb = http_canread; - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, cond); + proxy_do_write(connect_info, connect_info->fd, cond); } static int proxy_connect_http(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) { - int fd = -1; - gaim_debug_info("http proxy", "Connecting to %s:%d via %s:%d using HTTP\n", (connect_info->host ? connect_info->host : "(null)"), connect_info->port, (gaim_proxy_info_get_host(connect_info->gpi) ? gaim_proxy_info_get_host(connect_info->gpi) : "(null)"), gaim_proxy_info_get_port(connect_info->gpi)); - if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { + connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); + if (connect_info->fd < 0) return -1; - } - fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); #ifndef _WIN32 - fcntl(fd, F_SETFD, FD_CLOEXEC); + fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); #endif - if (connect(fd, addr, addrlen) != 0) + if (connect(connect_info->fd, addr, addrlen) != 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { - gaim_debug_warning("http proxy", - "Connect would have blocked.\n"); + gaim_debug_info("http proxy", "Connection in progress\n"); if (connect_info->port != 80) { /* we need to do CONNECT first */ - connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, http_canwrite, connect_info); } else { gaim_debug_info("proxy", "HTTP proxy connection established\n"); - gaim_proxy_connect_info_connected(connect_info, fd); + gaim_proxy_connect_info_connected(connect_info); } } else { - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } } @@ -1484,19 +1520,19 @@ socklen_t len; int error = ETIMEDOUT; - gaim_debug_misc("http proxy", - "Connect didn't block.\n"); + gaim_debug_info("http proxy", "Connected immediately.\n"); len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } - http_canwrite(connect_info, fd, GAIM_INPUT_WRITE); + http_canwrite(connect_info, connect_info->fd, GAIM_INPUT_WRITE); } - return fd; + return connect_info->fd; } @@ -1519,24 +1555,18 @@ buf = connect_info->read_buffer + connect_info->read_len; max_read = connect_info->read_buf_len - connect_info->read_len; - len = read(source, buf, max_read); + len = read(connect_info->fd, buf, max_read); if ((len < 0 && errno == EAGAIN) || (len > 0 && len + connect_info->read_len < 4)) return; else if (len + connect_info->read_len >= 4) { if (connect_info->read_buffer[1] == 90) { - gaim_proxy_connect_info_connected(connect_info, source); + gaim_proxy_connect_info_connected(connect_info); return; } } - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; - - close(source); - + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); } @@ -1559,9 +1589,8 @@ len = sizeof(error); - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - close(source); - + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1574,9 +1603,10 @@ * with an option, or some detection mechanism - in the * meantime, stick with plain old SOCKS4. */ - if (!(hp = gethostbyname(connect_info->host))) { - close(source); - + /* TODO: This needs to be non-blocking! */ + hp = gethostbyname(connect_info->host); + if (hp == NULL) { + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1596,60 +1626,59 @@ connect_info->written_len = 0; connect_info->read_cb = s4_canread; - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, cond); + proxy_do_write(connect_info, connect_info->fd, cond); } static int proxy_connect_socks4(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) { - int fd = -1; - gaim_debug_info("socks4 proxy", "Connecting to %s:%d via %s:%d using SOCKS4\n", connect_info->host, connect_info->port, gaim_proxy_info_get_host(connect_info->gpi), gaim_proxy_info_get_port(connect_info->gpi)); - if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) + connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); + if (connect_info->fd < 0) return -1; - fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); #ifndef _WIN32 - fcntl(fd, F_SETFD, FD_CLOEXEC); + fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); #endif - if (connect(fd, addr, addrlen) != 0) + if (connect(connect_info->fd, addr, addrlen) != 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { - gaim_debug_warning("socks4 proxy", - "Connect would have blocked.\n"); - connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, connect_info); + gaim_debug_info("socks4 proxy", "Connection in progress.\n"); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, s4_canwrite, connect_info); } else { - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } } else { socklen_t len; int error = ETIMEDOUT; - gaim_debug_misc("socks4 proxy", - "Connect didn't block.\n"); + gaim_debug_info("socks4 proxy", "Connected immediately.\n"); len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } - s4_canwrite(connect_info, fd, GAIM_INPUT_WRITE); + s4_canwrite(connect_info, connect_info->fd, GAIM_INPUT_WRITE); } - return fd; + return connect_info->fd; } static void @@ -1670,16 +1699,12 @@ gaim_debug_info("socks5 proxy", "Able to read again.\n"); - len = read(source, dest, (connect_info->read_buf_len - connect_info->read_len)); + len = read(connect_info->fd, dest, (connect_info->read_buf_len - connect_info->read_len)); if(len < 0 && errno == EAGAIN) return; else if(len <= 0) { gaim_debug_warning("socks5 proxy", "or not...\n"); - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1693,11 +1718,7 @@ gaim_debug_error("socks5 proxy", socks5errors[buf[1]]); else gaim_debug_error("socks5 proxy", "Bad data.\n"); - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1732,7 +1753,7 @@ /* Skip past BND.PORT */ buf += 2; - gaim_proxy_connect_info_connected(connect_info, source); + gaim_proxy_connect_info_connected(connect_info); } static void @@ -1755,8 +1776,8 @@ connect_info->read_cb = s5_canread_again; - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); + proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); } static void @@ -1773,16 +1794,12 @@ gaim_debug_info("socks5 proxy", "Got auth response.\n"); - len = read(source, connect_info->read_buffer + connect_info->read_len, + len = read(connect_info->fd, connect_info->read_buffer + connect_info->read_len, connect_info->read_buf_len - connect_info->read_len); if(len < 0 && errno == EAGAIN) return; else if(len <= 0) { - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1795,9 +1812,7 @@ connect_info->inpa = 0; if ((connect_info->read_buffer[0] != 0x01) || (connect_info->read_buffer[1] != 0x00)) { - close(source); - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1805,7 +1820,7 @@ g_free(connect_info->read_buffer); connect_info->read_buffer = NULL; - s5_sendconnect(connect_info, source); + s5_sendconnect(connect_info, connect_info->fd); } static void @@ -1867,17 +1882,13 @@ connect_info->read_len = 0; } - len = read(source, connect_info->read_buffer + connect_info->read_len, + len = read(connect_info->fd, connect_info->read_buffer + connect_info->read_len, connect_info->read_buf_len - connect_info->read_len); if(len < 0 && errno == EAGAIN) return; else if(len <= 0) { - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1889,11 +1900,7 @@ cmdbuf = connect_info->read_buffer; if (*cmdbuf != 0x01) { - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1917,18 +1924,14 @@ g_free(connect_info->read_buffer); connect_info->read_buffer = NULL; /* Success */ - s5_sendconnect(connect_info, source); + s5_sendconnect(connect_info, connect_info->fd); return; } else { /* Failure */ gaim_debug_warning("proxy", "socks5 CHAP authentication " "failed. Disconnecting..."); - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -1954,10 +1957,10 @@ connect_info->read_cb = s5_readchap; - connect_info->inpa = gaim_input_add(source, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); + proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); break; case 0x11: /* Server wants to select an algorithm */ @@ -1969,11 +1972,7 @@ "as supporting. This is a violation " "of the socks5 CHAP specification. " "Disconnecting..."); - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -2000,16 +1999,12 @@ gaim_debug_info("socks5 proxy", "Able to read.\n"); - len = read(source, connect_info->read_buffer + connect_info->read_len, + len = read(connect_info->fd, connect_info->read_buffer + connect_info->read_len, connect_info->read_buf_len - connect_info->read_len); if(len < 0 && errno == EAGAIN) return; else if(len <= 0) { - close(source); - gaim_input_remove(connect_info->inpa); - connect_info->inpa = 0; - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -2022,9 +2017,7 @@ connect_info->inpa = 0; if ((connect_info->read_buffer[0] != 0x05) || (connect_info->read_buffer[1] == 0xff)) { - close(source); - g_free(connect_info->read_buffer); - connect_info->read_buffer = NULL; + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -2056,10 +2049,10 @@ connect_info->read_cb = s5_readauth; - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); + proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); return; } else if (connect_info->read_buffer[1] == 0x03) { @@ -2085,17 +2078,17 @@ connect_info->read_cb = s5_readchap; - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); + proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); return; } else { g_free(connect_info->read_buffer); connect_info->read_buffer = NULL; - s5_sendconnect(connect_info, source); + s5_sendconnect(connect_info, connect_info->fd); } } @@ -2117,9 +2110,8 @@ } len = sizeof(error); - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - close(source); - + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + gaim_proxy_connect_info_disconnect(connect_info); try_connect(connect_info); return; } @@ -2146,39 +2138,37 @@ connect_info->read_cb = s5_canread; - connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); - proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); + proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); } static int proxy_connect_socks5(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) { - int fd = -1; - gaim_debug_info("socks5 proxy", "Connecting to %s:%d via %s:%d using SOCKS5\n", connect_info->host, connect_info->port, gaim_proxy_info_get_host(connect_info->gpi), gaim_proxy_info_get_port(connect_info->gpi)); - if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) + connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); + if (connect_info->fd < 0) return -1; - fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); #ifndef _WIN32 - fcntl(fd, F_SETFD, FD_CLOEXEC); + fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); #endif - if (connect(fd, addr, addrlen) != 0) + if (connect(connect_info->fd, addr, addrlen) != 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { - gaim_debug_warning("socks5 proxy", - "Connect would have blocked.\n"); - - connect_info->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, connect_info); + gaim_debug_info("socks5 proxy", "Connection in progress\n"); + connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, s5_canwrite, connect_info); } else { - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } } @@ -2186,22 +2176,28 @@ socklen_t len; int error = ETIMEDOUT; - gaim_debug_misc("socks5 proxy", "Connect didn't block.\n"); + gaim_debug_info("socks5 proxy", "Connected immediately.\n"); len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) + if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { - close(fd); + close(connect_info->fd); + connect_info->fd = -1; return -1; } - s5_canwrite(connect_info, fd, GAIM_INPUT_WRITE); + s5_canwrite(connect_info, connect_info->fd, GAIM_INPUT_WRITE); } - return fd; + return connect_info->fd; } +/** + * This function iterates through a list of IP addresses and attempts + * to connect to each one. This is called after the hostname is + * resolved, and if a connection attempt fails. + */ static void try_connect(GaimProxyConnectInfo *connect_info) { size_t addrlen; @@ -2356,6 +2352,7 @@ /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ connect_info = g_new0(GaimProxyConnectInfo, 1); + connect_info->fd = -1; connect_info->connect_cb = connect_cb; connect_info->error_cb = error_cb; connect_info->data = data; @@ -2418,6 +2415,7 @@ /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ connect_info = g_new0(GaimProxyConnectInfo, 1); + connect_info->fd = -1; connect_info->connect_cb = connect_cb; connect_info->error_cb = error_cb; connect_info->data = data; @@ -2437,6 +2435,11 @@ return connect_info; } +void +gaim_proxy_connect_cancel(GaimProxyConnectInfo *connect_info) +{ + gaim_proxy_connect_info_destroy(connect_info); +} static void proxy_pref_cb(const char *name, GaimPrefType type, Modified: branches/v2_0_0/src/proxy.h =================================================================== --- branches/v2_0_0/src/proxy.h 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/proxy.h 2006-08-13 08:45:09 UTC (rev 16736) @@ -271,6 +271,17 @@ GaimProxyErrorFunction error_cb, gpointer data); /** + * Cancel an in-progress connection attempt. This should be called + * by the PRPL if the user disables an account while it is still + * performing the initial sign on. Or when establishing a file + * transfer, if we attempt to connect to a remote user but they + * are behind a firewall then the PRPL can cancel the connection + * attempt early rather than just letting the OS's TCP/IP stack + * time-out the connection. + */ +void gaim_proxy_connect_cancel(GaimProxyConnectInfo *connect_info); + +/** * Do an async dns query * * @param hostname The hostname to resolve Modified: branches/v2_0_0/src/xmlnode.h =================================================================== --- branches/v2_0_0/src/xmlnode.h 2006-08-13 08:41:07 UTC (rev 16735) +++ branches/v2_0_0/src/xmlnode.h 2006-08-13 08:45:09 UTC (rev 16736) @@ -31,7 +31,7 @@ typedef enum _XMLNodeType { XMLNODE_TYPE_TAG, /**< Just a tag */ - XMLNODE_TYPE_ATTRIB, /**< Has attributes */ + XMLNODE_TYPE_ATTRIB, /**< Has attributes */ XMLNODE_TYPE_DATA /**< Has data */ } XMLNodeType; @@ -40,13 +40,13 @@ */ typedef struct _xmlnode { - char *name; /**< The name of the node. */ + char *name; /**< The name of the node. */ #ifdef HAVE_LIBXML - char *namespace; /**< The namespace of the node */ + char *namespace; /**< The namespace of the node */ #endif - XMLNodeType type; /**< The type of the node. */ - char *data; /**< The data for the node. */ - size_t data_sz; /**< The size of the data. */ + XMLNodeType type; /**< The type of the node. */ + char *data; /**< The data for the node. */ + size_t data_sz; /**< The size of the data. */ struct _xmlnode *parent; /**< The parent node or @c NULL.*/ struct _xmlnode *child; /**< The child node or @c NULL.*/ struct _xmlnode *lastchild; /**< The last child node or @c NULL.*/ @@ -125,7 +125,8 @@ * * @param node The node to get data from. * - * @return The data from the node. + * @return The data from the node. You must g_free + * this string when finished using it. */ char *xmlnode_get_data(xmlnode *node); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-14 08:36:38
|
Revision: 16756 Author: thekingant Date: 2006-08-14 01:36:25 -0700 (Mon, 14 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16756&view=rev Log Message: ----------- Alright, backport SVN revisions 16742 through 16755 from HEAD to v2_0_0 This was mostly my changes to protocols to use gaim_proxy_connect_cancel() Modified Paths: -------------- branches/v2_0_0/plugins/ChangeLog.API branches/v2_0_0/src/connection.h branches/v2_0_0/src/ft.c branches/v2_0_0/src/protocols/irc/irc.c branches/v2_0_0/src/protocols/irc/irc.h branches/v2_0_0/src/protocols/jabber/jabber.c branches/v2_0_0/src/protocols/jabber/jabber.h branches/v2_0_0/src/protocols/jabber/si.c branches/v2_0_0/src/protocols/msn/directconn.c branches/v2_0_0/src/protocols/msn/directconn.h branches/v2_0_0/src/protocols/msn/httpconn.c branches/v2_0_0/src/protocols/msn/httpconn.h branches/v2_0_0/src/protocols/msn/servconn.c branches/v2_0_0/src/protocols/msn/servconn.h branches/v2_0_0/src/protocols/oscar/flap_connection.c branches/v2_0_0/src/protocols/oscar/oscar.c branches/v2_0_0/src/protocols/oscar/oscar.h branches/v2_0_0/src/protocols/oscar/peer.c branches/v2_0_0/src/protocols/oscar/peer.h branches/v2_0_0/src/protocols/oscar/peer_proxy.c branches/v2_0_0/src/protocols/sametime/sametime.c branches/v2_0_0/src/protocols/silc/silc.c branches/v2_0_0/src/protocols/silc/silcgaim.h branches/v2_0_0/src/protocols/simple/simple.c branches/v2_0_0/src/protocols/toc/toc.c branches/v2_0_0/src/protocols/yahoo/yahoo.c branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c branches/v2_0_0/src/protocols/yahoo/yahoochat.c branches/v2_0_0/src/protocols/yahoo/ycht.c branches/v2_0_0/src/proxy.c branches/v2_0_0/src/proxy.h branches/v2_0_0/src/sslconn.c branches/v2_0_0/src/upnp.c branches/v2_0_0/src/util.c Modified: branches/v2_0_0/plugins/ChangeLog.API =================================================================== --- branches/v2_0_0/plugins/ChangeLog.API 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/plugins/ChangeLog.API 2006-08-14 08:36:25 UTC (rev 16756) @@ -114,9 +114,9 @@ * All network activity has been updated to use non-blocking sockets. This means that plugins must be updated to expect such a socket from gaim_proxy_connect() and gaim_network_listen*(). - * gaim_proxy_connect(): changed to return NULL on error and a void * - handle on success, and changed parameters. It is now possible to - cancel connection attempts. + * gaim_proxy_connect(): changed to return NULL on error and a pointer + to a GaimProxyConnectInfo object which can be used to cancel + connection attempts using gaim_proxy_connect_cancel(). * gaim_gtk_create_imhtml(): Added sw_ret() parameter * gaim_account_get_log(): Added create parameter * GAIM_CMD_P_VERYHIGH is now GAIM_CMD_P_VERY_HIGH Modified: branches/v2_0_0/src/connection.h =================================================================== --- branches/v2_0_0/src/connection.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/connection.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -271,6 +271,10 @@ * * @return @c TRUE if gc is valid. */ +/* + * TODO: Eventually this bad boy will be removed, because it is + * a gross fix for a crashy problem. + */ #define GAIM_CONNECTION_IS_VALID(gc) (g_list_find(gaim_connections_get_all(), (gc))) /*@}*/ Modified: branches/v2_0_0/src/ft.c =================================================================== --- branches/v2_0_0/src/ft.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/ft.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -911,7 +911,7 @@ } static void -connect_cb(gpointer data, gint source) +connect_cb(gpointer data, gint source, const gchar *error_message) { GaimXfer *xfer = (GaimXfer *)data; @@ -946,7 +946,7 @@ /* Establish a file descriptor. */ gaim_proxy_connect(xfer->account, xfer->remote_ip, - xfer->remote_port, connect_cb, NULL, xfer); + xfer->remote_port, connect_cb, xfer); return; } Modified: branches/v2_0_0/src/protocols/irc/irc.c =================================================================== --- branches/v2_0_0/src/protocols/irc/irc.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/irc/irc.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -46,7 +46,7 @@ /* static GList *irc_chat_info(GaimConnection *gc); */ static void irc_login(GaimAccount *account); static void irc_login_cb_ssl(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond); -static void irc_login_cb(gpointer data, gint source); +static void irc_login_cb(gpointer data, gint source, const gchar *error_message); static void irc_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, gpointer data); static void irc_close(GaimConnection *gc); static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags); @@ -283,7 +283,6 @@ struct irc_conn *irc; char **userparts; const char *username = gaim_account_get_username(account); - GaimProxyConnectInfo *connect_info; gc = gaim_account_get_connection(account); gc->flags |= GAIM_CONNECTION_NO_NEWLINES; @@ -325,11 +324,11 @@ if (!irc->gsc) { - connect_info = gaim_proxy_connect(account, irc->server, + irc->connect_info = gaim_proxy_connect(account, irc->server, gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), - irc_login_cb, NULL, gc); + irc_login_cb, gc); - if (!connect_info || !gaim_account_get_connection(account)) { + if (!irc->connect_info || !gaim_account_get_connection(account)) { gaim_connection_error(gc, _("Couldn't create socket")); return; } @@ -394,22 +393,18 @@ } } -static void irc_login_cb(gpointer data, gint source) +static void irc_login_cb(gpointer data, gint source, const gchar *error_message) { GaimConnection *gc = data; struct irc_conn *irc = gc->proto_data; - GList *connections = gaim_connections_get_all(); + irc->connect_info = NULL; + if (source < 0) { gaim_connection_error(gc, _("Couldn't connect to host")); return; } - if (!g_list_find(connections, gc)) { - close(source); - return; - } - irc->fd = source; if (do_login(gc)) { @@ -443,8 +438,12 @@ if (irc == NULL) return; - irc_cmd_quit(irc, "quit", NULL, NULL); + if (irc->gsc || (irc->fd >= 0)) + irc_cmd_quit(irc, "quit", NULL, NULL); + if (irc->connect_info) + gaim_proxy_connect_cancel(irc->connect_info); + if (gc->inpa) gaim_input_remove(gc->inpa); Modified: branches/v2_0_0/src/protocols/irc/irc.h =================================================================== --- branches/v2_0_0/src/protocols/irc/irc.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/irc/irc.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -54,6 +54,8 @@ guint timer; GHashTable *buddies; + GaimProxyConnectInfo *connect_info; + char *inbuf; int inbuflen; int inbufused; Modified: branches/v2_0_0/src/protocols/jabber/jabber.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/jabber/jabber.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -30,6 +30,7 @@ #include "message.h" #include "notify.h" #include "pluginpref.h" +#include "proxy.h" #include "prpl.h" #include "request.h" #include "server.h" @@ -418,21 +419,18 @@ static void -jabber_login_callback(gpointer data, gint source) +jabber_login_callback(gpointer data, gint source, const gchar *error) { GaimConnection *gc = data; JabberStream *js = gc->proto_data; + js->connect_info = NULL; + if (source < 0) { gaim_connection_error(gc, _("Couldn't connect to host")); return; } - if(!g_list_find(gaim_connections_get_all(), gc)) { - close(source); - return; - } - js->fd = source; if(js->state == JABBER_STREAM_CONNECTING) @@ -471,12 +469,10 @@ static void jabber_login_connect(JabberStream *js, const char *server, int port) { - GaimProxyConnectInfo *connect_info; + js->connect_info = gaim_proxy_connect(js->gc->account, server, + port, jabber_login_callback, js->gc); - connect_info = gaim_proxy_connect(js->gc->account, server, - port, jabber_login_callback, NULL, js->gc); - - if (connect_info == NULL) + if (js->connect_info == NULL) gaim_connection_error(js->gc, _("Unable to create socket")); } @@ -859,7 +855,6 @@ const char *connect_server = gaim_account_get_string(account, "connect_server", ""); const char *server; - GaimProxyConnectInfo *connect_info; js = gc->proto_data = g_new0(JabberStream, 1); js->gc = gc; @@ -909,11 +904,11 @@ } if(!js->gsc) { - connect_info = gaim_proxy_connect(account, server, + js->connect_info = gaim_proxy_connect(account, server, gaim_account_get_int(account, "port", 5222), - jabber_login_callback, NULL, gc); + jabber_login_callback, gc); - if (connect_info == NULL) + if (js->connect_info == NULL) gaim_connection_error(gc, _("Unable to create socket")); } } @@ -929,6 +924,9 @@ if (!gc->disconnect_timeout) jabber_send_raw(js, "</stream:stream>", -1); + if (js->connect_info) + gaim_proxy_connect_cancel(js->connect_info); + if(js->gsc) { #ifdef HAVE_OPENSSL if (!gc->disconnect_timeout) Modified: branches/v2_0_0/src/protocols/jabber/jabber.h =================================================================== --- branches/v2_0_0/src/protocols/jabber/jabber.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/jabber/jabber.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -67,6 +67,8 @@ { int fd; + GaimProxyConnectInfo *connect_info; + #ifdef HAVE_LIBXML xmlParserCtxt *context; #else Modified: branches/v2_0_0/src/protocols/jabber/si.c =================================================================== --- branches/v2_0_0/src/protocols/jabber/si.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/jabber/si.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -46,6 +46,8 @@ typedef struct _JabberSIXfer { JabberStream *js; + GaimProxyConnectInfo *connect_info; + gboolean accepted; char *stream_id; @@ -88,7 +90,8 @@ static void jabber_si_bytestreams_attempt_connect(GaimXfer *xfer); -static void jabber_si_bytestreams_connect_cb(gpointer data, gint source) +static void +jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message) { GaimXfer *xfer = data; JabberSIXfer *jsx = xfer->data; @@ -97,6 +100,7 @@ struct bytestreams_streamhost *streamhost = jsx->streamhosts->data; gaim_proxy_info_destroy(jsx->gpi); + jsx->connect_info = NULL; if(source < 0) { jsx->streamhosts = g_list_remove(jsx->streamhosts, streamhost); @@ -167,8 +171,18 @@ for(i=0; i<20; i++, p+=2) snprintf(p, 3, "%02x", hashval[i]); - gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, NULL, xfer); + jsx->connect_info = gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, + jabber_si_bytestreams_connect_cb, xfer); g_free(dstaddr); + + if (jsx->connect_info == NULL) + { + jsx->streamhosts = g_list_remove(jsx->streamhosts, streamhost); + g_free(streamhost->jid); + g_free(streamhost->host); + g_free(streamhost); + jabber_si_bytestreams_attempt_connect(xfer); + } } void jabber_bytestreams_parse(JabberStream *js, xmlnode *packet) @@ -682,6 +696,9 @@ js->file_transfers = g_list_remove(js->file_transfers, xfer); + if (jsx->connect_info != NULL) + gaim_proxy_connect_cancel(jsx->connect_info); + g_free(jsx->stream_id); g_free(jsx->iq_id); /* XXX: free other stuff */ Modified: branches/v2_0_0/src/protocols/msn/directconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/directconn.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/msn/directconn.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -288,11 +288,6 @@ /* ERROR */ gaim_debug_error("msn", "error reading\n"); - if (directconn->inpa) - gaim_input_remove(directconn->inpa); - - close(directconn->fd); - msn_directconn_destroy(directconn); return; @@ -307,11 +302,6 @@ /* ERROR */ gaim_debug_error("msn", "error reading\n"); - if (directconn->inpa) - gaim_input_remove(directconn->inpa); - - close(directconn->fd); - msn_directconn_destroy(directconn); return; @@ -358,17 +348,12 @@ /* ERROR */ gaim_debug_error("msn", "error reading\n"); - if (directconn->inpa) - gaim_input_remove(directconn->inpa); - - close(directconn->fd); - msn_directconn_destroy(directconn); } } static void -connect_cb(gpointer data, gint source) +connect_cb(gpointer data, gint source, const gchar *error_message) { MsnDirectConn* directconn; int fd; @@ -376,6 +361,7 @@ gaim_debug_misc("msn", "directconn: connect_cb: %d\n", source); directconn = data; + directconn->connect_info = NULL; if (TRUE) { @@ -423,7 +409,6 @@ msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port) { MsnSession *session; - GaimProxyConnectInfo *connect_info; g_return_val_if_fail(directconn != NULL, FALSE); g_return_val_if_fail(host != NULL, TRUE); @@ -438,10 +423,10 @@ } #endif - connect_info = gaim_proxy_connect(session->account, host, port, - connect_cb, NULL, directconn); + directconn->connect_info = gaim_proxy_connect(session->account, host, port, + connect_cb, directconn); - if (connect_info != NULL) + if (directconn->connect_info != NULL) { return TRUE; } @@ -491,6 +476,15 @@ void msn_directconn_destroy(MsnDirectConn *directconn) { + if (directconn->connect_info != NULL) + gaim_proxy_connect_cancel(directconn->connect_info); + + if (directconn->inpa != 0) + gaim_input_remove(directconn->inpa); + + if (directconn->fd >= 0) + close(directconn->fd); + if (directconn->nonce != NULL) g_free(directconn->nonce); Modified: branches/v2_0_0/src/protocols/msn/directconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/directconn.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/msn/directconn.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -35,6 +35,8 @@ MsnSlpLink *slplink; MsnSlpCall *initial_call; + GaimProxyConnectInfo *connect_info; + gboolean acked; char *nonce; Modified: branches/v2_0_0/src/protocols/msn/httpconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/msn/httpconn.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -693,21 +693,12 @@ } static void -connect_cb(gpointer data, gint source) +connect_cb(gpointer data, gint source, const gchar *error_message) { - MsnHttpConn *httpconn = data; + MsnHttpConn *httpconn; - /* - TODO: Need to do this in case the account is disabled while connecting - if (!g_list_find(gaim_connections_get_all(), gc)) - { - if (source >= 0) - close(source); - destroy_new_conn_data(new_conn_data); - return; - } - */ - + httpconn = data; + httpconn->connect_info = NULL; httpconn->fd = source; if (source >= 0) @@ -729,8 +720,6 @@ gboolean msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) { - GaimProxyConnectInfo *connect_info; - g_return_val_if_fail(httpconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); g_return_val_if_fail(port > 0, FALSE); @@ -738,10 +727,10 @@ if (httpconn->connected) msn_httpconn_disconnect(httpconn); - connect_info = gaim_proxy_connect(httpconn->session->account, - "gateway.messenger.hotmail.com", 80, connect_cb, NULL, httpconn); + httpconn->connect_info = gaim_proxy_connect(httpconn->session->account, + "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); - if (connect_info != NULL) + if (httpconn->connect_info != NULL) { httpconn->waiting_response = TRUE; httpconn->connected = TRUE; @@ -758,11 +747,18 @@ if (!httpconn->connected) return; + if (httpconn->connect_info != NULL) + { + gaim_proxy_connect_cancel(httpconn->connect_info); + httpconn->connect_info = NULL; + } + if (httpconn->timer) + { gaim_timeout_remove(httpconn->timer); + httpconn->timer = 0; + } - httpconn->timer = 0; - if (httpconn->inpa > 0) { gaim_input_remove(httpconn->inpa); @@ -770,6 +766,7 @@ } close(httpconn->fd); + httpconn->fd = -1; g_free(httpconn->rx_buf); httpconn->rx_buf = NULL; Modified: branches/v2_0_0/src/protocols/msn/httpconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/httpconn.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/msn/httpconn.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -37,6 +37,8 @@ MsnSession *session; /**< The MSN Session. */ MsnServConn *servconn; /**< The connection object. */ + GaimProxyConnectInfo *connect_info; + char *full_session_id; /**< The full session id. */ char *session_id; /**< The trimmed session id. */ Modified: branches/v2_0_0/src/protocols/msn/servconn.c =================================================================== --- branches/v2_0_0/src/protocols/msn/servconn.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/msn/servconn.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -166,10 +166,12 @@ **************************************************************************/ static void -connect_cb(gpointer data, gint source) +connect_cb(gpointer data, gint source, const gchar *error_message) { - MsnServConn *servconn = data; + MsnServConn *servconn; + servconn = data; + servconn->connect_info = NULL; servconn->processing = FALSE; if (servconn->wasted) @@ -199,7 +201,6 @@ msn_servconn_connect(MsnServConn *servconn, const char *host, int port) { MsnSession *session; - GaimProxyConnectInfo *connect_info; g_return_val_if_fail(servconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); @@ -232,10 +233,10 @@ return TRUE; } - connect_info = gaim_proxy_connect(session->account, host, port, - connect_cb, NULL, servconn); + servconn->connect_info = gaim_proxy_connect(session->account, host, port, + connect_cb, servconn); - if (connect_info != NULL) + if (servconn->connect_info != NULL) { servconn->processing = TRUE; return TRUE; @@ -267,6 +268,12 @@ return; } + if (servconn->connect_info != NULL) + { + gaim_proxy_connect_cancel(servconn->connect_info); + servconn->connect_info = NULL; + } + if (servconn->inpa > 0) { gaim_input_remove(servconn->inpa); Modified: branches/v2_0_0/src/protocols/msn/servconn.h =================================================================== --- branches/v2_0_0/src/protocols/msn/servconn.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/msn/servconn.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -63,6 +63,8 @@ MsnSession *session; /**< The MSN session of this connection. */ MsnCmdProc *cmdproc; /**< The command processor of this connection. */ + GaimProxyConnectInfo *connect_info; + gboolean connected; /**< A flag that states if it's connected. */ gboolean processing; /**< A flag that states if something is working with this connection. */ Modified: branches/v2_0_0/src/protocols/oscar/flap_connection.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/flap_connection.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/oscar/flap_connection.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -21,6 +21,7 @@ #include "oscar.h" #include "eventloop.h" +#include "proxy.h" #ifndef _WIN32 #include <netdb.h> @@ -131,21 +132,37 @@ /** * Close (but not free) a connection. * - * This leaves everything untouched except for setting the fd - * to -1 (used to recognize dead connections). + * This cancels any currently pending connection attempt, + * closes any open fd and frees the auth cookie. * * @param conn The connection to close. */ void flap_connection_close(OscarData *od, FlapConnection *conn) { - if (conn->fd == -1) - return; + if (conn->connect_info != NULL) + { + gaim_proxy_connect_cancel(conn->connect_info); + conn->connect_info = NULL; + } - if (conn->type == SNAC_FAMILY_LOCATE) - flap_connection_send_close(od, conn); + if (conn->connect_data != NULL) + { + if (conn->type == SNAC_FAMILY_CHAT) + { + oscar_chat_destroy(conn->connect_data); + conn->connect_data = NULL; + } + } - close(conn->fd); + if (conn->fd != -1) + { + if (conn->type == SNAC_FAMILY_LOCATE) + flap_connection_send_close(od, conn); + + close(conn->fd); + conn->fd = -1; + } } static void @@ -188,6 +205,8 @@ flap_connection_close(od, conn); + g_free(conn->cookie); + if (conn->watcher_incoming != 0) gaim_input_remove(conn->watcher_incoming); if (conn->watcher_outgoing != 0) Modified: branches/v2_0_0/src/protocols/oscar/oscar.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/oscar/oscar.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -76,35 +76,11 @@ static guint8 features_icq_offline[] = {0x01}; static guint8 ck[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -typedef struct _NewFlapConnectionData NewFlapConnectionData; -struct _NewFlapConnectionData -{ - GaimConnection *gc; - FlapConnection *conn; - guint16 cookielen; - guint8 *cookie; - gpointer data; -}; - struct create_room { char *name; int exchange; }; -struct chat_connection -{ - char *name; - char *show; /* AOL did something funny to us */ - guint16 exchange; - guint16 instance; - FlapConnection *conn; - int id; - GaimConnection *gc; /* i hate this. */ - GaimConversation *conv; /* bah. */ - int maxlen; - int maxvis; -}; - struct oscar_ask_directim_data { OscarData *od; @@ -903,7 +879,7 @@ return NULL; } -static void +void oscar_chat_destroy(struct chat_connection *cc) { g_free(cc->name); @@ -925,46 +901,25 @@ oscar_chat_destroy(cc); } -static void -destroy_new_conn_data(NewFlapConnectionData *new_conn_data) -{ - if ((new_conn_data->data != NULL) && - (new_conn_data->conn->type == SNAC_FAMILY_CHAT)) - { - oscar_chat_destroy(new_conn_data->data); - } - g_free(new_conn_data->cookie); - g_free(new_conn_data); -} - /** * This is the callback function anytime gaim_proxy_connect() * establishes a new TCP connection with an oscar host. Depending * on the type of host, we do a few different things here. */ static void -connection_established_cb(gpointer data, gint source) +connection_established_cb(gpointer data, gint source, const gchar *error_message) { - NewFlapConnectionData *new_conn_data; GaimConnection *gc; OscarData *od; GaimAccount *account; FlapConnection *conn; - new_conn_data = data; - gc = new_conn_data->gc; - - if (!GAIM_CONNECTION_IS_VALID(gc)) - { - if (source >= 0) - close(source); - destroy_new_conn_data(new_conn_data); - return; - } - - od = gc->proto_data; + conn = data; + od = conn->od; + gc = od->gc; account = gaim_connection_get_account(gc); - conn = new_conn_data->conn; + + conn->connect_info = NULL; conn->fd = source; if (source < 0) @@ -978,7 +933,6 @@ else /* Maybe we should call this for BOS connections, too? */ flap_connection_schedule_destroy(conn, OSCAR_DISCONNECT_COULD_NOT_CONNECT); - destroy_new_conn_data(new_conn_data); return; } @@ -986,7 +940,7 @@ conn->type); conn->watcher_incoming = gaim_input_add(conn->fd, GAIM_INPUT_READ, flap_connection_recv_cb, conn); - if (new_conn_data->cookie == NULL) + if (conn->cookie == NULL) { if (!aim_sn_is_icq(gaim_account_get_username(account))) /* @@ -997,8 +951,12 @@ flap_connection_send_version(od, conn); } else + { flap_connection_send_version_with_cookie(od, conn, - new_conn_data->cookielen, new_conn_data->cookie); + conn->cookielen, conn->cookie); + g_free(conn->cookie); + conn->cookie = NULL; + } if (conn->type == SNAC_FAMILY_AUTH) { @@ -1014,11 +972,9 @@ } else if (conn->type == SNAC_FAMILY_CHAT) { - od->oscar_chats = g_slist_append(od->oscar_chats, new_conn_data->data); - new_conn_data->data = NULL; + od->oscar_chats = g_slist_append(od->oscar_chats, conn->connect_data); + conn->connect_data = NULL; } - - destroy_new_conn_data(new_conn_data); } static void @@ -1152,7 +1108,7 @@ { GaimConnection *gc; OscarData *od; - NewFlapConnectionData *new_conn_data; + FlapConnection *newconn; gc = gaim_account_get_connection(account); od = gc->proto_data = oscar_data_new(); @@ -1240,17 +1196,12 @@ /* Connect to core Gaim signals */ gaim_prefs_connect_callback(gc, "/plugins/prpl/oscar/recent_buddies", recent_buddies_cb, gc); - new_conn_data = g_new(NewFlapConnectionData, 1); - new_conn_data->gc = gc; - new_conn_data->conn = flap_connection_new(od, SNAC_FAMILY_AUTH); - new_conn_data->cookielen = 0; - new_conn_data->cookie = NULL; - new_conn_data->data = NULL; - - if (gaim_proxy_connect(account, + newconn = flap_connection_new(od, SNAC_FAMILY_AUTH); + newconn->connect_info = gaim_proxy_connect(account, gaim_account_get_string(account, "server", OSCAR_DEFAULT_LOGIN_SERVER), gaim_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT), - connection_established_cb, NULL, new_conn_data) == NULL) + connection_established_cb, newconn); + if (newconn->connect_info == NULL) { gaim_connection_error(gc, _("Couldn't connect to host")); return; @@ -1295,8 +1246,7 @@ GaimAccount *account = gc->account; char *host; int port; int i; - GaimProxyConnectInfo *connect_info; - NewFlapConnectionData *new_conn_data; + FlapConnection *newconn; va_list ap; struct aim_authresp_info *info; @@ -1361,16 +1311,14 @@ } } host = g_strndup(info->bosip, i); - new_conn_data = g_new(NewFlapConnectionData, 1); - new_conn_data->gc = gc; - new_conn_data->conn = flap_connection_new(od, SNAC_FAMILY_LOCATE); - new_conn_data->cookielen = info->cookielen; - new_conn_data->cookie = g_memdup(info->cookie, info->cookielen); - new_conn_data->data = NULL; - connect_info = gaim_proxy_connect(gc->account, host, port, - connection_established_cb, NULL, new_conn_data); + newconn = flap_connection_new(od, SNAC_FAMILY_LOCATE); + newconn->cookielen = info->cookielen; + newconn->cookie = g_memdup(info->cookie, info->cookielen); + newconn->connect_info = gaim_proxy_connect(account, host, port, + connection_established_cb, newconn); g_free(host); - if (connect_info == NULL) { + if (newconn->connect_info == NULL) + { gaim_connection_error(gc, _("Could Not Connect")); od->killme = TRUE; return 0; @@ -1482,11 +1430,18 @@ } static void -straight_to_hell(gpointer data, gint source) +straight_to_hell(gpointer data, gint source, const gchar *error_message) { struct pieceofcrap *pos = data; gchar *buf; + if (!GAIM_CONNECTION_IS_VALID(pos->gc)) + { + g_free(pos->modname); + g_free(pos); + return; + } + pos->fd = source; if (source < 0) { @@ -1496,8 +1451,7 @@ _("Gaim was unable to get a valid AIM login hash."), buf); g_free(buf); - if (pos->modname) - g_free(pos->modname); + g_free(pos->modname); g_free(pos); return; } @@ -1506,8 +1460,7 @@ pos->offset, pos->len, pos->modname ? pos->modname : ""); write(pos->fd, buf, strlen(buf)); g_free(buf); - if (pos->modname) - g_free(pos->modname); + g_free(pos->modname); pos->inpa = gaim_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos); return; } @@ -1573,8 +1526,9 @@ pos->len = len; pos->modname = g_strdup(modname); + /* TODO: Keep track of this return value. */ if (gaim_proxy_connect(pos->gc->account, "gaim.sourceforge.net", 80, - straight_to_hell, NULL, pos) == NULL) + straight_to_hell, pos) == NULL) { char buf[256]; if (pos->modname) @@ -1622,7 +1576,7 @@ GaimAccount *account = gaim_connection_get_account(gc); char *host, *separator; int port; - NewFlapConnectionData *new_conn_data; + FlapConnection *newconn; va_list ap; struct aim_redirect_data *redir; @@ -1642,36 +1596,30 @@ gaim_debug_info("oscar", "Connecting to FLAP server %s:%d of type 0x%04hx\n", host, port, redir->group); - new_conn_data = g_new(NewFlapConnectionData, 1); - new_conn_data->gc = gc; - new_conn_data->conn = flap_connection_new(od, redir->group); - new_conn_data->cookielen = redir->cookielen; - new_conn_data->cookie = g_memdup(redir->cookie, redir->cookielen); - if (new_conn_data->conn->type == SNAC_FAMILY_CHAT) + newconn = flap_connection_new(od, redir->group); + newconn->cookielen = redir->cookielen; + newconn->cookie = g_memdup(redir->cookie, redir->cookielen); + if (newconn->type == SNAC_FAMILY_CHAT) { struct chat_connection *cc; cc = g_new0(struct chat_connection, 1); - cc->conn = new_conn_data->conn; + cc->conn = newconn; cc->gc = gc; cc->name = g_strdup(redir->chat.room); cc->exchange = redir->chat.exchange; cc->instance = redir->chat.instance; cc->show = extract_name(redir->chat.room); - new_conn_data->data = cc; + newconn->connect_data = cc; gaim_debug_info("oscar", "Connecting to chat room %s exchange %hu\n", cc->name, cc->exchange); } - else - { - new_conn_data->data = NULL; - } - if (gaim_proxy_connect(account, host, port, connection_established_cb, NULL, new_conn_data) == NULL) + newconn->connect_info = gaim_proxy_connect(account, host, port, + connection_established_cb, newconn); + if (newconn->connect_info == NULL) { - flap_connection_schedule_destroy(new_conn_data->conn, - OSCAR_DISCONNECT_COULD_NOT_CONNECT); + flap_connection_schedule_destroy(newconn, OSCAR_DISCONNECT_COULD_NOT_CONNECT); gaim_debug_error("oscar", "Unable to connect to FLAP server " "of type 0x%04hx\n", redir->group); - destroy_new_conn_data(new_conn_data); } g_free(host); Modified: branches/v2_0_0/src/protocols/oscar/oscar.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/oscar.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/oscar/oscar.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -33,6 +33,7 @@ #include "debug.h" #include "eventloop.h" #include "internal.h" +#include "proxy.h" #include <stdio.h> #include <string.h> @@ -366,6 +367,12 @@ guint destroy_timeout; OscarDisconnectReason disconnect_reason; + /* A few variables that are only used when connecting */ + GaimProxyConnectInfo *connect_info; + guint16 cookielen; + guint8 *cookie; + gpointer connect_data; + int fd; FlapFrame buffer_incoming; GaimCircBuffer *buffer_outgoing; @@ -661,6 +668,9 @@ guint32 minmsginterval; /* in milliseconds? */ }; +/* + * TODO: Should probably combine this with struct chat_connection. + */ struct aim_chat_roominfo { guint16 exchange; @@ -668,6 +678,25 @@ guint16 instance; }; +struct chat_connection +{ + char *name; + char *show; /* AOL did something funny to us */ + guint16 exchange; + guint16 instance; + FlapConnection *conn; + int id; + GaimConnection *gc; + GaimConversation *conv; + int maxlen; + int maxvis; +}; + +/* + * All this chat struct stuff should be in family_chat.c + */ +void oscar_chat_destroy(struct chat_connection *cc); + #define AIM_IMFLAGS_AWAY 0x0001 /* mark as an autoreply */ #define AIM_IMFLAGS_ACK 0x0002 /* request a receipt notice */ #define AIM_IMFLAGS_BUDDYREQ 0x0010 /* buddy icon requested */ Modified: branches/v2_0_0/src/protocols/oscar/peer.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/oscar/peer.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -482,7 +482,7 @@ * either connected or failed to connect. */ static void -peer_connection_established_cb(gpointer data, gint source) +peer_connection_established_cb(gpointer data, gint source, const gchar *error_message) { PeerConnection *conn; @@ -658,9 +658,7 @@ gaim_debug_info("oscar", "Peer connection timed out after 15 seconds. " "Trying next method...\n"); - gaim_proxy_connect_cancel(conn->connect_info); - conn->connect_info = NULL; - conn->connect_timeout_timer = 0; + peer_connection_close(conn); peer_connection_trynext(conn); @@ -706,7 +704,7 @@ conn->connect_info = gaim_proxy_connect(account, conn->verifiedip, conn->port, - peer_connection_established_cb, NULL, conn); + peer_connection_established_cb, conn); if (conn->connect_info != NULL) { /* Connecting... */ @@ -741,7 +739,7 @@ conn->connect_info = gaim_proxy_connect(account, conn->clientip, conn->port, - peer_connection_established_cb, NULL, conn); + peer_connection_established_cb, conn); if (conn->connect_info != NULL) { /* Connecting... */ @@ -813,7 +811,7 @@ conn->connect_info = gaim_proxy_connect(account, (conn->proxyip != NULL) ? conn->proxyip : PEER_PROXY_SERVER, PEER_PROXY_PORT, - peer_proxy_connection_established_cb, NULL, conn); + peer_proxy_connection_established_cb, conn); if (conn->connect_info != NULL) { /* Connecting... */ Modified: branches/v2_0_0/src/protocols/oscar/peer.h =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/oscar/peer.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -265,7 +265,7 @@ /* * For peer proxying */ -void peer_proxy_connection_established_cb(gpointer data, gint source); +void peer_proxy_connection_established_cb(gpointer data, gint source, const gchar *error_message); #if 0 int peer_oft_sendheader(OscarData *od, guint16 type, PeerConnection *peer_connection); Modified: branches/v2_0_0/src/protocols/oscar/peer_proxy.c =================================================================== --- branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/oscar/peer_proxy.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -326,7 +326,7 @@ * either connected or failed to connect. */ void -peer_proxy_connection_established_cb(gpointer data, gint source) +peer_proxy_connection_established_cb(gpointer data, gint source, const gchar *error_message) { PeerConnection *conn; Modified: branches/v2_0_0/src/protocols/sametime/sametime.c =================================================================== --- branches/v2_0_0/src/protocols/sametime/sametime.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/sametime/sametime.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -4,17 +4,17 @@ Adds Lotus Sametime support to Gaim using the Meanwhile library Copyright (C) 2004 Christopher (siege) O'Brien <si...@pr...> - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, @@ -226,6 +226,7 @@ /** socket fd */ int socket; gint outpa; /* like inpa, but the other way */ + GaimProxyConnectInfo *connect_info; /** circular buffer for outgoing data */ GaimCircBuffer *sock_buf; @@ -310,7 +311,7 @@ /* connection functions */ -static void connect_cb(gpointer data, gint source); +static void connect_cb(gpointer data, gint source, const gchar *error_message); /* ----- session ------ */ @@ -1409,7 +1410,7 @@ port = gaim_account_get_int(account, MW_KEY_PORT, MW_PLUGIN_DEFAULT_PORT); if(gaim_account_get_bool(account, MW_KEY_FORCE, FALSE) || - (gaim_proxy_connect(account, host, port, connect_cb, NULL, pd) == NULL)) { + (gaim_proxy_connect(account, host, port, connect_cb, pd) == NULL)) { mwSession_forceLogin(session); } @@ -1669,15 +1670,12 @@ /** Callback passed to gaim_proxy_connect when an account is logged in, and if the session logging in receives a redirect message */ -static void connect_cb(gpointer data, gint source) { +static void connect_cb(gpointer data, gint source, const gchar *error_message) { struct mwGaimPluginData *pd = data; GaimConnection *gc = pd->gc; - if(! g_list_find(gaim_connections_get_all(), pd->gc)) { - close(source); - g_return_if_reached(); - } + pd->connect_info = NULL; if(source < 0) { /* connection failed */ @@ -3683,7 +3681,8 @@ gaim_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS); - if(gaim_proxy_connect(account, host, port, connect_cb, NULL, pd) == NULL) { + pd->connect_info = gaim_proxy_connect(account, host, port, connect_cb, pd); + if(pd->connect_info == NULL) { gaim_connection_error(gc, _("Unable to connect to host")); } } @@ -3716,6 +3715,11 @@ gc->inpa = 0; } + if(pd->connect_info != NULL) { + gaim_proxy_connect_cancel(pd->connect_info); + pd->connect_info = NULL; + } + /* clean up the rest */ mwGaimPluginData_free(pd); } Modified: branches/v2_0_0/src/protocols/silc/silc.c =================================================================== --- branches/v2_0_0/src/protocols/silc/silc.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/silc/silc.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -141,7 +141,7 @@ } static void -silcgaim_login_connected(gpointer data, gint source) +silcgaim_login_connected(gpointer data, gint source, const gchar *error_message) { GaimConnection *gc = data; SilcGaim sg; @@ -153,20 +153,14 @@ g_return_if_fail(gc != NULL); - if (!GAIM_CONNECTION_IS_VALID(gc)) { - close(source); - return; - } + sg = gc->proto_data; + sg->connect_info = NULL; if (source < 0) { gaim_connection_error(gc, _("Connection failed")); return; } - sg = gc->proto_data; - if (sg == NULL) - return; - client = sg->client; account = sg->account; @@ -363,11 +357,12 @@ gc->proto_data = sg; /* Connect to the SILC server */ - if (gaim_proxy_connect(account, + sg->connect_info = gaim_proxy_connect(account, gaim_account_get_string(account, "server", "silc.silcnet.org"), gaim_account_get_int(account, "port", 706), - silcgaim_login_connected, NULL, gc) == NULL) + silcgaim_login_connected, gc); + if (sg->connect_info == NULL) { gaim_connection_error(gc, _("Unable to create connection")); return; @@ -387,6 +382,8 @@ SilcGaim sg = (SilcGaim)context; silc_client_stop(sg->client); silc_client_free(sg->client); + if (sg->connect_info != NULL) + gaim_proxy_connect_cancel(sg->connect_info); #ifdef HAVE_SILCMIME_H if (sg->mimeass) silc_mime_assembler_free(sg->mimeass); Modified: branches/v2_0_0/src/protocols/silc/silcgaim.h =================================================================== --- branches/v2_0_0/src/protocols/silc/silcgaim.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/silc/silcgaim.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -67,6 +67,7 @@ SilcClient client; SilcClientConnection conn; + GaimProxyConnectInfo *connect_info; guint scheduler; GaimConnection *gc; GaimAccount *account; Modified: branches/v2_0_0/src/protocols/simple/simple.c =================================================================== --- branches/v2_0_0/src/protocols/simple/simple.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/simple/simple.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -421,16 +421,24 @@ static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); -static void send_later_cb(gpointer data, gint source) { +static void send_later_cb(gpointer data, gint source, const gchar *error) { GaimConnection *gc = data; - struct simple_account_data *sip = gc->proto_data; + struct simple_account_data *sip; struct sip_connection *conn; + if (!GAIM_CONNECTION_IS_VALID(gc)) + { + if (source >= 0) + close(source); + return; + } + if(source < 0) { gaim_connection_error(gc, _("Could not connect")); return; } + sip = gc->proto_data; sip->fd = source; sip->connecting = FALSE; @@ -452,7 +460,7 @@ if(!sip->connecting) { gaim_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport); - connect_info = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, NULL, gc); + connect_info = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, gc); if(connect_info == NULL) { gaim_connection_error(gc, _("Couldn't create socket")); } @@ -1453,16 +1461,24 @@ conn->inputhandler = gaim_input_add(newfd, GAIM_INPUT_READ, simple_input_cb, gc); } -static void login_cb(gpointer data, gint source) { +static void login_cb(gpointer data, gint source, const gchar *error_message) { GaimConnection *gc = data; - struct simple_account_data *sip = gc->proto_data; + struct simple_account_data *sip; struct sip_connection *conn; + if (!GAIM_CONNECTION_IS_VALID(gc)) + { + if (source >= 0) + close(source); + return; + } + if(source < 0) { gaim_connection_error(gc, _("Could not connect")); return; } + sip = gc->proto_data; sip->fd = source; conn = connection_create(sip, source); @@ -1553,7 +1569,7 @@ sip->realhostname, sip->realport); /* open tcp connection to the server */ connect_info = gaim_proxy_connect(sip->account, sip->realhostname, - sip->realport, login_cb, NULL, sip->gc); + sip->realport, login_cb, sip->gc); if(connect_info == NULL) { gaim_connection_error(sip->gc, _("Couldn't create socket")); } Modified: branches/v2_0_0/src/protocols/toc/toc.c =================================================================== --- branches/v2_0_0/src/protocols/toc/toc.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/toc/toc.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -160,8 +160,9 @@ struct sockaddr_in name; socklen_t namelen; - if (!g_list_find(gaim_connections_get_all(), data)) { - close(source); + if (!GAIM_CONNECTION_IS_VALID(gc)) { + if (source >= 0) + close(source); return; } Modified: branches/v2_0_0/src/protocols/yahoo/yahoo.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/yahoo/yahoo.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -2239,7 +2239,7 @@ } } -static void yahoo_got_connected(gpointer data, gint source) +static void yahoo_got_connected(gpointer data, gint source, const gchar *error_message) { GaimConnection *gc = data; struct yahoo_data *yd; @@ -2266,7 +2266,7 @@ gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); } -static void yahoo_got_web_connected(gpointer data, gint source) +static void yahoo_got_web_connected(gpointer data, gint source, const gchar *error_message) { GaimConnection *gc = data; struct yahoo_data *yd; @@ -2348,7 +2348,7 @@ /* Now we have our cookies to login with. I'll go get the milk. */ if (gaim_proxy_connect(account, "wcs2.msg.dcn.yahoo.com", gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_web_connected, NULL, gc) == NULL) { + yahoo_got_web_connected, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; } @@ -2390,7 +2390,7 @@ gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc); } -static void yahoo_got_cookies(gpointer data, gint source) +static void yahoo_got_cookies(gpointer data, gint source, const gchar *error_message) { GaimConnection *gc = data; @@ -2516,7 +2516,7 @@ "Host: login.yahoo.com\r\n\r\n"); g_hash_table_destroy(hash); yd->auth = g_string_free(url, FALSE); - if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, NULL, gc) == NULL) { + if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; } @@ -2618,7 +2618,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST), gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_connected, NULL, gc) == NULL) + yahoo_got_connected, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; @@ -2628,7 +2628,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_connected, NULL, gc) == NULL) + yahoo_got_connected, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_filexfer.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -92,7 +92,7 @@ } -static void yahoo_receivefile_connected(gpointer data, gint source) +static void yahoo_receivefile_connected(gpointer data, gint source, const gchar *error_message) { GaimXfer *xfer; struct yahoo_xfer_data *xd; @@ -162,7 +162,7 @@ gaim_xfer_start(xfer, source, NULL, 0); } -static void yahoo_sendfile_connected(gpointer data, gint source) +static void yahoo_sendfile_connected(gpointer data, gint source, const gchar *error_message) { GaimXfer *xfer; struct yahoo_xfer_data *xd; @@ -263,7 +263,7 @@ if (yd->jp) { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_sendfile_connected, NULL, xfer) == NULL) + yahoo_sendfile_connected, xfer) == NULL) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); @@ -272,7 +272,7 @@ } else { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_sendfile_connected, NULL, xfer) == NULL) + yahoo_sendfile_connected, xfer) == NULL) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); @@ -282,7 +282,7 @@ } else { /* TODO: Using xfer->fd like this is probably a bad thing... */ if (gaim_proxy_connect(account, xfer_data->host, xfer_data->port, - yahoo_receivefile_connected, NULL, xfer) == NULL) + yahoo_receivefile_connected, xfer) == NULL) xfer->fd = -1; else xfer->fd = 0; Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_picture.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -406,7 +406,7 @@ } } -static void yahoo_buddy_icon_upload_connected(gpointer data, gint source) +static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, const gchar *error_message) { struct yahoo_buddy_icon_upload_data *d = data; struct yahoo_packet *pkt; @@ -484,7 +484,7 @@ if (yd->jp) { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, NULL, d) == NULL) + yahoo_buddy_icon_upload_connected, d) == NULL) { gaim_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); yahoo_buddy_icon_upload_data_free(d); @@ -492,7 +492,7 @@ } else { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, NULL, d) == NULL) + yahoo_buddy_icon_upload_connected, d) == NULL) { gaim_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); yahoo_buddy_icon_upload_data_free(d); Modified: branches/v2_0_0/src/protocols/yahoo/yahoochat.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/yahoo/yahoochat.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -1373,7 +1373,7 @@ } -static void yahoo_roomlist_got_connected(gpointer data, gint source) +static void yahoo_roomlist_got_connected(gpointer data, gint source, const gchar *error_message) { struct yahoo_roomlist *yrl = data; GaimRoomlist *list = yrl->list; @@ -1450,7 +1450,7 @@ gaim_roomlist_set_fields(rl, fields); if (gaim_proxy_connect(gaim_connection_get_account(gc), yrl->host, 80, - yahoo_roomlist_got_connected, NULL, yrl) == NULL) + yahoo_roomlist_got_connected, yrl) == NULL) { gaim_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list.")); yahoo_roomlist_cleanup(rl, yrl); @@ -1519,7 +1519,7 @@ gaim_roomlist_room_add(list, yrl->ucat); if (gaim_proxy_connect(list->account, yrl->host, 80, - yahoo_roomlist_got_connected, NULL, yrl) == NULL) + yahoo_roomlist_got_connected, yrl) == NULL) { gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Connection problem"), _("Unable to fetch room list.")); Modified: branches/v2_0_0/src/protocols/yahoo/ycht.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/ycht.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/protocols/yahoo/ycht.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -528,7 +528,7 @@ } } -static void ycht_got_connected(gpointer data, gint source) +static void ycht_got_connected(gpointer data, gint source, const gchar *error_message) { YchtConn *ycht = data; GaimConnection *gc = ycht->gc; @@ -571,7 +571,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "ycht-server", YAHOO_YCHT_HOST), gaim_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT), - ycht_got_connected, NULL, ycht) == NULL) + ycht_got_connected, ycht) == NULL) { ycht_connection_error(ycht, _("Connection problem")); return; Modified: branches/v2_0_0/src/proxy.c =================================================================== --- branches/v2_0_0/src/proxy.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/proxy.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -40,7 +40,6 @@ struct _GaimProxyConnectInfo { GaimProxyConnectFunction connect_cb; - GaimProxyErrorFunction error_cb; gpointer data; char *host; int port; @@ -324,7 +323,7 @@ static void gaim_proxy_connect_info_connected(GaimProxyConnectInfo *connect_info) { - connect_info->connect_cb(connect_info->data, connect_info->fd); + connect_info->connect_cb(connect_info->data, connect_info->fd, NULL); /* * We've passed the file descriptor to the protocol, so it's no longer @@ -348,22 +347,7 @@ static void gaim_proxy_connect_info_error(GaimProxyConnectInfo *connect_info, const gchar *error_message) { - if (connect_info->error_cb == NULL) - { - /* - * TODO - * While we're transitioning to the new gaim_proxy_connect() - * code, not all callers supply an error_cb. If this is the - * case then they're expecting connect_cb to be called with - * an fd of -1 in the case of an error. Once all callers have - * been changed this whole if statement should be removed. - */ - connect_info->connect_cb(connect_info->data, -1); - gaim_proxy_connect_info_destroy(connect_info); - return; - } - - connect_info->error_cb(connect_info->data, error_message); + connect_info->connect_cb(connect_info->data, -1, error_message); gaim_proxy_connect_info_destroy(connect_info); } @@ -2339,8 +2323,7 @@ GaimProxyConnectInfo * gaim_proxy_connect(GaimAccount *account, const char *host, int port, - GaimProxyConnectFunction connect_cb, - GaimProxyErrorFunction error_cb, gpointer data) + GaimProxyConnectFunction connect_cb, gpointer data) { const char *connecthost = host; int connectport = port; @@ -2349,12 +2332,10 @@ g_return_val_if_fail(host != NULL, NULL); g_return_val_if_fail(port > 0, NULL); g_return_val_if_fail(connect_cb != NULL, NULL); - /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ connect_info = g_new0(GaimProxyConnectInfo, 1); connect_info->fd = -1; connect_info->connect_cb = connect_cb; - connect_info->error_cb = error_cb; connect_info->data = data; connect_info->host = g_strdup(host); connect_info->port = port; @@ -2404,20 +2385,17 @@ */ GaimProxyConnectInfo * gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, - GaimProxyConnectFunction connect_cb, - GaimProxyErrorFunction error_cb, gpointer data) + GaimProxyConnectFunction connect_cb, gpointer data) { GaimProxyConnectInfo *connect_info; g_return_val_if_fail(host != NULL, NULL); g_return_val_if_fail(port > 0, NULL); g_return_val_if_fail(connect_cb != NULL, NULL); - /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ connect_info = g_new0(GaimProxyConnectInfo, 1); connect_info->fd = -1; connect_info->connect_cb = connect_cb; - connect_info->error_cb = error_cb; connect_info->data = data; connect_info->host = g_strdup(host); connect_info->port = port; Modified: branches/v2_0_0/src/proxy.h =================================================================== --- branches/v2_0_0/src/proxy.h 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/proxy.h 2006-08-14 08:36:25 UTC (rev 16756) @@ -58,8 +58,7 @@ typedef struct _GaimProxyConnectInfo GaimProxyConnectInfo; -typedef void (*GaimProxyConnectFunction)(gpointer data, gint source); -typedef void (*GaimProxyErrorFunction)(gpointer dat, const gchar *error_message); +typedef void (*GaimProxyConnectFunction)(gpointer data, gint source, const gchar *error_message); /** * The "hosts" parameter is a linked list containing pairs of @@ -235,9 +234,9 @@ * @param host The destination host. * @param port The destination port. * @param connect_cb The function to call when the connection is - * established. - * @param error_cb The function to call if there is an error while - * establishing the connection. + * established. If the connection failed then + * fd will be -1 and error message will be set + * to something descriptive (hopefully). * @param data User-defined data. * * @return NULL if there was an error, or a reference to a data @@ -246,8 +245,7 @@ */ GaimProxyConnectInfo *gaim_proxy_connect(GaimAccount *account, const char *host, int port, - GaimProxyConnectFunction connect_cb, - GaimProxyErrorFunction error_cb, gpointer data); + GaimProxyConnectFunction connect_cb, gpointer data); /** * Makes a connection through a SOCKS5 proxy. @@ -256,9 +254,9 @@ * @param host The destination host. * @param port The destination port. * @param connect_cb The function to call when the connection is - * established. - * @param error_cb The function to call if there is an error while - * establishing the connection. + * established. If the connection failed then + * fd will be -1 and error message will be set + * to something descriptive (hopefully). * @param data User-defined data. * * @return NULL if there was an error, or a reference to a data @@ -267,8 +265,7 @@ */ GaimProxyConnectInfo *gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, - GaimProxyConnectFunction connect_cb, - GaimProxyErrorFunction error_cb, gpointer data); + GaimProxyConnectFunction connect_cb, gpointer data); /** * Cancel an in-progress connection attempt. This should be called Modified: branches/v2_0_0/src/sslconn.c =================================================================== --- branches/v2_0_0/src/sslconn.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/sslconn.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -95,7 +95,7 @@ gsc->connect_cb = func; gsc->error_cb = error_func; - connect_info = gaim_proxy_connect(account, host, port, ops->connect_cb, NULL, gsc); + connect_info = gaim_proxy_connect(account, host, port, ops->connect_cb, gsc); if (connect_info == NULL) { Modified: branches/v2_0_0/src/upnp.c =================================================================== --- branches/v2_0_0/src/upnp.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/upnp.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -780,7 +780,7 @@ } static void -looked_up_internal_ip_cb(gpointer data, gint source) +looked_up_internal_ip_cb(gpointer data, gint source, const gchar *error_message) { if (source) { strncpy(control_info.internalip, @@ -811,7 +811,7 @@ } if(gaim_proxy_connect(NULL, addressOfControl, port, - looked_up_internal_ip_cb, NULL, NULL) == NULL) + looked_up_internal_ip_cb, NULL) == NULL) { gaim_debug_error("upnp", "Get Local IP Connect Failed: Address: %s @@@ Port %d\n", addressOfControl, port); Modified: branches/v2_0_0/src/util.c =================================================================== --- branches/v2_0_0/src/util.c 2006-08-14 08:32:52 UTC (rev 16755) +++ branches/v2_0_0/src/util.c 2006-08-14 08:36:25 UTC (rev 16756) @@ -3367,7 +3367,7 @@ } static void -url_fetch_connect_cb(gpointer url_data, gint source) +url_fetch_connect_cb(gpointer url_data, gint source, const gchar *error_message) { GaimFetchUrlData *gfud; @@ -3446,7 +3446,7 @@ &gfud->website.page, &gfud->website.user, &gfud->website.passwd); if (gaim_proxy_connect(NULL, gfud->website.address, - gfud->website.port, url_fetch_connect_cb, NULL, gfud) == NULL) + gfud->website.port, url_fetch_connect_cb, gfud) == NULL) { destroy_fetch_url_data(gfud); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dat...@us...> - 2006-08-14 12:58:14
|
Revision: 16757 Author: datallah Date: 2006-08-14 05:58:04 -0700 (Mon, 14 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16757&view=rev Log Message: ----------- Merge from trunk: 16740 - Fix for CID 97 16710 - Fix CID 101. Also fix the behavior of adding a group to a fields list so that it doesn't matter if you add the group to a fields list before you add fields to the group or not. 16709 - Deal with inability to create key pair. (CID 139) 16708 - Fix CID 122 - Avoid an assert when the conversation has been closed before a custom emoticon finishes loading Modified Paths: -------------- branches/v2_0_0/plugins/log_reader.c branches/v2_0_0/src/protocols/msn/slp.c branches/v2_0_0/src/protocols/silc/util.c branches/v2_0_0/src/request.c Modified: branches/v2_0_0/plugins/log_reader.c =================================================================== --- branches/v2_0_0/plugins/log_reader.c 2006-08-14 08:36:25 UTC (rev 16756) +++ branches/v2_0_0/plugins/log_reader.c 2006-08-14 12:58:04 UTC (rev 16757) @@ -857,11 +857,10 @@ * friendly name or alias. For this test, "match" is defined as: * ^(friendly_name|alias)([^a-zA-Z0-9].*)?$ */ - from_name_matches = from_name != NULL && ( - (gaim_str_has_prefix(from_name, friendly_name) && + from_name_matches = (gaim_str_has_prefix(from_name, friendly_name) && !isalnum(*(from_name + friendly_name_length))) || (gaim_str_has_prefix(from_name, log->account->alias) && - !isalnum(*(from_name + alias_length)))); + !isalnum(*(from_name + alias_length))); to_name_matches = to_name != NULL && ( (gaim_str_has_prefix(to_name, friendly_name) && @@ -930,10 +929,11 @@ !isalnum(*(from_name + friendly_name_length))); - to_name_matches = (gaim_str_has_prefix( + to_name_matches = to_name && ( + (gaim_str_has_prefix( to_name, buddy->server_alias) && !isalnum(*(to_name + - friendly_name_length))); + friendly_name_length)))); if (from_name_matches) { if (!to_name_matches) { Modified: branches/v2_0_0/src/protocols/msn/slp.c =================================================================== --- branches/v2_0_0/src/protocols/msn/slp.c 2006-08-14 08:36:25 UTC (rev 16756) +++ branches/v2_0_0/src/protocols/msn/slp.c 2006-08-14 12:58:04 UTC (rev 16757) @@ -768,14 +768,15 @@ gc = slpcall->slplink->session->account->gc; who = slpcall->slplink->remote_user; - conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, who, gc->account); + if ((conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, who, gc->account))) { - /* FIXME: it would be better if we wrote the data as we received it - instead of all at once, calling write multiple times and - close once at the very end - */ - gaim_conv_custom_smiley_write(conv, slpcall->data_info, data, size); - gaim_conv_custom_smiley_close(conv, slpcall->data_info ); + /* FIXME: it would be better if we wrote the data as we received it + instead of all at once, calling write multiple times and + close once at the very end + */ + gaim_conv_custom_smiley_write(conv, slpcall->data_info, data, size); + gaim_conv_custom_smiley_close(conv, slpcall->data_info); + } #ifdef MSN_DEBUG_UD gaim_debug_info("msn", "Got smiley: %s\n", slpcall->data_info); #endif Modified: branches/v2_0_0/src/protocols/silc/util.c =================================================================== --- branches/v2_0_0/src/protocols/silc/util.c 2006-08-14 08:36:25 UTC (rev 16756) +++ branches/v2_0_0/src/protocols/silc/util.c 2006-08-14 12:58:04 UTC (rev 16757) @@ -205,12 +205,20 @@ /* If file doesn't exist */ if (errno == ENOENT) { gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); - silc_create_key_pair(SILCGAIM_DEF_PKCS, + if (!silc_create_key_pair(SILCGAIM_DEF_PKCS, SILCGAIM_DEF_PKCS_LEN, file_public_key, file_private_key, NULL, (gc->password == NULL) ? "" : gc->password, - NULL, NULL, NULL, FALSE); - g_stat(file_public_key, &st); + NULL, NULL, NULL, FALSE)) { + gaim_debug_error("silc", "Couldn't create key pair\n"); + return FALSE; + } + + if ((g_stat(file_public_key, &st)) == -1) { + gaim_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", + file_public_key, strerror(errno)); + return FALSE; + } } else { gaim_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", file_public_key, strerror(errno)); Modified: branches/v2_0_0/src/request.c =================================================================== --- branches/v2_0_0/src/request.c 2006-08-14 08:36:25 UTC (rev 16756) +++ branches/v2_0_0/src/request.c 2006-08-14 12:58:04 UTC (rev 16757) @@ -84,7 +84,13 @@ field = l->data; g_hash_table_insert(fields->fields, - g_strdup(gaim_request_field_get_id(field)), field); + g_strdup(gaim_request_field_get_id(field)), field); + + if (gaim_request_field_is_required(field)) { + fields->required_fields = + g_list_append(fields->required_fields, field); + } + } } @@ -280,15 +286,16 @@ { g_hash_table_insert(group->fields_list->fields, g_strdup(gaim_request_field_get_id(field)), field); + + if (gaim_request_field_is_required(field)) + { + group->fields_list->required_fields = + g_list_append(group->fields_list->required_fields, field); + } } field->group = group; - if (gaim_request_field_is_required(field)) - { - group->fields_list->required_fields = - g_list_append(group->fields_list->required_fields, field); - } } const char * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-15 08:26:25
|
Revision: 16767 Author: thekingant Date: 2006-08-15 01:26:12 -0700 (Tue, 15 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16767&view=rev Log Message: ----------- Backport my changes that will hopefully fix idle-away stuff Modified Paths: -------------- branches/v2_0_0/src/connection.h branches/v2_0_0/src/gtkstatusbox.c branches/v2_0_0/src/idle.c branches/v2_0_0/src/savedstatuses.c branches/v2_0_0/src/savedstatuses.h Modified: branches/v2_0_0/src/connection.h =================================================================== --- branches/v2_0_0/src/connection.h 2006-08-15 08:22:29 UTC (rev 16766) +++ branches/v2_0_0/src/connection.h 2006-08-15 08:26:12 UTC (rev 16767) @@ -89,8 +89,6 @@ guint keepalive; /**< Keep-alive. */ - gboolean is_auto_away; /**< Whether or not it's auto-away. */ - gboolean wants_to_die; /**< Wants to Die state. This is set when the user chooses to log out, or when the protocol is Modified: branches/v2_0_0/src/gtkstatusbox.c =================================================================== --- branches/v2_0_0/src/gtkstatusbox.c 2006-08-15 08:22:29 UTC (rev 16766) +++ branches/v2_0_0/src/gtkstatusbox.c 2006-08-15 08:26:12 UTC (rev 16767) @@ -257,6 +257,7 @@ statusbox, GAIM_CALLBACK(account_status_changed_cb)); statusbox->status_changed_signal = 0; } + gaim_signals_disconnect_by_handle(statusbox); gaim_prefs_disconnect_by_handle(statusbox); G_OBJECT_CLASS(parent_class)->finalize(obj); @@ -825,8 +826,7 @@ } static void -current_status_pref_changed_cb(const char *name, GaimPrefType type, - gconstpointer val, gpointer data) +current_savedstatus_changed_cb(GaimSavedStatus *now, GaimSavedStatus *old, gpointer data) { GtkGaimStatusBox *status_box = data; @@ -996,8 +996,10 @@ gtk_gaim_status_box_regenerate(status_box); gtk_gaim_status_box_refresh(status_box); - gaim_prefs_connect_callback(status_box, "/core/savedstatus/current", - current_status_pref_changed_cb, status_box); + gaim_signal_connect(gaim_savedstatuses_get_handle(), "savedstatus-changed", + status_box, + GAIM_CALLBACK(current_savedstatus_changed_cb), + status_box); gaim_prefs_connect_callback(status_box, "/gaim/gtk/blist/show_buddy_icons", buddy_list_details_pref_changed_cb, status_box); gaim_prefs_connect_callback(status_box, "/gaim/gtk/conversations/spellcheck", @@ -1249,9 +1251,8 @@ * "Saved..." or a popular status then do nothing. * Popular statuses are * activated elsewhere, and we update the status_box - * accordingly by monitoring the preference - * "/core/savedstatus/current" and then calling - * status_menu_refresh_iter() + * accordingly by connecting to the savedstatus-changed + * signal and then calling status_menu_refresh_iter() */ if (type != GTK_GAIM_STATUS_BOX_TYPE_PRIMITIVE) return; Modified: branches/v2_0_0/src/idle.c =================================================================== --- branches/v2_0_0/src/idle.c 2006-08-15 08:22:29 UTC (rev 16766) +++ branches/v2_0_0/src/idle.c 2006-08-15 08:26:12 UTC (rev 16767) @@ -58,63 +58,6 @@ static time_t last_active_time = 0; static void -set_account_autoaway(GaimConnection *gc) -{ - GaimAccount *account; - GaimPresence *presence; - GaimStatus *status; - - if (gc->is_auto_away) - /* This account is already auto-away! */ - return; - - account = gaim_connection_get_account(gc); - presence = gaim_account_get_presence(account); - status = gaim_presence_get_active_status(presence); - - if (gaim_status_is_available(status)) - { - GaimSavedStatus *saved_status; - - gaim_debug_info("idle", "Making %s auto-away\n", - gaim_account_get_username(account)); - - saved_status = gaim_savedstatus_get_idleaway(); - gaim_savedstatus_activate_for_account(saved_status, account); - - gc->is_auto_away = GAIM_IDLE_AUTO_AWAY; - } else { - gc->is_auto_away = GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY; - } -} - -static void -unset_account_autoaway(GaimConnection *gc) -{ - GaimAccount *account; - GaimSavedStatus *saved_status; - - account = gaim_connection_get_account(gc); - - if (!gc->is_auto_away) - /* This account is already not auto-away! */ - return; - - if (gc->is_auto_away == GAIM_IDLE_AWAY_BUT_NOT_AUTO_AWAY) { - gc->is_auto_away = GAIM_IDLE_NOT_AWAY; - } else { - gc->is_auto_away = GAIM_IDLE_NOT_AWAY; - - gaim_debug_info("idle", "%s returning from auto-away\n", - gaim_account_get_username(account)); - - /* Return our account to its previous status */ - saved_status = gaim_savedstatus_get_current(); - gaim_savedstatus_activate_for_account(saved_status, account); - } -} - -static void set_account_idle(GaimAccount *account, int time_idle) { GaimPresence *presence; @@ -203,13 +146,11 @@ if (auto_away && (time_idle > (60 * gaim_prefs_get_int("/core/away/mins_before_away")))) { - for (l = gaim_connections_get_all(); l != NULL; l = l->next) - set_account_autoaway(l->data); + gaim_savedstatus_set_idleaway(TRUE); } else if (time_idle < 60 * gaim_prefs_get_int("/core/away/mins_before_away")) { - for (l = gaim_connections_get_all(); l != NULL; l = l->next) - unset_account_autoaway(l->data); + gaim_savedstatus_set_idleaway(FALSE); } /* Idle reporting stuff */ @@ -239,12 +180,19 @@ } static void +signing_on_cb(GaimConnection *gc, void *data) +{ + /* When signing on a new account, check if the account should be idle */ + check_idleness(); +} + +static void signing_off_cb(GaimConnection *gc, void *data) { GaimAccount *account; account = gaim_connection_get_account(gc); - idled_accts = g_list_remove(idled_accts, account); + set_account_unidle(account); } void @@ -288,6 +236,9 @@ gaim_signal_connect(gaim_conversations_get_handle(), "sent-im-msg", gaim_idle_get_handle(), GAIM_CALLBACK(im_msg_sent_cb), NULL); + gaim_signal_connect(gaim_connections_get_handle(), "signing-on", + gaim_idle_get_handle(), + GAIM_CALLBACK(signing_on_cb), NULL); gaim_signal_connect(gaim_connections_get_handle(), "signing-off", gaim_idle_get_handle(), GAIM_CALLBACK(signing_off_cb), NULL); Modified: branches/v2_0_0/src/savedstatuses.c =================================================================== --- branches/v2_0_0/src/savedstatuses.c 2006-08-15 08:22:29 UTC (rev 16766) +++ branches/v2_0_0/src/savedstatuses.c 2006-08-15 08:26:12 UTC (rev 16767) @@ -25,6 +25,7 @@ #include "internal.h" #include "debug.h" +#include "idle.h" #include "notify.h" #include "savedstatuses.h" #include "dbus-maybe.h" @@ -676,9 +677,9 @@ * If we just deleted our current status or our idleaway status, * then set the appropriate pref back to 0. */ - current = gaim_prefs_get_int("/core/savedstatus/current"); + current = gaim_prefs_get_int("/core/savedstatus/default"); if (current == creation_time) - gaim_prefs_set_int("/core/savedstatus/current", 0); + gaim_prefs_set_int("/core/savedstatus/default", 0); idleaway = gaim_prefs_get_int("/core/savedstatus/idleaway"); if (idleaway == creation_time) @@ -725,12 +726,21 @@ } GaimSavedStatus * -gaim_savedstatus_get_current() +gaim_savedstatus_get_current(void) { + if (gaim_savedstatus_is_idleaway()) + return gaim_savedstatus_get_idleaway(); + else + return gaim_savedstatus_get_default(); +} + +GaimSavedStatus * +gaim_savedstatus_get_default() +{ int creation_time; GaimSavedStatus *saved_status = NULL; - creation_time = gaim_prefs_get_int("/core/savedstatus/current"); + creation_time = gaim_prefs_get_int("/core/savedstatus/default"); if (creation_time != 0) saved_status = g_hash_table_lookup(creation_times, &creation_time); @@ -744,7 +754,7 @@ * using? In any case, add a default status. */ saved_status = gaim_savedstatus_new(NULL, GAIM_STATUS_AVAILABLE); - gaim_prefs_set_int("/core/savedstatus/current", + gaim_prefs_set_int("/core/savedstatus/default", gaim_savedstatus_get_creation_time(saved_status)); } @@ -780,6 +790,51 @@ return saved_status; } +gboolean +gaim_savedstatus_is_idleaway() +{ + return gaim_prefs_get_bool("/core/savedstatus/isidleaway"); +} + +void +gaim_savedstatus_set_idleaway(gboolean idleaway) +{ + GList *accounts, *node; + GaimSavedStatus *old, *saved_status; + + if (gaim_savedstatus_is_idleaway() == idleaway) + /* Don't need to do anything */ + return; + + /* Changing our status makes us un-idle */ + if (!idleaway) + gaim_idle_touch(); + + old = gaim_savedstatus_get_current(); + gaim_prefs_set_bool("/core/savedstatus/isidleaway", idleaway); + saved_status = gaim_savedstatus_get_current(); + + accounts = gaim_accounts_get_all_active(); + for (node = accounts; node != NULL; node = node->next) + { + GaimAccount *account; + GaimPresence *presence; + GaimStatus *status; + + account = node->data; + presence = gaim_account_get_presence(account); + status = gaim_presence_get_active_status(presence); + + if (!idleaway || gaim_status_is_available(status)) + gaim_savedstatus_activate_for_account(saved_status, account); + } + + g_list_free(accounts); + + gaim_signal_emit(gaim_savedstatuses_get_handle(), "savedstatus-changed", + saved_status, old); +} + GaimSavedStatus * gaim_savedstatus_get_startup() { @@ -1001,12 +1056,12 @@ g_list_free(accounts); - gaim_prefs_set_int("/core/savedstatus/current", + gaim_prefs_set_int("/core/savedstatus/default", gaim_savedstatus_get_creation_time(saved_status)); + gaim_savedstatus_set_idleaway(FALSE); gaim_signal_emit(gaim_savedstatuses_get_handle(), "savedstatus-changed", saved_status, old); - } void @@ -1070,10 +1125,11 @@ * saved status and return that to the user. */ gaim_prefs_add_none("/core/savedstatus"); - gaim_prefs_add_int("/core/savedstatus/current", 0); + gaim_prefs_add_int("/core/savedstatus/default", 0); gaim_prefs_add_int("/core/savedstatus/startup", 0); gaim_prefs_add_bool("/core/savedstatus/startup_current_status", TRUE); gaim_prefs_add_int("/core/savedstatus/idleaway", 0); + gaim_prefs_add_bool("/core/savedstatus/isidleaway", FALSE); load_statuses(); Modified: branches/v2_0_0/src/savedstatuses.h =================================================================== --- branches/v2_0_0/src/savedstatuses.h 2006-08-15 08:22:29 UTC (rev 16766) +++ branches/v2_0_0/src/savedstatuses.h 2006-08-15 08:26:12 UTC (rev 16767) @@ -171,7 +171,9 @@ GList *gaim_savedstatuses_get_popular(unsigned int how_many); /** - * Returns the currently selected saved status. + * Returns the currently selected saved status. If we are idle + * then this returns gaim_savedstatus_get_idleaway(). Otherwise + * it returns gaim_savedstatus_get_default(). * * @return A pointer to the in-use GaimSavedStatus. * This function never returns NULL. @@ -179,7 +181,16 @@ GaimSavedStatus *gaim_savedstatus_get_current(void); /** - * Returns the saved status that gets used when your + * Returns the default saved status that is used when our + * accounts are not idle-away. + * + * @return A pointer to the in-use GaimSavedStatus. + * This function never returns NULL. + */ +GaimSavedStatus *gaim_savedstatus_get_default(void); + +/** + * Returns the saved status that is used when your * accounts become idle-away. * * @return A pointer to the idle-away GaimSavedStatus. @@ -188,6 +199,23 @@ GaimSavedStatus *gaim_savedstatus_get_idleaway(void); /** + * Return TRUE if we are currently idle-away. Otherwise + * returns FALSE. + * + * @return TRUE if our accounts have been set to idle-away. + */ +gboolean gaim_savedstatus_is_idleaway(void); + +/** + * Set whether accounts in Gaim are idle-away or not. + * + * @param TRUE if accounts should be switched to use the + * idle-away saved status. FALSE if they should + * be switched to use the default status. + */ +void gaim_savedstatus_set_idleaway(gboolean idleaway); + +/** * Returns the status to be used when gaim is starting up * * @return A pointer to the startup GaimSavedStatus. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-08-16 07:37:51
|
Revision: 16787 Author: thekingant Date: 2006-08-16 00:37:42 -0700 (Wed, 16 Aug 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16787&view=rev Log Message: ----------- Backport the following SVN revisions from HEAD to v2_0_0 16774-16779 16781-16786 This includes Sean's global icon thing and the fix for the MSN crash Modified Paths: -------------- branches/v2_0_0/src/dbus-server.c branches/v2_0_0/src/gtkaccount.c branches/v2_0_0/src/gtkblist.c branches/v2_0_0/src/gtkstatusbox.c branches/v2_0_0/src/gtkstatusbox.h branches/v2_0_0/src/gtkutils.c branches/v2_0_0/src/gtkutils.h branches/v2_0_0/src/prefs.c branches/v2_0_0/src/protocols/msn/nexus.c branches/v2_0_0/src/protocols/yahoo/yahoo_packet.c Modified: branches/v2_0_0/src/dbus-server.c =================================================================== --- branches/v2_0_0/src/dbus-server.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/dbus-server.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -48,7 +48,7 @@ /* * Here we include the list of #GAIM_DBUS_DEFINE_TYPE statements for * all structs defined in gaim. This file has been generated by the - * #dbus-analize-types.py script. + * #dbus-analyze-types.py script. */ #include "dbus-types.c" Modified: branches/v2_0_0/src/gtkaccount.c =================================================================== --- branches/v2_0_0/src/gtkaccount.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/gtkaccount.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -115,6 +115,7 @@ GtkWidget *user_frame; GtkWidget *new_mail_check; GtkWidget *icon_hbox; + GtkWidget *icon_check; GtkWidget *icon_entry; char *icon_path; GtkWidget *icon_filesel; @@ -153,8 +154,6 @@ static void add_account_to_liststore(GaimAccount *account, gpointer user_data); static void set_account(GtkListStore *store, GtkTreeIter *iter, GaimAccount *account); -static char* -convert_buddy_icon(GaimPlugin *plugin, const char *path); /************************************************************************** * Add/Modify Account dialog @@ -271,210 +270,28 @@ } } -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ static void -icon_filesel_choose_cb(GtkWidget *widget, gint response, AccountPrefsDialog *dialog) +icon_filesel_choose_cb(const char *filename, gpointer data) { - char *filename, *current_folder; + AccountPrefsDialog *dialog; - if (response != GTK_RESPONSE_ACCEPT) { - if (response == GTK_RESPONSE_CANCEL) - gtk_widget_destroy(dialog->icon_filesel); - dialog->icon_filesel = NULL; - return; - } + dialog = data; - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog->icon_filesel)); - current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog->icon_filesel)); - if (current_folder != NULL) { - gaim_prefs_set_string("/gaim/gtk/filelocations/last_icon_folder", current_folder); - g_free(current_folder); + if (filename) { + g_free(dialog->icon_path); + dialog->icon_path = gaim_gtk_convert_buddy_icon(dialog->plugin, filename); + set_dialog_icon(dialog); + gtk_widget_show(dialog->icon_entry); } -#else /* FILECHOOSER */ -static void -icon_filesel_choose_cb(GtkWidget *w, AccountPrefsDialog *dialog) -{ - char *filename, *current_folder; - - filename = g_strdup(gtk_file_selection_get_filename( - GTK_FILE_SELECTION(dialog->icon_filesel))); - - /* If they typed in a directory, change there */ - if (gaim_gtk_check_if_dir(filename, - GTK_FILE_SELECTION(dialog->icon_filesel))) - { - g_free(filename); - return; - } - - current_folder = g_path_get_dirname(filename); - if (current_folder != NULL) { - gaim_prefs_set_string("/gaim/gtk/filelocations/last_icon_folder", current_folder); - g_free(current_folder); - } - -#endif /* FILECHOOSER */ - - g_free(dialog->icon_path); - dialog->icon_path = convert_buddy_icon(dialog->plugin, filename); - set_dialog_icon(dialog); - gtk_widget_show(dialog->icon_entry); - - gtk_widget_destroy(dialog->icon_filesel); dialog->icon_filesel = NULL; - g_free(filename); - } - -static void -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ -icon_preview_change_cb(GtkFileChooser *widget, AccountPrefsDialog *dialog) -#else /* FILECHOOSER */ -icon_preview_change_cb(GtkTreeSelection *sel, AccountPrefsDialog *dialog) -#endif /* FILECHOOSER */ -{ - GdkPixbuf *pixbuf, *scale; - int height, width; - char *basename, *markup, *size; - struct stat st; - char *filename; - -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - filename = gtk_file_chooser_get_preview_filename( - GTK_FILE_CHOOSER(dialog->icon_filesel)); -#else /* FILECHOOSER */ - filename = g_strdup(gtk_file_selection_get_filename( - GTK_FILE_SELECTION(dialog->icon_filesel))); -#endif /* FILECHOOSER */ - - if (!filename || g_stat(filename, &st)) - { - g_free(filename); - return; - } - - pixbuf = gdk_pixbuf_new_from_file(filename, NULL); - if (!pixbuf) { - gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_preview), NULL); - gtk_label_set_markup(GTK_LABEL(dialog->icon_text), ""); -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - gtk_file_chooser_set_preview_widget_active( - GTK_FILE_CHOOSER(dialog->icon_filesel), FALSE); -#endif /* FILECHOOSER */ - g_free(filename); - return; - } - - width = gdk_pixbuf_get_width(pixbuf); - height = gdk_pixbuf_get_height(pixbuf); - basename = g_path_get_basename(filename); - size = gaim_str_size_to_units(st.st_size); - markup = g_strdup_printf(_("<b>File:</b> %s\n" - "<b>File size:</b> %s\n" - "<b>Image size:</b> %dx%d"), - basename, size, width, height); - - scale = gdk_pixbuf_scale_simple(pixbuf, width * 50 / height, - 50, GDK_INTERP_BILINEAR); - gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_preview), scale); -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - gtk_file_chooser_set_preview_widget_active( - GTK_FILE_CHOOSER(dialog->icon_filesel), TRUE); -#endif /* FILECHOOSER */ - gtk_label_set_markup(GTK_LABEL(dialog->icon_text), markup); - - g_object_unref(G_OBJECT(pixbuf)); - g_object_unref(G_OBJECT(scale)); - g_free(filename); - g_free(basename); - g_free(size); - g_free(markup); } -#if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ static void -icon_filesel_delete_cb(GtkWidget *w, AccountPrefsDialog *dialog) -{ - if (dialog->icon_filesel != NULL) - gtk_widget_destroy(dialog->icon_filesel); - - dialog->icon_filesel = NULL; -} -#endif /* FILECHOOSER */ - -static void icon_select_cb(GtkWidget *button, AccountPrefsDialog *dialog) { -#if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - GtkWidget *hbox; - GtkWidget *tv; - GtkTreeSelection *sel; -#endif /* FILECHOOSER */ - const char *current_folder; - - if (dialog->icon_filesel != NULL) { - gtk_window_present(GTK_WINDOW(dialog->icon_filesel)); - return; - } - - current_folder = gaim_prefs_get_string("/gaim/gtk/filelocations/last_icon_folder"); -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - dialog->icon_filesel = gtk_file_chooser_dialog_new(_("Buddy Icon"), - GTK_WINDOW(dialog->window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - gtk_dialog_set_default_response(GTK_DIALOG(dialog->icon_filesel), GTK_RESPONSE_ACCEPT); - if ((current_folder != NULL) && (*current_folder != '\0')) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog->icon_filesel), - current_folder); - - dialog->icon_preview = gtk_image_new(); - dialog->icon_text = gtk_label_new(NULL); - gtk_widget_set_size_request(GTK_WIDGET(dialog->icon_preview), -1, 50); - gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog->icon_filesel), - GTK_WIDGET(dialog->icon_preview)); - g_signal_connect(G_OBJECT(dialog->icon_filesel), "update-preview", - G_CALLBACK(icon_preview_change_cb), dialog); - g_signal_connect(G_OBJECT(dialog->icon_filesel), "response", - G_CALLBACK(icon_filesel_choose_cb), dialog); - icon_preview_change_cb(NULL, dialog); -#else /* FILECHOOSER */ - dialog->icon_filesel = gtk_file_selection_new(_("Buddy Icon")); - dialog->icon_preview = gtk_image_new(); - dialog->icon_text = gtk_label_new(NULL); - if ((current_folder != NULL) && (*current_folder != '\0')) - gtk_file_selection_set_filename(GTK_FILE_SELECTION(dialog->icon_filesel), - current_folder); - - gtk_widget_set_size_request(GTK_WIDGET(dialog->icon_preview), -1, 50); - hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); - gtk_box_pack_start( - GTK_BOX(GTK_FILE_SELECTION(dialog->icon_filesel)->main_vbox), - hbox, FALSE, FALSE, 0); - gtk_box_pack_end(GTK_BOX(hbox), dialog->icon_preview, - FALSE, FALSE, 0); - gtk_box_pack_end(GTK_BOX(hbox), dialog->icon_text, FALSE, FALSE, 0); - - tv = GTK_FILE_SELECTION(dialog->icon_filesel)->file_list; - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); - - g_signal_connect(G_OBJECT(sel), "changed", - G_CALLBACK(icon_preview_change_cb), dialog); - g_signal_connect( - G_OBJECT(GTK_FILE_SELECTION(dialog->icon_filesel)->ok_button), - "clicked", - G_CALLBACK(icon_filesel_choose_cb), dialog); - g_signal_connect( - G_OBJECT(GTK_FILE_SELECTION(dialog->icon_filesel)->cancel_button), - "clicked", - G_CALLBACK(icon_filesel_delete_cb), dialog); - g_signal_connect(G_OBJECT(dialog->icon_filesel), "destroy", - G_CALLBACK(icon_filesel_delete_cb), dialog); -#endif /* FILECHOOSER */ - - gtk_widget_show_all(GTK_WIDGET(dialog->icon_filesel)); + dialog->icon_filesel = gaim_gtk_buddy_icon_chooser_new(GTK_WINDOW(dialog->window), icon_filesel_choose_cb, dialog); + gtk_widget_show_all(dialog->icon_filesel); } static void @@ -510,7 +327,8 @@ if ((rtmp = strchr(tmp, '\r')) || (rtmp = strchr(tmp, '\n'))) *rtmp = '\0'; g_free(dialog->icon_path); - dialog->icon_path = convert_buddy_icon(dialog->plugin, tmp); + + dialog->icon_path = gaim_gtk_convert_buddy_icon(dialog->plugin, tmp); set_dialog_icon(dialog); gtk_widget_show(dialog->icon_entry); g_free(tmp); @@ -520,207 +338,6 @@ gtk_drag_finish(dc, FALSE, FALSE, t); } - -#if GTK_CHECK_VERSION(2,2,0) -static gboolean -str_array_match(char **a, char **b) -{ - int i, j; - - if (!a || !b) - return FALSE; - for (i = 0; a[i] != NULL; i++) - for (j = 0; b[j] != NULL; j++) - if (!g_ascii_strcasecmp(a[i], b[j])) - return TRUE; - return FALSE; -} -#endif - -static char* -convert_buddy_icon(GaimPlugin *plugin, const char *path) -{ -#if GTK_CHECK_VERSION(2,2,0) - int width, height; - char **pixbuf_formats = NULL; - GdkPixbufFormat *format; - GdkPixbuf *pixbuf; - GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); - char **prpl_formats = g_strsplit (prpl_info->icon_spec.format,",",0); -#if !GTK_CHECK_VERSION(2,4,0) - GdkPixbufLoader *loader; - FILE *file; - struct stat st; - void *data = NULL; -#endif -#endif - const char *dirname = gaim_buddy_icons_get_cache_dir(); - char *random = g_strdup_printf("%x", g_random_int()); - char *filename = g_build_filename(dirname, random, NULL); - - if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { - gaim_debug_info("buddyicon", "Creating icon cache directory.\n"); - - if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { - gaim_debug_error("buddyicon", - "Unable to create directory %s: %s\n", - dirname, strerror(errno)); -#if GTK_CHECK_VERSION(2,2,0) - g_strfreev(prpl_formats); -#endif - g_free(random); - g_free(filename); - return NULL; - } - } - -#if GTK_CHECK_VERSION(2,2,0) -#if GTK_CHECK_VERSION(2,4,0) - format = gdk_pixbuf_get_file_info (path, &width, &height); -#else - loader = gdk_pixbuf_loader_new(); - if (!g_stat(path, &st) && (file = g_fopen(path, "rb")) != NULL) { - data = g_malloc(st.st_size); - fread(data, 1, st.st_size, file); - fclose(file); - gdk_pixbuf_loader_write(loader, data, st.st_size, NULL); - g_free(data); - } - gdk_pixbuf_loader_close(loader, NULL); - pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); - width = gdk_pixbuf_get_width(pixbuf); - height = gdk_pixbuf_get_height(pixbuf); - format = gdk_pixbuf_loader_get_format(loader); - g_object_unref(G_OBJECT(loader)); -#endif - pixbuf_formats = gdk_pixbuf_format_get_extensions(format); - - if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ - (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ - (prpl_info->icon_spec.min_width <= width && - prpl_info->icon_spec.max_width >= width && - prpl_info->icon_spec.min_height <= height && - prpl_info->icon_spec.max_height >= height))) /* The icon is the correct size */ -#endif - { - gchar *contents; - gsize length; - FILE *image; - -#if GTK_CHECK_VERSION(2,2,0) - g_strfreev(prpl_formats); - g_strfreev(pixbuf_formats); -#endif - - /* Copy the image to the cache folder as "filename". */ - - if (!g_file_get_contents(path, &contents, &length, NULL) || - (image = g_fopen(filename, "wb")) == NULL) - { - g_free(random); - g_free(filename); -#if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) - g_object_unref(G_OBJECT(pixbuf)); -#endif - return NULL; - } - - if (fwrite(contents, 1, length, image) != length) - { - fclose(image); - g_unlink(filename); - - g_free(random); - g_free(filename); -#if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) - g_object_unref(G_OBJECT(pixbuf)); -#endif - return NULL; - } - fclose(image); - -#if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) - g_object_unref(G_OBJECT(pixbuf)); -#endif - - g_free(filename); - return random; - } -#if GTK_CHECK_VERSION(2,2,0) - else - { - int i; - GError *error = NULL; - GdkPixbuf *scale; - pixbuf = gdk_pixbuf_new_from_file(path, &error); - g_strfreev(pixbuf_formats); - if (!error && (prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) && - (width < prpl_info->icon_spec.min_width || - width > prpl_info->icon_spec.max_width || - height < prpl_info->icon_spec.min_height || - height > prpl_info->icon_spec.max_height)) - { - int new_width = width; - int new_height = height; - - if(new_width > prpl_info->icon_spec.max_width) - new_width = prpl_info->icon_spec.max_width; - else if(new_width < prpl_info->icon_spec.min_width) - new_width = prpl_info->icon_spec.min_width; - if(new_height > prpl_info->icon_spec.max_height) - new_height = prpl_info->icon_spec.max_height; - else if(new_height < prpl_info->icon_spec.min_height) - new_height = prpl_info->icon_spec.min_height; - - /* preserve aspect ratio */ - if ((double)height * (double)new_width > - (double)width * (double)new_height) { - new_width = 0.5 + (double)width * (double)new_height / (double)height; - } else { - new_height = 0.5 + (double)height * (double)new_width / (double)width; - } - - scale = gdk_pixbuf_scale_simple (pixbuf, new_width, new_height, - GDK_INTERP_HYPER); - g_object_unref(G_OBJECT(pixbuf)); - pixbuf = scale; - } - if (error) { - g_free(random); - g_free(filename); - gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message); - g_error_free(error); - g_strfreev(prpl_formats); - return NULL; - } - - for (i = 0; prpl_formats[i]; i++) { - gaim_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename); - /* The gdk-pixbuf documentation is wrong. gdk_pixbuf_save returns TRUE if it was successful, - * FALSE if an error was set. */ - if (gdk_pixbuf_save (pixbuf, filename, prpl_formats[i], &error, NULL) == TRUE) - break; - gaim_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], error->message); - g_error_free(error); - error = NULL; - } - g_strfreev(prpl_formats); - if (!error) { - g_object_unref(G_OBJECT(pixbuf)); - g_free(filename); - return random; - } else { - gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message); - g_error_free(error); - } - g_free(random); - g_free(filename); - g_object_unref(G_OBJECT(pixbuf)); - } - return NULL; -#endif -} - static void update_editable(GaimConnection *gc, AccountPrefsDialog *dialog) { @@ -898,6 +515,12 @@ } static void +icon_check_cb(GtkWidget *checkbox, AccountPrefsDialog *dialog) +{ + gtk_widget_set_sensitive(dialog->icon_hbox, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))); +} + +static void add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent) { GtkWidget *frame; @@ -930,12 +553,17 @@ gtk_widget_show(dialog->new_mail_check); /* Buddy icon */ + dialog->icon_check = gtk_check_button_new_with_label(_("Use this buddy icon for this account:")); + g_signal_connect(G_OBJECT(dialog->icon_check), "toggled", G_CALLBACK(icon_check_cb), dialog); + gtk_widget_show(dialog->icon_check); + gtk_box_pack_start(GTK_BOX(vbox), dialog->icon_check, FALSE, FALSE, 0); + dialog->icon_hbox = hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); + gtk_widget_set_sensitive(hbox, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); - label = gtk_label_new(_("Buddy icon:")); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); + label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); @@ -976,12 +604,14 @@ if (dialog->account != NULL) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->new_mail_check), - gaim_account_get_check_mail(dialog->account)); + gaim_account_get_check_mail(dialog->account)); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->icon_check), + !gaim_account_get_ui_bool(dialog->account, GAIM_GTK_UI, "use-global-buddyicon", + TRUE)); - if (gaim_account_get_buddy_icon(dialog->account) != NULL) { - dialog->icon_path = g_strdup(gaim_account_get_buddy_icon(dialog->account)); - set_dialog_icon(dialog); - } + dialog->icon_path = g_strdup(gaim_account_get_ui_string(dialog->account, GAIM_GTK_UI, "non-global-buddyicon", NULL)); + set_dialog_icon(dialog); } if (!dialog->prpl_info || @@ -1425,12 +1055,13 @@ if (dialog->icon_path != NULL) { - const char *icon = gaim_account_get_buddy_icon(dialog->account); + const char *icon = gaim_account_get_ui_string(dialog->account, GAIM_GTK_UI, "non-global-buddyicon", NULL); if (dialog->icon_path != NULL && (icon == NULL || strcmp(dialog->icon_path, icon))) { /* The user set an icon, which would've been cached by convert_buddy_icon, * but didn't save the changes. Delete the cache file. */ char *filename = g_build_filename(gaim_buddy_icons_get_cache_dir(), dialog->icon_path, NULL); + printf("Deleting\n"); g_unlink(filename); g_free(filename); } @@ -1460,7 +1091,7 @@ const char *value; char *username; char *tmp; - gboolean new = FALSE; + gboolean new = FALSE, icon_change = FALSE; GaimAccount *account; if (dialog->account == NULL) @@ -1488,7 +1119,20 @@ gaim_account_set_alias(account, NULL); /* Buddy Icon */ - gaim_account_set_buddy_icon(account, dialog->icon_path); + if (gaim_account_get_ui_bool(account, GAIM_GTK_UI, "use-global-buddyicon", TRUE) == + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))) { + icon_change = TRUE; + } + gaim_account_set_ui_bool(account, GAIM_GTK_UI, "use-global-buddyicon", !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))); + gaim_account_set_ui_string(account, GAIM_GTK_UI, "non-global-buddyicon", dialog->icon_path); + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))) { + gaim_account_set_buddy_icon(account, dialog->icon_path); + } else if (gaim_prefs_get_string("/gaim/gtk/accounts/buddyicon") && icon_change) { + char *icon = gaim_gtk_convert_buddy_icon(dialog->plugin, gaim_prefs_get_string("/gaim/gtk/accounts/buddyicon")); + gaim_account_set_buddy_icon(account, icon); + g_free(icon); + } + /* Remember Password */ gaim_account_set_remember_password(account, @@ -2672,6 +2316,7 @@ gaim_prefs_add_none("/gaim/gtk/accounts/dialog"); gaim_prefs_add_int("/gaim/gtk/accounts/dialog/width", 520); gaim_prefs_add_int("/gaim/gtk/accounts/dialog/height", 321); + gaim_prefs_add_string("/gaim/gtk/accounts/buddyicon", NULL); gaim_signal_register(gaim_gtk_account_get_handle(), "account-modified", gaim_marshal_VOID__POINTER, NULL, 1, Modified: branches/v2_0_0/src/gtkblist.c =================================================================== --- branches/v2_0_0/src/gtkblist.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/gtkblist.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -3798,12 +3798,11 @@ /* Add the statusbox */ gtkblist->statusbox = gtk_gaim_status_box_new(); + gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->statusbox, FALSE, TRUE, 0); gtk_widget_set_name(gtkblist->statusbox, "gaim_gtkblist_statusbox"); - + gtk_gaim_status_box_set_buddy_icon(gtkblist->statusbox, gaim_prefs_get_string("/gaim/gtk/accounts/buddyicon")); gtk_widget_show(gtkblist->statusbox); - gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->statusbox, FALSE, TRUE, 0); - - + /* set the Show Offline Buddies option. must be done * after the treeview or faceprint gets mad. -Robot101 */ Modified: branches/v2_0_0/src/gtkstatusbox.c =================================================================== --- branches/v2_0_0/src/gtkstatusbox.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/gtkstatusbox.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -77,6 +77,8 @@ static gboolean gtk_gaim_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event); static void gtk_gaim_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); +static void do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift); + static void (*combo_box_size_request)(GtkWidget *widget, GtkRequisition *requisition); static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation); static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); @@ -260,6 +262,17 @@ gaim_signals_disconnect_by_handle(statusbox); gaim_prefs_disconnect_by_handle(statusbox); + gdk_cursor_unref(statusbox->hand_cursor); + gdk_cursor_unref(statusbox->arrow_cursor); + + g_object_unref(G_OBJECT(statusbox->buddy_icon)); + g_object_unref(G_OBJECT(statusbox->buddy_icon_hover)); + + if (statusbox->buddy_icon_sel) + gtk_widget_destroy(statusbox->buddy_icon_sel); + + g_free(statusbox->buddy_icon_path); + G_OBJECT_CLASS(parent_class)->finalize(obj); } @@ -903,6 +916,62 @@ } static void +icon_choose_cb(const char *filename, gpointer data) +{ + GtkGaimStatusBox *box; + + box = data; + + if (filename) { + GList *accounts; + for (accounts = gaim_accounts_get_all(); accounts != NULL; accounts = accounts->next) { + GaimAccount *account = accounts->data; + if (gaim_account_get_ui_bool(account, GAIM_GTK_UI, "use-global-buddy-icon", TRUE) && + GAIM_PLUGIN_PROTOCOL_INFO(gaim_find_prpl(gaim_account_get_protocol_id(account)))->icon_spec.format) { + char *icon = gaim_gtk_convert_buddy_icon(gaim_find_prpl(gaim_account_get_protocol_id(account)), + filename); + gaim_account_set_buddy_icon(account, icon); + g_free(icon); + } + } + gtk_gaim_status_box_set_buddy_icon(box, filename); + } + + box->buddy_icon_sel = NULL; +} + +static gboolean +icon_box_press_cb(GtkWidget *widget, GdkEventButton *event, GtkGaimStatusBox *box) +{ + GtkWidget *filesel; + + if (box->buddy_icon_sel) { + gtk_window_present(GTK_WINDOW(box->buddy_icon_sel)); + return FALSE; + } + + filesel = gaim_gtk_buddy_icon_chooser_new(NULL, icon_choose_cb, box); + gtk_widget_show_all(filesel); + return FALSE; +} + +static gboolean +icon_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, GtkGaimStatusBox *box) +{ + gdk_window_set_cursor(widget->window, box->hand_cursor); + gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon_hover); + return FALSE; +} + +static gboolean +icon_box_leave_cb(GtkWidget *widget, GdkEventCrossing *event, GtkGaimStatusBox *box) +{ + gdk_window_set_cursor(widget->window, box->arrow_cursor); + gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon) ; + return FALSE; +} + +static void gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) { GtkCellRenderer *text_rend; @@ -918,6 +987,18 @@ status_box->vsep = gtk_vseparator_new(); status_box->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); + status_box->buddy_icon = gdk_pixbuf_new_from_file("/home/seanegan/p1120233.jpg", NULL); + status_box->icon = gtk_image_new_from_pixbuf(status_box->buddy_icon); + status_box->icon_box = gtk_event_box_new(); + status_box->hand_cursor = gdk_cursor_new (GDK_HAND2); + status_box->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); + + g_signal_connect(G_OBJECT(status_box->icon_box), "enter-notify-event", G_CALLBACK(icon_box_enter_cb), status_box); + g_signal_connect(G_OBJECT(status_box->icon_box), "leave-notify-event", G_CALLBACK(icon_box_leave_cb), status_box); + g_signal_connect(G_OBJECT(status_box->icon_box), "button-press-event", G_CALLBACK(icon_box_press_cb), status_box); + + gtk_container_add(GTK_CONTAINER(status_box->icon_box), status_box->icon); + status_box->store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); status_box->dropdown_store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); @@ -930,6 +1011,7 @@ gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->arrow, FALSE, FALSE, 0); gtk_widget_show_all(status_box->toggle_button); + gtk_widget_show_all(status_box->icon_box); #if GTK_CHECK_VERSION(2,4,0) gtk_button_set_focus_on_click(GTK_BUTTON(status_box->toggle_button), FALSE); #endif @@ -980,6 +1062,7 @@ #endif gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box)); gtk_widget_set_parent(status_box->toggle_button, GTK_WIDGET(status_box)); + gtk_widget_set_parent(status_box->icon_box, GTK_WIDGET(status_box)); GTK_BIN(status_box)->child = status_box->toggle_button; gtk_box_pack_start(GTK_BOX(status_box->vbox), status_box->sw, TRUE, TRUE, 0); @@ -1020,14 +1103,58 @@ requisition->height += box_req.height + 3; requisition->width = 1; + + } +/* From gnome-panel */ static void +do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift) +{ + gint i, j; + gint width, height, has_alpha, srcrowstride, destrowstride; + guchar *target_pixels; + guchar *original_pixels; + guchar *pixsrc; + guchar *pixdest; + int val; + guchar r,g,b; + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + srcrowstride = gdk_pixbuf_get_rowstride (src); + destrowstride = gdk_pixbuf_get_rowstride (dest); + target_pixels = gdk_pixbuf_get_pixels (dest); + original_pixels = gdk_pixbuf_get_pixels (src); + + for (i = 0; i < height; i++) { + pixdest = target_pixels + i*destrowstride; + pixsrc = original_pixels + i*srcrowstride; + for (j = 0; j < width; j++) { + r = *(pixsrc++); + g = *(pixsrc++); + b = *(pixsrc++); + val = r + shift; + *(pixdest++) = CLAMP(val, 0, 255); + val = g + shift; + *(pixdest++) = CLAMP(val, 0, 255); + val = b + shift; + *(pixdest++) = CLAMP(val, 0, 255); + if (has_alpha) + *(pixdest++) = *(pixsrc++); + } + } +} + +static void gtk_gaim_status_box_size_allocate(GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { + GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX(widget); GtkRequisition req = {0,0}; - GtkAllocation parent_alc, box_alc; + GtkAllocation parent_alc, box_alc, icon_alc; + GdkPixbuf *scaled; combo_box_size_request(widget, &req); @@ -1039,7 +1166,33 @@ parent_alc = *allocation; parent_alc.height = MAX(1,req.height); parent_alc.y += 3; + parent_alc.width -= (parent_alc.height + 3); combo_box_size_allocate(widget, &parent_alc); + + icon_alc = *allocation; + icon_alc.height = MAX(1,req.height); + icon_alc.width = icon_alc.height; + icon_alc.x = allocation->width - icon_alc.width; + icon_alc.y += 3; + + if (status_box->icon_size != icon_alc.height) + { + if ((status_box->buddy_icon_path != NULL) && + (*status_box->buddy_icon_path != '\0')) + { + scaled = gdk_pixbuf_new_from_file_at_scale(status_box->buddy_icon_path, + icon_alc.height, icon_alc.width, FALSE, NULL); + status_box->buddy_icon_hover = gdk_pixbuf_copy(scaled); + do_colorshift(status_box->buddy_icon_hover, status_box->buddy_icon_hover, 30); + g_object_unref(status_box->buddy_icon); + status_box->buddy_icon = scaled; + gtk_image_set_from_pixbuf(GTK_IMAGE(status_box->icon), status_box->buddy_icon); + } + status_box->icon_size = icon_alc.height; + } + gtk_widget_size_allocate((GTK_GAIM_STATUS_BOX(widget))->icon_box, &icon_alc); + + gtk_widget_size_allocate((GTK_GAIM_STATUS_BOX(widget))->toggle_button, &parent_alc); widget->allocation = *allocation; } @@ -1051,6 +1204,7 @@ GtkGaimStatusBox *status_box = GTK_GAIM_STATUS_BOX(widget); gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->vbox, event); gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->toggle_button, event); + gtk_container_propagate_expose(GTK_CONTAINER(widget), status_box->icon_box, event); return FALSE; } @@ -1067,6 +1221,7 @@ (* callback) (status_box->vbox, callback_data); (* callback) (status_box->toggle_button, callback_data); (* callback) (status_box->arrow, callback_data); + (* callback) (status_box->icon_box, callback_data); } combo_box_forall(container, include_internals, callback, callback_data); @@ -1175,6 +1330,37 @@ } void +gtk_gaim_status_box_set_buddy_icon(GtkGaimStatusBox *box, const char *filename) +{ + GdkPixbuf *scaled; + g_free(box->buddy_icon_path); + box->buddy_icon_path = g_strdup(filename); + + if ((filename != NULL) && (*filename != '\0')) + { + if (box->buddy_icon != NULL) + g_object_unref(box->buddy_icon); + scaled = gdk_pixbuf_new_from_file_at_scale(filename, + box->icon_size, box->icon_size, FALSE, NULL); + if (scaled != NULL) + { + box->buddy_icon_hover = gdk_pixbuf_copy(scaled); + do_colorshift(box->buddy_icon_hover, box->buddy_icon_hover, 30); + box->buddy_icon = scaled; + gtk_image_set_from_pixbuf(GTK_IMAGE(box->icon), box->buddy_icon); + } + } + + gaim_prefs_set_string("/gaim/gtk/accounts/buddyicon", filename); +} + +const char* +gtk_gaim_status_box_get_buddy_icon(GtkGaimStatusBox *box) +{ + return box->buddy_icon_path; +} + +void gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box) { if (!status_box) Modified: branches/v2_0_0/src/gtkstatusbox.h =================================================================== --- branches/v2_0_0/src/gtkstatusbox.h 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/gtkstatusbox.h 2006-08-16 07:37:42 UTC (rev 16787) @@ -83,6 +83,17 @@ GtkWidget *vbox, *sw; GtkWidget *imhtml; + + char *buddy_icon_path; + GdkPixbuf *buddy_icon; + GdkPixbuf *buddy_icon_hover; + GtkWidget *buddy_icon_sel; + GtkWidget *icon; + GtkWidget *icon_box; + GdkCursor *hand_cursor; + GdkCursor *arrow_cursor; + int icon_size; + gboolean imhtml_visible; GtkWidget *cell_view; @@ -117,16 +128,16 @@ struct _GtkGaimStatusBoxClass { - GtkComboBoxClass parent_class; + GtkComboBoxClass parent_class; - /* signals */ - void (* changed) (GtkComboBox *combo_box); + /* signals */ + void (* changed) (GtkComboBox *combo_box); - /* Padding for future expansion */ - void (*_gtk_reserved0) (void); - void (*_gtk_reserved1) (void); - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); + /* Padding for future expansion */ + void (*_gtk_reserved0) (void); + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); }; @@ -146,6 +157,12 @@ void gtk_gaim_status_box_pulse_connecting(GtkGaimStatusBox *status_box); +void +gtk_gaim_status_box_set_buddy_icon(GtkGaimStatusBox *status_box, const char *filename); + +const char * +gtk_gaim_status_box_get_buddy_icon(GtkGaimStatusBox *status_box); + char *gtk_gaim_status_box_get_message(GtkGaimStatusBox *status_box); G_END_DECLS Modified: branches/v2_0_0/src/gtkutils.c =================================================================== --- branches/v2_0_0/src/gtkutils.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/gtkutils.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -2211,3 +2211,439 @@ gdk_window_set_cursor(widget->window, NULL); } +struct _icon_chooser { + GtkWidget *icon_filesel; + GtkWidget *icon_preview; + GtkWidget *icon_text; + + void (*callback)(const char*,gpointer); + gpointer data; +}; + +#if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ +static void +icon_filesel_delete_cb(GtkWidget *w, struct _icon_chooser *dialog) +{ + if (dialog->icon_filesel != NULL) + gtk_widget_destroy(dialog->icon_filesel); + + if (dialog->callback) + dialog->callback(NULL, data); + + g_free(dialog); +} +#endif /* FILECHOOSER */ + + + +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ +static void +icon_filesel_choose_cb(GtkWidget *widget, gint response, struct _icon_chooser *dialog) +{ + char *filename, *current_folder; + + if (response != GTK_RESPONSE_ACCEPT) { + if (response == GTK_RESPONSE_CANCEL) { + gtk_widget_destroy(dialog->icon_filesel); + } + dialog->icon_filesel = NULL; + if (dialog->callback) + dialog->callback(NULL, dialog->data); + g_free(dialog); + return; + } + + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog->icon_filesel)); + current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog->icon_filesel)); + if (current_folder != NULL) { + gaim_prefs_set_string("/gaim/gtk/filelocations/last_icon_folder", current_folder); + g_free(current_folder); + } + +#else /* FILECHOOSER */ +static void +icon_filesel_choose_cb(GtkWidget *w, AccountPrefsDialog *dialog) +{ + char *filename, *current_folder; + + filename = g_strdup(gtk_file_selection_get_filename( + GTK_FILE_SELECTION(dialog->icon_filesel))); + + /* If they typed in a directory, change there */ + if (gaim_gtk_check_if_dir(filename, + GTK_FILE_SELECTION(dialog->icon_filesel))) + { + g_free(filename); + return; + } + + current_folder = g_path_get_dirname(filename); + if (current_folder != NULL) { + gaim_prefs_set_string("/gaim/gtk/filelocations/last_icon_folder", current_folder); + g_free(current_folder); + } + +#endif /* FILECHOOSER */ + if (dialog->callback) + dialog->callback(filename, dialog->data); + gtk_widget_destroy(dialog->icon_filesel); + g_free(filename); + g_free(dialog); + } + + +static void +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ +icon_preview_change_cb(GtkFileChooser *widget, struct _icon_chooser *dialog) +#else /* FILECHOOSER */ +icon_preview_change_cb(GtkTreeSelection *sel, struct _icon_chooser *dialog) +#endif /* FILECHOOSER */ +{ + GdkPixbuf *pixbuf, *scale; + int height, width; + char *basename, *markup, *size; + struct stat st; + char *filename; + +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ + filename = gtk_file_chooser_get_preview_filename( + GTK_FILE_CHOOSER(dialog->icon_filesel)); +#else /* FILECHOOSER */ + filename = g_strdup(gtk_file_selection_get_filename( + GTK_FILE_SELECTION(dialog->icon_filesel))); +#endif /* FILECHOOSER */ + + if (!filename || g_stat(filename, &st)) + { + g_free(filename); + return; + } + + pixbuf = gdk_pixbuf_new_from_file(filename, NULL); + if (!pixbuf) { + gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_preview), NULL); + gtk_label_set_markup(GTK_LABEL(dialog->icon_text), ""); +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ + gtk_file_chooser_set_preview_widget_active( + GTK_FILE_CHOOSER(dialog->icon_filesel), FALSE); +#endif /* FILECHOOSER */ + g_free(filename); + return; + } + + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + basename = g_path_get_basename(filename); + size = gaim_str_size_to_units(st.st_size); + markup = g_strdup_printf(_("<b>File:</b> %s\n" + "<b>File size:</b> %s\n" + "<b>Image size:</b> %dx%d"), + basename, size, width, height); + + scale = gdk_pixbuf_scale_simple(pixbuf, width * 50 / height, + 50, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_preview), scale); +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ + gtk_file_chooser_set_preview_widget_active( + GTK_FILE_CHOOSER(dialog->icon_filesel), TRUE); +#endif /* FILECHOOSER */ + gtk_label_set_markup(GTK_LABEL(dialog->icon_text), markup); + + g_object_unref(G_OBJECT(pixbuf)); + g_object_unref(G_OBJECT(scale)); + g_free(filename); + g_free(basename); + g_free(size); + g_free(markup); +} + + +GtkWidget *gaim_gtk_buddy_icon_chooser_new(GtkWindow *parent, void(*callback)(const char *, gpointer), gpointer data) { + struct _icon_chooser *dialog = g_new0(struct _icon_chooser, 1); + +#if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ + GtkWidget *hbox; + GtkWidget *tv; + GtkTreeSelection *sel; +#endif /* FILECHOOSER */ + const char *current_folder; + + dialog->callback = callback; + dialog->data = data; + + if (dialog->icon_filesel != NULL) { + gtk_window_present(GTK_WINDOW(dialog->icon_filesel)); + return NULL; + } + + current_folder = gaim_prefs_get_string("/gaim/gtk/filelocations/last_icon_folder"); +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ + + dialog->icon_filesel = gtk_file_chooser_dialog_new(_("Buddy Icon"), + parent, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog->icon_filesel), GTK_RESPONSE_ACCEPT); + if ((current_folder != NULL) && (*current_folder != '\0')) + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog->icon_filesel), + current_folder); + + dialog->icon_preview = gtk_image_new(); + dialog->icon_text = gtk_label_new(NULL); + gtk_widget_set_size_request(GTK_WIDGET(dialog->icon_preview), -1, 50); + gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog->icon_filesel), + GTK_WIDGET(dialog->icon_preview)); + g_signal_connect(G_OBJECT(dialog->icon_filesel), "update-preview", + G_CALLBACK(icon_preview_change_cb), dialog); + g_signal_connect(G_OBJECT(dialog->icon_filesel), "response", + G_CALLBACK(icon_filesel_choose_cb), dialog); + icon_preview_change_cb(NULL, dialog); +#else /* FILECHOOSER */ + dialog->icon_filesel = gtk_file_selection_new(_("Buddy Icon")); + dialog->icon_preview = gtk_image_new(); + dialog->icon_text = gtk_label_new(NULL); + if ((current_folder != NULL) && (*current_folder != '\0')) + gtk_file_selection_set_filename(GTK_FILE_SELECTION(dialog->icon_filesel), + current_folder); + + gtk_widget_set_size_request(GTK_WIDGET(dialog->icon_preview), -1, 50); + hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); + gtk_box_pack_start( + GTK_BOX(GTK_FILE_SELECTION(dialog->icon_filesel)->main_vbox), + hbox, FALSE, FALSE, 0); + gtk_box_pack_end(GTK_BOX(hbox), dialog->icon_preview, + FALSE, FALSE, 0); + gtk_box_pack_end(GTK_BOX(hbox), dialog->icon_text, FALSE, FALSE, 0); + + tv = GTK_FILE_SELECTION(dialog->icon_filesel)->file_list; + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); + + g_signal_connect(G_OBJECT(sel), "changed", + G_CALLBACK(icon_preview_change_cb), dialog); + g_signal_connect( + G_OBJECT(GTK_FILE_SELECTION(dialog->icon_filesel)->ok_button), + "clicked", + G_CALLBACK(icon_filesel_choose_cb), dialog); + g_signal_connect( + G_OBJECT(GTK_FILE_SELECTION(dialog->icon_filesel)->cancel_button), + "clicked", + G_CALLBACK(icon_filesel_delete_cb), dialog); + g_signal_connect(G_OBJECT(dialog->icon_filesel), "destroy", + G_CALLBACK(icon_filesel_delete_cb), dialog); +#endif /* FILECHOOSER */ + return dialog->icon_filesel; +} + + +#if GTK_CHECK_VERSION(2,2,0) +static gboolean +str_array_match(char **a, char **b) +{ + int i, j; + + if (!a || !b) + return FALSE; + for (i = 0; a[i] != NULL; i++) + for (j = 0; b[j] != NULL; j++) + if (!g_ascii_strcasecmp(a[i], b[j])) + return TRUE; + return FALSE; +} +#endif + +char * +gaim_gtk_convert_buddy_icon(GaimPlugin *plugin, const char *path) +{ +#if GTK_CHECK_VERSION(2,2,0) + int width, height; + char **pixbuf_formats = NULL; + GdkPixbufFormat *format; + GdkPixbuf *pixbuf; + GaimPluginProtocolInfo *prpl_info; + char **prpl_formats; +#if !GTK_CHECK_VERSION(2,4,0) + GdkPixbufLoader *loader; + FILE *file; + struct stat st; + void *data = NULL; +#endif +#endif + const char *dirname; + char *random; + char *filename; + + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + g_return_val_if_fail(prpl_info->icon_spec.format != NULL, NULL); + + prpl_formats = g_strsplit(prpl_info->icon_spec.format,",",0); + dirname = gaim_buddy_icons_get_cache_dir(); + random = g_strdup_printf("%x", g_random_int()); + filename = g_build_filename(dirname, random, NULL); + + if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { + gaim_debug_info("buddyicon", "Creating icon cache directory.\n"); + + if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { + gaim_debug_error("buddyicon", + "Unable to create directory %s: %s\n", + dirname, strerror(errno)); +#if GTK_CHECK_VERSION(2,2,0) + g_strfreev(prpl_formats); +#endif + g_free(random); + g_free(filename); + return NULL; + } + } + +#if GTK_CHECK_VERSION(2,2,0) +#if GTK_CHECK_VERSION(2,4,0) + format = gdk_pixbuf_get_file_info (path, &width, &height); +#else + loader = gdk_pixbuf_loader_new(); + if (!g_stat(path, &st) && (file = g_fopen(path, "rb")) != NULL) { + data = g_malloc(st.st_size); + fread(data, 1, st.st_size, file); + fclose(file); + gdk_pixbuf_loader_write(loader, data, st.st_size, NULL); + g_free(data); + } + gdk_pixbuf_loader_close(loader, NULL); + pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + format = gdk_pixbuf_loader_get_format(loader); + g_object_unref(G_OBJECT(loader)); +#endif + if (format == NULL) + return NULL; + pixbuf_formats = gdk_pixbuf_format_get_extensions(format); + + if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ + (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ + (prpl_info->icon_spec.min_width <= width && + prpl_info->icon_spec.max_width >= width && + prpl_info->icon_spec.min_height <= height && + prpl_info->icon_spec.max_height >= height))) /* The icon is the correct size */ +#endif + { + gchar *contents; + gsize length; + FILE *image; + +#if GTK_CHECK_VERSION(2,2,0) + g_strfreev(prpl_formats); + g_strfreev(pixbuf_formats); +#endif + + /* Copy the image to the cache folder as "filename". */ + + if (!g_file_get_contents(path, &contents, &length, NULL) || + (image = g_fopen(filename, "wb")) == NULL) + { + g_free(random); + g_free(filename); +#if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) + g_object_unref(G_OBJECT(pixbuf)); +#endif + return NULL; + } + + if (fwrite(contents, 1, length, image) != length) + { + fclose(image); + g_unlink(filename); + + g_free(random); + g_free(filename); +#if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) + g_object_unref(G_OBJECT(pixbuf)); +#endif + return NULL; + } + fclose(image); + +#if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) + g_object_unref(G_OBJECT(pixbuf)); +#endif + + g_free(filename); + return random; + } +#if GTK_CHECK_VERSION(2,2,0) + else + { + int i; + GError *error = NULL; + GdkPixbuf *scale; + pixbuf = gdk_pixbuf_new_from_file(path, &error); + g_strfreev(pixbuf_formats); + if (!error && (prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) && + (width < prpl_info->icon_spec.min_width || + width > prpl_info->icon_spec.max_width || + height < prpl_info->icon_spec.min_height || + height > prpl_info->icon_spec.max_height)) + { + int new_width = width; + int new_height = height; + + if(new_width > prpl_info->icon_spec.max_width) + new_width = prpl_info->icon_spec.max_width; + else if(new_width < prpl_info->icon_spec.min_width) + new_width = prpl_info->icon_spec.min_width; + if(new_height > prpl_info->icon_spec.max_height) + new_height = prpl_info->icon_spec.max_height; + else if(new_height < prpl_info->icon_spec.min_height) + new_height = prpl_info->icon_spec.min_height; + + /* preserve aspect ratio */ + if ((double)height * (double)new_width > + (double)width * (double)new_height) { + new_width = 0.5 + (double)width * (double)new_height / (double)height; + } else { + new_height = 0.5 + (double)height * (double)new_width / (double)width; + } + + scale = gdk_pixbuf_scale_simple (pixbuf, new_width, new_height, + GDK_INTERP_HYPER); + g_object_unref(G_OBJECT(pixbuf)); + pixbuf = scale; + } + if (error) { + g_free(random); + g_free(filename); + gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message); + g_error_free(error); + g_strfreev(prpl_formats); + return NULL; + } + + for (i = 0; prpl_formats[i]; i++) { + gaim_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename); + /* The gdk-pixbuf documentation is wrong. gdk_pixbuf_save returns TRUE if it was successful, + * FALSE if an error was set. */ + if (gdk_pixbuf_save (pixbuf, filename, prpl_formats[i], &error, NULL) == TRUE) + break; + gaim_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], error->message); + g_error_free(error); + error = NULL; + } + g_strfreev(prpl_formats); + if (!error) { + g_object_unref(G_OBJECT(pixbuf)); + g_free(filename); + return random; + } else { + gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message); + g_error_free(error); + } + g_free(random); + g_free(filename); + g_object_unref(G_OBJECT(pixbuf)); + } + return NULL; +#endif +} Modified: branches/v2_0_0/src/gtkutils.h =================================================================== --- branches/v2_0_0/src/gtkutils.h 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/gtkutils.h 2006-08-16 07:37:42 UTC (rev 16787) @@ -462,4 +462,23 @@ */ void gaim_gtk_clear_cursor(GtkWidget *widget); +/** + * Creates a File Selection widget for choosing a buddy icon + * + * @param parent The parent window + * @param callback The callback to call when the window is closed. If the user chose an icon, the char* argument will point to its path + * @param data Data to pass to @callback + * @return The file dialog + */ +GtkWidget *gaim_gtk_buddy_icon_chooser_new(GtkWindow *parent, void(*callback)(const char*,gpointer), gpointer data); + +/** + * Converts a buddy icon to the required size and format + * + * @param plugin The prpl to conver the icon + * @param path The path of a buddy icon to convert + * @return The path of a new buddy icon + */ +char* gaim_gtk_convert_buddy_icon(GaimPlugin *plugin, const char *path); + #endif /* _GAIM_GTKUTILS_H_ */ Modified: branches/v2_0_0/src/prefs.c =================================================================== --- branches/v2_0_0/src/prefs.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/prefs.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -124,14 +124,14 @@ } else if (pref->type == GAIM_PREF_STRING) { xmlnode_set_attrib(node, "type", "string"); - xmlnode_set_attrib(node, "value", pref->value.string); + xmlnode_set_attrib(node, "value", pref->value.string ? pref->value.string : ""); } else if (pref->type == GAIM_PREF_STRING_LIST) { xmlnode_set_attrib(node, "type", "stringlist"); for (cur = pref->value.stringlist; cur != NULL; cur = cur->next) { childnode = xmlnode_new_child(node, "item"); - xmlnode_set_attrib(childnode, "value", cur->data); + xmlnode_set_attrib(childnode, "value", cur->data ? cur->data : ""); } } else if (pref->type == GAIM_PREF_BOOLEAN) { Modified: branches/v2_0_0/src/protocols/msn/nexus.c =================================================================== --- branches/v2_0_0/src/protocols/msn/nexus.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/protocols/msn/nexus.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -293,7 +293,16 @@ } +/* this guards against missing hash entries */ +static char * +nexus_challenge_data_lookup(GHashTable *challenge_data, const char *key) +{ + char *entry; + return (entry = (char *)g_hash_table_lookup(challenge_data, key)) ? + entry : "(null)"; +} + void login_connect_cb(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond) @@ -336,16 +345,16 @@ "Host: %s\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n", - (char *)g_hash_table_lookup(nexus->challenge_data, "lc"), - (char *)g_hash_table_lookup(nexus->challenge_data, "id"), - (char *)g_hash_table_lookup(nexus->challenge_data, "tw"), - (char *)g_hash_table_lookup(nexus->challenge_data, "fs"), - (char *)g_hash_table_lookup(nexus->challenge_data, "ru"), + nexus_challenge_data_lookup(nexus->challenge_data, "lc"), + nexus_challenge_data_lookup(nexus->challenge_data, "id"), + nexus_challenge_data_lookup(nexus->challenge_data, "tw"), + nexus_challenge_data_lookup(nexus->challenge_data, "fs"), + nexus_challenge_data_lookup(nexus->challenge_data, "ru"), ctint, - (char *)g_hash_table_lookup(nexus->challenge_data, "kpp"), - (char *)g_hash_table_lookup(nexus->challenge_data, "kv"), - (char *)g_hash_table_lookup(nexus->challenge_data, "ver"), - (char *)g_hash_table_lookup(nexus->challenge_data, "tpf"), + nexus_challenge_data_lookup(nexus->challenge_data, "kpp"), + nexus_challenge_data_lookup(nexus->challenge_data, "kv"), + nexus_challenge_data_lookup(nexus->challenge_data, "ver"), + nexus_challenge_data_lookup(nexus->challenge_data, "tpf"), nexus->login_host); buffer = g_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail); Modified: branches/v2_0_0/src/protocols/yahoo/yahoo_packet.c =================================================================== --- branches/v2_0_0/src/protocols/yahoo/yahoo_packet.c 2006-08-16 07:19:41 UTC (rev 16786) +++ branches/v2_0_0/src/protocols/yahoo/yahoo_packet.c 2006-08-16 07:37:42 UTC (rev 16787) @@ -40,7 +40,11 @@ void yahoo_packet_hash_str(struct yahoo_packet *pkt, int key, const char *value) { - struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); + struct yahoo_pair *pair; + + g_return_if_fail(value != NULL); + + pair = g_new0(struct yahoo_pair, 1); pair->key = key; pair->value = g_strdup(value); pkt->hash = g_slist_prepend(pkt->hash, pair); @@ -48,8 +52,9 @@ void yahoo_packet_hash_int(struct yahoo_packet *pkt, int key, int value) { - struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); + struct yahoo_pair *pair; + pair = g_new0(struct yahoo_pair, 1); pair->key = key; pair->value = g_strdup_printf("%d", value); pkt->hash = g_slist_prepend(pkt->hash, pair); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |