diff options
| author | root <root@cloud.av8n.net> | 2012-07-13 00:51:35 -0700 | 
|---|---|---|
| committer | John Denker <jsd@av8n.com> | 2012-07-13 18:39:52 -0700 | 
| commit | 1d7eff0ba635ac5983bed820dd349af2ebee0850 (patch) | |
| tree | ca33be1951d64bf1e3f36fdd77903dc16a9644b3 /tools | |
| parent | 1ead9453f3dfc28cf797aafbcc7b6e56b69c4770 (diff) | |
better comments, working toward MODE switching
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/hi-q.c | 85 | ||||
| -rwxr-xr-x | tools/mk_smtp_rules | 11 | ||||
| -rwxr-xr-x | tools/qmail | 6 | 
3 files changed, 66 insertions, 36 deletions
| diff --git a/tools/hi-q.c b/tools/hi-q.c index aa552e1..bf9c599 100644 --- a/tools/hi-q.c +++ b/tools/hi-q.c @@ -112,7 +112,14 @@ void usage() {  ////////////////////////////////////////  // we have data coming in on fd 0. -// and control coming in on fd 1. +// and envelope / control information coming in on fd 1. + +void dump___not_used(const string var){ +  char* str = getenv(var.c_str()); +  if (str) cerr << "hi-q: " << var +                << " is set to '" << str << "'" << endl; +  else cerr << "hi-q: " << var << " is not set." << endl; +}  int main(int argc, char** argv, char const * const * env) {    int verbose(1); @@ -143,10 +150,16 @@ int main(int argc, char** argv, char const * const * env) {    typedef vector<string> VS;    vector<VS> filter; -  char* conf_name; +  string conf_var = "HI_Q_CONF"; + +  int mode(0); +  char* modevar = getenv("HI_Q_MODE"); +  if (modevar) mode = 1000 + atoi(modevar); +  cerr << "hi-q mode: " << mode << endl; +  char* conf_name;    if (argc == 1) { -    conf_name = getenv("HI_Q_CONF"); +    conf_name = getenv(conf_var.c_str());      if (!conf_name) {        usage();        exit(1); @@ -194,22 +207,30 @@ int main(int argc, char** argv, char const * const * env) {    vector<pid_t> kidpid(nkids);  // indexed by kid number  // At this point, there are some loop invariants; -// (a) fd0 is open and ready for the next child to read, and -// (b) fd1 is open but is something children can (and should) -//  throw away as soon as convenient. - -  {int ii; for (ii=0; ii < nkids; ii++){  /* loop over all kids */ +// (a) fd0 is open and has the email msg,  +//     ready for the next child to read, and +// (b) fd1 is open and has envelope information. +//     We need it to be open, so that pipe() +//     doesn't choose it.  That allows us to close +//     it and dup() something onto it. + +  for (int ii=0; ii < nkids; ii++){  /* loop over all kids */      int datapipe[2];      int kid_end; -    int lastkid = (ii == nkids-1); -#define flip(a,b) (lastkid ? b : a)  //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); +    } +  // 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 fd1 rather -// than writing it. +// except for the last kid, which reads both fd0 and fd1, +// while writing nothing. +      rslt = pipe(datapipe);      if (rslt < 0) {        fprintf(stderr, "hi-q: could not create datapipe: "); @@ -218,34 +239,37 @@ int main(int argc, char** argv, char const * const * env) {      }  //xx fprintf(stderr, "pipe: %d %d\n", datapipe[0], datapipe[1]); -    if (loose_end) { -      close(0); -      dup2(loose_end, 0); -      close(loose_end); -    } +// 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(0,1)]; -    kid_end = datapipe[flip(1,0)]; +    kid_end   = datapipe[flip(1,0)];      kidpid[ii] = fork();      if (!kidpid[ii]) {  /*** child code ***/ -// Now that we are through creating pipes, get rid -// of the placeholder: +// 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 our business +      close(loose_end);          // the reading end is none of this kid's business +                                // except last kid:  writing end -      rslt = dup2(kid_end, 1); +      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: dup2(kid(%d),1) failed: ", kid_end); +        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 we are set up to read fd0 -      // and write fd1 (except last kid reads fd1). +      // 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].size(); @@ -272,15 +296,14 @@ int main(int argc, char** argv, char const * const * env) {                  ii, kidpid[ii], kid_end);  //    sleep(1); /* let kid run a while */  #endif -  }} +  }  // here with the whole pipeline of kids running    close(0);             // the reading end of stdin was                          // delegated to the first child - -  {int ii; for (ii=0; ii<nkids-1; ii++){        /* loop over N-1 kids */ +  for (int ii=0; ii<nkids-1; ii++){        /* loop over N-1 kids */                                          /* not last kid */  #ifdef testing @@ -296,10 +319,12 @@ int main(int argc, char** argv, char const * const * env) {      else panic(ex_syserr);      // any kill, not a normal exit  #endif - -  }} +  }  //xx fprintf(stderr, "slurping %d %d\n", 1, loose_end); + +// All is well. +// Now it is safe to transfer the envelope information:    slurp(1, loose_end);    close(1);    close(loose_end); diff --git a/tools/mk_smtp_rules b/tools/mk_smtp_rules index 85c3298..eb241b0 100755 --- a/tools/mk_smtp_rules +++ b/tools/mk_smtp_rules @@ -3,16 +3,19 @@  # if /etc/tcpserver/smtp.rules does not already exist,  # create it with some reasonable defaults -dest=/etc/tcpserver/smtp.rules +dest=$1 + +: ${dest:=/etc/tcpserver/smtp.rules}  install -d $( dirname $dest ) -if ! test -r $dest ; then +if test -r $dest ; then +  1>&2 echo "Oops, destination '$dest' already exists." +  exit 1 +fi  <<EoF cat > $dest  10.:allow,RELAYCLIENT=""  127.0.0.:allow,RELAYCLIENT=""  :allow  EoF - -fi diff --git a/tools/qmail b/tools/qmail index f58a5c7..b43db75 100755 --- a/tools/qmail +++ b/tools/qmail @@ -34,8 +34,10 @@ CDB=/etc/tcpserver/smtp.cdb  : ${PIDO:=/var/qmail/bin/pido}  banner="Starting Qmail MTA:" -test -n "$mailhost"  || mailhost=$(hostname -f ) - +: ${mailhost:=0} +# Some people might use mailhost=$(hostname -f ) +# but mailhost=0 is almost always better. +# In particular it is much better as a /default/ value.  proc_running(){          proc=$1 | 
