nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

qmail-rspawn.c (2376B)


      1 #include "fd.h"
      2 #include "spawn.h"
      3 #include "wait.h"
      4 #include "substdio.h"
      5 #include "exit.h"
      6 #include "fork.h"
      7 #include "error.h"
      8 #include "tcpto.h"
      9 #include "uidgid.h"
     10 #include "auto_uids.h"
     11 #include "auto_users.h"
     12 #include "env.h"
     13 
     14 void initialize(argc,argv)
     15 int argc;
     16 char **argv;
     17 {
     18  auto_uidq = inituid(auto_userq);
     19  tcpto_clean();
     20 }
     21 
     22 int truncreport = 0;
     23 
     24 void report(ss,wstat,s,len)
     25 substdio *ss;
     26 int wstat;
     27 char *s;
     28 int len;
     29 {
     30  int j;
     31  int k;
     32  int result;
     33  int orr;
     34 
     35  if (wait_crashed(wstat))
     36   { substdio_puts(ss,"Zqmail-remote crashed.\n"); return; }
     37  switch(wait_exitcode(wstat))
     38   {
     39    case 0: break;
     40    case 111: substdio_puts(ss,"ZUnable to run qmail-remote.\n"); return;
     41    default: substdio_puts(ss,"DUnable to run qmail-remote.\n"); return;
     42   }
     43  if (!len)
     44   { substdio_puts(ss,"Zqmail-remote produced no output.\n"); return; }
     45 
     46  result = -1;
     47  j = 0;
     48  for (k = 0;k < len;++k)
     49    if (!s[k])
     50     {
     51      if (s[j] == 'I') { result = -2; break; }; // Informational reports have no use to rspawn. In future, they should probably be posted upchain.
     52      if (s[j] == 'K') { result = 1; break; }
     53      if (s[j] == 'Z') { result = 0; break; }
     54      if (s[j] == 'D') break;
     55      j = k + 1;
     56     }
     57 
     58  orr = result;
     59  switch(s[0])
     60   {
     61    case 's': orr = 0; break;
     62    case 'h': orr = -1;
     63   }
     64 
     65  switch(orr)
     66   {
     67    case 1: substdio_put(ss,"K",1); break;
     68    case 0: substdio_put(ss,"Z",1); break;
     69    case -1: substdio_put(ss,"D",1); break;
     70    case -2: return; // Informational reports have no use to rspawn. In future, they should probably be posted upchain.
     71   }
     72 
     73  for (k = 1;k < len;)
     74    if (!s[k++])
     75     {
     76      substdio_puts(ss,s + 1);
     77      if (result <= orr)
     78        if (k < len)
     79 	 switch(s[k])
     80 	  {
     81 	   case 'Z': case 'D': case 'K':
     82              substdio_puts(ss,s + k + 1);
     83 	  }
     84      break;
     85     }
     86 }
     87 
     88 static char *setup_qrargs()
     89 {
     90  static char *qr;
     91  if (qr) return qr;
     92  qr = env_get("QMAILREMOTE");
     93  if (qr) return qr;
     94  qr = "qmail-remote";
     95  return qr;
     96 }
     97 
     98 int spawn(int fdmess, int fdout, char *s, char *r, int at)
     99 {
    100  int f;
    101  char *(args[5]);
    102 
    103  args[0] = setup_qrargs();
    104  args[1] = r + at + 1;
    105  args[2] = s;
    106  args[3] = r;
    107  args[4] = 0;
    108 
    109  if (!(f = fork()))
    110   {
    111    if (fd_move(0,fdmess) == -1) _exit(111);
    112    if (fd_move(1,fdout) == -1) _exit(111);
    113    if (fd_copy(2,1) == -1) _exit(111);
    114    execvp(*args,args);
    115    if (error_temp(errno)) _exit(111);
    116    _exit(100);
    117   }
    118  return f;
    119 }