Add %(unmailto) format function for List-Post headers
[mmh] / sbr / crawl_folders.c
index 4889bf1..7164616 100644 (file)
-
 /*
- * crawl_folders.c -- crawl folder hierarchy
- *
- * $Id$
- *
- * This code is Copyright (c) 2008, by the authors of nmh.  See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
+** crawl_folders.c -- crawl folder hierarchy
+**
+** This code is Copyright (c) 2008, 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 <h/crawl_folders.h>
 #include <h/utils.h>
+#include <dirent.h>
+#include <sys/stat.h>
 
 struct crawl_context {
-    int max;                   /* how many folders we currently can hold in
-                                * the array `folders', increased by
-                                * CRAWL_NUMFOLDERS at a time */
-    int total;                 /* how many `folders' actually has */
-    char **folders;            /* the array of folders */
-    int start;
-    int foldp;
+       int max;    /*
+                   ** number of folders we can hold in the folders array;
+                   ** increased by CRAWL_NUMFOLDERS at a time
+                   */
+       int total;  /* how many `folders' actually has */
+       char **folders;  /* the array of folders */
+       int start;
+       int foldp;
 };
 
 /*
- * Add the folder name into the
- * list in a sorted fashion.
- */
+** Add the folder name into the
+** list in a sorted fashion.
+*/
 
 static void
-add_folder (char *fold, struct crawl_context *crawl)
+add_folder(char *fold, struct crawl_context *crawl)
 {
-    register int i, j;
-
-    /* if necessary, reallocate the space for folder names */
-    if (crawl->foldp >= crawl->max) {
-       crawl->max += CRAWL_NUMFOLDERS;
-       crawl->folders = mh_xrealloc (crawl->folders,
-                                     crawl->max * sizeof(char *));
-    }
-
-    for (i = crawl->start; i < crawl->foldp; i++)
-       if (strcmp (fold, crawl->folders[i]) < 0) {
-           for (j = crawl->foldp - 1; j >= i; j--)
-               crawl->folders[j + 1] = crawl->folders[j];
-           crawl->foldp++;
-           crawl->folders[i] = fold;
-           return;
+       int i, j;
+
+       /* if necessary, reallocate the space for folder names */
+       if (crawl->foldp >= crawl->max) {
+               crawl->max += CRAWL_NUMFOLDERS;
+               crawl->folders = mh_xrealloc(crawl->folders,
+                       crawl->max * sizeof(char *));
        }
 
-    crawl->total++;
-    crawl->folders[crawl->foldp++] = fold;
+       for (i = crawl->start; i < crawl->foldp; i++)
+               if (strcmp(fold, crawl->folders[i]) < 0) {
+                       for (j = crawl->foldp - 1; j >= i; j--)
+                               crawl->folders[j + 1] = crawl->folders[j];
+                       crawl->foldp++;
+                       crawl->folders[i] = fold;
+                       return;
+               }
+
+       crawl->total++;
+       crawl->folders[crawl->foldp++] = fold;
 }
 
 static void
-add_children (char *name, struct crawl_context *crawl)
+add_children(char *name, struct crawl_context *crawl)
 {
-    char *prefix, *child;
-    struct stat st;
-    struct dirent *dp;
-    DIR * dd;
-    int child_is_folder;
-
-    if (!(dd = opendir (name))) {
-       admonish (name, "unable to read directory ");
-       return;
-    }
-
-    if (strcmp (name, ".") == 0) {
-       prefix = getcpy ("");
-    } else {
-       prefix = concat (name, "/", (void *)NULL);
-    }
-
-    while ((dp = readdir (dd))) {
-       /* If the system supports it, try to skip processing of children we
-        * know are not directories or symlinks. */
-       child_is_folder = -1;
-#if defined(HAVE_STRUCT_DIRENT_D_TYPE)
-       if (dp->d_type == DT_DIR) {
-           child_is_folder = 1;
-       } else if (dp->d_type != DT_LNK && dp->d_type != DT_UNKNOWN) {
-           continue;
+       char *prefix, *child;
+       struct stat st;
+       struct dirent *dp;
+       DIR * dd;
+       int child_is_folder;
+
+       if (!(dd = opendir(name))) {
+               admonish(name, "unable to read directory ");
+               return;
        }
-#endif
-       if (!strcmp (dp->d_name, ".") || !strcmp (dp->d_name, "..")) {
-           continue;
-       }
-       child = concat (prefix, dp->d_name, (void *)NULL);
-       /* If we have no d_type or d_type is DT_LNK or DT_UNKNOWN, stat the
-        * child to see what it is. */
-       if (child_is_folder == -1) {
-           child_is_folder = (stat (child, &st) != -1 && S_ISDIR(st.st_mode));
-       }
-       if (child_is_folder) {
-           /* add_folder saves child in the list, don't free it */
-           add_folder (child, crawl);
+
+       if (strcmp(name, ".") == 0) {
+               prefix = mh_xstrdup("");
        } else {
-           free (child);
+               prefix = concat(name, "/", (void *)NULL);
        }
-    }
 
-    closedir (dd);
-    free(prefix);
+       while ((dp = readdir(dd))) {
+               /*
+               ** If the system supports it, try to skip processing of
+               ** children we know are not directories or symlinks.
+               */
+               child_is_folder = -1;
+#if defined(HAVE_STRUCT_DIRENT_D_TYPE)
+               if (dp->d_type == DT_DIR) {
+                       child_is_folder = 1;
+               } else if (dp->d_type != DT_LNK && dp->d_type != DT_UNKNOWN) {
+                       continue;
+               }
+#endif
+               if (strcmp(dp->d_name, ".")==0 ||
+                               strcmp(dp->d_name, "..")==0) {
+                       continue;
+               }
+               child = concat(prefix, dp->d_name, (void *)NULL);
+               /*
+               ** If we have no d_type or d_type is DT_LNK or DT_UNKNOWN,
+               ** stat the child to see what it is.
+               */
+               if (child_is_folder == -1) {
+                       child_is_folder = (stat(child, &st) != -1 && S_ISDIR(st.st_mode));
+               }
+               if (child_is_folder) {
+                       /* add_folder saves child in the list, don't free it */
+                       add_folder(child, crawl);
+               } else {
+                       mh_free0(&child);
+               }
+       }
+
+       closedir(dd);
+       mh_free0(&prefix);
 }
 
 static void
-crawl_folders_body (struct crawl_context *crawl,
-                   char *dir, crawl_callback_t *callback, void *baton)
+crawl_folders_body(struct crawl_context *crawl, char *dir,
+       crawl_callback_t *callback, void *baton)
 {
-    int i;
-    int os = crawl->start;
-    int of = crawl->foldp;
+       int i;
+       int os = crawl->start;
+       int of = crawl->foldp;
 
-    crawl->start = crawl->foldp;
+       crawl->start = crawl->foldp;
 
-    add_children (dir, crawl);
+       add_children(dir, crawl);
 
-    for (i = crawl->start; i < crawl->foldp; i++) {
-       char *fold = crawl->folders[i];
-       int crawl_children = 1;
+       for (i = crawl->start; i < crawl->foldp; i++) {
+               char *fold = crawl->folders[i];
+               int crawl_children = 1;
 
-       if (callback != NULL) {
-           crawl_children = callback (fold, baton);
-       }
+               if (callback != NULL) {
+                       crawl_children = callback(fold, baton);
+               }
 
-       if (crawl_children) {
-           crawl_folders_body (crawl, fold, callback, baton);
+               if (crawl_children) {
+                       crawl_folders_body(crawl, fold, callback, baton);
+               }
        }
-    }
 
-    crawl->start = os;
-    crawl->foldp = of;
+       crawl->start = os;
+       crawl->foldp = of;
 }
 
 void
-crawl_folders (char *dir, crawl_callback_t *callback, void *baton)
+crawl_folders(char *dir, crawl_callback_t *callback, void *baton)
 {
-    struct crawl_context *crawl = mh_xmalloc (sizeof(*crawl));
-    crawl->max = CRAWL_NUMFOLDERS;
-    crawl->total = crawl->start = crawl->foldp = 0;
-    crawl->folders = mh_xmalloc (crawl->max * sizeof(*crawl->folders));
-
-    crawl_folders_body (crawl, dir, callback, baton);
-
-    /* Note that we "leak" the folder names, on the assumption that the caller
-     * is using them. */
-    free (crawl->folders);
-    free (crawl);
+       struct crawl_context *crawl = mh_xcalloc(1, sizeof(*crawl));
+       crawl->max = CRAWL_NUMFOLDERS;
+       crawl->total = crawl->start = crawl->foldp = 0;
+       crawl->folders = mh_xcalloc(crawl->max, sizeof(*crawl->folders));
+
+       crawl_folders_body(crawl, dir, callback, baton);
+
+       /*
+       ** Note that we "leak" the folder names, on the assumption that the
+       ** caller is using them.
+       */
+       mh_free0(&(crawl->folders));
+       mh_free0(&crawl);
 }