summaryrefslogtreecommitdiff
path: root/qmail-rspawn.c
blob: 9d838e69305f33e293171412a043cffc14797cbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "fd.h"
#include "wait.h"
#include "substdio.h"
#include "exit.h"
#include "fork.h"
#include "error.h"
#include "tcpto.h"

void initialize(argc,argv)
int argc;
char **argv;
{
 tcpto_clean();
}

int truncreport = 0;

void report(ss,wstat,s,len)
substdio *ss;
int wstat;
char *s;
int len;
{
 int j;
 int k;
 int result;
 int orr;

 if (wait_crashed(wstat))
  { substdio_puts(ss,"Zqmail-remote crashed.\n"); return; }
 switch(wait_exitcode(wstat))
  {
   case 0: break;
   case 111: substdio_puts(ss,"ZUnable to run qmail-remote.\n"); return;
   default: substdio_puts(ss,"DUnable to run qmail-remote.\n"); return;
  }
 if (!len)
  { substdio_puts(ss,"Zqmail-remote produced no output.\n"); return; }

 result = -1;
 j = 0;
 for (k = 0;k < len;++k)
   if (!s[k])
    {
     if (s[j] == 'K') { result = 1; break; }
     if (s[j] == 'Z') { result = 0; break; }
     if (s[j] == 'D') break;
     j = k + 1;
    }

 orr = result;
 switch(s[0])
  {
   case 's': orr = 0; break;
   case 'h': orr = -1;
  }

 switch(orr)
  {
   case 1: substdio_put(ss,"K",1); break;
   case 0: substdio_put(ss,"Z",1); break;
   case -1: substdio_put(ss,"D",1); break;
  }

 for (k = 1;k < len;)
   if (!s[k++])
    {
     substdio_puts(ss,s + 1);
     if (result <= orr)
       if (k < len)
	 switch(s[k])
	  {
	   case 'Z': case 'D': case 'K':
             substdio_puts(ss,s + k + 1);
	  }
     break;
    }
}

int spawn(fdmess,fdout,s,r,at)
int fdmess; int fdout;
char *s; char *r; int at;
{
 int f;
 char *(args[5]);

 args[0] = "qmail-remote";
 args[1] = r + at + 1;
 args[2] = s;
 args[3] = r;
 args[4] = 0;

 if (!(f = vfork()))
  {
   if (fd_move(0,fdmess) == -1) _exit(111);
   if (fd_move(1,fdout) == -1) _exit(111);
   if (fd_copy(2,1) == -1) _exit(111);
   execvp(*args,args);
   if (error_temp(errno)) _exit(111);
   _exit(100);
  }
 return f;
}