summaryrefslogtreecommitdiff
path: root/src/libs6rcd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs6rcd')
-rw-r--r--src/libs6rcd/s6rcd.h9
-rw-r--r--src/libs6rcd/s6rcd_db_load.c17
-rw-r--r--src/libs6rcd/s6rcd_livedir_init.c124
-rw-r--r--src/libs6rcd/s6rcd_livesubdir_create.c35
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 ;
+}