comparison libpurple/protocols/msn/notification.c @ 25947:4b8c4870b13a

propagate from branch 'im.pidgin.pidgin.next.minor' (head 7305b29db7bd00d3261f348c71674c93aa31b327) to branch 'im.pidgin.pidgin' (head d8c03c68d591d9392607d954942ee58b8618d946)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Mon, 02 Mar 2009 04:18:40 +0000
parents fd5eedf131b4
children d51b8647d43c c9f179cfffaa
comparison
equal deleted inserted replaced
25946:8998ca47e6d0 25947:4b8c4870b13a
542 g_strfreev(tokens); 542 g_strfreev(tokens);
543 g_return_if_reached(); 543 g_return_if_reached();
544 } 544 }
545 545
546 /*find a domain Node*/ 546 /*find a domain Node*/
547 for(d_node = xmlnode_get_child(mlNode,"d"); d_node; d_node = xmlnode_get_next_twin(d_node)) 547 for (d_node = xmlnode_get_child(mlNode, "d"); d_node;
548 { 548 d_node = xmlnode_get_next_twin(d_node)) {
549 const char *attr = xmlnode_get_attrib(d_node,"n"); 549 const char *attr = xmlnode_get_attrib(d_node,"n");
550 if (attr == NULL) 550 if (attr == NULL)
551 continue; 551 continue;
552 if (!strcmp(attr,domain)) 552 if (!strcmp(attr, domain))
553 break; 553 break;
554 } 554 }
555 555
556 if(d_node == NULL) 556 if (d_node == NULL) {
557 {
558 /*domain not found, create a new domain Node*/ 557 /*domain not found, create a new domain Node*/
559 purple_debug_info("msn", "Didn't find existing domain node, adding one.\n"); 558 purple_debug_info("msn", "Didn't find existing domain node, adding one.\n");
560 d_node = xmlnode_new("d"); 559 d_node = xmlnode_new("d");
561 xmlnode_set_attrib(d_node, "n", domain); 560 xmlnode_set_attrib(d_node, "n", domain);
562 xmlnode_insert_child(mlNode, d_node); 561 xmlnode_insert_child(mlNode, d_node);
564 563
565 /*create contact node*/ 564 /*create contact node*/
566 c_node = xmlnode_new("c"); 565 c_node = xmlnode_new("c");
567 xmlnode_set_attrib(c_node, "n", email); 566 xmlnode_set_attrib(c_node, "n", email);
568 567
569 purple_debug_info("msn", "list_op: %d\n", list_op); 568 if (list_op != 0) {
570 g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op); 569 purple_debug_info("msn", "list_op: %d\n", list_op);
571 xmlnode_set_attrib(c_node, "l", fmt_str); 570 g_snprintf(fmt_str, sizeof(fmt_str), "%d", list_op);
572 571 xmlnode_set_attrib(c_node, "l", fmt_str);
573 if (networkId != MSN_NETWORK_UNKNOWN) 572 }
573
574 if (networkId != MSN_NETWORK_UNKNOWN) {
574 g_snprintf(fmt_str, sizeof(fmt_str), "%d", networkId); 575 g_snprintf(fmt_str, sizeof(fmt_str), "%d", networkId);
575 else if (msn_user_is_yahoo(session->account, passport)) 576 /*mobile*/
576 g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_NETWORK_YAHOO); 577 /*type_str = g_strdup_printf("4");*/
577 else 578 xmlnode_set_attrib(c_node, "t", fmt_str);
578 g_snprintf(fmt_str, sizeof(fmt_str), "%d", MSN_NETWORK_PASSPORT); 579 }
579
580 /*mobile*/
581 /*type_str = g_strdup_printf("4");*/
582 xmlnode_set_attrib(c_node, "t", fmt_str);
583 580
584 xmlnode_insert_child(d_node, c_node); 581 xmlnode_insert_child(d_node, c_node);
585 582
586 g_strfreev(tokens); 583 g_strfreev(tokens);
587 } 584 }
594 trans = msn_transaction_new(cmdproc, "ADL", "%i", payload_len); 591 trans = msn_transaction_new(cmdproc, "ADL", "%i", payload_len);
595 msn_transaction_set_payload(trans, payload, payload_len); 592 msn_transaction_set_payload(trans, payload, payload_len);
596 msn_cmdproc_send_trans(cmdproc, trans); 593 msn_cmdproc_send_trans(cmdproc, trans);
597 } 594 }
598 595
596 void
597 msn_notification_send_fqy(MsnSession *session,
598 const char *payload, int payload_len,
599 MsnFqyCb cb)
600 {
601 MsnTransaction *trans;
602 MsnCmdProc *cmdproc;
603
604 cmdproc = session->notification->cmdproc;
605
606 trans = msn_transaction_new(cmdproc, "FQY", "%d", payload_len);
607 msn_transaction_set_payload(trans, payload, payload_len);
608 msn_transaction_set_data(trans, cb);
609 msn_cmdproc_send_trans(cmdproc, trans);
610 }
611
612 static void
613 update_contact_network(MsnSession *session, const char *passport, MsnNetwork network)
614 {
615 MsnUser *user = msn_userlist_find_user(session->userlist, passport);
616 /* TODO: Also figure out how to update membership lists */
617 if (user) {
618 xmlnode *adl_node;
619 char *payload;
620 int payload_len;
621
622 msn_user_set_network(user, network);
623
624 adl_node = xmlnode_new("ml");
625 xmlnode_set_attrib(adl_node, "l", "1");
626 msn_add_contact_xml(session, adl_node, passport,
627 user->list_op & MSN_LIST_OP_MASK, network);
628 payload = xmlnode_to_str(adl_node, &payload_len);
629 msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
630
631 } else {
632 purple_debug_error("msn",
633 "Got FQY update for unkwown user %s on network %d.\n",
634 passport, network);
635 }
636 }
637
599 /*dump contact info to NS*/ 638 /*dump contact info to NS*/
600 void 639 void
601 msn_notification_dump_contact(MsnSession *session) 640 msn_notification_dump_contact(MsnSession *session)
602 { 641 {
603 MsnUser *user; 642 MsnUser *user;
604 GList *l; 643 GList *l;
605 xmlnode *adl_node; 644 xmlnode *adl_node;
645 xmlnode *fqy_node;
606 char *payload; 646 char *payload;
607 int payload_len; 647 int payload_len;
608 int adl_count = 0; 648 int adl_count = 0;
649 int fqy_count = 0;
609 const char *display_name; 650 const char *display_name;
610 651
611 adl_node = xmlnode_new("ml"); 652 adl_node = xmlnode_new("ml");
612 adl_node->child = NULL; 653 adl_node->child = NULL;
613 xmlnode_set_attrib(adl_node, "l", "1"); 654 xmlnode_set_attrib(adl_node, "l", "1");
655 fqy_node = xmlnode_new("ml");
614 656
615 /*get the userlist*/ 657 /*get the userlist*/
616 for (l = session->userlist->users; l != NULL; l = l->next) { 658 for (l = session->userlist->users; l != NULL; l = l->next) {
617 user = l->data; 659 user = l->data;
618 660
621 continue; 663 continue;
622 664
623 if (user->passport && !strcmp(user->passport, "messenger@microsoft.com")) 665 if (user->passport && !strcmp(user->passport, "messenger@microsoft.com"))
624 continue; 666 continue;
625 667
626 msn_add_contact_xml(session, adl_node, user->passport, 668 if ((user->list_op & MSN_LIST_OP_MASK) == (MSN_LIST_AL_OP | MSN_LIST_BL_OP)) {
627 user->list_op & MSN_LIST_OP_MASK, user->networkid); 669 /* The server will complain if we send it a user on both the
628 670 Allow and Block lists. So assume they're on the Block list
629 /* each ADL command may contain up to 150 contacts */ 671 and remove them from the Allow list in the membership lists to
630 if (++adl_count % 150 == 0 || l->next == NULL) { 672 stop this from happening again. */
631 payload = xmlnode_to_str(adl_node,&payload_len); 673 purple_debug_warning("msn",
632 674 "User %s is on both Allow and Block list,"
633 msn_notification_post_adl(session->notification->cmdproc, 675 "removing from Allow list.\n",
634 payload, payload_len); 676 user->passport);
635 677 msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL);
636 g_free(payload); 678 }
637 xmlnode_free(adl_node); 679
638 680 if (user->networkid != MSN_NETWORK_UNKNOWN) {
639 if (l->next) { 681 msn_add_contact_xml(session, adl_node, user->passport,
682 user->list_op & MSN_LIST_OP_MASK, user->networkid);
683
684 /* each ADL command may contain up to 150 contacts */
685 if (++adl_count % 150 == 0) {
686 payload = xmlnode_to_str(adl_node, &payload_len);
687
688 msn_notification_post_adl(session->notification->cmdproc,
689 payload, payload_len);
690
691 g_free(payload);
692 xmlnode_free(adl_node);
693
640 adl_node = xmlnode_new("ml"); 694 adl_node = xmlnode_new("ml");
641 adl_node->child = NULL; 695 adl_node->child = NULL;
642 xmlnode_set_attrib(adl_node, "l", "1"); 696 xmlnode_set_attrib(adl_node, "l", "1");
643 } 697 }
698 } else {
699 msn_add_contact_xml(session, fqy_node, user->passport,
700 0, user->networkid);
701
702 /* each FQY command may contain up to 150 contacts, probably */
703 if (++fqy_count % 150 == 0) {
704 payload = xmlnode_to_str(fqy_node, &payload_len);
705
706 msn_notification_send_fqy(session, payload, payload_len,
707 update_contact_network);
708
709 g_free(payload);
710 xmlnode_free(fqy_node);
711 fqy_node = xmlnode_new("ml");
712 }
644 } 713 }
645 } 714 }
646 715
647 if (adl_count == 0) { 716 /* Send the rest, or just an empty one to let the server set us online */
648 payload = xmlnode_to_str(adl_node,&payload_len); 717 if (adl_count == 0 || adl_count % 150 != 0) {
718 payload = xmlnode_to_str(adl_node, &payload_len);
649 719
650 msn_notification_post_adl(session->notification->cmdproc, payload, payload_len); 720 msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
651 721
652 g_free(payload); 722 g_free(payload);
653 xmlnode_free(adl_node); 723 }
654 } 724
725 if (fqy_count % 150 != 0) {
726 payload = xmlnode_to_str(fqy_node, &payload_len);
727
728 msn_notification_send_fqy(session, payload, payload_len,
729 update_contact_network);
730
731 g_free(payload);
732 }
733
734 xmlnode_free(adl_node);
735 xmlnode_free(fqy_node);
655 736
656 display_name = purple_connection_get_display_name(session->account->gc); 737 display_name = purple_connection_get_display_name(session->account->gc);
657 if (display_name 738 if (display_name
658 && strcmp(display_name, 739 && strcmp(display_name,
659 purple_account_get_username(session->account))) { 740 purple_account_get_username(session->account))) {
660 msn_act_id(session->account->gc, display_name); 741 msn_act_id(session->account->gc, display_name);
661 } 742 }
662 743
663 }
664
665 /*Post FQY to NS,Inform add a Yahoo User*/
666 void
667 msn_notification_send_fqy(MsnSession *session, const char *passport)
668 {
669 MsnTransaction *trans;
670 MsnCmdProc *cmdproc;
671 char* email,*domain,*payload;
672 char **tokens;
673
674 cmdproc = session->notification->cmdproc;
675
676 tokens = g_strsplit(passport, "@", 2);
677 email = tokens[0];
678 domain = tokens[1];
679
680 payload = g_strdup_printf("<ml><d n=\"%s\"><c n=\"%s\"/></d></ml>", domain, email);
681 trans = msn_transaction_new(cmdproc, "FQY","%" G_GSIZE_FORMAT, strlen(payload));
682 msn_transaction_set_payload(trans, payload, strlen(payload));
683 msn_cmdproc_send_trans(cmdproc, trans);
684
685 g_free(payload);
686 g_strfreev(tokens);
687 } 744 }
688 745
689 static void 746 static void
690 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 747 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
691 { 748 {
847 904
848 static void 905 static void
849 fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, 906 fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
850 size_t len) 907 size_t len)
851 { 908 {
852 MsnUserList *userlist; 909 MsnSession *session;
853 xmlnode *ml, *d, *c; 910 xmlnode *ml, *d, *c;
854 const char *domain; 911 const char *domain;
855 const char *local; 912 const char *local;
856 const char *type; 913 const char *type;
857 char *passport; 914 char *passport;
858 MsnNetwork network = MSN_NETWORK_PASSPORT; 915 MsnNetwork network = MSN_NETWORK_PASSPORT;
859 916
860 userlist = cmdproc->session->userlist; 917 session = cmdproc->session;
861 918
862 /* FQY response: 919 /* FQY response:
863 <ml><d n="domain.com"><c n="local-node" t="network" /></d></ml> */ 920 <ml><d n="domain.com"><c n="local-node" t="network" /></d></ml> */
864 ml = xmlnode_from_str(payload, len); 921 ml = xmlnode_from_str(payload, len);
865 d = xmlnode_get_child(ml, "d"); 922 for (d = xmlnode_get_child(ml, "d");
866 c = xmlnode_get_child(d, "c"); 923 d != NULL;
867 domain = xmlnode_get_attrib(d, "n"); 924 d = xmlnode_get_next_twin(d)) {
868 local = xmlnode_get_attrib(c, "n"); 925 domain = xmlnode_get_attrib(d, "n");
869 type = xmlnode_get_attrib(c, "t"); 926 for (c = xmlnode_get_child(d, "c");
870 927 c != NULL;
871 passport = g_strdup_printf("%s@%s", local, domain); 928 c = xmlnode_get_next_twin(c)) {
872 929 local = xmlnode_get_attrib(c, "n");
873 if (type != NULL) 930 type = xmlnode_get_attrib(c, "t");
874 network = (MsnNetwork)strtoul(type, NULL, 10); 931
875 purple_debug_info("msn", "FQY response says %s is from network %d\n", 932 passport = g_strdup_printf("%s@%s", local, domain);
876 passport, network); 933
877 msn_userlist_add_pending_buddy(userlist, passport, network); 934 if (type != NULL)
878 935 network = (MsnNetwork)strtoul(type, NULL, 10);
879 g_free(passport); 936 else
937 network = MSN_NETWORK_PASSPORT;
938
939 purple_debug_info("msn", "FQY response says %s is from network %d\n",
940 passport, network);
941 if (cmd->trans->data)
942 ((MsnFqyCb)cmd->trans->data)(session, passport, network);
943
944 g_free(passport);
945 }
946 }
947
880 xmlnode_free(ml); 948 xmlnode_free(ml);
881 } 949 }
882 950
883 static void 951 static void
884 fqy_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 952 fqy_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
1092 } else { 1160 } else {
1093 purple_debug_warning("msn", "Received ILN with unknown number of parameters.\n"); 1161 purple_debug_warning("msn", "Received ILN with unknown number of parameters.\n");
1094 return; 1162 return;
1095 } 1163 }
1096 1164
1097 serv_got_alias(gc, passport, friendly); 1165 if (msn_user_set_friendly_name(user, friendly)) {
1098 msn_user_set_friendly_name(user, friendly); 1166 serv_got_alias(gc, passport, friendly);
1167 msn_update_contact(session, passport, MSN_UPDATE_DISPLAY, friendly);
1168 }
1099 g_free(friendly); 1169 g_free(friendly);
1100 1170
1101 msn_user_set_object(user, msnobj); 1171 msn_user_set_object(user, msnobj);
1102 1172
1103 user->mobile = (clientid & MSN_CLIENT_CAP_MSNMOBILE) || (user->phone.mobile && user->phone.mobile[0] == '+'); 1173 user->mobile = (clientid & MSN_CLIENT_CAP_MSNMOBILE) || (user->phone.mobile && user->phone.mobile[0] == '+');
1218 PurpleConnection *gc; 1288 PurpleConnection *gc;
1219 MsnUser *user; 1289 MsnUser *user;
1220 MsnObject *msnobj; 1290 MsnObject *msnobj;
1221 unsigned long clientid; 1291 unsigned long clientid;
1222 int networkid; 1292 int networkid;
1223 const char *state, *passport, *friendly, *old_friendly; 1293 const char *state, *passport, *friendly;
1224 1294
1225 session = cmdproc->session; 1295 session = cmdproc->session;
1226 account = session->account; 1296 account = session->account;
1227 gc = purple_account_get_connection(account); 1297 gc = purple_account_get_connection(account);
1228 1298
1232 friendly = purple_url_decode(cmd->params[3]); 1302 friendly = purple_url_decode(cmd->params[3]);
1233 1303
1234 user = msn_userlist_find_user(session->userlist, passport); 1304 user = msn_userlist_find_user(session->userlist, passport);
1235 if (user == NULL) return; 1305 if (user == NULL) return;
1236 1306
1237 old_friendly = msn_user_get_friendly_name(user); 1307 if (msn_user_set_friendly_name(user, friendly))
1238 if (!old_friendly || (old_friendly && (!friendly || strcmp(old_friendly, friendly))))
1239 { 1308 {
1240 serv_got_alias(gc, passport, friendly); 1309 serv_got_alias(gc, passport, friendly);
1241 msn_user_set_friendly_name(user, friendly); 1310 msn_update_contact(session, passport, MSN_UPDATE_DISPLAY, friendly);
1242 } 1311 }
1243 1312
1244 if (cmd->param_count == 6) 1313 if (cmd->param_count == 6)
1245 { 1314 {
1246 msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[5])); 1315 msnobj = msn_object_new_from_string(purple_url_decode(cmd->params[5]));
1616 passport, str); 1685 passport, str);
1617 g_free(str); 1686 g_free(str);
1618 return; 1687 return;
1619 } 1688 }
1620 1689
1621 psm_str = msn_get_psm(cmd->payload,len); 1690 if (len != 0) {
1622 msn_user_set_statusline(user, psm_str); 1691 psm_str = msn_get_psm(cmd->payload,len);
1623 g_free(psm_str); 1692 msn_user_set_statusline(user, psm_str);
1624 1693 g_free(psm_str);
1625 str = msn_get_currentmedia(cmd->payload, len); 1694
1626 if (msn_parse_currentmedia(str, &media)) 1695 str = msn_get_currentmedia(cmd->payload, len);
1627 msn_user_set_currentmedia(user, &media); 1696 if (msn_parse_currentmedia(str, &media))
1628 else 1697 msn_user_set_currentmedia(user, &media);
1698 else
1699 msn_user_set_currentmedia(user, NULL);
1700 g_free(media.title);
1701 g_free(media.album);
1702 g_free(media.artist);
1703 g_free(str);
1704
1705 } else {
1706 msn_user_set_statusline(user, NULL);
1629 msn_user_set_currentmedia(user, NULL); 1707 msn_user_set_currentmedia(user, NULL);
1630 g_free(media.title); 1708 }
1631 g_free(media.album);
1632 g_free(media.artist);
1633 g_free(str);
1634 1709
1635 msn_user_update(user); 1710 msn_user_update(user);
1636 } 1711 }
1637 1712
1638 static void 1713 static void
2093 "text/x-msmsgsactivemailnotification", 2168 "text/x-msmsgsactivemailnotification",
2094 delete_oim_msg); 2169 delete_oim_msg);
2095 msn_table_add_msg_type(cbs_table, 2170 msn_table_add_msg_type(cbs_table,
2096 "application/x-msmsgssystemmessage", 2171 "application/x-msmsgssystemmessage",
2097 system_msg); 2172 system_msg);
2173 /* generic message handlers */
2174 msn_table_add_msg_type(cbs_table, "text/plain",
2175 msn_plain_msg);
2176 msn_table_add_msg_type(cbs_table, "text/x-msmsgscontrol",
2177 msn_control_msg);
2178 msn_table_add_msg_type(cbs_table, "text/x-msnmsgr-datacast",
2179 msn_datacast_msg);
2098 } 2180 }
2099 2181
2100 void 2182 void
2101 msn_notification_end(void) 2183 msn_notification_end(void)
2102 { 2184 {