static void resolve_host(PurpleDnsQueryData *query_data) { queued_requests = g_slist_append(queued_requests, query_data); handle_next_queued_request(); }
static void host_resolved(gpointer data, gint source, PurpleInputCondition cond) { PurpleDnsQueryData *query_data; int rc, err; GSList *hosts = NULL; struct sockaddr *addr = NULL; size_t addrlen; char message[1024]; query_data = data; purple_debug_info("dns", "Got response for '%s'\n", query_data->hostname); purple_input_remove(query_data->resolver->inpa); query_data->resolver->inpa = 0; rc = read(query_data->resolver->fd_out, &err, sizeof(err)); if ((rc == 4) && (err != 0)) { #ifdef HAVE_GETADDRINFO g_snprintf(message, sizeof(message), _("Error resolving %s:\n%s"), query_data->hostname, purple_gai_strerror(err)); #else g_snprintf(message, sizeof(message), _("Error resolving %s: %d"), query_data->hostname, err); #endif /* Re-read resolv.conf and friends in case DNS servers have changed */ res_init(); purple_dnsquery_failed(query_data, message); } else if (rc > 0) { /* Success! */ while (rc > 0) { rc = read(query_data->resolver->fd_out, &addrlen, sizeof(addrlen)); if (rc > 0 && addrlen > 0 && addrlen < MAX_ADDR_RESPONSE_LEN) { addr = g_malloc(addrlen); rc = read(query_data->resolver->fd_out, addr, addrlen); hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen)); hosts = g_slist_append(hosts, addr); } else { break; } } /* wait4(resolver->dns_pid, NULL, WNOHANG, NULL); */ purple_dnsquery_resolved(query_data, hosts); } else if (rc == -1) { g_snprintf(message, sizeof(message), _("Error reading from resolver process:\n%s"), g_strerror(errno)); purple_dnsquery_failed(query_data, message); } else if (rc == 0) { g_snprintf(message, sizeof(message), _("Resolver process exited without answering our request")); purple_dnsquery_failed(query_data, message); } handle_next_queued_request(); }
static gboolean resolve_host(gpointer data) { PurpleDnsQueryData *query_data; query_data = data; query_data->timeout = 0; handle_next_queued_request(); return FALSE; }
static void handle_next_queued_request() { PurpleDnsQueryData *query_data; PurpleDnsQueryResolverProcess *resolver; if (queued_requests == NULL) /* No more DNS queries, yay! */ return; query_data = queued_requests->data; queued_requests = g_slist_delete_link(queued_requests, queued_requests); if (purple_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 * set to the PurpleDnsQueryResolverProcess. Otherwise, resolver * will be NULL and we'll need to create a new DNS request child. */ while (free_dns_children != NULL) { resolver = free_dns_children->data; free_dns_children = g_slist_remove(free_dns_children, resolver); if (send_dns_request_to_child(query_data, resolver)) /* We found an acceptable child, yay */ break; } /* We need to create a new DNS request child */ if (query_data->resolver == NULL) { if (number_of_dns_children >= MAX_DNS_CHILDREN) { /* Apparently all our children are busy */ queued_requests = g_slist_prepend(queued_requests, query_data); return; } resolver = purple_dnsquery_resolver_new(purple_debug_is_enabled()); if (resolver == NULL) { purple_dnsquery_failed(query_data, _("Unable to create new resolver process\n")); return; } if (!send_dns_request_to_child(query_data, resolver)) { purple_dnsquery_failed(query_data, _("Unable to send request to resolver process\n")); return; } } query_data->resolver->inpa = purple_input_add(query_data->resolver->fd_out, PURPLE_INPUT_READ, host_resolved, query_data); }