From d4ca9eda839b2c9d3bbbf8b48617977f483001b2 Mon Sep 17 00:00:00 2001 From: John Denker Date: Thu, 19 Jul 2012 17:24:43 -0700 Subject: bare beginnings of a greylisting system --- tools/hi-q.c | 111 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 51 deletions(-) (limited to 'tools/hi-q.c') 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 #include /* for exit(), getenv() */ -#include +#include /* for perror */ #include #include /* for fork(), wait() */ #include @@ -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 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 -- cgit v1.2.3