debug(("Error %ld: %s (h=%lx)\n", err, lpMsgBuf, h));
SockAddr sk_namelookup(char *host, char **canonicalname){    SockAddr ret = smalloc(sizeof(struct SockAddr_tag));    unsigned long a;    struct hostent *h = NULL;    /* Clear the structure and default to IPv4. */    memset(ret, 0, sizeof(struct SockAddr_tag));    ret->family = 0;		       /* We set this one when we have resolved the host. */    *canonicalname = ret->realhost;    /* This makes sure we always have a hostname to return. */    if ( (a = inet_addr(host)) == (unsigned long) INADDR_NONE)    {#ifdef IPV6	/* Try to get the getaddrinfo() function from wship6.dll */	/* This way one doesn't need to have IPv6 dll's to use PuTTY and	 * it will fallback to IPv4. */	typedef int (CALLBACK* FGETADDRINFO)(const char *nodename,					     const char *servname,					     const struct addrinfo *hints,					     struct addrinfo **res);	FGETADDRINFO fGetAddrInfo = NULL;	HINSTANCE dllWSHIP6 = LoadLibrary("wship6.dll");	if (dllWSHIP6)	    fGetAddrInfo = (FGETADDRINFO)GetProcAddress(dllWSHIP6,							"getaddrinfo");	/*	 * Use fGetAddrInfo when it's available (which usually also	 * means IPv6 is installed...)	 */	if (fGetAddrInfo)	{	    /*debug(("Resolving \"%s\" with getaddrinfo()  (IPv4+IPv6 capable)...\n", host)); */	    if (fGetAddrInfo(host, NULL, NULL, &ret->ai) == 0)		ret->family = ret->ai->ai_family;	}	else#endif	    /*	     * Otherwise use the IPv4-only gethostbyname...	     * (NOTE: we don't use gethostbyname as a	     * fallback!)	     */	    if (ret->family == 0)	{	    /*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */	    if (h = gethostbyname(host)) ret->family = AF_INET;	}	/*debug(("Done resolving...(family is %d) AF_INET = %d, AF_INET6 = %d\n", ret->family, AF_INET, AF_INET6)); */	if (ret->family == 0)	{	    DWORD err = WSAGetLastError();	    ret->error = (err == WSAENETDOWN ? "Network is down" :			  err == WSAHOST_NOT_FOUND ? "Host does not exist" :			  err == WSATRY_AGAIN ? "Host not found" :#ifdef IPV6			  fGetAddrInfo ? "getaddrinfo: unknown error" :#endif			  "gethostbyname: unknown error");#ifdef DEBUG	    {		LPVOID lpMsgBuf;		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf,	0,	NULL);		debug(("Error %ld: %s (h=%lx)\n", err, lpMsgBuf, h));		/* Free the buffer. */		LocalFree(lpMsgBuf);	    }#endif	}	else	{	    ret->error = NULL;#ifdef IPV6	    /* If we got an address info use that... */	    if (ret->ai)	    {		typedef int (CALLBACK* FGETNAMEINFO)		    (const struct sockaddr FAR *sa, socklen_t salen,		     char FAR * host, size_t hostlen, char FAR * serv,		     size_t servlen, int flags);		FGETNAMEINFO fGetNameInfo = NULL;		/* Are we in IPv4 fallback mode? */		/* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */		if (ret->family == AF_INET)		    memcpy(&a, (char *)&((SOCKADDR_IN *)ret->ai->ai_addr)->sin_addr, sizeof(a));		/* Now let's find that canonicalname... */		if ((dllWSHIP6) && (fGetNameInfo = (FGETNAMEINFO)GetProcAddress(dllWSHIP6, "getnameinfo")))		{		    if (fGetNameInfo((struct sockaddr *)ret->ai->ai_addr,				     ret->family == AF_INET ?				     sizeof(SOCKADDR_IN) :				     sizeof(SOCKADDR_IN6), ret->realhost,				     sizeof(ret->realhost), NULL,				     0, 0) != 0)		    {			strncpy(ret->realhost, host,				sizeof(ret->realhost));		    }		}	    }	    /* We used the IPv4-only gethostbyname()... */	    else	    {#endif		memcpy(&a, h->h_addr, sizeof(a));		/* This way we are always sure the h->h_name is valid :) */		strncpy(ret->realhost, h->h_name, sizeof(ret->realhost));#ifdef IPV6	    }#endif	}#ifdef IPV6	FreeLibrary(dllWSHIP6);#endif    }    else    {        /*         * Hack inserted to deal with problems with numeric IPs.         * FIXME: how will this work in IPv6?         */        ret->family = AF_INET;	*canonicalname = host;    }    ret->address = ntohl(a);    return ret;}