]> diplodocus.org Git - nmh/blobdiff - sbr/makedir.c
Added warning about when post(1) can't refile(1) a draft.
[nmh] / sbr / makedir.c
index 6cf9e03c29303f90aab20eb9612228cbd78c5760..165fc4f0df95aa2276100a4ea50123e9e3f7e9e7 100644 (file)
@@ -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.
  */
 
 /*
  */
 
 #include <h/mh.h>
-#include <errno.h>
-#include <sys/param.h>
 #include <sys/file.h>
 
-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;
 }