From 900863bf7638c2cedbb5652c2672c043cbcb6c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Tempel?= Date: Tue, 8 Oct 2024 23:16:07 +0200 Subject: [PATCH] Exit with a non-zero exit status if a given file does not exist Sadly, the diff is quite large as we will have to change the API of `blaze822_loop` to differentiate the number of processed messages and a status code indicating a missing mail. Note that currently execution is not aborted upon encountering the first non-existent mail; hence, we can't do both via the return value. Surprisingly, very few utilities actually use the number of processed messages as return by `blaze822_loop`. Therefore, we could reduce the diff quite a bit by differentiating the two use cases through separate function (e.g. `blaze822_loop` and `blaze822_loop_num`), which would allow the API of blaze822_loop to remain largely unchanged. The new `blaze822_loop` API would also allow us to improve error handling for blaze822_seq_next but I haven't done this so far. There are also some tests, but these should be expanded. Fixes #264 --- blaze822.h | 4 ++-- maddr.c | 6 ++---- magrep.c | 4 ++-- mdeliver.c | 4 +--- mexport.c | 4 ++-- mflag.c | 20 +++++++++----------- mhdr.c | 4 ++-- minc.c | 2 +- mlist.c | 5 +++-- mpick.c | 7 ++++--- mscan.c | 12 ++++++------ msed.c | 6 ++---- mseq.c | 9 +++++---- mshow.c | 21 +++++++++++---------- msort.c | 7 ++++--- mthread.c | 9 +++++---- seq.c | 41 ++++++++++++++++++++++++++++------------- t/1100-mhdr.t | 3 ++- t/1500-maddr.t | 3 ++- t/1800-mexport.t | 3 ++- t/8000-mflag.t | 3 ++- 21 files changed, 97 insertions(+), 80 deletions(-) diff --git a/blaze822.h b/blaze822.h index 1346345..aeb9c04 100644 --- a/blaze822.h +++ b/blaze822.h @@ -85,8 +85,8 @@ struct blaze822_seq_iter { }; char *blaze822_seq_next(char *map, char *range, struct blaze822_seq_iter *iter); -long blaze822_loop(int, char **, void (*)(char *)); -long blaze822_loop1(char *arg, void (*cb)(char *)); +int blaze822_loop(long *num, int, char **, void (*)(char *)); +int blaze822_loop1(long *num, char *arg, void (*cb)(char *)); char *blaze822_home_file(char *basename); // filter.c diff --git a/maddr.c b/maddr.c index 4982a8c..b534dda 100644 --- a/maddr.c +++ b/maddr.c @@ -114,9 +114,7 @@ main(int argc, char *argv[]) xpledge("stdio rpath", ""); if (argc == optind && isatty(0)) - blaze822_loop1(":", addr); + return blaze822_loop1(NULL, ":", addr); else - blaze822_loop(argc-optind, argv+optind, addr); - - return 0; + return blaze822_loop(NULL, argc-optind, argv+optind, addr); } diff --git a/magrep.c b/magrep.c index 608048a..03be789 100644 --- a/magrep.c +++ b/magrep.c @@ -232,9 +232,9 @@ main(int argc, char *argv[]) } if (argc == optind && isatty(0)) - blaze822_loop1(":", magrep); + blaze822_loop1(NULL, ":", magrep); else - blaze822_loop(argc-optind, argv+optind, magrep); + blaze822_loop(NULL, argc-optind, argv+optind, magrep); if (cflag && !qflag && !mflag) printf("%ld\n", matches); diff --git a/mdeliver.c b/mdeliver.c index 73fac4a..2e11ded 100644 --- a/mdeliver.c +++ b/mdeliver.c @@ -331,9 +331,7 @@ main(int argc, char *argv[]) if (argc == optind + 1 && isatty(0)) goto usage; else - blaze822_loop(argc - 1 - optind, argv + optind, refile); - - return 0; + return blaze822_loop(NULL, argc - 1 - optind, argv + optind, refile); } int c; diff --git a/mexport.c b/mexport.c index 0ac490d..fd64e47 100644 --- a/mexport.c +++ b/mexport.c @@ -148,9 +148,9 @@ main(int argc, char *argv[]) xpledge("stdio rpath", ""); if (argc == optind && isatty(0)) - blaze822_loop1(":", export); + status |= blaze822_loop1(NULL, ":", export); else - blaze822_loop(argc-optind, argv+optind, export); + status |= blaze822_loop(NULL, argc-optind, argv+optind, export); return status; } diff --git a/mflag.c b/mflag.c index ae9a9f2..4881737 100644 --- a/mflag.c +++ b/mflag.c @@ -141,31 +141,29 @@ main(int argc, char *argv[]) if (vflag) { if (argc == optind && !isatty(0)) { - blaze822_loop(0, 0, flag); // read from stdin - return 0; + return blaze822_loop(NULL, 0, 0, flag); // read from stdin } args = calloc(argsalloc, sizeof (char *)); if (!args) exit(-1); + int status; if (argc == optind) - blaze822_loop1(".", add); + status = blaze822_loop1(NULL, ".", add); else - blaze822_loop(argc-optind, argv+optind, add); + status = blaze822_loop(NULL, argc-optind, argv+optind, add); if (isatty(0)) - blaze822_loop1(":", flag); + status |= blaze822_loop1(NULL, ":", flag); else - blaze822_loop(0, 0, flag); + status |= blaze822_loop(NULL, 0, 0, flag); - return 0; + return status; } if (argc == optind && isatty(0)) - blaze822_loop1(".", flag); + return blaze822_loop1(NULL, ".", flag); else - blaze822_loop(argc-optind, argv+optind, flag); - - return 0; + return blaze822_loop(NULL, argc-optind, argv+optind, flag); } diff --git a/mhdr.c b/mhdr.c index b6e9fa0..a16d586 100644 --- a/mhdr.c +++ b/mhdr.c @@ -250,9 +250,9 @@ main(int argc, char *argv[]) xpledge("stdio rpath", ""); if (argc == optind && isatty(0)) - blaze822_loop1(".", header); + status |= blaze822_loop1(NULL, ".", header); else - blaze822_loop(argc-optind, argv+optind, header); + status |= blaze822_loop(NULL, argc-optind, argv+optind, header); return status; } diff --git a/minc.c b/minc.c index 757c65b..74af291 100644 --- a/minc.c +++ b/minc.c @@ -81,7 +81,7 @@ main(int argc, char *argv[]) if (optind == argc) { if (isatty(0)) goto usage; - blaze822_loop(0, 0, inc); + status = blaze822_loop(NULL, 0, 0, inc); } else { for (i = optind; i < argc; i++) inc(argv[i]); diff --git a/mlist.c b/mlist.c index e0ec42c..b358554 100644 --- a/mlist.c +++ b/mlist.c @@ -282,10 +282,11 @@ main(int argc, char *argv[]) flagsum++; } + int status = 0; if (optind == argc) { if (isatty(0)) goto usage; - blaze822_loop(0, 0, listarg); + status = blaze822_loop(NULL, 0, 0, listarg); } else { for (i = optind; i < argc; i++) listarg(argv[i]); @@ -300,5 +301,5 @@ main(int argc, char *argv[]) tunseen, tflagged, tcount); } - return 0; + return status; } diff --git a/mpick.c b/mpick.c index 661e472..c158291 100644 --- a/mpick.c +++ b/mpick.c @@ -1464,11 +1464,12 @@ main(int argc, char *argv[]) xpledge("stdio rpath wpath cpath proc exec", 0); + int status; void (*cb)(char *) = need_thr ? collect : oneline; if (argc == optind && isatty(0)) - i = blaze822_loop1(":", cb); + status = blaze822_loop1(&i, ":", cb); else - i = blaze822_loop(argc-optind, argv+optind, cb); + status = blaze822_loop(&i, argc-optind, argv+optind, cb); /* print and free last thread */ if (Tflag && thr) @@ -1488,5 +1489,5 @@ main(int argc, char *argv[]) free(files); } - return 0; + return status; } diff --git a/mscan.c b/mscan.c index bb6cd9e..4ff1267 100644 --- a/mscan.c +++ b/mscan.c @@ -559,10 +559,9 @@ main(int argc, char *argv[]) if (nflag) { if (argc == optind && isatty(0)) - blaze822_loop1(":", numline); + return blaze822_loop1(NULL, ":", numline); else - blaze822_loop(argc-optind, argv+optind, numline); - return 0; + return blaze822_loop(NULL, argc-optind, argv+optind, numline); } now = time(0); @@ -623,10 +622,11 @@ main(int argc, char *argv[]) } long i; + int status; if (argc == optind && isatty(0)) - i = blaze822_loop1(":", oneline); + status = blaze822_loop1(&i, ":", oneline); else - i = blaze822_loop(argc-optind, argv+optind, oneline); + status = blaze822_loop(&i, argc-optind, argv+optind, oneline); if (pager_pid > 0) pipeclose(pager_pid); @@ -634,5 +634,5 @@ main(int argc, char *argv[]) if (vflag) fprintf(stderr, "%ld mails scanned\n", i); - return 0; + return status; } diff --git a/msed.c b/msed.c index c545278..ab78300 100644 --- a/msed.c +++ b/msed.c @@ -330,9 +330,7 @@ main(int argc, char *argv[]) optind++; if (argc == optind && isatty(0)) - blaze822_loop1(".", sed); + return blaze822_loop1(NULL, ".", sed); else - blaze822_loop(argc-optind, argv+optind, sed); - - return 0; + return blaze822_loop(NULL, argc-optind, argv+optind, sed); } diff --git a/mseq.c b/mseq.c index ac3aa19..f653345 100644 --- a/mseq.c +++ b/mseq.c @@ -301,12 +301,13 @@ main(int argc, char *argv[]) xpledge("stdio rpath wpath cpath", ""); - if (cflag) - blaze822_loop1(cflag, overridecur); + if (cflag) { + if (blaze822_loop1(NULL, cflag, overridecur)) + return 1; + } if (Cflag) { - blaze822_loop1(Cflag, setcur); - return 0; + return blaze822_loop1(NULL, Cflag, setcur); } if (Sflag && optind != argc) { diff --git a/mshow.c b/mshow.c index d0871f2..76df723 100644 --- a/mshow.c +++ b/mshow.c @@ -587,13 +587,13 @@ extract_cb(char *file) blaze822_walk_mime(msg, 0, extract_mime); } -void +int extract(char *file, int argc, char **argv, int use_stdout) { extract_argc = argc; extract_argv = argv; extract_stdout = use_stdout; - blaze822_loop1(file, extract_cb); + return blaze822_loop1(NULL, file, extract_cb); } static char *newcur; @@ -832,21 +832,22 @@ main(int argc, char *argv[]) } } + int status = 0; if (xflag) { // extract xpledge("stdio rpath wpath cpath", NULL); - extract(xflag, argc-optind, argv+optind, 0); + status = extract(xflag, argc-optind, argv+optind, 0); } else if (Oflag) { // extract to stdout xpledge("stdio rpath", NULL); - extract(Oflag, argc-optind, argv+optind, 1); + status = extract(Oflag, argc-optind, argv+optind, 1); } else if (tflag) { // list xpledge("stdio rpath", NULL); if (argc == optind && isatty(0)) - blaze822_loop1(".", list); + status = blaze822_loop1(NULL, ".", list); else - blaze822_loop(argc-optind, argv+optind, list); + status = blaze822_loop(NULL, argc-optind, argv+optind, list); } else if (Rflag) { // render for reply xpledge("stdio rpath", NULL); - blaze822_loop(argc-optind, argv+optind, reply); + status = blaze822_loop(NULL, argc-optind, argv+optind, reply); } else { // show /* XXX pledge: still r/w on the whole file-system + fork/exec */ if (!(qflag || rflag || Fflag)) { @@ -857,9 +858,9 @@ main(int argc, char *argv[]) filters = blaze822(f); } if (argc == optind && isatty(0)) - blaze822_loop1(".", show); + status = blaze822_loop1(NULL, ".", show); else - blaze822_loop(argc-optind, argv+optind, show); + status = blaze822_loop(NULL, argc-optind, argv+optind, show); if (!nflag) // don't set cur if (newcur) blaze822_seq_setcur(newcur); @@ -875,5 +876,5 @@ main(int argc, char *argv[]) return 1; } - return 0; + return status; } diff --git a/msort.c b/msort.c index 55ec6aa..ccb375a 100644 --- a/msort.c +++ b/msort.c @@ -323,10 +323,11 @@ main(int argc, char *argv[]) if (!mails) exit(-1); + int status; if (argc == optind && isatty(0)) - blaze822_loop1(":", add); + status = blaze822_loop1(NULL, ":", add); else - blaze822_loop(argc-optind, argv+optind, add); + status = blaze822_loop(NULL, argc-optind, argv+optind, add); qsort(mails, idx, sizeof (struct mail), order); @@ -337,5 +338,5 @@ main(int argc, char *argv[]) for (i = 0; i < idx; i++) printf("%s\n", mails[i].file); - return 0; + return status; } diff --git a/mthread.c b/mthread.c index 77fb21e..8344b73 100644 --- a/mthread.c +++ b/mthread.c @@ -421,7 +421,7 @@ main(int argc, char *argv[]) while ((c = getopt(argc, argv, "S:prv")) != -1) switch (c) { - case 'S': blaze822_loop1(optarg, thread); break; + case 'S': blaze822_loop1(NULL, optarg, thread); break; case 'v': vflag = 1; break; case 'p': pflag = 1; break; case 'r': rflag = 1; break; @@ -432,10 +432,11 @@ main(int argc, char *argv[]) optional = 0; + int status; if (argc == optind && isatty(0)) - blaze822_loop1(":", thread); + status = blaze822_loop1(NULL, ":", thread); else - blaze822_loop(argc-optind, argv+optind, thread); + status = blaze822_loop(NULL, argc-optind, argv+optind, thread); // the tree of all toplevel threads has depth -1, // so toplevel threads have depth 0. @@ -446,5 +447,5 @@ main(int argc, char *argv[]) sort_tree(top, -1); print_tree(top, -1); - return 0; + return status; } diff --git a/seq.c b/seq.c index 5d98284..d1cebac 100644 --- a/seq.c +++ b/seq.c @@ -493,11 +493,13 @@ iterdir(char *dir, void (*cb)(char *)) m = ""; n = scandir(dir, &namelist, 0, mailsort); } - - if (n == -1) { - if (errno == ENOTDIR) + + if (n == -1) { + if (errno == ENOTDIR) { cb(dir); - return 1; + return 1; + } + return 0; } long i = 0; @@ -515,8 +517,8 @@ iterdir(char *dir, void (*cb)(char *)) return i; } -long -blaze822_loop(int argc, char *argv[], void (*cb)(char *)) +int +blaze822_loop(long *num, int argc, char *argv[], void (*cb)(char *)) { char *line = 0; size_t linelen = 0; @@ -531,15 +533,25 @@ blaze822_loop(int argc, char *argv[], void (*cb)(char *)) i++; } free(line); - return i; + + if (num) + *num = i; + return 0; } char *map = 0; + int status = 0; int map_opened = 0; - int j = 0; + long j = 0; for (i = 0; i < argc; i++) { if (strchr(argv[i], '/')) { // a file name - j += iterdir(argv[i], cb); + long n = iterdir(argv[i], cb); + if (!n) { + fprintf(stderr, "mblaze: warning: file '%s' does not exist\n", argv[i]); + status = 1; + } else { + j += n; + } } else if (strcmp(argv[i], "-") == 0) { if (isatty(0)) { fprintf(stderr, "mblaze: warning: - now means " @@ -562,12 +574,15 @@ blaze822_loop(int argc, char *argv[], void (*cb)(char *)) } } free(map); - return j; + + if (num) + *num = j; + return status; } -long -blaze822_loop1(char *arg, void (*cb)(char *)) +int +blaze822_loop1(long *num, char *arg, void (*cb)(char *)) { char *args[] = { arg }; - return blaze822_loop(1, args, cb); + return blaze822_loop(num, 1, args, cb); } diff --git a/t/1100-mhdr.t b/t/1100-mhdr.t index 9937041..85128bd 100755 --- a/t/1100-mhdr.t +++ b/t/1100-mhdr.t @@ -2,7 +2,7 @@ cd ${0%/*} . ./lib.sh -plan 9 +plan 10 cat <tmp Header: foo @@ -24,3 +24,4 @@ check_same 'header-Three' 'mhdr -h header-Three ./tmp' 'echo quux' check_same 'header_Four' 'mhdr -h header_Four ./tmp' 'echo ding' check 'issue 235' 'mhdr ./tmp |grep -i header_four' +check 'non-existent file' 'mhdr ./does-not-exist ; [ $? -eq 1 ]' diff --git a/t/1500-maddr.t b/t/1500-maddr.t index cfca3e7..bccc695 100755 --- a/t/1500-maddr.t +++ b/t/1500-maddr.t @@ -1,7 +1,7 @@ #!/bin/sh -e cd ${0%/*} . ./lib.sh -plan 11 +plan 12 rm -rf test.dir mkdir test.dir @@ -82,5 +82,6 @@ check_same 'long addr' 'maddr -h long 4' 'echo "heeeeeeeeeeeeeeeeeeeeeeeeeeeeeee check_same 'decode iso8859' 'maddr -h DecodeISO8859 5' 'echo "Keld Jørn Simonsen "' check_same 'decode long iso8859' 'maddr -h DecodeLongISO8859 5' 'echo "\"If you can read this you understand the example. z a b\" "' check_same 'decode utf8' 'maddr -h DecodeUTF8 5' 'echo "z’z "' +check 'non-existent file' 'maddr -S /does/not/exist ; [ $? -eq 1 ]' ) diff --git a/t/1800-mexport.t b/t/1800-mexport.t index c0eadbd..d7192c7 100755 --- a/t/1800-mexport.t +++ b/t/1800-mexport.t @@ -1,7 +1,7 @@ #!/bin/sh -e cd ${0%/*} . ./lib.sh -plan 2 +plan 3 cat <tmp.1 Subject: message 1 @@ -24,3 +24,4 @@ mexport ./tmp.1 ./tmp.2 ./tmp.3 >./tmp.mbox check 'generated mbox has 16 lines' 'cat ./tmp.mbox | wc -l | grep 16' check 'generated mbox has 7 empty lines' 'grep -c "^$" ./tmp.mbox | grep 7' +check 'non-existent file' 'mexport ./foo-bar ; [ $? -eq 1 ]' diff --git a/t/8000-mflag.t b/t/8000-mflag.t index 65562f6..3ae51d3 100644 --- a/t/8000-mflag.t +++ b/t/8000-mflag.t @@ -1,7 +1,7 @@ #!/bin/sh -e cd ${0%/*} . ./lib.sh -plan 16 +plan 17 rm -rf test.dir mkdir test.dir @@ -35,5 +35,6 @@ check 'mark trashed' 'mflag -T 1 && [ -e "inbox/cur/1:2,T" ]' check_test 'fix seq' -eq 2 'mseq -f : | mseq -S | wc -l' check 'unmark trashed' 'mflag -t 1 && [ -e "inbox/cur/1:2," ]' check_test 'fix seq' -eq 2 'mseq -f : | mseq -S | wc -l' +check 'non-existent file' 'mflag -S /does/not/exist ; [ $? -eq 1 ]' )