The gethostbyname function returns information about a host identified by name. The host information is returned in a structure of type hostent. This structure is allocated by the WinSock2 library, and your program should not attempt to modify or de-allocate, the structure or any of its components.
Only one copy of the hostent structure is allocated per calling thread, and since Irie Pascal programs only have one thread, there will be only one copy of this structure allocated for your program. As a result, you should copy any host information you need from the structure before calling any other Windows Sockets functions.
The system include file WinSock2.inc contains the following declaration for the hostent and p_hostent types and the gethostbyname function:
hostent = packed record h_name : address; h_aliases : address; h_addrtype : shortint; h_length : shortint; h_addr_list : address; end; p_hostent = ^hostent; function gethostbyname(name : address) : p_hostent; external dll='ws2_32.dll';
The first, and only, argument passed to the gethostbyname function is the operating system address of the buffer containing the name of the host you want to get information about. The type of this argument is the built-in type address, so you must use the built-in function addr to get the operating system address of the buffer. The host name contained in the buffer must be a null-terminated string (i.e. a cstring).
The buffer pointed to by this argument must contain a valid host name and not an address. If you have the address (as a null-terminated string) of a host instead of the name of the host, and you want to get information about that host then you should do the following:
The gethostbyname function returns a pointer to the hostent structure that contains the host information, if the call is successful. If the call fails then the value nil is returned, and in this case you can use the WSAGetLastError function to retrieve a code that identifies the error that caused the call to fail.
The following procedure was taken from one of the sample programs distributed with Irie Pascal and shows one way to use the gethostbyname function.
//PURPOSE: Given the name of a host performs a DNS lookup //PARAMETER(s): // 1. sName - contains the name of the host procedure DNSLookUp(strName : string); var pHostEnt : p_hostent; cstrName : cstring; begin //Convert the name to a cstring since 'gethostbyname' expects a cstring cstrName := strName; pHostEnt := gethostbyname(addr(cstrName)); if pHostEnt = nil then writeln('Can not find host ''', cstrName, '''') else DisplayHostEntInfo(pHostEnt); end;
The procedure DisplayHostEntInfo is defined by the sample program and displays the host information stored in the hostent structure. The procedure DisplayHostEntInfo is below and shows one way to access the host information.
//PURPOSE: Displays the information that was obtained from a DNS or Reverse DNS lookup //PARAMETER(s): // 1. pHostEnt - a pointer to the sockets API hostent structure that contains // the result of the lookup. //NOTES: // This procedure uses the Windows API functions 'lstrlen' and 'lstrcpy' to //manipulate strings in C format (i.e. null-terminated arrays of char). These //functions are used because the strings in the hostent structure are in C format. //Since these functions are not described in the online help (because they are //Windows API functions not Irie Pascal functions) a brief description is given //below for persons not already familiar with these functions: // 'lstrlen' returns the length of the string (not counting the null terminator). // 'lstrcpy' copies the string pointed to by its second argument into the memory // pointed to by its first argument (the null terminator is also copied). procedure DisplayHostEntInfo(pHostEnt : p_hostent); const MAX_ASCII_ADDRESS = 15; var AddrTemp, AddrAddr, AddrRet : address; iRet : integer; strAddress : cstring[MAX_ASCII_ADDRESS]; strName : cstring; //PURPOSE: Returns the address pointed to be another address. //PARAMETER(s): // 1. a - an address pointing to another address //RETURNS: // The address pointed to by the parameter 'a'. //NOTES: //Irie Pascal pointer variables contain virtual addresses that are only //meaningful to the Irie Pascal Run Time Engine. However when using the //Windows API you occassionally need to manipulate non-virtual addresses. //To make this easier Irie Pascal supports a new type called 'address'. //However you can't use ^ to dereference an address, because addresses //are like untyped pointers (i.e. the compiler does not know the type of //the value pointed to by the address, so it can not generate code to return //the value pointed to be the address). The address type is assignment //compatible with all pointer types and vice/versa, so the solution to this //problem is to assign the address to suitable pointer variable and then //dereference the pointer variable. //In the case of the function below the address is known to be pointing // to another address. So the address to be deferenced is assigned to // a pointer to an address, and then this pointer is dereferenced. function DereferenceAddress(a : address) : address; var p : ^address; begin p := a; DereferenceAddress := p^; end; begin (* DisplayHostEntInfo *) //pHostEnt^.h_name is the address of a null-terminated string containing //the name of the host. writeln('NAME:'); if pHostEnt^.h_name=NULL then writeln('NOT FOUND') else if (lstrlen(pHostEnt^.h_name)+1) > sizeof(strName) then writeln('TOO LONG') else begin iRet := lstrcpy(addr(strName), pHostEnt^.h_name); writeln(strName); end; writeln; //pHostEnt^.h_aliases is the address of a null terminated array of addresses //of null-terminated strings containing alternative names for the host. writeln('ALIASES:'); AddrAddr := pHostEnt^.h_aliases; if AddrAddr = NULL then writeln('None') else begin AddrTemp := DereferenceAddress(AddrAddr); while AddrTemp <> NULL do begin if lstrlen(AddrTemp) > 0 then begin if (lstrlen(addrTemp)+1) > sizeof(strName) then writeln('TOO LONG') else begin iRet := lstrcpy(addr(strName), AddrTemp); writeln(strName); end; end else writeln('EMPTY'); AddrAddr := AddrAddr + sizeof(address); AddrTemp := DereferenceAddress(AddrAddr); end; end; writeln; if pHostEnt^.h_addrtype <> AF_INET then writeln('Invalid address type') else if pHostEnt^.h_length <> sizeof(address) then writeln('Invalid address length') else begin //pHostEnt^.h_addr_list is the address of a null terminated array of //addresses of IP addresses of the host. writeln('ADDRESSES:'); AddrAddr := pHostEnt^.h_addr_list; if AddrAddr = NULL then writeln('None') else begin //Get the first element of the array AddrTemp := DereferenceAddress(AddrAddr); while AddrTemp <> NULL do begin //Dereference the current array element to get the //IP address. AddrTemp := DereferenceAddress(AddrTemp); //Convert the IP address from binary format to a human //readable format (like nnnn.nnnn.nnnn.nnn) AddrRet := inet_ntoa(AddrTemp); if (AddrRet=null) or ((lstrlen(AddrRet)+1)>sizeof(strAddress)) then writeln('[ERROR]') else begin iRet := lstrcpy(addr(strAddress), AddrRet); writeln(strAddress); end; AddrAddr := AddrAddr + sizeof(address); //Get the next element of the array AddrTemp := DereferenceAddress(AddrAddr); end; end; writeln; end; end; (* DisplayHostEntInfo *)
The authoritative source of information about the WinSock2 library is the Microsoft Developers Network (MSDN). You can access the MSDN on the Microsoft website at msdn.microsoft.com.