From c5cd4df026e8f8b7a8334028dda21af13e205ce3 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Thu, 10 Jan 2019 16:43:25 +0100 Subject: seq: sort dir file lists numerically --- GNUmakefile | 3 +-- seq.c | 59 ++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 04f4944..3aa3c30 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -28,12 +28,11 @@ $(ALL) : % : %.o maddr magrep mdeliver mexport mflag mflow mgenmid mhdr mpick mscan msed mshow \ msort mthread : blaze822.o mymemmem.o mytimegm.o maddr magrep mdeliver mexport mflag mgenmid mhdr mlist mpick mscan msed mseq \ - mshow msort mthread : seq.o slurp.o + mshow msort mthread : seq.o slurp.o mystrverscmp.o maddr magrep mflow mhdr mpick mscan mshow : rfc2047.o magrep mflow mhdr mshow : rfc2045.o mshow : filter.o safe_u8putstr.o rfc2231.o pipeto.o mscan : pipeto.o -msort : mystrverscmp.o mmime : slurp.o minc mlist : squeeze_slash.o diff --git a/seq.c b/seq.c index b8186af..0272e31 100644 --- a/seq.c +++ b/seq.c @@ -467,44 +467,53 @@ blaze822_seq_next(char *map, char *range, struct blaze822_seq_iter *iter) return r; } +int mystrverscmp(const char *, const char *); + +static int +mailsort(const struct dirent **a, const struct dirent **b) +{ + return mystrverscmp((*a)->d_name, (*b)->d_name); +} + static long iterdir(char *dir, void (*cb)(char *)) { - DIR *fd, *fd2; - struct dirent *d; + struct dirent **namelist; - long i = 0; + int n; + + char sub[PATH_MAX]; + snprintf(sub, sizeof sub, "%s/cur", dir); - fd = opendir(dir); - if (!fd) { + char *m = "/cur"; + + n = scandir(sub, &namelist, 0, mailsort); + if (n == -1 && (errno == ENOENT || errno == ENOTDIR)) { + m = ""; + n = scandir(dir, &namelist, 0, mailsort); + } + + if (n == -1) { if (errno == ENOTDIR) cb(dir); return 1; } - char sub[PATH_MAX]; - snprintf(sub, sizeof sub, "%s/cur", dir); - fd2 = opendir(sub); - if (fd2) { - closedir(fd); - fd = fd2; - } - - while ((d = readdir(fd))) { + long i = 0; + for (i = 0; i < n; i++) { + if (namelist[i]->d_name[0] != '.') #if defined(DT_REG) && defined(DT_UNKNOWN) - if (d->d_type != DT_REG && d->d_type != DT_UNKNOWN) - continue; + if (namelist[i]->d_type == DT_REG || + namelist[i]->d_type == DT_UNKNOWN) #endif - if (d->d_name[0] == '.') - continue; - if (fd2) - snprintf(sub, sizeof sub, "%s/cur/%s", dir, d->d_name); - else - snprintf(sub, sizeof sub, "%s/%s", dir, d->d_name); - cb(sub); - i++; + { + snprintf(sub, sizeof sub, "%s%s/%s", + dir, m, namelist[i]->d_name); + cb(sub); + } + free(namelist[i]); } - closedir(fd); + free(namelist); return i; } -- cgit 1.4.1