# HG changeset patch # User Sulabh Mahajan # Date 1232468920 0 # Node ID 97c420d623819e41f58f64892f4e4ea928c78fdb # Parent ffb0d441d0a3ec92245a99f47319df779e53aa7a implement wlm interoperability, add/message friends using wlm/ as id, note prefix "wlm/" diff -r ffb0d441d0a3 -r 97c420d62381 libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Fri Nov 14 09:21:26 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Tue Jan 20 16:28:40 2009 +0000 @@ -155,6 +155,7 @@ char *name = NULL; gboolean unicode = FALSE; char *message = NULL; + char *wlm_name = NULL; if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { if (!purple_account_get_remember_password(account)) @@ -354,7 +355,12 @@ if(f && strtol(pair->value, NULL, 10)) f->version_id = strtol(pair->value, NULL, 10); break; - + case 241: /* protocol buddy belongs to */ + if(strtol(pair->value, NULL, 10) == 2) { + wlm_name = g_strconcat("wlm/", name, NULL); + name = wlm_name; + } + break; default: purple_debug_warning("yahoo", "Unknown status key %d\n", pair->key); @@ -475,10 +481,13 @@ struct yahoo_data *yd = gc->proto_data; GHashTable *ht; char *norm_bud = NULL; + char *temp = NULL; YahooFriend *f = NULL; /* It's your friends. They're going to want you to share your StarBursts. */ /* But what if you had no friends? */ PurpleBuddy *b; PurpleGroup *g; + int protocol = 0; + int stealth = 0; ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free); @@ -502,6 +511,48 @@ break; case 301: /* This is 319 before all s/n's in a group after the first. It is followed by an identical 300. */ + if(temp != NULL) { + if(protocol == 2) + norm_bud = g_strconcat("wlm/", temp, NULL); + else + norm_bud = g_strdup(temp); + + if (yd->current_list15_grp) { + /* This buddy is in a group */ + f = yahoo_friend_find_or_new(gc, norm_bud); + if (!(b = purple_find_buddy(account, norm_bud))) { + if (!(g = purple_find_group(yd->current_list15_grp))) { + g = purple_group_new(yd->current_list15_grp); + purple_blist_add_group(g, NULL); + } + b = purple_buddy_new(account, norm_bud, NULL); + purple_blist_add_buddy(b, NULL, g, NULL); + } + yahoo_do_group_check(account, ht, norm_bud, yd->current_list15_grp); + if(protocol != 0) { + f->protocol = protocol; + purple_debug_info("yahoo", "Setting protocol to %d\n", f->protocol); + } + if(stealth == 2) + f->presence = YAHOO_PRESENCE_PERM_OFFLINE; + + /* set p2p status not connected and no p2p packet sent */ + if(protocol == 0) { + yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); + f->p2p_packet_sent = 0; + } else + yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_DO_NOT_CONNECT); + } else { + /* This buddy is on the ignore list (and therefore in no group) */ + 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; + temp = NULL; + } break; case 300: /* This is 318 before a group, 319 before any s/n in a group, and 320 before any ignored s/n. */ break; @@ -510,46 +561,16 @@ yd->current_list15_grp = yahoo_string_decode(gc, pair->value, FALSE); break; case 7: /* buddy's s/n */ - g_free(norm_bud); - norm_bud = g_strdup(purple_normalize(account, pair->value)); - - if (yd->current_list15_grp) { - /* This buddy is in a group */ - f = yahoo_friend_find_or_new(gc, norm_bud); - if (!(b = purple_find_buddy(account, norm_bud))) { - if (!(g = purple_find_group(yd->current_list15_grp))) { - g = purple_group_new(yd->current_list15_grp); - purple_blist_add_group(g, NULL); - } - b = purple_buddy_new(account, norm_bud, NULL); - purple_blist_add_buddy(b, NULL, g, NULL); - } - yahoo_do_group_check(account, ht, norm_bud, yd->current_list15_grp); - - /* set p2p status not connected and no p2p packet sent */ - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); - f->p2p_packet_sent = 0; - - } else { - /* This buddy is on the ignore list (and therefore in no group) */ - 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); - } + temp = g_strdup(purple_normalize(account, pair->value)); break; case 241: /* another protocol user */ - if (f) { - f->protocol = strtol(pair->value, NULL, 10); - purple_debug_info("yahoo", "Setting protocol to %d\n", f->protocol); - } + protocol = strtol(pair->value, NULL, 10); break; case 59: /* somebody told cookies come here too, but im not sure */ yahoo_process_cookie(yd, pair->value); break; case 317: /* Stealth Setting */ - if (f && (strtol(pair->value, NULL, 10) == 2)) { - f->presence = YAHOO_PRESENCE_PERM_OFFLINE; - } + stealth = strtol(pair->value, NULL, 10); break; /* case 242: */ /* this seems related to 241 */ /* break; */ @@ -559,6 +580,7 @@ g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL); g_hash_table_destroy(ht); g_free(norm_bud); + g_free(temp); } static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt) @@ -715,6 +737,8 @@ GSList *l = pkt->hash; gint val_11 = 0; struct yahoo_data *yd = gc->proto_data; + gboolean wlm = FALSE; + char *wlm_from = NULL; account = purple_connection_get_account(gc); @@ -730,6 +754,9 @@ game = pair->value; if (pair->key == 11) val_11 = strtol(pair->value, NULL, 10); + if (pair->key == 241) + if(strtol(pair->value, NULL, 10) == 2) + wlm = TRUE; l = l->next; } @@ -744,13 +771,24 @@ return; } + if(wlm) + wlm_from = g_strconcat("wlm/", from, NULL); + if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING")) && (purple_privacy_check(account, from))) { - if (*stat == '1') - serv_got_typing(gc, from, 0, PURPLE_TYPING); - else - serv_got_typing_stopped(gc, from); + if(wlm) { + if (*stat == '1') + serv_got_typing(gc, wlm_from, 0, PURPLE_TYPING); + else + serv_got_typing_stopped(gc, wlm_from); + } + else { + if (*stat == '1') + serv_got_typing(gc, from, 0, PURPLE_TYPING); + else + serv_got_typing_stopped(gc, from); + } } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { PurpleBuddy *bud = purple_find_buddy(account, from); @@ -778,6 +816,7 @@ g_free(buf); } + g_free(wlm_from); } @@ -860,6 +899,8 @@ struct _yahoo_im *im = NULL; const char *imv = NULL; gint val_11 = 0; + gboolean wlm = FALSE; + char *wlm_from = NULL; account = purple_connection_get_account(gc); @@ -887,6 +928,10 @@ if (im) im->msg = pair->value; } + if (pair->key == 241) { + if(strtol(pair->value, NULL, 10) == 2) + wlm = TRUE; + } /* peer session id */ if (pair->key == 11) { if (im) @@ -904,6 +949,9 @@ _("Your Yahoo! message did not get sent."), NULL); } + if(wlm) + wlm_from = g_strconcat("wlm/", im->from, NULL); + /* disconnect the peer if connected through p2p and sends wrong value for session id */ if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) { purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->from); @@ -948,6 +996,7 @@ for (l = list; l; l = l->next) { YahooFriend *f; char *m, *m2; + PurpleConversation *c; im = l->data; if (!im->from || !im->msg) { @@ -970,35 +1019,54 @@ m = m2; purple_util_chrreplace(m, '\r', '\n'); + c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->from, account); + if ((c == NULL) && wlm) + c=purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, wlm_from, account); + if (!strcmp(m, "")) { - PurpleConversation *c; char *username; - c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->from, account); - if (c == NULL) - c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from); - - username = g_markup_escape_text(im->from, -1); + if(c == NULL) { + if(wlm) + c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, wlm_from); + else + c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from); + } + if(wlm) + username = g_markup_escape_text(wlm_from, -1); + else + username = g_markup_escape_text(im->from, -1); + purple_prpl_got_attention(gc, username, YAHOO_BUZZ); g_free(username); g_free(m); g_free(im); + g_free(wlm_from); continue; } m2 = yahoo_codes_to_html(m); g_free(m); - serv_got_im(gc, im->from, m2, 0, im->time); + + if(wlm) + serv_got_im(gc, wlm_from, m2, 0, im->time); + else + serv_got_im(gc, im->from, m2, 0, im->time); + g_free(m2); - if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { - if (yahoo_friend_get_buddy_icon_need_request(f)) { - yahoo_send_picture_request(gc, im->from); - yahoo_friend_set_buddy_icon_need_request(f, FALSE); + /* laters : implement buddy icon for wlm friends */ + if(!wlm) { + if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { + if (yahoo_friend_get_buddy_icon_need_request(f)) { + yahoo_send_picture_request(gc, im->from); + yahoo_friend_set_buddy_icon_need_request(f, FALSE); + } } } g_free(im); + g_free(wlm_from); } g_slist_free(list); } @@ -1131,12 +1199,14 @@ PurpleAccount *account; GSList *l = pkt->hash; const char *msg = NULL; + int protocol = 0; account = purple_connection_get_account(gc); /* Buddy authorized/declined our addition */ if (pkt->status == 1) { - const char *who = NULL; + char *temp = NULL; + char *who = NULL; int response = 0; while (l) { @@ -1144,7 +1214,7 @@ switch (pair->key) { case 4: - who = pair->value; + temp = pair->value; break; case 13: response = strtol(pair->value, NULL, 10); @@ -1152,10 +1222,18 @@ case 14: msg = pair->value; break; + case 241: + protocol = strtol(pair->value, NULL, 10); + break; } l = l->next; } + if(protocol == 0) + who = temp; + else if(protocol == 2) + who = g_strconcat("wlm/", temp, NULL); + if (response == 1) /* Authorized */ purple_debug_info("yahoo", "Received authorization from buddy '%s'.\n", who ? who : "(Unknown Buddy)"); else if (response == 2) { /* Declined */ @@ -1163,12 +1241,13 @@ yahoo_buddy_denied_our_add(gc, who, msg); } else purple_debug_error("yahoo", "Received unknown authorization response of %d from buddy '%s'.\n", response, who ? who : "(Unknown Buddy)"); - + g_free(who); } /* Buddy requested authorization to add us. */ else if (pkt->status == 3) { struct yahoo_add_request *add_req; const char *firstname = NULL, *lastname = NULL; + char *temp = NULL; add_req = g_new0(struct yahoo_add_request, 1); add_req->gc = gc; @@ -1178,6 +1257,7 @@ switch (pair->key) { case 4: + temp = pair->value; add_req->who = g_strdup(pair->value); break; case 5: @@ -1199,6 +1279,10 @@ } l = l->next; } + if(add_req->protocol == 2) + add_req->who = g_strconcat("wlm/", temp, NULL); + else + add_req->who = g_strdup(temp); if (add_req->id && add_req->who) { char *alias = NULL, *dec_msg = NULL; @@ -2284,6 +2368,7 @@ { int err = 0; char *who = NULL; + char *temp = NULL; char *group = NULL; char *decoded_group; char *buf; @@ -2291,6 +2376,7 @@ GSList *l = pkt->hash; struct yahoo_data *yd = gc->proto_data; int protocol = 0; + gboolean wlm = FALSE; while (l) { struct yahoo_pair *pair = l->data; @@ -2300,23 +2386,30 @@ err = strtol(pair->value, NULL, 10); break; case 7: - who = pair->value; + temp = pair->value; break; case 65: group = pair->value; break; case 241: protocol = strtol(pair->value, NULL, 10); + if(protocol == 2) + wlm = TRUE; break; } l = l->next; } - if (!who) + if (!temp) return; if (!group) group = ""; + + if(wlm) + who = g_strconcat("wlm/", temp, NULL); + else + who = g_strdup(temp); if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */ f = yahoo_friend_find_or_new(gc, who); @@ -2326,8 +2419,12 @@ if( !g_hash_table_lookup(yd->peers, who) ) { /* we are not connected as client, so set friend to not connected */ - yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); - f->p2p_packet_sent = 0; + if(wlm) + yahoo_friend_set_p2p_status(f,YAHOO_P2PSTATUS_DO_NOT_CONNECT); + else { + yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); + f->p2p_packet_sent = 0; + } } else /* we are already connected. set friend to YAHOO_P2PSTATUS_WE_ARE_CLIENT */ yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT); @@ -2341,6 +2438,7 @@ purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); g_free(buf); g_free(decoded_group); + g_free(who); } /* write pkt to the source */ @@ -4338,9 +4436,11 @@ int ret = 1; YahooFriend *f = NULL; struct yahoo_p2p_data *p2p_data; - + gboolean wlm = FALSE; msg2 = yahoo_string_encode(gc, msg, &utf8); + wlm = g_str_has_prefix(who, "wlm/") || g_str_has_prefix(who, "WLM/"); + if( strncmp(who, "+", 1) == 0 ) { /* we have an sms to be sent */ gchar *carrier = NULL; @@ -4391,12 +4491,15 @@ } pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); - yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who); - if ((f = yahoo_friend_find(gc, who)) && f->protocol) - yahoo_packet_hash_int(pkt, 241, f->protocol); - else - if(strchr(who,'@')) - yahoo_packet_hash_int(pkt, 241, 2); + if(wlm) { + yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who+4); + yahoo_packet_hash_int(pkt, 241, 2); + } + else { + yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who); + if ((f = yahoo_friend_find(gc, who)) && f->protocol) + yahoo_packet_hash_int(pkt, 241, f->protocol); + } if (utf8) yahoo_packet_hash_str(pkt, 97, "1"); @@ -4437,13 +4540,14 @@ /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) { /* if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p */ - if( (p2p_data = g_hash_table_lookup(yd->peers, who)) ) { + if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !wlm ) { yahoo_packet_hash_int(pkt, 11, p2p_data->session_id); yahoo_p2p_write_pkt(p2p_data->source, pkt); } else { yahoo_packet_send(pkt, yd); - yahoo_send_p2p_pkt(gc, who, 0); /* send p2p packet, with val_13=0 */ + if(!wlm) + yahoo_send_p2p_pkt(gc, who, 0); /* send p2p packet, with val_13=0 */ } } else @@ -4461,15 +4565,17 @@ { struct yahoo_data *yd = gc->proto_data; struct yahoo_p2p_data *p2p_data; - - struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); + gboolean wlm = (g_str_has_prefix(who, "wlm/") || g_str_has_prefix(who, "WLM/")); + struct yahoo_packet *pkt = NULL; /* Don't do anything if sms is being typed */ if( strncmp(who, "+", 1) == 0 ) return 0; + pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); + /* check to see if p2p link exists, send through it */ - if( (p2p_data = g_hash_table_lookup(yd->peers, who)) ) { + if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !wlm ) { 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 */ @@ -4477,9 +4583,14 @@ yahoo_packet_free(pkt); } else { /* send through yahoo server */ - yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), + if(wlm) + yahoo_packet_hash(pkt, "sssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", - 5, who, 1002, "1"); + 5, who+4, 1002, "1", 241, "2"); + else + yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), + 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", + 5, who+4, 1002, "1"); yahoo_packet_send_and_free(pkt, yd); } @@ -4714,10 +4825,13 @@ const char *group = NULL; char *group2; YahooFriend *f; + gboolean wlm = FALSE; if (!yd->logged_in) return; + wlm = g_str_has_prefix(buddy->name, "wlm/") || g_str_has_prefix(buddy->name, "WLM/"); + if (!purple_privacy_check(purple_connection_get_account(gc), purple_buddy_get_name(buddy))) return; @@ -4732,7 +4846,7 @@ group2 = yahoo_string_encode(gc, group, NULL); pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); - if(strchr(buddy->name, '@')) { + if(wlm) { yahoo_packet_hash(pkt, "sssssssssss", 14, "", 65, group2, @@ -4740,7 +4854,7 @@ 1, purple_connection_get_display_name(gc), 302, "319", 300, "319", - 7, buddy->name, + 7, buddy->name + 4, 241, "2", 334, "0", 301, "319", @@ -4762,8 +4876,6 @@ ); } - if (f && f->protocol) - yahoo_packet_hash_int(pkt, 241, f->protocol); yahoo_packet_send_and_free(pkt, yd); g_free(group2); } @@ -4777,6 +4889,7 @@ gboolean remove = TRUE; char *cg; YahooFriend *f = yahoo_friend_find(gc, buddy->name); + gboolean wlm = FALSE; if (!f) return; @@ -4797,7 +4910,14 @@ cg = yahoo_string_encode(gc, group->name, NULL); pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); - yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), + + if(f->protocol == 2) + wlm = TRUE; + if(wlm) + yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), + 7, buddy->name+4, 65, cg); + else + yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), 7, buddy->name, 65, cg); if(f->protocol) yahoo_packet_hash_int(pkt, 241, f->protocol);