diff options
Diffstat (limited to 'src/preline.c')
-rw-r--r-- | src/preline.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/preline.c b/src/preline.c new file mode 100644 index 0000000..c2af3bf --- /dev/null +++ b/src/preline.c @@ -0,0 +1,87 @@ +#include <unistd.h> +#include "fd.h" +#include "buffer.h" +#include "exit.h" +#include "wait.h" +#include "env.h" +#include "sig.h" +#include "getoptb.h" +#include "logmsg.h" +#include "qmail.h" + +#define WHO "preline" + +void die_usage() +{ + logmsg(WHO,100,USAGE,"preline cmd [ arg ... ]"); +} + +int flagufline = 1; char *ufline; +int flagrpline = 1; char *rpline; +int flagdtline = 1; char *dtline; + +char outbuf[BUFSIZE_LINE]; +buffer bo = BUFFER_INIT(write,1,outbuf,sizeof(outbuf)); +char inbuf[BUFSIZE_LINE]; +buffer bi = BUFFER_INIT(read,0,inbuf,sizeof(inbuf)); + +int main(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: die_usage(); + } + argc -= optind; + argv += optind; + if (!*argv) die_usage(); + + if (pipe(pi) == -1) + logmsg(WHO,111,FATAL,"unable to create pipe"); + + pid = fork(); + if (pid == -1) + logmsg(WHO,111,FATAL,"unable to fork"); + + if (pid == 0) { + close(pi[1]); + if (fd_move(0,pi[0]) == -1) + logmsg(WHO,111,FATAL,"unable to set up fds"); + sig_pipedefault(); + execvp(*argv,argv); + logmsg(WHO,errno,FATAL,B("unable to run: ",*argv)); + } + close(pi[0]); + if (fd_move(1,pi[1]) == -1) + logmsg(WHO,111,FATAL,"unable to set up fds"); + + if (flagufline) buffer_puts(&bo,ufline); + if (flagrpline) buffer_puts(&bo,rpline); + if (flagdtline) buffer_puts(&bo,dtline); + if (buffer_copy(&bo,&bi) != 0) + logmsg(WHO,111,FATAL,"unable to copy input"); + buffer_flush(&bo); + close(1); + + if (wait_pid(&wstat,pid) == -1) + logmsg(WHO,111,FATAL,"wait failed"); + if (wait_crashed(wstat)) + logmsg(WHO,111,FATAL,"child crashed"); + _exit(wait_exitcode(wstat)); +} |