| 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, |