int main (int argc, char const *const *argv) { stralloc sa = STRALLOC_ZERO ; unsigned int n = 8 ; PROG = "s6-uniquename" ; { subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { register int opt = subgetopt_r(argc, argv, "n:", &l) ; if (opt == -1) break ; switch (opt) { case 'n' : if (!uint0_scan(l.arg, &n)) usage() ; break ; default : usage() ; } } argc -= l.ind ; argv += l.ind ; } if (argc < 1) usage() ; if (!stralloc_cats(&sa, argv[0])) strerr_diefu1sys(111, "stralloc_cats") ; if ((n ? random_sauniquename(&sa, n) : sauniquename(&sa)) < 0) strerr_diefu1sys(111, "make unique name") ; if (!stralloc_catb(&sa, "\n", 1)) strerr_diefu1sys(111, "stralloc_cats") ; if (allwrite(1, sa.s, sa.len) < sa.len) strerr_diefu1sys(111, "write to stdout") ; return 0 ; }
static int makeuniquename (stralloc *sa, char const *path, char const *magic) { unsigned int base = sa->len ; int wasnull = !sa->s ; if (!stralloc_cats(sa, path)) return 0 ; if (!stralloc_cats(sa, magic)) goto err ; if (random_sauniquename(sa, 8) == -1) goto err ; if (!stralloc_0(sa)) goto err ; return 1 ; err: if (wasnull) stralloc_free(sa) ; else sa->len = base ; return 0 ; }
int mkdir_unique (stralloc *sa, char const *fn, unsigned int mode) { unsigned int base = sa->len ; int wasnull = !sa->s ; if (!stralloc_cats(sa, fn)) return 0 ; if (!stralloc_cats(sa, "/mkdir_unique")) goto fail ; if (random_sauniquename(sa, 8) < 0) goto fail ; if (!stralloc_0(sa)) goto fail ; if (mkdir(sa->s + base, mode) < 0) goto fail ; sa->len-- ; return 1 ; fail: if (wasnull) stralloc_free(sa) ; else sa->len = base ; return 0 ; }
int atomic_rm_rf_tmp (char const *filename, stralloc *tmp) { unsigned int tmpbase = tmp->len ; unsigned int start ; if (!stralloc_cats(tmp, ".skalibs-rmrf-") || !stralloc_cats(tmp, filename)) return -1 ; start = tmp->len ; for (;;) { if (random_sauniquename(tmp, 64) < 0) goto err ; if (!stralloc_0(tmp)) goto err ; if (!rename(filename, tmp->s + tmpbase)) break ; if (errno != EEXIST && errno != ENOTEMPTY) goto err ; tmp->len = start ; } if (rm_rf_in_tmp(tmp, tmpbase) < 0) goto err ; tmp->len = tmpbase ; return 0 ; err: tmp->len = tmpbase ; return -1 ; }