summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-07-15 05:22:05 -0700
committerJohn Denker <jsd@av8n.com>2012-07-15 05:22:05 -0700
commitf96288efc416089567dac7bcfa674b1cd6931c97 (patch)
tree2ffe080000ad1306bf5d3337ce27c9ec829fa8ed
parent5b14bc41824ae70d33f1e7cd1486aec32b46b3e1 (diff)
untested possible implementation of exeunt ... kill peers
as soon as we know the msg is spam
-rw-r--r--tools/hi-q.c58
-rw-r--r--tools/skrewt.c45
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);
}