+#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
+}
void (*build)(struct Target*);
} Target;
-int MaxJobs = 4;
+int MaxJobs = 1;
char* CCCMD[] = {
"cc",
};
char* LIBS[] = {
+ "-la",
+ "-lnet",
"-lX11",
"-lfontconfig",
NULL
{
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));
}
{
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));
}
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));
}
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 */
+#include <stdio.h>
+
void fatal(const char* fmt, ...);
void warn(const char* fmt, ...);
void esignal(int sig, void (*func)(int));
--- /dev/null
+#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);
#include <stdc.h>
#include <liba.h>
-char* ARGV0;
\ No newline at end of file
+char* ARGV0 = 0;
\ No newline at end of file
--- /dev/null
+#include <libnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int netaccept(int fd)
+{
+ return accept(fd, 0, 0);
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#include <libnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int netlisten(int fd, int backlog)
+{
+ return listen(fd, backlog);
+}
+
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}