--- a/libpurple/protocols/gg/resolver-purple.c Thu Dec 17 20:05:56 2015 -0600
+++ b/libpurple/protocols/gg/resolver-purple.c Thu Dec 17 20:06:15 2015 -0600
@@ -29,22 +29,22 @@
#include "resolver-purple.h"
static int ggp_resolver_purple_start(int *fd, void **private_data,
static void ggp_resolver_purple_cleanup(void **private_data, int force);
-static void ggp_resolver_purple_cb(GSList *hosts, gpointer cbdata,
- const char *error_message);
+static void ggp_resolver_purple_cb(GObject *sender, GAsyncResult *res, gpointer data); - PurpleDnsQueryData *purpleQuery;
+ GCancellable *cancellable; @@ -64,67 +64,72 @@
-void ggp_resolver_purple_cb(GSList *hosts, gpointer cbdata,
- const char *error_message)
+void ggp_resolver_purple_cb(GObject *sender, GAsyncResult *res, gpointer cbdata) { + GList *addresses = NULL, *in_addrs = NULL, *l = NULL; + gsize native_size = 0; /* this is kind of dirty, but it'll be initialized before we use it */ ggp_resolver_purple_data *data = (ggp_resolver_purple_data*)cbdata;
const int fd = data->pipes[1];
- int ipv4_count, all_count, write_size;
- struct in_addr *addresses;
- purple_debug_misc("gg", "ggp_resolver_purple_cb(%p, %p, \"%s\")\n",
- hosts, cbdata, error_message);
- data->purpleQuery = NULL;
+ addresses = g_resolver_lookup_by_name_finish(g_resolver_get_default(), res, &error); + if(addresses == NULL) { + purple_debug_error("gg", "ggp_resolver_purple_cb failed: %s\n",
- purple_debug_error("gg", "ggp_resolver_purple_cb failed: %s\n",
+ purple_debug_misc("gg", "ggp_resolver_purple_cb succeeded: (%p, %p)\n", - all_count = g_slist_length(hosts);
- g_assert(all_count % 2 == 0);
- addresses = malloc((all_count + 1) * sizeof(struct in_addr));
+ g_object_unref(G_OBJECT(data->cancellable)); + data->cancellable = NULL;
- while (hosts && (hosts = g_slist_delete_link(hosts, hosts))) {
- common_sockaddr_t addr;
- char dst[INET6_ADDRSTRLEN];
+ for(l = addresses; l; l = l->next) { + GInetAddress *inet_address = G_INET_ADDRESS(l->data); + GSocketFamily family = G_SOCKET_FAMILY_INVALID; + gchar *ip_address = g_inet_address_to_string(inet_address); - memcpy(&addr, hosts->data, sizeof(addr));
+ family = g_inet_address_get_family(inet_address); + case G_SOCKET_FAMILY_IPV4: + purple_debug_misc("gg", "ggp_resolver_purple_cb " + "ipv4: %s\n", ip_address); - if (addr.sa.sa_family == AF_INET6) {
- inet_ntop(addr.sa.sa_family, &addr.in6.sin6_addr,
- purple_debug_misc("gg", "ggp_resolver_purple_cb "
- "ipv6 (ignore): %s\n", dst);
- } else if (addr.sa.sa_family == AF_INET) {
- inet_ntop(addr.sa.sa_family, &addr.in.sin_addr,
- purple_debug_misc("gg", "ggp_resolver_purple_cb "
+ native_size = g_inet_address_get_native_size(inet_address); + in_addrs = g_list_append(in_addrs, g_memdup(g_inet_address_to_bytes(inet_address), native_size)); + case G_SOCKET_FAMILY_IPV6: + purple_debug_misc("gg", "ggp_resolver_purple_cb " + "ipv6 (ignore): %s\n", ip_address); - g_assert(ipv4_count < all_count);
- addresses[ipv4_count++] = addr.in.sin_addr;
- purple_debug_warning("gg", "ggp_resolver_purple_cb "
- "unexpected sa_family: %d\n",
+ purple_debug_warning("gg", "ggp_resolver_purple_cb " + "unexpected sa_family: %d\n",
- hosts = g_slist_delete_link(hosts, hosts);
- addresses[ipv4_count].s_addr = INADDR_NONE;
+ for(l = in_addrs; l; l = l->next) { + gint write_size = native_size; + if(write(fd, l->data, write_size) != write_size) { + purple_debug_error("gg", + "ggp_resolver_purple_cb write error on %p\n", l->data); - write_size = (ipv4_count + 1) * sizeof(struct in_addr);
- if (write(fd, addresses, write_size) != write_size) {
- purple_debug_error("gg",
- "ggp_resolver_purple_cb write error\n");
+ g_resolver_free_addresses(addresses); int ggp_resolver_purple_start(int *fd, void **private_data,
@@ -136,7 +141,7 @@
data = malloc(sizeof(ggp_resolver_purple_data));
*private_data = (void*)data;
- data->purpleQuery = NULL;
+ data->cancellable = NULL; @@ -150,10 +155,15 @@
/* account and port is unknown in this context */
- data->purpleQuery = purple_dnsquery_a(NULL, hostname, 80,
- ggp_resolver_purple_cb, (gpointer)data);
+ data->cancellable = g_cancellable_new(); - if (!data->purpleQuery) {
+ g_resolver_lookup_by_name_async(g_resolver_get_default(), + ggp_resolver_purple_cb, + if (!data->cancellable) { purple_debug_error("gg", "ggp_resolver_purple_start: "
"unable to call purple_dnsquery_a\n");
ggp_resolver_purple_cleanup(private_data, 0);
@@ -175,8 +185,12 @@
- purple_dnsquery_destroy(data->purpleQuery);
+ if (G_IS_CANCELLABLE(data->cancellable)) { + g_cancellable_cancel(data->cancellable); + g_object_unref(G_OBJECT(data->cancellable));