18 void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
19 void die_usage() { die(100,"qsmhook: fatal: incorrect usage\n"); }
20 void die_temp() { die(111,"qsmhook: fatal: temporary problem\n"); }
21 void die_read() { die(111,"qsmhook: fatal: unable to read message\n"); }
22 void die_badcmd() { die(100,"qsmhook: fatal: command not found\n"); }
24 int flagrpline = 0; char *rpline;
25 int flagufline = 1; char *ufline;
26 int flagdtline = 0; char *dtline;
31 stralloc newarg = {0};
34 char outbuf[SUBSTDIO_OUTSIZE];
36 char inbuf[SUBSTDIO_INSIZE];
53 if (!(dtline = env_get("DTLINE"))) die_usage();
54 if (!(rpline = env_get("RPLINE"))) die_usage();
55 if (!(ufline = env_get("UFLINE"))) die_usage();
56 if (!(recip = env_get("LOCAL"))) die_usage();
57 if (!(host = env_get("HOST"))) die_usage();
58 if (!(sender = env_get("SENDER"))) die_usage();
60 while ((opt = getopt(argc,argv,"DFlMmnPsx:")) != opteof)
63 case 'D': case 'F': case 'M': break; /* be serious */
64 case 'l': flagdtline = 1; break; /* also return-receipt-to? blech */
65 case 'm': break; /* we only handle one recipient anyway */
66 case 'n': flagufline = 0; break;
67 case 's': break; /* could call quote() otherwise, i suppose... */
68 case 'P': flagrpline = 1; break;
70 if (case_starts(recip,optarg))
71 recip += str_len(optarg);
79 if (!*argv) die_usage();
81 for (arg = argv;x = *arg;++arg)
83 if (!stralloc_copys(&newarg,"")) die_temp();
90 case '%': if (!stralloc_cats(&newarg,"%")) die_temp(); break;
91 case 'g': if (!stralloc_cats(&newarg,sender)) die_temp(); break;
92 case 'h': if (!stralloc_cats(&newarg,host)) die_temp(); break;
93 case 'u': if (!stralloc_cats(&newarg,recip)) die_temp(); break;
101 if (!stralloc_append(&newarg,&x[i])) die_temp();
102 if (!stralloc_0(&newarg)) die_temp();
103 i = str_len(newarg.s) + 1;
104 if (!(x = alloc(i))) die_temp();
105 byte_copy(x,i,newarg.s);
109 if (pipe(pi) == -1) die_temp();
117 if (fd_move(0,pi[0]) == -1) die_temp();
120 if (error_temp(errno)) die_temp();
125 substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf));
126 substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
127 if (flagufline) substdio_bputs(&ssout,ufline);
128 if (flagrpline) substdio_bputs(&ssout,rpline);
129 if (flagdtline) substdio_bputs(&ssout,dtline);
130 if (substdio_copy(&ssout,&ssin) == -2) die_read();
131 substdio_flush(&ssout);
134 if (wait_pid(&wstat,pid) == -1) die_temp();
135 if (wait_crashed(wstat)) die_temp();
136 _exit(wait_exitcode(wstat));