*** \postgresql-snapshot\src\port\getaddrinfo.c	Wed Aug 24 11:54:09 2005
--- \postgresql-patched\src\port\getaddrinfo.c	Wed Aug 24 11:53:05 2005
***************
*** 8,18 ****
   * platform, we'll need to split this file and provide a separate configure
   * test for getnameinfo().
   *
   *
   * Copyright (c) 2003-2005, PostgreSQL Global Development Group
   *
   * IDENTIFICATION
!  *	  $PostgreSQL: pgsql/src/port/getaddrinfo.c,v 1.17 2005/07/28 04:03:14 tgl Exp $
   *
   *-------------------------------------------------------------------------
   */
--- 8,22 ----
   * platform, we'll need to split this file and provide a separate configure
   * test for getnameinfo().
   *
+  * Windows may or may not have these routines, so we handle Windows special
+  * by dynamically checking for their existance.  If they already exist, we
+  * use the Windows native routines, but if not, we use our own.
+  *
   *
   * Copyright (c) 2003-2005, PostgreSQL Global Development Group
   *
   * IDENTIFICATION
!  *	  $PostgreSQL: pgsql/src/port/getaddrinfo.c,v 1.16 2005/01/01 20:44:33 tgl Exp $
   *
   *-------------------------------------------------------------------------
   */
***************
*** 29,34 ****
--- 33,124 ----
  
  #include "getaddrinfo.h"
  
+ 
+ #ifdef WIN32
+ 
+ #define WIN32_LEAN_AND_MEAN
+ /* Bring in windows.h for LoadLibrary, FreeLibrary, and GetProcAddress routines */
+ #include <windows.h>
+ 
+ /* 
+  * The native routines may or may not exist on the Windows platform we are on,
+  * so we dynamically look up the routines, and call them via function pointers.
+  * Here we need to declare what the function pointers look like
+  */
+ typedef
+ int
+ (__stdcall * getaddrinfo_ptr_t)(const char * nodename, const char * servname,
+      const struct addrinfo * hints, struct addrinfo ** res);
+ 
+ typedef
+ void
+ (__stdcall * freeaddrinfo_ptr_t)(struct addrinfo * ai);
+ 
+ typedef
+ int
+ (__stdcall * getnameinfo_ptr_t)(const struct sockaddr * sa, int salen,
+      char *  host, int hostlen, char * serv, int servlen, int flags);
+ 
+ /* static pointers to the native Windows IPv6 routines, so we only do the lookup once. */
+ static getaddrinfo_ptr_t getaddrinfo_ptr = NULL;
+ static freeaddrinfo_ptr_t freeaddrinfo_ptr = NULL;
+ static getnameinfo_ptr_t getnameinfo_ptr = NULL;
+ 
+ static
+ bool haveNativeWindowsIPv6routines(void)
+ {
+     void * hLibrary  = NULL;
+     static bool  alreadyLookedForIpv6routines    = FALSE;
+    
+     if (alreadyLookedForIpv6routines)            
+         return (getaddrinfo_ptr != NULL);
+ 
+     /* 
+ 	 * For Windows XP and Windows 2003 (and longhorn/vista), the IPv6
+      * routines are present the WinSock 2 library (ws2_32.dll).  Try that first
+ 	 */
+ 
+     hLibrary = LoadLibraryA("ws2_32");
+ 
+ 	if (hLibrary == NULL || GetProcAddress(hLibrary, "getaddrinfo") == NULL)
+ 	{
+ 		/* Well, ws2_32 doesn't exist, or more likely doesn't have getaddrinfo. */
+ 		if (hLibrary != NULL)
+ 			FreeLibrary(hLibrary);
+ 
+ 		/* In Windows 2000, there was only the IPv6 Technology Preview        
+ 		 * look in the IPv6 WinSock library (wship6.dll).
+ 		 */
+ 
+ 		hLibrary = LoadLibraryA("wship6");
+ 	}
+ 
+ 	/* If hLibrary is null, we couldn't find a dll that supports the functions */
+     if (hLibrary != NULL)
+     {
+ 		/* We found a dll, so now get the addresses of the routines */
+ 
+         getaddrinfo_ptr = GetProcAddress(hLibrary, "getaddrinfo");
+ 		freeaddrinfo_ptr = GetProcAddress(hLibrary, "freeaddrinfo");
+ 		getnameinfo_ptr = GetProcAddress(hLibrary, "getnameinfo");
+ 
+ 		/* If any one of the routines is missing, let's play it safe and ignore them all */
+         if (getaddrinfo_ptr == NULL || freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL)
+         {
+             FreeLibrary(hLibrary);
+             hLibrary = NULL;
+ 			getaddrinfo_ptr = NULL;
+ 			freeaddrinfo_ptr = NULL;
+ 			getnameinfo_ptr = NULL;
+         }
+     }
+         
+     alreadyLookedForIpv6routines = TRUE;
+     return (getaddrinfo_ptr != NULL); 
+ }
+ #endif 
+ 
+ 
  /*
   * get address info for ipv4 sockets.
   *
***************
*** 47,52 ****
--- 137,151 ----
  			   *psin;
  	struct addrinfo hints;
  
+ #ifdef WIN32
+ 	/* 
+ 	 * If Windows has native IPv6 support, use the native Windows routine.
+ 	 * Otherwise, fall through and use our own code.
+ 	 */
+ 	if (haveNativeWindowsIPv6routines())
+ 		return (*getaddrinfo_ptr)(node,service,hintp,res);
+ #endif
+ 
  	if (hintp == NULL)
  	{
  		memset(&hints, 0, sizeof(hints));
***************
*** 160,165 ****
--- 259,275 ----
  {
  	if (res)
  	{
+ #ifdef WIN32
+ 		/* 
+ 		 * If Windows has native IPv6 support, use the native Windows routine.
+ 		 * Otherwise, fall through and use our own code.
+ 		 */
+ 		if (haveNativeWindowsIPv6routines())
+ 		{
+ 			(*freeaddrinfo_ptr)(node,service,hintp,res);
+ 			return;
+ 		}
+ #endif
  		if (res->ai_addr)
  			free(res->ai_addr);
  		free(res);
***************
*** 216,221 ****
--- 326,341 ----
  			char *node, int nodelen,
  			char *service, int servicelen, int flags)
  {
+ 
+ #ifdef WIN32
+ 	/* 
+ 	 * If Windows has native IPv6 support, use the native Windows routine.
+ 	 * Otherwise, fall through and use our own code.
+ 	 */
+ 	if (haveNativeWindowsIPv6routines())
+ 		return (*getnameinfo_ptr)(sa,salen,node,nodelen,service,servicelen,flags);
+ #endif
+ 
  	/* Invalid arguments. */
  	if (sa == NULL || (node == NULL && service == NULL))
  		return EAI_FAIL;
