staload "libc/SATS/stdio.sats"
staload "libc/SATS/time.sats"
staload "libc/sys/SATS/socket.sats"
staload "libc/netinet/SATS/in.sats"
staload "libc/arpa/SATS/inet.sats"
#define LISTENQ 1
#define TIME_SERVER_PORT 13000
extern fun show_client (cliaddr: &sockaddr_in_struct_t): void
= "show_client"
implement main (argc, argv) = let
val [fd_s:int] (pf_sock_s | fd_s) =
socket_family_type_exn (AF_INET, SOCK_STREAM)
var servaddr: sockaddr_in_struct_t val nport = (if argc > 1 then int_of argv.[1] else TIME_SERVER_PORT): int
val servport = in_port_nbo_of_int (nport)
val in4addr_any = in_addr_nbo_of_hbo (INADDR_ANY)
val () = sockaddr_ipv4_init (servaddr, AF_INET, in4addr_any, servport)
val () = bind_ipv4_exn (pf_sock_s | fd_s, servaddr)
val () = listen_exn (pf_sock_s | fd_s, LISTENQ)
val () = loop (pf_sock_s | fd_s) where {
fun loop (pf_sock_s: !socket_v (fd_s, listen) | fd_s: int fd_s): void = let
var addrlen: socklen_t var cliaddr: sockaddr_in_struct_t val (pf_sock_c | fd_c) = accept_ipv4_exn (pf_sock_s | fd_s, cliaddr, addrlen)
val () = show_client (cliaddr)
var ntick = time_get ()
val time_str = ctime ntick val time_str = string1_of_string (time_str)
val time_str_len = string1_length (time_str)
val _ = socket_write_substring_exn (pf_sock_c | fd_c, time_str, 0, time_str_len)
val () = socket_close_exn (pf_sock_c | fd_c)
in
loop (pf_sock_s | fd_s)
end } val () = socket_close_exn (pf_sock_s | fd_s)
in
end
%{$
ats_void_type
show_client (ats_ptr_type cliaddr0) {
struct sockaddr_in *cliaddr = cliaddr0 ;
char *str = inet_ntoa (cliaddr->sin_addr) ;
int port = ntohs (cliaddr->sin_port) ;
printf ("connection from %s at port %d\n", str, port) ;
return ;
} // end of [show_client]
%}