nightmaremail

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

qmail-rspawn.c (2349B)


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