Mercurial > pidgin.yaz
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) |