rats

RAdix iniT Suite
git clone https://git.daat.foo/repos/rats.git
Log | Files | Refs | README | LICENSE

commit d0f26ec93b305edd594fee40e43ccb23b7f8d406
parent a3e8dd750e830d79b09f52874c47c4a9f93cdf6a
Author: cowmonk <cowmonk@based.pt>
Date:   Tue,  6 Oct 2026 12:30:13 -0700

added conditional _POSIX_C_SOURCE definition and changed handling of services

Specifically, `request()` handles one command and one socket connection.
`main()` now sends a separate request for each given service name (e.g.
`svc -s foo bar` queries both services instead of looking for one
service named `foo bar`).

Diffstat:
Msvc.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/svc.c b/svc.c @@ -1,10 +1,15 @@ /* svc: control client for ssv */ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif + #include "arg.h" #include "util.h" #include <sys/socket.h> #include <sys/un.h> +#include <errno.h> #include <stdio.h> #include <string.h> #include <unistd.h> @@ -19,16 +24,59 @@ usage(void) eprintf("usage: %s [-udrkts] [-a] [service...]\n", argv0); } -int -main(int argc, char *argv[]) +static int +request(int action, const char *name) { - int sock, aflag, action, i, n; + int sock, len; struct sockaddr_un addr; - char buf[4096], resp[4096]; - size_t off; + char buf[4096], resp[4096], prefix[5]; + ssize_t n; + size_t have = 0, chunk; + + if (strchr(name, '\n') || strchr(name, '\r')) + eprintf("invalid service name\n"); + len = snprintf(buf, sizeof(buf), "%c %s\n", action, name); + if (len < 0 || (size_t)len >= sizeof(buf)) + eprintf("command too long\n"); + + /* connect to ssv control socket */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + eprintf("socket:"); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (strlcpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + eprintf("socket path too long: %s\n", SOCK_PATH); + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + eprintf("connect %s:", SOCK_PATH); - aflag = 0; - action = 0; + /* send command, print response */ + if (writeall(sock, buf, len) != len) + eprintf("write socket:"); + if (shutdown(sock, SHUT_WR) < 0) + eprintf("shutdown socket:"); + for (;;) { + n = read(sock, resp, sizeof(resp)); + if (n < 0 && errno == EINTR) + continue; + if (n < 0) + eprintf("read socket:"); + if (n == 0) + break; + chunk = MIN((size_t)n, sizeof(prefix) - have); + memcpy(prefix + have, resp, chunk); + have += chunk; + if (writeall(STDOUT_FILENO, resp, n) != n) + eprintf("write stdout:"); + } + close(sock); + return have == sizeof(prefix) && memcmp(prefix, "ERR: ", sizeof(prefix)) == 0; +} + +int +main(int argc, char *argv[]) +{ + int aflag = 0, action = 0, ret = 0, i; ARGBEGIN { case 'u': action = 'u'; break; @@ -41,42 +89,18 @@ main(int argc, char *argv[]) default: usage(); } ARGEND - if (!action) + if (!action || (action != 's' && !aflag && argc == 0)) usage(); - if (action != 's' && !aflag && argc == 0) + if (aflag && (argc != 0 || (action != 'u' && action != 'd'))) usage(); - /* connect to ssv control socket */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - eprintf("socket:"); - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path)); - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) - eprintf("connect %s:", SOCK_PATH); - - /* build command line */ - if (action == 's' && argc == 0) { - strlcpy(buf, "s\n", sizeof(buf)); - } else if (aflag) { - snprintf(buf, sizeof(buf), "%c a\n", action); - } else { - off = snprintf(buf, sizeof(buf), "%c", action); + if (aflag || argc == 0) + ret = request(action, aflag ? "a" : ""); + else for (i = 0; i < argc; i++) - off += snprintf(buf + off, sizeof(buf) - off, - " %s", argv[i]); - off += snprintf(buf + off, sizeof(buf) - off, "\n"); - } - - /* send command, print response */ - writeall(sock, buf, strlen(buf)); - shutdown(sock, SHUT_WR); - while ((n = read(sock, resp, sizeof(resp))) > 0) - writeall(STDOUT_FILENO, resp, n); - close(sock); + ret |= request(action, argv[i]); if (fshut(stdout, "<stdout>")) return 2; - return 0; + return ret; }