X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/qmail/blobdiff_plain/2117e02ec495fdfd6e96b39778b701a5bcff8aa5..897b03dfcf776b99815eaddde4d58479f05ba166:/condredirect.c diff --git a/condredirect.c b/condredirect.c index c6a2e6d..593d2f5 100644 --- a/condredirect.c +++ b/condredirect.c @@ -7,81 +7,79 @@ #include "wait.h" #include "seek.h" #include "qmail.h" -#include "stralloc.h" -#include "subfd.h" +#include "strerr.h" #include "substdio.h" +#include "fmt.h" -void die_success() { _exit(0); } -void die_99() { _exit(99); } -void die_perm(s) char *s; { substdio_putsflush(subfderr,s); _exit(100); } -void die_temp(s) char *s; { substdio_putsflush(subfderr,s); _exit(111); } -void die_nomem() { die_temp("condredirect: fatal: out of memory\n"); } +#define FATAL "condredirect: fatal: " struct qmail qqt; int mywrite(fd,buf,len) int fd; char *buf; int len; { - qmail_put(&qqt,buf,len); - return len; + qmail_put(&qqt,buf,len); + return len; } -substdio ssin; -substdio ssout; char inbuf[SUBSTDIO_INSIZE]; -char outbuf[16]; +char outbuf[1]; +substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); +substdio ssout = SUBSTDIO_FDBUF(mywrite,-1,outbuf,sizeof outbuf); + +char num[FMT_ULONG]; void main(argc,argv) int argc; char **argv; { - char *sender; - char *dtline; - int pid; - int wstat; - - if (!argv[1] || !argv[2]) - die_perm("condredirect: usage: condredirect newaddress program arg ...\n"); - - switch(pid = fork()) - { - case -1: die_temp("condredirect: fatal: unable to fork\n"); - case 0: - execvp(argv[2],argv + 2); - if (error_temp(errno)) _exit(111); - _exit(100); + char *sender; + char *dtline; + int pid; + int wstat; + char *qqx; + + if (!argv[1] || !argv[2]) + strerr_die1x(100,"condredirect: usage: condredirect newaddress program [ arg ... ]"); + + pid = fork(); + if (pid == -1) + strerr_die2sys(111,FATAL,"unable to fork: "); + if (pid == 0) { + execvp(argv[2],argv + 2); + if (error_temp(errno)) _exit(111); + _exit(100); } - if (wait_pid(&wstat,pid) != pid) - die_perm("condredirect: fatal: internal bug\n"); - if (wait_crashed(wstat)) die_temp("condredirect: fatal: child crashed\n"); - switch(wait_exitcode(wstat)) - { - case 0: break; - case 111: die_temp("condredirect: fatal: temporary child error\n"); - default: die_success(); + if (wait_pid(&wstat,pid) == -1) + strerr_die2x(111,FATAL,"wait failed"); + if (wait_crashed(wstat)) + strerr_die2x(111,FATAL,"child crashed"); + switch(wait_exitcode(wstat)) { + case 0: break; + case 111: strerr_die2x(111,FATAL,"temporary child error"); + default: _exit(0); } - if (seek_begin(0) == -1) die_temp("condredirect: fatal: unable to rewind\n"); - sig_pipeignore(); + if (seek_begin(0) == -1) + strerr_die2sys(111,FATAL,"unable to rewind: "); + sig_pipeignore(); + + sender = env_get("SENDER"); + if (!sender) strerr_die2x(100,FATAL,"SENDER not set"); + dtline = env_get("DTLINE"); + if (!dtline) strerr_die2x(100,FATAL,"DTLINE not set"); + + if (qmail_open(&qqt) == -1) + strerr_die2sys(111,FATAL,"unable to fork: "); + qmail_puts(&qqt,dtline); + if (substdio_copy(&ssout,&ssin) != 0) + strerr_die2sys(111,FATAL,"unable to read message: "); + substdio_flush(&ssout); + + num[fmt_ulong(num,qmail_qp(&qqt))] = 0; - sender = env_get("SENDER"); - if (!sender) die_perm("condredirect: fatal: SENDER not set\n"); - dtline = env_get("DTLINE"); - if (!dtline) die_perm("condredirect: fatal: DTLINE not set\n"); - - if (qmail_open(&qqt) == -1) die_temp("condredirect: fatal: unable to fork\n"); - qmail_puts(&qqt,dtline); - substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf)); - substdio_fdbuf(&ssout,mywrite,-1,outbuf,sizeof(outbuf)); - if (substdio_copy(&ssout,&ssin) != 0) - die_temp("condredirect: fatal: error while reading message\n"); - substdio_flush(&ssout); - - qmail_from(&qqt,sender); - qmail_to(&qqt,argv[1]); - switch(qmail_close(&qqt)) - { - case 0: die_99(); - case QMAIL_TOOLONG: die_perm("condredirect: fatal: permanent qmail-queue error\n"); - default: die_temp("condredirect: fatal: temporary qmail-queue error\n"); - } + qmail_from(&qqt,sender); + qmail_to(&qqt,argv[1]); + qqx = qmail_close(&qqt); + if (*qqx) strerr_die2x(*qqx == 'D' ? 100 : 111,FATAL,qqx + 1); + strerr_die2x(99,"condredirect: qp ",num); }