diff options
| author | John Denker <jsd@av8n.com> | 2012-07-15 05:22:05 -0700 | 
|---|---|---|
| committer | John Denker <jsd@av8n.com> | 2012-07-15 05:22:05 -0700 | 
| commit | f96288efc416089567dac7bcfa674b1cd6931c97 (patch) | |
| tree | 2ffe080000ad1306bf5d3337ce27c9ec829fa8ed | |
| parent | 5b14bc41824ae70d33f1e7cd1486aec32b46b3e1 (diff) | |
untested possible implementation of exeunt ... kill peers
as soon as we know the msg is spam
| -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);  }  | 
