comparison libpurple/protocols/msn/notification.c @ 25172:fd5eedf131b4

Generalize the FQY command so it can be used by different callbacks based on the place that called it. Then automatically call an FQY when sending the buddy list ADL's for a buddy with an unknown network. Then we can send a corrected ADL later with the network from the FQY. This should make it easier for people with OCS/Yahoo contacts that were added incorrectly by previous versions, as they shouldn't need to mess with their address book outside of Pidgin (but if there are multiple buddy copies, that may need fixing externally). I should probably figure out how to permanently fix the Membership lists, eventually. References #6755. References #3322
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 27 Feb 2009 07:13:20 +0000
parents 9398f0f2cdc6
children c9f179cfffaa d51b8647d43c
comparison
equal deleted inserted replaced
25169:14b927f45ec5 25172:fd5eedf131b4
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
633 "removing from Allow list.\n", 675 "removing from Allow list.\n",
634 user->passport); 676 user->passport);
635 msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL); 677 msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL);
636 } 678 }
637 679
638 msn_add_contact_xml(session, adl_node, user->passport, 680 if (user->networkid != MSN_NETWORK_UNKNOWN) {
639 user->list_op & MSN_LIST_OP_MASK, user->networkid); 681 msn_add_contact_xml(session, adl_node, user->passport,
640 682 user->list_op & MSN_LIST_OP_MASK, user->networkid);
641 /* each ADL command may contain up to 150 contacts */ 683
642 if (++adl_count % 150 == 0 || l->next == NULL) { 684 /* each ADL command may contain up to 150 contacts */
643 payload = xmlnode_to_str(adl_node,&payload_len); 685 if (++adl_count % 150 == 0) {
644 686 payload = xmlnode_to_str(adl_node, &payload_len);
645 msn_notification_post_adl(session->notification->cmdproc, 687
646 payload, payload_len); 688 msn_notification_post_adl(session->notification->cmdproc,
647 689 payload, payload_len);
648 g_free(payload); 690
649 xmlnode_free(adl_node); 691 g_free(payload);
650 692 xmlnode_free(adl_node);
651 if (l->next) { 693
652 adl_node = xmlnode_new("ml"); 694 adl_node = xmlnode_new("ml");
653 adl_node->child = NULL; 695 adl_node->child = NULL;
654 xmlnode_set_attrib(adl_node, "l", "1"); 696 xmlnode_set_attrib(adl_node, "l", "1");
655 } 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 }
656 } 713 }
657 } 714 }
658 715
659 if (adl_count == 0) { 716 /* Send the rest, or just an empty one to let the server set us online */
660 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);
661 719
662 msn_notification_post_adl(session->notification->cmdproc, payload, payload_len); 720 msn_notification_post_adl(session->notification->cmdproc, payload, payload_len);
663 721
664 g_free(payload); 722 g_free(payload);
665 xmlnode_free(adl_node); 723 }
666 } 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);
667 736
668 display_name = purple_connection_get_display_name(session->account->gc); 737 display_name = purple_connection_get_display_name(session->account->gc);
669 if (display_name 738 if (display_name
670 && strcmp(display_name, 739 && strcmp(display_name,
671 purple_account_get_username(session->account))) { 740 purple_account_get_username(session->account))) {
672 msn_act_id(session->account->gc, display_name); 741 msn_act_id(session->account->gc, display_name);
673 } 742 }
674 743
675 }
676
677 /*Post FQY to NS,Inform add a Yahoo User*/
678 void
679 msn_notification_send_fqy(MsnSession *session, const char *passport)
680 {
681 MsnTransaction *trans;
682 MsnCmdProc *cmdproc;
683 char* email,*domain,*payload;
684 char **tokens;
685
686 cmdproc = session->notification->cmdproc;
687
688 tokens = g_strsplit(passport, "@", 2);
689 email = tokens[0];
690 domain = tokens[1];
691
692 payload = g_strdup_printf("<ml><d n=\"%s\"><c n=\"%s\"/></d></ml>", domain, email);
693 trans = msn_transaction_new(cmdproc, "FQY","%" G_GSIZE_FORMAT, strlen(payload));
694 msn_transaction_set_payload(trans, payload, strlen(payload));
695 msn_cmdproc_send_trans(cmdproc, trans);
696
697 g_free(payload);
698 g_strfreev(tokens);
699 } 744 }
700 745
701 static void 746 static void
702 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 747 blp_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
703 { 748 {
859 904
860 static void 905 static void
861 fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, 906 fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
862 size_t len) 907 size_t len)
863 { 908 {
864 MsnUserList *userlist; 909 MsnSession *session;
865 xmlnode *ml, *d, *c; 910 xmlnode *ml, *d, *c;
866 const char *domain; 911 const char *domain;
867 const char *local; 912 const char *local;
868 const char *type; 913 const char *type;
869 char *passport; 914 char *passport;
870 MsnNetwork network = MSN_NETWORK_PASSPORT; 915 MsnNetwork network = MSN_NETWORK_PASSPORT;
871 916
872 userlist = cmdproc->session->userlist; 917 session = cmdproc->session;
873 918
874 /* FQY response: 919 /* FQY response:
875 <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> */
876 ml = xmlnode_from_str(payload, len); 921 ml = xmlnode_from_str(payload, len);
877 d = xmlnode_get_child(ml, "d"); 922 for (d = xmlnode_get_child(ml, "d");
878 c = xmlnode_get_child(d, "c"); 923 d != NULL;
879 domain = xmlnode_get_attrib(d, "n"); 924 d = xmlnode_get_next_twin(d)) {
880 local = xmlnode_get_attrib(c, "n"); 925 domain = xmlnode_get_attrib(d, "n");
881 type = xmlnode_get_attrib(c, "t"); 926 for (c = xmlnode_get_child(d, "c");
882 927 c != NULL;
883 passport = g_strdup_printf("%s@%s", local, domain); 928 c = xmlnode_get_next_twin(c)) {
884 929 local = xmlnode_get_attrib(c, "n");
885 if (type != NULL) 930 type = xmlnode_get_attrib(c, "t");
886 network = (MsnNetwork)strtoul(type, NULL, 10); 931
887 purple_debug_info("msn", "FQY response says %s is from network %d\n", 932 passport = g_strdup_printf("%s@%s", local, domain);
888 passport, network); 933
889 msn_userlist_add_pending_buddy(userlist, passport, network); 934 if (type != NULL)
890 935 network = (MsnNetwork)strtoul(type, NULL, 10);
891 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
892 xmlnode_free(ml); 948 xmlnode_free(ml);
893 } 949 }
894 950
895 static void 951 static void
896 fqy_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) 952 fqy_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)