X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Ffolder.c;h=a94f1315ff94a83c5e9fe702280f2ced870f87f4;hp=7706f90f46ae7d11c4dca8679a804e4bf77f001e;hb=9be69008c0dd066816b4a9b04d47fade2282664a;hpb=5afa7072e3fe7fc42287e2149e1c23b363700795 diff --git a/uip/folder.c b/uip/folder.c index 7706f90..a94f131 100644 --- a/uip/folder.c +++ b/uip/folder.c @@ -12,6 +12,7 @@ */ #include +#include #include 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 @@ -370,6 +365,9 @@ main (int argc, char **argv) /* * If no folder is given, do them all */ + /* change directory to base of nmh directory for dodir */ + if (chdir (nmhdir) == NOTOK) + adios (nmhdir, "unable to change directory to"); if (!argfolder) { if (msg) admonish (NULL, "no folder given for message %s", msg); @@ -396,22 +394,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 +408,8 @@ main (int argc, char **argv) print_folders(); context_save (); /* save the context file */ - return done (0); + done (0); + return 1; } /* @@ -438,15 +422,10 @@ 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))); + addir (dir); for (i = start; i < foldp; i++) { get_folder_info (folds[i], NULL); @@ -461,7 +440,6 @@ static int get_folder_info (char *fold, char *msg) { int i, retval = 1; - char *mailfile; struct msgs *mp = NULL; i = total_folders++; @@ -472,8 +450,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; @@ -484,42 +461,36 @@ get_folder_info (char *fold, char *msg) fi[i].others = 0; fi[i].error = 0; - mailfile = m_maildir (fold); - - 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; + 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 (fpack) { - if (folder_pack (&mp, fverb) == -1) - done (1); - seq_save (mp); /* synchronize the sequences */ - context_save (); /* save the context file */ - } + /* set the current message */ + if (msg && !sfold (mp, msg)) + retval = 0; - /* 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); - } + if (fpack) { + if (folder_pack (&mp, fverb) == -1) + done (1); + seq_save (mp); /* synchronize the sequences */ + context_save (); /* save the context file */ + } - folder_free (mp); /* free folder/message structure */ + /* 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); } - } else { - fi[i].error = 1; + + folder_free (mp); /* free folder/message structure */ } if (frecurse && (fshort || fi[i].others) && (fi[i].error == 0)) @@ -660,29 +631,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 */ @@ -709,58 +657,53 @@ sfold (struct msgs *mp, char *msg) static void addir (char *name) { - int nlink; - char *base, *cp; + char *prefix, *child; struct stat st; struct dirent *dp; DIR * dd; + int child_is_folder; - 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; + if (strcmp (name, ".") == 0) { + prefix = getcpy (""); + } else { + prefix = concat (name, "/", (void *)NULL); + } - while (nlink && (dp = readdir (dd))) { - if (!strcmp (dp->d_name, ".") || !strcmp (dp->d_name, "..")) { - nlink--; + 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; } - if (cp + NLENGTH(dp) + 2 >= name + BUFSIZ) +#endif + if (!strcmp (dp->d_name, ".") || !strcmp (dp->d_name, "..")) { 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); + } + 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) { + /* addfold saves child in the list, don't free it */ + addfold (child); + } else { + free (child); } } closedir (dd); - *--cp = '\0'; + free(prefix); } /* @@ -772,26 +715,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; }