1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6#ifndef _WSPIAPI_H_
7#define _WSPIAPI_H_
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <malloc.h>
12#include <string.h>
13#include <ws2tcpip.h>
14
15#include <_mingw_print_push.h>
16
17#define _WSPIAPI_STRCPY_S(_Dst,_Size,_Src) strcpy((_Dst),(_Src))
18#define _WSPIAPI_STRCAT_S(_Dst,_Size,_Src) strcat((_Dst),(_Src))
19#define _WSPIAPI_STRNCPY_S(_Dst,_Size,_Src,_Count) strncpy((_Dst),(_Src),(_Count)); (_Dst)[(_Size) - 1] = 0
20#define _WSPIAPI_SPRINTF_S_1(_Dst,_Size,_Format,_Arg1) sprintf((_Dst),(_Format),(_Arg1))
21
22#ifndef _WSPIAPI_COUNTOF
23#ifndef __cplusplus
24#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
25#else
26template <typename __CountofType,size_t _N> char (&__wspiapi_countof_helper(__CountofType (&_Array)[_N]))[_N];
27#define _WSPIAPI_COUNTOF(_Array) sizeof(__wspiapi_countof_helper(_Array))
28#endif
29#endif
30
31#define WspiapiMalloc(tSize) calloc(1,(tSize))
32#define WspiapiFree(p) free(p)
33#define WspiapiSwap(a,b,c) { (c) = (a); (a) = (b); (b) = (c); }
34#define getaddrinfo WspiapiGetAddrInfo
35#define getnameinfo WspiapiGetNameInfo
36#define freeaddrinfo WspiapiFreeAddrInfo
37
38typedef int (WINAPI *WSPIAPI_PGETADDRINFO)(const char *nodename,const char *servname,const struct addrinfo *hints,struct addrinfo **res);
39typedef int (WINAPI *WSPIAPI_PGETNAMEINFO)(const struct sockaddr *sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags);
40typedef void (WINAPI *WSPIAPI_PFREEADDRINFO)(struct addrinfo *ai);
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45  typedef struct {
46    char const *pszName;
47    FARPROC pfAddress;
48  } WSPIAPI_FUNCTION;
49
50#define WSPIAPI_FUNCTION_ARRAY { { "getaddrinfo",(FARPROC) WspiapiLegacyGetAddrInfo }, \
51  { "getnameinfo",(FARPROC) WspiapiLegacyGetNameInfo }, \
52  { "freeaddrinfo",(FARPROC) WspiapiLegacyFreeAddrInfo } }
53
54  char *WINAPI WspiapiStrdup (const char *pszString);
55  WINBOOL WINAPI WspiapiParseV4Address (const char *pszAddress,PDWORD pdwAddress);
56  struct addrinfo * WINAPI WspiapiNewAddrInfo (int iSocketType,int iProtocol,WORD wPort,DWORD dwAddress);
57  int WINAPI WspiapiQueryDNS (const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,char pszAlias[NI_MAXHOST],struct addrinfo **pptResult);
58  int WINAPI WspiapiLookupNode (const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,WINBOOL bAI_CANONNAME,struct addrinfo **pptResult);
59  int WINAPI WspiapiClone (WORD wPort,struct addrinfo *ptResult);
60  void WINAPI WspiapiLegacyFreeAddrInfo (struct addrinfo *ptHead);
61  int WINAPI WspiapiLegacyGetAddrInfo(const char *pszNodeName,const char *pszServiceName,const struct addrinfo *ptHints,struct addrinfo **pptResult);
62  int WINAPI WspiapiLegacyGetNameInfo(const struct sockaddr *ptSocketAddress,socklen_t tSocketLength,char *pszNodeName,size_t tNodeLength,char *pszServiceName,size_t tServiceLength,int iFlags);
63  FARPROC WINAPI WspiapiLoad(WORD wFunction);
64  int WINAPI WspiapiGetAddrInfo(const char *nodename,const char *servname,const struct addrinfo *hints,struct addrinfo **res);
65  int WINAPI WspiapiGetNameInfo (const struct sockaddr *sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags);
66  void WINAPI WspiapiFreeAddrInfo (struct addrinfo *ai);
67
68#ifndef __CRT__NO_INLINE
69  __CRT_INLINE char * WINAPI
70  WspiapiStrdup (const char *pszString)
71  {
72    char *rstr;
73    size_t szlen;
74
75    if(!pszString)
76      return NULL;
77    szlen = strlen(pszString) + 1;
78    rstr = (char *) WspiapiMalloc (szlen);
79    if (!rstr)
80      return NULL;
81    strcpy (rstr, pszString);
82    return rstr;
83  }
84
85  __CRT_INLINE WINBOOL WINAPI
86  WspiapiParseV4Address (const char *pszAddress, PDWORD pdwAddress)
87  {
88    DWORD dwAddress = 0;
89    const char *h = NULL;
90    int cnt;
91
92    for (cnt = 0,h = pszAddress; *h != 0; h++)
93      if (h[0] == '.')
94	cnt++;
95    if (cnt != 3)
96      return FALSE;
97    dwAddress = inet_addr (pszAddress);
98    if (dwAddress == INADDR_NONE)
99      return FALSE;
100    *pdwAddress = dwAddress;
101    return TRUE;
102  }
103
104  __CRT_INLINE struct addrinfo * WINAPI
105  WspiapiNewAddrInfo (int iSocketType,int iProtocol, WORD wPort,DWORD dwAddress)
106  {
107    struct addrinfo *n;
108    struct sockaddr_in *pa;
109
110    if ((n = (struct addrinfo *) WspiapiMalloc (sizeof (struct addrinfo))) == NULL)
111      return NULL;
112    if ((pa = (struct sockaddr_in *) WspiapiMalloc (sizeof(struct sockaddr_in))) == NULL)
113      {
114	WspiapiFree(n);
115	return NULL;
116      }
117    pa->sin_family = AF_INET;
118    pa->sin_port = wPort;
119    pa->sin_addr.s_addr = dwAddress;
120    n->ai_family = PF_INET;
121    n->ai_socktype = iSocketType;
122    n->ai_protocol = iProtocol;
123    n->ai_addrlen = sizeof (struct sockaddr_in);
124    n->ai_addr = (struct sockaddr *) pa;
125    return n;
126  }
127
128  __CRT_INLINE int WINAPI
129  WspiapiLookupNode (const char *pszNodeName, int iSocketType, int iProtocol, WORD wPort,
130		     WINBOOL bAI_CANONNAME, struct addrinfo **pptResult)
131  {
132    int err = 0, cntAlias = 0;
133    char name[NI_MAXHOST] = "";
134    char alias[NI_MAXHOST] = "";
135    char *pname = name, *palias = alias, *tmp = NULL;
136
137    strncpy (pname, pszNodeName, NI_MAXHOST - 1);
138    pname[NI_MAXHOST - 1] = 0;
139    for (;;)
140      {
141	err = WspiapiQueryDNS (pszNodeName, iSocketType, iProtocol, wPort, palias, pptResult);
142	if (err)
143	  break;
144	if (*pptResult)
145	  break;
146	++cntAlias;
147	if (strlen (palias) == 0 || !strcmp (pname, palias) || cntAlias == 16)
148	  {
149	    err = EAI_FAIL;
150	    break;
151	  }
152	WspiapiSwap(pname, palias, tmp);
153      }
154    if (!err && bAI_CANONNAME)
155      {
156        (*pptResult)->ai_canonname = WspiapiStrdup (palias);
157        if (!(*pptResult)->ai_canonname)
158	  err = EAI_MEMORY;
159      }
160    return err;
161  }
162
163  __CRT_INLINE int WINAPI
164  WspiapiClone (WORD wPort,struct addrinfo *ptResult)
165  {
166    struct addrinfo *p = NULL;
167    struct addrinfo *n = NULL;
168
169    for (p = ptResult; p != NULL;)
170      {
171	n = WspiapiNewAddrInfo (SOCK_DGRAM, p->ai_protocol, wPort,
172				((struct sockaddr_in *) p->ai_addr)->sin_addr.s_addr);
173	if (!n)
174	  break;
175	n->ai_next = p->ai_next;
176	p->ai_next = n;
177	p = n->ai_next;
178      }
179    if (p != NULL)
180      return EAI_MEMORY;
181    return 0;
182  }
183
184  __CRT_INLINE void WINAPI
185  WspiapiLegacyFreeAddrInfo (struct addrinfo *ptHead)
186  {
187    struct addrinfo *p;
188
189    for (p = ptHead; p != NULL; p = ptHead)
190      {
191	if (p->ai_canonname)
192	  WspiapiFree (p->ai_canonname);
193	if (p->ai_addr)
194	  WspiapiFree (p->ai_addr);
195	ptHead = p->ai_next;
196	WspiapiFree (p);
197      }
198  }
199#endif /* !__CRT__NO_INLINE */
200
201#ifdef __cplusplus
202}
203#endif
204
205#include <_mingw_print_pop.h>
206
207#endif
208