X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Ffolder_read.c;h=6a8139a62e314a94df1f6ece55dec91b3b0c6f6c;hp=c77ea1ea253fbd14710cc8fa839534b5d1070870;hb=a1eafa7c48fb08f96613e85ad6ee3af5532bf2f3;hpb=a485ed478abbd599d8c9aab48934e7a26733ecb1 diff --git a/sbr/folder_read.c b/sbr/folder_read.c index c77ea1e..6a8139a 100644 --- a/sbr/folder_read.c +++ b/sbr/folder_read.c @@ -1,159 +1,112 @@ /* - * folder_read.c -- initialize folder structure and read folder - * - * This code is Copyright (c) 2002, by the authors of nmh. See the - * COPYRIGHT file in the root directory of the nmh distribution for - * complete copyright information. - */ - +** folder_read.c -- initialize folder structure and read folder +** +** This code is Copyright (c) 2002, by the authors of nmh. See the +** COPYRIGHT file in the root directory of the nmh distribution for +** complete copyright information. +*/ + +#include #include #include - -/* We allocate the `mi' array 1024 elements at a time */ -#define NUMMSGS 1024 +#include +#include /* - * 1) Create the folder/message structure - * 2) Read the directory (folder) and temporarily - * record the numbers of the messages we have seen. - * 3) Then allocate the array for message attributes and - * set the initial flags for all messages we've seen. - * 4) Read and initialize the sequence information. - */ +** 1) Create the folder/message structure +** 2) Read the directory (folder) and temporarily +** record the numbers of the messages we have seen. +** 3) Then allocate the array for message attributes and +** set the initial flags for all messages we've seen. +** 4) Read and initialize the sequence information. +*/ + +static int others; + +static int +msgnumcmp(const struct dirent **d1, const struct dirent **d2) +{ + size_t l1, l2; + + l1 = strlen((*d1)->d_name); + l2 = strlen((*d2)->d_name); + if (l1 < l2) { + return -1; + } + if (l1 > l2) { + return 1; + } + return strcmp((*d1)->d_name, (*d2)->d_name); +} + +static int +msgfilter(const struct dirent *e) +{ + int i; + /* For compatibility with nmh, ignore rmm backup files. */ + if (e->d_name[0] == '.' || e->d_name[0] == ',' || e->d_name[0] == '#') { + return 0; + } + for (i = 0; e->d_name[i]; i++) { + if ((i == 0 && e->d_name[i] == '0') || e->d_name[i] < '0' || e->d_name[i] > '9') { + others = 1; + return 0; + } + } + return 1; +} struct msgs * -folder_read (char *name) +folder_read(char *name) { - int msgnum, prefix_len, len, *mi; + int i; struct msgs *mp; struct stat st; - struct dirent *dp; - DIR *dd; + struct dirent **dp; - name = m_mailpath (name); - if (!(dd = opendir (name))) { - free (name); - return NULL; - } + others = 0; + name = mh_xstrdup(toabsdir(name)); - if (stat (name, &st) == -1) { - free (name); + if (stat(name, &st) == -1) { + mh_free0(&name); return NULL; } /* Allocate the main structure for folder information */ - mp = (struct msgs *) mh_xmalloc ((size_t) sizeof(*mp)); + mp = mh_xcalloc(1, sizeof(*mp)); - clear_folder_flags (mp); mp->foldpath = name; - mp->lowmsg = 0; - mp->hghmsg = 0; - mp->curmsg = 0; - mp->lowsel = 0; - mp->hghsel = 0; - mp->numsel = 0; - mp->nummsg = 0; - - if (access (name, W_OK) == -1) - set_readonly (mp); - prefix_len = strlen(backup_prefix); - /* - * Allocate a temporary place to record the - * name of the messages in this folder. - */ - len = NUMMSGS; - mi = (int *) mh_xmalloc ((size_t) (len * sizeof(*mi))); - - while ((dp = readdir (dd))) { - if ((msgnum = m_atoi (dp->d_name)) && msgnum > 0) { - /* - * Check if we need to allocate more - * temporary elements for message names. - */ - if (mp->nummsg >= len) { - len += NUMMSGS; - mi = (int *) mh_xrealloc (mi, (size_t) (len * sizeof(*mi))); - } - - /* Check if this is the first message we've seen */ - if (mp->nummsg == 0) { - mp->lowmsg = msgnum; - mp->hghmsg = msgnum; - } else { - /* Check if this is it the highest or lowest we've seen? */ - if (msgnum < mp->lowmsg) - mp->lowmsg = msgnum; - if (msgnum > mp->hghmsg) - mp->hghmsg = msgnum; - } - - /* - * Now increment count, and record message - * number in a temporary place for now. - */ - mi[mp->nummsg++] = msgnum; - - } else { - switch (dp->d_name[0]) { - case '.': - case ',': -#ifdef MHE - case '+': -#endif /* MHE */ - continue; - - default: - /* skip any files beginning with backup prefix */ - if (!strncmp (dp->d_name, backup_prefix, prefix_len)) - continue; - - /* skip the altmsg link file */ - if (!strcmp (dp->d_name, altmsglink)) - continue; - - /* indicate that there are other files in folder */ - set_other_files (mp); - continue; - } - } - } - - closedir (dd); - mp->lowoff = max (mp->lowmsg, 1); - - /* Go ahead and allocate space for 100 additional messages. */ - mp->hghoff = mp->hghmsg + 100; - - /* for testing, allocate minimal necessary space */ - /* mp->hghoff = max (mp->hghmsg, 1); */ + if (access(name, W_OK) == -1) + set_readonly(mp); - /* - * Allocate space for status of each message. - */ - mp->msgstats = mh_xmalloc (MSGSTATSIZE(mp, mp->lowoff, mp->hghoff)); + mp->nummsg = scandir(name, &dp, msgfilter, msgnumcmp); - /* - * Clear all the flag bits for all the message - * status entries we just allocated. - */ - for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++) - clear_msg_flags (mp, msgnum); + if (others) + set_other_files(mp); - /* - * Scan through the array of messages we've seen and - * setup the initial flags for those messages in the - * newly allocated mp->msgstats area. - */ - for (msgnum = 0; msgnum < mp->nummsg; msgnum++) - set_exists (mp, mi[msgnum]); - - free (mi); /* We don't need this anymore */ + if (mp->nummsg < 0) { + mh_free0(&name); + mh_free0(&mp); + return NULL; + } + if (mp->nummsg > 0) { + mp->lowmsg = m_atoi(dp[0]->d_name); + mp->hghmsg = m_atoi(dp[mp->nummsg-1]->d_name); + } + mp->lowoff = max(mp->lowmsg, 1); + mp->hghoff = mp->hghmsg + 100; + mp->msgstats = mh_xcalloc(MSGSTATSIZE(mp, mp->lowoff, mp->hghoff), 1); + for (i = 0; i < mp->nummsg; i++) { + set_exists(mp, m_atoi(dp[i]->d_name)); + mh_free0(dp + i); + } + mh_free0(&dp); /* - * Read and initialize the sequence information. - */ - seq_read (mp); + ** Read and initialize the sequence information. + */ + seq_read(mp); return mp; }