diff options
Diffstat (limited to 'src/libs6rcd')
-rw-r--r-- | src/libs6rcd/s6rcd.h | 9 | ||||
-rw-r--r-- | src/libs6rcd/s6rcd_db_load.c | 17 | ||||
-rw-r--r-- | src/libs6rcd/s6rcd_livedir_init.c | 124 | ||||
-rw-r--r-- | src/libs6rcd/s6rcd_livesubdir_create.c | 35 |
4 files changed, 185 insertions, 0 deletions
diff --git a/src/libs6rcd/s6rcd.h b/src/libs6rcd/s6rcd.h new file mode 100644 index 0000000..a9326b7 --- /dev/null +++ b/src/libs6rcd/s6rcd.h @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <s6-rc/db.h> + +extern int s6rcd_livedir_init (char const *, char const *, char const *, char const *, int *) +extern int s6rcd_livesubdir_create (char *, char const *, char const *) ; + +extern int s6rcd_db_load (s6rc_db_t *, char const *) ; +extern int s6rcd_db_read_sizes (s6rc_db_sizes_t *, char const *) ; diff --git a/src/libs6rcd/s6rcd_db_load.c b/src/libs6rcd/s6rcd_db_load.c new file mode 100644 index 0000000..68aa11e --- /dev/null +++ b/src/libs6rcd/s6rcd_db_load.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <s6-rc/db.h> +#include "s6rcd.h" + +int s6rcd_db_load (s6rc_db_t *db, char const *compiled) +{ + if (!s6rcd_db_read_sizes(db, compiled)) return 0 ; + +} diff --git a/src/libs6rcd/s6rcd_livedir_init.c b/src/libs6rcd/s6rcd_livedir_init.c new file mode 100644 index 0000000..f252dba --- /dev/null +++ b/src/libs6rcd/s6rcd_livedir_init.c @@ -0,0 +1,124 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <skalibs/strerr2.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> + +#include "s6rcd.h" + +#ifdef NAME_MAX +# define S6RC_NAME_MAX NAME_MAX +#else +# define S6RC_NAME_MAX 63 +#endif + +static inline int mksubdirs (char *s) +{ + size_t n = strlen(s) ; + size_t i = 0 ; + for (; i < n ; i++) + { + if (s[i] == '/') + { + int r ; + s[i] = 0 ; + r = mkdir(s, 0755) ; + s[i] = '/' ; + if (r < 0 && errno != EEXIST) break ; + } + } + return i >= n ; +} + +int s6rcd_livedir_init (char const *livedir, char const *scandir, char const *prefix, char const *compiled, int *sock) +{ + size_t plen = strlen(prefix) ; + size_t llen = strlen(livedir) ; + struct stat st ; + char ltmp[llen + 9] ; + if (plen >= S6RC_NAME_MAX) + strerr_dief1x(100, "prefix is too long") ; + + memcpy(ltmp, livedir, llen + 1) ; + if (!mksubdirs(ltmp, len)) + strerr_diefu2sys(111, "create subdirectories of ", s) ; + if (mkdir(ltmp, 0755) < 0 && errno != EEXIST) + strerr_diefu2sys(111, "mkdir ", ltmp) ; + + memcpy(ltmp + llen, "/s", 3) ; + *sock = ipc_stream() ; + if (*sock < 0) + strerr_diefu1sys(111, "create socket") ; + if (ipc_bind_reuse(*sock, ltmp) < 0) + strerr_diefu2sys(111, "bind to ", ltmp) ; + + memcpy(ltmp + llen + 1, "scandir", 8) ; + if (lstat(ltmp, &st) < 0) + { + if (errno != ENOENT) + strerr_diefu2sys(111, "lstat ", ltmp) ; + if (symlink(scandir, ltmp) < 0) + strerr_diefu4sys(111, "symlink ", ltmp, " to ", scandir) ; + } + else + { + size_t slen = strlen(scandir) ; + char stmp[slen + 1] ; + if (!S_ISLNK(st.st_mode)) + strerr_dief3x(100, "file ", ltmp, " exists and is not a symbolic link") ; + if (readlink(ltmp, stmp, slen + 1) < 0) + strerr_diefu2sys(111, "readlink ", ltmp) ; + if (strncmp(scandir, stmp, slen + 1)) + strerr_dief4x(100, "provided scandir ", scandir, " does not match the contents of existing ", ltmp) ; + } + + memcpy(ltmp + llen + 1, "prefix", 7) ; + if (stat(ltmp, &st) < 0) + { + if (errno != ENOENT) + strerr_diefu2sys(111, "stat ", ltmp) ; + if (!openwritenclose_unsafe(ltmp, prefix, strlen(prefix))) + strerr_diefu2sys(111, "write prefix to ", ltmp) ; + } + else + { + if (!S_IFREG(st.st_mode)) + strerr_dief3x(100, "file ", ltmp, " exists and is not a regular file") ; + if (st.st_size != plen) + strerr_dief4x(100, "provided prefix ", prefix, " does not match the contents of existing ", ltmp) ; + { + char stmp[plen] ; + ssize_t r = openreadnclose(ltmp, ptmp, plen) ; + if (r != plen) + strerr_diefu2sys(111, "read ", ltmp) ; + if (memcmp(ptmp, prefix, plen)) + strerr_dief4x(100, "provided prefix ", prefix, " does not match the contents of existing ", ltmp) ; + } + } + + memcpy(ltmp + llen + 1, "live", 5) ; + if (lstat(ltmp, &st) < 0) + { + char name[12] ; + if (errno != ENOENT) strerr_diefu2sys(111, "lstat ", ltmp) ; + if (!s6rcd_livesubdir_create(name, live, compiled)) + strerr_diefu2sys(111, "create live subdirectory in ", live) ; + if (symlink(name, ltmp) < 0) + strerr_diefu4sys(111, "symlink ", ltmp, " to ", name) ; + return 0 ; + } + if (!S_ISLNK(st.st_mode)) + strerr_dief3x(100, "livesubdir ", ltmp, " exists and is not a symbolic link") ; + if (stat(ltmp, &st) < 0) + strerr_diefu2sys(111, "stat ", ltmp) ; + if (!S_ISDIR(st.st_mode)) + strerr_dief4x(100, "livesubdir ", ltmp, " exists and is not a symbolic link", " to a directory") ; + return 1 ; +} diff --git a/src/libs6rcd/s6rcd_livesubdir_create.c b/src/libs6rcd/s6rcd_livesubdir_create.c new file mode 100644 index 0000000..ff989aa --- /dev/null +++ b/src/libs6rcd/s6rcd_livesubdir_create.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <skalibs/djbunix.h> + +#include "s6rcd.h" + +int s6rcd_livesubdir_create (char *name, char const *live, char const *compiled) +{ + size_t llen = strlen(live) ; + size_t clen = strlen(compiled) ; + char cfn[clen + 13] ; + char lfn[llen + 25] ; + memcpy(lfn, live, llen) ; + memcpy(lfn + llen, "/live:XXXXXX", 13) ; + if (!mkdtemp(lfn)) return 0 ; + + memcpy(lfn + llen + 12, "/compiled", 10) ; + if (symlink(compiled, lfn) < 0) return 0 ; + strerr_diefu4sys(111, "symlink ", compiled, " to ", realfn + llen + 1) ; + + memcpy(cfn, compiled, clen) ; + memcpy(cfn + clen, "/servicedirs", 13) ; + memcpy(lfn + llen + 13, "servicedirs", 12) ; + if (!hiercopy(cfn, lfn)) return 0 ; + + lfn[llen + 12] = 0 ; + if (chmod(lfn, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) return 0 ; + memcpy(name, lfn + llen + 1, 12) ; + return 1 ; +} |