From e0dab12078fa6dc9903c8a73616a84347a6b93b2 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Fri, 14 Aug 2020 15:56:10 -0400 Subject: Implement spawntab parsing --- daemon.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- daemon.h | 51 ++++++++++++++++++++++++++++++++++++++++---- service.c | 55 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 168 insertions(+), 11 deletions(-) diff --git a/daemon.c b/daemon.c index 7030978..6cbf8eb 100644 --- a/daemon.c +++ b/daemon.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,72 @@ #define ETCDIR "/usr/local/etc" #endif +#define WS " \t" + +int restartInterval = 1000; +struct Set256 stopExits; + +static void configerr(bool exit, const char *format, ...) { + va_list ap; + va_start(ap, format); + if (exit) { + verrx(EX_DATAERR, format, ap); + } else { + vsyslog(LOG_ERR, format, ap); + } + va_end(ap); +} + +static void parseConfig(bool exit, const char *path) { + size_t cap = 0; + char *buf = NULL; + + FILE *file = fopen(path, "r"); + if (!file) { + configerr(exit, "%s: %s", path, strerror(errno)); + goto err; + } + + prependClear(); + + int line = 1; + for (ssize_t len; 0 <= (len = getline(&buf, &cap, file)); ++line) { + if (buf[len - 1] == '\n') buf[len - 1] = '\0'; + + char *ptr = &buf[strspn(buf, WS)]; + if (!ptr[0] || ptr[0] == '#') { + continue; + } else if (ptr[0] == '%') { + int error = prependAdd(&ptr[1]); + if (error) { + configerr( + exit, "cannot add prepend command: %s", strerror(errno) + ); + goto err; + } + } else { + char *name = strsep(&ptr, WS); + if (!ptr) { + configerr( + exit, "%s:%d: no command line for service %s", + path, line, name + ); + goto err; + } + int error = serviceAdd(name, ptr); + if (error) { + configerr(exit, "cannot add service: %s", strerror(errno)); + goto err; + } + } + } + if (ferror(file)) configerr(exit, "%s: %s", path, strerror(errno)); + +err: + free(buf); + fclose(file); +} + static void parseExits(char *list) { setClear(&stopExits); while (*list) { @@ -52,6 +119,8 @@ static void parseExits(char *list) { } int main(int argc, char *argv[]) { + setprogname(argv[0]); + bool daemonize = true; setAdd(&stopExits, 127); setAdd(&stopExits, EX_USAGE); @@ -83,7 +152,7 @@ int main(int argc, char *argv[]) { } } - // TODO: Read config file. + parseConfig(true, configPath); int error = access(serviceDir, X_OK); if (error) err(EX_NOINPUT, "%s", serviceDir); @@ -116,7 +185,7 @@ int main(int argc, char *argv[]) { int fifo = open(fifoPath, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (fifo < 0) err(EX_CANTCREAT, "%s", fifoPath); - openlog("spawnd", LOG_NDELAY | LOG_PID | LOG_PERROR, LOG_DAEMON); + openlog(getprogname(), LOG_NDELAY | LOG_PID | LOG_PERROR, LOG_DAEMON); if (daemonize) { error = daemon(0, 0); diff --git a/daemon.h b/daemon.h index 3a141ba..d7efb28 100644 --- a/daemon.h +++ b/daemon.h @@ -17,9 +17,56 @@ #include #include #include +#include +#include typedef unsigned char byte; +extern struct Prepend { + size_t cap, len; + char **commands; +} prepend; + +static inline void prependClear(void) { + for (size_t i = 0; i < prepend.len; ++i) { + free(prepend.commands[i]); + } + prepend.len = 0; +} +static inline int prependAdd(const char *command) { + if (prepend.len == prepend.cap) { + size_t cap = (prepend.cap ? prepend.cap * 2 : 8); + void *ptr = realloc(prepend.commands, sizeof(*prepend.commands) * cap); + if (!ptr) return -1; + prepend.cap = cap; + prepend.commands = ptr; + } + prepend.commands[prepend.len] = strdup(command); + if (!prepend.commands[prepend.len]) return -1; + prepend.len++; + return 0; +} + +extern const char *serviceDir; +extern struct passwd *serviceUser; +extern struct group *serviceGroup; + +struct Service { + char *name; + char *command; + // TODO: And many other things... +}; + +extern struct Services { + size_t cap, len; + struct Service *ptr; +} services; + +int serviceAdd(const char *name, const char *command); + +extern char configError[]; +int configParse(const char *path); + struct Set256 { uint32_t bits[8]; }; @@ -35,7 +82,3 @@ static inline uint32_t setTest(const struct Set256 *set, byte x) { extern int restartInterval; extern struct Set256 stopExits; - -extern const char *serviceDir; -extern struct passwd *serviceUser; -extern struct group *serviceGroup; diff --git a/service.c b/service.c index a81a588..b6e6ce1 100644 --- a/service.c +++ b/service.c @@ -14,18 +14,63 @@ * along with this program. If not, see . */ -#include #include #include #include #include -#include +#include #include "daemon.h" -struct Set256 stopExits; -int restartInterval = 1000; - const char *serviceDir = "/"; struct passwd *serviceUser; struct group *serviceGroup; + +struct Prepend prepend; +struct Services services; + +static void serviceFree(struct Service *service) { + free(service->name); + free(service->command); +} + +int serviceAdd(const char *name, const char *command) { + struct Service *service = NULL; + for (size_t i = 0; i < services.len; ++i) { + if (!strcmp(services.ptr[i].name, name)) { + service = &services.ptr[i]; + break; + } + } + + if (service) { + char *dup = strdup(command); + if (!dup) return -1; + free(service->command); + service->command = dup; + return 0; + } + + if (services.len == services.cap) { + size_t cap = (services.cap ? services.cap * 2 : 8); + void *ptr = realloc(services.ptr, sizeof(*services.ptr) * cap); + if (!ptr) return -1; + services.cap = cap; + services.ptr = ptr; + } + service = &services.ptr[services.len]; + memset(service, 0, sizeof(*service)); + + service->name = strdup(name); + if (!service->name) goto err; + + service->command = strdup(command); + if (!service->command) goto err; + + services.len++; + return 0; + +err: + serviceFree(service); + return -1; +} -- cgit 1.4.1 14c7553&follow=1'>Match \ before newline in string as EscapeJune McEnroe 2021-01-13Remove -t flag from ctags commandsJune McEnroe It's the default/only there for compatibility on the implementations I use. 2021-01-13Match strftime format specifiersJune McEnroe 2021-01-13Switch git.causal.agency to hilex and htagmlJune McEnroe Still missing a shell lexer in hilex, but well... it's shell. 2021-01-13Try to return make substitutions as single tokensJune McEnroe 2021-01-13Shorten hilex class namesJune McEnroe 2021-01-13Move text "lexer" to hilex.cJune McEnroe 2021-01-13Try to return strings as single tokensJune McEnroe 2021-01-13Match [] as Operator in C lexerJune McEnroe 2021-01-13Fix C lexer to require a digit in a float literalJune McEnroe Otherwise ".l" is matched as Number. 2021-01-13Support long double in c.shJune McEnroe 2021-01-13Update Terminal.app coloursJune McEnroe God what is this garbage I only changed one colour. 2021-01-13Increase dark white brightness slightlyJune McEnroe 2021-01-13Add hilex example to htagml manualJune McEnroe 2021-01-12Style causal.agency like bin HTMLJune McEnroe 2021-01-12Avoid matching tag text inside HTML elementsJune McEnroe 2021-01-12Use hilex for up -hJune McEnroe 2021-01-12Use hilex for bin HTMLJune McEnroe 2021-01-12Don't output a pre in hilex by defaultJune McEnroe 2021-01-12Move hilex out of hilex directoryJune McEnroe 2021-01-12Consolidate hilex formatters into hilex.cJune McEnroe 2021-01-12Remove hacky tagging from hilexJune McEnroe God that makes the lexers so much simpler. 2021-01-12Add htagml -iJune McEnroe 2021-01-12Render tag index in HTMLJune McEnroe 2021-01-12Add htagml -xJune McEnroe 2021-01-12Prevent matching the same tag twiceJune McEnroe 2021-01-12Process htagml file line by lineJune McEnroe This simplifies some things, adds support for line number tag definitions, and should enable combining htagml with other preprocessors in the future. 2021-01-12Split fields by tab onlyJune McEnroe Also don't fail hard on non-forward-search definitions. 2021-01-12List both Makefile and html.sh under README.7June McEnroe 2021-01-12Add htagml exampleJune McEnroe 2021-01-12Use mandoc and htagml for bin htmlJune McEnroe 2021-01-12Add htagmlJune McEnroe 2021-01-12Replace causal.agency with a simple mdoc pageJune McEnroe 2021-01-11Publish "Using vi"June McEnroe 2021-01-11Enable diff.colorMovedJune McEnroe 2021-01-10Set less search case-insensitiveJune McEnroe 2021-01-10Set EXINITJune McEnroe neovim is laggy as hell in my OpenBSD VM, so I switched to vi so I could type without getting frustrated. 2021-01-09Add c -t flag to print expression typeJune McEnroe Also add missing float case. 2021-01-05Update taglineJune McEnroe