summaryrefslogtreecommitdiff
path: root/src/libs6
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs6')
-rw-r--r--src/libs6/deps-lib/s62
-rw-r--r--src/libs6/s6_servicedir_instances_recreate_offline.c10
-rw-r--r--src/libs6/s6_servicedir_instances_recreate_offline_tmp.c73
3 files changed, 85 insertions, 0 deletions
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 732e071..9924d83 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -33,6 +33,8 @@ s6_dtally_read.o
s6_dtally_write.o
s6_instance_chdirservice.o
s6_servicedir_file_list.o
+s6_servicedir_instances_recreate_offline.o
+s6_servicedir_instances_recreate_offline_tmp.o
s6_svc_ok.o
s6_svc_write.o
s6_svc_writectl.o
diff --git a/src/libs6/s6_servicedir_instances_recreate_offline.c b/src/libs6/s6_servicedir_instances_recreate_offline.c
new file mode 100644
index 0000000..f461a1d
--- /dev/null
+++ b/src/libs6/s6_servicedir_instances_recreate_offline.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <skalibs/skamisc.h>
+
+#include <s6/servicedir.h>
+
+int s6_servicedir_instances_recreate_offline (char const *old, char const *new)
+{
+ return s6_servicedir_instances_recreate_offline_tmp(old, new, &satmp) ;
+}
diff --git a/src/libs6/s6_servicedir_instances_recreate_offline_tmp.c b/src/libs6/s6_servicedir_instances_recreate_offline_tmp.c
new file mode 100644
index 0000000..b6a7ddb
--- /dev/null
+++ b/src/libs6/s6_servicedir_instances_recreate_offline_tmp.c
@@ -0,0 +1,73 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#include <s6/servicedir.h>
+
+int s6_servicedir_instances_recreate_offline_tmp (char const *old, char const *new, stralloc *sa)
+{
+ int n ;
+ mode_t m ;
+ size_t maxlen = 0 ;
+ size_t sabase = sa->len ;
+ size_t oldlen = strlen(old) ;
+ size_t newlen = strlen(new) ;
+ char templatedir[oldlen + 11] ;
+ memcpy(templatedir, old, oldlen) ;
+ memcpy(templatedir + oldlen, "/instances", 11) ;
+ n = sals(templatedir, sa, &maxlen) ;
+ if (n == -1) return errno == ENOENT ? 0 : -1 ;
+
+ {
+ size_t pos = sabase ;
+ char olddir[oldlen + 16 + maxlen] ;
+ char newsd[newlen + 11 + maxlen] ;
+ char newdir[newlen + 17 + maxlen] ;
+ char lnk[14 + maxlen] ;
+ memcpy(olddir, templatedir, oldlen + 10) ;
+ olddir[oldlen + 10] = '/' ;
+ memcpy(templatedir + oldlen + 1, "template", 9) ;
+ memcpy(newsd, new, newlen) ;
+ memcpy(newsd + newlen, "/instance", 10) ;
+ memcpy(newdir, newsd, newlen + 9) ;
+ newdir[newlen + 9] = 's' ; newdir[newlen + 10] = 0 ;
+ memcpy(lnk, "../instances/", 13) ;
+ m = umask(0) ;
+ if (mkdir(newsd, 0755) == -1 && errno != EEXIST) goto merr ;
+ if (mkdir(newdir, 0755) == -1 && errno != EEXIST) goto merr ;
+ umask(m) ;
+ newsd[newlen+9] = '/' ;
+ newdir[newlen+10] = '/' ;
+ while (pos < sa->len)
+ {
+ size_t len = strlen(sa->s + pos) ;
+ memcpy(olddir + oldlen + 10, sa->s + pos, len) ;
+ memcpy(olddir + oldlen + 10 + len, "/down", 6) ;
+ memcpy(newsd + newlen + 10, sa->s + pos, len + 1) ;
+ memcpy(newdir + newlen + 11, sa->s + pos, len + 1) ;
+ memcpy(lnk + 13, sa->s + pos, len + 1) ;
+ if (!hiercopy_tmp(templatedir, newdir, sa)) goto err ;
+ if (symlink(lnk, newsd) == -1 && errno != EEXIST) goto err ;
+ if (access(olddir, F_OK) == 0)
+ {
+ memcpy(newdir + newlen + 11 + len, "/down", 6) ;
+ if (!openwritenclose_unsafe(newdir, "", 0)) goto err ;
+ }
+ else if (errno != ENOENT) goto err ;
+ pos += len + 1 ;
+ }
+ }
+ return n ;
+
+ merr:
+ umask(m) ;
+ err:
+ sa->len = sabase ;
+ return -1 ;
+}