diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/include-local/s6f.h | 19 | ||||
| -rw-r--r-- | src/libs6f/deps-exe/s6f | 1 | ||||
| -rw-r--r-- | src/libs6f/s6f_user_get_confdirs.c | 77 | ||||
| -rw-r--r-- | src/s6/process.c | 12 | ||||
| -rw-r--r-- | src/s6/process_kill.c | 4 | ||||
| -rw-r--r-- | src/s6/process_status.c | 4 | ||||
| -rw-r--r-- | src/s6/s6-internal.h | 22 | ||||
| -rw-r--r-- | src/s6/s6.c | 22 | ||||
| -rw-r--r-- | src/s6/service_start.c | 1 |
9 files changed, 138 insertions, 24 deletions
diff --git a/src/include-local/s6f.h b/src/include-local/s6f.h new file mode 100644 index 0000000..4879536 --- /dev/null +++ b/src/include-local/s6f.h @@ -0,0 +1,19 @@ +/* ISC license. */ + +#ifndef S6F_H +#define S6F_H + +#include <skalibs/stralloc.h> + +typedef struct s6f_confdirs_s s6f_confdirs, *s6f_confdirs_ref ; +struct s6f_confdirs_s +{ + char const *scan ; /* $XDG_RUNTIME_DIR/service */ + char const *live ; /* $XDG_RUNTIME_DIR/s6-rc */ + char const *repo ; /* $XDG_DATA_HOME/s6-frontend/repository */ + char const *boot ; /* $XDG_CONFIG_HOME/s6-rc */ +} ; + +extern void s6f_user_get_confdirs (s6f_confdirs *, stralloc *) ; + +#endif diff --git a/src/libs6f/deps-exe/s6f b/src/libs6f/deps-exe/s6f new file mode 100644 index 0000000..e77c0cc --- /dev/null +++ b/src/libs6f/deps-exe/s6f @@ -0,0 +1 @@ +s6f_user_get_confdirs.o diff --git a/src/libs6f/s6f_user_get_confdirs.c b/src/libs6f/s6f_user_get_confdirs.c new file mode 100644 index 0000000..57e6451 --- /dev/null +++ b/src/libs6f/s6f_user_get_confdirs.c @@ -0,0 +1,77 @@ +/* ISC license. */ + +#include <pwd.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> + +#include <skalibs/types.h> +#include <skalibs/strerr.h> +#include <skalibs/stralloc.h> + +#include "s6-internal.h" + +#define dienomem() strerr_diefu1sys(111, "allocate memory") + +void s6f_user_get_confdirs (s6f_confdirs *dirs, stralloc *storage) +{ + size_t scanpos, livepos, repopos, bootpos ; + size_t homelen = 0 ; + struct passwd *pw = 0 ; + char const *home = 0 ; + char const *datahome = getenv("XDG_DATA_HOME") ; + char const *confighome = getenv("XDG_DATA_HOME") ; + char const *runtime = getenv("XDG_RUNTIME_DIR") ; + if (!runtime) strerr_dienotset(100, "XDG_RUNTIME_DIR") ; + + if (!datahome || !confighome) + { + *home = getenv("HOME") ; + if (!home) + { + errno = 0 ; + pw = getpwuid(uid) ; + if (!pw) + { + char fmt[UID_FMT] ; + fmt[uid_fmt(fmt, uid)] = 0 ; + if (errno) strerr_diefu2sys(111, "getpwuid for user ", fmt) ; + else strerr_diefu3x(100, "getpwuid for user ", fmt, ": uid not found in passwd database") ; + } + homelen = strlen(pw->pw_dir) ; + } + } + char homeinstack[homelen + 1] ; + if (homelen) + { + memcpy(homeinstack, pw->pw_dir, homelen) ; + homestack[homelen] = 0 ; + home = homeinstack ; + } + + scanpos = storage->len ; + if (!stralloc_cats(storage, runtime) + || !stralloc_cats(storage, "/service") + || !stralloc_0(storage)) dienomem() ; + + livepos = storage->len ; + if (!stralloc_cats(storage, runtime) + || !stralloc_cats(storage, "/s6-rc") + || !stralloc_0(storage)) dienomem() ; + + repopos = storage.len ; + if (!(datahome ? stralloc_cats(storage, datahome) : stralloc_cats(storage, home) && stralloc_cats(storage, "/.local/share")) + || !stralloc_cats(storage, "/s6-frontend/repository") + || !stralloc_0(storage)) dienomem ; + + bootpos = storage.len ; + if (!(confighome ? stralloc_cats(storage, confighome) : stralloc_cats(storage, home) && stralloc_cats(storage, "/.config")) + || !stralloc_cats(storage, "/s6-rc") + || !stralloc_0(storage)) dienomem ; + + /* Don't add to storage past this point */ + + dirs->scan = storage.s + scanpos ; + +} diff --git a/src/s6/process.c b/src/s6/process.c index 6f8586c..1dca89d 100644 --- a/src/s6/process.c +++ b/src/s6/process.c @@ -22,7 +22,7 @@ static int check_service (char const *name, size_t scandirlen) struct stat st ; size_t namelen = strlen(name) ; char path[scandirlen + namelen + 2] ; - memcpy(path, g->scandir, scandirlen) ; + memcpy(path, g->dirs.scan, scandirlen) ; path[scandirlen] = '/' ; memcpy(path + scandirlen + 1, name, namelen) ; path[scandirlen + 1 + namelen] = 0 ; @@ -31,21 +31,21 @@ static int check_service (char const *name, size_t scandirlen) void process_check_services (char const *const *argv, size_t argc) { - size_t scandirlen = strlen(g->scandir) ; + size_t scandirlen = strlen(g->dirs.scan) ; for (size_t i = 0 ; i < argc ; i++) { int r = check_service(argv[i], scandirlen) ; if (r == -1) - strerr_diefu4sys(111, "stat ", g->scandir, "/", argv[i]) ; + strerr_diefu4sys(111, "stat ", g->dirs.scan, "/", argv[i]) ; else if (!r) - strerr_dief3x(100, argv[i], "is not registered as a supervised service in ", g->scandir) ; + strerr_dief3x(100, argv[i], "is not registered as a supervised service in ", g->dirs.scan) ; } } int process_send_svc (char const *svcopt, char const *const *argv, size_t argc) { char const *newargv[5] = { S6_EXTBINPREFIX "s6-svc", svcopt, "--", 0, 0 } ; - size_t scandirlen = strlen(g->scandir) ; + size_t scandirlen = strlen(g->dirs.scan) ; int wstat ; pid_t pids[argc] ; @@ -53,7 +53,7 @@ int process_send_svc (char const *svcopt, char const *const *argv, size_t argc) { size_t arglen = strlen(argv[i]) ; char path[scandirlen + arglen + 2] ; - memcpy(path, g->scandir, scandirlen) ; + memcpy(path, g->dirs.scan, scandirlen) ; path[scandirlen] = '/' ; memcpy(path + scandirlen + 1, argv[i], arglen) ; path[scandirlen + 1 + arglen] = 0 ; diff --git a/src/s6/process_kill.c b/src/s6/process_kill.c index fdad688..e33b47f 100644 --- a/src/s6/process_kill.c +++ b/src/s6/process_kill.c @@ -21,7 +21,7 @@ static int process_kill_hack_kill (int sig, char const *const *argv) { - size_t scandirlen = strlen(g->scandir) ; + size_t scandirlen = strlen(g->dirs.scan) ; if (g->verbosity) { char fmt[INT_FMT] ; @@ -34,7 +34,7 @@ static int process_kill_hack_kill (int sig, char const *const *argv) s6_svstatus_t status ; size_t arglen = strlen(*argv) ; char path[scandirlen + arglen + 2] ; - memcpy(path, g->scandir, scandirlen) ; + memcpy(path, g->dirs.scan, scandirlen) ; path[scandirlen] = '/' ; memcpy(path + scandirlen + 1, *argv, arglen) ; path[scandirlen + 1 + arglen] = 0 ; diff --git a/src/s6/process_status.c b/src/s6/process_status.c index 2240c85..96eb84b 100644 --- a/src/s6/process_status.c +++ b/src/s6/process_status.c @@ -87,7 +87,7 @@ static gol_bool const process_status_golb[1] = int process_status (char const *const *argv) { - size_t scandirlen = strlen(g->scandir) ; + size_t scandirlen = strlen(g->dirs.scan) ; uint64_t golb = 0 ; int e = 0 ; PROG = "s6 process status" ; @@ -99,7 +99,7 @@ int process_status (char const *const *argv) { size_t len = strlen(*argv) ; char path[scandirlen + len + 2] ; - memcpy(path, g->scandir, scandirlen) ; + memcpy(path, g->dirs.scan, scandirlen) ; path[scandirlen] = '/' ; memcpy(path + scandirlen + 1, *argv, len+1) ; if (do_status(path, !!(golb & 1 << PROCESS_STATUS_GOLB_WITHLOGS))) e = 1 ; diff --git a/src/s6/s6-internal.h b/src/s6/s6-internal.h index 6616c87..34a9c16 100644 --- a/src/s6/s6-internal.h +++ b/src/s6/s6-internal.h @@ -8,8 +8,10 @@ #include <stdlib.h> #include <skalibs/functypes.h> -#include <s6-frontend/config.h> +#include <skalibs/stralloc.h> +#include <s6-frontend/config.h> +#include "s6f.h" /* util */ @@ -53,18 +55,24 @@ extern int service (char const *const *) ; struct global_s { unsigned int verbosity ; - char const *scandir ; - char const *livedir ; - char const *repodir ; + s6f_confdirs dirs ; + stralloc userstorage ; + uint8_t isuser : 1 ; uint8_t istty : 1 ; uint8_t color : 1 ; } ; #define GLOBAL_ZERO \ { \ .verbosity = 1, \ - .scandir = S6_FRONTEND_SCANDIR, \ - .livedir = S6_FRONTEND_LIVEDIR, \ - .repodir = S6_FRONTEND_REPODIR, \ + .dirs = \ + { \ + .scan = S6_FRONTEND_SCANDIR, \ + .live = S6_FRONTEND_LIVEDIR, \ + .repo = S6_FRONTEND_REPODIR, \ + .boot = S6_FRONTEND_BOOTDIR, \ + }, \ + .userstorage = STRALLOC_ZERO, \ + .isuser = 0, \ .istty = 0, \ .color = 0 \ } diff --git a/src/s6/s6.c b/src/s6/s6.c index 9b6b88a..8d5295c 100644 --- a/src/s6/s6.c +++ b/src/s6/s6.c @@ -32,6 +32,7 @@ enum main_golb_e { MAIN_GOLB_HELP, MAIN_GOLB_VERSION, + MAIN_GOLB_USER, MAIN_GOLB_N } ; @@ -40,6 +41,7 @@ enum main_gola_e MAIN_GOLA_SCANDIR, MAIN_GOLA_LIVEDIR, MAIN_GOLA_REPODIR, + MAIN_GOLA_BOOTDIR, MAIN_GOLA_VERBOSITY, MAIN_GOLA_COLOR, MAIN_GOLA_N @@ -48,7 +50,8 @@ enum main_gola_e static gol_bool const main_golb[MAIN_GOLB_N] = { { .so = 'h', .lo = "help", .set = 1, .mask = 1 << MAIN_GOLB_HELP }, - { .so = 'V', .lo = "version", .set = 1, .mask = 1 << MAIN_GOLB_VERSION } + { .so = 'V', .lo = "version", .set = 1, .mask = 1 << MAIN_GOLB_VERSION }, + { .so = 0, .lo = "user", .set = 1, .mask = 1 << MAIN_GOLB_USER } } ; static gol_arg const main_gola[MAIN_GOLA_N] = @@ -56,6 +59,7 @@ static gol_arg const main_gola[MAIN_GOLA_N] = { .so = 's', .lo = "scandir", .i = MAIN_GOLA_SCANDIR }, { .so = 'l', .lo = "livedir", .i = MAIN_GOLA_LIVEDIR }, { .so = 'r', .lo = "repodir", .i = MAIN_GOLA_REPODIR }, + { .so = 'b', .lo = "bootdir", .i = MAIN_GOLA_BOOTDIR }, { .so = 'v', .lo = "verbosity", .i = MAIN_GOLA_VERBOSITY }, { .so = 0, .lo = "color", .i = MAIN_GOLA_COLOR } } ; @@ -86,13 +90,14 @@ int main (int argc, char const *const *argv, char const *const *envp) if (gola[MAIN_GOLA_VERBOSITY] && !uint0_scan(gola[MAIN_GOLA_VERBOSITY], &g->verbosity)) strerr_dief1x(100, "verbosity must be an unsigned integer") ; - if (golb & (1 << MAIN_GOLB_VERSION)) version(argv) ; - if (golb & (1 << MAIN_GOLB_HELP)) help(argv) ; - if (golb & ((1 << MAIN_GOLB_VERSION) | (1 << MAIN_GOLB_HELP))) return 0 ; + if (golb & 1 << MAIN_GOLB_VERSION) version(argv) ; + if (golb & 1 << MAIN_GOLB_HELP) help(argv) ; + if (golb & (1 << MAIN_GOLB_VERSION | 1 << MAIN_GOLB_HELP)) return 0 ; - if (gola[MAIN_GOLA_SCANDIR]) g->scandir = gola[MAIN_GOLA_SCANDIR] ; - if (gola[MAIN_GOLA_LIVEDIR]) g->livedir = gola[MAIN_GOLA_LIVEDIR] ; - if (gola[MAIN_GOLA_REPODIR]) g->repodir = gola[MAIN_GOLA_REPODIR] ; + if (gola[MAIN_GOLA_SCANDIR]) g->dirs.scan = gola[MAIN_GOLA_SCANDIR] ; + if (gola[MAIN_GOLA_LIVEDIR]) g->dirs.live = gola[MAIN_GOLA_LIVEDIR] ; + if (gola[MAIN_GOLA_REPODIR]) g->dirs.repo = gola[MAIN_GOLA_REPODIR] ; + if (gola[MAIN_GOLA_BOOTDIR]) g->dirs.boot = gola[MAIN_GOLA_BOOTDIR] ; { int force_color = 0 ; @@ -115,6 +120,9 @@ int main (int argc, char const *const *argv, char const *const *envp) if (!force_color) g->color = g->istty ; } + g->isuser = !!(golb & 1 << MAIN_GOLB_USER) ; + if (g->isuser) s6f_user_get_confdirs(&g->dirs, &g->userstorage) ; + if (!*argv) dieusage() ; cmd = BSEARCH(struct command_s, *argv, main_commands) ; if (!cmd) dieusage() ; diff --git a/src/s6/service_start.c b/src/s6/service_start.c index 4b8c3a6..8e876ea 100644 --- a/src/s6/service_start.c +++ b/src/s6/service_start.c @@ -49,6 +49,7 @@ int service_start (char const *const *argv) newargv[m++] = "-n" ; newargv[m++] = "1" ; } + newargv[m++] = "--" ; } return 0 ; } |
