summaryrefslogtreecommitdiff
path: root/src/skaembutils/s6-mkdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/skaembutils/s6-mkdir.c')
-rw-r--r--src/skaembutils/s6-mkdir.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/skaembutils/s6-mkdir.c b/src/skaembutils/s6-mkdir.c
new file mode 100644
index 0000000..92bae67
--- /dev/null
+++ b/src/skaembutils/s6-mkdir.c
@@ -0,0 +1,79 @@
+/* ISC license. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <skalibs/sgetopt.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/uint.h>
+#include <skalibs/buffer.h>
+#include <skalibs/strerr2.h>
+
+#define USAGE "s6-mkdir [ -p ] [ -v ] [ -m mode ] dir"
+
+static int doit (char const *s, unsigned int mode, int verbose, int ee)
+{
+ if (mkdir(s, mode) == -1)
+ {
+ if (ee || (errno != EEXIST))
+ {
+ strerr_warnwu2sys("mkdir ", s) ;
+ return 111 ;
+ }
+ }
+ else if (verbose)
+ {
+ buffer_puts(buffer_2, PROG) ;
+ buffer_puts(buffer_2, ": created directory ") ;
+ buffer_puts(buffer_2, s) ;
+ buffer_putflush(buffer_2, "\n", 1) ;
+ }
+ return 0 ;
+}
+
+static int doparents (char const *s, unsigned int mode, int verbose)
+{
+ unsigned int n = str_len(s), i = 0 ;
+ char tmp[n+1] ;
+ for (; i < n ; i++)
+ {
+ if ((s[i] == '/') && i)
+ {
+ register int e ;
+ tmp[i] = 0 ;
+ e = doit(tmp, mode, verbose, 0) ;
+ if (e) return e ;
+ }
+ tmp[i] = s[i] ;
+ }
+ return doit(s, mode, verbose, 0) ;
+}
+
+int main (int argc, char const *const *argv)
+{
+ int parents = 0, verbose = 0 ;
+ unsigned int mode = 0777 ;
+ int e = 0 ;
+ PROG = "s6-mkdir" ;
+ {
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ register int opt = subgetopt_r(argc, argv, "pvm:", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'p': parents = 1 ; break ;
+ case 'v': verbose = 1 ; break ;
+ case 'm': if (uint_oscan(l.arg, &mode)) break ;
+ default : strerr_dieusage(100, USAGE) ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+ for ( ; *argv ; argv++)
+ e |= parents ? doparents(*argv, mode, verbose) :
+ doit(*argv, mode, verbose, 1) ;
+ return e ;
+}