condredirect.c (1953B)
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 GEN_QMAILPUT_WRITE(&qqt) 19 20 char inbuf[SUBSTDIO_INSIZE]; 21 char outbuf[1]; 22 substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof(inbuf)); 23 substdio ssout = SUBSTDIO_FDBUF(qmail_put_write,-1,outbuf,sizeof(outbuf)); 24 25 char num[FMT_ULONG]; 26 27 int main(int argc, char **argv) 28 { 29 char *sender; 30 char *dtline; 31 int pid; 32 int wstat; 33 char *qqx; 34 35 if (argc < 3) 36 strerr_die1x(100,"condredirect: usage: condredirect newaddress program [ arg ... ]"); 37 38 pid = fork(); 39 if (pid == -1) 40 strerr_die2sys(111,FATAL,"unable to fork: "); 41 if (pid == 0) { 42 execvp(argv[2],argv + 2); 43 if (error_temp(errno)) _exit(111); 44 _exit(100); 45 } 46 if (wait_pid(&wstat,pid) == -1) 47 strerr_die2x(111,FATAL,"wait failed"); 48 if (wait_crashed(wstat)) 49 strerr_die2x(111,FATAL,"child crashed"); 50 switch(wait_exitcode(wstat)) { 51 case 0: break; 52 case 111: strerr_die2x(111,FATAL,"temporary child error"); 53 default: _exit(0); 54 } 55 56 if (seek_begin(0) == -1) 57 strerr_die2sys(111,FATAL,"unable to rewind: "); 58 sig_pipeignore(); 59 60 sender = env_get("SENDER"); 61 if (!sender) strerr_die2x(100,FATAL,"SENDER not set"); 62 dtline = env_get("DTLINE"); 63 if (!dtline) strerr_die2x(100,FATAL,"DTLINE not set"); 64 65 if (qmail_open(&qqt) == -1) 66 strerr_die2sys(111,FATAL,"unable to fork: "); 67 qmail_puts(&qqt,dtline); 68 if (substdio_copy(&ssout,&ssin) != 0) 69 strerr_die2sys(111,FATAL,"unable to read message: "); 70 substdio_flush(&ssout); 71 72 num[fmt_ulong(num,qmail_qp(&qqt))] = 0; 73 74 qmail_from(&qqt,sender); 75 qmail_to(&qqt,argv[1]); 76 qqx = qmail_close(&qqt); 77 if (*qqx) strerr_die2x(*qqx == 'D' ? 100 : 111,FATAL,qqx + 1); 78 strerr_die2x(99,"condredirect: qp ",num); 79 }