diff options
Diffstat (limited to 'daemon.c')
| -rw-r--r-- | daemon.c | 91 |
1 files changed, 81 insertions, 10 deletions
@@ -3,44 +3,109 @@ #include <signal.h> #include <unistd.h> #include <stdio.h> +#include <time.h> #include <err.h> #include "tunnel.h" #include "macro.h" +#include "utils.h" -static void sighandler(int signo __unused) +static time_t since; + +static void tunnel_daemon_atexit(void) { unlink(TUNNEL_SOCK_PATH); +} + +static void sighandler(int signo __unused) +{ exit(EXIT_FAILURE); } +static char **parse_args(char *buf, int len) +{ + char **args = NULL; + + while (len) { + addv(&args, buf); + + char *p = memchr(buf, '\0', len); + if (!p) + break; + + len -= p - buf + 1; + buf = p + 1; + } + + return args; +} + +static void echo(FILE *fp, char **args) +{ + for (int n = 0; args[n]; n++) + fprintf(fp, "%s%s", n ? " " : "", args[n]); +} + static void tunnel_daemon_loop(int sock) { - for (;;) { + bool alive = true; + + while (alive) { + char msg[1024]; + int len; + int fd = accept(sock, NULL, NULL); if (fd < 0) { warn("accept"); continue; } - FILE *fp = fdopen(fd, "w"); - if (fp) { - fprintf(fp, "hello from %d", getpid()); - fclose(fp); + len = read(fd, msg, sizeof(msg) - 1); + if (len < 0) { + warn("read"); + close(fd); + continue; + } + + if (! len) { + close(fd); + continue; + } + + msg[len] = '\0'; + + char **args = parse_args(msg, len); + + let (fp, fdopen(fd, "w"), fclose) { + char *cmd = *args; + + if (strequal(cmd, "echo")) + echo(fp, args + 1); + else if (strequal(cmd, "hello")) + fprintf(fp, "hello from %d", getpid()); + else if (strequal(cmd, "alive")) + fprintf(fp, "since %s", ctime(&since)); + else if (strequal(cmd, "stop")) { + fprintf(fp, "ok"); + alive = false; + } else + fprintf(fp, "what do you want?"); } + + free(args); } } -int tunnel_daemon(int sock) +bool tunnel_daemon(int sock) { switch (fork()) { case -1: warn("fork"); - return -1; + return false; case 0: break; default: - return 0; + return true; } if (setsid() < 0) @@ -68,7 +133,13 @@ int tunnel_daemon(int sock) close(fd); #endif + time(&since); + + atexit(tunnel_daemon_atexit); + tunnel_daemon_loop(sock); - return 0; + exit(EXIT_SUCCESS); + + return true; } |
