3 * makedir.c -- make a directory
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
13 * Modified to try recursive create.
18 #include <sys/param.h>
27 char* folder_perms_ASCII;
29 mode_t folder_perms, saved_umask;
33 context_save(); /* save the context file */
36 if (!(folder_perms_ASCII = context_find ("folder-protect")))
37 folder_perms_ASCII = foldprot; /* defaults to "700" */
39 /* Because mh-profile.man documents "Folder-Protect:" as an octal constant,
40 and we don't want to force the user to remember to include a leading
41 zero, we call atooi(folder_perms_ASCII) here rather than
42 strtoul(folder_perms_ASCII, NULL, 0). Therefore, if anyone ever tries to
43 specify a mode in say, hex, they'll get garbage. (I guess nmh uses its
44 atooi() function rather than calling strtoul() with a radix of 8 because
45 some ancient platforms are missing that functionality. */
46 folder_perms = atooi(folder_perms_ASCII);
48 /* Folders have definite desired permissions that are set -- we don't want
49 to interact with the umask. Clear it temporarily. */
50 saved_umask = umask(0);
52 if (getuid () == geteuid ()) {
53 c = strncpy(path, dir, sizeof(path));
55 while (!had_an_error && (c = strchr((c + 1), '/')) != NULL) {
57 if (access(path, X_OK)) {
59 advise (dir, "unable to create directory");
62 /* Create an outer directory. */
63 if (mkdir(path, folder_perms)) {
64 advise (dir, "unable to create directory");
72 /* Create the innermost nested subdirectory of the path we're being
74 if (mkdir (dir, folder_perms) == -1) {
75 advise (dir, "unable to create directory");
81 /* Ummm, why do we want to avoid creating directories with the effective
82 user ID? None of the nmh tools are installed such that the effective
83 should be different from the real, and if some parent process made
84 the two be different, I don't see why it should be our job to enforce
85 the real UID. Also, why the heck do we call the mkdir executable
86 rather than the library function in this case?? If we do want to
87 call the mkdir executable, we should at least be giving it -p (and
88 change the single chmod() call below) so it can successfully create
89 nested directories like the above code can.
91 -- Dan Harkless <dan-nmh@dilvish.speed.net> */
92 switch (pid = vfork()) {
94 advise ("fork", "unable to");
101 execl ("/bin/mkdir", "mkdir", dir, NULL);
102 execl ("/usr/bin/mkdir", "mkdir", dir, NULL);
103 fprintf (stderr, "unable to exec ");
108 if (pidXwait(pid, "mkdir"))
113 chmod (dir, folder_perms);
116 umask(saved_umask); /* put the user's umask back */
119 return 0; /* opposite of UNIX error return convention */