pidgin: 84593314: Added PurpleSrvTxtQueryUiOps which allow...

thijsalkemade at gmail.com thijsalkemade at gmail.com
Thu Mar 24 19:25:54 EDT 2011


----------------------------------------------------------------------
Revision: 8459331448aff4ed1551775d833a55e5fde5f543
Parent:   8b553e4963d7a342a8ea58c15ce07815e4c0f6d0
Author:   thijsalkemade at gmail.com
Date:     03/24/11 19:22:29
Branch:   im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/8459331448aff4ed1551775d833a55e5fde5f543

Changelog: 

Added PurpleSrvTxtQueryUiOps which allow UIs to specify their own mechanisms
to resolve SRV and/or TXT queries.

Additionally, some functions and datatypes have been renamed to show which
are SRV only, which TXT only, and which are used by both.

Changes against parent 8b553e4963d7a342a8ea58c15ce07815e4c0f6d0

  patched  ChangeLog.API
  patched  libpurple/dnsquery.h
  patched  libpurple/dnssrv.c
  patched  libpurple/dnssrv.h
  patched  libpurple/gaim-compat.h
  patched  libpurple/protocols/jabber/jabber.h
  patched  libpurple/protocols/simple/simple.h

-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/jabber.h	8093864e192c0e6f0cc8f19f0bb91a7a19ea77c2
+++ libpurple/protocols/jabber/jabber.h	4886d45526932fb189a96ac9ce60e4268952b8de
@@ -100,7 +100,7 @@ struct _JabberStream
 {
 	int fd;
 
-	PurpleSrvQueryData *srv_query_data;
+	PurpleSrvTxtQueryData *srv_query_data;
 
 	xmlParserCtxt *context;
 	xmlnode *current;
============================================================
--- ChangeLog.API	b23d685d49dd3a35d42b5286daa734fd57ed8526
+++ ChangeLog.API	59e0fad480f101d6695f7c6b20723c3d8e3dfc95
@@ -14,6 +14,9 @@ version 2.8.0 (??/??/????):
 		* purple_media_manager_set_video_caps (Jakub Adam) (#13095)
 		* Added add_buddy_with_invite to PurplePluginProtocolInfo
 		* Added add_buddies_with_invite to PurplePluginProtocolInfo
+		* Added PurpleSrvTxtQueryUiOps which allow UIs to specify their
+		  own mechanisms to resolve SRV and/or TXT queries. It works
+		  similar to PurpleDnsQueryUiOps
 
 		Deprecated:
 		* purple_account_add_buddy
============================================================
--- libpurple/protocols/simple/simple.h	24f6f70ea74764bc22b2788d37ba1c9eecfa4cc3
+++ libpurple/protocols/simple/simple.h	31ab290f0c245c35ab4f380749a5090a01f0ed77
@@ -83,7 +83,7 @@ struct simple_account_data {
 	gchar *username;
 	gchar *password;
 	PurpleDnsQueryData *query_data;
-	PurpleSrvQueryData *srv_query_data;
+	PurpleSrvTxtQueryData *srv_query_data;
 	PurpleNetworkListenData *listen_data;
 	int fd;
 	int cseq;
============================================================
--- libpurple/dnssrv.c	1d94e35f4ea150180ff8cc5dfa325673e118cd1a
+++ libpurple/dnssrv.c	2a67e00901b33608a8be01cafb66b366609fb788
@@ -31,19 +31,19 @@
 #include <arpa/nameser_compat.h>
 #endif
 #ifndef T_SRV
-#define T_SRV	33
+#define T_SRV	PurpleDnsTypeSrv
 #endif
 #ifndef T_TXT
-#define T_TXT	16
+#define T_TXT	PurpleDnsTypeTxt
 #endif
 #else /* WIN32 */
 #include <windns.h>
 /* Missing from the mingw headers */
 #ifndef DNS_TYPE_SRV
-# define DNS_TYPE_SRV 33
+# define DNS_TYPE_SRV PurpleDnsTypeSrv
 #endif
 #ifndef DNS_TYPE_TXT
-# define DNS_TYPE_TXT 16
+# define DNS_TYPE_TXT PurpleDnsTypeTxt
 #endif
 #endif
 
@@ -52,6 +52,8 @@
 #include "eventloop.h"
 #include "network.h"
 
+static PurpleSrvTxtQueryUiOps *srv_txt_query_ui_ops = NULL;
+
 #ifndef _WIN32
 typedef union {
 	HEADER hdr;
@@ -66,11 +68,7 @@ static void (WINAPI *MyDnsRecordListFree
 	DNS_FREE_TYPE FreeType) = NULL;
 #endif
 
-struct _PurpleTxtResponse {
-	char *content;
-};
-
-struct _PurpleSrvQueryData {
+struct _PurpleSrvTxtQueryData {
 	union {
 		PurpleSrvCallback srv;
 		PurpleTxtCallback txt;
@@ -79,9 +77,9 @@ struct _PurpleSrvQueryData {
 	gpointer extradata;
 	guint handle;
 	int type;
+	char *query;
 #ifdef _WIN32
 	GThread *resolver;
-	char *query;
 	char *error_message;
 	GList *results;
 #else
@@ -100,6 +98,8 @@ typedef struct _PurpleSrvResponseContain
 	int sum;
 } PurpleSrvResponseContainer;
 
+static gboolean purple_srv_txt_query_ui_resolve(PurpleSrvTxtQueryData *query_data);
+
 /**
  * Sort by priority, then by weight.  Strictly numerically--no
  * randomness.  Technically we only need to sort by pref and then
@@ -430,7 +430,7 @@ resolved(gpointer data, gint source, Pur
 {
 	int size;
 	int type;
-	PurpleSrvQueryData *query_data = (PurpleSrvQueryData*)data;
+	PurpleSrvTxtQueryData *query_data = (PurpleSrvTxtQueryData*)data;
 	int i;
 	int status;
 
@@ -532,7 +532,7 @@ res_main_thread_cb(gpointer data)
 res_main_thread_cb(gpointer data)
 {
 	PurpleSrvResponse *srvres = NULL;
-	PurpleSrvQueryData *query_data = data;
+	PurpleSrvTxtQueryData *query_data = data;
 	if(query_data->error_message != NULL) {
 		purple_debug_error("dnssrv", "%s", query_data->error_message);
 		if (query_data->type == DNS_TYPE_SRV) {
@@ -592,7 +592,7 @@ res_thread(gpointer data)
 	PDNS_RECORD dr = NULL;
 	int type;
 	DNS_STATUS ds;
-	PurpleSrvQueryData *query_data = data;
+	PurpleSrvTxtQueryData *query_data = data;
 	type = query_data->type;
 	ds = MyDnsQuery_UTF8(query_data->query, type, DNS_QUERY_STANDARD, NULL, &dr, NULL);
 	if (ds != ERROR_SUCCESS) {
@@ -672,12 +672,12 @@ res_thread(gpointer data)
 
 #endif
 
-PurpleSrvQueryData *
+PurpleSrvTxtQueryData *
 purple_srv_resolve(const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata)
 {
 	char *query;
 	char *hostname;
-	PurpleSrvQueryData *query_data;
+	PurpleSrvTxtQueryData *query_data;
 #ifndef _WIN32
 	PurpleSrvInternalQuery internal_query;
 	int in[2], out[2];
@@ -709,6 +709,17 @@ purple_srv_resolve(const char *protocol,
 	purple_debug_info("dnssrv","querying SRV record for %s: %s\n", domain,
 			query);
 	g_free(hostname);
+	
+	query_data = g_new0(PurpleSrvTxtQueryData, 1);
+	query_data->type = T_SRV;
+	query_data->cb.srv = cb;
+	query_data->extradata = extradata;
+	query_data->query = query;
+	
+	if (purple_srv_txt_query_ui_resolve(query_data))
+	{
+		return query_data;
+	}
 
 #ifndef _WIN32
 	if(pipe(in) || pipe(out)) {
@@ -747,10 +758,6 @@ purple_srv_resolve(const char *protocol,
 	if (write(in[1], &internal_query, sizeof(internal_query)) < 0)
 		purple_debug_error("dnssrv", "Could not write to SRV resolver\n");
 
-	query_data = g_new0(PurpleSrvQueryData, 1);
-	query_data->type = T_SRV;
-	query_data->cb.srv = cb;
-	query_data->extradata = extradata;
 	query_data->pid = pid;
 	query_data->fd_out = out[0];
 	query_data->fd_in = in[1];
@@ -767,7 +774,7 @@ purple_srv_resolve(const char *protocol,
 		initialized = TRUE;
 	}
 
-	query_data = g_new0(PurpleSrvQueryData, 1);
+	query_data = g_new0(PurpleSrvTxtQueryData, 1);
 	query_data->type = DNS_TYPE_SRV;
 	query_data->cb.srv = cb;
 	query_data->query = query;
@@ -793,11 +800,11 @@ purple_srv_resolve(const char *protocol,
 #endif
 }
 
-PurpleSrvQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata)
+PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata)
 {
 	char *query;
 	char *hostname;
-	PurpleSrvQueryData *query_data;
+	PurpleSrvTxtQueryData *query_data;
 #ifndef _WIN32
 	PurpleSrvInternalQuery internal_query;
 	int in[2], out[2];
@@ -823,6 +830,18 @@ PurpleSrvQueryData *purple_txt_resolve(c
 	purple_debug_info("dnssrv","querying TXT record for %s: %s\n", domain,
 			query);
 	g_free(hostname);
+	
+	query_data = g_new0(PurpleSrvTxtQueryData, 1);
+	query_data->type = T_TXT;
+	query_data->cb.txt = cb;
+	query_data->extradata = extradata;
+	query_data->query = query;
+	
+	if (purple_srv_txt_query_ui_resolve(query_data)) {
+		/* query intentionally not freed
+		 */
+		return query_data;
+	}
 
 #ifndef _WIN32
 	if(pipe(in) || pipe(out)) {
@@ -860,11 +879,7 @@ PurpleSrvQueryData *purple_txt_resolve(c
 
 	if (write(in[1], &internal_query, sizeof(internal_query)) < 0)
 		purple_debug_error("dnssrv", "Could not write to TXT resolver\n");
-
-	query_data = g_new0(PurpleSrvQueryData, 1);
-	query_data->type = T_TXT;
-	query_data->cb.txt = cb;
-	query_data->extradata = extradata;
+	
 	query_data->pid = pid;
 	query_data->fd_out = out[0];
 	query_data->fd_in = in[1];
@@ -881,7 +896,7 @@ PurpleSrvQueryData *purple_txt_resolve(c
 		initialized = TRUE;
 	}
 
-	query_data = g_new0(PurpleSrvQueryData, 1);
+	query_data = g_new0(PurpleSrvTxtQueryData, 1);
 	query_data->type = DNS_TYPE_TXT;
 	query_data->cb.txt = cb;
 	query_data->query = query;
@@ -908,8 +923,13 @@ void
 }
 
 void
-purple_srv_cancel(PurpleSrvQueryData *query_data)
+purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
 {
+	PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
+
+	if (ops && ops->destroy)
+		ops->destroy(query_data);
+	
 	if (query_data->handle > 0)
 		purple_input_remove(query_data->handle);
 #ifdef _WIN32
@@ -933,7 +953,7 @@ void
 }
 
 void
-purple_txt_cancel(PurpleSrvQueryData *query_data)
+purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
 {
 	purple_srv_cancel(query_data);
 }
@@ -953,3 +973,85 @@ void purple_txt_response_destroy(PurpleT
 	g_free(resp->content);
 	g_free(resp);
 }
+
+/*
+ * Only used as the callback for the ui ops.
+ */
+static void
+purple_srv_query_resolved(PurpleSrvTxtQueryData *query_data, GList *records)
+{
+	g_return_if_fail(records != NULL);
+	
+	purple_debug_info("dnssrv", "SRV records resolved for %s, count: %d\n", query_data->query, g_list_length(records));
+	
+	if (query_data->cb.srv != NULL)
+		query_data->cb.srv(purple_srv_sort(records)->data, g_list_length(records), query_data->extradata);
+}
+
+/*
+ * Only used as the callback for the ui ops.
+ */
+static void
+purple_txt_query_resolved(PurpleSrvTxtQueryData *query_data, GList *entries)
+{
+	g_return_if_fail(entries != NULL);
+
+	purple_debug_info("dnssrv", "TXT entries resolved for %s, count: %d\n", query_data->query, g_list_length(entries));
+
+	if (query_data->cb.txt != NULL)
+		query_data->cb.txt(entries, query_data->extradata);
+}
+
+static void
+purple_srv_query_failed(PurpleSrvTxtQueryData *query_data, const gchar *error_message)
+{
+	purple_debug_error("dnssrv", "%s\n", error_message);
+	
+	if (query_data->cb.srv != NULL)
+		query_data->cb.srv(NULL, 0, query_data->extradata);
+		
+	purple_srv_cancel(query_data);
+}
+
+static gboolean
+purple_srv_txt_query_ui_resolve(PurpleSrvTxtQueryData *query_data)
+{
+	PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
+
+	if (ops && ops->resolve)
+		return ops->resolve(query_data, (query_data->type == T_SRV ? purple_srv_query_resolved : purple_txt_query_resolved), purple_srv_query_failed);
+
+	return FALSE;
+}
+
+void
+purple_srv_txt_query_set_ui_ops(PurpleSrvTxtQueryUiOps *ops)
+{
+	srv_txt_query_ui_ops = ops;
+}
+
+PurpleSrvTxtQueryUiOps *
+purple_srv_txt_query_get_ui_ops(void)
+{
+	/* It is perfectly acceptable for srv_txt_query_ui_ops to be NULL; this just
+	 * means that the default platform-specific implementation will be used.
+	 */
+	return srv_txt_query_ui_ops;
+}
+
+char *
+purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data)
+{
+	g_return_val_if_fail(query_data != NULL, NULL);
+	
+	return query_data->query;
+}
+
+
+int
+purple_srv_txt_query_get_type(PurpleSrvTxtQueryData *query_data)
+{
+	g_return_val_if_fail(query_data != NULL, 0);
+	
+	return query_data->type;
+}
\ No newline at end of file
============================================================
--- libpurple/dnssrv.h	f11ce6a54bb734cc907d4085e7ecfabb9bdb5946
+++ libpurple/dnssrv.h	ffd16af4046c57fb98dc652c812b4c1f3531cc4f
@@ -28,12 +28,21 @@ extern "C" {
 extern "C" {
 #endif
 
-typedef struct _PurpleSrvQueryData PurpleSrvQueryData;
+typedef struct _PurpleSrvTxtQueryData PurpleSrvTxtQueryData;
 typedef struct _PurpleSrvResponse PurpleSrvResponse;
 typedef struct _PurpleTxtResponse PurpleTxtResponse;
 
+/* For compatibility, should be removed for 3.0.0
+ */
+typedef struct _PurpleSrvTxtQueryData PurpleSrvQueryData;
+
 #include <glib.h>
 
+enum PurpleDnsType {
+	PurpleDnsTypeTxt = 16,
+	PurpleDnsTypeSrv = 33
+};
+
 struct _PurpleSrvResponse {
 	char hostname[256];
 	int port;
@@ -41,7 +50,41 @@ struct _PurpleSrvResponse {
 	int pref;
 };
 
+struct _PurpleTxtResponse {
+	char *content;
+};
+
+typedef void  (*PurpleSrvTxtQueryResolvedCallback) (PurpleSrvTxtQueryData *query_data, GList *records);
+typedef void  (*PurpleSrvTxtQueryFailedCallback) (PurpleSrvTxtQueryData *query_data, const gchar *error_message);
+
 /**
+ * SRV Request UI operations;  UIs should implement this if they want to do SRV
+ * lookups themselves, rather than relying on the core.
+ *
+ * @see @ref ui-ops
+ */
+typedef struct
+{
+	/** If implemented, return TRUE if the UI takes responsibility for SRV
+	  * queries. When returning FALSE, the standard implementation is used. 
+	  * These callbacks MUST be called asynchronously. */
+	gboolean (*resolve)(PurpleSrvTxtQueryData *query_data,
+	                    PurpleSrvTxtQueryResolvedCallback resolved_cb,
+	                    PurpleSrvTxtQueryFailedCallback failed_cb);
+
+	/** Called just before @a query_data is freed; this should cancel any
+	 *  further use of @a query_data the UI would make. Unneeded if
+	 *  #resolve_host is not implemented.
+	 */
+	void (*destroy)(PurpleSrvTxtQueryData *query_data);
+
+	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
+	void (*_purple_reserved4)(void);
+} PurpleSrvTxtQueryUiOps;
+
+/**
  * @param resp An array of PurpleSrvResponse of size results.  The array
  *        is sorted based on the order described in the DNS SRV RFC.
  *        Users of this API should try each record in resp in order,
@@ -66,14 +109,14 @@ typedef void (*PurpleTxtCallback)(GList 
  * @param cb A callback which will be called with the results
  * @param extradata Extra data to be passed to the callback
  */
-PurpleSrvQueryData *purple_srv_resolve(const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
+PurpleSrvTxtQueryData *purple_srv_resolve(const char *protocol, const char *transport, const char *domain, PurpleSrvCallback cb, gpointer extradata);
 
 /**
- * Cancel an SRV DNS query.
+ * Cancel an SRV or DNS query.
  *
  * @param query_data The request to cancel.
  */
-void purple_srv_cancel(PurpleSrvQueryData *query_data);
+void purple_srv_cancel(PurpleSrvTxtQueryData *query_data);
 
 /**
  * Queries an TXT record.
@@ -85,7 +128,7 @@ void purple_srv_cancel(PurpleSrvQueryDat
  *
  * @since 2.6.0
  */
-PurpleSrvQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
+PurpleSrvTxtQueryData *purple_txt_resolve(const char *owner, const char *domain, PurpleTxtCallback cb, gpointer extradata);
 
 /**
  * Cancel an TXT DNS query.
@@ -93,7 +136,7 @@ PurpleSrvQueryData *purple_txt_resolve(c
  * @param query_data The request to cancel.
  * @since 2.6.0
  */
-void purple_txt_cancel(PurpleSrvQueryData *query_data);
+void purple_txt_cancel(PurpleSrvTxtQueryData *query_data);
 
 /**
  * Get the value of the current TXT record.
@@ -112,6 +155,47 @@ void purple_txt_response_destroy(PurpleT
  */
 void purple_txt_response_destroy(PurpleTxtResponse *response);
 
+/**
+ * Cancel a SRV/TXT query and destroy the associated data structure.
+ *
+ * @param query_data The SRV/TXT query to cancel.  This data structure
+ *        is freed by this function.
+ */
+void purple_srv_txt_query_destroy(PurpleSrvTxtQueryData *query_data);
+
+/**
+ * Sets the UI operations structure to be used when doing a SRV/TXT
+ * resolve.  The UI operations need only be set if the UI wants to
+ * handle the resolve itself; otherwise, leave it as NULL.
+ *
+ * @param ops The UI operations structure.
+ */
+void purple_srv_txt_query_set_ui_ops(PurpleSrvTxtQueryUiOps *ops);
+
+/**
+ * Returns the UI operations structure to be used when doing a SRV/TXT
+ * resolve.
+ *
+ * @return The UI operations structure.
+ */
+PurpleSrvTxtQueryUiOps *purple_srv_txt_query_get_ui_ops(void);
+
+/**
+ * Get the query from a PurpleDnsQueryData
+ *
+ * @param query_data The SRV/TXT query
+ * @return The query.
+ */
+char *purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data);
+
+/**
+ * Get the type from a PurpleDnsQueryData (TXT or SRV)
+ *
+ * @param query_data The query
+ * @return The query.
+ */
+int purple_srv_txt_query_get_type(PurpleSrvTxtQueryData *query_data);
+
 #ifdef __cplusplus
 }
 #endif
============================================================
--- libpurple/dnsquery.h	944e28388107f81f3deb5429466cc5244eb6ebd3
+++ libpurple/dnsquery.h	5b75e45455b1faddc365998a81122db7c4823f31
@@ -58,7 +58,8 @@ typedef struct
  */
 typedef struct
 {
-	/** If implemented, the UI is responsible for DNS queries */
+	/** If implemented, return TRUE if the UI takes responsibility for DNS
+	  * queries. When returning FALSE, the standard implementation is used. */
 	gboolean (*resolve_host)(PurpleDnsQueryData *query_data,
 	                         PurpleDnsQueryResolvedCallback resolved_cb,
 	                         PurpleDnsQueryFailedCallback failed_cb);
============================================================
--- libpurple/gaim-compat.h	9d2db46bb46891a7dcdf471a694d990024fde4e6
+++ libpurple/gaim-compat.h	a39fb4cd97370189974e5464835b636c6a07695b
@@ -841,7 +841,7 @@
 /* from dnssrv.h */
 
 #define GaimSrvResponse   PurpleSrvResponse
-#define GaimSrvQueryData  PurpleSrvQueryData
+#define GaimSrvQueryData  PurpleSrvTxtQueryData
 #define GaimSrvCallback   PurpleSrvCallback
 
 #define gaim_srv_resolve  purple_srv_resolve


More information about the Commits mailing list