comparison libpurple/protocols/yahoo/yahoo.c @ 26242:97c420d62381

implement wlm interoperability, add/message friends using wlm/<wlm id> as id, note prefix "wlm/"
author Sulabh Mahajan <sulabh@soc.pidgin.im>
date Tue, 20 Jan 2009 16:28:40 +0000
parents ffb0d441d0a3
children 90ffe6f71fa9
comparison
equal deleted inserted replaced
26241:ffb0d441d0a3 26242:97c420d62381
153 GSList *l = pkt->hash; 153 GSList *l = pkt->hash;
154 YahooFriend *f = NULL; 154 YahooFriend *f = NULL;
155 char *name = NULL; 155 char *name = NULL;
156 gboolean unicode = FALSE; 156 gboolean unicode = FALSE;
157 char *message = NULL; 157 char *message = NULL;
158 char *wlm_name = NULL;
158 159
159 if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { 160 if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) {
160 if (!purple_account_get_remember_password(account)) 161 if (!purple_account_get_remember_password(account))
161 purple_account_set_password(account, NULL); 162 purple_account_set_password(account, NULL);
162 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE, 163 purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NAME_IN_USE,
352 break; 353 break;
353 case 244: /* client version number. Yahoo Client Detection */ 354 case 244: /* client version number. Yahoo Client Detection */
354 if(f && strtol(pair->value, NULL, 10)) 355 if(f && strtol(pair->value, NULL, 10))
355 f->version_id = strtol(pair->value, NULL, 10); 356 f->version_id = strtol(pair->value, NULL, 10);
356 break; 357 break;
357 358 case 241: /* protocol buddy belongs to */
359 if(strtol(pair->value, NULL, 10) == 2) {
360 wlm_name = g_strconcat("wlm/", name, NULL);
361 name = wlm_name;
362 }
363 break;
358 default: 364 default:
359 purple_debug_warning("yahoo", 365 purple_debug_warning("yahoo",
360 "Unknown status key %d\n", pair->key); 366 "Unknown status key %d\n", pair->key);
361 break; 367 break;
362 } 368 }
473 479
474 PurpleAccount *account = purple_connection_get_account(gc); 480 PurpleAccount *account = purple_connection_get_account(gc);
475 struct yahoo_data *yd = gc->proto_data; 481 struct yahoo_data *yd = gc->proto_data;
476 GHashTable *ht; 482 GHashTable *ht;
477 char *norm_bud = NULL; 483 char *norm_bud = NULL;
484 char *temp = NULL;
478 YahooFriend *f = NULL; /* It's your friends. They're going to want you to share your StarBursts. */ 485 YahooFriend *f = NULL; /* It's your friends. They're going to want you to share your StarBursts. */
479 /* But what if you had no friends? */ 486 /* But what if you had no friends? */
480 PurpleBuddy *b; 487 PurpleBuddy *b;
481 PurpleGroup *g; 488 PurpleGroup *g;
489 int protocol = 0;
490 int stealth = 0;
482 491
483 492
484 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free); 493 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_slist_free);
485 494
486 while (l) { 495 while (l) {
500 yd->current_list15_grp = NULL; 509 yd->current_list15_grp = NULL;
501 } 510 }
502 511
503 break; 512 break;
504 case 301: /* This is 319 before all s/n's in a group after the first. It is followed by an identical 300. */ 513 case 301: /* This is 319 before all s/n's in a group after the first. It is followed by an identical 300. */
505 break; 514 if(temp != NULL) {
506 case 300: /* This is 318 before a group, 319 before any s/n in a group, and 320 before any ignored s/n. */ 515 if(protocol == 2)
507 break; 516 norm_bud = g_strconcat("wlm/", temp, NULL);
508 case 65: /* This is the group */ 517 else
509 g_free(yd->current_list15_grp); 518 norm_bud = g_strdup(temp);
510 yd->current_list15_grp = yahoo_string_decode(gc, pair->value, FALSE); 519
511 break; 520 if (yd->current_list15_grp) {
512 case 7: /* buddy's s/n */ 521 /* This buddy is in a group */
513 g_free(norm_bud); 522 f = yahoo_friend_find_or_new(gc, norm_bud);
514 norm_bud = g_strdup(purple_normalize(account, pair->value)); 523 if (!(b = purple_find_buddy(account, norm_bud))) {
515 524 if (!(g = purple_find_group(yd->current_list15_grp))) {
516 if (yd->current_list15_grp) { 525 g = purple_group_new(yd->current_list15_grp);
517 /* This buddy is in a group */ 526 purple_blist_add_group(g, NULL);
518 f = yahoo_friend_find_or_new(gc, norm_bud);
519 if (!(b = purple_find_buddy(account, norm_bud))) {
520 if (!(g = purple_find_group(yd->current_list15_grp))) {
521 g = purple_group_new(yd->current_list15_grp);
522 purple_blist_add_group(g, NULL);
523 } 527 }
524 b = purple_buddy_new(account, norm_bud, NULL); 528 b = purple_buddy_new(account, norm_bud, NULL);
525 purple_blist_add_buddy(b, NULL, g, NULL); 529 purple_blist_add_buddy(b, NULL, g, NULL);
526 } 530 }
527 yahoo_do_group_check(account, ht, norm_bud, yd->current_list15_grp); 531 yahoo_do_group_check(account, ht, norm_bud, yd->current_list15_grp);
528 532 if(protocol != 0) {
533 f->protocol = protocol;
534 purple_debug_info("yahoo", "Setting protocol to %d\n", f->protocol);
535 }
536 if(stealth == 2)
537 f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
538
529 /* set p2p status not connected and no p2p packet sent */ 539 /* set p2p status not connected and no p2p packet sent */
530 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); 540 if(protocol == 0) {
531 f->p2p_packet_sent = 0; 541 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED);
532 542 f->p2p_packet_sent = 0;
533 } else { 543 } else
534 /* This buddy is on the ignore list (and therefore in no group) */ 544 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_DO_NOT_CONNECT);
535 purple_debug_info("yahoo", "%s adding %s to the deny list because of the ignore list / no group was found\n", 545 } else {
536 account->username, norm_bud); 546 /* This buddy is on the ignore list (and therefore in no group) */
537 purple_privacy_deny_add(account, norm_bud, 1); 547 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);
548 purple_privacy_deny_add(account, norm_bud, 1);
549 }
550
551 protocol = 0;
552 stealth = 0;
553 norm_bud = NULL;
554 temp = NULL;
538 } 555 }
539 break; 556 break;
557 case 300: /* This is 318 before a group, 319 before any s/n in a group, and 320 before any ignored s/n. */
558 break;
559 case 65: /* This is the group */
560 g_free(yd->current_list15_grp);
561 yd->current_list15_grp = yahoo_string_decode(gc, pair->value, FALSE);
562 break;
563 case 7: /* buddy's s/n */
564 temp = g_strdup(purple_normalize(account, pair->value));
565 break;
540 case 241: /* another protocol user */ 566 case 241: /* another protocol user */
541 if (f) { 567 protocol = strtol(pair->value, NULL, 10);
542 f->protocol = strtol(pair->value, NULL, 10);
543 purple_debug_info("yahoo", "Setting protocol to %d\n", f->protocol);
544 }
545 break; 568 break;
546 case 59: /* somebody told cookies come here too, but im not sure */ 569 case 59: /* somebody told cookies come here too, but im not sure */
547 yahoo_process_cookie(yd, pair->value); 570 yahoo_process_cookie(yd, pair->value);
548 break; 571 break;
549 case 317: /* Stealth Setting */ 572 case 317: /* Stealth Setting */
550 if (f && (strtol(pair->value, NULL, 10) == 2)) { 573 stealth = strtol(pair->value, NULL, 10);
551 f->presence = YAHOO_PRESENCE_PERM_OFFLINE;
552 }
553 break; 574 break;
554 /* case 242: */ /* this seems related to 241 */ 575 /* case 242: */ /* this seems related to 241 */
555 /* break; */ 576 /* break; */
556 } 577 }
557 } 578 }
558 579
559 g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL); 580 g_hash_table_foreach(ht, yahoo_do_group_cleanup, NULL);
560 g_hash_table_destroy(ht); 581 g_hash_table_destroy(ht);
561 g_free(norm_bud); 582 g_free(norm_bud);
583 g_free(temp);
562 } 584 }
563 585
564 static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt) 586 static void yahoo_process_list(PurpleConnection *gc, struct yahoo_packet *pkt)
565 { 587 {
566 GSList *l = pkt->hash; 588 GSList *l = pkt->hash;
713 char *game = NULL; 735 char *game = NULL;
714 YahooFriend *f = NULL; 736 YahooFriend *f = NULL;
715 GSList *l = pkt->hash; 737 GSList *l = pkt->hash;
716 gint val_11 = 0; 738 gint val_11 = 0;
717 struct yahoo_data *yd = gc->proto_data; 739 struct yahoo_data *yd = gc->proto_data;
740 gboolean wlm = FALSE;
741 char *wlm_from = NULL;
718 742
719 account = purple_connection_get_account(gc); 743 account = purple_connection_get_account(gc);
720 744
721 while (l) { 745 while (l) {
722 struct yahoo_pair *pair = l->data; 746 struct yahoo_pair *pair = l->data;
728 stat = pair->value; 752 stat = pair->value;
729 if (pair->key == 14) 753 if (pair->key == 14)
730 game = pair->value; 754 game = pair->value;
731 if (pair->key == 11) 755 if (pair->key == 11)
732 val_11 = strtol(pair->value, NULL, 10); 756 val_11 = strtol(pair->value, NULL, 10);
757 if (pair->key == 241)
758 if(strtol(pair->value, NULL, 10) == 2)
759 wlm = TRUE;
733 l = l->next; 760 l = l->next;
734 } 761 }
735 762
736 if (!from || !msg) 763 if (!from || !msg)
737 return; 764 return;
742 /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ 769 /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
743 g_hash_table_remove(yd->peers, from); 770 g_hash_table_remove(yd->peers, from);
744 return; 771 return;
745 } 772 }
746 773
774 if(wlm)
775 wlm_from = g_strconcat("wlm/", from, NULL);
776
747 if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING")) 777 if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))
748 && (purple_privacy_check(account, from))) 778 && (purple_privacy_check(account, from)))
749 { 779 {
750 if (*stat == '1') 780 if(wlm) {
751 serv_got_typing(gc, from, 0, PURPLE_TYPING); 781 if (*stat == '1')
752 else 782 serv_got_typing(gc, wlm_from, 0, PURPLE_TYPING);
753 serv_got_typing_stopped(gc, from); 783 else
784 serv_got_typing_stopped(gc, wlm_from);
785 }
786 else {
787 if (*stat == '1')
788 serv_got_typing(gc, from, 0, PURPLE_TYPING);
789 else
790 serv_got_typing_stopped(gc, from);
791 }
754 } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { 792 } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) {
755 PurpleBuddy *bud = purple_find_buddy(account, from); 793 PurpleBuddy *bud = purple_find_buddy(account, from);
756 794
757 if (!bud) { 795 if (!bud) {
758 purple_debug(PURPLE_DEBUG_WARNING, "yahoo", 796 purple_debug(PURPLE_DEBUG_WARNING, "yahoo",
776 char *buf = g_strdup_printf(_("%s has sent you a webcam invite, which is not yet supported."), from); 814 char *buf = g_strdup_printf(_("%s has sent you a webcam invite, which is not yet supported."), from);
777 purple_conversation_write(conv, NULL, buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL)); 815 purple_conversation_write(conv, NULL, buf, PURPLE_MESSAGE_SYSTEM|PURPLE_MESSAGE_NOTIFY, time(NULL));
778 g_free(buf); 816 g_free(buf);
779 } 817 }
780 818
819 g_free(wlm_from);
781 } 820 }
782 821
783 822
784 struct _yahoo_im { 823 struct _yahoo_im {
785 char *from; 824 char *from;
858 GSList *l = pkt->hash; 897 GSList *l = pkt->hash;
859 GSList *list = NULL; 898 GSList *list = NULL;
860 struct _yahoo_im *im = NULL; 899 struct _yahoo_im *im = NULL;
861 const char *imv = NULL; 900 const char *imv = NULL;
862 gint val_11 = 0; 901 gint val_11 = 0;
902 gboolean wlm = FALSE;
903 char *wlm_from = NULL;
863 904
864 account = purple_connection_get_account(gc); 905 account = purple_connection_get_account(gc);
865 906
866 if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) { 907 if (pkt->status <= 1 || pkt->status == 5 || pkt->status == YAHOO_STATUS_OFFLINE) {
867 /* messages are received with status YAHOO_STATUS_OFFLINE in case of p2p */ 908 /* messages are received with status YAHOO_STATUS_OFFLINE in case of p2p */
885 im->buddy_icon = strtol(pair->value, NULL, 10); 926 im->buddy_icon = strtol(pair->value, NULL, 10);
886 if (pair->key == 14) { 927 if (pair->key == 14) {
887 if (im) 928 if (im)
888 im->msg = pair->value; 929 im->msg = pair->value;
889 } 930 }
931 if (pair->key == 241) {
932 if(strtol(pair->value, NULL, 10) == 2)
933 wlm = TRUE;
934 }
890 /* peer session id */ 935 /* peer session id */
891 if (pair->key == 11) { 936 if (pair->key == 11) {
892 if (im) 937 if (im)
893 val_11 = strtol(pair->value, NULL, 10); 938 val_11 = strtol(pair->value, NULL, 10);
894 } 939 }
902 } else if (pkt->status == 2) { 947 } else if (pkt->status == 2) {
903 purple_notify_error(gc, NULL, 948 purple_notify_error(gc, NULL,
904 _("Your Yahoo! message did not get sent."), NULL); 949 _("Your Yahoo! message did not get sent."), NULL);
905 } 950 }
906 951
952 if(wlm)
953 wlm_from = g_strconcat("wlm/", im->from, NULL);
954
907 /* disconnect the peer if connected through p2p and sends wrong value for session id */ 955 /* disconnect the peer if connected through p2p and sends wrong value for session id */
908 if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) { 956 if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) {
909 purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->from); 957 purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->from);
910 /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ 958 /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
911 g_hash_table_remove(yd->peers, im->from); 959 g_hash_table_remove(yd->peers, im->from);
946 } 994 }
947 995
948 for (l = list; l; l = l->next) { 996 for (l = list; l; l = l->next) {
949 YahooFriend *f; 997 YahooFriend *f;
950 char *m, *m2; 998 char *m, *m2;
999 PurpleConversation *c;
951 im = l->data; 1000 im = l->data;
952 1001
953 if (!im->from || !im->msg) { 1002 if (!im->from || !im->msg) {
954 g_free(im); 1003 g_free(im);
955 continue; 1004 continue;
968 m2 = purple_strreplace(m, "\r\n", "\n"); 1017 m2 = purple_strreplace(m, "\r\n", "\n");
969 g_free(m); 1018 g_free(m);
970 m = m2; 1019 m = m2;
971 purple_util_chrreplace(m, '\r', '\n'); 1020 purple_util_chrreplace(m, '\r', '\n');
972 1021
1022 c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->from, account);
1023 if ((c == NULL) && wlm)
1024 c=purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, wlm_from, account);
1025
973 if (!strcmp(m, "<ding>")) { 1026 if (!strcmp(m, "<ding>")) {
974 PurpleConversation *c;
975 char *username; 1027 char *username;
976 1028
977 c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, im->from, account); 1029 if(c == NULL) {
978 if (c == NULL) 1030 if(wlm)
979 c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from); 1031 c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, wlm_from);
980 1032 else
981 username = g_markup_escape_text(im->from, -1); 1033 c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, im->from);
1034 }
1035 if(wlm)
1036 username = g_markup_escape_text(wlm_from, -1);
1037 else
1038 username = g_markup_escape_text(im->from, -1);
1039
982 purple_prpl_got_attention(gc, username, YAHOO_BUZZ); 1040 purple_prpl_got_attention(gc, username, YAHOO_BUZZ);
983 g_free(username); 1041 g_free(username);
984 g_free(m); 1042 g_free(m);
985 g_free(im); 1043 g_free(im);
1044 g_free(wlm_from);
986 continue; 1045 continue;
987 } 1046 }
988 1047
989 m2 = yahoo_codes_to_html(m); 1048 m2 = yahoo_codes_to_html(m);
990 g_free(m); 1049 g_free(m);
991 serv_got_im(gc, im->from, m2, 0, im->time); 1050
1051 if(wlm)
1052 serv_got_im(gc, wlm_from, m2, 0, im->time);
1053 else
1054 serv_got_im(gc, im->from, m2, 0, im->time);
1055
992 g_free(m2); 1056 g_free(m2);
993 1057
994 if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) { 1058 /* laters : implement buddy icon for wlm friends */
995 if (yahoo_friend_get_buddy_icon_need_request(f)) { 1059 if(!wlm) {
996 yahoo_send_picture_request(gc, im->from); 1060 if ((f = yahoo_friend_find(gc, im->from)) && im->buddy_icon == 2) {
997 yahoo_friend_set_buddy_icon_need_request(f, FALSE); 1061 if (yahoo_friend_get_buddy_icon_need_request(f)) {
1062 yahoo_send_picture_request(gc, im->from);
1063 yahoo_friend_set_buddy_icon_need_request(f, FALSE);
1064 }
998 } 1065 }
999 } 1066 }
1000 1067
1001 g_free(im); 1068 g_free(im);
1069 g_free(wlm_from);
1002 } 1070 }
1003 g_slist_free(list); 1071 g_slist_free(list);
1004 } 1072 }
1005 1073
1006 static void yahoo_process_sysmessage(PurpleConnection *gc, struct yahoo_packet *pkt) 1074 static void yahoo_process_sysmessage(PurpleConnection *gc, struct yahoo_packet *pkt)
1129 1197
1130 static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *pkt) { 1198 static void yahoo_buddy_auth_req_15(PurpleConnection *gc, struct yahoo_packet *pkt) {
1131 PurpleAccount *account; 1199 PurpleAccount *account;
1132 GSList *l = pkt->hash; 1200 GSList *l = pkt->hash;
1133 const char *msg = NULL; 1201 const char *msg = NULL;
1202 int protocol = 0;
1134 1203
1135 account = purple_connection_get_account(gc); 1204 account = purple_connection_get_account(gc);
1136 1205
1137 /* Buddy authorized/declined our addition */ 1206 /* Buddy authorized/declined our addition */
1138 if (pkt->status == 1) { 1207 if (pkt->status == 1) {
1139 const char *who = NULL; 1208 char *temp = NULL;
1209 char *who = NULL;
1140 int response = 0; 1210 int response = 0;
1141 1211
1142 while (l) { 1212 while (l) {
1143 struct yahoo_pair *pair = l->data; 1213 struct yahoo_pair *pair = l->data;
1144 1214
1145 switch (pair->key) { 1215 switch (pair->key) {
1146 case 4: 1216 case 4:
1147 who = pair->value; 1217 temp = pair->value;
1148 break; 1218 break;
1149 case 13: 1219 case 13:
1150 response = strtol(pair->value, NULL, 10); 1220 response = strtol(pair->value, NULL, 10);
1151 break; 1221 break;
1152 case 14: 1222 case 14:
1153 msg = pair->value; 1223 msg = pair->value;
1154 break; 1224 break;
1225 case 241:
1226 protocol = strtol(pair->value, NULL, 10);
1227 break;
1155 } 1228 }
1156 l = l->next; 1229 l = l->next;
1157 } 1230 }
1231
1232 if(protocol == 0)
1233 who = temp;
1234 else if(protocol == 2)
1235 who = g_strconcat("wlm/", temp, NULL);
1158 1236
1159 if (response == 1) /* Authorized */ 1237 if (response == 1) /* Authorized */
1160 purple_debug_info("yahoo", "Received authorization from buddy '%s'.\n", who ? who : "(Unknown Buddy)"); 1238 purple_debug_info("yahoo", "Received authorization from buddy '%s'.\n", who ? who : "(Unknown Buddy)");
1161 else if (response == 2) { /* Declined */ 1239 else if (response == 2) { /* Declined */
1162 purple_debug_info("yahoo", "Received authorization decline from buddy '%s'.\n", who ? who : "(Unknown Buddy)"); 1240 purple_debug_info("yahoo", "Received authorization decline from buddy '%s'.\n", who ? who : "(Unknown Buddy)");
1163 yahoo_buddy_denied_our_add(gc, who, msg); 1241 yahoo_buddy_denied_our_add(gc, who, msg);
1164 } else 1242 } else
1165 purple_debug_error("yahoo", "Received unknown authorization response of %d from buddy '%s'.\n", response, who ? who : "(Unknown Buddy)"); 1243 purple_debug_error("yahoo", "Received unknown authorization response of %d from buddy '%s'.\n", response, who ? who : "(Unknown Buddy)");
1166 1244 g_free(who);
1167 } 1245 }
1168 /* Buddy requested authorization to add us. */ 1246 /* Buddy requested authorization to add us. */
1169 else if (pkt->status == 3) { 1247 else if (pkt->status == 3) {
1170 struct yahoo_add_request *add_req; 1248 struct yahoo_add_request *add_req;
1171 const char *firstname = NULL, *lastname = NULL; 1249 const char *firstname = NULL, *lastname = NULL;
1250 char *temp = NULL;
1172 1251
1173 add_req = g_new0(struct yahoo_add_request, 1); 1252 add_req = g_new0(struct yahoo_add_request, 1);
1174 add_req->gc = gc; 1253 add_req->gc = gc;
1175 1254
1176 while (l) { 1255 while (l) {
1177 struct yahoo_pair *pair = l->data; 1256 struct yahoo_pair *pair = l->data;
1178 1257
1179 switch (pair->key) { 1258 switch (pair->key) {
1180 case 4: 1259 case 4:
1260 temp = pair->value;
1181 add_req->who = g_strdup(pair->value); 1261 add_req->who = g_strdup(pair->value);
1182 break; 1262 break;
1183 case 5: 1263 case 5:
1184 add_req->id = g_strdup(pair->value); 1264 add_req->id = g_strdup(pair->value);
1185 break; 1265 break;
1197 break; 1277 break;
1198 1278
1199 } 1279 }
1200 l = l->next; 1280 l = l->next;
1201 } 1281 }
1282 if(add_req->protocol == 2)
1283 add_req->who = g_strconcat("wlm/", temp, NULL);
1284 else
1285 add_req->who = g_strdup(temp);
1202 1286
1203 if (add_req->id && add_req->who) { 1287 if (add_req->id && add_req->who) {
1204 char *alias = NULL, *dec_msg = NULL; 1288 char *alias = NULL, *dec_msg = NULL;
1205 1289
1206 if (!purple_privacy_check(account, add_req->who)) 1290 if (!purple_privacy_check(account, add_req->who))
2282 2366
2283 static void yahoo_process_addbuddy(PurpleConnection *gc, struct yahoo_packet *pkt) 2367 static void yahoo_process_addbuddy(PurpleConnection *gc, struct yahoo_packet *pkt)
2284 { 2368 {
2285 int err = 0; 2369 int err = 0;
2286 char *who = NULL; 2370 char *who = NULL;
2371 char *temp = NULL;
2287 char *group = NULL; 2372 char *group = NULL;
2288 char *decoded_group; 2373 char *decoded_group;
2289 char *buf; 2374 char *buf;
2290 YahooFriend *f; 2375 YahooFriend *f;
2291 GSList *l = pkt->hash; 2376 GSList *l = pkt->hash;
2292 struct yahoo_data *yd = gc->proto_data; 2377 struct yahoo_data *yd = gc->proto_data;
2293 int protocol = 0; 2378 int protocol = 0;
2379 gboolean wlm = FALSE;
2294 2380
2295 while (l) { 2381 while (l) {
2296 struct yahoo_pair *pair = l->data; 2382 struct yahoo_pair *pair = l->data;
2297 2383
2298 switch (pair->key) { 2384 switch (pair->key) {
2299 case 66: 2385 case 66:
2300 err = strtol(pair->value, NULL, 10); 2386 err = strtol(pair->value, NULL, 10);
2301 break; 2387 break;
2302 case 7: 2388 case 7:
2303 who = pair->value; 2389 temp = pair->value;
2304 break; 2390 break;
2305 case 65: 2391 case 65:
2306 group = pair->value; 2392 group = pair->value;
2307 break; 2393 break;
2308 case 241: 2394 case 241:
2309 protocol = strtol(pair->value, NULL, 10); 2395 protocol = strtol(pair->value, NULL, 10);
2396 if(protocol == 2)
2397 wlm = TRUE;
2310 break; 2398 break;
2311 } 2399 }
2312 2400
2313 l = l->next; 2401 l = l->next;
2314 } 2402 }
2315 2403
2316 if (!who) 2404 if (!temp)
2317 return; 2405 return;
2318 if (!group) 2406 if (!group)
2319 group = ""; 2407 group = "";
2408
2409 if(wlm)
2410 who = g_strconcat("wlm/", temp, NULL);
2411 else
2412 who = g_strdup(temp);
2320 2413
2321 if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */ 2414 if (!err || (err == 2)) { /* 0 = ok, 2 = already on serv list */
2322 f = yahoo_friend_find_or_new(gc, who); 2415 f = yahoo_friend_find_or_new(gc, who);
2323 yahoo_update_status(gc, who, f); 2416 yahoo_update_status(gc, who, f);
2324 if(protocol) 2417 if(protocol)
2325 f->protocol = protocol; 2418 f->protocol = protocol;
2326 2419
2327 if( !g_hash_table_lookup(yd->peers, who) ) { 2420 if( !g_hash_table_lookup(yd->peers, who) ) {
2328 /* we are not connected as client, so set friend to not connected */ 2421 /* we are not connected as client, so set friend to not connected */
2329 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED); 2422 if(wlm)
2330 f->p2p_packet_sent = 0; 2423 yahoo_friend_set_p2p_status(f,YAHOO_P2PSTATUS_DO_NOT_CONNECT);
2424 else {
2425 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_NOT_CONNECTED);
2426 f->p2p_packet_sent = 0;
2427 }
2331 } 2428 }
2332 else /* we are already connected. set friend to YAHOO_P2PSTATUS_WE_ARE_CLIENT */ 2429 else /* we are already connected. set friend to YAHOO_P2PSTATUS_WE_ARE_CLIENT */
2333 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT); 2430 yahoo_friend_set_p2p_status(f, YAHOO_P2PSTATUS_WE_ARE_CLIENT);
2334 return; 2431 return;
2335 } 2432 }
2339 who, decoded_group, purple_connection_get_display_name(gc)); 2436 who, decoded_group, purple_connection_get_display_name(gc));
2340 if (!purple_conv_present_error(who, purple_connection_get_account(gc), buf)) 2437 if (!purple_conv_present_error(who, purple_connection_get_account(gc), buf))
2341 purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); 2438 purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf);
2342 g_free(buf); 2439 g_free(buf);
2343 g_free(decoded_group); 2440 g_free(decoded_group);
2441 g_free(who);
2344 } 2442 }
2345 2443
2346 /* write pkt to the source */ 2444 /* write pkt to the source */
2347 static void yahoo_p2p_write_pkt(gint source, struct yahoo_packet *pkt) 2445 static void yahoo_p2p_write_pkt(gint source, struct yahoo_packet *pkt)
2348 { 2446 {
4336 gboolean utf8 = TRUE; 4434 gboolean utf8 = TRUE;
4337 PurpleWhiteboard *wb; 4435 PurpleWhiteboard *wb;
4338 int ret = 1; 4436 int ret = 1;
4339 YahooFriend *f = NULL; 4437 YahooFriend *f = NULL;
4340 struct yahoo_p2p_data *p2p_data; 4438 struct yahoo_p2p_data *p2p_data;
4341 4439 gboolean wlm = FALSE;
4342 msg2 = yahoo_string_encode(gc, msg, &utf8); 4440 msg2 = yahoo_string_encode(gc, msg, &utf8);
4441
4442 wlm = g_str_has_prefix(who, "wlm/") || g_str_has_prefix(who, "WLM/");
4343 4443
4344 if( strncmp(who, "+", 1) == 0 ) { 4444 if( strncmp(who, "+", 1) == 0 ) {
4345 /* we have an sms to be sent */ 4445 /* we have an sms to be sent */
4346 gchar *carrier = NULL; 4446 gchar *carrier = NULL;
4347 const char *alias = NULL; 4447 const char *alias = NULL;
4389 4489
4390 return ret; 4490 return ret;
4391 } 4491 }
4392 4492
4393 pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); 4493 pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0);
4394 yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who); 4494 if(wlm) {
4395 if ((f = yahoo_friend_find(gc, who)) && f->protocol) 4495 yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who+4);
4396 yahoo_packet_hash_int(pkt, 241, f->protocol); 4496 yahoo_packet_hash_int(pkt, 241, 2);
4397 else 4497 }
4398 if(strchr(who,'@')) 4498 else {
4399 yahoo_packet_hash_int(pkt, 241, 2); 4499 yahoo_packet_hash(pkt, "ss", 1, purple_connection_get_display_name(gc), 5, who);
4500 if ((f = yahoo_friend_find(gc, who)) && f->protocol)
4501 yahoo_packet_hash_int(pkt, 241, f->protocol);
4502 }
4400 4503
4401 if (utf8) 4504 if (utf8)
4402 yahoo_packet_hash_str(pkt, 97, "1"); 4505 yahoo_packet_hash_str(pkt, 97, "1");
4403 yahoo_packet_hash_str(pkt, 14, msg2); 4506 yahoo_packet_hash_str(pkt, 14, msg2);
4404 4507
4435 yahoo_packet_hash_str(pkt, 206, "2"); 4538 yahoo_packet_hash_str(pkt, 206, "2");
4436 4539
4437 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */ 4540 /* We may need to not send any packets over 2000 bytes, but I'm not sure yet. */
4438 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) { 4541 if ((YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt)) <= 2000) {
4439 /* if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p */ 4542 /* if p2p link exists, send through it. To-do: key 15, time value to be sent in case of p2p */
4440 if( (p2p_data = g_hash_table_lookup(yd->peers, who)) ) { 4543 if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !wlm ) {
4441 yahoo_packet_hash_int(pkt, 11, p2p_data->session_id); 4544 yahoo_packet_hash_int(pkt, 11, p2p_data->session_id);
4442 yahoo_p2p_write_pkt(p2p_data->source, pkt); 4545 yahoo_p2p_write_pkt(p2p_data->source, pkt);
4443 } 4546 }
4444 else { 4547 else {
4445 yahoo_packet_send(pkt, yd); 4548 yahoo_packet_send(pkt, yd);
4446 yahoo_send_p2p_pkt(gc, who, 0); /* send p2p packet, with val_13=0 */ 4549 if(!wlm)
4550 yahoo_send_p2p_pkt(gc, who, 0); /* send p2p packet, with val_13=0 */
4447 } 4551 }
4448 } 4552 }
4449 else 4553 else
4450 ret = -E2BIG; 4554 ret = -E2BIG;
4451 4555
4459 4563
4460 static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state) 4564 static unsigned int yahoo_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState state)
4461 { 4565 {
4462 struct yahoo_data *yd = gc->proto_data; 4566 struct yahoo_data *yd = gc->proto_data;
4463 struct yahoo_p2p_data *p2p_data; 4567 struct yahoo_p2p_data *p2p_data;
4464 4568 gboolean wlm = (g_str_has_prefix(who, "wlm/") || g_str_has_prefix(who, "WLM/"));
4465 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); 4569 struct yahoo_packet *pkt = NULL;
4466 4570
4467 /* Don't do anything if sms is being typed */ 4571 /* Don't do anything if sms is being typed */
4468 if( strncmp(who, "+", 1) == 0 ) 4572 if( strncmp(who, "+", 1) == 0 )
4469 return 0; 4573 return 0;
4470 4574
4575 pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0);
4576
4471 /* check to see if p2p link exists, send through it */ 4577 /* check to see if p2p link exists, send through it */
4472 if( (p2p_data = g_hash_table_lookup(yd->peers, who)) ) { 4578 if( (p2p_data = g_hash_table_lookup(yd->peers, who)) && !wlm ) {
4473 yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc), 4579 yahoo_packet_hash(pkt, "sssssis", 49, "TYPING", 1, purple_connection_get_display_name(gc),
4474 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", 4580 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
4475 5, who, 11, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */ 4581 5, who, 11, p2p_data->session_id, 1002, "1"); /* To-do: key 15 to be sent in case of p2p */
4476 yahoo_p2p_write_pkt(p2p_data->source, pkt); 4582 yahoo_p2p_write_pkt(p2p_data->source, pkt);
4477 yahoo_packet_free(pkt); 4583 yahoo_packet_free(pkt);
4478 } 4584 }
4479 else { /* send through yahoo server */ 4585 else { /* send through yahoo server */
4480 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc), 4586 if(wlm)
4587 yahoo_packet_hash(pkt, "sssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc),
4481 14, " ", 13, state == PURPLE_TYPING ? "1" : "0", 4588 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
4482 5, who, 1002, "1"); 4589 5, who+4, 1002, "1", 241, "2");
4590 else
4591 yahoo_packet_hash(pkt, "ssssss", 49, "TYPING", 1, purple_connection_get_display_name(gc),
4592 14, " ", 13, state == PURPLE_TYPING ? "1" : "0",
4593 5, who+4, 1002, "1");
4483 yahoo_packet_send_and_free(pkt, yd); 4594 yahoo_packet_send_and_free(pkt, yd);
4484 } 4595 }
4485 4596
4486 return 0; 4597 return 0;
4487 } 4598 }
4712 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; 4823 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data;
4713 struct yahoo_packet *pkt; 4824 struct yahoo_packet *pkt;
4714 const char *group = NULL; 4825 const char *group = NULL;
4715 char *group2; 4826 char *group2;
4716 YahooFriend *f; 4827 YahooFriend *f;
4828 gboolean wlm = FALSE;
4717 4829
4718 if (!yd->logged_in) 4830 if (!yd->logged_in)
4719 return; 4831 return;
4832
4833 wlm = g_str_has_prefix(buddy->name, "wlm/") || g_str_has_prefix(buddy->name, "WLM/");
4720 4834
4721 if (!purple_privacy_check(purple_connection_get_account(gc), 4835 if (!purple_privacy_check(purple_connection_get_account(gc),
4722 purple_buddy_get_name(buddy))) 4836 purple_buddy_get_name(buddy)))
4723 return; 4837 return;
4724 4838
4730 else 4844 else
4731 group = "Buddies"; 4845 group = "Buddies";
4732 4846
4733 group2 = yahoo_string_encode(gc, group, NULL); 4847 group2 = yahoo_string_encode(gc, group, NULL);
4734 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); 4848 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0);
4735 if(strchr(buddy->name, '@')) { 4849 if(wlm) {
4736 yahoo_packet_hash(pkt, "sssssssssss", 4850 yahoo_packet_hash(pkt, "sssssssssss",
4737 14, "", 4851 14, "",
4738 65, group2, 4852 65, group2,
4739 97, "1", 4853 97, "1",
4740 1, purple_connection_get_display_name(gc), 4854 1, purple_connection_get_display_name(gc),
4741 302, "319", 4855 302, "319",
4742 300, "319", 4856 300, "319",
4743 7, buddy->name, 4857 7, buddy->name + 4,
4744 241, "2", 4858 241, "2",
4745 334, "0", 4859 334, "0",
4746 301, "319", 4860 301, "319",
4747 303, "319" 4861 303, "319"
4748 ); 4862 );
4760 301, "319", 4874 301, "319",
4761 303, "319" 4875 303, "319"
4762 ); 4876 );
4763 } 4877 }
4764 4878
4765 if (f && f->protocol)
4766 yahoo_packet_hash_int(pkt, 241, f->protocol);
4767 yahoo_packet_send_and_free(pkt, yd); 4879 yahoo_packet_send_and_free(pkt, yd);
4768 g_free(group2); 4880 g_free(group2);
4769 } 4881 }
4770 4882
4771 static void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) 4883 static void yahoo_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
4775 GSList *buddies, *l; 4887 GSList *buddies, *l;
4776 PurpleGroup *g; 4888 PurpleGroup *g;
4777 gboolean remove = TRUE; 4889 gboolean remove = TRUE;
4778 char *cg; 4890 char *cg;
4779 YahooFriend *f = yahoo_friend_find(gc, buddy->name); 4891 YahooFriend *f = yahoo_friend_find(gc, buddy->name);
4892 gboolean wlm = FALSE;
4780 4893
4781 if (!f) 4894 if (!f)
4782 return; 4895 return;
4783 4896
4784 buddies = purple_find_buddies(purple_connection_get_account(gc), buddy->name); 4897 buddies = purple_find_buddies(purple_connection_get_account(gc), buddy->name);
4795 if (remove) 4908 if (remove)
4796 g_hash_table_remove(yd->friends, buddy->name); 4909 g_hash_table_remove(yd->friends, buddy->name);
4797 4910
4798 cg = yahoo_string_encode(gc, group->name, NULL); 4911 cg = yahoo_string_encode(gc, group->name, NULL);
4799 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); 4912 pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0);
4800 yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc), 4913
4914 if(f->protocol == 2)
4915 wlm = TRUE;
4916 if(wlm)
4917 yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc),
4918 7, buddy->name+4, 65, cg);
4919 else
4920 yahoo_packet_hash(pkt, "sss", 1, purple_connection_get_display_name(gc),
4801 7, buddy->name, 65, cg); 4921 7, buddy->name, 65, cg);
4802 if(f->protocol) 4922 if(f->protocol)
4803 yahoo_packet_hash_int(pkt, 241, f->protocol); 4923 yahoo_packet_hash_int(pkt, 241, f->protocol);
4804 yahoo_packet_send_and_free(pkt, yd); 4924 yahoo_packet_send_and_free(pkt, yd);
4805 g_free(cg); 4925 g_free(cg);