Release 1.2.4.
[checkpath] / tmpdir.c
index f0fcb5f..0bf51d3 100644 (file)
--- a/tmpdir.c
+++ b/tmpdir.c
@@ -48,6 +48,7 @@
 #include <mLib/report.h>
 
 #include "checkpath.h"
+#include "utils.h"
 
 /*----- Static variables --------------------------------------------------*/
 
@@ -68,6 +69,17 @@ static struct passwd *pw;
  *             and @*f@ is set, then try to create the directory.
  */
 
+static void complain(const char *p, const char *msg, int err)
+{
+  dstr d = DSTR_INIT;
+
+  if (!cp.cp_verbose) return;
+  dstr_putf(&d, "Path: %s: %s", p, msg);
+  if (err) dstr_putf(&d, ": %s", strerror(err));
+  moan(d.buf);
+  dstr_destroy(&d);
+}
+
 static int ok(const char *p, int *f)
 {
   struct stat st;
@@ -78,9 +90,12 @@ static int ok(const char *p, int *f)
 
     /* --- Maybe create it if it doesn't exist --- */
 
-    if (errno != ENOENT || !f || !*f)
+    if (errno != ENOENT || !f || !*f) {
+      complain(p, "can't stat", errno);
       return (0);
+    }
     if (mkdir(p, 0700)) {
+      complain(p, "can't create", errno);
       *f = 0;
       return (0);
     }
@@ -91,8 +106,10 @@ static int ok(const char *p, int *f)
      * the @mkdir@.
      */
 
-    if (lstat(p, &st))
+    if (lstat(p, &st)) {
+      complain(p, "can't stat after creating", errno);
       return (0);
+    }
   }
 
   /* --- Make sure the directory is good --- *
@@ -101,7 +118,13 @@ static int ok(const char *p, int *f)
    * and writable only by its owner, and that owner must be me.
    */
 
-  if (S_ISDIR(st.st_mode) && (st.st_mode & 0777) == 0700 && st.st_uid == me)
+  if (!S_ISDIR(st.st_mode))
+    complain(p, "not a directory", 0);
+  else if (st.st_uid != me)
+    complain(p, "not owner", 0);
+  else if ((st.st_mode & 0777) != 0700)
+    complain(p, "non-owner access permitted", 0);
+  else
     return (1);
   return (0);
 }
@@ -233,7 +256,7 @@ static void report(unsigned what, int verbose,
 /* --- @usage@ --- */
 
 static void usage(FILE *fp)
-  { fprintf(fp, "Usage: %s [-bc] [-v PATH]\n", QUIS); }
+  { fprintf(fp, "Usage: %s [-bcv] [-g NAME] [-C PATH]\n", QUIS); }
 
 /* --- @version@ --- */
 
@@ -272,46 +295,6 @@ setting for that shell type.\n\
        fp);
 }
 
-/* --- @allowgroup@ --- *
- *
- * Arguments:  @const char *gname@ = trust group @gname@
- *
- * Returns:    ---
- *
- * Use:                Adds the gid corresponding to @gname@ (which may be a number)
- *             to the list of things we trust.
- */
-
-static void allowgroup(const char *gname)
-{
-  struct group *gr;
-  const char *p;
-  gid_t g;
-
-  /* --- Check for numeric group spec --- */
-
-  for (p = gname; *p; p++) {
-    if (!isdigit((unsigned char)*p))
-      goto lookup;
-  }
-  g = atoi(gname);
-  goto insert;
-
-  /* --- Look up a group by name --- */
-
-lookup:
-  if ((gr = getgrnam(gname)) == 0)
-    die(1, "group %s not found", gname);
-  g = gr->gr_gid;
-
-  /* --- Insert the group into the table --- */
-
-insert:
-  if (cp.cp_gids >= N(cp.cp_gid))
-    die(1, "too many groups");
-  cp.cp_gid[cp.cp_gids++] = g;
-}
-
 /* --- @main@ --- *
  *
  * Arguments:  @int argc@ = number of command line arguments
@@ -337,12 +320,11 @@ int main(int argc, char *argv[])
   /* --- Initialize variables --- */
 
   ego(argv[0]);
-  me = geteuid();
+  me = cp.cp_uid = geteuid();
   cp.cp_what = (CP_WRWORLD | CP_WROTHGRP | CP_WROTHUSR |
-               CP_STICKYOK | CP_REPORT);
+               CP_STICKYOK | CP_REPORT | CP_ERROR);
   cp.cp_verbose = 0;
   cp.cp_report = report;
-  checkpath_setids(&cp);
   cp.cp_gids = 0;                      /* ignore group membership */
   pw = getpwuid(me);
   if (!pw)
@@ -353,7 +335,7 @@ int main(int argc, char *argv[])
   for (;;) {
     static struct option opts[] = {
       { "help",                0,              0,      'h' },
-      { "version",     0,              0,      'V' },
+      { "version",     0,              0,      'V' },
       { "usage",       0,              0,      'u' },
       { "bourne",      0,              0,      'b' },
       { "cshell",      0,              0,      'c' },
@@ -364,7 +346,7 @@ int main(int argc, char *argv[])
       { "group",       OPTF_ARGREQ,    0,      'g' },
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "hVu" "bcvtg:c:", opts, 0, 0, 0);
+    int i = mdwopt(argc, argv, "hVu" "bcvtg:C:", opts, 0, 0, 0);
 
     if (i < 0)
       break;
@@ -388,7 +370,7 @@ int main(int argc, char *argv[])
        return (!fullcheck(optarg));
        break;
       case 'g':
-       allowgroup(optarg);
+       allowgroup(&cp, optarg);
        break;
       case 'v':
        cp.cp_verbose++;
@@ -426,7 +408,7 @@ int main(int argc, char *argv[])
     case sh_csh:
       printf("setenv TMPDIR \"%s\"\n", p);
        break;
-  }    
+  }
 
   return (0);
 }