chiark / gitweb /
Merge branches 'idx/verh' and 'idx/qmqpc'
[qmail] / condredirect.c
1 #include "sig.h"
2 #include "readwrite.h"
3 #include "exit.h"
4 #include "env.h"
5 #include "error.h"
6 #include "fork.h"
7 #include "wait.h"
8 #include "seek.h"
9 #include "qmail.h"
10 #include "strerr.h"
11 #include "substdio.h"
12 #include "fmt.h"
13
14 #define FATAL "condredirect: fatal: "
15
16 struct qmail qqt;
17
18 int mywrite(fd,buf,len) int fd; char *buf; int len;
19 {
20   qmail_put(&qqt,buf,len);
21   return len;
22 }
23
24 char inbuf[SUBSTDIO_INSIZE];
25 char outbuf[1];
26 substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf);
27 substdio ssout = SUBSTDIO_FDBUF(mywrite,-1,outbuf,sizeof outbuf);
28
29 char num[FMT_ULONG];
30
31 void main(argc,argv)
32 int argc;
33 char **argv;
34 {
35   char *sender;
36   char *dtline;
37   int pid;
38   int wstat;
39   char *qqx;
40  
41   if (!argv[1] || !argv[2])
42     strerr_die1x(100,"condredirect: usage: condredirect newaddress program [ arg ... ]");
43  
44   pid = fork();
45   if (pid == -1)
46     strerr_die2sys(111,FATAL,"unable to fork: ");
47   if (pid == 0) {
48     execvp(argv[2],argv + 2);
49     if (error_temp(errno)) _exit(111);
50     _exit(100);
51   }
52   if (wait_pid(&wstat,pid) == -1)
53     strerr_die2x(111,FATAL,"wait failed");
54   if (wait_crashed(wstat))
55     strerr_die2x(111,FATAL,"child crashed");
56   switch(wait_exitcode(wstat)) {
57     case 0: break;
58     case 111: strerr_die2x(111,FATAL,"temporary child error");
59     default: _exit(0);
60   }
61
62   if (seek_begin(0) == -1)
63     strerr_die2sys(111,FATAL,"unable to rewind: ");
64   sig_pipeignore();
65  
66   sender = env_get("SENDER");
67   if (!sender) strerr_die2x(100,FATAL,"SENDER not set");
68   dtline = env_get("DTLINE");
69   if (!dtline) strerr_die2x(100,FATAL,"DTLINE not set");
70  
71   if (qmail_open(&qqt) == -1)
72     strerr_die2sys(111,FATAL,"unable to fork: ");
73   qmail_puts(&qqt,dtline);
74   if (substdio_copy(&ssout,&ssin) != 0)
75     strerr_die2sys(111,FATAL,"unable to read message: ");
76   substdio_flush(&ssout);
77  
78   num[fmt_ulong(num,qmail_qp(&qqt))] = 0;
79
80   qmail_from(&qqt,sender);
81   qmail_to(&qqt,argv[1]);
82   qqx = qmail_close(&qqt);
83   if (*qqx) strerr_die2x(*qqx == 'D' ? 100 : 111,FATAL,qqx + 1);
84   strerr_die2x(99,"condredirect: qp ",num);
85 }