X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/1691e80890e5d8ba258c51c214a3e91880e1db2b..44ce2010:/sbr/makedir.c?ds=sidebyside diff --git a/sbr/makedir.c b/sbr/makedir.c index 6cf9e03c..165fc4f0 100644 --- a/sbr/makedir.c +++ b/sbr/makedir.c @@ -1,8 +1,8 @@ - -/* - * makedir.c -- make a directory +/* makedir.c -- make a directory * - * $Id$ + * This code is Copyright (c) 2002, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. */ /* @@ -10,70 +10,66 @@ */ #include -#include -#include #include -extern int errno; - int -makedir (char *dir) +makedir (const char *dir) { - pid_t pid; - register char *cp; - register char *c; - char path[PATH_MAX]; + char path[PATH_MAX]; + char* folder_perms_ASCII; + int had_an_error = 0; + mode_t folder_perms, saved_umask; + char* c; - context_save(); /* save the context file */ + context_save(); /* save the context file */ fflush(stdout); - if (getuid () == geteuid ()) { - c = strncpy(path, dir, sizeof(path)); + if (!(folder_perms_ASCII = context_find ("folder-protect"))) + folder_perms_ASCII = foldprot; /* defaults to "700" */ - while ((c = strchr((c + 1), '/')) != NULL) { - *c = (char)0; - if (access(path, X_OK)) { - if (errno != ENOENT){ - advise (dir, "unable to create directory"); - return 0; - } - if (mkdir(path, 0775)) { - advise (dir, "unable to create directory"); - return 0; - } - } - *c = '/'; - } - - if (mkdir (dir, 0755) == -1) { - advise (dir, "unable to create directory"); - return 0; - } - } else { - switch (pid = vfork()) { - case -1: - advise ("fork", "unable to"); - return 0; + /* Because mh-profile.man documents "Folder-Protect:" as an octal constant, + and we don't want to force the user to remember to include a leading + zero, we call atooi(folder_perms_ASCII) here rather than + strtoul(folder_perms_ASCII, NULL, 0). Therefore, if anyone ever tries to + specify a mode in say, hex, they'll get garbage. (I guess nmh uses its + atooi() function rather than calling strtoul() with a radix of 8 because + some ancient platforms are missing that functionality. */ + folder_perms = atooi(folder_perms_ASCII); - case 0: - setgid (getgid ()); - setuid (getuid ()); + /* Folders have definite desired permissions that are set -- we don't want + to interact with the umask. Clear it temporarily. */ + saved_umask = umask(0); - execl ("/bin/mkdir", "mkdir", dir, NULL); - execl ("/usr/bin/mkdir", "mkdir", dir, NULL); - fprintf (stderr, "unable to exec "); - perror ("mkdir"); - _exit (-1); + c = strncpy(path, dir, sizeof(path)); - default: - if (pidXwait(pid, "mkdir")) - return 0; - break; - } + while (!had_an_error && (c = strchr((c + 1), '/')) != NULL) { + *c = (char)0; + if (access(path, X_OK)) { + if (errno != ENOENT){ + advise (dir, "unable to create directory"); + had_an_error = 1; + } + /* Create an outer directory. */ + if (mkdir(path, folder_perms)) { + advise (dir, "unable to create directory"); + had_an_error = 1; + } + } + *c = '/'; } - if (!(cp = context_find ("folder-protect"))) - cp = foldprot; - chmod (dir, atooi (cp)); + if (!had_an_error) { + /* Create the innermost nested subdirectory of the path we're being + asked to create. */ + if (mkdir (dir, folder_perms) == -1) { + advise (dir, "unable to create directory"); + had_an_error = 1; + } + } + + umask(saved_umask); /* put the user's umask back */ + + if (had_an_error) + return 0; /* opposite of UNIX error return convention */ return 1; }