chiark / gitweb /
Merge branches 'idx/verh' and 'idx/qmqpc'
[qmail] / qmail-rspawn.c
1 #include "fd.h"
2 #include "wait.h"
3 #include "substdio.h"
4 #include "exit.h"
5 #include "fork.h"
6 #include "error.h"
7 #include "tcpto.h"
8
9 void initialize(argc,argv)
10 int argc;
11 char **argv;
12 {
13  tcpto_clean();
14 }
15
16 int truncreport = 0;
17
18 void report(ss,wstat,s,len)
19 substdio *ss;
20 int wstat;
21 char *s;
22 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] == 'K') { result = 1; break; }
46      if (s[j] == 'Z') { result = 0; break; }
47      if (s[j] == 'D') break;
48      j = k + 1;
49     }
50
51  orr = result;
52  switch(s[0])
53   {
54    case 's': orr = 0; break;
55    case 'h': orr = -1;
56   }
57
58  switch(orr)
59   {
60    case 1: substdio_put(ss,"K",1); break;
61    case 0: substdio_put(ss,"Z",1); break;
62    case -1: substdio_put(ss,"D",1); break;
63   }
64
65  for (k = 1;k < len;)
66    if (!s[k++])
67     {
68      substdio_puts(ss,s + 1);
69      if (result <= orr)
70        if (k < len)
71          switch(s[k])
72           {
73            case 'Z': case 'D': case 'K':
74              substdio_puts(ss,s + k + 1);
75           }
76      break;
77     }
78 }
79
80 int spawn(fdmess,fdout,s,r,at)
81 int fdmess; int fdout;
82 char *s; char *r; int at;
83 {
84  int f;
85  char *(args[5]);
86
87  args[0] = "qmail-remote";
88  args[1] = r + at + 1;
89  args[2] = s;
90  args[3] = r;
91  args[4] = 0;
92
93  if (!(f = vfork()))
94   {
95    if (fd_move(0,fdmess) == -1) _exit(111);
96    if (fd_move(1,fdout) == -1) _exit(111);
97    if (fd_copy(2,1) == -1) _exit(111);
98    execvp(*args,args);
99    if (error_temp(errno)) _exit(111);
100    _exit(100);
101   }
102  return f;
103 }