# HG changeset patch # User Evan Schoenberg # Date 1172429005 0 # Node ID 6a0b9734a7229a1be5f196246bb9d1f031367265 # Parent 40025258611979f86d71bed930ac0d747cb1873a The UI can now use the GaimDnsQueryUiOps to handle DNS resolving itself; if this is done, the platform-specific DNS query code won't be used. This will be used in Adium to use an efficient threads-based DNS resolve (since Adium is already multithreaded, this is significantly cheaper than fork()). diff -r 400252586119 -r 6a0b9734a722 libpurple/dnsquery.c --- a/libpurple/dnsquery.c Sun Feb 25 18:35:08 2007 +0000 +++ b/libpurple/dnsquery.c Sun Feb 25 18:43:25 2007 +0000 @@ -35,6 +35,8 @@ * DNS query API **************************************************************************/ +static GaimDnsQueryUiOps *dns_query_ui_ops = NULL; + typedef struct _GaimDnsQueryResolverProcess GaimDnsQueryResolverProcess; struct _GaimDnsQueryData { @@ -114,6 +116,20 @@ gaim_dnsquery_destroy(query_data); } +static gboolean +gaim_dnsquery_ui_resolve(GaimDnsQueryData *query_data) +{ + GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops(); + + if (ops && ops->resolve_host) + { + if (ops->resolve_host(query_data, gaim_dnsquery_resolved, gaim_dnsquery_failed)) + return TRUE; + } + + return FALSE; +} + #if defined(__unix__) || defined(__APPLE__) /* @@ -157,7 +173,7 @@ #endif #ifdef HAVE_SIGNAL_H - gaim_restore_default_signal_handlers(); + gaim_restore_default_signal_handlers(); signal(SIGTRAP, trap_gdb_bug); #endif @@ -455,6 +471,13 @@ query_data = queued_requests->data; queued_requests = g_slist_delete_link(queued_requests, queued_requests); + if (gaim_dnsquery_ui_resolve(query_data)) + { + /* The UI is handling the resolve; we're done */ + handle_next_queued_request(); + return; + } + /* * If we have any children, attempt to have them perform the DNS * query. If we're able to send the query then resolver will be @@ -704,6 +727,12 @@ query_data = data; query_data->timeout = 0; + if (gaim_dnsquery_ui_resolve(query_data)) + { + /* The UI is handling the resolve; we're done */ + return FALSE; + } + if (inet_aton(query_data->hostname, &sin.sin_addr)) { /* @@ -788,6 +817,12 @@ query_data = data; query_data->timeout = 0; + if (gaim_dnsquery_ui_resolve(query_data)) + { + /* The UI is handling the resolve; we're done */ + return FALSE; + } + if (!inet_aton(query_data->hostname, &sin.sin_addr)) { struct hostent *hp; if(!(hp = gethostbyname(query_data->hostname))) { @@ -846,6 +881,11 @@ void gaim_dnsquery_destroy(GaimDnsQueryData *query_data) { + GaimDnsQueryUiOps *ops = gaim_dnsquery_get_ui_ops(); + + if (ops && ops->destroy) + ops->destroy(query_data); + #if defined(__unix__) || defined(__APPLE__) queued_requests = g_slist_remove(queued_requests, query_data); @@ -887,6 +927,36 @@ g_free(query_data); } +char * +gaim_dnsquery_get_host(GaimDnsQueryData *query_data) +{ + g_return_val_if_fail(query_data != NULL, NULL); + + return query_data->hostname; +} + +int +gaim_dnsquery_get_port(GaimDnsQueryData *query_data) +{ + g_return_val_if_fail(query_data != NULL, NULL); + + return query_data->port; +} + +void +gaim_dnsquery_set_ui_ops(GaimDnsQueryUiOps *ops) +{ + dns_query_ui_ops = ops; +} + +GaimDnsQueryUiOps * +gaim_dnsquery_get_ui_ops(void) +{ + g_return_val_if_fail(dns_query_ui_ops != NULL, NULL); + + return dns_query_ui_ops; +} + void gaim_dnsquery_init(void) { diff -r 400252586119 -r 6a0b9734a722 libpurple/dnsquery.h --- a/libpurple/dnsquery.h Sun Feb 25 18:35:08 2007 +0000 +++ b/libpurple/dnsquery.h Sun Feb 25 18:43:25 2007 +0000 @@ -27,6 +27,7 @@ #include #include "eventloop.h" +#include "account.h" typedef struct _GaimDnsQueryData GaimDnsQueryData; @@ -37,8 +38,26 @@ */ typedef void (*GaimDnsQueryConnectFunction)(GSList *hosts, gpointer data, const char *error_message); +/** + * Callbacks used by the UI if it handles resolving DNS + */ +typedef void (*GaimDnsQueryResolvedCallback) (GaimDnsQueryData *query_data, GSList *hosts); +typedef void (*GaimDnsQueryFailedCallback) (GaimDnsQueryData *query_data, const gchar *error_message); -#include "account.h" +/** + * DNS Request UI operations + */ +typedef struct +{ + /* If implemented, the UI is responsible for DNS queries */ + gboolean (*resolve_host)(GaimDnsQueryData *query_data, GaimDnsQueryResolvedCallback resolved_cb, GaimDnsQueryFailedCallback failed_cb); + + /* After destroy is called, query_data will be feed, so this must + * cancel any further use of it the UI would do. Unneeded if + * resolve_host is not implemented. + */ + void (*destroy)(GaimDnsQueryData *query_data); +} GaimDnsQueryUiOps; #ifdef __cplusplus extern "C" { @@ -72,6 +91,39 @@ void gaim_dnsquery_destroy(GaimDnsQueryData *query_data); /** + * Sets the UI operations structure to be used when doing a DNS + * 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 gaim_dnsquery_set_ui_ops(GaimDnsQueryUiOps *ops); + +/** + * Returns the UI operations structure to be used when doing a DNS + * resolve. + * + * @return The UI operations structure. + */ +GaimDnsQueryUiOps *gaim_dnsquery_get_ui_ops(void); + +/** + * Get the host associated with a GaimDnsQueryData + * + * @param query_data The DNS query + * @return The host. + */ +char *gaim_dnsquery_get_host(GaimDnsQueryData *query_data); + +/** + * Get the port associated with a GaimDnsQueryData + * + * @param query_data The DNS query + * @return The port. + */ +int gaim_dnsquery_get_port(GaimDnsQueryData *query_data); + +/** * Initializes the DNS query subsystem. */ void gaim_dnsquery_init(void);