X-Git-Url: https://git.distorted.org.uk/~mdw/qmail/blobdiff_plain/2117e02ec495fdfd6e96b39778b701a5bcff8aa5..HEAD:/preline.c diff --git a/preline.c b/preline.c index 8e76485..1a4cef8 100644 --- a/preline.c +++ b/preline.c @@ -1,7 +1,7 @@ #include "fd.h" #include "sgetopt.h" #include "readwrite.h" -#include "subfd.h" +#include "strerr.h" #include "substdio.h" #include "exit.h" #include "fork.h" @@ -10,78 +10,81 @@ #include "sig.h" #include "error.h" -void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); } -void die_usage() { die(100,"preline: fatal: incorrect usage\n"); } -void die_temp() { die(111,"preline: fatal: temporary problem\n"); } -void die_read() { die(111,"preline: fatal: unable to read message\n"); } -void die_badcmd() { die(100,"preline: fatal: command not found\n"); } +#define FATAL "preline: fatal: " + +void die_usage() +{ + strerr_die1x(100,"preline: usage: preline cmd [ arg ... ]"); +} int flagufline = 1; char *ufline; int flagrpline = 1; char *rpline; int flagdtline = 1; char *dtline; -substdio ssout; char outbuf[SUBSTDIO_OUTSIZE]; -substdio ssin; char inbuf[SUBSTDIO_INSIZE]; +substdio ssout = SUBSTDIO_FDBUF(write,1,outbuf,sizeof outbuf); +substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); void main(argc,argv) int argc; char **argv; { - int opt; - int pi[2]; - int pid; - int wstat; - - sig_pipeignore(); - - if (!(ufline = env_get("UFLINE"))) die_usage(); - if (!(rpline = env_get("RPLINE"))) die_usage(); - if (!(dtline = env_get("DTLINE"))) die_usage(); - - while ((opt = getopt(argc,argv,"frdFRD")) != opteof) - switch(opt) - { - case 'f': flagufline = 0; break; - case 'r': flagrpline = 0; break; - case 'd': flagdtline = 0; break; - case 'F': flagufline = 1; break; - case 'R': flagrpline = 1; break; - case 'D': flagdtline = 1; break; - default: - _exit(100); + int opt; + int pi[2]; + int pid; + int wstat; + + sig_pipeignore(); + + if (!(ufline = env_get("UFLINE"))) die_usage(); + if (!(rpline = env_get("RPLINE"))) die_usage(); + if (!(dtline = env_get("DTLINE"))) die_usage(); + + while ((opt = getopt(argc,argv,"frdFRD")) != opteof) + switch(opt) { + case 'f': flagufline = 0; break; + case 'r': flagrpline = 0; break; + case 'd': flagdtline = 0; break; + case 'F': flagufline = 1; break; + case 'R': flagrpline = 1; break; + case 'D': flagdtline = 1; break; + default: die_usage(); } - argc -= optind; - argv += optind; - if (!*argv) die_usage(); + argc -= optind; + argv += optind; + if (!*argv) die_usage(); + + if (pipe(pi) == -1) + strerr_die2sys(111,FATAL,"unable to create pipe: "); - if (pipe(pi) == -1) die_temp(); + pid = fork(); + if (pid == -1) + strerr_die2sys(111,FATAL,"unable to fork: "); - switch(pid = fork()) - { - case -1: - die_temp(); - case 0: - close(pi[1]); - if (fd_move(0,pi[0])) die_temp(); - sig_pipedefault(); - execvp(*argv,argv); - if (error_temp(errno)) die_temp(); - die_badcmd(); + if (pid == 0) { + close(pi[1]); + if (fd_move(0,pi[0]) == -1) + strerr_die2sys(111,FATAL,"unable to set up fds: "); + sig_pipedefault(); + execvp(*argv,argv); + strerr_die4sys(error_temp(errno) ? 111 : 100,FATAL,"unable to run ",*argv,": "); } - close(pi[0]); - - substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf)); - substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf)); - if (flagufline) substdio_bputs(&ssout,ufline); - if (flagrpline) substdio_bputs(&ssout,rpline); - if (flagdtline) substdio_bputs(&ssout,dtline); - if (substdio_copy(&ssout,&ssin) == -2) die_read(); - substdio_flush(&ssout); - close(pi[1]); - - if (wait_pid(&wstat,pid) == -1) die_temp(); - if (wait_crashed(wstat)) die_temp(); - _exit(wait_exitcode(wstat)); + close(pi[0]); + if (fd_move(1,pi[1]) == -1) + strerr_die2sys(111,FATAL,"unable to set up fds: "); + + if (flagufline) substdio_bputs(&ssout,ufline); + if (flagrpline) substdio_bputs(&ssout,rpline); + if (flagdtline) substdio_bputs(&ssout,dtline); + if (substdio_copy(&ssout,&ssin) != 0) + strerr_die2sys(111,FATAL,"unable to copy input: "); + substdio_flush(&ssout); + close(1); + + if (wait_pid(&wstat,pid) == -1) + strerr_die2sys(111,FATAL,"wait failed: "); + if (wait_crashed(wstat)) + strerr_die2x(111,FATAL,"child crashed"); + _exit(wait_exitcode(wstat)); }