aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include-local/s6f.h19
-rw-r--r--src/libs6f/deps-exe/s6f1
-rw-r--r--src/libs6f/s6f_user_get_confdirs.c77
-rw-r--r--src/s6/process.c12
-rw-r--r--src/s6/process_kill.c4
-rw-r--r--src/s6/process_status.c4
-rw-r--r--src/s6/s6-internal.h22
-rw-r--r--src/s6/s6.c22
-rw-r--r--src/s6/service_start.c1
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 ;
}