X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fflist.c;h=71ae8e85aba5e26e51c9d1a0ff9e861c286d39ff;hp=0e2b16145a2deab0272e7de2639e7f1249f7dc70;hb=32b2354dbaf4bf934936eb5b102a4a3d2fdd209a;hpb=1691e80890e5d8ba258c51c214a3e91880e1db2b diff --git a/uip/flist.c b/uip/flist.c index 0e2b161..71ae8e8 100644 --- a/uip/flist.c +++ b/uip/flist.c @@ -1,81 +1,77 @@ /* - * flist.c -- list nmh folders containing messages - * -- in a given sequence - * - * originally by - * David Nichols, Xerox-PARC, November, 1992 - * - * Copyright (c) 1994 Xerox Corporation. - * Use and copying of this software and preparation of derivative works based - * upon this software are permitted. Any distribution of this software or - * derivative works must comply with all applicable United States export - * control laws. This software is made available AS IS, and Xerox Corporation - * makes no warranty about the software, its performance or its conformity to - * any specification. - * - * $Id$ - */ +** flist.c -- list nmh folders containing messages +** -- in a given sequence +** +** originally by +** David Nichols, Xerox-PARC, November, 1992 +** +** Copyright (c) 1994 Xerox Corporation. +** Use and copying of this software and preparation of derivative works based +** upon this software are permitted. Any distribution of this software or +** derivative works must comply with all applicable United States export +** control laws. This software is made available AS IS, and Xerox Corporation +** makes no warranty about the software, its performance or its conformity to +** any specification. +*/ #include - -#define FALSE 0 -#define TRUE 1 +#include /* - * We allocate space to record the names of folders - * (foldersToDo array), this number of elements at a time. - */ +** We allocate space to record the names of folders +** (foldersToDo array), this number of elements at a time. +*/ #define MAXFOLDERS 100 static struct swit switches[] = { -#define SEQSW 0 - { "sequence name", 0 }, -#define ALLSW 1 - { "all", 0 }, -#define NOALLSW 2 - { "noall", 0 }, -#define RECURSE 3 - { "recurse", 0 }, -#define NORECURSE 4 - { "norecurse", 0 }, -#define SHOWZERO 5 - { "showzero", 0 }, -#define NOSHOWZERO 6 - { "noshowzero", 0 }, -#define ALPHASW 7 - { "alpha", 0 }, -#define NOALPHASW 8 - { "noalpha", 0 }, -#define FASTSW 9 - { "fast", 0 }, -#define NOFASTSW 10 - { "nofast", 0 }, -#define TOTALSW 11 - { "total", -5 }, -#define NOTOTALSW 12 - { "nototal", -7 }, -#define VERSIONSW 13 - { "version", 0 }, -#define HELPSW 14 - { "help", 4 }, - { NULL, 0 } +#define SEQSW 0 + { "sequence name", 0 }, +#define ALLSW 1 + { "all", 0 }, +#define NOALLSW 2 + { "noall", 0 }, +#define RECURSE 3 + { "recurse", 0 }, +#define NORECURSE 4 + { "norecurse", 0 }, +#define SHOWZERO 5 + { "showzero", 0 }, +#define NOSHOWZERO 6 + { "noshowzero", 0 }, +#define ALPHASW 7 + { "alpha", 0 }, +#define NOALPHASW 8 + { "noalpha", 0 }, +#define FASTSW 9 + { "fast", 0 }, +#define NOFASTSW 10 + { "nofast", 0 }, +#define TOTALSW 11 + { "total", -5 }, +#define NOTOTALSW 12 + { "nototal", -7 }, +#define VERSIONSW 13 + { "Version", 0 }, +#define HELPSW 14 + { "help", 0 }, + { NULL, 0 } }; struct Folder { - char *name; /* name of folder */ - int priority; - int error; /* error == 1 for unreadable folder */ - int nMsgs; /* number of messages in folder */ - int nSeq[NUMATTRS]; /* number of messages in each sequence */ - int private[NUMATTRS]; /* is given sequence, public or private */ + char *name; /* name of folder */ + int priority; + int error; /* error == 1 for unreadable folder */ + int nMsgs; /* number of messages in folder */ + int nSeq[NUMATTRS]; /* number of messages in each sequence */ + int private[NUMATTRS]; /* is given sequence, public or private */ }; static struct Folder *orders = NULL; static int nOrders = 0; static int nOrdersAlloced = 0; static struct Folder *folders = NULL; -static int nFolders = 0; +static unsigned int nFolders = 0; static int nFoldersAlloced = 0; /* info on folders to search */ @@ -85,27 +81,27 @@ static int maxfolders; /* info on sequences to search for */ static char *sequencesToDo[NUMATTRS]; -static int numsequences; +static unsigned int numsequences; -static int all = FALSE; /* scan all folders in top level? */ -static int alphaOrder = FALSE; /* want alphabetical order only */ -static int recurse = FALSE; /* show nested folders? */ -static int showzero = TRUE; /* show folders even if no messages in seq? */ -static int Total = TRUE; /* display info on number of messages in * - * sequence found, and total num messages */ +static int all = FALSE; /* scan all folders in top level? */ +static int alphaOrder = FALSE; /* want alphabetical order only */ +static int recurse = FALSE; /* show nested folders? */ +static int showzero = TRUE; /* show folders even if no messages in seq? */ +static int Total = TRUE; /* display info on number of messages in + * sequence found, and total num messages */ -static char curfolder[BUFSIZ]; /* name of the current folder */ -static char *nmhdir; /* base nmh mail directory */ +static char curfol[BUFSIZ]; /* name of the current folder */ +static char *nmhdir; /* base nmh mail directory */ /* - * Type for a compare function for qsort. This keeps - * the compiler happy. - */ +** Type for a compare function for qsort. This keeps +** the compiler happy. +*/ typedef int (*qsort_comp) (const void *, const void *); /* - * prototypes - */ +** prototypes +*/ int CompareFolders(struct Folder *, struct Folder *); void GetFolderOrder(void); void ScanFolders(void); @@ -113,7 +109,6 @@ int AddFolder(char *, int); void BuildFolderList(char *, int); void BuildFolderListRecurse(char *, struct stat *, int); void PrintFolders(void); -static int num_digits (int); void AllocFolders(struct Folder **, int *, int); int AssignPriority(char *); static void do_readonly_folders(void); @@ -123,587 +118,576 @@ static void do_readonly_folders(void); int main(int argc, char **argv) { - char *cp, **argp; - char **arguments; - char buf[BUFSIZ]; + char *cp, **argp; + char **arguments; + char buf[BUFSIZ]; #ifdef LOCALE - setlocale(LC_ALL, ""); + setlocale(LC_ALL, ""); #endif - invo_name = r1bindex(argv[0], '/'); - - /* read user profile/context */ - context_read(); - - /* - * If program was invoked with name ending - * in `s', then add switch `-all'. - */ - if (argv[0][strlen (argv[0]) - 1] == 's') - all = TRUE; - - arguments = getarguments (invo_name, argc, argv, 1); - argp = arguments; - - /* allocate the initial space to record the folder names */ - numfolders = 0; - maxfolders = MAXFOLDERS; - if (!(foldersToDo = (char **) malloc ((size_t) (maxfolders * sizeof(*foldersToDo))))) - adios (NULL, "unable to allocate folder storage"); - - /* no sequences yet */ - numsequences = 0; - - /* parse arguments */ - while ((cp = *argp++)) { - if (*cp == '-') { - switch (smatch(++cp, switches)) { - case AMBIGSW: - ambigsw(cp, switches); - done(1); - case UNKWNSW: - adios(NULL, "-%s unknown", cp); - - case HELPSW: - snprintf(buf, sizeof(buf), "%s [+folder1 [+folder2 ...]][switches]", - invo_name); - print_help(buf, switches, 1); - done(1); - case VERSIONSW: - print_version(invo_name); - done (1); - - case SEQSW: - if (!(cp = *argp++) || *cp == '-') - adios (NULL, "missing argument to %s", argp[-2]); - - /* check if too many sequences specified */ - if (numsequences >= NUMATTRS) - adios (NULL, "too many sequences (more than %d) specified", NUMATTRS); - sequencesToDo[numsequences++] = cp; - break; - - case ALLSW: + invo_name = mhbasename(argv[0]); + + /* read user profile/context */ + context_read(); + + /* + ** If program was invoked with name ending + ** in `s', then add switch `-all'. + */ + if (argv[0][strlen(argv[0]) - 1] == 's') all = TRUE; - break; - case NOALLSW: - all = FALSE; - break; - - case SHOWZERO: - showzero = TRUE; - break; - case NOSHOWZERO: - showzero = FALSE; - break; - - case ALPHASW: - alphaOrder = TRUE; - break; - case NOALPHASW: - alphaOrder = FALSE; - break; - - case NOFASTSW: - case TOTALSW: - Total = TRUE; - break; - - case FASTSW: - case NOTOTALSW: - Total = FALSE; - break; - - case RECURSE: - recurse = TRUE; - break; - case NORECURSE: - recurse = FALSE; - break; - } - } else { - /* - * Check if we need to allocate more space - * for folder names. - */ - if (numfolders >= maxfolders) { - maxfolders += MAXFOLDERS; - if (!(foldersToDo = (char **) realloc (foldersToDo, - (size_t) (maxfolders * sizeof(*foldersToDo))))) - adios (NULL, "unable to reallocate folder name storage"); - } - if (*cp == '+') - ++cp; - foldersToDo[numfolders++] = cp; + + arguments = getarguments(invo_name, argc, argv, 1); + argp = arguments; + + /* allocate the initial space to record the folder names */ + numfolders = 0; + maxfolders = MAXFOLDERS; + foldersToDo = (char **) mh_xmalloc((size_t) + (maxfolders * sizeof(*foldersToDo))); + + /* no sequences yet */ + numsequences = 0; + + /* parse arguments */ + while ((cp = *argp++)) { + if (*cp == '-') { + switch (smatch(++cp, switches)) { + case AMBIGSW: + ambigsw(cp, switches); + done(1); + case UNKWNSW: + adios(NULL, "-%s unknown", cp); + + case HELPSW: + snprintf(buf, sizeof(buf), "%s [+folder1 [+folder2 ...]][switches]", invo_name); + print_help(buf, switches, 1); + done(1); + case VERSIONSW: + print_version(invo_name); + done(1); + + case SEQSW: + if (!(cp = *argp++) || *cp == '-') + adios(NULL, "missing argument to %s", + argp[-2]); + + /* check if too many sequences specified */ + if (numsequences >= NUMATTRS) + adios(NULL, "too many sequences (more than %d) specified", NUMATTRS); + sequencesToDo[numsequences++] = cp; + break; + + case ALLSW: + all = TRUE; + break; + case NOALLSW: + all = FALSE; + break; + + case SHOWZERO: + showzero = TRUE; + break; + case NOSHOWZERO: + showzero = FALSE; + break; + + case ALPHASW: + alphaOrder = TRUE; + break; + case NOALPHASW: + alphaOrder = FALSE; + break; + + case NOFASTSW: + case TOTALSW: + Total = TRUE; + break; + + case FASTSW: + case NOTOTALSW: + Total = FALSE; + break; + + case RECURSE: + recurse = TRUE; + break; + case NORECURSE: + recurse = FALSE; + break; + } + } else { + /* + ** Check if we need to allocate more space + ** for folder names. + */ + if (numfolders >= maxfolders) { + maxfolders += MAXFOLDERS; + foldersToDo = (char **) mh_xrealloc(foldersToDo, (size_t) (maxfolders * sizeof(*foldersToDo))); + } + if (*cp == '+' || *cp == '@') { + foldersToDo[numfolders++] = getcpy(expandfol(cp)); + } else + foldersToDo[numfolders++] = cp; + } } - } - - if (!context_find ("path")) - free (path ("./", TFOLDER)); - - /* get current folder */ - strncpy (curfolder, getfolder(1), sizeof(curfolder)); - - /* get nmh base directory */ - nmhdir = m_maildir (""); - - /* - * If we didn't specify any sequences, we search - * for the "Unseen-Sequence" profile entry and use - * all the sequences defined there. We check to - * make sure that the Unseen-Sequence entry doesn't - * contain more than NUMATTRS sequences. - */ - if (numsequences == 0) { - if ((cp = context_find(usequence)) && *cp) { - char **ap, *dp; - - dp = getcpy(cp); - ap = brkstring (dp, " ", "\n"); - for (; ap && *ap; ap++) { - if (numsequences >= NUMATTRS) - adios (NULL, "too many sequences (more than %d) in %s profile entry", - NUMATTRS, usequence); - else - sequencesToDo[numsequences++] = *ap; - } - } else { - adios (NULL, "no sequence specified or %s profile entry found", usequence); + + /* get current folder */ + strncpy(curfol, getcurfol(), sizeof(curfol)); + + /* get nmh base directory */ + nmhdir = toabsdir("+"); + + /* + ** If no sequences specified, we use the `unseen' sequence(s) + ** We check to make sure that the Unseen-Sequence entry doesn't + ** contain too many sequences. + */ + if (numsequences == 0) { + char **ap, *dp; + + if ((cp = context_find(usequence))) { + if (!*cp) { + adios(NULL, "profile entry %s set, but empty, and no sequence given", usequence); + } + } else { + cp = seq_unseen; /* use default */ + } + dp = getcpy(cp); + ap = brkstring(dp, " ", "\n"); + for (; ap && *ap; ap++) { + if (numsequences >= NUMATTRS) { + adios(NULL, "too many sequences (more than %d) in %s profile entry", NUMATTRS, usequence); + } else { + sequencesToDo[numsequences++] = *ap; + } + } } - } - GetFolderOrder(); - ScanFolders(); - qsort(folders, nFolders, sizeof(struct Folder), (qsort_comp) CompareFolders); - PrintFolders(); - done (0); + GetFolderOrder(); + ScanFolders(); + qsort(folders, nFolders, sizeof(struct Folder), + (qsort_comp) CompareFolders); + PrintFolders(); + done(0); + return 1; } /* - * Read the Flist-Order profile entry to determine - * how to sort folders for output. - */ +** Read the Flist-Order profile entry to determine +** how to sort folders for output. +*/ void GetFolderOrder(void) { - char *p, *s; - int priority = 1; - struct Folder *o; - - if (!(p = context_find("Flist-Order"))) - return; - for (;;) { - while (isspace(*p)) - ++p; - s = p; - while (*p && !isspace(*p)) - ++p; - if (p != s) { - /* Found one. */ - AllocFolders(&orders, &nOrdersAlloced, nOrders + 1); - o = &orders[nOrders++]; - o->priority = priority++; - o->name = (char *) malloc(p - s + 1); - strncpy(o->name, s, p - s); - o->name[p - s] = 0; - } else - break; - } + unsigned char *p, *s; + int priority = 1; + struct Folder *o; + + if (!(p = context_find("Flist-Order"))) + return; + for (;;) { + while (isspace(*p)) + ++p; + s = p; + while (*p && !isspace(*p)) + ++p; + if (p != s) { + /* Found one. */ + AllocFolders(&orders, &nOrdersAlloced, nOrders + 1); + o = &orders[nOrders++]; + o->priority = priority++; + o->name = (char *) mh_xmalloc(p - s + 1); + strncpy(o->name, s, p - s); + o->name[p - s] = 0; + } else + break; + } } /* - * Scan all the necessary folders - */ +** Scan all the necessary folders +*/ void ScanFolders(void) { - int i; - - /* - * change directory to base of nmh directory - */ - if (chdir (nmhdir) == NOTOK) - adios (nmhdir, "unable to change directory to"); - - if (numfolders > 0) { - /* Update context */ - strncpy (curfolder, foldersToDo[numfolders - 1], sizeof(curfolder)); - context_replace (pfolder, curfolder);/* update current folder */ - context_save (); /* save the context file */ + int i; /* - * Scan each given folder. If -all is given, - * then also scan the 1st level subfolders under - * each given folder. + * change directory to base of nmh directory */ - for (i = 0; i < numfolders; ++i) - BuildFolderList(foldersToDo[i], all ? 1 : 0); - } else { - if (all) { - /* - * Do the readonly folders - */ - do_readonly_folders(); - - /* - * Now scan the entire nmh directory for folders - */ - BuildFolderList(".", 0); + if (chdir(nmhdir) == NOTOK) + adios(nmhdir, "unable to change directory to"); + + if (numfolders > 0) { + /* Update context */ + strncpy(curfol, foldersToDo[numfolders - 1], sizeof(curfol)); + context_replace(curfolder, curfol); /* update current folder */ + context_save(); /* save the context file */ + + /* + ** Scan each given folder. If -all is given, + ** then also scan the 1st level subfolders under + ** each given folder. + */ + for (i = 0; i < numfolders; ++i) + BuildFolderList(foldersToDo[i], all ? 1 : 0); } else { - /* - * Else scan current folder - */ - BuildFolderList(curfolder, 0); + if (all) { + /* Do the readonly folders */ + do_readonly_folders(); + + /* Now scan the entire nmh directory for folders */ + BuildFolderList(".", 0); + } else { + /* Else scan current folder */ + BuildFolderList(curfol, 0); + } } - } } /* - * Initial building of folder list for - * the top of our search tree. - */ +** Initial building of folder list for +** the top of our search tree. +*/ void BuildFolderList(char *dirName, int searchdepth) { - struct stat st; - - /* Make sure we have a directory */ - if ((stat(dirName, &st) == -1) || !S_ISDIR(st.st_mode)) - return; - - /* - * If base directory, don't add it to the - * folder list. We just recurse into it. - */ - if (!strcmp (dirName, ".")) { - BuildFolderListRecurse (".", &st, 0); - return; - } - - /* - * Add this folder to the list. - * If recursing and directory has subfolders, - * then build folder list for subfolders. - */ - if (AddFolder(dirName, showzero) && (recurse || searchdepth) && st.st_nlink > 2) - BuildFolderListRecurse(dirName, &st, searchdepth - 1); + struct stat st; + + /* Make sure we have a directory */ + if ((stat(dirName, &st) == -1) || !S_ISDIR(st.st_mode)) + return; + + /* + ** If base directory, don't add it to the + ** folder list. We just recurse into it. + */ + if (strcmp(dirName, ".")==0) { + BuildFolderListRecurse(".", &st, 0); + return; + } + + /* + ** Add this folder to the list. + ** If recursing and directory has subfolders, + ** then build folder list for subfolders. + */ + if (AddFolder(dirName, showzero) && (recurse || searchdepth) && + st.st_nlink > 2) + BuildFolderListRecurse(dirName, &st, searchdepth - 1); } /* - * Recursive building of folder list - */ +** Recursive building of folder list +*/ void BuildFolderListRecurse(char *dirName, struct stat *s, int searchdepth) { - char *base, name[PATH_MAX]; - int nlinks; - DIR *dir; - struct dirent *dp; - struct stat st; - - /* - * Keep track of number of directories we've seen so we can - * stop stat'ing entries in this directory once we've seen - * them all. This optimization will fail if you have extra - * directories beginning with ".", since we don't bother to - * stat them. But that shouldn't generally be a problem. - */ - nlinks = s->st_nlink; - - if (!(dir = opendir(dirName))) - adios(dirName, "can't open directory"); - - /* - * A hack so that we don't see a - * leading "./" in folder names. - */ - base = strcmp (dirName, ".") ? dirName : dirName + 1; - - while (nlinks && (dp = readdir(dir))) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) { - nlinks--; - continue; - } - if (dp->d_name[0] == '.') - continue; - strncpy (name, base, sizeof(name) - 2); - if (*base) - strcat(name, "/"); - strncat(name, dp->d_name, sizeof(name) - strlen(name) - 1); - if ((stat(name, &st) != -1) && S_ISDIR(st.st_mode)) { - /* - * Check if this was really a symbolic link pointing - * to a directory. If not, then decrement link count. - */ - if (lstat (name, &st) == -1) - nlinks--; - /* Add this folder to the list */ - if (AddFolder(name, showzero) && - (recurse || searchdepth) && st.st_nlink > 2) - BuildFolderListRecurse(name, &st, searchdepth - 1); + char *base, name[PATH_MAX]; + unsigned char *n; + int nlinks; + DIR *dir; + struct dirent *dp; + struct stat st; + + /* + ** Keep track of number of directories we've seen so we can + ** stop stat'ing entries in this directory once we've seen + ** them all. This optimization will fail if you have extra + ** directories beginning with ".", since we don't bother to + ** stat them. But that shouldn't generally be a problem. + */ + nlinks = s->st_nlink; + + if (!(dir = opendir(dirName))) + adios(dirName, "can't open directory"); + + /* + ** A hack so that we don't see a + ** leading "./" in folder names. + */ + base = (strcmp(dirName, ".")==0) ? dirName + 1 : dirName; + + while (nlinks && (dp = readdir(dir))) { + if (strcmp(dp->d_name, ".")==0 || + strcmp(dp->d_name, "..")==0) { + nlinks--; + continue; + } + if (dp->d_name[0] == '.') + continue; + /* Check to see if the name of the file is a number + ** if it is, we assume it's a mail file and skip it + */ + for (n = dp->d_name; *n && isdigit(*n); n++); + if (!*n) + continue; + strncpy(name, base, sizeof(name) - 2); + if (*base) + strcat(name, "/"); + strncat(name, dp->d_name, sizeof(name) - strlen(name) - 1); + if ((stat(name, &st) != -1) && S_ISDIR(st.st_mode)) { + /* + ** Check if this was really a symbolic link pointing + ** to a directory. If not, then decrement link count. + */ + if (lstat(name, &st) == -1) + nlinks--; + /* Add this folder to the list */ + if (AddFolder(name, showzero) && + (recurse || searchdepth) && + st.st_nlink > 2) + BuildFolderListRecurse(name, &st, + searchdepth - 1); + } } - } - closedir(dir); + closedir(dir); } /* - * Add this folder to our list, counting the total number of - * messages and the number of messages in each sequence. - */ +** Add this folder to our list, counting the total number of +** messages and the number of messages in each sequence. +*/ int AddFolder(char *name, int force) { - int i, msgnum, nonzero; - int seqnum[NUMATTRS], nSeq[NUMATTRS]; - struct Folder *f; - struct msgs *mp; - - /* Read folder and create message structure */ - if (!(mp = folder_read (name))) { - /* Oops, error occurred. Record it and continue. */ - AllocFolders(&folders, &nFoldersAlloced, nFolders + 1); - f = &folders[nFolders++]; - f->name = getcpy(name); - f->error = 1; - f->priority = AssignPriority(f->name); - return 0; - } - - for (i = 0; i < numsequences; i++) { - /* Convert sequences to their sequence numbers */ - if (sequencesToDo[i]) - seqnum[i] = seq_getnum(mp, sequencesToDo[i]); - else - seqnum[i] = -1; - - /* Now count messages in this sequence */ - nSeq[i] = 0; - if (mp->nummsg > 0 && seqnum[i] != -1) { - for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) { - if (in_sequence(mp, seqnum[i], msgnum)) - nSeq[i]++; - } + unsigned int i; + int msgnum, nonzero; + int seqnum[NUMATTRS], nSeq[NUMATTRS]; + struct Folder *f; + struct msgs *mp; + + /* Read folder and create message structure */ + if (!(mp = folder_read(name))) { + /* Oops, error occurred. Record it and continue. */ + AllocFolders(&folders, &nFoldersAlloced, nFolders + 1); + f = &folders[nFolders++]; + f->name = getcpy(name); + f->error = 1; + f->priority = AssignPriority(f->name); + return 0; } - } - - /* Check if any of the sequence checks were nonzero */ - nonzero = 0; - for (i = 0; i < numsequences; i++) { - if (nSeq[i] > 0) { - nonzero = 1; - break; + + for (i = 0; i < numsequences; i++) { + /* Convert sequences to their sequence numbers */ + if (sequencesToDo[i]) + seqnum[i] = seq_getnum(mp, sequencesToDo[i]); + else + seqnum[i] = -1; + + /* Now count messages in this sequence */ + nSeq[i] = 0; + if (mp->nummsg > 0 && seqnum[i] != -1) { + for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; + msgnum++) { + if (in_sequence(mp, seqnum[i], msgnum)) + nSeq[i]++; + } + } } - } - - if (nonzero || force) { - /* save general folder information */ - AllocFolders(&folders, &nFoldersAlloced, nFolders + 1); - f = &folders[nFolders++]; - f->name = getcpy(name); - f->nMsgs = mp->nummsg; - f->error = 0; - f->priority = AssignPriority(f->name); - - /* record the sequence information */ + + /* Check if any of the sequence checks were nonzero */ + nonzero = 0; for (i = 0; i < numsequences; i++) { - f->nSeq[i] = nSeq[i]; - f->private[i] = (seqnum[i] != -1) ? is_seq_private(mp, seqnum[i]) : 0; + if (nSeq[i] > 0) { + nonzero = 1; + break; + } } - } - folder_free (mp); /* free folder/message structure */ - return 1; + if (nonzero || force) { + /* save general folder information */ + AllocFolders(&folders, &nFoldersAlloced, nFolders + 1); + f = &folders[nFolders++]; + f->name = getcpy(name); + f->nMsgs = mp->nummsg; + f->error = 0; + f->priority = AssignPriority(f->name); + + /* record the sequence information */ + for (i = 0; i < numsequences; i++) { + f->nSeq[i] = nSeq[i]; + f->private[i] = (seqnum[i] != -1) ? + is_seq_private(mp, seqnum[i]) : 0; + } + } + + folder_free(mp); /* free folder/message structure */ + return 1; } /* - * Print the folder/sequence information - */ +** Print the folder/sequence information +*/ void PrintFolders(void) { - char tmpname[BUFSIZ]; - int i, j, len, has_private = 0; - int maxfolderlen = 0, maxseqlen = 0; - int maxnum = 0, maxseq = 0; - - if (!Total) { - for (i = 0; i < nFolders; i++) - printf("%s\n", folders[i].name); - return; - } - - /* - * Find the width we need for various fields - */ - for (i = 0; i < nFolders; ++i) { - /* find the length of longest folder name */ - len = strlen(folders[i].name); - if (len > maxfolderlen) - maxfolderlen = len; - - /* If folder had error, skip the rest */ - if (folders[i].error) - continue; - - /* find the maximum total messages */ - if (folders[i].nMsgs > maxnum) - maxnum = folders[i].nMsgs; - - for (j = 0; j < numsequences; j++) { - /* find maximum width of sequence name */ - len = strlen (sequencesToDo[j]); - if ((folders[i].nSeq[j] > 0 || showzero) && (len > maxseqlen)) - maxseqlen = len; - - /* find the maximum number of messages in sequence */ - if (folders[i].nSeq[j] > maxseq) - maxseq = folders[i].nSeq[j]; - - /* check if this sequence is private in any of the folders */ - if (folders[i].private[j]) - has_private = 1; + char tmpname[BUFSIZ]; + unsigned int i, j, len, has_private = 0; + unsigned int maxfolderlen = 0, maxseqlen = 0; + int maxnum = 0, maxseq = 0; + + if (!Total) { + for (i = 0; i < nFolders; i++) + printf("%s\n", folders[i].name); + return; } - } - - /* Now print all the folder/sequence information */ - for (i = 0; i < nFolders; i++) { - for (j = 0; j < numsequences; j++) { - if (folders[i].nSeq[j] > 0 || showzero) { - /* Add `+' to end of name of current folder */ - if (strcmp(curfolder, folders[i].name)) - snprintf(tmpname, sizeof(tmpname), "%s", folders[i].name); - else - snprintf(tmpname, sizeof(tmpname), "%s+", folders[i].name); - if (folders[i].error) { - printf("%-*s is unreadable\n", maxfolderlen+1, tmpname); - continue; + /* + ** Find the width we need for various fields + */ + for (i = 0; i < nFolders; ++i) { + /* find the length of longest folder name */ + len = strlen(folders[i].name); + if (len > maxfolderlen) + maxfolderlen = len; + + /* If folder had error, skip the rest */ + if (folders[i].error) + continue; + + /* find the maximum total messages */ + if (folders[i].nMsgs > maxnum) + maxnum = folders[i].nMsgs; + + for (j = 0; j < numsequences; j++) { + /* find maximum width of sequence name */ + len = strlen(sequencesToDo[j]); + if ((folders[i].nSeq[j] > 0 || showzero) && + (len > maxseqlen)) + maxseqlen = len; + + /* find the maximum number of messages in sequence */ + if (folders[i].nSeq[j] > maxseq) + maxseq = folders[i].nSeq[j]; + + /* + ** check if this sequence is private in any of + ** the folders + */ + if (folders[i].private[j]) + has_private = 1; } - - printf("%-*s has %*d in sequence %-*s%s; out of %*d\n", - maxfolderlen+1, tmpname, - num_digits(maxseq), folders[i].nSeq[j], - maxseqlen, sequencesToDo[j], - !has_private ? "" : folders[i].private[j] ? " (private)" : " ", - num_digits(maxnum), folders[i].nMsgs); - } } - } -} -/* - * Calculate the number of digits in a nonnegative integer - */ -static 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; + /* Now print all the folder/sequence information */ + for (i = 0; i < nFolders; i++) { + for (j = 0; j < numsequences; j++) { + if (folders[i].nSeq[j] > 0 || showzero) { + /* Add `+' to end of name of current folder */ + if (strcmp(curfol, folders[i].name)!=0) + snprintf(tmpname, sizeof(tmpname), + "%s", folders[i].name); + else + snprintf(tmpname, sizeof(tmpname), + "%s+", + folders[i].name); + + if (folders[i].error) { + printf("%-*s is unreadable\n", + maxfolderlen+1, + tmpname); + continue; + } + + printf("%-*s has %*d in sequence %-*s%s; out of %*d\n", maxfolderlen+1, tmpname, num_digits(maxseq), folders[i].nSeq[j], maxseqlen, sequencesToDo[j], !has_private ? "" : folders[i].private[j] ? " (private)" : " ", num_digits(maxnum), folders[i].nMsgs); + } + } + } } /* - * Put them in priority order. - */ +** Put them in priority order. +*/ int CompareFolders(struct Folder *f1, struct Folder *f2) { - if (!alphaOrder && f1->priority != f2->priority) - return f1->priority - f2->priority; - else - return strcmp(f1->name, f2->name); + if (!alphaOrder && f1->priority != f2->priority) + return f1->priority - f2->priority; + else + return strcmp(f1->name, f2->name); } /* - * Make sure we have at least n folders allocated. - */ +** Make sure we have at least n folders allocated. +*/ void AllocFolders(struct Folder **f, int *nfa, int n) { - if (n <= *nfa) - return; - if (*f == NULL) { - *nfa = 10; - *f = (struct Folder *) malloc (*nfa * (sizeof(struct Folder))); - } else { - *nfa *= 2; - *f = (struct Folder *) realloc (*f, *nfa * (sizeof(struct Folder))); - } + if (n <= *nfa) + return; + if (*f == NULL) { + *nfa = 10; + *f = (struct Folder *) mh_xmalloc( + *nfa * (sizeof(struct Folder))); + } else { + *nfa *= 2; + *f = (struct Folder *) mh_xrealloc( + *f, *nfa * (sizeof(struct Folder))); + } } /* - * Return the priority for a name. The highest comes from an exact match. - * After that, the longest match (then first) assigns the priority. - */ +** Return the priority for a name. The highest comes from an exact match. +** After that, the longest match (then first) assigns the priority. +*/ int AssignPriority(char *name) { - int i, ol, nl; - int best = nOrders; - int bestLen = 0; - struct Folder *o; - - nl = strlen(name); - for (i = 0; i < nOrders; ++i) { - o = &orders[i]; - if (!strcmp(name, o->name)) - return o->priority; - ol = strlen(o->name); - if (nl < ol - 1) - continue; - if (ol < bestLen) - continue; - if (o->name[0] == '*' && !strcmp(o->name + 1, name + (nl - ol + 1))) { - best = o->priority; - bestLen = ol; - } else if (o->name[ol - 1] == '*' && strncmp(o->name, name, ol - 1) == 0) { - best = o->priority; - bestLen = ol; + int i, ol, nl; + int best = nOrders; + int bestLen = 0; + struct Folder *o; + + nl = strlen(name); + for (i = 0; i < nOrders; ++i) { + o = &orders[i]; + if (strcmp(name, o->name)==0) + return o->priority; + ol = strlen(o->name); + if (nl < ol - 1) + continue; + if (ol < bestLen) + continue; + if (o->name[0] == '*' && + strcmp(o->name + 1, name + (nl - ol + 1))==0) { + best = o->priority; + bestLen = ol; + } else if (o->name[ol - 1] == '*' && + strncmp(o->name, name, ol - 1) == 0) { + best = o->priority; + bestLen = ol; + } } - } - return best; + return best; } /* - * Do the read only folders - */ +** Do the read only folders +*/ static void -do_readonly_folders (void) +do_readonly_folders(void) { - int atrlen; - char atrcur[BUFSIZ]; - register struct node *np; - - /* sanity check - check that context has been read */ - if (defpath == NULL) - adios (NULL, "oops, context hasn't been read yet"); - - snprintf (atrcur, sizeof(atrcur), "atr-%s-", current); - atrlen = strlen (atrcur); - - for (np = m_defs; np; np = np->n_next) - if (ssequal (atrcur, np->n_name) - && !ssequal (nmhdir, np->n_name + atrlen)) - BuildFolderList (np->n_name + atrlen, 0); + int atrlen; + char atrcur[BUFSIZ]; + register struct node *np; + + snprintf(atrcur, sizeof(atrcur), "atr-%s-", seq_cur); + atrlen = strlen(atrcur); + + for (np = m_defs; np; np = np->n_next) + if (strncmp(np->n_name, atrcur, atrlen)==0 + && strncmp(np->n_name+atrlen, nmhdir, strlen(nmhdir))!=0) + /* Why do we exclude absolute path names? --meillo */ + BuildFolderList(np->n_name + atrlen, 0); }