| #ifndef WIN32_LEAN_AND_MEAN |
| #define WIN32_LEAN_AND_MEAN |
| #endif |
| #undef __CRT__NO_INLINE |
| #define __CRT__NO_INLINE |
| #include <winsock2.h> |
| #include <wspiapi.h> |
| |
| int WINAPI |
| WspiapiLegacyGetAddrInfo(const char *pszNodeName, |
| const char *pszServiceName, |
| const struct addrinfo *ptHints, |
| struct addrinfo **pptResult) |
| { |
| int err = 0, iFlags = 0, iFamily = PF_UNSPEC, iSocketType = 0, iProtocol = 0; |
| struct in_addr inAddress; |
| struct servent *svc = NULL; |
| char *pc = NULL; |
| WINBOOL isCloned = FALSE; |
| WORD tcpPort = 0, udpPort = 0, port = 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) != 0 && !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) |
| { |
| port = (WORD) strtoul (pszServiceName, &pc, 10); |
| if(*pc == 0) |
| { |
| port = tcpPort = udpPort = htons (port); |
| if (iSocketType == 0) |
| { |
| isCloned = TRUE; |
| iSocketType = SOCK_STREAM; |
| } |
| } |
| else |
| { |
| if (iSocketType == 0 || iSocketType == SOCK_DGRAM) |
| { |
| svc = getservbyname(pszServiceName, "udp"); |
| if (svc) |
| port = udpPort = svc->s_port; |
| } |
| if (iSocketType == 0 || iSocketType == SOCK_STREAM) |
| { |
| svc = getservbyname(pszServiceName, "tcp"); |
| if (svc) |
| port = tcpPort = svc->s_port; |
| } |
| if (port == 0) |
| return (iSocketType ? EAI_SERVICE : EAI_NONAME); |
| if (iSocketType==0) |
| { |
| iSocketType = (tcpPort) ? SOCK_STREAM : SOCK_DGRAM; |
| isCloned = (tcpPort && udpPort); |
| } |
| } |
| } |
| if (!pszNodeName || WspiapiParseV4Address(pszNodeName,&inAddress.s_addr)) |
| { |
| if (!pszNodeName) |
| { |
| inAddress.s_addr = htonl ((iFlags & AI_PASSIVE) ? INADDR_ANY : INADDR_LOOPBACK); |
| } |
| *pptResult = WspiapiNewAddrInfo(iSocketType, iProtocol, port, inAddress.s_addr); |
| if (!(*pptResult)) |
| err = EAI_MEMORY; |
| if (!err && pszNodeName) |
| { |
| (*pptResult)->ai_flags |= AI_NUMERICHOST; |
| if (iFlags & AI_CANONNAME) |
| { |
| (*pptResult)->ai_canonname = |
| WspiapiStrdup (inet_ntoa (inAddress)); |
| if (!(*pptResult)->ai_canonname) |
| err = EAI_MEMORY; |
| } |
| } |
| } |
| else if (iFlags & AI_NUMERICHOST) |
| err = EAI_NONAME; |
| else |
| err = WspiapiLookupNode (pszNodeName, iSocketType, iProtocol, port, |
| (iFlags & AI_CANONNAME), pptResult); |
| if (!err && isCloned) |
| err = WspiapiClone(udpPort, *pptResult); |
| if (err) |
| { |
| WspiapiLegacyFreeAddrInfo (*pptResult); |
| *pptResult = NULL; |
| } |
| return err; |
| } |