--- a/libpurple/protocols/yahoo/yahoo.c Mon Jun 08 18:28:31 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Mon Jun 22 21:53:53 2009 +0000 @@ -64,7 +64,7 @@ static void yahoo_add_buddy(PurpleConnection *gc, PurpleBuddy *, PurpleGroup *); #ifdef TRY_WEBMESSENGER_LOGIN static void yahoo_login_page_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message); -#endif +#endif /* TRY_WEBMESSENGER_LOGIN */ static void yahoo_set_status(PurpleAccount *account, PurpleStatus *status); static void yahoo_update_status(PurpleConnection *gc, const char *name, YahooFriend *f) @@ -523,7 +523,7 @@ purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n",account->username, norm_bud); purple_privacy_deny_add(account, norm_bud, 1); } - + protocol = 0; stealth = 0; norm_bud = NULL; @@ -554,7 +554,7 @@ } g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL); - + /* Now that we have processed the buddy list, we can say yahoo has connected */ purple_connection_set_display_name(gc, purple_normalize(account, purple_account_get_username(account))); purple_connection_set_state(gc, PURPLE_CONNECTED); @@ -813,6 +813,7 @@ int time; int utf8; int buddy_icon; + char *id; char *msg; }; @@ -824,8 +825,8 @@ struct yahoo_data *yd; char *server_msg = NULL; char *m; - - yd = gc->proto_data; + + yd = gc->proto_data; account = purple_connection_get_account(gc); while (l != NULL) { @@ -858,7 +859,7 @@ } else purple_notify_error(gc, NULL, _("Your SMS was not delivered"), NULL); - + g_free(sms->from); g_free(sms); return ; @@ -871,7 +872,7 @@ m = yahoo_string_decode(gc, sms->msg, sms->utf8); serv_got_im(gc, sms->from, m, 0, sms->time); - + g_free(m); g_free(sms->from); g_free(sms); @@ -930,6 +931,9 @@ { imv = pair->value; } + if (pair->key == 429) + if (im) + im->id = pair->value; l = l->next; } } else if (pkt->status == 2) { @@ -997,6 +1001,28 @@ return; } + /* + * TODO: Is there anything else we should check when determining whether + * we should send an acknowledgement? + */ + if (im->id != NULL) { + /* Send acknowledgement. If we don't do this then the official + * Yahoo Messenger client for Windows will send us the same + * message 7 seconds later as an offline message. This is true + * for at least version 9.0.0.2162 on Windows XP. */ + struct yahoo_packet *pkt2; + pkt2 = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_ACK, + YAHOO_STATUS_AVAILABLE, pkt->id); + yahoo_packet_hash(pkt2, "ssisii", + 1, purple_connection_get_display_name(gc), + 5, im->from, + 302, 430, + 430, im->id, + 303, 430, + 450, 0); + yahoo_packet_send_and_free(pkt2, yd); + } + m = yahoo_string_decode(gc, im->msg, im->utf8); /* This may actually not be necessary, but it appears * that at least at one point some clients were sending @@ -1024,7 +1050,7 @@ username = g_markup_escape_text(msn_from, -1); else username = g_markup_escape_text(im->from, -1); - + purple_prpl_got_attention(gc, username, YAHOO_BUZZ); purple_conversation_attention(c, username, 0, PURPLE_MESSAGE_RECV, time(NULL)); @@ -1045,7 +1071,7 @@ g_free(m2); - /* laters : implement buddy icon for msn friends */ + /* laters : implement buddy icon for msn friends */ if(!msn) { if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { if (yahoo_friend_get_buddy_icon_need_request(f)) { @@ -1627,16 +1653,21 @@ purple_debug_error("yahoo", "Login Failed, unable to retrieve stage 2 url: %s\n", error_message); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, error_message); g_free(auth_data->seed); - g_free(auth_data); + g_free(auth_data); return; } else if (len > 0 && ret_data && *ret_data) { gchar **split_data = g_strsplit(ret_data, "\r\n", -1); - int totalelements = g_strv_length(split_data); + int totalelements = 0; int response_no = -1; char *crumb = NULL; char *crypt = NULL; +#if GLIB_CHECK_VERSION(2,6,0) + totalelements = g_strv_length(split_data); +#else + while (split_data[++totalelements] != NULL); +#endif if (totalelements >= 5) { response_no = strtol(split_data[1], NULL, 10); crumb = g_strdup(split_data[2] + strlen("crumb=")); @@ -1714,10 +1745,15 @@ } else if (len > 0 && ret_data && *ret_data) { gchar **split_data = g_strsplit(ret_data, "\r\n", -1); - int totalelements = g_strv_length(split_data); + int totalelements = 0; int response_no = -1; char *token = NULL; +#if GLIB_CHECK_VERSION(2,6,0) + totalelements = g_strv_length(split_data); +#else + while (split_data[++totalelements] != NULL); +#endif if(totalelements >= 5) { response_no = strtol(split_data[1], NULL, 10); token = g_strdup(split_data[2] + strlen("ymsgr=")); @@ -1974,7 +2010,7 @@ { #ifdef TRY_WEBMESSENGER_LOGIN struct yahoo_data *yd = gc->proto_data; -#endif +#endif /* TRY_WEBMESSENGER_LOGIN */ GSList *l = pkt->hash; int err = 0; char *msg; @@ -2018,7 +2054,7 @@ yd->url_datas = g_slist_prepend(yd->url_datas, url_data); return; } -#endif +#endif /* TRY_WEBMESSENGER_LOGIN */ if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); @@ -2084,7 +2120,7 @@ return; if (!group) group = ""; - + if(msn) who = g_strconcat("msn/", temp, NULL); else @@ -2125,7 +2161,7 @@ { size_t pkt_len; guchar *raw_packet; - + /*build the raw packet and send it to the host*/ pkt_len = yahoo_packet_build(pkt, 0, 0, 0, &raw_packet); if(write(source, raw_packet, pkt_len) != pkt_len) @@ -2304,7 +2340,7 @@ yahoo_p2p_disconnect_destroy_data(data); return; } - + if(len < YAHOO_PACKET_HDRLEN) return; @@ -2313,13 +2349,11 @@ purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n"); start = memchr(buf + 1, 'Y', len - 1); - if(start) { - g_memmove(buf, start, len - (start - buf)); - len -= start - buf; - } else { - g_free(buf); + if (start == NULL) return; - } + + g_memmove(buf, start, len - (start - buf)); + len -= start - buf; } pos += 4; /* YMSG */ @@ -2444,7 +2478,7 @@ void yahoo_send_p2p_pkt(PurpleConnection *gc, const char *who, int val_13) { const char *public_ip; - guint32 temp[4]; + guint32 temp[4]; guint32 ip; char temp_str[100]; gchar *base64_ip = NULL; @@ -2465,7 +2499,7 @@ if( strcmp(purple_normalize(account, purple_account_get_username(account)), who) == 0) return; - /* send packet to only those friends who arent p2p connected and to whom we havent already sent. Do not send if this condition doesn't hold good */ + /* send packet to only those friends who arent p2p connected and to whom we havent already sent. Do not send if this condition doesn't hold good */ if( !( f && (yahoo_friend_get_p2p_status(f) == YAHOO_P2PSTATUS_NOT_CONNECTED) && (f->p2p_packet_sent == 0)) ) return; @@ -2528,7 +2562,7 @@ if(error_message != NULL) { purple_debug_warning("yahoo","p2p: %s\n",error_message); yahoo_send_p2p_pkt(p2p_data->gc, p2p_data->host_username, 2);/* send p2p init packet with val_13=2 */ - + yahoo_p2p_disconnect_destroy_data(p2p_data); return; } @@ -2649,7 +2683,7 @@ p2p_data->source = -1; /* connect to host */ - if((purple_proxy_connect(NULL, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, p2p_data))==NULL) { + if((purple_proxy_connect(gc, account, host_ip, YAHOO_PAGER_PORT_P2P, yahoo_p2p_init_cb, p2p_data))==NULL) { purple_debug_info("yahoo","p2p: Connection to %s failed\n", host_ip); g_free(p2p_data->host_ip); g_free(p2p_data->host_username); @@ -2967,11 +3001,6 @@ struct yahoo_data *yd; struct yahoo_packet *pkt; - if (!PURPLE_CONNECTION_IS_VALID(gc)) { - close(source); - return; - } - if (source < 0) { gchar *tmp; tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"), @@ -2999,11 +3028,6 @@ struct yahoo_data *yd; struct yahoo_packet *pkt; - if (!PURPLE_CONNECTION_IS_VALID(gc)) { - close(source); - return; - } - if (source < 0) { gchar *tmp; tmp = g_strdup_printf(_("Could not establish a connection with the server:\n%s"), @@ -3293,7 +3317,7 @@ purple_cipher_context_destroy(context); } -#endif +#endif /* TRY_WEBMESSENGER_LOGIN */ static void yahoo_server_check(PurpleAccount *account) { @@ -3900,7 +3924,7 @@ struct yahoo_data *yd = gc->proto_data; g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc)); - + yd->url_datas = g_slist_remove(yd->url_datas, url_data); if (error_message != NULL) @@ -4041,7 +4065,7 @@ xmlnode *validate_data_root = xmlnode_from_str(webdata, -1); xmlnode *validate_data_child = xmlnode_get_child(validate_data_root, "mobile_no"); mobile_no = (char *)xmlnode_get_attrib(validate_data_child, "msisdn"); - + validate_data_root = xmlnode_copy(validate_data_child); validate_data_child = xmlnode_get_child(validate_data_root, "status"); status = xmlnode_get_data(validate_data_child); @@ -4144,7 +4168,7 @@ struct yahoo_p2p_data *p2p_data; gboolean msn = FALSE; msg2 = yahoo_string_encode(gc, msg, &utf8); - + if(msg2) { lenb = strlen(msg2); lenc = g_utf8_strlen(msg2, -1); @@ -4174,13 +4198,11 @@ struct yahoo_sms_carrier_cb_data *sms_cb_data; sms_cb_data = g_malloc(sizeof(struct yahoo_sms_carrier_cb_data)); sms_cb_data->gc = gc; - sms_cb_data->who = g_malloc(strlen(who)); - sms_cb_data->what = g_malloc(strlen(what)); - strcpy(sms_cb_data->who, who); - strcpy(sms_cb_data->what, what); + sms_cb_data->who = g_strdup(who); + sms_cb_data->what = g_strdup(what); purple_conversation_write(conv, NULL, "Getting mobile carrier to send the sms", PURPLE_MESSAGE_SYSTEM, time(NULL)); - + yahoo_get_sms_carrier(gc, sms_cb_data); g_free(msg); @@ -4299,7 +4321,7 @@ if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !msn ) { yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc), 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", - 5, who, 11, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */ + 5, who, 11, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */ yahoo_p2p_write_pkt(p2p_data->source, pkt); yahoo_packet_free(pkt); }