From a1eafa7c48fb08f96613e85ad6ee3af5532bf2f3 Mon Sep 17 00:00:00 2001 From: Philipp Takacs Date: Thu, 19 Mar 2020 02:50:51 +0100 Subject: [PATCH] use scandir in folder_read --- sbr/folder_read.c | 149 ++++++++++++++++++++--------------------------------- 1 file changed, 56 insertions(+), 93 deletions(-) diff --git a/sbr/folder_read.c b/sbr/folder_read.c index 011958f..6a8139a 100644 --- a/sbr/folder_read.c +++ b/sbr/folder_read.c @@ -12,9 +12,6 @@ #include #include -/* We allocate the `mi' array 1024 elements at a time */ -#define NUMMSGS 1024 - /* ** 1) Create the folder/message structure ** 2) Read the directory (folder) and temporarily @@ -24,121 +21,87 @@ ** 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) { - int msgnum, len, *mi; + int i; struct msgs *mp; struct stat st; - struct dirent *dp; - DIR *dd; + struct dirent **dp; + others = 0; name = mh_xstrdup(toabsdir(name)); - if (!(dd = opendir(name))) { - mh_free0(&name); - return NULL; - } if (stat(name, &st) == -1) { mh_free0(&name); - closedir(dd); return NULL; } /* Allocate the main structure for folder information */ 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); - /* - ** Allocate a temporary place to record the - ** name of the messages in this folder. - */ - len = NUMMSGS; - mi = mh_xcalloc(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 = mh_xrealloc(mi, 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 ',': - continue; - - default: - /* - ** indicate that there are other - ** files in folder - */ - set_other_files(mp); - continue; - } - } - } + mp->nummsg = scandir(name, &dp, msgfilter, msgnumcmp); - closedir(dd); - mp->lowoff = max(mp->lowmsg, 1); + if (others) + set_other_files(mp); - /* Go ahead and allocate space for 100 additional messages. */ + 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; - - /* for testing, allocate minimal necessary space */ - /* mp->hghoff = max(mp->hghmsg, 1); */ - - /* Allocate space for status of each message. */ - mp->msgstats = mh_xcalloc(MSGSTATSIZE(mp, mp->lowoff, mp->hghoff), 1); - - /* - ** 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]); - - mh_free0(&mi); /* We don't need this anymore */ + 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. -- 1.7.10.4