X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Ffolder.c;h=f83bedcab0b4f83bf433f90cf1c06f502f280e8e;hp=3348ae56b90dc6b47e3299cece827ce496e30545;hb=d8916ff5d389de5ab225cd6f40aeda1b285d0f28;hpb=81a21a9a97d8633f6d6231e31fdb6e328d0d3ff2 diff --git a/uip/folder.c b/uip/folder.c index 3348ae5..f83bedc 100644 --- a/uip/folder.c +++ b/uip/folder.c @@ -6,12 +6,13 @@ * * $Id$ * - * This code is Copyright (c) 2002, by the authors of nmh. See the + * This code is Copyright (c) 2002, 2008, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for * complete copyright information. */ #include +#include #include #include @@ -78,22 +79,10 @@ static int all = 0; /* should we output all folders */ static int total_folders = 0; /* total number of folders */ -static int start = 0; -static int foldp = 0; - static char *nmhdir; static char *stack = "Folder-Stack"; static char folder[BUFSIZ]; -#define NUMFOLDERS 100 - -/* - * This is how many folders we currently can hold in the array - * `folds'. We increase this amount by NUMFOLDERS at a time. - */ -static int maxfolders; -static char **folds; - /* * Structure to hold information about * folders as we scan them. @@ -118,14 +107,10 @@ static int maxFolderInfo; /* * static prototypes */ -static void dodir (char *); static int get_folder_info (char *, char *); +static crawl_callback_t get_folder_info_callback; static void print_folders (void); -static int num_digits (int); static int sfold (struct msgs *, char *); -static void addir (char *); -static void addfold (char *); -static int compare (char *, char *); static void readonly_folders (void); @@ -136,7 +121,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, ""); @@ -261,7 +245,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!"); @@ -352,12 +336,8 @@ main (int argc, char **argv) done (0); } - /* Allocate initial space to record folder names */ - maxfolders = NUMFOLDERS; - folds = mh_xmalloc (maxfolders * sizeof(char *)); - /* Allocate initial space to record folder information */ - maxFolderInfo = NUMFOLDERS; + maxFolderInfo = CRAWL_NUMFOLDERS; fi = mh_xmalloc (maxFolderInfo * sizeof(*fi)); /* @@ -367,12 +347,15 @@ main (int argc, char **argv) /* * If no folder is given, do them all */ + /* change directory to base of nmh directory for crawl_folders */ + if (chdir (nmhdir) == NOTOK) + adios (nmhdir, "unable to change directory to"); if (!argfolder) { if (msg) admonish (NULL, "no folder given for message %s", msg); readonly_folders (); /* do any readonly folders */ strncpy (folder, (cp = context_find (pfolder)) ? cp : "", sizeof(folder)); - dodir ("."); + crawl_folders (".", get_folder_info_callback, NULL); } else { strncpy (folder, argfolder, sizeof(folder)); if (get_folder_info (argfolder, msg)) { @@ -384,7 +367,7 @@ main (int argc, char **argv) * we still need to list all level-1 sub-folders. */ if (!frecurse) - dodir (folder); + crawl_folders (folder, get_folder_info_callback, NULL); } } else { strncpy (folder, argfolder ? argfolder : getfolder (1), sizeof(folder)); @@ -393,22 +376,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 */ @@ -422,43 +390,14 @@ main (int argc, char **argv) print_folders(); context_save (); /* save the context file */ - return done (0); -} - -/* - * Base routine for scanning a folder - */ - -static void -dodir (char *dir) -{ - int i; - int os = start; - int of = foldp; - char buffer[BUFSIZ]; - - start = foldp; - - /* change directory to base of nmh directory */ - if (chdir (nmhdir) == NOTOK) - adios (nmhdir, "unable to change directory to"); - - addir (strncpy (buffer, dir, sizeof(buffer))); - - for (i = start; i < foldp; i++) { - get_folder_info (folds[i], NULL); - fflush (stdout); - } - - start = os; - foldp = of; + done (0); + return 1; } static int -get_folder_info (char *fold, char *msg) +get_folder_info_body (char *fold, char *msg, boolean *crawl_children) { int i, retval = 1; - char *mailfile; struct msgs *mp = NULL; i = total_folders++; @@ -468,9 +407,8 @@ get_folder_info (char *fold, char *msg) * for folder information */ if (total_folders >= maxFolderInfo) { - maxFolderInfo += NUMFOLDERS; - if ((fi = realloc (fi, maxFolderInfo * sizeof(*fi))) == NULL) - adios (NULL, "unable to re-allocate storage for folder info"); + maxFolderInfo += CRAWL_NUMFOLDERS; + fi = mh_xrealloc (fi, maxFolderInfo * sizeof(*fi)); } fi[i].name = fold; @@ -481,46 +419,64 @@ get_folder_info (char *fold, char *msg) fi[i].others = 0; fi[i].error = 0; - mailfile = m_maildir (fold); + if ((ftotal > 0) || !fshort || msg || fpack) { + /* + * create message structure and get folder info + */ + if (!(mp = folder_read (fold))) { + admonish (NULL, "unable to read folder %s", fold); + return 0; + } - if (!chdir (mailfile)) { - if ((ftotal > 0) || !fshort || msg || fpack) { - /* - * create message structure and get folder info - */ - if (!(mp = folder_read (fold))) { - admonish (NULL, "unable to read folder %s", fold); - return 0; - } + /* set the current message */ + if (msg && !sfold (mp, msg)) + retval = 0; - /* set the current message */ - if (msg && !sfold (mp, msg)) - retval = 0; + if (fpack) { + if (folder_pack (&mp, fverb) == -1) + done (1); + seq_save (mp); /* synchronize the sequences */ + context_save (); /* save the context file */ + } - if (fpack) { - if (folder_pack (&mp, fverb) == -1) - done (1); - seq_save (mp); /* synchronize the sequences */ - context_save (); /* save the context file */ - } + /* record info for this folder */ + if ((ftotal > 0) || !fshort) { + fi[i].nummsg = mp->nummsg; + fi[i].curmsg = mp->curmsg; + fi[i].lowmsg = mp->lowmsg; + fi[i].hghmsg = mp->hghmsg; + fi[i].others = other_files (mp); + } - /* record info for this folder */ - if ((ftotal > 0) || !fshort) { - fi[i].nummsg = mp->nummsg; - fi[i].curmsg = mp->curmsg; - fi[i].lowmsg = mp->lowmsg; - fi[i].hghmsg = mp->hghmsg; - fi[i].others = other_files (mp); - } + folder_free (mp); /* free folder/message structure */ + } - folder_free (mp); /* free folder/message structure */ - } - } else { - fi[i].error = 1; + *crawl_children = (frecurse && (fshort || fi[i].others) + && (fi[i].error == 0)); + return retval; +} + +static boolean +get_folder_info_callback (char *fold, void *baton) +{ + boolean crawl_children; + get_folder_info_body (fold, NULL, &crawl_children); + fflush (stdout); + return crawl_children; +} + +static int +get_folder_info (char *fold, char *msg) +{ + boolean crawl_children; + int retval; + + retval = get_folder_info_body (fold, msg, &crawl_children); + + if (crawl_children) { + crawl_folders (fold, get_folder_info_callback, NULL); } - if (frecurse && (fshort || fi[i].others) && (fi[i].error == 0)) - dodir (fold); return retval; } @@ -657,29 +613,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 */ @@ -703,107 +636,6 @@ sfold (struct msgs *mp, char *msg) } -static void -addir (char *name) -{ - int nlink; - char *base, *cp; - 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; - - if (!(dd = opendir (name))) { - admonish (name, "unable to read directory "); - return; - } - - /* - * Keep track of the number of directories we've seen - * so we can quit stat'ing early, if we've seen them all. - */ - nlink = st.st_nlink; - - while (nlink && (dp = readdir (dd))) { - if (!strcmp (dp->d_name, ".") || !strcmp (dp->d_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)) { - /* - * Check if this was really a symbolic link pointing at - * a directory. If not, then decrement link count. - */ - if (lstat (name, &st) == -1) - nlink--; - addfold (base); - } - } - - closedir (dd); - *--cp = '\0'; -} - -/* - * Add the folder name into the - * list in a sorted fashion. - */ - -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"); - } - - cp = getcpy (fold); - for (i = start; i < foldp; i++) - if (compare (cp, folds[i]) < 0) { - for (j = foldp - 1; j >= i; j--) - folds[j + 1] = folds[j]; - foldp++; - folds[i] = cp; - return; - } - - folds[foldp++] = cp; -} - - -static int -compare (char *s1, char *s2) -{ - register int i; - - while (*s1 || *s2) - if ((i = *s1++ - *s2++)) - return i; - - return 0; -} - /* * Do the read only folders */