--- pan-0.112/pan/tasks/socket-impl-gio.cc	2006-09-08 13:25:08.000000000 -0500
+++ pan-devel/pan/tasks/socket-impl-gio.cc	2006-09-18 16:24:12.000000000 -0500
@@ -91,15 +91,62 @@
 
 namespace 
 {
+  typedef int (*t_getaddrinfo)(const char *,const char *, const struct addrinfo*, struct addrinfo **);
+  t_getaddrinfo p_getaddrinfo (0);
+
+  typedef void (*t_freeaddrinfo)(struct addrinfo*);
+  t_freeaddrinfo p_freeaddrinfo (0);
+  
   void ensure_module_inited (void)
   {
     static bool inited (false);
 
     if (!inited)
     {
+      p_freeaddrinfo=NULL;
+      p_getaddrinfo=NULL;
+      
 #ifdef G_OS_WIN32
       WSADATA wsaData;
       WSAStartup(MAKEWORD(2,2), &wsaData);
+      
+      char sysdir[MAX_PATH], path[MAX_PATH+8];
+      
+      if(GetSystemDirectory(sysdir,MAX_PATH)!=0)
+      {
+        HMODULE lib=NULL;
+        FARPROC pfunc=NULL;
+        const char *libs[]={"ws2_32","wship6",NULL};
+        
+        for(const char **p=libs;*p!=NULL;++p)
+        {
+          g_snprintf(path,MAX_PATH+8,"%s\\%s",sysdir,*p);
+          lib=LoadLibrary(path);
+          if(!lib)
+            continue;
+          pfunc=GetProcAddress(lib,"getaddrinfo");
+          if(!pfunc)
+          {
+            FreeLibrary(lib);
+            lib=NULL;
+            continue;
+          }
+          p_getaddrinfo=reinterpret_cast<t_getaddrinfo>(pfunc);
+          pfunc=GetProcAddress(lib,"freeaddrinfo");
+          if(!pfunc)
+          {
+            FreeLibrary(lib);
+            lib=NULL;
+            p_getaddrinfo=NULL;
+            continue;
+          }
+          p_freeaddrinfo=reinterpret_cast<t_freeaddrinfo>(pfunc);
+          break;
+        }
+      }
+#else
+      p_freeaddrinfo=::freeaddrinfo;
+      p_getaddrinfo=::getaddrinfo;
 #endif
       inited = true;
     }
@@ -110,7 +157,6 @@
   {
     int err;
     int sockfd;
-    ensure_module_inited ();
 
 #ifndef G_OS_WIN32
     signal (SIGPIPE, SIG_IGN);
@@ -122,92 +168,96 @@
     g_snprintf (hostbuf, sizeof(hostbuf), "%*.*s", host.len, host.len, host.str);
     g_snprintf (portbuf, sizeof(portbuf), "%d", port);
 
-#if defined(G_OS_WIN32) && _WIN32_WINNT <= 0x0500
-#warning "Compiling in backward compatibility mode, may lead to problems"
-
-    struct hostent * ans = isalpha (hostbuf[0])
-      ? gethostbyname (hostbuf)
-      : gethostbyaddr (hostbuf, host.len, AF_INET);
-
-    err = WSAGetLastError();
-    if (err || !ans) {
-      PrintLastError(err);	
-      return NULL;
-    }
-
-    /* try opening socket */
-    sockfd = socket (AF_INET, SOCK_STREAM, 0 /*IPPROTO_TCP*/);
-    if (sockfd < 0) {
-      g_message ("couldn't create a socket.");
-      return NULL;
-    }
-
-    /* Try connecting */
-    int i = 0;
-    err = -1;
-    struct sockaddr_in server;
-    memset (&server, 0, sizeof(struct sockaddr_in));
-    while (err && ans->h_addr_list[i])
+#ifdef G_OS_WIN32 // windows might not have getaddrinfo...
+    if (!p_getaddrinfo)
     {
-      char *addr = ans->h_addr_list[i];
-      memcpy (&server.sin_addr, addr, ans->h_length);
-      server.sin_family = AF_INET;
-      server.sin_port = htons(port);
-      g_snprintf (hostbuf, sizeof(hostbuf),
-                  "Trying host %u.%u.%u.%u, port %d\n",
-                  addr[0], addr[1], addr[2], addr[3], port);
-      OutputDebugString (hostbuf);
-      ++i;
+      struct hostent * ans = isalpha (hostbuf[0])
+        ? gethostbyname (hostbuf)
+        : gethostbyaddr (hostbuf, host.len, AF_INET);
+
+      err = WSAGetLastError();
+      if (err || !ans) {
+        PrintLastError(err);	
+        return 0;
+      }
 
-      err = connect (sockfd,(struct sockaddr*)&server, sizeof(server));
-      if (err) PrintLastError(err);
-    }
-    if (!err)
-      OutputDebugString ("Connection seems to be opened");
-    else {
-      closesocket (sockfd);
-      PrintLastError(err);
-      return NULL;
-    }
+      // try opening the socket
+      sockfd = socket (AF_INET, SOCK_STREAM, 0 /*IPPROTO_TCP*/);
+      if (sockfd < 0) {
+        g_message ("couldn't create a socket.");
+        return 0;
+      }
 
-#else	
+      // Try connecting
+      int i = 0;
+      err = -1;
+      struct sockaddr_in server;
+      memset (&server, 0, sizeof(struct sockaddr_in));
+      while (err && ans->h_addr_list[i])
+      {
+        char *addr = ans->h_addr_list[i];
+        memcpy (&server.sin_addr, addr, ans->h_length);
+        server.sin_family = AF_INET;
+        server.sin_port = htons(port);
+        g_snprintf (hostbuf, sizeof(hostbuf),
+                    "Trying host %u.%u.%u.%u, port %d\n",
+                    addr[0], addr[1], addr[2], addr[3], port);
+        OutputDebugString (hostbuf);
+        ++i;
 
-    struct addrinfo hints;
-    memset (&hints, 0, sizeof(struct addrinfo));
-    hints.ai_flags = 0;
-    hints.ai_family = 0;
-    hints.ai_socktype = SOCK_STREAM;
-    struct addrinfo * ans;
-    err = ::getaddrinfo (hostbuf, portbuf, &hints, &ans);
-    if (err != 0) {
-      g_message ("Lookup error: %s", gai_strerror(err));
-      return NULL;
-    }
+        err = connect (sockfd,(struct sockaddr*)&server, sizeof(server));
+        if (err) PrintLastError(err);
+      }
 
-    // try to open a socket on any ipv4 or ipv6 addresses we found
-    sockfd = -1;
-    for (struct addrinfo * walk(ans); walk && sockfd<0; walk=walk->ai_next)
-    {
-      // only use ipv4 or ipv6 addresses
-      if ((walk->ai_family!=PF_INET) && (walk->ai_family!=PF_INET6))
-        continue;
-
-      // try to create a socket...
-      sockfd = ::socket (walk->ai_family, walk->ai_socktype, walk->ai_protocol);
-      if (sockfd < 0)
-        continue;
-
-      // and make a connection
-      if (::connect (sockfd, ans->ai_addr, ans->ai_addrlen) < 0) {
-        g_message ("Connect failed: %s", g_strerror(errno));
+      if (!err)
+        OutputDebugString ("Connection seems to be opened");
+      else {
         closesocket (sockfd);
-        sockfd = -1;
+        PrintLastError(err);
+        return NULL;
       }
     }
-    ::freeaddrinfo (ans);
+    else
+#endif // #ifdef G_OS_WIN32 ...
+    {
+      struct addrinfo hints;
+      memset (&hints, 0, sizeof(struct addrinfo));
+      hints.ai_flags = 0;
+      hints.ai_family = 0;
+      hints.ai_socktype = SOCK_STREAM;
+      struct addrinfo * ans;
+      err = p_getaddrinfo (hostbuf, portbuf, &hints, &ans);
+      if (err != 0) {
+        g_message ("Lookup error: %s", gai_strerror(err));
+        return 0;
+      }
 
-#endif
+      // try to open a socket on any ipv4 or ipv6 addresses we found
+      sockfd = -1;
+      for (struct addrinfo * walk(ans); walk && sockfd<0; walk=walk->ai_next)
+      {
+        // only use ipv4 or ipv6 addresses
+        if ((walk->ai_family!=PF_INET) && (walk->ai_family!=PF_INET6))
+          continue;
+
+        // try to create a socket...
+        sockfd = ::socket (walk->ai_family, walk->ai_socktype, walk->ai_protocol);
+        if (sockfd < 0)
+          continue;
+
+        // and make a connection
+        if (::connect (sockfd, ans->ai_addr, ans->ai_addrlen) < 0) {
+          g_message ("Connect failed: %s", g_strerror(errno));
+          closesocket (sockfd);
+          sockfd = -1;
+        }
+      }
 
+      // cleanup
+      p_freeaddrinfo (ans);
+    }
+
+    // create the giochannel...
     GIOChannel * channel (0);
     if (sockfd < 0)
       g_message ("couldn't create a socket.");
@@ -539,6 +589,8 @@
                                               int                port,
                                               Listener         * listener)
 {
+  ensure_module_inited ();
+
   // farm this out to a worker thread so that the main thread
   // doesn't block while we open the socket.
   g_thread_create (create_socket_thread_func,
