Mercurial > pidgin
comparison libpurple/protocols/jabber/disco.c @ 26259:9d0bad6f4b0d
Add a node parameter to jabber_disco_items_do and use it in the new disco-listing code.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Tue, 31 Mar 2009 18:32:33 +0000 |
parents | b5fe3f47487b |
children | d6b2944f04b3 |
comparison
equal
deleted
inserted
replaced
26258:b5fe3f47487b | 26259:9d0bad6f4b0d |
---|---|
644 | 644 |
645 static void | 645 static void |
646 jabber_disco_service_info_cb(JabberStream *js, xmlnode *packet, gpointer data); | 646 jabber_disco_service_info_cb(JabberStream *js, xmlnode *packet, gpointer data); |
647 | 647 |
648 static void | 648 static void |
649 jabber_disco_service_items_cb(JabberStream *js, xmlnode *packet, gpointer data) | 649 jabber_disco_service_items_cb(JabberStream *js, const char *who, const char *node, |
650 { | 650 GSList *items, gpointer data) |
651 struct _disco_data *disco_data = data; | 651 { |
652 GSList *l; | |
653 struct _disco_data *disco_data; | |
652 struct jabber_disco_list_data *list_data; | 654 struct jabber_disco_list_data *list_data; |
653 PurpleDiscoList *list; | 655 PurpleDiscoList *list; |
654 PurpleDiscoService *parent = disco_data->parent; | 656 PurpleDiscoService *parent; |
655 const char *parent_node = disco_data->node; | 657 const char *parent_node; |
656 xmlnode *query = xmlnode_get_child(packet, "query"); | |
657 const char *from = xmlnode_get_attrib(packet, "from"); | |
658 const char *result = xmlnode_get_attrib(packet, "type"); | |
659 xmlnode *child; | |
660 gboolean has_items = FALSE; | 658 gboolean has_items = FALSE; |
661 | 659 |
660 disco_data = data; | |
662 list_data = disco_data->list_data; | 661 list_data = disco_data->list_data; |
663 list = list_data->list; | 662 list = list_data->list; |
664 | 663 |
665 --list_data->fetch_count; | 664 --list_data->fetch_count; |
666 | 665 |
669 jabber_disco_list_data_destroy(list_data); | 668 jabber_disco_list_data_destroy(list_data); |
670 | 669 |
671 return; | 670 return; |
672 } | 671 } |
673 | 672 |
674 if (!from || !result || !query || strcmp(result, "result") != 0) { | 673 if (items == NULL) { |
675 if (list_data->fetch_count == 0) | 674 if (list_data->fetch_count == 0) |
676 purple_disco_list_set_in_progress(list, FALSE); | 675 purple_disco_list_set_in_progress(list, FALSE); |
677 | 676 |
678 purple_disco_list_unref(list); | 677 purple_disco_list_unref(list); |
679 return; | 678 return; |
680 } | 679 } |
681 | 680 |
682 query = xmlnode_get_child(packet, "query"); | 681 parent = disco_data->parent; |
683 | 682 parent_node = disco_data->node; |
684 for(child = xmlnode_get_child(query, "item"); child; | 683 |
685 child = xmlnode_get_next_twin(child)) { | 684 for (l = items; l; l = l->next) { |
685 JabberDiscoItem *item = l->data; | |
686 JabberIq *iq; | 686 JabberIq *iq; |
687 xmlnode *q; | 687 struct _disco_data *req_data; |
688 const char *jid, *node; | |
689 struct _disco_data *disco_data; | |
690 char *full_node; | 688 char *full_node; |
691 | 689 |
692 if(!(jid = xmlnode_get_attrib(child, "jid")) || !purple_disco_list_get_protocol_data(list)) | |
693 continue; | |
694 | |
695 node = xmlnode_get_attrib(child, "node"); | |
696 | |
697 if (parent_node) { | 690 if (parent_node) { |
698 if (node) { | 691 if (item->node) { |
699 full_node = g_new0(char, strlen(parent_node) + 1 + strlen(node) + 1); | 692 full_node = g_strdup_printf("%s/%s", parent_node, item->node); |
700 strcat(full_node, parent_node); | |
701 strcat(full_node, "/"); | |
702 strcat(full_node, node); | |
703 } else { | 693 } else { |
704 continue; | 694 continue; |
705 } | 695 } |
706 } else { | 696 } else { |
707 full_node = g_strdup(node); | 697 full_node = g_strdup(item->node); |
708 } | 698 } |
709 | 699 |
710 disco_data = g_new0(struct _disco_data, 1); | 700 req_data = g_new0(struct _disco_data, 1); |
711 disco_data->list_data = list_data; | 701 req_data->list_data = list_data; |
712 disco_data->parent = parent; | 702 req_data->parent = parent; |
713 disco_data->node = full_node; | 703 req_data->node = full_node; |
714 | 704 |
715 has_items = TRUE; | 705 has_items = TRUE; |
706 | |
716 ++list_data->fetch_count; | 707 ++list_data->fetch_count; |
717 purple_disco_list_ref(list); | 708 purple_disco_list_ref(list); |
709 | |
718 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info"); | 710 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#info"); |
719 xmlnode_set_attrib(iq->node, "to", jid); | 711 xmlnode_set_attrib(iq->node, "to", item->jid); |
720 if (full_node && (q = xmlnode_get_child(iq->node, "query"))) | 712 if (full_node) |
721 xmlnode_set_attrib(q, "node", full_node); | 713 xmlnode_set_attrib(xmlnode_get_child(iq->node, "query"), |
722 jabber_iq_set_callback(iq, jabber_disco_service_info_cb, disco_data); | 714 "node", full_node); |
715 jabber_iq_set_callback(iq, jabber_disco_service_info_cb, req_data); | |
723 | 716 |
724 jabber_iq_send(iq); | 717 jabber_iq_send(iq); |
725 } | 718 } |
719 | |
720 g_slist_foreach(items, (GFunc)jabber_disco_item_free, NULL); | |
721 g_slist_free(items); | |
726 | 722 |
727 if (list_data->fetch_count == 0) | 723 if (list_data->fetch_count == 0) |
728 purple_disco_list_set_in_progress(list, FALSE); | 724 purple_disco_list_set_in_progress(list, FALSE); |
729 | 725 |
730 purple_disco_list_unref(list); | 726 purple_disco_list_unref(list); |
737 jabber_disco_service_info_cb(JabberStream *js, xmlnode *packet, gpointer data) | 733 jabber_disco_service_info_cb(JabberStream *js, xmlnode *packet, gpointer data) |
738 { | 734 { |
739 struct _disco_data *disco_data = data; | 735 struct _disco_data *disco_data = data; |
740 struct jabber_disco_list_data *list_data; | 736 struct jabber_disco_list_data *list_data; |
741 PurpleDiscoList *list; | 737 PurpleDiscoList *list; |
742 PurpleDiscoService *parent = disco_data->parent; | 738 PurpleDiscoService *parent; |
743 char *node = g_strdup(disco_data->node); | 739 char *node; |
744 xmlnode *query, *ident, *child; | 740 xmlnode *query, *ident, *child; |
745 const char *from = xmlnode_get_attrib(packet, "from"); | 741 const char *from = xmlnode_get_attrib(packet, "from"); |
746 const char *result = xmlnode_get_attrib(packet, "type"); | 742 const char *result = xmlnode_get_attrib(packet, "type"); |
747 const char *acat, *atype, *adesc, *anode; | 743 const char *acat, *atype, *adesc, *anode; |
748 char *aname; | 744 char *aname; |
751 PurpleDiscoServiceType type; | 747 PurpleDiscoServiceType type; |
752 PurpleDiscoServiceFlags flags = PURPLE_DISCO_ADD; | 748 PurpleDiscoServiceFlags flags = PURPLE_DISCO_ADD; |
753 | 749 |
754 list_data = disco_data->list_data; | 750 list_data = disco_data->list_data; |
755 list = list_data->list; | 751 list = list_data->list; |
756 | 752 parent = disco_data->parent; |
757 g_free(disco_data->node); | 753 |
754 node = disco_data->node; | |
755 disco_data->node = NULL; | |
758 g_free(disco_data); | 756 g_free(disco_data); |
759 | 757 |
760 --list_data->fetch_count; | 758 --list_data->fetch_count; |
761 | 759 |
762 if (list_data->list == NULL) { | 760 if (list_data->list == NULL) { |
818 s = purple_disco_list_service_new(cat, aname, type, adesc, flags); | 816 s = purple_disco_list_service_new(cat, aname, type, adesc, flags); |
819 purple_disco_list_service_add(list, s, parent); | 817 purple_disco_list_service_add(list, s, parent); |
820 | 818 |
821 /* if (flags & PURPLE_DISCO_FLAG_BROWSE) - not all browsable services has this future */ | 819 /* if (flags & PURPLE_DISCO_FLAG_BROWSE) - not all browsable services has this future */ |
822 { | 820 { |
823 xmlnode *q; | |
824 JabberIq *iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items"); | |
825 | |
826 ++list_data->fetch_count; | 821 ++list_data->fetch_count; |
827 purple_disco_list_ref(list); | 822 purple_disco_list_ref(list); |
828 disco_data = g_new0(struct _disco_data, 1); | 823 disco_data = g_new0(struct _disco_data, 1); |
829 disco_data->list_data = list_data; | 824 disco_data->list_data = list_data; |
830 disco_data->parent = s; | 825 disco_data->parent = s; |
831 | 826 |
832 xmlnode_set_attrib(iq->node, "to", from); | 827 jabber_disco_items_do(js, from, node, jabber_disco_service_items_cb, |
833 jabber_iq_set_callback(iq, jabber_disco_service_items_cb, disco_data); | 828 disco_data); |
834 if (anode && (q = xmlnode_get_child(iq->node, "query"))) | |
835 xmlnode_set_attrib(q, "node", node); | |
836 jabber_iq_send(iq); | |
837 } | 829 } |
838 | 830 |
839 if (list_data->fetch_count == 0) | 831 if (list_data->fetch_count == 0) |
840 purple_disco_list_set_in_progress(list, FALSE); | 832 purple_disco_list_set_in_progress(list, FALSE); |
841 | 833 |
1030 jabber_disco_items_cb(JabberStream *js, xmlnode *packet, gpointer data) | 1022 jabber_disco_items_cb(JabberStream *js, xmlnode *packet, gpointer data) |
1031 { | 1023 { |
1032 struct _jabber_disco_items_cb_data *jdicd; | 1024 struct _jabber_disco_items_cb_data *jdicd; |
1033 xmlnode *query, *child; | 1025 xmlnode *query, *child; |
1034 const char *from; | 1026 const char *from; |
1027 const char *node = NULL; | |
1035 const char *type; | 1028 const char *type; |
1036 GSList *items = NULL; | 1029 GSList *items = NULL; |
1037 | 1030 |
1038 jdicd = data; | 1031 jdicd = data; |
1039 | 1032 |
1040 from = xmlnode_get_attrib(packet, "from"); | 1033 from = xmlnode_get_attrib(packet, "from"); |
1041 type = xmlnode_get_attrib(packet, "type"); | 1034 type = xmlnode_get_attrib(packet, "type"); |
1042 query = xmlnode_get_child(packet, "query"); | 1035 query = xmlnode_get_child(packet, "query"); |
1043 | 1036 |
1037 if (query) | |
1038 node = xmlnode_get_attrib(query, "node"); | |
1039 | |
1044 if (!from || !strcmp(type, "error") || !query) { | 1040 if (!from || !strcmp(type, "error") || !query) { |
1045 jdicd->callback(js, NULL, jdicd->data); | 1041 jdicd->callback(js, from, node, NULL, jdicd->data); |
1046 g_free(jdicd); | 1042 g_free(jdicd); |
1047 return; | 1043 return; |
1048 } | 1044 } |
1049 | 1045 |
1050 for (child = xmlnode_get_child(query, "item"); child; | 1046 for (child = xmlnode_get_child(query, "item"); child; |
1058 | 1054 |
1059 items = g_slist_prepend(items, item); | 1055 items = g_slist_prepend(items, item); |
1060 } | 1056 } |
1061 | 1057 |
1062 items = g_slist_reverse(items); | 1058 items = g_slist_reverse(items); |
1063 jdicd->callback(js, items, jdicd->data); | 1059 jdicd->callback(js, from, node, items, jdicd->data); |
1064 g_free(jdicd); | 1060 g_free(jdicd); |
1065 } | 1061 } |
1066 | 1062 |
1067 void jabber_disco_items_do(JabberStream *js, const char *who, | 1063 void jabber_disco_items_do(JabberStream *js, const char *who, const char *node, |
1068 JabberDiscoItemsCallback *callback, gpointer data) | 1064 JabberDiscoItemsCallback *callback, gpointer data) |
1069 { | 1065 { |
1070 struct _jabber_disco_items_cb_data *jdicd; | 1066 struct _jabber_disco_items_cb_data *jdicd; |
1071 JabberIq *iq; | 1067 JabberIq *iq; |
1072 | 1068 |
1073 jdicd = g_new0(struct _jabber_disco_items_cb_data, 1); | 1069 jdicd = g_new0(struct _jabber_disco_items_cb_data, 1); |
1074 jdicd->data = data; | 1070 jdicd->data = data; |
1075 jdicd->callback = callback; | 1071 jdicd->callback = callback; |
1076 | 1072 |
1077 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items"); | 1073 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "http://jabber.org/protocol/disco#items"); |
1074 if (node) | |
1075 xmlnode_set_attrib(xmlnode_get_child(iq->node, "query"), "node", node); | |
1076 | |
1078 xmlnode_set_attrib(iq->node, "to", who); | 1077 xmlnode_set_attrib(iq->node, "to", who); |
1079 | 1078 |
1080 jabber_iq_set_callback(iq, jabber_disco_items_cb, jdicd); | 1079 jabber_iq_set_callback(iq, jabber_disco_items_cb, jdicd); |
1081 jabber_iq_send(iq); | 1080 jabber_iq_send(iq); |
1082 } | 1081 } |