Mercurial > pidgin
comparison libpurple/protocols/jabber/disco.c @ 26604:ff33b65b2448
Iteratively expand the disco tree as prompted by the UI.
Walking the entire tree automatically = bad.
This doesn't really work yet. The UI needs to be updated to support the little
expandy things like on the buddy list. It doesn't crash, though, and retrieves
the first level.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Tue, 14 Apr 2009 06:54:44 +0000 |
parents | 6b3a23ecbb42 |
children | 217a3ad87fc4 |
comparison
equal
deleted
inserted
replaced
26603:6b3a23ecbb42 | 26604:ff33b65b2448 |
---|---|
52 feature = xmlnode_new_child(query, "feature"); \ | 52 feature = xmlnode_new_child(query, "feature"); \ |
53 xmlnode_set_attrib(feature, "var", x); \ | 53 xmlnode_set_attrib(feature, "var", x); \ |
54 } | 54 } |
55 | 55 |
56 struct jabber_disco_list_data { | 56 struct jabber_disco_list_data { |
57 JabberStream *js; | 57 JabberStream *js; /* TODO: Needed? */ |
58 PurpleDiscoList *list; | 58 PurpleDiscoList *list; |
59 char *server; | 59 char *server; |
60 int fetch_count; | 60 int fetch_count; |
61 }; | |
62 | |
63 struct jabber_disco_service_data { | |
64 char *jid; | |
65 char *node; | |
61 }; | 66 }; |
62 | 67 |
63 static void | 68 static void |
64 jabber_disco_bytestream_server_cb(JabberStream *js, const char *from, | 69 jabber_disco_bytestream_server_cb(JabberStream *js, const char *from, |
65 JabberIqType type, const char *id, | 70 JabberIqType type, const char *id, |
759 | 764 |
760 PurpleDiscoList *list; | 765 PurpleDiscoList *list; |
761 PurpleDiscoService *parent, *service; | 766 PurpleDiscoService *parent, *service; |
762 PurpleDiscoServiceType service_type; | 767 PurpleDiscoServiceType service_type; |
763 PurpleDiscoServiceFlags flags; | 768 PurpleDiscoServiceFlags flags; |
769 struct jabber_disco_service_data *service_data; | |
764 | 770 |
765 disco_data = data; | 771 disco_data = data; |
766 list_data = disco_data->list_data; | 772 list_data = disco_data->list_data; |
767 list = list_data->list; | 773 list = list_data->list; |
768 parent = disco_data->parent; | 774 parent = disco_data->parent; |
771 disco_data->node = NULL; | 777 disco_data->node = NULL; |
772 g_free(disco_data); | 778 g_free(disco_data); |
773 | 779 |
774 --list_data->fetch_count; | 780 --list_data->fetch_count; |
775 | 781 |
776 if (list_data->list == NULL) { | 782 if (!purple_disco_list_get_in_progress(list)) { |
777 if (list_data->fetch_count == 0) | 783 purple_disco_list_unref(list); |
778 jabber_disco_list_data_destroy(list_data); | |
779 | |
780 return; | 784 return; |
781 } | 785 } |
782 | 786 |
783 if (!from || type == JABBER_IQ_ERROR | 787 if (!from || type == JABBER_IQ_ERROR |
784 || (!(query = xmlnode_get_child(packet, "query"))) | 788 || (!(query = xmlnode_get_child(packet, "query"))) |
816 if ((anode = xmlnode_get_attrib(query, "node"))) | 820 if ((anode = xmlnode_get_attrib(query, "node"))) |
817 aname = g_strdup_printf("%s%s", from, anode); | 821 aname = g_strdup_printf("%s%s", from, anode); |
818 else | 822 else |
819 aname = g_strdup(from); | 823 aname = g_strdup(from); |
820 | 824 |
825 service_data = g_new0(struct jabber_disco_service_data, 1); | |
826 service_data->jid = g_strdup(from); | |
827 if (anode) | |
828 service_data->node = g_strdup(anode); | |
829 | |
821 service = purple_disco_list_service_new(service_type, aname, | 830 service = purple_disco_list_service_new(service_type, aname, |
822 xmlnode_get_attrib(identity, "name"), flags); | 831 xmlnode_get_attrib(identity, "name"), flags, service_data); |
823 g_free(aname); | 832 g_free(aname); |
824 | 833 |
825 if (service_type == PURPLE_DISCO_SERVICE_TYPE_GATEWAY) | 834 if (service_type == PURPLE_DISCO_SERVICE_TYPE_GATEWAY) |
826 purple_disco_service_set_gateway_type(service, | 835 purple_disco_service_set_gateway_type(service, |
827 jabber_disco_type_from_string(xmlnode_get_attrib(identity, | 836 jabber_disco_type_from_string(xmlnode_get_attrib(identity, |
828 "type"))); | 837 "type"))); |
829 | 838 |
830 purple_disco_list_service_add(list, service, parent); | 839 purple_disco_list_service_add(list, service, parent); |
831 | 840 |
832 /* if (flags & PURPLE_DISCO_FLAG_BROWSE) - not all browsable services have this feature */ | |
833 { | |
834 ++list_data->fetch_count; | |
835 purple_disco_list_ref(list); | |
836 disco_data = g_new0(struct _disco_data, 1); | |
837 disco_data->list_data = list_data; | |
838 disco_data->parent = service; | |
839 | |
840 jabber_disco_items_do(js, from, node, jabber_disco_service_items_cb, | |
841 disco_data); | |
842 } | |
843 | |
844 if (list_data->fetch_count == 0) | 841 if (list_data->fetch_count == 0) |
845 purple_disco_list_set_in_progress(list, FALSE); | 842 purple_disco_list_set_in_progress(list, FALSE); |
846 | 843 |
847 purple_disco_list_unref(list); | 844 purple_disco_list_unref(list); |
848 | 845 |
849 g_free(aname); | |
850 g_free(node); | 846 g_free(node); |
851 } | 847 } |
852 | 848 |
853 static void | 849 static void |
854 jabber_disco_server_items_cb(JabberStream *js, const char *from, | 850 jabber_disco_server_items_cb(JabberStream *js, const char *from, |
857 { | 853 { |
858 struct jabber_disco_list_data *list_data; | 854 struct jabber_disco_list_data *list_data; |
859 xmlnode *query, *child; | 855 xmlnode *query, *child; |
860 gboolean has_items = FALSE; | 856 gboolean has_items = FALSE; |
861 | 857 |
862 if (!from || type == JABBER_IQ_ERROR) | |
863 return; | |
864 | |
865 list_data = data; | 858 list_data = data; |
866 --list_data->fetch_count; | 859 --list_data->fetch_count; |
867 | 860 |
868 if (list_data->list == NULL) { | 861 if (!from || type == JABBER_IQ_ERROR || |
869 if (list_data->fetch_count == 0) | 862 !purple_disco_list_get_in_progress(list_data->list)) { |
870 jabber_disco_list_data_destroy(list_data); | 863 purple_disco_list_unref(list_data->list); |
871 | |
872 return; | 864 return; |
873 } | 865 } |
874 | 866 |
875 query = xmlnode_get_child(packet, "query"); | 867 query = xmlnode_get_child(packet, "query"); |
876 | 868 |
966 ++list_data->fetch_count; | 958 ++list_data->fetch_count; |
967 jabber_disco_info_do(js, list_data->server, jabber_disco_server_info_cb, list_data); | 959 jabber_disco_info_do(js, list_data->server, jabber_disco_server_info_cb, list_data); |
968 } | 960 } |
969 | 961 |
970 static void | 962 static void |
963 jabber_disco_service_close(PurpleDiscoService *service) | |
964 { | |
965 struct jabber_disco_service_data *data; | |
966 | |
967 data = purple_disco_service_get_protocol_data(service); | |
968 g_free(data->jid); | |
969 g_free(data->node); | |
970 g_free(data); | |
971 } | |
972 | |
973 #if 0 | |
974 static void | |
971 jabber_disco_cancel(PurpleDiscoList *list) | 975 jabber_disco_cancel(PurpleDiscoList *list) |
972 { | 976 { |
973 struct jabber_disco_list_data *list_data = purple_disco_list_get_protocol_data(list); | 977 /* This space intentionally letft blank */ |
974 purple_disco_list_set_protocol_data(list, NULL, NULL); | 978 } |
975 | 979 #endif |
976 if (list_data->fetch_count == 0) { | 980 |
977 /* Nothing outstanding, just free it now... */ | 981 static void |
978 jabber_disco_list_data_destroy(list_data); | 982 jabber_disco_list_expand(PurpleDiscoList *list, PurpleDiscoService *service) |
979 } else { | 983 { |
980 int i; | 984 PurpleAccount *account; |
981 /* Lose all our references to the PurpleDiscoList */ | 985 PurpleConnection *pc; |
982 for (i = 0; i < list_data->fetch_count; ++i) { | 986 JabberStream *js; |
983 purple_disco_list_unref(list); | 987 struct jabber_disco_list_data *list_data; |
984 } | 988 struct jabber_disco_service_data *service_data; |
985 | 989 struct _disco_data *disco_data; |
986 /* We'll free list_data when fetch_count is down to 0 */ | 990 |
987 list_data->list = NULL; | 991 account = purple_disco_list_get_account(list); |
988 } | 992 pc = purple_account_get_connection(account); |
993 js = purple_connection_get_protocol_data(pc); | |
994 | |
995 list_data = purple_disco_list_get_protocol_data(list); | |
996 | |
997 ++list_data->fetch_count; | |
998 purple_disco_list_ref(list); | |
999 disco_data = g_new0(struct _disco_data, 1); | |
1000 disco_data->list_data = list_data; | |
1001 disco_data->parent = service; | |
1002 | |
1003 service_data = purple_disco_service_get_protocol_data(service); | |
1004 | |
1005 jabber_disco_items_do(js, service_data->jid, service_data->node, | |
1006 jabber_disco_service_items_cb, disco_data); | |
989 } | 1007 } |
990 | 1008 |
991 static void | 1009 static void |
992 jabber_disco_service_register(PurpleConnection *gc, PurpleDiscoService *service) | 1010 jabber_disco_service_register(PurpleConnection *gc, PurpleDiscoService *service) |
993 { | 1011 { |
1012 list = purple_disco_list_new(account); | 1030 list = purple_disco_list_new(account); |
1013 | 1031 |
1014 disco_list_data = g_new0(struct jabber_disco_list_data, 1); | 1032 disco_list_data = g_new0(struct jabber_disco_list_data, 1); |
1015 disco_list_data->list = list; | 1033 disco_list_data->list = list; |
1016 disco_list_data->js = js; | 1034 disco_list_data->js = js; |
1017 purple_disco_list_set_protocol_data(list, disco_list_data, disco_proto_data_destroy_cb); | 1035 purple_disco_list_set_protocol_data(list, disco_list_data, |
1036 disco_proto_data_destroy_cb); | |
1037 purple_disco_list_set_service_close_func(list, jabber_disco_service_close); | |
1038 #if 0 | |
1018 purple_disco_list_set_cancel_func(list, jabber_disco_cancel); | 1039 purple_disco_list_set_cancel_func(list, jabber_disco_cancel); |
1040 #endif | |
1041 purple_disco_list_set_expand_func(list, jabber_disco_list_expand); | |
1019 purple_disco_list_set_register_func(list, jabber_disco_service_register); | 1042 purple_disco_list_set_register_func(list, jabber_disco_service_register); |
1020 | 1043 |
1021 purple_request_input(gc, _("Server name request"), _("Enter an XMPP Server"), | 1044 purple_request_input(gc, _("Server name request"), _("Enter an XMPP Server"), |
1022 _("Select an XMPP server to query"), | 1045 _("Select an XMPP server to query"), |
1023 js->last_disco_server ? js->last_disco_server : js->user->domain, | 1046 js->last_disco_server ? js->last_disco_server : js->user->domain, |