changeset 10237:2f6dcbaaabe0

[gaim-migrate @ 11373] Asynchronous host name resolution for win32. committer: Tailor Script <tailor@pidgin.im>
author Herman Bloggs <hermanator12002@yahoo.com>
date Mon, 22 Nov 2004 18:52:44 +0000
parents 1a62febbf3d6
children b8b4769d9800
files src/Makefile.mingw src/proxy.c
diffstat 2 files changed, 87 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.mingw	Mon Nov 22 18:26:12 2004 +0000
+++ b/src/Makefile.mingw	Mon Nov 22 18:52:44 2004 +0000
@@ -164,6 +164,7 @@
 			-latk-1.0 \
 			-lpango-1.0 \
 			-lglib-2.0 \
+			-lgthread-2.0 \
 			-lgdk-win32-2.0 \
 			-lgobject-2.0 \
 			-lintl \
--- a/src/proxy.c	Mon Nov 22 18:26:12 2004 +0000
+++ b/src/proxy.c	Mon Nov 22 18:52:44 2004 +0000
@@ -631,7 +631,87 @@
 
 	return 0;
 }
-#else /* __unix__ */
+
+elif defined _WIN32 /* end __unix__ */
+
+/* Note: The below win32 implementation is actually platform independent.
+   Perhaps this can be used in place of the above platform dependent code.
+*/ 
+
+typedef struct _dns_tdata {
+	char *hostname;
+	int port;
+	dns_callback_t callback;
+	gpointer data;
+	GSList *hosts;
+	char *errmsg;
+} dns_tdata;
+
+static gboolean dns_main_thread_cb(gpointer data) {
+	dns_tdata *td = (dns_tdata*)data;
+	td->callback(td->hosts, td->data, td->errmsg);
+	g_free(td->hostname);
+	g_free(td);
+	return FALSE;
+}
+
+static gpointer dns_thread(gpointer data) {
+	struct sockaddr_in sin;
+	dns_tdata *td = (dns_tdata*)data;
+	struct hostent *hp;
+
+	if(!(hp = gethostbyname(td->hostname)))
+		goto failure;
+	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(td->port);
+
+	td->hosts = g_slist_append(td->hosts, GINT_TO_POINTER(sizeof(sin)));
+	td->hosts = g_slist_append(td->hosts, g_memdup(&sin, sizeof(sin)));
+	/* back to main thread */
+	g_idle_add(dns_main_thread_cb, td);
+	return 0;
+ failure:
+	g_free(td->hostname);
+	g_free(td);
+	return 0;
+} 
+
+int gaim_gethostbyname_async(const char *hostname, int port,
+							  dns_callback_t callback, gpointer data) {
+	dns_tdata *td;
+	struct sockaddr_in sin;
+	GError* err = NULL;
+
+	if(inet_aton(hostname, &sin.sin_addr)) {
+		GSList *hosts = NULL;
+		sin.sin_family = AF_INET;
+		sin.sin_port = htons(port);
+		hosts = g_slist_append(hosts, GINT_TO_POINTER(sizeof(sin)));
+		hosts = g_slist_append(hosts, g_memdup(&sin, sizeof(sin)));
+		callback(hosts, data, NULL);
+		return 0;
+	}
+
+	gaim_debug_info("dns", "DNS Lookup for: %s\n", hostname);
+	td = g_new0(dns_tdata, 1);
+	td->hostname = g_strdup(hostname);
+	td->port = port;
+	td->callback = callback;
+	td->data = data;
+
+	if(!g_thread_create(dns_thread, td, FALSE, &err)) {
+		gaim_debug_error("dns", "DNS thread create failure: %s\n", err?err->message:"");
+		g_error_free(err);
+		g_free(td->hostname);
+		g_free(td);
+		return -1;
+	}
+	return 0;
+}
+
+#else /* not __unix__ or _WIN32 */
 
 typedef struct {
 	gpointer data;
@@ -682,7 +762,7 @@
 	return 0;
 }
 
-#endif /* __unix__ */
+#endif /* not __unix__ or _WIN32 */
 
 static void
 no_one_calls(gpointer data, gint source, GaimInputCondition cond)
@@ -1638,6 +1718,10 @@
 								proxy_pref_cb, NULL);
 	gaim_prefs_connect_callback(handle, "/core/proxy/password",
 								proxy_pref_cb, NULL);
+#ifdef _WIN32
+	if(!g_thread_supported())
+		g_thread_init(NULL);
+#endif
 }
 
 void *