Upstream qmail 1.01
[qmail] / preline.c
CommitLineData
2117e02e
MW
1#include "fd.h"
2#include "sgetopt.h"
3#include "readwrite.h"
4#include "subfd.h"
5#include "substdio.h"
6#include "exit.h"
7#include "fork.h"
8#include "wait.h"
9#include "env.h"
10#include "sig.h"
11#include "error.h"
12
13void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
14void die_usage() { die(100,"preline: fatal: incorrect usage\n"); }
15void die_temp() { die(111,"preline: fatal: temporary problem\n"); }
16void die_read() { die(111,"preline: fatal: unable to read message\n"); }
17void die_badcmd() { die(100,"preline: fatal: command not found\n"); }
18
19int flagufline = 1; char *ufline;
20int flagrpline = 1; char *rpline;
21int flagdtline = 1; char *dtline;
22
23substdio ssout;
24char outbuf[SUBSTDIO_OUTSIZE];
25substdio ssin;
26char inbuf[SUBSTDIO_INSIZE];
27
28void main(argc,argv)
29int argc;
30char **argv;
31{
32 int opt;
33 int pi[2];
34 int pid;
35 int wstat;
36
37 sig_pipeignore();
38
39 if (!(ufline = env_get("UFLINE"))) die_usage();
40 if (!(rpline = env_get("RPLINE"))) die_usage();
41 if (!(dtline = env_get("DTLINE"))) die_usage();
42
43 while ((opt = getopt(argc,argv,"frdFRD")) != opteof)
44 switch(opt)
45 {
46 case 'f': flagufline = 0; break;
47 case 'r': flagrpline = 0; break;
48 case 'd': flagdtline = 0; break;
49 case 'F': flagufline = 1; break;
50 case 'R': flagrpline = 1; break;
51 case 'D': flagdtline = 1; break;
52 default:
53 _exit(100);
54 }
55 argc -= optind;
56 argv += optind;
57 if (!*argv) die_usage();
58
59 if (pipe(pi) == -1) die_temp();
60
61 switch(pid = fork())
62 {
63 case -1:
64 die_temp();
65 case 0:
66 close(pi[1]);
67 if (fd_move(0,pi[0])) die_temp();
68 sig_pipedefault();
69 execvp(*argv,argv);
70 if (error_temp(errno)) die_temp();
71 die_badcmd();
72 }
73 close(pi[0]);
74
75 substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf));
76 substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
77 if (flagufline) substdio_bputs(&ssout,ufline);
78 if (flagrpline) substdio_bputs(&ssout,rpline);
79 if (flagdtline) substdio_bputs(&ssout,dtline);
80 if (substdio_copy(&ssout,&ssin) == -2) die_read();
81 substdio_flush(&ssout);
82 close(pi[1]);
83
84 if (wait_pid(&wstat,pid) == -1) die_temp();
85 if (wait_crashed(wstat)) die_temp();
86 _exit(wait_exitcode(wstat));
87}