ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ns.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS WinSock 2 DLL
00004  * FILE:        misc/ns.c
00005  * PURPOSE:     Namespace APIs
00006  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
00007  * REVISIONS:
00008  *   CSH 01/09-2000 Created
00009  */
00010 
00011 #include "ws2_32.h"
00012 
00013 #ifndef BUFSIZ
00014 #define BUFSIZ 1024
00015 #endif/*BUFSIZ*/
00016 
00017 #ifndef MAX_HOSTNAME_LEN
00018 #define MAX_HOSTNAME_LEN 256
00019 #endif
00020 
00021 /* Name resolution APIs */
00022 
00023 /*
00024  * @unimplemented
00025  */
00026 INT
00027 EXPORT
00028 WSAAddressToStringA(IN      LPSOCKADDR lpsaAddress,
00029                     IN      DWORD dwAddressLength,
00030                     IN      LPWSAPROTOCOL_INFOA lpProtocolInfo,
00031                     OUT     LPSTR lpszAddressString,
00032                     IN OUT  LPDWORD lpdwAddressStringLength)
00033 {
00034     DWORD size;
00035     CHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
00036     CHAR *p;
00037 
00038     if (!lpsaAddress) return SOCKET_ERROR;
00039     if (!lpszAddressString || !lpdwAddressStringLength) return SOCKET_ERROR;
00040 
00041     switch(lpsaAddress->sa_family)
00042     {
00043     case AF_INET:
00044         if (dwAddressLength < sizeof(SOCKADDR_IN)) return SOCKET_ERROR;
00045         sprintf( buffer, "%u.%u.%u.%u:%u",
00046                (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 24 & 0xff),
00047                (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 16 & 0xff),
00048                (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) >> 8 & 0xff),
00049                (unsigned int)(ntohl( ((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr ) & 0xff),
00050                ntohs( ((SOCKADDR_IN *)lpsaAddress)->sin_port ) );
00051 
00052         p = strchr( buffer, ':' );
00053         if (!((SOCKADDR_IN *)lpsaAddress)->sin_port) *p = 0;
00054         break;
00055     default:
00056         WSASetLastError(WSAEINVAL);
00057         return SOCKET_ERROR;
00058     }
00059 
00060     size = strlen( buffer ) + 1;
00061 
00062     if (*lpdwAddressStringLength <  size)
00063     {
00064         *lpdwAddressStringLength = size;
00065         WSASetLastError(WSAEFAULT);
00066         return SOCKET_ERROR;
00067     }
00068 
00069     *lpdwAddressStringLength = size;
00070     strcpy( lpszAddressString, buffer );
00071     return 0;
00072 }
00073 
00074 
00075 /*
00076  * @unimplemented
00077  */
00078 INT
00079 EXPORT
00080 WSAAddressToStringW(IN      LPSOCKADDR lpsaAddress,
00081                     IN      DWORD dwAddressLength,
00082                     IN      LPWSAPROTOCOL_INFOW lpProtocolInfo,
00083                     OUT     LPWSTR lpszAddressString,
00084                     IN OUT  LPDWORD lpdwAddressStringLength)
00085 {
00086     INT   ret;
00087     DWORD size;
00088     WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
00089     CHAR bufAddr[54];
00090 
00091     size = *lpdwAddressStringLength;
00092     ret = WSAAddressToStringA(lpsaAddress, dwAddressLength, NULL, bufAddr, &size);
00093 
00094     if (ret) return ret;
00095 
00096     MultiByteToWideChar( CP_ACP, 0, bufAddr, size, buffer, sizeof( buffer )/sizeof(WCHAR));
00097 
00098     if (*lpdwAddressStringLength <  size)
00099     {
00100         *lpdwAddressStringLength = size;
00101         WSASetLastError(WSAEFAULT);
00102         return SOCKET_ERROR;
00103     }
00104 
00105     *lpdwAddressStringLength = size;
00106     lstrcpyW( lpszAddressString, buffer );
00107     return 0;
00108 }
00109 
00110 
00111 /*
00112  * @unimplemented
00113  */
00114 INT
00115 EXPORT
00116 WSAEnumNameSpaceProvidersA(IN OUT  LPDWORD lpdwBufferLength,
00117                            OUT     LPWSANAMESPACE_INFOA lpnspBuffer)
00118 {
00119     UNIMPLEMENTED
00120 
00121     WSASetLastError(WSASYSCALLFAILURE);
00122     return SOCKET_ERROR;
00123 }
00124 
00125 
00126 /*
00127  * @unimplemented
00128  */
00129 INT
00130 EXPORT
00131 WSAEnumNameSpaceProvidersW(IN OUT  LPDWORD lpdwBufferLength,
00132                            OUT     LPWSANAMESPACE_INFOW lpnspBuffer)
00133 {
00134     UNIMPLEMENTED
00135 
00136     WSASetLastError(WSASYSCALLFAILURE);
00137     return SOCKET_ERROR;
00138 }
00139 
00140 
00141 /*
00142  * @unimplemented
00143  */
00144 INT
00145 EXPORT
00146 WSAGetServiceClassInfoA(IN      LPGUID lpProviderId,
00147                         IN      LPGUID lpServiceClassId,
00148                         IN OUT  LPDWORD lpdwBufferLength,
00149                         OUT     LPWSASERVICECLASSINFOA lpServiceClassInfo)
00150 {
00151     UNIMPLEMENTED
00152 
00153     WSASetLastError(WSASYSCALLFAILURE);
00154     return SOCKET_ERROR;
00155 }
00156 
00157 
00158 /*
00159  * @unimplemented
00160  */
00161 INT
00162 EXPORT
00163 WSAGetServiceClassInfoW(IN      LPGUID lpProviderId,
00164                         IN      LPGUID lpServiceClassId,
00165                         IN OUT  LPDWORD lpdwBufferLength,
00166                         OUT     LPWSASERVICECLASSINFOW lpServiceClassInfo)
00167 {
00168     UNIMPLEMENTED
00169 
00170     WSASetLastError(WSASYSCALLFAILURE);
00171     return SOCKET_ERROR;
00172 }
00173 
00174 
00175 /*
00176  * @unimplemented
00177  */
00178 INT
00179 EXPORT
00180 WSAGetServiceClassNameByClassIdA(IN      LPGUID lpServiceClassId,
00181                                  OUT     LPSTR lpszServiceClassName,
00182                                  IN OUT  LPDWORD lpdwBufferLength)
00183 {
00184     UNIMPLEMENTED
00185 
00186     WSASetLastError(WSASYSCALLFAILURE);
00187     return SOCKET_ERROR;
00188 }
00189 
00190 
00191 /*
00192  * @unimplemented
00193  */
00194 INT
00195 EXPORT
00196 WSAGetServiceClassNameByClassIdW(IN      LPGUID lpServiceClassId,
00197                                  OUT     LPWSTR lpszServiceClassName,
00198                                  IN OUT  LPDWORD lpdwBufferLength)
00199 {
00200     UNIMPLEMENTED
00201 
00202     WSASetLastError(WSASYSCALLFAILURE);
00203     return SOCKET_ERROR;
00204 }
00205 
00206 
00207 /*
00208  * @unimplemented
00209  */
00210 INT
00211 EXPORT
00212 WSAInstallServiceClassA(IN  LPWSASERVICECLASSINFOA lpServiceClassInfo)
00213 {
00214     UNIMPLEMENTED
00215 
00216     WSASetLastError(WSASYSCALLFAILURE);
00217     return SOCKET_ERROR;
00218 }
00219 
00220 
00221 /*
00222  * @unimplemented
00223  */
00224 INT
00225 EXPORT
00226 WSAInstallServiceClassW(IN  LPWSASERVICECLASSINFOW lpServiceClassInfo)
00227 {
00228     UNIMPLEMENTED
00229 
00230     WSASetLastError(WSASYSCALLFAILURE);
00231     return SOCKET_ERROR;
00232 }
00233 
00234 
00235 /*
00236  * @unimplemented
00237  */
00238 INT
00239 EXPORT
00240 WSALookupServiceBeginA(IN  LPWSAQUERYSETA lpqsRestrictions,
00241                        IN  DWORD dwControlFlags,
00242                        OUT LPHANDLE lphLookup)
00243 {
00244     UNIMPLEMENTED
00245 
00246     WSASetLastError(WSASYSCALLFAILURE);
00247     return SOCKET_ERROR;
00248 }
00249 
00250 
00251 /*
00252  * @unimplemented
00253  */
00254 INT
00255 EXPORT
00256 WSALookupServiceBeginW(IN  LPWSAQUERYSETW lpqsRestrictions,
00257                        IN  DWORD dwControlFlags,
00258                        OUT LPHANDLE lphLookup)
00259 {
00260     UNIMPLEMENTED
00261 
00262     WSASetLastError(WSASYSCALLFAILURE);
00263     return SOCKET_ERROR;
00264 }
00265 
00266 
00267 /*
00268  * @unimplemented
00269  */
00270 INT
00271 EXPORT
00272 WSALookupServiceEnd(IN  HANDLE hLookup)
00273 {
00274     UNIMPLEMENTED
00275 
00276     WSASetLastError(WSASYSCALLFAILURE);
00277     return SOCKET_ERROR;
00278 }
00279 
00280 
00281 /*
00282  * @unimplemented
00283  */
00284 INT
00285 EXPORT
00286 WSALookupServiceNextA(IN      HANDLE hLookup,
00287                       IN      DWORD dwControlFlags,
00288                       IN OUT  LPDWORD lpdwBufferLength,
00289                       OUT     LPWSAQUERYSETA lpqsResults)
00290 {
00291     UNIMPLEMENTED
00292 
00293     WSASetLastError(WSASYSCALLFAILURE);
00294     return SOCKET_ERROR;
00295 }
00296 
00297 
00298 /*
00299  * @unimplemented
00300  */
00301 INT
00302 EXPORT
00303 WSALookupServiceNextW(IN      HANDLE hLookup,
00304                       IN      DWORD dwControlFlags,
00305                       IN OUT  LPDWORD lpdwBufferLength,
00306                       OUT     LPWSAQUERYSETW lpqsResults)
00307 {
00308     UNIMPLEMENTED
00309 
00310     WSASetLastError(WSASYSCALLFAILURE);
00311     return SOCKET_ERROR;
00312 }
00313 
00314 
00315 /*
00316  * @unimplemented
00317  */
00318 INT
00319 EXPORT
00320 WSARemoveServiceClass(IN  LPGUID lpServiceClassId)
00321 {
00322     UNIMPLEMENTED
00323 
00324     WSASetLastError(WSASYSCALLFAILURE);
00325     return SOCKET_ERROR;
00326 }
00327 
00328 
00329 /*
00330  * @unimplemented
00331  */
00332 INT
00333 EXPORT
00334 WSASetServiceA(IN  LPWSAQUERYSETA lpqsRegInfo,
00335                IN  WSAESETSERVICEOP essOperation,
00336                IN  DWORD dwControlFlags)
00337 {
00338     UNIMPLEMENTED
00339 
00340     WSASetLastError(WSASYSCALLFAILURE);
00341     return SOCKET_ERROR;
00342 }
00343 
00344 
00345 /*
00346  * @unimplemented
00347  */
00348 INT
00349 EXPORT
00350 WSASetServiceW(IN  LPWSAQUERYSETW lpqsRegInfo,
00351                IN  WSAESETSERVICEOP essOperation,
00352                IN  DWORD dwControlFlags)
00353 {
00354     UNIMPLEMENTED
00355 
00356     WSASetLastError(WSASYSCALLFAILURE);
00357     return SOCKET_ERROR;
00358 }
00359 
00360 
00361 /*
00362  * @unimplemented
00363  */
00364 INT
00365 EXPORT
00366 WSAStringToAddressA(IN     LPSTR AddressString,
00367                     IN     INT AddressFamily,
00368                     IN     LPWSAPROTOCOL_INFOA lpProtocolInfo,
00369                     OUT    LPSOCKADDR lpAddress,
00370                     IN OUT LPINT lpAddressLength)
00371 {
00372     INT ret, len;
00373     LPWSTR szTemp;
00374     WSAPROTOCOL_INFOW ProtoInfoW;
00375 
00376     len = MultiByteToWideChar(CP_ACP,
00377                               0,
00378                               AddressString,
00379                               -1,
00380                               NULL,
00381                               0);
00382 
00383     szTemp = HeapAlloc(GetProcessHeap(),
00384                        0,
00385                        len * sizeof(WCHAR));
00386 
00387     MultiByteToWideChar(CP_ACP,
00388                         0,
00389                         AddressString,
00390                         -1,
00391                         szTemp,
00392                         len);
00393 
00394     if (lpProtocolInfo)
00395     {
00396         memcpy(&ProtoInfoW,
00397                lpProtocolInfo,
00398                FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol));
00399 
00400         MultiByteToWideChar(CP_ACP,
00401                             0,
00402                             lpProtocolInfo->szProtocol,
00403                             -1,
00404                             ProtoInfoW.szProtocol,
00405                             WSAPROTOCOL_LEN + 1);
00406     }
00407 
00408     ret = WSAStringToAddressW(szTemp,
00409                               AddressFamily,
00410                               &ProtoInfoW,
00411                               lpAddress,
00412                               lpAddressLength);
00413 
00414     HeapFree(GetProcessHeap(),
00415              0,
00416              szTemp );
00417 
00418     WSASetLastError(ret);
00419     return ret;
00420 }
00421 
00422 
00423 
00424 /*
00425  * @implemented
00426  */
00427 INT
00428 EXPORT
00429 WSAStringToAddressW(IN      LPWSTR AddressString,
00430                     IN      INT AddressFamily,
00431                     IN      LPWSAPROTOCOL_INFOW lpProtocolInfo,
00432                     OUT     LPSOCKADDR lpAddress,
00433                     IN OUT  LPINT lpAddressLength)
00434 {
00435     int pos=0;
00436     int res=0;
00437     LONG inetaddr = 0;
00438     LPWSTR *bp=NULL;
00439     SOCKADDR_IN *sockaddr;
00440 
00441     if (!lpAddressLength || !lpAddress || !AddressString)
00442     {
00443         WSASetLastError(WSAEINVAL);
00444         return SOCKET_ERROR;
00445     }
00446 
00447     sockaddr = (SOCKADDR_IN *) lpAddress;
00448 
00449     /* Set right adress family */
00450     if (lpProtocolInfo!=NULL)
00451         sockaddr->sin_family = lpProtocolInfo->iAddressFamily;
00452     else
00453         sockaddr->sin_family = AddressFamily;
00454 
00455     /* Report size */
00456     if (AddressFamily == AF_INET)
00457     {
00458         if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
00459         {
00460             *lpAddressLength = sizeof(SOCKADDR_IN);
00461             res = WSAEFAULT;
00462         }
00463         else
00464         {
00465             // translate ip string to ip
00466 
00467             /* rest sockaddr.sin_addr.s_addr
00468                    for we need to be sure it is zero when we come to while */
00469             memset(lpAddress,0,sizeof(SOCKADDR_IN));
00470 
00471             /* Set right adress family */
00472             sockaddr->sin_family = AF_INET;
00473 
00474             /* Get port number */
00475             pos = wcscspn(AddressString,L":") + 1;
00476 
00477             if (pos < (int)wcslen(AddressString))
00478                 sockaddr->sin_port = wcstol(&AddressString[pos],
00479                                             bp,
00480                                             10);
00481 
00482             else
00483                 sockaddr->sin_port = 0;
00484 
00485             /* Get ip number */
00486             pos=0;
00487             inetaddr=0;
00488 
00489             while (pos < (int)wcslen(AddressString))
00490             {
00491                 inetaddr = (inetaddr<<8) + ((UCHAR)wcstol(&AddressString[pos],
00492                                                           bp,
00493                                                           10));
00494                 pos += wcscspn( &AddressString[pos],L".") +1 ;
00495             }
00496 
00497             res = 0;
00498             sockaddr->sin_addr.s_addr = inetaddr;
00499 
00500         }
00501     }
00502 
00503     WSASetLastError(res);
00504     if (!res) return 0;
00505     return SOCKET_ERROR;
00506 }
00507 
00508 void check_hostent(struct hostent **he)
00509 {
00510     struct hostent *new_he;
00511 
00512     WS_DbgPrint(MID_TRACE,("*he: %x\n",*he));
00513 
00514     if(!*he)
00515     {
00516         new_he = HeapAlloc(GlobalHeap,
00517                            0,
00518                            sizeof(struct hostent) + MAX_HOSTNAME_LEN + 1);
00519 
00520         new_he->h_name = (PCHAR)(new_he + 1);
00521         new_he->h_aliases = 0;
00522         new_he->h_addrtype = 0; // AF_INET
00523         new_he->h_length = 0;   // sizeof(in_addr)
00524         new_he->h_addr_list = HeapAlloc(GlobalHeap,
00525                                         0,
00526                                         sizeof(char *) * 2);
00527 
00528         RtlZeroMemory(new_he->h_addr_list,
00529                       sizeof(char *) * 2);
00530         *he = new_he;
00531     }
00532 }
00533 
00534 void populate_hostent(struct hostent *he, char* name, DNS_A_DATA addr)
00535 {
00536     ASSERT(he);
00537 
00538     //he = HeapAlloc(GlobalHeap, 0, sizeof(struct hostent));
00539     //he->h_name = HeapAlloc(GlobalHeap, 0, MAX_HOSTNAME_LEN+1);
00540 
00541     strncpy(he->h_name,
00542             name,
00543             MAX_HOSTNAME_LEN);
00544 
00545     if( !he->h_aliases ) {
00546        he->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *));
00547        he->h_aliases[0] = 0;
00548     }
00549     he->h_addrtype = AF_INET;
00550     he->h_length = sizeof(IN_ADDR); //sizeof(struct in_addr);
00551 
00552     if( he->h_addr_list[0] )
00553     {
00554         HeapFree(GlobalHeap,
00555                  0,
00556                  he->h_addr_list[0]);
00557     }
00558 
00559     he->h_addr_list[0] = HeapAlloc(GlobalHeap,
00560                                    0,
00561                                    MAX_HOSTNAME_LEN + 1);
00562 
00563     WS_DbgPrint(MID_TRACE,("he->h_addr_list[0] %x\n", he->h_addr_list[0]));
00564 
00565     RtlCopyMemory(he->h_addr_list[0],
00566                   (char*)&addr.IpAddress,
00567                   sizeof(addr.IpAddress));
00568 
00569     he->h_addr_list[1] = 0;
00570 }
00571 
00572 
00573 #define HFREE(x) if(x) { HeapFree(GlobalHeap, 0, (x)); x=0; }
00574 void free_hostent(struct hostent *he)
00575 {
00576     if(he)
00577     {
00578        char *next = 0;
00579         HFREE(he->h_name);
00580         if(he->h_aliases)
00581        {
00582            next = he->h_aliases[0];
00583            while(next) { HFREE(next); next++; }
00584        }
00585        if(he->h_addr_list)
00586        {
00587            next = he->h_addr_list[0];
00588            while(next) { HFREE(next); next++; }
00589        }
00590         HFREE(he->h_addr_list);
00591        HFREE(he->h_aliases);
00592         HFREE(he);
00593     }
00594 }
00595 
00596 /* WinSock 1.1 compatible name resolution APIs */
00597 
00598 /*
00599  * @unimplemented
00600  */
00601 LPHOSTENT
00602 EXPORT
00603 gethostbyaddr(IN  CONST CHAR FAR* addr,
00604               IN  INT len,
00605               IN  INT type)
00606 {
00607     UNIMPLEMENTED
00608 
00609     return (LPHOSTENT)NULL;
00610 }
00611 
00612 /*
00613   Assumes rfc 1123 - adam *
00614    addr[1] = 0;
00615     addr[0] = inet_addr(name);
00616     strcpy( hostname, name );
00617     if(addr[0] == 0xffffffff) return NULL;
00618     he.h_addr_list = (void *)addr;
00619     he.h_name = hostname;
00620     he.h_aliases = NULL;
00621     he.h_addrtype = AF_INET;
00622     he.h_length = sizeof(addr);
00623     return &he;
00624 
00625 <RANT>
00626 From the MSDN Platform SDK: Windows Sockets 2
00627 "The gethostbyname function cannot resolve IP address strings passed to it.
00628 Such a request is treated exactly as if an unknown host name were passed."
00629 </RANT>
00630 
00631 Defferring to the the documented behaviour, rather than the unix behaviour
00632 What if the hostname is in the HOSTS file? see getservbyname
00633 
00634  * @implemented
00635  */
00636 
00637 /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
00638    /* see ws2_32.h, winsock2.h*/
00639     /*getnetworkparameters - iphlp api */
00640 /*
00641 REFERENCES
00642 
00643 servent -- w32api/include/winsock2.h
00644 PWINSOCK_THREAD_BLOCK -- ws2_32.h
00645 dllmain.c -- threadlocal memory allocation / deallocation
00646 lib/dnsapi
00647 
00648 
00649 */
00650       /* lib/adns/src/adns.h XXX */
00651 
00652 
00653 /*
00654 struct  hostent {
00655         char    *h_name;
00656         char    **h_aliases;
00657         short   h_addrtype;
00658         short   h_length;
00659         char    **h_addr_list;
00660 #define h_addr h_addr_list[0]
00661 };
00662 struct  servent {
00663         char    *s_name;
00664         char    **s_aliases;
00665         short   s_port;
00666         char    *s_proto;
00667 };
00668 
00669 
00670 struct hostent defined in w32api/include/winsock2.h
00671 */
00672 
00673 void free_servent(struct servent* s)
00674 {
00675     char* next;
00676     HFREE(s->s_name);
00677     next = s->s_aliases[0];
00678     while(next) { HFREE(next); next++; }
00679     s->s_port = 0;
00680     HFREE(s->s_proto);
00681     HFREE(s);
00682 }
00683 
00684 /* This function is far from perfect but it works enough */
00685 static
00686 LPHOSTENT
00687 FindEntryInHosts(IN CONST CHAR FAR* name)
00688 {
00689     BOOL Found = FALSE;
00690     HANDLE HostsFile;
00691     CHAR HostsDBData[BUFSIZ] = { 0 };
00692     PCHAR SystemDirectory = HostsDBData;
00693     PCHAR HostsLocation = "\\drivers\\etc\\hosts";
00694     PCHAR AddressStr, DnsName = NULL, AddrTerm, NameSt, NextLine, ThisLine, Comment;
00695     UINT SystemDirSize = sizeof(HostsDBData) - 1, ValidData = 0;
00696     DWORD ReadSize;
00697     ULONG Address;
00698     PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
00699 
00700     /* We assume that the parameters are valid */
00701 
00702     if (!GetSystemDirectoryA(SystemDirectory, SystemDirSize))
00703     {
00704         WSASetLastError(WSANO_RECOVERY);
00705         WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n"));
00706         return NULL; /* Can't get system directory */
00707     }
00708 
00709     strncat(SystemDirectory,
00710             HostsLocation,
00711             SystemDirSize );
00712 
00713     HostsFile = CreateFileA(SystemDirectory,
00714                             GENERIC_READ,
00715                             FILE_SHARE_READ,
00716                             NULL,
00717                             OPEN_EXISTING,
00718                             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
00719                             NULL);
00720     if (HostsFile == INVALID_HANDLE_VALUE)
00721     {
00722         WSASetLastError(WSANO_RECOVERY);
00723         return NULL;
00724     }
00725 
00726     while(!Found &&
00727           ReadFile(HostsFile,
00728                    HostsDBData + ValidData,
00729                    sizeof(HostsDBData) - ValidData,
00730                    &ReadSize,
00731                    NULL))
00732     {
00733         ValidData += ReadSize;
00734         ReadSize = 0;
00735         NextLine = ThisLine = HostsDBData;
00736 
00737         /* Find the beginning of the next line */
00738         while(NextLine < HostsDBData + ValidData &&
00739               *NextLine != '\r' && *NextLine != '\n' )
00740         {
00741             NextLine++;
00742         }
00743 
00744         /* Zero and skip, so we can treat what we have as a string */
00745         if( NextLine > HostsDBData + ValidData )
00746             break;
00747 
00748         *NextLine = 0; NextLine++;
00749 
00750         Comment = strchr( ThisLine, '#' );
00751         if( Comment ) *Comment = 0; /* Terminate at comment start */
00752 
00753         AddressStr = ThisLine;
00754         /* Find the first space separating the IP address from the DNS name */
00755         AddrTerm = strchr(ThisLine, ' ');
00756         if (AddrTerm)
00757         {
00758            /* Terminate the address string */
00759            *AddrTerm = 0;
00760 
00761            /* Find the last space before the DNS name */
00762            NameSt = strrchr(ThisLine, ' ');
00763 
00764            /* If there is only one space (the one we removed above), then just use the address terminator */
00765            if (!NameSt)
00766                NameSt = AddrTerm;
00767 
00768            /* Move from the space to the first character of the DNS name */
00769            NameSt++;
00770 
00771            DnsName = NameSt;
00772 
00773            if (!strcmp(name, DnsName))
00774            {
00775                Found = TRUE;
00776                break;
00777            }
00778         }
00779 
00780         /* Get rid of everything we read so far */
00781         while( NextLine <= HostsDBData + ValidData &&
00782                isspace (*NextLine))
00783         {
00784             NextLine++;
00785         }
00786 
00787         if (HostsDBData + ValidData - NextLine <= 0)
00788             break;
00789 
00790         WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
00791                     HostsDBData + ValidData - NextLine));
00792 
00793         memmove(HostsDBData,
00794                 NextLine,
00795                 HostsDBData + ValidData - NextLine );
00796         ValidData -= NextLine - HostsDBData;
00797         WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
00798     }
00799 
00800     CloseHandle(HostsFile);
00801 
00802     if (!Found)
00803     {
00804         WS_DbgPrint(MAX_TRACE,("Not found\n"));
00805         WSASetLastError(WSANO_DATA);
00806         return NULL;
00807     }
00808 
00809     if( !p->Hostent )
00810     {
00811         p->Hostent = HeapAlloc(GlobalHeap, 0, sizeof(*p->Hostent));
00812         if( !p->Hostent )
00813         {
00814             WSASetLastError( WSATRY_AGAIN );
00815             return NULL;
00816         }
00817     }
00818 
00819     p->Hostent->h_name = HeapAlloc(GlobalHeap, 0, strlen(DnsName));
00820     if( !p->Hostent->h_name )
00821     {
00822         WSASetLastError( WSATRY_AGAIN );
00823         return NULL;
00824     }
00825 
00826     RtlCopyMemory(p->Hostent->h_name,
00827                   DnsName,
00828                   strlen(DnsName));
00829 
00830     p->Hostent->h_aliases = HeapAlloc(GlobalHeap, 0, sizeof(char *));
00831     if( !p->Hostent->h_aliases )
00832     {
00833         WSASetLastError( WSATRY_AGAIN );
00834         return NULL;
00835     }
00836 
00837     p->Hostent->h_aliases[0] = 0;
00838 
00839     if (strstr(AddressStr, ":"))
00840     {
00841        DbgPrint("AF_INET6 NOT SUPPORTED!\n");
00842        WSASetLastError(WSAEINVAL);
00843        return NULL;
00844     }
00845     else
00846        p->Hostent->h_addrtype = AF_INET;
00847 
00848     p->Hostent->h_addr_list = HeapAlloc(GlobalHeap, 0, sizeof(char *));
00849     if( !p->Hostent->h_addr_list )
00850     {
00851         WSASetLastError( WSATRY_AGAIN );
00852         return NULL;
00853     }
00854 
00855     Address = inet_addr(AddressStr);
00856     if (Address == INADDR_NONE)
00857     {
00858         WSASetLastError(WSAEINVAL);
00859         return NULL;
00860     }
00861 
00862     p->Hostent->h_addr_list[0] = HeapAlloc(GlobalHeap, 0, sizeof(Address));
00863     if( !p->Hostent->h_addr_list[0] )
00864     {
00865         WSASetLastError( WSATRY_AGAIN );
00866         return NULL;
00867     }
00868 
00869     RtlCopyMemory(p->Hostent->h_addr_list[0],
00870                   &Address,
00871                   sizeof(Address));
00872 
00873     p->Hostent->h_length = sizeof(Address);
00874 
00875     return p->Hostent;
00876 }
00877 
00878 LPHOSTENT
00879 EXPORT
00880 gethostbyname(IN  CONST CHAR FAR* name)
00881 {
00882     enum addr_type
00883     {
00884         GH_INVALID,
00885         GH_IPV6,
00886         GH_IPV4,
00887         GH_RFC1123_DNS
00888     };
00889     typedef enum addr_type addr_type;
00890     addr_type addr;
00891     int ret = 0;
00892     char* found = 0;
00893     DNS_STATUS dns_status = {0};
00894     /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
00895     PDNS_RECORD dp = 0;
00896     PWINSOCK_THREAD_BLOCK p;
00897     LPHOSTENT Hostent;
00898 
00899     addr = GH_INVALID;
00900 
00901     p = NtCurrentTeb()->WinSockData;
00902 
00903     if( !p )
00904     {
00905         WSASetLastError( WSANOTINITIALISED );
00906         return NULL;
00907     }
00908 
00909     check_hostent(&p->Hostent);   /*XXX alloc_hostent*/
00910 
00911     /* Hostname NULL - behave like gethostname */
00912     if(name == NULL)
00913     {
00914         ret = gethostname(p->Hostent->h_name, MAX_HOSTNAME_LEN);
00915         if(ret)
00916         {
00917             WSASetLastError( WSAHOST_NOT_FOUND ); //WSANO_DATA  ??
00918             return NULL;
00919         }
00920         return p->Hostent;
00921     }
00922 
00923     /* Is it an IPv6 address? */
00924     found = strstr(name, ":");
00925     if( found != NULL )
00926     {
00927         addr = GH_IPV6;
00928         goto act;
00929     }
00930 
00931     /* Is it an IPv4 address? */
00932     if (!isalpha(name[0]))
00933     {
00934         addr = GH_IPV4;
00935         goto act;
00936     }
00937 
00938     addr = GH_RFC1123_DNS;
00939 
00940  /* Broken out in case we want to get fancy later */
00941  act:
00942     switch(addr)
00943     {
00944         case GH_IPV6:
00945             WSASetLastError(STATUS_NOT_IMPLEMENTED);
00946             return NULL;
00947         break;
00948 
00949         case GH_INVALID:
00950             WSASetLastError(WSAEFAULT);
00951             return NULL;
00952         break;
00953 
00954         /* Note: If passed an IP address, MSDN says that gethostbyname()
00955                  treats it as an unknown host.
00956            This is different from the unix implementation. Use inet_addr()
00957         */
00958         case GH_IPV4:
00959         case GH_RFC1123_DNS:
00960         /* DNS_TYPE_A: include/WinDNS.h */
00961         /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
00962 
00963         /* Look for the DNS name in the hosts file */
00964         Hostent = FindEntryInHosts(name);
00965         if (Hostent)
00966            return Hostent;
00967 
00968         dns_status = DnsQuery_A(name,
00969                                 DNS_TYPE_A,
00970                                 DNS_QUERY_STANDARD,
00971                                 0,
00972                                 /* extra dns servers */ &dp,
00973                                 0);
00974 
00975         if(dns_status == 0)
00976         {
00977             //ASSERT(dp->wType == DNS_TYPE_A);
00978             //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
00979             PDNS_RECORD curr;
00980             for(curr=dp;
00981                 curr != NULL && curr->wType != DNS_TYPE_A;
00982                 curr = curr->pNext )
00983             {
00984                 WS_DbgPrint(MID_TRACE,("wType: %i\n", curr->wType));
00985                 /*empty */
00986             }
00987 
00988             if(curr)
00989             {
00990                 WS_DbgPrint(MID_TRACE,("populating hostent\n"));
00991                 WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName));
00992                 populate_hostent(p->Hostent, (PCHAR)curr->pName, curr->Data.A);
00993                 DnsRecordListFree(dp, DnsFreeRecordList);
00994                 return p->Hostent;
00995             }
00996             else
00997             {
00998                 DnsRecordListFree(dp, DnsFreeRecordList);
00999             }
01000         }
01001 
01002         WS_DbgPrint(MID_TRACE,("Called DnsQuery, but host not found. Err: %i\n",
01003                     dns_status));
01004         WSASetLastError(WSAHOST_NOT_FOUND);
01005         return NULL;
01006 
01007         break;
01008 
01009         default:
01010             WSASetLastError(WSANO_RECOVERY);
01011             return NULL;
01012         break;
01013     }
01014 
01015     WSASetLastError(WSANO_RECOVERY);
01016     return NULL;
01017 }
01018 
01019 /*
01020  * @implemented
01021  */
01022 INT
01023 EXPORT
01024 gethostname(OUT CHAR FAR* name,
01025             IN  INT namelen)
01026 {
01027     DWORD size = namelen;
01028 
01029     int ret = GetComputerNameExA(ComputerNameDnsHostname,
01030                                  name,
01031                                  &size);
01032     if(ret == 0)
01033     {
01034         WSASetLastError(WSAEFAULT);
01035         return SOCKET_ERROR;
01036     }
01037     else
01038     {
01039         name[namelen-1] = '\0';
01040         return 0;
01041     }
01042 }
01043 
01044 
01045 /*
01046  * XXX arty -- Partial implementation pending a better one.  This one will
01047  * do for normal purposes.#include <ws2_32.h>
01048  *
01049  * Return the address of a static LPPROTOENT corresponding to the named
01050  * protocol.  These structs aren't very interesting, so I'm not too ashamed
01051  * to have this function work on builtins for now.
01052  *
01053  * @unimplemented
01054  */
01055  
01056 static CHAR *no_aliases = 0;
01057 static PROTOENT protocols[] =
01058 {
01059     {"icmp",&no_aliases, IPPROTO_ICMP},
01060     {"tcp", &no_aliases, IPPROTO_TCP},
01061     {"udp", &no_aliases, IPPROTO_UDP},
01062     {NULL, NULL, 0}
01063 };
01064  
01065 LPPROTOENT
01066 EXPORT
01067 getprotobyname(IN  CONST CHAR FAR* name)
01068 {
01069     UINT i;
01070     for (i = 0; protocols[i].p_name; i++)
01071     {
01072        if (_stricmp(protocols[i].p_name, name) == 0)
01073          return &protocols[i];
01074     }
01075     return NULL;
01076 }
01077 
01078 /*
01079  * @unimplemented
01080  */
01081 LPPROTOENT
01082 EXPORT
01083 getprotobynumber(IN  INT number)
01084 {
01085     UINT i;
01086     for (i = 0; protocols[i].p_name; i++)
01087     {
01088        if (protocols[i].p_proto == number)
01089          return &protocols[i];
01090     }
01091     return NULL;
01092 }
01093 
01094 #define SKIPWS(ptr,act) \
01095 {while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;}
01096 #define SKIPANDMARKSTR(ptr,act) \
01097 {while(*ptr && !isspace(*ptr)) ptr++; \
01098  if(!*ptr) {act;} else { *ptr = 0; ptr++; }}
01099 
01100 
01101 static BOOL
01102 DecodeServEntFromString(IN  PCHAR ServiceString,
01103                         OUT PCHAR *ServiceName,
01104                         OUT PCHAR *PortNumberStr,
01105                         OUT PCHAR *ProtocolStr,
01106                         IN  PCHAR *Aliases,
01107                         IN  DWORD MaxAlias)
01108 {
01109     UINT NAliases = 0;
01110 
01111     WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString));
01112 
01113     SKIPWS(ServiceString, return FALSE);
01114     *ServiceName = ServiceString;
01115     SKIPANDMARKSTR(ServiceString, return FALSE);
01116     SKIPWS(ServiceString, return FALSE);
01117     *PortNumberStr = ServiceString;
01118     SKIPANDMARKSTR(ServiceString, ;);
01119 
01120     while( *ServiceString && NAliases < MaxAlias - 1 )
01121     {
01122         SKIPWS(ServiceString, break);
01123         if( *ServiceString )
01124         {
01125             SKIPANDMARKSTR(ServiceString, ;);
01126             if( strlen(ServiceString) )
01127             {
01128                 WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString));
01129                 *Aliases++ = ServiceString;
01130                 NAliases++;
01131             }
01132         }
01133     }
01134     *Aliases = NULL;
01135 
01136     *ProtocolStr = strchr(*PortNumberStr,'/');
01137     if( !*ProtocolStr ) return FALSE;
01138     **ProtocolStr = 0; (*ProtocolStr)++;
01139 
01140     WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n",
01141                 *ServiceName, *ProtocolStr, *PortNumberStr,
01142                 NAliases));
01143 
01144     return TRUE;
01145 }
01146 
01147 #define ADJ_PTR(p,b1,b2) p = (p - b1) + b2
01148 
01149 /*
01150  * @implemented
01151  */
01152 LPSERVENT
01153 EXPORT
01154 getservbyname(IN  CONST CHAR FAR* name,
01155               IN  CONST CHAR FAR* proto)
01156 {
01157     BOOL  Found = FALSE;
01158     HANDLE ServicesFile;
01159     CHAR ServiceDBData[BUFSIZ] = { 0 };
01160     PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */
01161     PCHAR ServicesFileLocation = "\\drivers\\etc\\services";
01162     PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0,
01163     ProtocolStr = 0, Comment = 0, EndValid;
01164     PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 };
01165     UINT i,SizeNeeded = 0,
01166     SystemDirSize = sizeof(ServiceDBData) - 1;
01167     DWORD ReadSize = 0;
01168     PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
01169 
01170     if( !p )
01171     {
01172         WSASetLastError( WSANOTINITIALISED );
01173         return NULL;
01174     }
01175 
01176     if( !name )
01177     {
01178         WSASetLastError( WSANO_RECOVERY );
01179         return NULL;
01180     }
01181 
01182     if( !GetSystemDirectoryA( SystemDirectory, SystemDirSize ) )
01183     {
01184         WSASetLastError( WSANO_RECOVERY );
01185         WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n"));
01186         return NULL; /* Can't get system directory */
01187     }
01188 
01189     strncat(SystemDirectory,
01190             ServicesFileLocation,
01191             SystemDirSize );
01192 
01193     ServicesFile = CreateFileA(SystemDirectory,
01194                                GENERIC_READ,
01195                                FILE_SHARE_READ,
01196                                NULL,
01197                                OPEN_EXISTING,
01198                                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
01199                                NULL );
01200 
01201     if( ServicesFile == INVALID_HANDLE_VALUE )
01202     {
01203         WSASetLastError( WSANO_RECOVERY );
01204         return NULL;
01205     }
01206     
01207     /* Scan the services file ...
01208     *
01209     * We will be share the buffer on the lines. If the line does not fit in
01210     * the buffer, then moving it to the beginning of the buffer and read
01211     * the remnants of line from file.
01212     */
01213     
01214     /* Initial Read */
01215     ReadFile(ServicesFile,
01216                    ServiceDBData,
01217                    sizeof( ServiceDBData ) - 1,
01218                    &ReadSize, NULL );
01219     ThisLine = NextLine = ServiceDBData;
01220     EndValid = ServiceDBData + ReadSize;
01221     ServiceDBData[sizeof(ServiceDBData) - 1] = '\0';
01222     
01223     while(ReadSize)
01224     {
01225         for(; *NextLine != '\r' && *NextLine != '\n'; NextLine++)
01226         {
01227             if(NextLine == EndValid)
01228             {
01229                 int LineLen = NextLine - ThisLine;
01230                 
01231                 if(ThisLine == ServiceDBData)
01232                 {
01233                     WS_DbgPrint(MIN_TRACE,("Line too long"));
01234                     WSASetLastError( WSANO_RECOVERY );
01235                     return NULL;
01236                 }
01237 
01238                 memmove(ServiceDBData, ThisLine, LineLen);
01239            
01240                 ReadFile(ServicesFile, ServiceDBData + LineLen,
01241                          sizeof( ServiceDBData )-1 - LineLen,
01242                          &ReadSize, NULL );
01243                                
01244                 EndValid = ServiceDBData + LineLen + ReadSize;
01245                 NextLine = ServiceDBData + LineLen;
01246                 ThisLine = ServiceDBData;
01247                 
01248                 if(!ReadSize) break;
01249             }
01250         }
01251         
01252         *NextLine = '\0';
01253         Comment = strchr( ThisLine, '#' );
01254         if( Comment ) *Comment = '\0'; /* Terminate at comment start */
01255         
01256         if(DecodeServEntFromString(ThisLine,
01257                                    &ServiceName,
01258                                    &PortNumberStr,
01259                                    &ProtocolStr,
01260                                    Aliases,
01261                                    WS2_INTERNAL_MAX_ALIAS) &&
01262            !strcmp( ServiceName, name ) &&
01263            (proto ? !strcmp( ProtocolStr, proto ) : TRUE) )
01264         {
01265 
01266             WS_DbgPrint(MAX_TRACE,("Found the service entry.\n"));
01267             Found = TRUE;
01268             SizeNeeded = sizeof(WINSOCK_GETSERVBYNAME_CACHE) +
01269                 (NextLine - ThisLine);
01270             break;
01271         }
01272         NextLine++;
01273         ThisLine = NextLine;
01274     }
01275 
01276     /* This we'll do no matter what */
01277     CloseHandle( ServicesFile );
01278 
01279     if( !Found )
01280     {
01281         WS_DbgPrint(MAX_TRACE,("Not found\n"));
01282         WSASetLastError( WSANO_DATA );
01283         return NULL;
01284     }
01285 
01286     if( !p->Getservbyname || p->Getservbyname->Size < SizeNeeded )
01287     {
01288         /* Free previous getservbyname buffer, allocate bigger */
01289         if( p->Getservbyname )
01290             HeapFree(GlobalHeap, 0, p->Getservbyname);
01291         p->Getservbyname = HeapAlloc(GlobalHeap, 0, SizeNeeded);
01292         if( !p->Getservbyname )
01293         {
01294             WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n",
01295                         SizeNeeded));
01296             WSASetLastError( WSATRY_AGAIN );
01297             return NULL;
01298         }
01299         p->Getservbyname->Size = SizeNeeded;
01300     }
01301 
01302     /* Copy the data */
01303     memmove(p->Getservbyname->Data,
01304             ThisLine,
01305             NextLine - ThisLine );
01306 
01307     ADJ_PTR(ServiceName,ThisLine,p->Getservbyname->Data);
01308     ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyname->Data);
01309     WS_DbgPrint(MAX_TRACE, ("ServiceName: %s, Protocol: %s\n",
01310                 ServiceName,
01311                 ProtocolStr));
01312 
01313     for( i = 0; Aliases[i]; i++ )
01314     {
01315         ADJ_PTR(Aliases[i],ThisLine,p->Getservbyname->Data);
01316         WS_DbgPrint(MAX_TRACE,("Aliase %d: %s\n", i, Aliases[i]));
01317     }
01318 
01319     memcpy(p->Getservbyname,
01320            Aliases,
01321            sizeof(Aliases));
01322 
01323     /* Create the struct proper */
01324     p->Getservbyname->ServerEntry.s_name = ServiceName;
01325     p->Getservbyname->ServerEntry.s_aliases = p->Getservbyname->Aliases;
01326     p->Getservbyname->ServerEntry.s_port = htons(atoi(PortNumberStr));
01327     p->Getservbyname->ServerEntry.s_proto = ProtocolStr;
01328 
01329     return &p->Getservbyname->ServerEntry;
01330 }
01331 
01332 
01333 /*
01334  * @implemented
01335  */
01336 LPSERVENT
01337 EXPORT
01338 getservbyport(IN  INT port,
01339               IN  CONST CHAR FAR* proto)
01340 {
01341     BOOL  Found = FALSE;
01342     HANDLE ServicesFile;
01343     CHAR ServiceDBData[BUFSIZ] = { 0 };
01344     PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */
01345     PCHAR ServicesFileLocation = "\\drivers\\etc\\services";
01346     PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0,
01347     ProtocolStr = 0, Comment = 0;
01348     PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 };
01349     UINT i,SizeNeeded = 0,
01350     SystemDirSize = sizeof(ServiceDBData) - 1;
01351     DWORD ReadSize = 0, ValidData = 0;
01352     PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
01353 
01354     if( !p )
01355     {
01356         WSASetLastError( WSANOTINITIALISED );
01357         return NULL;
01358     }
01359 
01360     if ( !port )
01361     {
01362         WSASetLastError( WSANO_RECOVERY );
01363         return NULL;
01364     }
01365 
01366     if( !GetSystemDirectoryA( SystemDirectory, SystemDirSize ) )
01367     {
01368         WSASetLastError( WSANO_RECOVERY );
01369         WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n"));
01370         return NULL; /* Can't get system directory */
01371     }
01372 
01373     strncat(SystemDirectory,
01374             ServicesFileLocation,
01375             SystemDirSize );
01376 
01377     ServicesFile = CreateFileA(SystemDirectory,
01378                                GENERIC_READ,
01379                                FILE_SHARE_READ,
01380                                NULL,
01381                                OPEN_EXISTING,
01382                                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
01383                                NULL );
01384 
01385     if( ServicesFile == INVALID_HANDLE_VALUE )
01386     {
01387         WSASetLastError( WSANO_RECOVERY );
01388         return NULL;
01389     }
01390 
01391     /* Scan the services file ...
01392      *
01393      * We will read up to BUFSIZ bytes per pass, until the buffer does not
01394      * contain a full line, then we will try to read more.
01395      *
01396      * We fall from the loop if the buffer does not have a line terminator.
01397      */
01398 
01399     /* Initial Read */
01400     while(!Found &&
01401           ReadFile(ServicesFile,
01402                    ServiceDBData + ValidData,
01403                    sizeof( ServiceDBData ) - ValidData,
01404                    &ReadSize, NULL ) )
01405     {
01406         ValidData += ReadSize;
01407         ReadSize = 0;
01408         NextLine = ThisLine = ServiceDBData;
01409 
01410         /* Find the beginning of the next line */
01411         while( NextLine < ServiceDBData + ValidData &&
01412                *NextLine != '\r' && *NextLine != '\n' ) NextLine++;
01413 
01414         /* Zero and skip, so we can treat what we have as a string */
01415         if( NextLine > ServiceDBData + ValidData )
01416             break;
01417 
01418         *NextLine = 0; NextLine++;
01419 
01420         Comment = strchr( ThisLine, '#' );
01421         if( Comment ) *Comment = 0; /* Terminate at comment start */
01422 
01423         if(DecodeServEntFromString(ThisLine,
01424                                    &ServiceName,
01425                                    &PortNumberStr,
01426                                    &ProtocolStr,
01427                                    Aliases,
01428                                    WS2_INTERNAL_MAX_ALIAS ) &&
01429            (htons(atoi( PortNumberStr )) == port ) &&
01430            (proto ? !strcmp( ProtocolStr, proto ) : TRUE) )
01431         {
01432 
01433             WS_DbgPrint(MAX_TRACE,("Found the port entry.\n"));
01434 
01435             Found = TRUE;
01436             SizeNeeded = sizeof(WINSOCK_GETSERVBYPORT_CACHE) +
01437             (NextLine - ThisLine);
01438             break;
01439         }
01440 
01441         /* Get rid of everything we read so far */
01442         while( NextLine <= ServiceDBData + ValidData &&
01443                isspace( *NextLine ) )
01444         {
01445             NextLine++;
01446         }
01447 
01448         WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
01449                     ServiceDBData + ValidData - NextLine));
01450 
01451         memmove(ServiceDBData,
01452                 NextLine,
01453                 ServiceDBData + ValidData - NextLine );
01454         ValidData -= NextLine - ServiceDBData;
01455         WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
01456     }
01457 
01458     /* This we'll do no matter what */
01459     CloseHandle( ServicesFile );
01460 
01461     if( !Found )
01462     {
01463         WS_DbgPrint(MAX_TRACE,("Not found\n"));
01464         WSASetLastError( WSANO_DATA );
01465         return NULL;
01466     }
01467 
01468     if( !p->Getservbyport || p->Getservbyport->Size < SizeNeeded )
01469     {
01470         /* Free previous getservbyport buffer, allocate bigger */
01471         if( p->Getservbyport )
01472             HeapFree(GlobalHeap, 0, p->Getservbyport);
01473         p->Getservbyport = HeapAlloc(GlobalHeap,
01474                                      0,
01475                                      SizeNeeded);
01476         if( !p->Getservbyport )
01477         {
01478             WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n",
01479                         SizeNeeded));
01480             WSASetLastError( WSATRY_AGAIN );
01481             return NULL;
01482         }
01483         p->Getservbyport->Size = SizeNeeded;
01484     }
01485     /* Copy the data */
01486     memmove(p->Getservbyport->Data,
01487             ThisLine,
01488             NextLine - ThisLine );
01489 
01490     ADJ_PTR(PortNumberStr,ThisLine,p->Getservbyport->Data);
01491     ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyport->Data);
01492     WS_DbgPrint(MAX_TRACE, ("Port Number: %s, Protocol: %s\n",
01493                 PortNumberStr, ProtocolStr));
01494 
01495     for( i = 0; Aliases[i]; i++ )
01496     {
01497         ADJ_PTR(Aliases[i],ThisLine,p->Getservbyport->Data);
01498         WS_DbgPrint(MAX_TRACE,("Aliases %d: %s\n", i, Aliases[i]));
01499     }
01500 
01501     memcpy(p->Getservbyport,Aliases,sizeof(Aliases));
01502 
01503     /* Create the struct proper */
01504     p->Getservbyport->ServerEntry.s_name = ServiceName;
01505     p->Getservbyport->ServerEntry.s_aliases = p->Getservbyport->Aliases;
01506     p->Getservbyport->ServerEntry.s_port = port;
01507     p->Getservbyport->ServerEntry.s_proto = ProtocolStr;
01508 
01509     WS_DbgPrint(MID_TRACE,("s_name: %s\n", ServiceName));
01510 
01511     return &p->Getservbyport->ServerEntry;
01512 
01513 }
01514 
01515 
01516 /*
01517  * @implemented
01518  */
01519 ULONG
01520 EXPORT
01521 inet_addr(IN  CONST CHAR FAR* cp)
01522 /*
01523  * FUNCTION: Converts a string containing an IPv4 address to an unsigned long
01524  * ARGUMENTS:
01525  *     cp = Pointer to string with address to convert
01526  * RETURNS:
01527  *     Binary representation of IPv4 address, or INADDR_NONE
01528  */
01529 {
01530     UINT i;
01531     PCHAR p;
01532     ULONG u = 0;
01533 
01534     p = (PCHAR)cp;
01535 
01536     if (!p)
01537     {
01538         WSASetLastError(WSAEFAULT);
01539         return INADDR_NONE;
01540     }
01541 
01542     if (strlen(p) == 0)
01543         return INADDR_NONE;
01544 
01545     if (strcmp(p, " ") == 0)
01546         return 0;
01547 
01548     for (i = 0; i <= 3; i++)
01549     {
01550         u += (strtoul(p, &p, 0) << (i * 8));
01551 
01552         if (strlen(p) == 0)
01553             return u;
01554 
01555         if (p[0] != '.')
01556             return INADDR_NONE;
01557 
01558         p++;
01559     }
01560 
01561     return u;
01562 }
01563 
01564 
01565 /*
01566  * @implemented
01567  */
01568 CHAR FAR*
01569 EXPORT
01570 inet_ntoa(IN  IN_ADDR in)
01571 {
01572     CHAR b[10];
01573     PCHAR p;
01574 
01575     p = ((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Intoa;
01576     _itoa(in.S_un.S_addr & 0xFF, b, 10);
01577     strcpy(p, b);
01578     _itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10);
01579     strcat(p, ".");
01580     strcat(p, b);
01581     _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
01582     strcat(p, ".");
01583     strcat(p, b);
01584     _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
01585     strcat(p, ".");
01586     strcat(p, b);
01587 
01588     return (CHAR FAR*)p;
01589 }
01590 
01591 
01592 /*
01593  * @implemented
01594  */
01595 VOID
01596 EXPORT
01597 freeaddrinfo(struct addrinfo *pAddrInfo)
01598 {
01599     struct addrinfo *next, *cur;
01600     cur = pAddrInfo;
01601     while (cur)
01602     {
01603         next = cur->ai_next;
01604         if (cur->ai_addr)
01605           HeapFree(GetProcessHeap(), 0, cur->ai_addr);
01606         if (cur->ai_canonname)
01607           HeapFree(GetProcessHeap(), 0, cur->ai_canonname);
01608         HeapFree(GetProcessHeap(), 0, cur);
01609         cur = next;
01610     }
01611 }
01612 
01613 
01614 struct addrinfo *
01615 new_addrinfo(struct addrinfo *prev)
01616 {
01617     struct addrinfo *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct addrinfo));
01618     if (prev)
01619       prev->ai_next = ret;
01620     return ret;
01621 }
01622 
01623 /*
01624  * @implemented
01625  */
01626 INT
01627 EXPORT
01628 getaddrinfo(const char FAR * nodename,
01629             const char FAR * servname,
01630             const struct addrinfo FAR * hints,
01631             struct addrinfo FAR * FAR * res)
01632 {
01633     struct addrinfo *ret = NULL, *ai;
01634     ULONG addr;
01635     USHORT port;
01636     struct servent *se;
01637     char *proto;
01638     LPPROTOENT pent;
01639     DNS_STATUS dns_status;
01640     PDNS_RECORD dp, currdns;
01641     struct sockaddr_in *sin;
01642 
01643     if (res == NULL)
01644         return WSAEINVAL;
01645     if (nodename == NULL && servname == NULL)
01646         return WSAHOST_NOT_FOUND;
01647         
01648     if (!WSAINITIALIZED)
01649         return WSANOTINITIALISED;
01650 
01651     if (servname)
01652     {
01653         /* converting port number */
01654         port = strtoul(servname, NULL, 10);
01655         /* service name was specified? */
01656         if (port == 0)
01657         {
01658             /* protocol was specified? */
01659             if (hints && hints->ai_protocol)
01660             {
01661                 pent = getprotobynumber(hints->ai_protocol);
01662                 if (pent == NULL)
01663                   return WSAEINVAL;
01664                 proto = pent->p_name;
01665             }
01666             else
01667                 proto = NULL;
01668             se = getservbyname(servname, proto);
01669             if (se == NULL)
01670                 return WSATYPE_NOT_FOUND;
01671             port = se->s_port;
01672         }
01673         else
01674             port = htons(port);
01675     }
01676     else
01677         port = 0;
01678 
01679     if (nodename)
01680     {
01681         /* Is it an IPv6 address? */
01682         if (strstr(nodename, ":"))
01683             return WSAHOST_NOT_FOUND;
01684             
01685         /* Is it an IPv4 address? */
01686         addr = inet_addr(nodename);
01687         if (addr != INADDR_NONE)
01688         {
01689             ai = new_addrinfo(NULL);
01690             ai->ai_family = PF_INET;
01691             ai->ai_addrlen = sizeof(struct sockaddr_in);
01692             ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen);
01693             sin = (struct sockaddr_in *)ai->ai_addr;
01694             sin->sin_family = AF_INET;
01695             sin->sin_port = port;
01696             RtlCopyMemory(&sin->sin_addr, &addr, sizeof(sin->sin_addr));
01697             if (hints)
01698             {
01699                 if (ai->ai_socktype == 0)
01700                     ai->ai_socktype = hints->ai_socktype;
01701                 if (ai->ai_protocol == 0)
01702                     ai->ai_protocol = hints->ai_protocol;
01703             }
01704             ret = ai;
01705         }
01706         else
01707         {
01708            /* resolving host name */
01709             dns_status = DnsQuery_A(nodename,
01710                                     DNS_TYPE_A,
01711                                     DNS_QUERY_STANDARD,
01712                                     0,
01713                                     /* extra dns servers */ &dp,
01714                                     0);
01715 
01716             if (dns_status == 0)
01717             {
01718                 ai = NULL;
01719                 for (currdns = dp; currdns; currdns = currdns->pNext )
01720                 {
01721                     /* accept only A records */
01722                     if (currdns->wType != DNS_TYPE_A) continue;
01723                     
01724                     ai = new_addrinfo(ai);
01725                     if (ret == NULL)
01726                       ret = ai;
01727                     ai->ai_family = PF_INET;
01728                     ai->ai_addrlen = sizeof(struct sockaddr_in);
01729                     ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen);
01730                     sin = (struct sockaddr_in *)ret->ai_addr;
01731                     sin->sin_family = AF_INET;
01732                     sin->sin_port = port;
01733                     RtlCopyMemory(&sin->sin_addr, &currdns->Data.A.IpAddress, sizeof(sin->sin_addr));
01734                     if (hints)
01735                     {
01736                         if (ai->ai_socktype == 0)
01737                             ai->ai_socktype = hints->ai_socktype;
01738                         if (ai->ai_protocol == 0)
01739                             ai->ai_protocol = hints->ai_protocol;
01740                     }
01741                 }
01742                 DnsRecordListFree(dp, DnsFreeRecordList);
01743             }
01744         }
01745     }
01746     else
01747     {
01748         ai = new_addrinfo(NULL);
01749         ai->ai_family = PF_INET;
01750         ai->ai_addrlen = sizeof(struct sockaddr_in);
01751         ai->ai_addr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ai->ai_addrlen);
01752         sin = (struct sockaddr_in *)ai->ai_addr;
01753         sin->sin_family = AF_INET;
01754         sin->sin_port = port;
01755         if (hints)
01756         {
01757             if (!(hints->ai_flags & AI_PASSIVE))
01758             {
01759                 sin->sin_addr.S_un.S_un_b.s_b1 = 127;
01760                 sin->sin_addr.S_un.S_un_b.s_b2 = 0;
01761                 sin->sin_addr.S_un.S_un_b.s_b3 = 0;
01762                 sin->sin_addr.S_un.S_un_b.s_b4 = 1;
01763             }
01764             if (ai->ai_socktype == 0)
01765                 ai->ai_socktype = hints->ai_socktype;
01766             if (ai->ai_protocol == 0)
01767                 ai->ai_protocol = hints->ai_protocol;
01768         }
01769         ret = ai;
01770     }
01771 
01772     if (ret == NULL)
01773         return WSAHOST_NOT_FOUND;
01774         
01775     if (hints && hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET)
01776     {
01777         freeaddrinfo(ret);
01778         return WSAEAFNOSUPPORT;
01779     }
01780 
01781     *res = ret;
01782     return 0;
01783 }
01784 
01785 /* EOF */

Generated on Sun May 27 2012 04:27:08 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.