Simplify dodir/addir/addfold (patch from Eric Gillespie)
[mmh] / uip / folder.c
index 7706f90..a0821c2 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <h/mh.h>
+#include <h/utils.h>
 #include <errno.h>
 
 static struct swit switches[] = {
@@ -66,8 +67,6 @@ static struct swit switches[] = {
     { NULL, 0 }
 };
 
-extern int errno;
-
 static int fshort   = 0;       /* output only folder names                 */
 static int fcreat   = 0;       /* should we ask to create new folders?     */
 static int fpack    = 0;       /* are we packing the folder?               */
@@ -122,7 +121,6 @@ static int maxFolderInfo;
 static void dodir (char *);
 static int get_folder_info (char *, char *);
 static void print_folders (void);
-static int num_digits (int);
 static int sfold (struct msgs *, char *);
 static void addir (char *);
 static void addfold (char *);
@@ -137,7 +135,6 @@ main (int argc, char **argv)
     int pushsw = 0, popsw = 0;
     char *cp, *dp, *msg = NULL, *argfolder = NULL;
     char **ap, **argp, buf[BUFSIZ], **arguments;
-    struct stat st;
 
 #ifdef LOCALE
     setlocale(LC_ALL, "");
@@ -262,7 +259,7 @@ main (int argc, char **argv)
            if (argfolder)
                adios (NULL, "only one folder at a time!");
            else
-               argfolder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
+               argfolder = pluspath (cp);
        } else {
            if (msg)
                adios (NULL, "only one (current) message at a time!");
@@ -355,13 +352,11 @@ main (int argc, char **argv)
 
     /* Allocate initial space to record folder names */
     maxfolders = NUMFOLDERS;
-    if ((folds = malloc (maxfolders * sizeof(char *))) == NULL)
-       adios (NULL, "unable to allocate storage for folder names");
+    folds = mh_xmalloc (maxfolders * sizeof(char *));
 
     /* Allocate initial space to record folder information */
     maxFolderInfo = NUMFOLDERS;
-    if ((fi = malloc (maxFolderInfo * sizeof(*fi))) == NULL)
-       adios (NULL, "unable to allocate storage for folder info");
+    fi = mh_xmalloc (maxFolderInfo * sizeof(*fi));
 
     /*
      * Scan the folders
@@ -396,22 +391,7 @@ main (int argc, char **argv)
         * Check if folder exists.  If not, then see if
         * we should create it, or just exit.
         */
-       if (stat (strncpy (buf, m_maildir (folder), sizeof(buf)), &st) == -1) {
-           if (errno != ENOENT)
-               adios (buf, "error on folder");
-           if (fcreat == 0) {
-               /* ask before creating folder */
-               cp = concat ("Create folder \"", buf, "\"? ", NULL);
-               if (!getanswer (cp))
-                   done (1);
-               free (cp);
-           } else if (fcreat == -1) {
-               /* do not create, so exit */
-               done (1);
-           }
-           if (!makedir (buf))
-               adios (NULL, "unable to create folder %s", buf);
-       }
+        create_folder (m_maildir (folder), fcreat, done);
 
        if (get_folder_info (folder, msg) && argfolder) {
            /* update current folder */
@@ -425,7 +405,8 @@ main (int argc, char **argv)
     print_folders();
 
     context_save ();   /* save the context file */
-    return done (0);
+    done (0);
+    return 1;
 }
 
 /*
@@ -438,7 +419,6 @@ dodir (char *dir)
     int i;
     int os = start;
     int of = foldp;
-    char buffer[BUFSIZ];
 
     start = foldp;
 
@@ -446,7 +426,7 @@ dodir (char *dir)
     if (chdir (nmhdir) == NOTOK)
        adios (nmhdir, "unable to change directory to");
 
-    addir (strncpy (buffer, dir, sizeof(buffer)));
+    addir (dir);
 
     for (i = start; i < foldp; i++) {
        get_folder_info (folds[i], NULL);
@@ -472,8 +452,7 @@ get_folder_info (char *fold, char *msg)
      */
     if (total_folders >= maxFolderInfo) {
        maxFolderInfo += NUMFOLDERS;
-       if ((fi = realloc (fi, maxFolderInfo * sizeof(*fi))) == NULL)
-           adios (NULL, "unable to re-allocate storage for folder info");
+       fi = mh_xrealloc (fi, maxFolderInfo * sizeof(*fi));
     }
 
     fi[i].name   = fold;
@@ -660,29 +639,6 @@ print_folders (void)
 }
 
 /*
- * Calculate the number of digits in a nonnegative integer
- */
-int
-num_digits (int n)
-{
-    int ndigits = 0;
-
-    /* Sanity check */
-    if (n < 0)
-       adios (NULL, "oops, num_digits called with negative value");
-
-    if (n == 0)
-       return 1;
-
-    while (n) {
-       n /= 10;
-       ndigits++;
-    }
-
-    return ndigits;
-}
-
-/*
  * Set the current message and sychronize sequences
  */
 
@@ -710,21 +666,11 @@ static void
 addir (char *name)
 {
     int nlink;
-    char *base, *cp;
+    char *prefix, *child;
     struct stat st;
     struct dirent *dp;
     DIR * dd;
 
-    cp = name + strlen (name);
-    *cp++ = '/';
-    *cp = '\0';
-
-    /*
-     * A hack to skip over a leading
-     * "./" in folder names.
-     */
-    base = strcmp (name, "./") ? name : name + 2;
-
    /* short-cut to see if directory has any sub-directories */
     if (stat (name, &st) != -1 && st.st_nlink == 2)
         return;
@@ -734,6 +680,12 @@ addir (char *name)
        return;
     }
 
+    if (strcmp (name, ".") == 0) {
+       prefix = getcpy ("");
+    } else {
+       prefix = concat (name, "/", (void *)NULL);
+    }
+
     /*
      * Keep track of the number of directories we've seen
      * so we can quit stat'ing early, if we've seen them all.
@@ -745,22 +697,23 @@ addir (char *name)
            nlink--;
            continue;
        }
-       if (cp + NLENGTH(dp) + 2 >= name + BUFSIZ)
-           continue;
-       strcpy (cp, dp->d_name);
-       if (stat (name, &st) != -1 && S_ISDIR(st.st_mode)) {
+       child = concat (prefix, dp->d_name, (void *)NULL);
+       if (stat (child, &st) != -1 && S_ISDIR(st.st_mode)) {
            /*
             * Check if this was really a symbolic link pointing at
             * a directory.  If not, then decrement link count.
             */
-           if (lstat (name, &st) == -1)
+           if (lstat (child, &st) == -1)
                nlink--;
-           addfold (base);
+           /* addfold saves child in the list, don't free it */
+           addfold (child);
+       } else {
+           free (child);
        }
     }
 
     closedir (dd);
-    *--cp = '\0';
+    free(prefix);
 }
 
 /*
@@ -772,26 +725,23 @@ static void
 addfold (char *fold)
 {
     register int i, j;
-    register char *cp;
 
     /* if necessary, reallocate the space for folder names */
     if (foldp >= maxfolders) {
        maxfolders += NUMFOLDERS;
-       if ((folds = realloc (folds, maxfolders * sizeof(char *))) == NULL)
-           adios (NULL, "unable to re-allocate storage for folder names");
+       folds = mh_xrealloc (folds, maxfolders * sizeof(char *));
     }
 
-    cp = getcpy (fold);
     for (i = start; i < foldp; i++)
-       if (compare (cp, folds[i]) < 0) {
+       if (compare (fold, folds[i]) < 0) {
            for (j = foldp - 1; j >= i; j--)
                folds[j + 1] = folds[j];
            foldp++;
-           folds[i] = cp;
+           folds[i] = fold;
            return;
        }
 
-    folds[foldp++] = cp;
+    folds[foldp++] = fold;
 }