summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-07-20 12:15:59 -0700
committerJohn Denker <jsd@av8n.com>2012-07-29 15:32:34 -0700
commit60fd39ff24975486da7d02cdf07abae31c525529 (patch)
tree329475b031811b1a17c2064a05cdc8671f1452b0
parente9b59f501b23b53eb6f230e0dfc4d50bb6995d45 (diff)
much smarter about exit status conventions
-rw-r--r--tools/filters.conf6
-rw-r--r--tools/hi-q.c23
-rw-r--r--tools/hi-test.conf4
-rw-r--r--tools/hi-test2.conf4
-rwxr-xr-xtools/hi-test3.conf5
-rw-r--r--tools/skrewt.c52
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);
}