summaryrefslogtreecommitdiff
path: root/tools/hi-q.c
diff options
context:
space:
mode:
authorJohn Denker <jsd@av8n.com>2012-07-20 00:24:43 (GMT)
committerJohn Denker <jsd@av8n.com>2012-07-20 00:24:43 (GMT)
commitd4ca9eda839b2c9d3bbbf8b48617977f483001b2 (patch)
tree0b8a5c2a93c48ee52a72a3c3d9d69fb563280059 /tools/hi-q.c
parent82616449ee0c9f704e8c123d8b485c65fe428179 (diff)
bare beginnings of a greylisting system
Diffstat (limited to 'tools/hi-q.c')
-rw-r--r--tools/hi-q.c111
1 files changed, 60 insertions, 51 deletions
diff --git a/tools/hi-q.c b/tools/hi-q.c
index 2ddc448..21724a1 100644
--- a/tools/hi-q.c
+++ b/tools/hi-q.c
@@ -11,7 +11,7 @@
#include <unistd.h>
#include <stdlib.h> /* for exit(), getenv() */
-#include <stdio.h>
+#include <stdio.h> /* for perror */
#include <errno.h>
#include <sys/types.h> /* for fork(), wait() */
#include <sys/stat.h>
@@ -29,6 +29,7 @@ using namespace std;
// error exit codes, mostly as stated in qmail.c
const int ex_good = 0;
const int ex_spam = 21;
+const int ex_grey = 70;
const int ex_syserr = 71;
const int ex_comerr = 74;
@@ -139,7 +140,7 @@ int xclose(int arg){
extern char** environ;
-typedef enum {gray, black, qq, fail} moder;
+typedef enum {grey, black, qq, fail} moder;
class jobber{
public:
@@ -161,8 +162,8 @@ public:
void setmode(const string _mode) {
if (0) {}
- else if (_mode == "gray") mode = gray;
- else if (_mode == "grey") mode = gray; // variant spelling
+ else if (_mode == "gray") mode = grey;
+ else if (_mode == "grey") mode = grey; // variant spelling
else if (_mode == "black") mode = black;
else if (_mode == "qq") mode = qq;
else {
@@ -175,8 +176,8 @@ public:
int main(int argc, char** argv) {
progname = *argv;
mypid = getpid();
- dump("TCPREMOTEIP");
- dump("TCPREMOTEHOST");
+// dump("TCPREMOTEIP");
+// dump("TCPREMOTEHOST");
int verbose(0);
int kidstatus;
@@ -270,41 +271,44 @@ int main(int argc, char** argv) {
// to close it and dup() something useful onto it.
map<int,int> iiofpid;
- for (unsigned int ii=0; ii < nkids; ii++){ /* loop starting all kids */
- int datapipe[2];
- int kid_end;
+ for (unsigned int ii=0; ii < nkids; ii++){ /* loop starting all kids */
//xx fprintf(stderr, "Top of loop %d loose: %d\n", ii, loose_end);
- if (loose_end) {
- close(0);
- dup2(loose_end, 0);
- close(loose_end);
- }
+ int kid_end;
+ if (filter[ii].mode != grey){
+ int datapipe[2];
-// Create a pipe, which will be used to connect
-// this child's fd1 to the next child's fd0 ...
-// except for the last kid, which reads both fd0 and fd1,
-// while writing nothing.
+ if (loose_end) {
+ close(0);
+ dup2(loose_end, 0);
+ close(loose_end);
+ }
- rslt = pipe(datapipe);
- if (rslt < 0) {
- fprintf(stderr, "hi-q: could not create datapipe: ");
- perror(0);
- panic(ex_syserr);
- }
+ // Create a pipe, which will be used to connect
+ // this child's fd1 to the next child's fd0 ...
+ // except for the last kid, which reads both fd0 and fd1,
+ // while writing nothing.
-//xx fprintf(stderr, "pipe: %d %d\n", datapipe[0], datapipe[1]);
+ rslt = pipe(datapipe);
+ if (rslt < 0) {
+ fprintf(stderr, "hi-q: could not create datapipe: ");
+ perror(0);
+ panic(ex_syserr);
+ }
-// For N-1 kids, the loose end feeds forward.
-// It will be written by this kid and read by the next kid.
-// For the last kid, the loose end connects to hi-q.
-// It will be written by hi-q and read by the last kid.
+ //xx fprintf(stderr, "pipe: %d %d\n", datapipe[0], datapipe[1]);
- int lastkid = (ii == nkids-1);
-#define flip(a,b) (lastkid ? b : a)
- loose_end = datapipe[flip(rEnd, wEnd)];
- kid_end = datapipe[flip(wEnd, rEnd)];
+ // For N-1 kids, the loose end feeds forward.
+ // It will be written by this kid and read by the next kid.
+ // For the last kid, the loose end connects to hi-q.
+ // It will be written by hi-q and read by the last kid.
+
+ int lastkid = (ii == nkids-1);
+ #define flip(a,b) (lastkid ? b : a)
+ loose_end = datapipe[flip(rEnd, wEnd)];
+ kid_end = datapipe[flip(wEnd, rEnd)];
+ }
kidpid[ii] = fork();
if (kidpid[ii] == -1) {
@@ -358,24 +362,23 @@ int main(int argc, char** argv) {
}
}
-// Now that we are through creating pipes, we don't
-// need to continue blocking fd1:
- close(1);
-
- close(loose_end); // the reading end is none of this kid's business
- // except last kid: writing end
+ if (filter[ii].mode != grey){
+ close(loose_end); // the reading end is none of this kid's business
+ // except last kid: writing end
+
+ // Note this does an implicit close on the previously-open fd1:
+ rslt = dup2(kid_end, 1); // the writing end is stdout for this kid
+ // except last kid: nonstandard input
+ if (rslt < 0) {
+ fprintf(stderr, "hi-q: kid %d: dup2(%d,1) failed: ", ii, kid_end);
+ perror(0);
+ exit(ex_syserr);
+ }
- rslt = dup2(kid_end, 1); // the writing end is stdout for this kid
- // except last kid: nonstandard input
- if (rslt < 0) {
- fprintf(stderr, "hi-q: kid %d: dup2(%d,1) failed: ", ii, kid_end);
- perror(0);
- exit(ex_syserr);
+ close(kid_end); // use fd1 instead now
+ // OK, at this point this kid is set up to read fd0 and write fd1
+ // (except last kid reads fd1 as well as fd0).
}
-
- close(kid_end); // use fd1 instead now
- // OK, at this point this kid is set up to read fd0 and write fd1
- // (except last kid reads fd1 as well as fd0).
//// probe_fd();
int ntok = filter[ii].cmd.size();
@@ -499,14 +502,20 @@ int main(int argc, char** argv) {
if (best_blame) {
string short_name("");
int kidno(iiofpid[argbest_blame]);
+ string exword = "spam";
+ int excode = ex_spam;
+ if (filter[kidno].mode == grey) {
+ exword = "greylisting";
+ excode = ex_grey;
+ }
if (WIFEXITED(best_blame)) {
int sts = WEXITSTATUS(best_blame);
if (sts == 1) {
cerr << "hi-q says: kid[" << kidno << "]"
<< " pid " << argbest_blame
<< " i.e. '" << filter[kidno].cmd[0] << "'"
- << " reports spam." << endl;
- panic(ex_spam);
+ << " reports " << exword << endl;
+ panic(excode);
}
if (sts != 0) {
cerr << "hi-q says: kid " << argbest_blame