summaryrefslogtreecommitdiff
path: root/sqmail-4.3.07/src/fastforward.c
diff options
context:
space:
mode:
Diffstat (limited to 'sqmail-4.3.07/src/fastforward.c')
-rw-r--r--sqmail-4.3.07/src/fastforward.c399
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));
-}