]> git.mdlowis.com Git - proto/aos.git/commitdiff
implemented bin/listen and libnet
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 10 Dec 2020 03:12:10 +0000 (22:12 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 10 Dec 2020 03:12:10 +0000 (22:12 -0500)
bin/listen.c
build.c
inc/dial.h [deleted file]
inc/liba.h
inc/libnet.h [new file with mode: 0644]
lib/a/argv0.c
lib/net/netaccept.c [new file with mode: 0644]
lib/net/netannounce.c [new file with mode: 0644]
lib/net/netlisten.c [new file with mode: 0644]
lib/net/netresolve.c [new file with mode: 0644]
lib/net/netsocket.c [new file with mode: 0644]

index cbfdb1c54dad327ce77458d25d3268bcbaddbe3c..28781f68c08ab0783f9a4e00dd9dd6334998625f 100644 (file)
@@ -1,6 +1,49 @@
+#include <liba.h>
+#include <libnet.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+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 75fa30a9feab5cafd8b4fee03d52591c56653ea3..014f49112aeceb0f4a5b57eb22dca7ff8e2272e6 100644 (file)
--- 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 (file)
index e69de29..0000000
index 8229f0127d542e3e0a072e3f5d6c6ec211dcb888..dcc8583e33b2c75d4bd89840c293ddf399a28ec2 100644 (file)
@@ -1,3 +1,5 @@
+#include <stdio.h>
+
 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 (file)
index 0000000..d3e75a8
--- /dev/null
@@ -0,0 +1,17 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+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);
index 442159cd32665daf0a511ce5ba74c48d74993df6..62a3c3539e10d7912d82f0ef6fcd11732ac6650b 100644 (file)
@@ -1,4 +1,4 @@
 #include <stdc.h>
 #include <liba.h>
 
-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 (file)
index 0000000..cc18f58
--- /dev/null
@@ -0,0 +1,8 @@
+#include <libnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+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 (file)
index 0000000..a266378
--- /dev/null
@@ -0,0 +1,38 @@
+#include <liba.h>
+#include <libnet.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+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 (file)
index 0000000..e1e13fd
--- /dev/null
@@ -0,0 +1,9 @@
+#include <libnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+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 (file)
index 0000000..86611eb
--- /dev/null
@@ -0,0 +1,20 @@
+#include <liba.h>
+#include <impl/dial.h>
+
+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 (file)
index 0000000..2999646
--- /dev/null
@@ -0,0 +1,57 @@
+#include <liba.h>
+#include <libnet.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+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;
+}