/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the w64 mingw-runtime package.
 * No warranty is given; refer to the file DISCLAIMER within this package.
 */
#ifndef _WSPIAPI_H_
#define _WSPIAPI_H_

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <ws2tcpip.h>

#define _WSPIAPI_STRCPY_S(_Dst,_Size,_Src) strcpy((_Dst),(_Src))
#define _WSPIAPI_STRCAT_S(_Dst,_Size,_Src) strcat((_Dst),(_Src))
#define _WSPIAPI_STRNCPY_S(_Dst,_Size,_Src,_Count) strncpy((_Dst),(_Src),(_Count)); (_Dst)[(_Size) - 1] = 0
#define _WSPIAPI_SPRINTF_S_1(_Dst,_Size,_Format,_Arg1) sprintf((_Dst),(_Format),(_Arg1))

#ifndef _WSPIAPI_COUNTOF
#ifndef __cplusplus
#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#else
template <typename __CountofType,size_t _N> char (&__wspiapi_countof_helper(__CountofType (&_Array)[_N]))[_N];
#define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array))
#endif
#endif

#define WspiapiMalloc(tSize) calloc(1,(tSize))
#define WspiapiFree(p) free(p)
#define WspiapiSwap(a,b,c) { (c) = (a); (a) = (b); (b) = (c); }
#define getaddrinfo WspiapiGetAddrInfo
#define getnameinfo WspiapiGetNameInfo
#define freeaddrinfo WspiapiFreeAddrInfo

typedef int (WINAPI *WSPIAPI_PGETADDRINFO)(const char *nodename,const char *servname,const struct addrinfo *hints,struct addrinfo **res);
typedef int (WINAPI *WSPIAPI_PGETNAMEINFO)(const struct sockaddr *sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags);
typedef void (WINAPI *WSPIAPI_PFREEADDRINFO)(struct addrinfo *ai);

#ifdef __cplusplus
extern "C" {
#endif
  typedef struct {
    char const *pszName;
    FARPROC pfAddress;
  } WSPIAPI_FUNCTION;

#define WSPIAPI_FUNCTION_ARRAY { { "getaddrinfo",(FARPROC) WspiapiLegacyGetAddrInfo }, \
  { "getnameinfo",(FARPROC) WspiapiLegacyGetNameInfo }, \
  { "freeaddrinfo",(FARPROC) WspiapiLegacyFreeAddrInfo } }

  char *WINAPI WspiapiStrdup (const char *pszString);
  WINBOOL WINAPI WspiapiParseV4Address (const char *pszAddress,PDWORD pdwAddress);
  struct addrinfo * WINAPI WspiapiNewAddrInfo (int iSocketType,int iProtocol,WORD wPort,DWORD dwAddress);
  int WINAPI WspiapiQueryDNS(const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,char pszAlias[NI_MAXHOST],struct addrinfo **pptResult);
  int WINAPI WspiapiLookupNode(const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,WINBOOL bAI_CANONNAME,struct addrinfo **pptResult);
  int WINAPI WspiapiClone (WORD wPort,struct addrinfo *ptResult);
  void WINAPI WspiapiLegacyFreeAddrInfo (struct addrinfo *ptHead);
  int WINAPI WspiapiLegacyGetAddrInfo(const char *pszNodeName,const char *pszServiceName,const struct addrinfo *ptHints,struct addrinfo **pptResult);
  int WINAPI WspiapiLegacyGetNameInfo(const struct sockaddr *ptSocketAddress,socklen_t tSocketLength,char *pszNodeName,size_t tNodeLength,char *pszServiceName,size_t tServiceLength,int iFlags);
  FARPROC WINAPI WspiapiLoad(WORD wFunction);
  int WINAPI WspiapiGetAddrInfo(const char *nodename,const char *servname,const struct addrinfo *hints,struct addrinfo **res);
  int WINAPI WspiapiGetNameInfo (const struct sockaddr *sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags);
  void WINAPI WspiapiFreeAddrInfo (struct addrinfo *ai);

#ifndef __CRT__NO_INLINE
  __CRT_INLINE char *WINAPI WspiapiStrdup (const char *pszString) {
    char *pszMemory;
    size_t cchMemory;
    if(!pszString) return(NULL);
    cchMemory = strlen(pszString) + 1;
    pszMemory = (char *) WspiapiMalloc(cchMemory);
    if(!pszMemory) return(NULL);
    _WSPIAPI_STRCPY_S(pszMemory,cchMemory,pszString);
    return pszMemory;
  }

  __CRT_INLINE WINBOOL WINAPI WspiapiParseV4Address (const char *pszAddress,PDWORD pdwAddress) {
    DWORD dwAddress = 0;
    const char *pcNext = NULL;
    int iCount = 0;
    for(pcNext = pszAddress;*pcNext!='\0';pcNext++)
      if(*pcNext=='.') iCount++;
    if(iCount!=3) return FALSE;
    dwAddress = inet_addr(pszAddress);
    if(dwAddress==INADDR_NONE) return FALSE;
    *pdwAddress = dwAddress;
    return TRUE;
  }

  __CRT_INLINE struct addrinfo *WINAPI WspiapiNewAddrInfo (int iSocketType,int iProtocol,WORD wPort,DWORD dwAddress) {
    struct addrinfo *ptNew;
    struct sockaddr_in *ptAddress;
    ptNew = (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo));
    if(!ptNew) return NULL;
    ptAddress = (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in));
    if(!ptAddress) {
      WspiapiFree(ptNew);
      return NULL;
    }
    ptAddress->sin_family = AF_INET;
    ptAddress->sin_port = wPort;
    ptAddress->sin_addr.s_addr = dwAddress;
    ptNew->ai_family = PF_INET;
    ptNew->ai_socktype = iSocketType;
    ptNew->ai_protocol = iProtocol;
    ptNew->ai_addrlen = sizeof(struct sockaddr_in);
    ptNew->ai_addr = (struct sockaddr *) ptAddress;
    return ptNew;
  }

  __CRT_INLINE int WINAPI WspiapiQueryDNS(const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,char pszAlias[NI_MAXHOST],struct addrinfo **pptResult) {
    struct addrinfo **pptNext = pptResult;
    struct hostent *ptHost = NULL;
    char **ppAddresses;
    *pptNext = NULL;
    pszAlias[0] = '\0';
    ptHost = gethostbyname(pszNodeName);
    if(ptHost) {
      if((ptHost->h_addrtype==AF_INET) && (ptHost->h_length==sizeof(struct in_addr))) {
	for(ppAddresses = ptHost->h_addr_list;*ppAddresses!=NULL;ppAddresses++) {
	  *pptNext = WspiapiNewAddrInfo(iSocketType,iProtocol,wPort,((struct in_addr *) *ppAddresses)->s_addr);
	  if(!*pptNext) return EAI_MEMORY;
	  pptNext = &((*pptNext)->ai_next);
	}
      }
      _WSPIAPI_STRNCPY_S(pszAlias,NI_MAXHOST,ptHost->h_name,NI_MAXHOST - 1);
      return 0;
    }
    switch(WSAGetLastError()) {
		case WSAHOST_NOT_FOUND: return EAI_NONAME;
		case WSATRY_AGAIN: return EAI_AGAIN;
		case WSANO_RECOVERY: return EAI_FAIL;
		case WSANO_DATA: return EAI_NODATA;
		default: return EAI_NONAME;
    }
  }

  __CRT_INLINE int WINAPI WspiapiLookupNode(const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,WINBOOL bAI_CANONNAME,struct addrinfo **pptResult) {
    int iError = 0;
    int iAliasCount = 0;
    char szFQDN1[NI_MAXHOST] = "";
    char szFQDN2[NI_MAXHOST] = "";
    char *pszName = szFQDN1;
    char *pszAlias = szFQDN2;
    char *pszScratch = NULL;
    _WSPIAPI_STRNCPY_S(pszName,NI_MAXHOST,pszNodeName,NI_MAXHOST - 1);
    for(;;) {
      iError = WspiapiQueryDNS(pszNodeName,iSocketType,iProtocol,wPort,pszAlias,pptResult);
      if(iError) break;
      if(*pptResult) break;
      if((!strlen(pszAlias)) || (!strcmp(pszName,pszAlias)) || (++iAliasCount==16)) {
	iError = EAI_FAIL;
	break;
      }
      WspiapiSwap(pszName,pszAlias,pszScratch);
    }
    if(!iError && bAI_CANONNAME) {
      (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias);
      if(!(*pptResult)->ai_canonname) iError = EAI_MEMORY;
    }
    return iError;
  }

  __CRT_INLINE int WINAPI WspiapiClone (WORD wPort,struct addrinfo *ptResult) {
    struct addrinfo *ptNext = NULL;
    struct addrinfo *ptNew = NULL;
    for(ptNext = ptResult; ptNext!=NULL;) {
      ptNew = WspiapiNewAddrInfo(SOCK_DGRAM,ptNext->ai_protocol,wPort,((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr);
      if(!ptNew) break;
      ptNew->ai_next = ptNext->ai_next;
      ptNext->ai_next = ptNew;
      ptNext = ptNew->ai_next;
    }
    if(ptNext!=NULL) return EAI_MEMORY;
    return 0;
  }

  __CRT_INLINE void WINAPI WspiapiLegacyFreeAddrInfo (struct addrinfo *ptHead) {
    struct addrinfo *ptNext;
    for(ptNext = ptHead;ptNext!=NULL;ptNext = ptHead) {
      if(ptNext->ai_canonname) WspiapiFree(ptNext->ai_canonname);
      if(ptNext->ai_addr) WspiapiFree(ptNext->ai_addr);
      ptHead = ptNext->ai_next;
      WspiapiFree(ptNext);
    }
  }

  __CRT_INLINE int WINAPI WspiapiLegacyGetAddrInfo(const char *pszNodeName,const char *pszServiceName,const struct addrinfo *ptHints,struct addrinfo **pptResult) {
    int iError = 0;
    int iFlags = 0;
    int iFamily = PF_UNSPEC;
    int iSocketType = 0;
    int iProtocol = 0;
    WORD wPort = 0;
    DWORD dwAddress = 0;
    struct servent *ptService = NULL;
    char *pc = NULL;
    WINBOOL bClone = FALSE;
    WORD wTcpPort = 0;
    WORD wUdpPort = 0;
    *pptResult = NULL;
    if((!pszNodeName) && (!pszServiceName)) return EAI_NONAME;
    if(ptHints) {
      if((ptHints->ai_addrlen!=0) || (ptHints->ai_canonname!=NULL) || (ptHints->ai_addr!=NULL) || (ptHints->ai_next!=NULL)) return EAI_FAIL;
      iFlags = ptHints->ai_flags;
      if((iFlags & AI_CANONNAME) && !pszNodeName) return EAI_BADFLAGS;
      iFamily = ptHints->ai_family;
      if((iFamily!=PF_UNSPEC) && (iFamily!=PF_INET)) return EAI_FAMILY;
      iSocketType = ptHints->ai_socktype;
      if((iSocketType!=0) && (iSocketType!=SOCK_STREAM) && (iSocketType!=SOCK_DGRAM) && (iSocketType!=SOCK_RAW)) return EAI_SOCKTYPE;
      iProtocol = ptHints->ai_protocol;
    }
    if(pszServiceName) {
      wPort = (WORD) strtoul(pszServiceName,&pc,10);
      if(*pc=='\0') {
	wPort = wTcpPort = wUdpPort = htons(wPort);
	if(iSocketType==0) {
	  bClone = TRUE;
	  iSocketType = SOCK_STREAM;
	}
      } else {
	if((iSocketType==0) || (iSocketType==SOCK_DGRAM)) {
	  ptService = getservbyname(pszServiceName,"udp");
	  if(ptService) wPort = wUdpPort = ptService->s_port;
	}
	if((iSocketType==0) || (iSocketType==SOCK_STREAM)) {
	  ptService = getservbyname(pszServiceName,"tcp");
	  if(ptService) wPort = wTcpPort = ptService->s_port;
	}
	if(wPort==0) return (iSocketType ? EAI_SERVICE : EAI_NONAME);
	if(iSocketType==0) {
	  iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM;
	  bClone = (wTcpPort && wUdpPort);
	}
      }
    }
    if((!pszNodeName) || (WspiapiParseV4Address(pszNodeName,&dwAddress))) {
      if(!pszNodeName) {
	dwAddress = htonl((iFlags & AI_PASSIVE) ? INADDR_ANY : INADDR_LOOPBACK);
      }
      *pptResult = WspiapiNewAddrInfo(iSocketType,iProtocol,wPort,dwAddress);
      if(!(*pptResult)) iError = EAI_MEMORY;
      if(!iError && pszNodeName) {
	(*pptResult)->ai_flags |= AI_NUMERICHOST;
	if(iFlags & AI_CANONNAME) {
	  (*pptResult)->ai_canonname =
	    WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress)));
	  if(!(*pptResult)->ai_canonname) iError = EAI_MEMORY;
	}
      }
    } else if(iFlags & AI_NUMERICHOST) iError = EAI_NONAME;
    else iError = WspiapiLookupNode(pszNodeName,iSocketType,iProtocol,wPort,(iFlags & AI_CANONNAME),pptResult);
    if(!iError && bClone) iError = WspiapiClone(wUdpPort,*pptResult);
    if(iError) {
      WspiapiLegacyFreeAddrInfo(*pptResult);
      *pptResult = NULL;
    }
    return (iError);
  }

  __CRT_INLINE int WINAPI WspiapiLegacyGetNameInfo(const struct sockaddr *ptSocketAddress,socklen_t tSocketLength,char *pszNodeName,size_t tNodeLength,char *pszServiceName,size_t tServiceLength,int iFlags) {
    struct servent *ptService;
    WORD wPort;
    char szBuffer[] = "65535";
    char *pszService = szBuffer;
    struct hostent *ptHost;
    struct in_addr tAddress;
    char *pszNode = NULL;
    char *pc = NULL;

    if((!ptSocketAddress) || (tSocketLength < sizeof(struct sockaddr))) return EAI_FAIL;
    if(ptSocketAddress->sa_family!=AF_INET) return EAI_FAMILY;
    if(tSocketLength < sizeof(struct sockaddr_in)) return EAI_FAIL;
    if(!(pszNodeName && tNodeLength) && !(pszServiceName && tServiceLength)) return EAI_NONAME;
    if((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD)) return EAI_BADFLAGS;
    if(pszServiceName && tServiceLength) {
      wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port;
      if(iFlags & NI_NUMERICSERV) {
	_WSPIAPI_SPRINTF_S_1(szBuffer,_WSPIAPI_COUNTOF(szBuffer),"%u",ntohs(wPort));
      } else {
	ptService = getservbyport(wPort,(iFlags & NI_DGRAM) ? "udp" : NULL);
	if(ptService && ptService->s_name) {
	  pszService = ptService->s_name;
	} else {
	  _WSPIAPI_SPRINTF_S_1(szBuffer,_WSPIAPI_COUNTOF(szBuffer),"%u",ntohs(wPort));
	}
      }
      if(tServiceLength > strlen(pszService))
	_WSPIAPI_STRCPY_S(pszServiceName,tServiceLength,pszService);
      else return EAI_FAIL;
    }
    if(pszNodeName && tNodeLength) {
      tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr;
      if(iFlags & NI_NUMERICHOST) {
	pszNode = inet_ntoa(tAddress);
      } else {
	ptHost = gethostbyaddr((char *) &tAddress,sizeof(struct in_addr),AF_INET);
	if(ptHost && ptHost->h_name) {
	  pszNode = ptHost->h_name;
	  if((iFlags & NI_NOFQDN) && ((pc = strchr(pszNode,'.'))!=NULL)) *pc = '\0';
	} else {
	  if(iFlags & NI_NAMEREQD) {
	    switch(WSAGetLastError()) {
						case WSAHOST_NOT_FOUND: return EAI_NONAME;
						case WSATRY_AGAIN: return EAI_AGAIN;
						case WSANO_RECOVERY: return EAI_FAIL;
						default: return EAI_NONAME;
	    }
	  } else pszNode = inet_ntoa(tAddress);
	}
      }
      if(tNodeLength > strlen(pszNode)) _WSPIAPI_STRCPY_S(pszNodeName,tNodeLength,pszNode);
      else return EAI_FAIL;
    }
    return 0;
  }

  __CRT_INLINE FARPROC WINAPI WspiapiLoad(WORD wFunction) {
    HMODULE hLibrary = NULL;
    static WINBOOL bInitialized = FALSE;
    static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY;
    static const int iNumGlobal = (sizeof(rgtGlobal) / sizeof(WSPIAPI_FUNCTION));
    WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY;
    FARPROC fScratch = NULL;
    int i = 0;
    if(bInitialized) return (rgtGlobal[wFunction].pfAddress);
    for(;;) {
      CHAR SystemDir[MAX_PATH + 1];
      CHAR Path[MAX_PATH + 8];
      if(GetSystemDirectoryA(SystemDir,MAX_PATH)==0) break;
      _WSPIAPI_STRCPY_S(Path,_WSPIAPI_COUNTOF(Path),SystemDir);
      _WSPIAPI_STRCAT_S(Path,_WSPIAPI_COUNTOF(Path),"\\ws2_32");
      hLibrary = LoadLibraryA(Path);
      if(hLibrary!=NULL) {
	fScratch = GetProcAddress(hLibrary,"getaddrinfo");
	if(!fScratch) {
	  FreeLibrary(hLibrary);
	  hLibrary = NULL;
	}
      }
      if(hLibrary!=NULL) break;
      _WSPIAPI_STRCPY_S(Path,_WSPIAPI_COUNTOF(Path),SystemDir);
      _WSPIAPI_STRCAT_S(Path,_WSPIAPI_COUNTOF(Path),"\\wship6");
      hLibrary = LoadLibraryA(Path);
      if(hLibrary!=NULL) {
	fScratch = GetProcAddress(hLibrary,"getaddrinfo");
	if(!fScratch) {
	  FreeLibrary(hLibrary);
	  hLibrary = NULL;
	}
      }
      break;
    }
    if(hLibrary!=NULL) {
      for(i = 0;i < iNumGlobal;i++) {
	rgtLocal[i].pfAddress = GetProcAddress(hLibrary,rgtLocal[i].pszName);
	if(!(rgtLocal[i].pfAddress)) {
	  FreeLibrary(hLibrary);
	  hLibrary = NULL;
	  break;
	}
      }
      if(hLibrary!=NULL) {
	for(i = 0;i < iNumGlobal;i++)
	  rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress;
      }
    }
    bInitialized = TRUE;
    return (rgtGlobal[wFunction].pfAddress);
  }

  __CRT_INLINE int WINAPI WspiapiGetAddrInfo(const char *nodename,const char *servname,const struct addrinfo *hints,struct addrinfo **res) {
    int iError;
    static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL;
    if(!pfGetAddrInfo) pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0);
    iError = (*pfGetAddrInfo)(nodename,servname,hints,res);
    WSASetLastError(iError);
    return iError;
  }

  __CRT_INLINE int WINAPI WspiapiGetNameInfo (const struct sockaddr *sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags) {
    int iError;
    static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL;
    if(!pfGetNameInfo) pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1);
    iError = (*pfGetNameInfo)(sa,salen,host,hostlen,serv,servlen,flags);
    WSASetLastError(iError);
    return iError;
  }

  __CRT_INLINE void WINAPI WspiapiFreeAddrInfo (struct addrinfo *ai) {
    static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL;
    if(!pfFreeAddrInfo) pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2);
    (*pfFreeAddrInfo)(ai);
  }
#endif /* !__CRT__NO_INLINE */

#ifdef __cplusplus
}
#endif
#endif
