Mercurial > pidgin.yaz
comparison libpurple/dnssrv.c @ 32010:ce968e115c95
propagate from branch 'im.pidgin.cpw.masca.p2p' (head 33ca865dacb9e5bcf763d06f6a42cbaca337cc64)
to branch 'im.pidgin.pidgin' (head 92f47f4e8b0cbb107fd97e1ab814d1cedbf109ad)
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Fri, 06 May 2011 06:25:14 +0000 |
parents | 92f3d821653f |
children | ad79fa168cee |
comparison
equal
deleted
inserted
replaced
32009:f021d93a1f9b | 32010:ce968e115c95 |
---|---|
18 * | 18 * |
19 * You should have received a copy of the GNU General Public License | 19 * You should have received a copy of the GNU General Public License |
20 * along with this program; if not, write to the Free Software | 20 * along with this program; if not, write to the Free Software |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
22 */ | 22 */ |
23 #define _PURPLE_DNSSRV_C_ | |
23 | 24 |
24 #include "internal.h" | 25 #include "internal.h" |
25 #include "util.h" | 26 #include "util.h" |
26 | 27 |
27 #ifndef _WIN32 | 28 #ifndef _WIN32 |
28 #include <arpa/nameser.h> | 29 #include <arpa/nameser.h> |
29 #include <resolv.h> | 30 #include <resolv.h> |
30 #ifdef HAVE_ARPA_NAMESER_COMPAT_H | 31 #ifdef HAVE_ARPA_NAMESER_COMPAT_H |
31 #include <arpa/nameser_compat.h> | 32 #include <arpa/nameser_compat.h> |
32 #endif | 33 #endif |
33 #ifndef T_SRV | |
34 #define T_SRV 33 | |
35 #endif | |
36 #ifndef T_TXT | |
37 #define T_TXT 16 | |
38 #endif | |
39 #else /* WIN32 */ | 34 #else /* WIN32 */ |
40 #include <windns.h> | 35 #include <windns.h> |
41 /* Missing from the mingw headers */ | 36 /* Missing from the mingw headers */ |
42 #ifndef DNS_TYPE_SRV | 37 #ifndef DNS_TYPE_SRV |
43 # define DNS_TYPE_SRV 33 | 38 # define DNS_TYPE_SRV PurpleDnsTypeSrv |
44 #endif | 39 #endif |
45 #ifndef DNS_TYPE_TXT | 40 #ifndef DNS_TYPE_TXT |
46 # define DNS_TYPE_TXT 16 | 41 # define DNS_TYPE_TXT PurpleDnsTypeTxt |
47 #endif | 42 #endif |
43 #endif | |
44 | |
45 #ifndef T_SRV | |
46 #define T_SRV PurpleDnsTypeSrv | |
47 #endif | |
48 #ifndef T_TXT | |
49 #define T_TXT PurpleDnsTypeTxt | |
48 #endif | 50 #endif |
49 | 51 |
50 #include "debug.h" | 52 #include "debug.h" |
51 #include "dnssrv.h" | 53 #include "dnssrv.h" |
52 #include "eventloop.h" | 54 #include "eventloop.h" |
53 #include "network.h" | 55 #include "network.h" |
56 | |
57 static PurpleSrvTxtQueryUiOps *srv_txt_query_ui_ops = NULL; | |
54 | 58 |
55 #ifndef _WIN32 | 59 #ifndef _WIN32 |
56 typedef union { | 60 typedef union { |
57 HEADER hdr; | 61 HEADER hdr; |
58 u_char buf[1024]; | 62 u_char buf[1024]; |
64 PVOID* pReserved) = NULL; | 68 PVOID* pReserved) = NULL; |
65 static void (WINAPI *MyDnsRecordListFree) (PDNS_RECORD pRecordList, | 69 static void (WINAPI *MyDnsRecordListFree) (PDNS_RECORD pRecordList, |
66 DNS_FREE_TYPE FreeType) = NULL; | 70 DNS_FREE_TYPE FreeType) = NULL; |
67 #endif | 71 #endif |
68 | 72 |
69 struct _PurpleTxtResponse { | 73 struct _PurpleSrvTxtQueryData { |
70 char *content; | |
71 }; | |
72 | |
73 struct _PurpleSrvQueryData { | |
74 union { | 74 union { |
75 PurpleSrvCallback srv; | 75 PurpleSrvCallback srv; |
76 PurpleTxtCallback txt; | 76 PurpleTxtCallback txt; |
77 } cb; | 77 } cb; |
78 | 78 |
79 gpointer extradata; | 79 gpointer extradata; |
80 guint handle; | 80 guint handle; |
81 int type; | 81 int type; |
82 char *query; | |
82 #ifdef _WIN32 | 83 #ifdef _WIN32 |
83 GThread *resolver; | 84 GThread *resolver; |
84 char *query; | |
85 char *error_message; | 85 char *error_message; |
86 GList *results; | 86 GList *results; |
87 #else | 87 #else |
88 int fd_in, fd_out; | 88 int fd_in, fd_out; |
89 pid_t pid; | 89 pid_t pid; |
97 | 97 |
98 typedef struct _PurpleSrvResponseContainer { | 98 typedef struct _PurpleSrvResponseContainer { |
99 PurpleSrvResponse *response; | 99 PurpleSrvResponse *response; |
100 int sum; | 100 int sum; |
101 } PurpleSrvResponseContainer; | 101 } PurpleSrvResponseContainer; |
102 | |
103 static gboolean purple_srv_txt_query_ui_resolve(PurpleSrvTxtQueryData *query_data); | |
102 | 104 |
103 /** | 105 /** |
104 * Sort by priority, then by weight. Strictly numerically--no | 106 * Sort by priority, then by weight. Strictly numerically--no |
105 * randomness. Technically we only need to sort by pref and then | 107 * randomness. Technically we only need to sort by pref and then |
106 * make sure any records with weight 0 are at the beginning of | 108 * make sure any records with weight 0 are at the beginning of |
428 static void | 430 static void |
429 resolved(gpointer data, gint source, PurpleInputCondition cond) | 431 resolved(gpointer data, gint source, PurpleInputCondition cond) |
430 { | 432 { |
431 int size; | 433 int size; |
432 int type; | 434 int type; |
433 PurpleSrvQueryData *query_data = (PurpleSrvQueryData*)data; | 435 PurpleSrvTxtQueryData *query_data = (PurpleSrvTxtQueryData*)data; |
434 int i; | 436 int i; |
435 int status; | 437 int status; |
436 | 438 |
437 if (read(source, &type, sizeof(type)) == sizeof(type)) { | 439 if (read(source, &type, sizeof(type)) == sizeof(type)) { |
438 if (read(source, &size, sizeof(size)) == sizeof(size)) { | 440 if (read(source, &size, sizeof(size)) == sizeof(size)) { |
530 | 532 |
531 static gboolean | 533 static gboolean |
532 res_main_thread_cb(gpointer data) | 534 res_main_thread_cb(gpointer data) |
533 { | 535 { |
534 PurpleSrvResponse *srvres = NULL; | 536 PurpleSrvResponse *srvres = NULL; |
535 PurpleSrvQueryData *query_data = data; | 537 PurpleSrvTxtQueryData *query_data = data; |
536 if(query_data->error_message != NULL) { | 538 if(query_data->error_message != NULL) { |
537 purple_debug_error("dnssrv", "%s", query_data->error_message); | 539 purple_debug_error("dnssrv", "%s", query_data->error_message); |
538 if (query_data->type == DNS_TYPE_SRV) { | 540 if (query_data->type == DNS_TYPE_SRV) { |
539 if (query_data->cb.srv) | 541 if (query_data->cb.srv) |
540 query_data->cb.srv(srvres, 0, query_data->extradata); | 542 query_data->cb.srv(srvres, 0, query_data->extradata); |
590 res_thread(gpointer data) | 592 res_thread(gpointer data) |
591 { | 593 { |
592 PDNS_RECORD dr = NULL; | 594 PDNS_RECORD dr = NULL; |
593 int type; | 595 int type; |
594 DNS_STATUS ds; | 596 DNS_STATUS ds; |
595 PurpleSrvQueryData *query_data = data; | 597 PurpleSrvTxtQueryData *query_data = data; |
596 type = query_data->type; | 598 type = query_data->type; |
597 ds = MyDnsQuery_UTF8(query_data->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL); | 599 ds = MyDnsQuery_UTF8(query_data->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL); |
598 if (ds != ERROR_SUCCESS) { | 600 if (ds != ERROR_SUCCESS) { |
599 gchar *msg = g_win32_error_message(ds); | 601 gchar *msg = g_win32_error_message(ds); |
600 if (type == DNS_TYPE_SRV) { | 602 if (type == DNS_TYPE_SRV) { |
670 return NULL; | 672 return NULL; |
671 } | 673 } |
672 | 674 |
673 #endif | 675 #endif |
674 | 676 |
675 PurpleSrvQueryData * | 677 PurpleSrvTxtQueryData * |
676 purple_srv_resolve(const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata) | 678 purple_srv_resolve(const char *protocol, const char *transport, |
679 const char *domain, PurpleSrvCallback cb, gpointer extradata) | |
680 { | |
681 return purple_srv_resolve_account(NULL, protocol, transport, domain, | |
682 cb, extradata); | |
683 } | |
684 | |
685 PurpleSrvTxtQueryData * | |
686 purple_srv_resolve_account(PurpleAccount *account, const char *protocol, | |
687 const char *transport, const char *domain, PurpleSrvCallback cb, | |
688 gpointer extradata) | |
677 { | 689 { |
678 char *query; | 690 char *query; |
679 char *hostname; | 691 char *hostname; |
680 PurpleSrvQueryData *query_data; | 692 PurpleSrvTxtQueryData *query_data; |
693 PurpleProxyType proxy_type; | |
681 #ifndef _WIN32 | 694 #ifndef _WIN32 |
682 PurpleSrvInternalQuery internal_query; | 695 PurpleSrvInternalQuery internal_query; |
683 int in[2], out[2]; | 696 int in[2], out[2]; |
684 int pid; | 697 int pid; |
685 #else | 698 #else |
691 purple_debug_error("dnssrv", "Wrong arguments\n"); | 704 purple_debug_error("dnssrv", "Wrong arguments\n"); |
692 cb(NULL, 0, extradata); | 705 cb(NULL, 0, extradata); |
693 g_return_val_if_reached(NULL); | 706 g_return_val_if_reached(NULL); |
694 } | 707 } |
695 | 708 |
709 proxy_type = purple_proxy_info_get_type( | |
710 purple_proxy_get_setup(account)); | |
711 if (proxy_type == PURPLE_PROXY_TOR) { | |
712 purple_debug_info("dnssrv", "Aborting SRV lookup in Tor Proxy mode."); | |
713 cb(NULL, 0, extradata); | |
714 return NULL; | |
715 } | |
716 | |
696 #ifdef USE_IDN | 717 #ifdef USE_IDN |
697 if (!dns_str_is_ascii(domain)) { | 718 if (!dns_str_is_ascii(domain)) { |
698 int ret = purple_network_convert_idn_to_ascii(domain, &hostname); | 719 int ret = purple_network_convert_idn_to_ascii(domain, &hostname); |
699 if (ret != 0) { | 720 if (ret != 0) { |
700 purple_debug_error("dnssrv", "IDNA ToASCII failed\n"); | 721 purple_debug_error("dnssrv", "IDNA ToASCII failed\n"); |
707 | 728 |
708 query = g_strdup_printf("_%s._%s.%s", protocol, transport, hostname); | 729 query = g_strdup_printf("_%s._%s.%s", protocol, transport, hostname); |
709 purple_debug_info("dnssrv","querying SRV record for %s: %s\n", domain, | 730 purple_debug_info("dnssrv","querying SRV record for %s: %s\n", domain, |
710 query); | 731 query); |
711 g_free(hostname); | 732 g_free(hostname); |
733 | |
734 query_data = g_new0(PurpleSrvTxtQueryData, 1); | |
735 query_data->type = PurpleDnsTypeSrv; | |
736 query_data->cb.srv = cb; | |
737 query_data->extradata = extradata; | |
738 query_data->query = query; | |
739 | |
740 if (purple_srv_txt_query_ui_resolve(query_data)) | |
741 { | |
742 return query_data; | |
743 } | |
712 | 744 |
713 #ifndef _WIN32 | 745 #ifndef _WIN32 |
714 if(pipe(in) || pipe(out)) { | 746 if(pipe(in) || pipe(out)) { |
715 purple_debug_error("dnssrv", "Could not create pipe\n"); | 747 purple_debug_error("dnssrv", "Could not create pipe\n"); |
716 g_free(query); | 748 g_free(query); |
745 internal_query.query[255] = '\0'; | 777 internal_query.query[255] = '\0'; |
746 | 778 |
747 if (write(in[1], &internal_query, sizeof(internal_query)) < 0) | 779 if (write(in[1], &internal_query, sizeof(internal_query)) < 0) |
748 purple_debug_error("dnssrv", "Could not write to SRV resolver\n"); | 780 purple_debug_error("dnssrv", "Could not write to SRV resolver\n"); |
749 | 781 |
750 query_data = g_new0(PurpleSrvQueryData, 1); | |
751 query_data->type = T_SRV; | |
752 query_data->cb.srv = cb; | |
753 query_data->extradata = extradata; | |
754 query_data->pid = pid; | 782 query_data->pid = pid; |
755 query_data->fd_out = out[0]; | 783 query_data->fd_out = out[0]; |
756 query_data->fd_in = in[1]; | 784 query_data->fd_in = in[1]; |
757 query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data); | 785 query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data); |
758 | 786 |
765 MyDnsRecordListFree = (void*) wpurple_find_and_loadproc( | 793 MyDnsRecordListFree = (void*) wpurple_find_and_loadproc( |
766 "dnsapi.dll", "DnsRecordListFree"); | 794 "dnsapi.dll", "DnsRecordListFree"); |
767 initialized = TRUE; | 795 initialized = TRUE; |
768 } | 796 } |
769 | 797 |
770 query_data = g_new0(PurpleSrvQueryData, 1); | |
771 query_data->type = DNS_TYPE_SRV; | |
772 query_data->cb.srv = cb; | |
773 query_data->query = query; | |
774 query_data->extradata = extradata; | |
775 | |
776 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) | 798 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) |
777 query_data->error_message = g_strdup("System missing DNS API (Requires W2K+)\n"); | 799 query_data->error_message = g_strdup("System missing DNS API (Requires W2K+)\n"); |
778 else { | 800 else { |
779 query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err); | 801 query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err); |
780 if (query_data->resolver == NULL) { | 802 if (query_data->resolver == NULL) { |
791 | 813 |
792 return query_data; | 814 return query_data; |
793 #endif | 815 #endif |
794 } | 816 } |
795 | 817 |
796 PurpleSrvQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata) | 818 PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner, |
819 const char *domain, PurpleTxtCallback cb, gpointer extradata) | |
820 { | |
821 return purple_txt_resolve_account(NULL, owner, domain, cb, extradata); | |
822 } | |
823 | |
824 PurpleSrvTxtQueryData *purple_txt_resolve_account(PurpleAccount *account, | |
825 const char *owner, const char *domain, PurpleTxtCallback cb, | |
826 gpointer extradata) | |
797 { | 827 { |
798 char *query; | 828 char *query; |
799 char *hostname; | 829 char *hostname; |
800 PurpleSrvQueryData *query_data; | 830 PurpleSrvTxtQueryData *query_data; |
831 PurpleProxyType proxy_type; | |
801 #ifndef _WIN32 | 832 #ifndef _WIN32 |
802 PurpleSrvInternalQuery internal_query; | 833 PurpleSrvInternalQuery internal_query; |
803 int in[2], out[2]; | 834 int in[2], out[2]; |
804 int pid; | 835 int pid; |
805 #else | 836 #else |
806 GError* err = NULL; | 837 GError* err = NULL; |
807 static gboolean initialized = FALSE; | 838 static gboolean initialized = FALSE; |
808 #endif | 839 #endif |
809 | 840 |
841 proxy_type = purple_proxy_info_get_type( | |
842 purple_proxy_get_setup(account)); | |
843 if (proxy_type == PURPLE_PROXY_TOR) { | |
844 purple_debug_info("dnssrv", "Aborting TXT lookup in Tor Proxy mode."); | |
845 cb(NULL, extradata); | |
846 return NULL; | |
847 } | |
848 | |
810 #ifdef USE_IDN | 849 #ifdef USE_IDN |
811 if (!dns_str_is_ascii(domain)) { | 850 if (!dns_str_is_ascii(domain)) { |
812 int ret = purple_network_convert_idn_to_ascii(domain, &hostname); | 851 int ret = purple_network_convert_idn_to_ascii(domain, &hostname); |
813 if (ret != 0) { | 852 if (ret != 0) { |
814 purple_debug_error("dnssrv", "IDNA ToASCII failed\n"); | 853 purple_debug_error("dnssrv", "IDNA ToASCII failed\n"); |
821 | 860 |
822 query = g_strdup_printf("%s.%s", owner, hostname); | 861 query = g_strdup_printf("%s.%s", owner, hostname); |
823 purple_debug_info("dnssrv","querying TXT record for %s: %s\n", domain, | 862 purple_debug_info("dnssrv","querying TXT record for %s: %s\n", domain, |
824 query); | 863 query); |
825 g_free(hostname); | 864 g_free(hostname); |
865 | |
866 query_data = g_new0(PurpleSrvTxtQueryData, 1); | |
867 query_data->type = PurpleDnsTypeTxt; | |
868 query_data->cb.txt = cb; | |
869 query_data->extradata = extradata; | |
870 query_data->query = query; | |
871 | |
872 if (purple_srv_txt_query_ui_resolve(query_data)) { | |
873 /* query intentionally not freed | |
874 */ | |
875 return query_data; | |
876 } | |
826 | 877 |
827 #ifndef _WIN32 | 878 #ifndef _WIN32 |
828 if(pipe(in) || pipe(out)) { | 879 if(pipe(in) || pipe(out)) { |
829 purple_debug_error("dnssrv", "Could not create pipe\n"); | 880 purple_debug_error("dnssrv", "Could not create pipe\n"); |
830 g_free(query); | 881 g_free(query); |
858 strncpy(internal_query.query, query, 255); | 909 strncpy(internal_query.query, query, 255); |
859 internal_query.query[255] = '\0'; | 910 internal_query.query[255] = '\0'; |
860 | 911 |
861 if (write(in[1], &internal_query, sizeof(internal_query)) < 0) | 912 if (write(in[1], &internal_query, sizeof(internal_query)) < 0) |
862 purple_debug_error("dnssrv", "Could not write to TXT resolver\n"); | 913 purple_debug_error("dnssrv", "Could not write to TXT resolver\n"); |
863 | 914 |
864 query_data = g_new0(PurpleSrvQueryData, 1); | |
865 query_data->type = T_TXT; | |
866 query_data->cb.txt = cb; | |
867 query_data->extradata = extradata; | |
868 query_data->pid = pid; | 915 query_data->pid = pid; |
869 query_data->fd_out = out[0]; | 916 query_data->fd_out = out[0]; |
870 query_data->fd_in = in[1]; | 917 query_data->fd_in = in[1]; |
871 query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data); | 918 query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data); |
872 | 919 |
879 MyDnsRecordListFree = (void*) wpurple_find_and_loadproc( | 926 MyDnsRecordListFree = (void*) wpurple_find_and_loadproc( |
880 "dnsapi.dll", "DnsRecordListFree"); | 927 "dnsapi.dll", "DnsRecordListFree"); |
881 initialized = TRUE; | 928 initialized = TRUE; |
882 } | 929 } |
883 | 930 |
884 query_data = g_new0(PurpleSrvQueryData, 1); | |
885 query_data->type = DNS_TYPE_TXT; | |
886 query_data->cb.txt = cb; | |
887 query_data->query = query; | |
888 query_data->extradata = extradata; | |
889 | |
890 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) | 931 if (!MyDnsQuery_UTF8 || !MyDnsRecordListFree) |
891 query_data->error_message = g_strdup("System missing DNS API (Requires W2K+)\n"); | 932 query_data->error_message = g_strdup("System missing DNS API (Requires W2K+)\n"); |
892 else { | 933 else { |
893 query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err); | 934 query_data->resolver = g_thread_create(res_thread, query_data, FALSE, &err); |
894 if (query_data->resolver == NULL) { | 935 if (query_data->resolver == NULL) { |
906 return query_data; | 947 return query_data; |
907 #endif | 948 #endif |
908 } | 949 } |
909 | 950 |
910 void | 951 void |
911 purple_srv_cancel(PurpleSrvQueryData *query_data) | 952 purple_srv_cancel(PurpleSrvTxtQueryData *query_data) |
912 { | 953 { |
954 PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops(); | |
955 | |
956 if (ops && ops->destroy) | |
957 ops->destroy(query_data); | |
958 | |
913 if (query_data->handle > 0) | 959 if (query_data->handle > 0) |
914 purple_input_remove(query_data->handle); | 960 purple_input_remove(query_data->handle); |
915 #ifdef _WIN32 | 961 #ifdef _WIN32 |
916 if (query_data->resolver != NULL) | 962 if (query_data->resolver != NULL) |
917 { | 963 { |
931 #endif | 977 #endif |
932 g_free(query_data); | 978 g_free(query_data); |
933 } | 979 } |
934 | 980 |
935 void | 981 void |
936 purple_txt_cancel(PurpleSrvQueryData *query_data) | 982 purple_txt_cancel(PurpleSrvTxtQueryData *query_data) |
937 { | 983 { |
938 purple_srv_cancel(query_data); | 984 purple_srv_cancel(query_data); |
939 } | 985 } |
940 | 986 |
941 const gchar * | 987 const gchar * |
951 g_return_if_fail(resp != NULL); | 997 g_return_if_fail(resp != NULL); |
952 | 998 |
953 g_free(resp->content); | 999 g_free(resp->content); |
954 g_free(resp); | 1000 g_free(resp); |
955 } | 1001 } |
1002 | |
1003 /* | |
1004 * Only used as the callback for the ui ops. | |
1005 */ | |
1006 static void | |
1007 purple_srv_query_resolved(PurpleSrvTxtQueryData *query_data, GList *records) | |
1008 { | |
1009 g_return_if_fail(records != NULL); | |
1010 | |
1011 purple_debug_info("dnssrv", "SRV records resolved for %s, count: %d\n", query_data->query, g_list_length(records)); | |
1012 | |
1013 if (query_data->cb.srv != NULL) | |
1014 query_data->cb.srv(purple_srv_sort(records)->data, g_list_length(records), query_data->extradata); | |
1015 } | |
1016 | |
1017 /* | |
1018 * Only used as the callback for the ui ops. | |
1019 */ | |
1020 static void | |
1021 purple_txt_query_resolved(PurpleSrvTxtQueryData *query_data, GList *entries) | |
1022 { | |
1023 g_return_if_fail(entries != NULL); | |
1024 | |
1025 purple_debug_info("dnssrv", "TXT entries resolved for %s, count: %d\n", query_data->query, g_list_length(entries)); | |
1026 | |
1027 if (query_data->cb.txt != NULL) | |
1028 query_data->cb.txt(entries, query_data->extradata); | |
1029 } | |
1030 | |
1031 static void | |
1032 purple_srv_query_failed(PurpleSrvTxtQueryData *query_data, const gchar *error_message) | |
1033 { | |
1034 purple_debug_error("dnssrv", "%s\n", error_message); | |
1035 | |
1036 if (query_data->cb.srv != NULL) | |
1037 query_data->cb.srv(NULL, 0, query_data->extradata); | |
1038 | |
1039 purple_srv_cancel(query_data); | |
1040 } | |
1041 | |
1042 static gboolean | |
1043 purple_srv_txt_query_ui_resolve(PurpleSrvTxtQueryData *query_data) | |
1044 { | |
1045 PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops(); | |
1046 | |
1047 if (ops && ops->resolve) | |
1048 return ops->resolve(query_data, (query_data->type == T_SRV ? purple_srv_query_resolved : purple_txt_query_resolved), purple_srv_query_failed); | |
1049 | |
1050 return FALSE; | |
1051 } | |
1052 | |
1053 void | |
1054 purple_srv_txt_query_set_ui_ops(PurpleSrvTxtQueryUiOps *ops) | |
1055 { | |
1056 srv_txt_query_ui_ops = ops; | |
1057 } | |
1058 | |
1059 PurpleSrvTxtQueryUiOps * | |
1060 purple_srv_txt_query_get_ui_ops(void) | |
1061 { | |
1062 /* It is perfectly acceptable for srv_txt_query_ui_ops to be NULL; this just | |
1063 * means that the default platform-specific implementation will be used. | |
1064 */ | |
1065 return srv_txt_query_ui_ops; | |
1066 } | |
1067 | |
1068 char * | |
1069 purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data) | |
1070 { | |
1071 g_return_val_if_fail(query_data != NULL, NULL); | |
1072 | |
1073 return query_data->query; | |
1074 } | |
1075 | |
1076 | |
1077 int | |
1078 purple_srv_txt_query_get_type(PurpleSrvTxtQueryData *query_data) | |
1079 { | |
1080 g_return_val_if_fail(query_data != NULL, 0); | |
1081 | |
1082 return query_data->type; | |
1083 } |