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
));