comparison libpurple/protocols/jabber/disco.c @ 26686: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
26685:6b3a23ecbb42 26686: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,