condredirect.c
changeset 0 068428edee47
equal deleted inserted replaced
-1:000000000000 0:068428edee47
       
     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 }