diff options
author | John Denker <jsd@av8n.com> | 2012-07-20 12:15:59 -0700 |
---|---|---|
committer | John Denker <jsd@av8n.com> | 2012-07-20 12:15:59 -0700 |
commit | 6923595761a5006862bd785c63b35eb988543362 (patch) | |
tree | 144fcd365ccdc2842e4b99b5505a056b42f917a3 | |
parent | d77d56ab050f7763f06461787cc862b6ec0095c4 (diff) |
much smarter about exit status conventions
-rw-r--r-- | tools/filters.conf | 6 | ||||
-rw-r--r-- | tools/hi-q.c | 23 | ||||
-rw-r--r-- | tools/hi-test.conf | 4 | ||||
-rw-r--r-- | tools/hi-test2.conf | 4 | ||||
-rwxr-xr-x | tools/hi-test3.conf | 5 | ||||
-rw-r--r-- | tools/skrewt.c | 52 |
6 files changed, 63 insertions, 31 deletions
diff --git a/tools/filters.conf b/tools/filters.conf index 641b792..dfd1180 100644 --- a/tools/filters.conf +++ b/tools/filters.conf @@ -1,5 +1,5 @@ # configuration file for hi-q -black /var/qmail/bin/skrewt -gray /var/qmail/bin/greylist -black /usr/local/bin/spamc -Y 0 -s 1000000 +series /var/qmail/bin/skrewt +stub /var/qmail/bin/greylist +sa /usr/local/bin/spamc -Y 0 -s 1000000 qq /var/qmail/bin/qmail-queue diff --git a/tools/hi-q.c b/tools/hi-q.c index f195508..369935e 100644 --- a/tools/hi-q.c +++ b/tools/hi-q.c @@ -68,6 +68,7 @@ foo_sa(TOOBIG, 98, "message was too big to process (see --max-size)" void panic(const int sts) { // FIXME: stop other children + cerr << "hi-q: panic called with " << sts << endl; exit(sts); } @@ -171,7 +172,15 @@ int xclose(int arg){ extern char** environ; -typedef enum {grey, black, qq, fail} moder; +// meanings: +// sa is a filter, using not-very-expressive exit codes: 0=ham 1=spam. +// stub is not a filter; no stdin or stdout; just looks at environment. +// series is a filter. +// qq is not a filter, just an absorber. +// +// Note that series and stub use the same exit codes as qq. +// +typedef enum {series, stub, sa, qq, fail} moder; class jobber{ public: @@ -193,9 +202,9 @@ public: void setmode(const string _mode) { if (0) {} - else if (_mode == "gray") mode = grey; - else if (_mode == "grey") mode = grey; // variant spelling - else if (_mode == "black") mode = black; + else if (_mode == "sa") mode = sa; + else if (_mode == "stub") mode = stub; + else if (_mode == "series") mode = series; else if (_mode == "qq") mode = qq; else { cerr << "jobber: bad mode: " << _mode << endl; @@ -310,7 +319,7 @@ bar //xx fprintf(stderr, "Top of loop %d loose: %d\n", ii, loose_end); int kid_end; - if (filter[ii].mode != grey){ + if (filter[ii].mode != stub){ int datapipe[2]; if (loose_end) { @@ -396,7 +405,7 @@ bar } } - if (filter[ii].mode != grey){ + if (filter[ii].mode != stub){ close(loose_end); // the reading end is none of this kid's business // except last kid: writing end @@ -540,7 +549,7 @@ bar string exword = "spam"; // default, for non-modern status codes int excode = ex_spam; // default, for non-modern status codes int sts = WEXITSTATUS(best_blame); - if (filter[kidno].mode == grey) { + if (filter[kidno].mode != sa) { exword = codemap[sts]; excode = sts; } diff --git a/tools/hi-test.conf b/tools/hi-test.conf index a89640d..aa6a1cf 100644 --- a/tools/hi-test.conf +++ b/tools/hi-test.conf @@ -1,6 +1,6 @@ # comment # another comment, with blank line between -black hi-test x0 -snooze 10 -black hi-test x1 -snooze 1 -exit 2 -kill +series hi-test x0 -snooze 10 +stub hi-test x1 -snooze 1 -exit 21 -kill qq hi-test x2 -snooze 10 diff --git a/tools/hi-test2.conf b/tools/hi-test2.conf index 3c1422c..e8e4390 100644 --- a/tools/hi-test2.conf +++ b/tools/hi-test2.conf @@ -1,3 +1,3 @@ -grey hi-test x0 -snooze 10 -gray greylist +stub hi-test x0 -snooze 10 +stub greylist qq hi-test x1 -snooze 1 -exit 3 diff --git a/tools/hi-test3.conf b/tools/hi-test3.conf new file mode 100755 index 0000000..714073a --- /dev/null +++ b/tools/hi-test3.conf @@ -0,0 +1,5 @@ +#! /bin/echo 1</dev/null </dev/null hi-q hi-test3.conf + +stub hi-test x0 -snooze 10 +sa hi-test x1 -snooze 1 -exit 0 +qq hi-test x1 -snooze 10 -exit 0 diff --git a/tools/skrewt.c b/tools/skrewt.c index 2ca32a4..d0289a6 100644 --- a/tools/skrewt.c +++ b/tools/skrewt.c @@ -19,7 +19,7 @@ void usage(const int sts){ "Usage: skrewt [options]\n" "\n" " Scrutinizes email. Reads stdin, copies it to stdout.\n" -" Exit result 0 means good, 1 means rejection (spam).\n" +" Exit result 0 means good, 21 means rejection (spam).\n" " Writes reason for rejection to stderr.\n" "\n" " Typically used as a filter in a pipeline, along with spamc -E\n" @@ -33,10 +33,20 @@ void usage(const int sts){ exit(sts); } -// exit codes, compatible with spamassassin (not with qmail-queue) -const int sa_good(0); -const int sa_spam(1); -const int sa_usage(64); +// error exit codes, mostly as stated in qmail.c +#define bar \ +foo(good, 0) ;\ +foo(spam, 21) ;\ +foo(permerr, 31) ;\ +foo(usage, 39) ;\ +foo(greylisting, 70) ;\ +foo(syserr, 71) ;\ +foo(comerr, 74) ; + +#define foo(name, num) const int ex_ ## name = num +bar +#undef foo + ///////////////////////////////////////////////////////// // Case insensitive comparison of strings @@ -106,7 +116,7 @@ int prefix(const string shorter, const string longer){ } void exeunt(const int sts){ - if (sts == sa_good) exit(sts); + if (sts == ex_good) exit(sts); const char* foo = getenv("HI_Q_GROUP"); if (!foo) exit(sts); @@ -144,18 +154,18 @@ int main(int _argc, const char** _argv){ if (prefix(arg, "-maxsize")) { if (!argc) { cerr << "Option -maxsize requires an argument" << endl; - exit(sa_usage); + exit(ex_usage); } maxsize = atoi(*argv); argv++; argc--; } if (arg.substr(0,1) == "-") { cerr << "Unrecognized option '" << arg << "'" << endl; cerr << "For help, try: " << progname << " -help" << endl; - exit(sa_usage); + exit(ex_usage); } else { cerr << "Extraneous verbiage '" << arg << "'" << endl; cerr << "For help, try: " << progname << " -help" << endl; - exit(sa_usage); + exit(ex_usage); } } @@ -172,6 +182,10 @@ int main(int _argc, const char** _argv){ string header; if (getline(cin, header).fail()) continue; msgsize += header.length()+1; + if (msgsize > maxsize) { + cerr << "skrewt rejection: bigger than " << maxsize << endl; + exeunt(ex_spam); + } for (;;) { if (cin.eof()) break; if (cin.bad()) return 1; @@ -184,18 +198,22 @@ int main(int _argc, const char** _argv){ msgsize += line.length()+1; if (msgsize > maxsize) { cerr << "skrewt rejection: bigger than " << maxsize << endl; - exeunt(sa_spam); + exeunt(ex_spam); } header += "\n" + line; } - if (header.length() == 0) { + int len = header.length(); + if (len && header[len-1] == '\r') len--; // reduced length, not counting <cr> + if (len == 0) { if (!gotdate) { cerr << "skrewt rejection: no date" << endl; - exeunt(sa_spam); // disallow mail with no date + exeunt(ex_spam); // disallow mail with no date } inheads = 0; + //cerr << "end of headers" << endl; } else { +// here if it's a header line string headword; string rest; size_t where = header.find(":"); @@ -239,18 +257,18 @@ int main(int _argc, const char** _argv){ } else if (headword == "subject") { if (rest.find("-please-bounce-this-") != string::npos) { cerr << "skrewt rejection: by request" << endl; - exeunt(sa_spam); + exeunt(ex_spam); } } } - cout << header << endl; + //cout << header.length() << " ... " << header << endl; } else { string line; if (!getline(cin, line).fail()) { msgsize += line.length()+1; if (msgsize > maxsize) { cerr << "skrewt rejection: bigger than " << maxsize << endl; - exeunt(sa_spam); + exeunt(ex_spam); } if (line == "--" + boundary) { inheads = 1; @@ -266,8 +284,8 @@ int main(int _argc, const char** _argv){ if (0) cerr << "textlines: " << textlines << endl; if (!textlines) { cerr << "skrewt rejection: no text" << endl; - exeunt(sa_spam); + exeunt(ex_spam); } cerr << "skrewt normal completion" << endl; - exit(sa_good); + exit(ex_good); } |