# HG changeset patch # User Daniel Atallah # Date 1303172436 0 # Node ID 5095ed88829ac090c3853556300eab55cef66226 # Parent 3248407d3cfef29830d088c56c43bea0e0c18edb# Parent 68a1efda3654de3993f22aa0d725b8ae40293cd5 merge of '649c72408dd9527b22c5e15aced51c15e325d4bb' and 'c64a4a6aaa74f97f9aa696b4f7756d93a9a243b8' diff -r 3248407d3cfe -r 5095ed88829a libpurple/dnsquery.c --- a/libpurple/dnsquery.c Mon Apr 18 21:29:45 2011 +0000 +++ b/libpurple/dnsquery.c Tue Apr 19 00:20:36 2011 +0000 @@ -153,6 +153,7 @@ resolve_ip(PurpleDnsQueryData *query_data) { struct sockaddr_in sin; + /* TODO: Use inet_pton for IPv6 support */ if (inet_aton(query_data->hostname, &sin.sin_addr)) { /* @@ -341,20 +342,17 @@ } freeaddrinfo(tmp); #else - if (!inet_aton(hostname, &sin.sin_addr)) { - struct hostent *hp; - if (!(hp = gethostbyname(hostname))) { - write_to_parent(child_out, &h_errno, sizeof(int)); - close(child_out); - if (show_debug) - printf("DNS Error: %d\n", h_errno); - _exit(0); - } - memset(&sin, 0, sizeof(struct sockaddr_in)); - memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); - sin.sin_family = hp->h_addrtype; - } else - sin.sin_family = AF_INET; + struct hostent *hp; + if (!(hp = gethostbyname(hostname))) { + write_to_parent(child_out, &h_errno, sizeof(int)); + close(child_out); + if (show_debug) + printf("DNS Error: %d\n", h_errno); + _exit(0); + } + memset(&sin, 0, sizeof(struct sockaddr_in)); + memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); + sin.sin_family = hp->h_addrtype; sin.sin_port = htons(dns_params.port); rc = 0; @@ -669,62 +667,12 @@ handle_next_queued_request(); } -static gboolean -resolve_host(gpointer data) +static void +resolve_host(PurpleDnsQueryData *query_data) { - PurpleDnsQueryData *query_data; - - query_data = data; - query_data->timeout = 0; - - if (resolve_ip(query_data)) - { - /* resolve_ip calls purple_dnsquery_resolved */ - return FALSE; - } - - if (purple_dnsquery_ui_resolve(query_data)) - { - /* The UI is handling the resolve; we're done */ - return FALSE; - } - queued_requests = g_slist_append(queued_requests, query_data); handle_next_queued_request(); - - return FALSE; -} - -PurpleDnsQueryData * -purple_dnsquery_a(const char *hostname, int port, - PurpleDnsQueryConnectFunction callback, gpointer data) -{ - PurpleDnsQueryData *query_data; - - g_return_val_if_fail(hostname != NULL, NULL); - g_return_val_if_fail(port != 0, NULL); - g_return_val_if_fail(callback != NULL, NULL); - - query_data = g_new(PurpleDnsQueryData, 1); - query_data->hostname = g_strdup(hostname); - g_strstrip(query_data->hostname); - query_data->port = port; - query_data->callback = callback; - query_data->data = data; - query_data->resolver = NULL; - - if (*query_data->hostname == '\0') - { - purple_dnsquery_destroy(query_data); - g_return_val_if_reached(NULL); - } - - purple_debug_info("dns", "DNS query for '%s' queued\n", query_data->hostname); - - query_data->timeout = purple_timeout_add(0, resolve_host, query_data); - - return query_data; } #elif defined _WIN32 /* end PURPLE_DNSQUERY_USE_FORK */ @@ -837,42 +785,100 @@ return 0; } +static void +resolve_host(PurpleDnsQueryData *query_data) +{ + GError *err = NULL; + + /* + * Spin off a separate thread to perform the DNS lookup so + * that we don't block the UI. + */ + query_data->resolver = g_thread_create(dns_thread, + query_data, FALSE, &err); + if (query_data->resolver == NULL) + { + char message[1024]; + g_snprintf(message, sizeof(message), _("Thread creation failure: %s"), + (err && err->message) ? err->message : _("Unknown reason")); + g_error_free(err); + purple_dnsquery_failed(query_data, message); + } +} + +#else /* not PURPLE_DNSQUERY_USE_FORK or _WIN32 */ + +/* + * We weren't able to do anything fancier above, so use the + * fail-safe name resolution code, which is blocking. + */ + +static void +resolve_host(PurpleDnsQueryData *query_data) +{ + struct sockaddr_in sin; + GSList *hosts = NULL; + struct hostent *hp; + gchar *hostname; +#ifdef USE_IDN + if (!dns_str_is_ascii(query_data->hostname)) { + int ret = purple_network_convert_idn_to_ascii(query_data->hostname, + &hostname); + if (ret != 0) { + char message[1024]; + g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), + query_data->hostname, ret); + purple_dnsquery_failed(query_data, message); + return; + } + } else /* fallthrough is intentional to the g_strdup */ +#endif + hostname = g_strdup(query_data->hostname); + + if(!(hp = gethostbyname(hostname))) { + char message[1024]; + g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), + query_data->hostname, h_errno); + purple_dnsquery_failed(query_data, message); + g_free(hostname); + return; + } + memset(&sin, 0, sizeof(struct sockaddr_in)); + memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); + sin.sin_family = hp->h_addrtype; + g_free(hostname); + sin.sin_port = htons(query_data->port); + + hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); + hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin))); + + purple_dnsquery_resolved(query_data, hosts); +} + +#endif /* not PURPLE_DNSQUERY_USE_FORK or _WIN32 */ + static gboolean -resolve_host(gpointer data) +initiate_resolving(gpointer data) { PurpleDnsQueryData *query_data; - GError *err = NULL; query_data = data; query_data->timeout = 0; + if (resolve_ip(query_data)) + /* resolve_ip calls purple_dnsquery_resolved */ + return FALSE; + if (purple_dnsquery_ui_resolve(query_data)) - { /* The UI is handling the resolve; we're done */ return FALSE; - } - if (!resolve_ip(query_data)) - { - /* - * Spin off a separate thread to perform the DNS lookup so - * that we don't block the UI. - */ - query_data->resolver = g_thread_create(dns_thread, - query_data, FALSE, &err); - if (query_data->resolver == NULL) - { - char message[1024]; - g_snprintf(message, sizeof(message), _("Thread creation failure: %s"), - (err && err->message) ? err->message : _("Unknown reason")); - g_error_free(err); - purple_dnsquery_failed(query_data, message); - } - } + resolve_host(query_data); return FALSE; } + PurpleDnsQueryData * purple_dnsquery_a(const char *hostname, int port, PurpleDnsQueryConnectFunction callback, gpointer data) @@ -880,7 +886,7 @@ PurpleDnsQueryData *query_data; g_return_val_if_fail(hostname != NULL, NULL); - g_return_val_if_fail(port != 0, NULL); + g_return_val_if_fail(port != 0, NULL); g_return_val_if_fail(callback != NULL, NULL); purple_debug_info("dnsquery", "Performing DNS lookup for %s\n", hostname); @@ -892,113 +898,17 @@ query_data->callback = callback; query_data->data = data; - if (strlen(query_data->hostname) == 0) + if (*query_data->hostname == '\0') { purple_dnsquery_destroy(query_data); g_return_val_if_reached(NULL); } - /* Don't call the callback before returning */ - query_data->timeout = purple_timeout_add(0, resolve_host, query_data); + query_data->timeout = purple_timeout_add(0, initiate_resolving, query_data); return query_data; } -#else /* not PURPLE_DNSQUERY_USE_FORK or _WIN32 */ - -/* - * We weren't able to do anything fancier above, so use the - * fail-safe name resolution code, which is blocking. - */ - -static gboolean -resolve_host(gpointer data) -{ - PurpleDnsQueryData *query_data; - struct sockaddr_in sin; - GSList *hosts = NULL; - - query_data = data; - query_data->timeout = 0; - - if (purple_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; - gchar *hostname; -#ifdef USE_IDN - if (!dns_str_is_ascii(query_data->hostname)) { - int ret = purple_network_convert_idn_to_ascii(query_data->hostname, - &hostname); - if (ret != 0) { - char message[1024]; - g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), - query_data->hostname, ret); - purple_dnsquery_failed(query_data, message); - return FALSE; - } - } else /* fallthrough is intentional to the g_strdup */ -#endif - hostname = g_strdup(query_data->hostname); - - if(!(hp = gethostbyname(hostname))) { - char message[1024]; - g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), - query_data->hostname, h_errno); - purple_dnsquery_failed(query_data, message); - g_free(hostname); - return FALSE; - } - memset(&sin, 0, sizeof(struct sockaddr_in)); - memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); - sin.sin_family = hp->h_addrtype; - g_free(hostname); - } else - sin.sin_family = AF_INET; - sin.sin_port = htons(query_data->port); - - hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin))); - hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin))); - - purple_dnsquery_resolved(query_data, hosts); - - return FALSE; -} - -PurpleDnsQueryData * -purple_dnsquery_a(const char *hostname, int port, - PurpleDnsQueryConnectFunction callback, gpointer data) -{ - PurpleDnsQueryData *query_data; - - g_return_val_if_fail(hostname != NULL, NULL); - g_return_val_if_fail(port != 0, NULL); - g_return_val_if_fail(callback != NULL, NULL); - - query_data = g_new(PurpleDnsQueryData, 1); - query_data->hostname = g_strdup(hostname); - g_strstrip(query_data->hostname); - query_data->port = port; - query_data->callback = callback; - query_data->data = data; - - if (strlen(query_data->hostname) == 0) - { - purple_dnsquery_destroy(query_data); - g_return_val_if_reached(NULL); - } - - /* Don't call the callback before returning */ - query_data->timeout = purple_timeout_add(0, resolve_host, query_data); - - return query_data; -} - -#endif /* not PURPLE_DNSQUERY_USE_FORK or _WIN32 */ void purple_dnsquery_destroy(PurpleDnsQueryData *query_data)