143 lines
4.1 KiB
Text
143 lines
4.1 KiB
Text
without js
|
|
include builtins\cffi.e
|
|
|
|
constant AF_UNSPEC = 0,
|
|
-- AF_INET = 2,
|
|
-- AF_INET6 = 23,
|
|
-- SOCK_STREAM = 1,
|
|
SOCK_DGRAM = 2,
|
|
-- IPPROTO_TCP = 6,
|
|
NI_MAXHOST = 1025,
|
|
NI_NUMERICHOST = iff(platform()=LINUX?1:2)
|
|
|
|
constant tWAD = """
|
|
typedef struct WSAData {
|
|
WORD wVersion;
|
|
WORD wHighVersion;
|
|
char szDescription[257];
|
|
char szSystemStatus[129];
|
|
unsigned short iMaxSockets;
|
|
unsigned short iMaxUdpDg;
|
|
char *lpVendorInfo;
|
|
} WSADATA, *LPWSADATA;
|
|
""",
|
|
tWAS = """
|
|
int WSAStartup(
|
|
_In_ WORD wVersionRequested,
|
|
_Out_ LPWSADATA lpWSAData
|
|
);
|
|
""",
|
|
tWAC = """
|
|
int WSACleanup(void);
|
|
""",
|
|
tAI_W="""
|
|
typedef struct addrinfo {
|
|
int ai_flags;
|
|
int ai_family;
|
|
int ai_socktype;
|
|
int ai_protocol;
|
|
size_t ai_addrlen;
|
|
char *ai_canonname;
|
|
struct sockaddr *ai_addr;
|
|
struct addrinfo *ai_next;
|
|
} ADDRINFOA, *PADDRINFOA;
|
|
""",
|
|
tAI_L="""
|
|
typedef struct addrinfo {
|
|
int ai_flags;
|
|
int ai_family;
|
|
int ai_socktype;
|
|
int ai_protocol;
|
|
int ai_addrlen;
|
|
struct sockaddr *ai_addr;
|
|
char *ai_canonname;
|
|
struct addrinfo *ai_next;
|
|
};
|
|
""",
|
|
tGAI = """
|
|
int getaddrinfo(
|
|
_In_opt_ PCSTR pNodeName,
|
|
_In_opt_ PCSTR pServiceName,
|
|
_In_opt_ const ADDRINFOA *pHints,
|
|
_Out_ PADDRINFOA *ppResult
|
|
);
|
|
""",
|
|
--int getaddrinfo(const char *node, const char *service,
|
|
-- const struct addrinfo *hints,
|
|
-- struct addrinfo **res);
|
|
tGNI = """
|
|
int getnameinfo(
|
|
_In_ sockaddr *sa,
|
|
_In_ int salen,
|
|
_Out_ char *host,
|
|
_In_ DWORD hostlen,
|
|
_Out_ char *serv,
|
|
_In_ DWORD servlen,
|
|
_In_ int flags
|
|
);
|
|
""",
|
|
--int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
|
|
-- char *host, socklen_t hostlen,
|
|
-- char *serv, socklen_t servlen, int flags);
|
|
tFAI = """
|
|
void freeaddrinfo(
|
|
_In_ struct addrinfo *ai
|
|
);
|
|
"""
|
|
--void freeaddrinfo(struct addrinfo *res);
|
|
|
|
integer xgetaddrinfo = NULL, xgetnameinfo, xfreeaddrinfo, idAI,
|
|
xwsastartup, xwsacleanup, error
|
|
|
|
function get_name_info(string fqdn)
|
|
if xgetaddrinfo=NULL then
|
|
atom lib
|
|
if platform()=WINDOWS then
|
|
integer idWAD = define_struct(tWAD)
|
|
atom pWAD = allocate_struct(idWAD,cleanup:=true)
|
|
lib = open_dll("Ws2_32.dll")
|
|
xwsastartup = define_cffi_func(lib,tWAS)
|
|
xwsacleanup = define_cffi_func(lib,tWAC)
|
|
error = c_func(xwsastartup,{#00020002,pWAD})
|
|
if error then ?9/0 end if
|
|
idAI = define_struct(tAI_W)
|
|
elsif platform()=LINUX then
|
|
lib = open_dll("libc.so.6")
|
|
idAI = define_struct(tAI_L)
|
|
end if
|
|
xgetaddrinfo = define_cffi_func(lib,tGAI)
|
|
xgetnameinfo = define_cffi_func(lib,tGNI)
|
|
xfreeaddrinfo = define_cffi_proc(lib,tFAI)
|
|
end if
|
|
atom hints = allocate_struct(idAI,cleanup:=true),
|
|
res = allocate(machine_word(),cleanup:=true),
|
|
host = allocate(NI_MAXHOST,cleanup:=true)
|
|
set_struct_field(idAI,hints,"ai_family",AF_UNSPEC)
|
|
-- set_struct_field(idAI,hints,"ai_socktype",SOCK_STREAM)
|
|
set_struct_field(idAI,hints,"ai_socktype",SOCK_DGRAM)
|
|
error = c_func(xgetaddrinfo,{fqdn,NULL,hints,res})
|
|
if error then ?9/0 end if
|
|
res = peekNS(res,machine_word(),false)
|
|
atom ptr = res
|
|
sequence results = {}
|
|
while ptr!=NULL do
|
|
atom addr = get_struct_field(idAI,ptr,"ai_addr")
|
|
integer len = get_struct_field(idAI,ptr,"ai_addrlen")
|
|
error = c_func(xgetnameinfo,{addr, len, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST})
|
|
if error then ?9/0 end if
|
|
results = append(results,peek_string(host))
|
|
ptr = get_struct_field(idAI,ptr,"ai_next")
|
|
end while
|
|
c_proc(xfreeaddrinfo,{res})
|
|
return results
|
|
end function
|
|
|
|
procedure WSACleanup()
|
|
if platform()=WINDOWS then
|
|
error = c_func(xwsacleanup,{})
|
|
if error then crash("WSACleanup failed: %d\n",{error}) end if
|
|
end if
|
|
end procedure
|
|
|
|
?get_name_info("www.kame.net")
|
|
WSACleanup()
|