diff options
-rw-r--r-- | tools/hi-q.c | 58 | ||||
-rw-r--r-- | tools/skrewt.c | 45 |
2 files changed, 71 insertions, 32 deletions
diff --git a/tools/hi-q.c b/tools/hi-q.c index 9d85b7a..8107e27 100644 --- a/tools/hi-q.c +++ b/tools/hi-q.c @@ -22,7 +22,8 @@ using namespace std; #include <vector> #include <sstream> -// error exit codes, as stated in qmail.c +// error exit codes, mostly as stated in qmail.c +const int ex_good = 0; const int ex_spam = 21; const int ex_syserr = 71; const int ex_comerr = 74; @@ -392,7 +393,7 @@ int main(int argc, char** argv) { close(sync[rEnd]); close(0); // Housecleaning: the reading end of stdin was - // delegated to the first child, + // delegated to the first child, // so we don't need it. if (verbose) for (unsigned int ii = 0; ii < nkids; ii++) { @@ -406,33 +407,44 @@ int main(int argc, char** argv) { cerr << endl; } - for (unsigned int ii=0; ii<nkids-1; ii++){ /* loop over N-1 kids */ - /* _not_ including last kid */ +// loop over N-1 kids ... _not_ including last kid + for (unsigned int ii=0; ii<nkids-1; ii++){ #ifdef testing blurb(ii, kidpid); #else - somekid = waitpid(kidpid[ii], &kidstatus, WUNTRACED); - if (somekid) {} // avoid silly compiler warning - if (WIFEXITED(kidstatus)) { - int sts = WEXITSTATUS(kidstatus); - if (sts == 1) { - cerr << "hi-q says: kid " << ii - << " i.e. '" << filter[ii][0] << "' reports spam." - << endl; - panic(ex_spam); - } - if (sts != 0) { - cerr << "hi-q says: kid " << ii - << " i.e. '" << filter[ii][0] << "'" - << " suffered an error: " << sts - << endl; - panic(ex_syserr); + for (;;){ + somekid = waitpid(kidpid[ii], &kidstatus, WUNTRACED); + if (somekid) {} // avoid silly compiler warning + if (WIFEXITED(kidstatus)) { + int sts = WEXITSTATUS(kidstatus); + if (sts == 1) { + cerr << "hi-q says: kid " << ii + << " i.e. '" << filter[ii][0] << "' reports spam." + << endl; + panic(ex_spam); + } + if (sts != 0) { + cerr << "hi-q says: kid " << ii + << " i.e. '" << filter[ii][0] << "'" + << " exited with bad status: " << sts + << endl; + panic(ex_syserr); + } + break; // kidstatus==0 means clean exit; + // go check other kids + } else if (WIFSIGNALED(kidstatus)) { + cerr << "hi-q says: kid " << ii + << " i.e. '" << filter[ii][0] << "'" + << " was killed by signal: " << WTERMSIG(kidstatus) + << endl; + + panic(ex_syserr); // any kill, not a normal exit + } else { + // some status change other than exit or kill + // perhaps stopped for terminal input } - /* otherwise kidstatus==0 and we fall through */ } - else panic(ex_syserr); // any kill, not a normal exit #endif - } //xx fprintf(stderr, "slurping %d %d\n", 1, loose_end); diff --git a/tools/skrewt.c b/tools/skrewt.c index b81f0ea..2ca32a4 100644 --- a/tools/skrewt.c +++ b/tools/skrewt.c @@ -8,6 +8,9 @@ #include <stdlib.h> /* for exit() */ #include <string> /* for strcmp() */ #include <ctype.h> /* toupper */ +#include <signal.h> + +#include <stdio.h> /* perror */ using namespace std; @@ -30,6 +33,11 @@ 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); + ///////////////////////////////////////////////////////// // Case insensitive comparison of strings @@ -97,6 +105,25 @@ int prefix(const string shorter, const string longer){ return shorter == longer.substr(0, shorter.length()); } +void exeunt(const int sts){ + if (sts == sa_good) exit(sts); + + const char* foo = getenv("HI_Q_GROUP"); + if (!foo) exit(sts); + +// No point in signalling ourself: + sighandler_t rslt = signal(SIGUSR1, SIG_IGN); + if (rslt == SIG_ERR) { + cerr << "error setting signal" << endl; + } + int k = kill(-atoi(foo), SIGUSR1); + if (k) { + cerr << "kill failed on group " << atoi(foo) << " ... "; + perror(0); + } + exit(sts); +} + //////////////////////////////////////////////////////////// int main(int _argc, const char** _argv){ //// pid_t pid = getpid(); @@ -117,18 +144,18 @@ int main(int _argc, const char** _argv){ if (prefix(arg, "-maxsize")) { if (!argc) { cerr << "Option -maxsize requires an argument" << endl; - exit(1); + exit(sa_usage); } maxsize = atoi(*argv); argv++; argc--; } if (arg.substr(0,1) == "-") { cerr << "Unrecognized option '" << arg << "'" << endl; cerr << "For help, try: " << progname << " -help" << endl; - exit(1); + exit(sa_usage); } else { cerr << "Extraneous verbiage '" << arg << "'" << endl; cerr << "For help, try: " << progname << " -help" << endl; - exit(1); + exit(sa_usage); } } @@ -157,14 +184,14 @@ int main(int _argc, const char** _argv){ msgsize += line.length()+1; if (msgsize > maxsize) { cerr << "skrewt rejection: bigger than " << maxsize << endl; - exit(1); + exeunt(sa_spam); } header += "\n" + line; } if (header.length() == 0) { if (!gotdate) { cerr << "skrewt rejection: no date" << endl; - exit(1); // disallow mail with no date + exeunt(sa_spam); // disallow mail with no date } inheads = 0; } @@ -212,7 +239,7 @@ 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; - exit(1); + exeunt(sa_spam); } } } @@ -223,7 +250,7 @@ int main(int _argc, const char** _argv){ msgsize += line.length()+1; if (msgsize > maxsize) { cerr << "skrewt rejection: bigger than " << maxsize << endl; - exit(1); + exeunt(sa_spam); } if (line == "--" + boundary) { inheads = 1; @@ -239,8 +266,8 @@ int main(int _argc, const char** _argv){ if (0) cerr << "textlines: " << textlines << endl; if (!textlines) { cerr << "skrewt rejection: no text" << endl; - exit(1); + exeunt(sa_spam); } cerr << "skrewt normal completion" << endl; - return 0; + exit(sa_good); } |