From b43543e7db1bd39fd61964a3d9388f9ec8c3252c Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 9 Dec 2020 22:12:10 -0500 Subject: [PATCH] implemented bin/listen and libnet --- bin/listen.c | 49 ++++++++++++++++++++++++++++++++++--- build.c | 11 +++++++-- inc/dial.h | 0 inc/liba.h | 2 ++ inc/libnet.h | 17 +++++++++++++ lib/a/argv0.c | 2 +- lib/net/netaccept.c | 8 ++++++ lib/net/netannounce.c | 38 +++++++++++++++++++++++++++++ lib/net/netlisten.c | 9 +++++++ lib/net/netresolve.c | 20 +++++++++++++++ lib/net/netsocket.c | 57 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 207 insertions(+), 6 deletions(-) delete mode 100644 inc/dial.h create mode 100644 inc/libnet.h create mode 100644 lib/net/netaccept.c create mode 100644 lib/net/netannounce.c create mode 100644 lib/net/netlisten.c create mode 100644 lib/net/netresolve.c create mode 100644 lib/net/netsocket.c diff --git a/bin/listen.c b/bin/listen.c index cbfdb1c..28781f6 100644 --- a/bin/listen.c +++ b/bin/listen.c @@ -1,6 +1,49 @@ +#include +#include +#include +#include + +void serve(int cfd, char** argv) +{ + switch (fork()) + { + case -1: + perror("fork"); + break; + case 0: + dup2(cfd, 0); dup2(cfd, 1); dup2(cfd, 2); + exit(execvp(argv[0], argv)); + break; + default: + break; + } + close(cfd); +} + int main(int argc, char** argv) { - (void)argc; - (void)argv; + if (argc < 3) + { + fprintf(stderr, "usage: listen DIALSTR CMD [ARG...]\n"); + return 1; + } + + int sfd = netannounce(argv[1]); + if (sfd < 0) + { + fatal("netanounce():"); + } + + while (!netlisten(sfd, 5)) + { + int cfd; + if ((cfd = netaccept(sfd)) >= 0) + { + serve(cfd, argv+2); + } + while (waitpid(-1, 0, WNOHANG) > 0); + } + perror("listen"); + return 0; -} \ No newline at end of file +} diff --git a/build.c b/build.c index 75fa30a..014f491 100644 --- a/build.c +++ b/build.c @@ -16,7 +16,7 @@ typedef struct Target { void (*build)(struct Target*); } Target; -int MaxJobs = 4; +int MaxJobs = 1; char* CCCMD[] = { "cc", @@ -47,6 +47,8 @@ char* LDCMD[] = { }; char* LIBS[] = { + "-la", + "-lnet", "-lX11", "-lfontconfig", NULL @@ -214,6 +216,7 @@ void object(Target* tgt) { printf("Object %s\n", tgt->outputs[0]); char** cmd = make_cmd((char**[]){ CCCMD, tgt->outputs, tgt->inputs, NULL }); + print_cmd(cmd); make_dirs(tgt->outputs); exit(execvp(cmd[0], cmd)); } @@ -222,6 +225,7 @@ void library(Target* tgt) { printf("Library %s\n", tgt->outputs[0]); char** cmd = make_cmd((char**[]){ ARCMD, tgt->outputs, tgt->inputs, NULL }); + print_cmd(cmd); exit(execvp(cmd[0], cmd)); } @@ -230,6 +234,7 @@ void binary(Target* tgt) printf("Binary %s\n", tgt->outputs[0]); char** cmd = make_cmd((char**[]){ LDCMD, tgt->outputs, tgt->inputs, LIBS, NULL }); + print_cmd(cmd); exit(execvp(cmd[0], cmd)); } @@ -368,7 +373,9 @@ int main(int argc, char** argv) char** sbins = dir_entries("bin", F_FILES); for (; *sbins; sbins++) { - add_bin(*sbins, (char*[]){ *sbins, NULL }); + char** srcs = calloc(2, sizeof(char*)); + srcs[0] = add_src(*sbins); + add_bin(*sbins, srcs); } /* create output directories */ diff --git a/inc/dial.h b/inc/dial.h deleted file mode 100644 index e69de29..0000000 diff --git a/inc/liba.h b/inc/liba.h index 8229f01..dcc8583 100644 --- a/inc/liba.h +++ b/inc/liba.h @@ -1,3 +1,5 @@ +#include + void fatal(const char* fmt, ...); void warn(const char* fmt, ...); void esignal(int sig, void (*func)(int)); diff --git a/inc/libnet.h b/inc/libnet.h new file mode 100644 index 0000000..d3e75a8 --- /dev/null +++ b/inc/libnet.h @@ -0,0 +1,17 @@ +#include +#include +#include + +struct socket_t { + int fd; + union { + struct sockaddr_in in; + struct sockaddr_un un; + } addr; +}; + +int netsocket(char* dialstr, struct socket_t* sock); +struct in_addr netresolve(char *hostname); +int netannounce(char* dialstr); +int netlisten(int fd, int backlog); +int netaccept(int fd); diff --git a/lib/a/argv0.c b/lib/a/argv0.c index 442159c..62a3c35 100644 --- a/lib/a/argv0.c +++ b/lib/a/argv0.c @@ -1,4 +1,4 @@ #include #include -char* ARGV0; \ No newline at end of file +char* ARGV0 = 0; \ No newline at end of file diff --git a/lib/net/netaccept.c b/lib/net/netaccept.c new file mode 100644 index 0000000..cc18f58 --- /dev/null +++ b/lib/net/netaccept.c @@ -0,0 +1,8 @@ +#include +#include +#include + +int netaccept(int fd) +{ + return accept(fd, 0, 0); +} diff --git a/lib/net/netannounce.c b/lib/net/netannounce.c new file mode 100644 index 0000000..a266378 --- /dev/null +++ b/lib/net/netannounce.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include + +int netannounce(char* dialstr) +{ + struct socket_t sock = { .fd = -1 }; + if (netsocket(dialstr, &sock)) + { + int rv = -1; + switch (sock.addr.in.sin_family) + { + case AF_INET: + rv = bind(sock.fd, (struct sockaddr*)&sock.addr.in, sizeof(sock.addr.in)); + break; + + case AF_UNIX: + if ((rv = bind(sock.fd, (struct sockaddr*)&sock.addr.un, sizeof(sock.addr.un))) < 0) + { + if (connect(sock.fd, (struct sockaddr*)&sock.addr.un, sizeof(sock.addr.un)) < 0) + { + unlink(sock.addr.un.sun_path); + rv = bind(sock.fd, (struct sockaddr*)&sock.addr.un, sizeof(sock.addr.un)); + } + } + break; + } + if (rv < 0) + { + close(sock.fd); + sock.fd = -1; + } + } + return sock.fd; +} diff --git a/lib/net/netlisten.c b/lib/net/netlisten.c new file mode 100644 index 0000000..e1e13fd --- /dev/null +++ b/lib/net/netlisten.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int netlisten(int fd, int backlog) +{ + return listen(fd, backlog); +} + diff --git a/lib/net/netresolve.c b/lib/net/netresolve.c new file mode 100644 index 0000000..86611eb --- /dev/null +++ b/lib/net/netresolve.c @@ -0,0 +1,20 @@ +#include +#include + +struct in_addr netresolve(char *hostname) +{ + struct in_addr addr = {0}; + struct addrinfo *servinfo, hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM + }; + if (getaddrinfo(hostname , NULL , &hints , &servinfo) == 0) + { + for (struct addrinfo* p = servinfo; p != NULL; p = p->ai_next) + { + addr = ((struct sockaddr_in *)p->ai_addr)->sin_addr; + } + freeaddrinfo(servinfo); + } + return addr; +} diff --git a/lib/net/netsocket.c b/lib/net/netsocket.c new file mode 100644 index 0000000..2999646 --- /dev/null +++ b/lib/net/netsocket.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include + +typedef struct { + char* network; + char* address; + char* service; +} conn_t; + +int netsocket(char* dialstr, struct socket_t* sock) +{ + size_t i; + /* make a local copy of dial string */ + char dstr[8192]; + for (i = 0; i < sizeof(dstr)-1 && dialstr[i]; i++) + { + dstr[i] = dialstr[i]; + } + dstr[i] = '\0'; + + /* parse the dial string */ + conn_t conn; + conn.network = strtok(dstr, ":"); if (!conn.network) conn.network = ""; + conn.address = strtok(NULL, ":"); if (!conn.address) conn.address = ""; + conn.service = strtok(NULL, ":"); if (!conn.service) conn.service = ""; + + /* try and make the connection with the appropriate handler */ + memset(&sock->addr, 0, sizeof(sock->addr)); + if (!strcmp("tcp", conn.network)) + { + sock->addr.in.sin_family = AF_INET; + sock->addr.in.sin_port = htons(strtol(conn.service, NULL, 0)); + sock->addr.in.sin_addr = netresolve(conn.address); + sock->fd = socket(AF_INET, SOCK_STREAM, 0); + } + else if (!strcmp("udp", conn.network)) + { + sock->addr.in.sin_family = AF_INET; + sock->addr.in.sin_port = htons(strtol(conn.service, NULL, 0)); + sock->addr.in.sin_addr = netresolve(conn.address); + sock->fd = socket(AF_INET, SOCK_DGRAM, 0); + } + else if (!strcmp("unix", conn.network)) + { + sock->addr.un.sun_family = AF_UNIX; + sock->fd = socket(AF_UNIX, SOCK_STREAM, 0); + strncpy(sock->addr.un.sun_path, conn.address, sizeof(sock->addr.un.sun_path)-1); + } + else + { + errno = EINVAL, sock->fd = -1; + } + return sock->fd; +} -- 2.52.0