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 }