24#define WHO "fastforward"
28 logmsg(
WHO,100,USAGE,
"fastforward [ -nNpP ] data.cdb");
32 logmsg(
WHO,111,FATAL,
"out of memory");
35static void print(
char *s)
39 buffer_put(buffer_2,&ch,1);
43static void printsafe(
char *s)
47 if (ch < 32) ch =
'_';
48 buffer_put(buffer_2,&ch,1);
80static void dofile(
char *
fn)
91 logmsg(
WHO,111,FATAL,B(
"unable to read: ",
fn));
92 if (fstat(
fd,&st) == -1)
93 logmsg(
WHO,111,FATAL,B(
"unable to read: ",
fn));
94 if ((st.st_mode & 0444) != 0444)
95 logmsg(
WHO,111,FATAL,B(
fn,
" is not world-readable"));
97 logmsg(
WHO,111,FATAL,B(
"unable to read: ",
fn));
121static void cdbreaderror()
123 logmsg(
WHO,111,FATAL,B(
"unable to read: ",
fncdb));
126static int findtarget(
int flagwild,
char *prepend,
char *
addr)
133 case_lowerb(
key.s,
key.len);
136 if (r == -1) cdbreaderror();
139 if (!flagwild)
return 0;
140 at = str_rchr(
addr,
'@');
141 if (!
addr[at])
return 0;
145 case_lowerb(
key.s,
key.len);
148 if (r == -1) cdbreaderror();
153 case_lowerb(
key.s,
key.len);
156 if (r == -1) cdbreaderror();
162static int gettarget(
int flagwild,
char *prepend,
char *
addr)
164 if (!findtarget(flagwild,prepend,
addr))
return 0;
174static void doprogram(
char *arg)
184 buffer_flush(buffer_2);
202 switch (child = vfork()) {
204 logmsg(
WHO,111,FATAL,
"unable to fork: ");
208 logmsg(
WHO,111,FATAL,B(
"unable to run: ",arg));
211 wait_pid(&wstat,child);
212 if (wait_crashed(wstat))
213 logmsg(
WHO,111,FATAL,B(
"child crashed in: ",arg));
215 switch (wait_exitcode(wstat)) {
216 case 64:
case 65:
case 70:
case 76:
case 77:
case 78:
case 112:
217 case 100:
_exit(100);
222 if (seek_begin(0) == -1)
223 logmsg(
WHO,111,FATAL,
"unable to rewind input: ");
234 if ((
data.s[i] ==
'|') || (
data.s[i] ==
'!'))
235 doprogram(
data.s + i);
236 else if ((
data.s[i] ==
'.') || (
data.s[i] ==
'/')) {
240 else if ((
data.s[i] ==
'&') && (
j - i < 900)) {
248static void dorecip(
char *
addr)
251 if (!findtarget(0,
"?",
addr))
252 if (gettarget(0,
":",
addr)) {
260static void doorigrecip(
char *
addr)
264 if (gettarget(1,
"?",
addr))
266 if (!gettarget(1,
":",
addr))
270 logmsg(
WHO,100,ERROR,
"Sorry, no mailbox here by that name. (#5.1.1)");
277int main(
int argc,
char *
const *argv)
285 dtline = env_get(
"DTLINE");
288 x = env_get(
"SENDER");
289 if (!x) x =
"original envelope sender";
295 while ((opt = getoptb(argc,(
char **)argv,
"nNpPdD")) != opteof)
310 if (
fdcdb == -1) cdbreaderror();
314 x = env_get(
"DEFAULT");
315 if (!x) x = env_get(
"EXT");
316 if (!x) logmsg(
WHO,100,FATAL,
"$DEFAULT or $EXT must be set");
320 if (!x) logmsg(
WHO,100,FATAL,
"$HOST must be set");
326 x = env_get(
"RECIPIENT");
327 if (!x) logmsg(
WHO,100,FATAL,
"$RECIPIENT must be set");
334 while ((i > 0) &&
todo.s[i - 1]) --i;
339 x = alloc(str_len(
todo.s + i) + 1);
341 str_copy(x,
todo.s + i);
347 else if ((*x ==
'.') || (*x ==
'/'))
355 print(
"no forwarding\n");
356 buffer_flush(buffer_2);
369 while ((i > 0) &&
forward.s[i - 1]) --i;
375 buffer_flush(buffer_2);
380 logmsg(
WHO,111,FATAL,
"unable to fork: ");
383 logmsg(
WHO,111,FATAL,
"unable to read message: ");
391 while ((i > 0) &&
forward.s[i - 1]) --i;
397 if (*x) logmsg(
WHO,*x ==
'D' ? 100 : 111,FATAL,x + 1);
int stralloc_copys(stralloc *, char const *)
ssize_t qqwrite(int fd, char *buf, int len)
char messbuf[BUFSIZE_MESS]
void qmail_to(struct qmail *, char *)
void qmail_from(struct qmail *, char *)
void qmail_put(struct qmail *, char *, int)
char * qmail_close(struct qmail *)
unsigned long qmail_qp(struct qmail *)
void qmail_puts(struct qmail *, char *)
int qmail_open(struct qmail *)
int strset_add(strset *, char *)
int strset_init(strset *)
char * strset_in(strset *, char *)