UNSAFE MODULE*********** PROCEDURE GetHostByName(nm: TEXT; VAR (*out; IMPORT IPError, M3toC, Process, WinSock; VAR mu := NEW(MUTEX); IP
res: Address): BOOLEAN RAISES {Error} = BEGIN LOCK mu DO VAR s := M3toC.SharedTtoS(nm); h := WinSock.gethostbyname(s); BEGIN M3toC.FreeSharedS(nm, s); IF h = NIL THEN InterpretError(); RETURN FALSE; END; res := GetAddress(h); END; END; RETURN TRUE; END GetHostByName; **************) PROCEDURE************ PROCEDURE GetCanonicalByName(nm: TEXT): TEXT RAISES {Error} = BEGIN LOCK mu DO VAR s := M3toC.SharedTtoS(nm); h := WinSock.gethostbyname(s); BEGIN M3toC.FreeSharedS (nm, s); IF h # NIL THEN RETURN M3toC.CopyStoT(h.h_name); END; InterpretError(); END; END; RETURN NIL; END GetCanonicalByName; ***********GetHostByName (nm: TEXT; VAR (*out*) res: Address): BOOLEAN RAISES {Error} = (* Apparently WinSock "gethostbyname" does not resolve names that happen to be dotted IP addresses (e.g. "123.33.44.44"). This function does. *) VAR s := M3toC.SharedTtoS(nm); a := WinSock.inet_addr(s); h : WinSock.struct_hostent_star; BEGIN IF a # WinSock.INADDR_NONE THEN (* the name is already a dotted IP address *) M3toC.FreeSharedS(nm, s); res := LOOPHOLE (a, Address); ELSE (* the name is not a dotted IP address *) LOCK mu DO h := WinSock.gethostbyname(s); M3toC.FreeSharedS(nm, s); IF h = NIL THEN InterpretError(); RETURN FALSE; END; res := GetAddress(h); END; END; RETURN TRUE; END GetHostByName;
PROCEDUREGetCanonicalByName (nm: TEXT): TEXT RAISES {Error} = (* Apparently WinSock "gethostbyname" does not resolve names that happen to be dotted IP addresses (e.g. "123.33.44.44"). This function does. *) VAR s := M3toC.SharedTtoS(nm); a := WinSock.inet_addr(s); h : WinSock.struct_hostent_star; BEGIN LOCK mu DO IF a = WinSock.INADDR_NONE THEN (* the name is not a dotted IP address *) h := WinSock.gethostbyname(s); ELSE (* the name is a dotted IP address *) h := WinSock.gethostbyaddr(ADR(a), BYTESIZE(a), WinSock.PF_INET); END; M3toC.FreeSharedS(nm, s); IF h = NIL THEN InterpretError(); RETURN NIL; END; RETURN M3toC.CopyStoT(h.h_name); END; END GetCanonicalByName; PROCEDUREGetCanonicalByAddr (addr: Address): TEXT RAISES {Error} = VAR ua: WinSock.struct_in_addr; BEGIN ua.s_addr := LOOPHOLE(addr, WinSock.u_long); LOCK mu DO VAR h := WinSock.gethostbyaddr( ADR(ua), BYTESIZE(ua), WinSock.AF_INET); BEGIN IF h # NIL THEN RETURN M3toC.CopyStoT(h.h_name); END; END; InterpretError(); END; RETURN NIL; END GetCanonicalByAddr; PROCEDUREGetAddress (ent: WinSock.struct_hostent_star): Address = VAR ua: WinSock.struct_in_addr; BEGIN <* ASSERT ent.h_length <= BYTESIZE(Address) *> ua := LOOPHOLE(ent.h_addr_list, UNTRACED REF UNTRACED REF WinSock.struct_in_addr)^^; RETURN LOOPHOLE(ua.s_addr, Address); END GetAddress; PROCEDUREGetHostAddr (): Address = VAR hname: ARRAY [0..255] OF CHAR; BEGIN LOCK mu DO IF WinSock.gethostname(ADR(hname[0]), BYTESIZE(hname)) # 0 THEN IPError.Die(); END; RETURN GetAddress(WinSock.gethostbyname(ADR(hname[0]))); END; END GetHostAddr; PROCEDUREInterpretError () RAISES {Error} = VAR err := WinSock.WSAGetLastError(); BEGIN CASE err OF | WinSock.TRY_AGAIN, WinSock.NO_RECOVERY, WinSock.NO_ADDRESS => IPError.Raise(LookupFailure); ELSE END; END InterpretError; CONST WinSockVersion = 16_0101; (* App version 1.1 *) PROCEDUREInit () = VAR data: WinSock.WSAData; BEGIN IF WinSock.WSAStartup(WinSockVersion, ADR(data)) # 0 THEN IPError.Die(); END; Process.RegisterExitor(Exitor); END Init; PROCEDUREExitor () = BEGIN EVAL WinSock.WSACleanup(); END Exitor; BEGIN Init(); END IP.