diff options
Diffstat (limited to 'sqmail-4.3.07/src/fastforward.c')
-rw-r--r-- | sqmail-4.3.07/src/fastforward.c | 399 |
1 files changed, 0 insertions, 399 deletions
diff --git a/sqmail-4.3.07/src/fastforward.c b/sqmail-4.3.07/src/fastforward.c deleted file mode 100644 index f8a7d55..0000000 --- a/sqmail-4.3.07/src/fastforward.c +++ /dev/null @@ -1,399 +0,0 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include "readclose.h" -#include "stralloc.h" -#include "buffer.h" -#include "strset.h" -#include "getoptb.h" -#include "exit.h" -#include "logmsg.h" -#include "env.h" -#include "sig.h" -#include "qmail.h" -#include "fmt.h" -#include "case.h" -#include "alloc.h" -#include "seek.h" -#include "wait.h" -#include "byte.h" -#include "str.h" -#include "open.h" -#include "cdbread.h" - -#define WHO "fastforward" - -static void usage() -{ - logmsg(WHO,100,USAGE,"fastforward [ -nNpP ] data.cdb"); -} -static void nomem() -{ - logmsg(WHO,111,FATAL,"out of memory"); -} - -static void print(char *s) -{ - char ch; - while ((ch = *s++)) { - buffer_put(buffer_2,&ch,1); - } -} - -static void printsafe(char *s) -{ - char ch; - while ((ch = *s++)) { - if (ch < 32) ch = '_'; - buffer_put(buffer_2,&ch,1); - } -} - -struct qmail qq; -char qp[FMT_ULONG]; -char qqbuf[1]; - -ssize_t qqwrite(int fd,char *buf,int len) -{ - qmail_put(&qq,buf,len); - return len; -} - -buffer bufq = BUFFER_INIT(qqwrite,-1,qqbuf,sizeof(qqbuf)); - -char messbuf[BUFSIZE_MESS]; -buffer mess = BUFFER_INIT(read,0,messbuf,sizeof(messbuf)); - -int flagdeliver = 1; -int flagpassthrough = 0; - -char *dtline; -stralloc sender = {0}; -stralloc programs = {0}; -stralloc forward = {0}; - -strset done; -stralloc todo = {0}; - -stralloc mailinglist = {0}; - -void dofile(char *fn) -{ - int fd; - struct stat st; - int i; - int j; - - if (!stralloc_copys(&mailinglist,"")) nomem(); - - fd = open_read(fn); - if (fd == -1) - logmsg(WHO,111,FATAL,B("unable to read: ",fn)); - if (fstat(fd,&st) == -1) - logmsg(WHO,111,FATAL,B("unable to read: ",fn)); - if ((st.st_mode & 0444) != 0444) - logmsg(WHO,111,FATAL,B(fn," is not world-readable")); - if (readclose_append(fd,&mailinglist,1024) == -1) - logmsg(WHO,111,FATAL,B("unable to read: ",fn)); - - i = 0; - for (j = 0; j < mailinglist.len; ++j) - if (!mailinglist.s[j]) { - if ((mailinglist.s[i] == '.') || (mailinglist.s[i] == '/')) { - if (!stralloc_cats(&todo,mailinglist.s + i)) nomem(); - if (!stralloc_0(&todo)) nomem(); - } - else if ((mailinglist.s[i] == '&') && (j - i < 900)) { - if (!stralloc_cats(&todo,mailinglist.s + i)) nomem(); - if (!stralloc_0(&todo)) nomem(); - } - i = j + 1; - } -} - -char *fncdb; -int fdcdb; -stralloc key = {0}; -uint32 dlen; -stralloc data = {0}; -struct cdb cdb; - -void cdbreaderror() -{ - logmsg(WHO,111,FATAL,B("unable to read: ",fncdb)); -} - -int findtarget(int flagwild,char *prepend,char *addr) -{ - int r; - int at; - - if (!stralloc_copys(&key,prepend)) nomem(); - if (!stralloc_cats(&key,addr)) nomem(); - case_lowerb(key.s,key.len); - - r = cdb_find(&cdb,key.s,key.len); - if (r == -1) cdbreaderror(); - if (r) return 1; - - if (!flagwild) return 0; - at = str_rchr(addr,'@'); - if (!addr[at]) return 0; - - if (!stralloc_copys(&key,prepend)) nomem(); - if (!stralloc_cats(&key,addr + at)) nomem(); - case_lowerb(key.s,key.len); - - r = cdb_find(&cdb,key.s,key.len); - if (r == -1) cdbreaderror(); - if (r) return 1; - - if (!stralloc_copys(&key,prepend)) nomem(); - if (!stralloc_catb(&key,addr,at + 1)) nomem(); - case_lowerb(key.s,key.len); - - r = cdb_find(&cdb,key.s,key.len); - if (r == -1) cdbreaderror(); - if (r) return 1; - - return 0; -} - -int gettarget(int flagwild,char *prepend,char *addr) -{ - if (!findtarget(flagwild,prepend,addr)) return 0; - dlen = cdb_datalen(&cdb); - if (!stralloc_ready(&data,(unsigned int) dlen)) nomem(); - data.len = dlen; - if (cdb_read(&cdb,data.s,data.len,cdb_datapos(&cdb)) == -1) - cdbreaderror(); - - return 1; -} - -void doprogram(char *arg) -{ - char *args[5]; - int child; - int wstat; - - if (!flagdeliver) { - print("run "); - printsafe(arg); - print("\n"); - buffer_flush(buffer_2); - return; - } - - if (*arg == '!') { - args[0] = "preline"; - args[1] = "sh"; - args[2] = "-c"; - args[3] = arg + 1; - args[4] = 0; - } - else { - args[0] = "sh"; - args[1] = "-c"; - args[2] = arg + 1; - args[3] = 0; - } - - switch (child = vfork()) { - case -1: - logmsg(WHO,111,FATAL,"unable to fork: "); - case 0: - sig_pipedefault(); - execvp(*args,args); - logmsg(WHO,111,FATAL,B("unable to run: ",arg)); - } - - wait_pid(&wstat,child); - if (wait_crashed(wstat)) - logmsg(WHO,111,FATAL,B("child crashed in: ",arg)); - - switch (wait_exitcode(wstat)) { - case 64: case 65: case 70: case 76: case 77: case 78: case 112: - case 100: _exit(100); - case 0: break; - default: _exit(111); - } - - if (seek_begin(0) == -1) - logmsg(WHO,111,FATAL,"unable to rewind input: "); -} - -void dodata() -{ - int i; - int j; - i = 0; - - for (j = 0; j < data.len; ++j) - if (!data.s[j]) { - if ((data.s[i] == '|') || (data.s[i] == '!')) - doprogram(data.s + i); - else if ((data.s[i] == '.') || (data.s[i] == '/')) { - if (!stralloc_cats(&todo,data.s + i)) nomem(); - if (!stralloc_0(&todo)) nomem(); - } - else if ((data.s[i] == '&') && (j - i < 900)) { - if (!stralloc_cats(&todo,data.s + i)) nomem(); - if (!stralloc_0(&todo)) nomem(); - } - i = j + 1; - } -} - -void dorecip(char *addr) -{ - - if (!findtarget(0,"?",addr)) - if (gettarget(0,":",addr)) { - dodata(); - return; - } - if (!stralloc_cats(&forward,addr)) nomem(); - if (!stralloc_0(&forward)) nomem(); -} - -void doorigrecip(char *addr) -{ - if (sender.len) - if ((sender.len != 4) || byte_diff(sender.s,4,"#@[]")) - if (gettarget(1,"?",addr)) - if (!stralloc_copy(&sender,&data)) nomem(); - if (!gettarget(1,":",addr)) - if (flagpassthrough) - _exit(0); - else - logmsg(WHO,100,ERROR,"Sorry, no mailbox here by that name. (#5.1.1)"); - dodata(); -} - -stralloc recipient = {0}; -int flagdefault = 0; - -int main(int argc,char **argv) -{ - int opt; - char *x; - int i; - - sig_pipeignore(); - - dtline = env_get("DTLINE"); - if (!dtline) dtline = ""; - - x = env_get("SENDER"); - if (!x) x = "original envelope sender"; - if (!stralloc_copys(&sender,x)) nomem(); - - if (!stralloc_copys(&forward,"")) nomem(); - if (!strset_init(&done)) nomem(); - - while ((opt = getopt(argc,argv,"nNpPdD")) != opteof) - switch (opt) { - case 'n': flagdeliver = 0; break; - case 'N': flagdeliver = 1; break; - case 'p': flagpassthrough = 1; break; - case 'P': flagpassthrough = 0; break; - case 'd': flagdefault = 1; break; - case 'D': flagdefault = 0; break; - default: usage(); - } - argv += optind; - - fncdb = *argv; - if (!fncdb) usage(); - fdcdb = open_read(fncdb); - if (fdcdb == -1) cdbreaderror(); - cdb_init(&cdb,fdcdb); - - if (flagdefault) { - x = env_get("DEFAULT"); - if (!x) x = env_get("EXT"); - if (!x) logmsg(WHO,100,FATAL,"$DEFAULT or $EXT must be set"); - if (!stralloc_copys(&recipient,x)) nomem(); - if (!stralloc_cats(&recipient,"@")) nomem(); - x = env_get("HOST"); - if (!x) logmsg(WHO,100,FATAL,"$HOST must be set"); - if (!stralloc_cats(&recipient,x)) nomem(); - if (!stralloc_0(&recipient)) nomem(); - x = recipient.s; - } - else { - x = env_get("RECIPIENT"); - if (!x) logmsg(WHO,100,FATAL,"$RECIPIENT must be set"); - } - if (!strset_add(&done,x)) nomem(); - doorigrecip(x); - - while (todo.len) { - i = todo.len - 1; - while ((i > 0) && todo.s[i - 1]) --i; - todo.len = i; - - if (strset_in(&done,todo.s + i)) continue; - - x = alloc(str_len(todo.s + i) + 1); - if (!x) nomem(); - str_copy(x,todo.s + i); - if (!strset_add(&done,x)) nomem(); - - x = todo.s + i; - if (*x == 0) - continue; - else if ((*x == '.') || (*x == '/')) - dofile(x); - else - dorecip(x + 1); - } - - if (!forward.len) { - if (!flagdeliver) { - print("no forwarding\n"); - buffer_flush(buffer_2); - } - _exit(flagpassthrough ? 99 : 0); - } - - if (!stralloc_0(&sender)) nomem(); - - if (!flagdeliver) { - print("from <"); - printsafe(sender.s); - print(">\n"); - while (forward.len) { - i = forward.len - 1; - while ((i > 0) && forward.s[i - 1]) --i; - forward.len = i; - print("to <"); - printsafe(forward.s + i); - print(">\n"); - } - buffer_flush(buffer_2); - _exit(flagpassthrough ? 99 : 0); - } - - if (qmail_open(&qq) == -1) - logmsg(WHO,111,FATAL,"unable to fork: "); - qmail_puts(&qq,dtline); - if (buffer_copy(&bufq,&mess) != 0) - logmsg(WHO,111,FATAL,"unable to read message: "); - buffer_flush(&bufq); - qp[fmt_ulong(qp,qmail_qp(&qq))] = 0; - - qmail_from(&qq,sender.s); - - while (forward.len) { - i = forward.len - 1; - while ((i > 0) && forward.s[i - 1]) --i; - forward.len = i; - qmail_to(&qq,forward.s + i); - } - - x = qmail_close(&qq); - if (*x) logmsg(WHO,*x == 'D' ? 100 : 111,FATAL,x + 1); - logmsg(WHO,flagpassthrough ? 99 : 0,LOG,B("qp ",qp)); -} |