diff --git a/usr.sbin/certctl/certctl.c b/usr.sbin/certctl/certctl.c --- a/usr.sbin/certctl/certctl.c +++ b/usr.sbin/certctl/certctl.c @@ -100,6 +100,28 @@ static FILE *mlf; +/* + * Create a directory and its parents as needed. + */ +static void +mkdirp(const char *dir) +{ + struct stat sb; + const char *sep; + char *parent; + + if (stat(dir, &sb) == 0) + return; + if ((sep = strrchr(dir, '/')) != NULL) { + parent = xasprintf("%.*s", (int)(sep - dir), dir); + mkdirp(parent); + free(parent); + } + info("creating %s", dir); + if (mkdir(dir, 0755) != 0) + err(1, "mkdir %s", dir); +} + /* * Remove duplicate and trailing slashes from a path. */ @@ -685,7 +707,7 @@ { int ret; - /* save untrusted certs */ + mkdirp(trusted_dest); ret = write_certs(trusted_dest, &trusted); return (ret); } @@ -700,6 +722,7 @@ { int ret; + mkdirp(untrusted_dest); ret = write_certs(untrusted_dest, &untrusted); return (ret); } @@ -721,6 +744,7 @@ } else { dir = xasprintf("%.*s", (int)(sep - bundle_dest), bundle_dest); file = sep + 1; + mkdirp(dir); } ret = write_bundle(dir, file, &trusted); free(dir); @@ -995,17 +1019,17 @@ if ((value = getenv("TRUSTDESTDIR")) != NULL || (value = getenv("CERTDESTDIR")) != NULL) - trusted_dest = xstrdup(value); + trusted_dest = normalize_path(value); else trusted_dest = expand_path(TRUSTED_PATH); if ((value = getenv("UNTRUSTDESTDIR")) != NULL) - untrusted_dest = xstrdup(value); + untrusted_dest = normalize_path(value); else untrusted_dest = expand_path(UNTRUSTED_PATH); if ((value = getenv("BUNDLE")) != NULL) - bundle_dest = xstrdup(value); + bundle_dest = normalize_path(value); else bundle_dest = expand_path(BUNDLE_PATH); diff --git a/usr.sbin/certctl/tests/certctl_test.sh b/usr.sbin/certctl/tests/certctl_test.sh --- a/usr.sbin/certctl/tests/certctl_test.sh +++ b/usr.sbin/certctl/tests/certctl_test.sh @@ -76,9 +76,9 @@ mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted mkdir -p ${DESTDIR}/usr/local/share/certs - # Create output directories - mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/certs - mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/untrusted + # Do not create output directories; certctl will take care of it + #mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/certs + #mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/untrusted # Generate a random key keyname="testkey"