summaryrefslogtreecommitdiff
path: root/tools/skrewt.c
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-07-20 19:15:59 (GMT)
committerJohn Denker <jsd@av8n.com>2012-07-29 22:32:34 (GMT)
commit60fd39ff24975486da7d02cdf07abae31c525529 (patch)
tree329475b031811b1a17c2064a05cdc8671f1452b0 /tools/skrewt.c
parente9b59f501b23b53eb6f230e0dfc4d50bb6995d45 (diff)
much smarter about exit status conventions
Diffstat (limited to 'tools/skrewt.c')
-rw-r--r--tools/skrewt.c52
1 files changed, 35 insertions, 17 deletions
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);
}