package hello
import "core:fmt"
import "core:strings"
import "core:c"
import "../../bsd"
port :: #config(port, 4000)
main :: proc() {
hints: bsd.addrinfo
servinfo: ^bsd.addrinfo
their_addr: bsd.sockaddr_storage
server, client: bsd.Socket
err: bsd.error
hints.family = bsd.AF_UNSPEC
hints.socktype = bsd.SOCK_STREAM
hints.flags = bsd.AF_PASSIVE
portstr := strings.unsafe_string_to_cstring(fmt.tprintf("%d\x00", port))
if err = bsd.errno(bsd.getaddrinfo(nil, portstr, &hints, &servinfo)); err != 0 {
fmt.eprintf("getaddrinfo error: %d\n", err)
return
}
p := servinfo
for ; p != nil; p = p.next {
if server, err = bsd.errno(bsd.socket(bsd.Family(p.family), p.socktype, p.protocol));
err != 0 {
fmt.eprintf("socket error: %d\n", err)
continue
}
yes: c.int = 1
if err = bsd.errno(
bsd.setsockopt(server, bsd.SOL_SOCKET, bsd.SO_REUSEADDR, &yes, size_of(c.int)),
); err != 0 {
fmt.eprintf("setsockopt error: %d\n", err)
bsd.freeaddrinfo(servinfo)
return
}
if err = bsd.errno(bsd.bind(server, p.addr, p.addrlen)); err != 0 {
_ = bsd.close(server)
fmt.eprintf("server error: %d\n", err)
continue
}
break
}
bsd.freeaddrinfo(servinfo)
if p == nil {
fmt.eprintln("server: failed to bind")
return
}
if err = bsd.errno(bsd.listen(server, 4)); err != 0 {
fmt.printf("listen error: %d\n", err)
return
}
fmt.println("listening on port", port)
// main accept() loop
sin_size := c.uint(size_of(type_of(their_addr)))
whobuf: [40]u8
for {
if client, err = bsd.errno(
bsd.accept(server, transmute(^bsd.sockaddr)&their_addr, &sin_size),
); err != 0 {
fmt.eprintf("accept error: %d\n", err)
continue
}
who: cstring
if who, err = bsd.errno(
bsd.inet_ntop(
(transmute(^bsd.sockaddr)&their_addr).family,
bsd.get_in_addr(transmute(^bsd.sockaddr)&their_addr),
&whobuf[0],
len(whobuf),
),
); err != 0 {
fmt.eprintf("inet_ntop error: %d\n", err)
who = "(unknown)"
}
fmt.println("got connection from", who)
sent: uint
msg :: "Hello, world!\n"
if sent, err = bsd.errno(bsd.send(client, raw_data(string(msg)), len(msg), 0)); err != 0 {
fmt.eprintf("send error: %d\n", err)
}
_ = bsd.close(client)
fmt.printf("sent %d bytes\n", sent)
}
}