diff -r -P -u3 fastforward-0.51_orig/Makefile fastforward-0.51_my/Makefile --- fastforward-0.51_orig/Makefile Mon Jun 14 21:20:12 1999 +++ fastforward-0.51_my/Makefile Tue Jun 15 00:34:35 1999 @@ -129,16 +129,20 @@ ./compile control.c env.a: \ -makelib envread.o - ./makelib env.a envread.o +makelib env.o envread.o + ./makelib env.a env.o envread.o + +env.o: \ +compile env.c str.h alloc.h env.h + ./compile env.c envread.o: \ compile envread.c env.h str.h ./compile envread.c error.a: \ -makelib error.o error_str.o - ./makelib error.a error.o error_str.o +makelib error.o error_str.o error_temp.o + ./makelib error.a error.o error_str.o error_temp.o error.o: \ compile error.c error.h @@ -148,14 +152,24 @@ compile error_str.c error.h ./compile error_str.c +error_temp.o: \ +compile error_temp.c error.h + ./compile error_temp.c + fastforward: \ load fastforward.o slurpclose.o coe.o strset.o qmail.o auto_qmail.o \ getopt.a cdb.a env.a strerr.a substdio.a stralloc.a alloc.a error.a \ -case.a str.a fs.a sig.a wait.a seek.a open.a fd.a +case.a str.a fs.a sig.a wait.a seek.a open.a fd.a seek.a now.o lock.a \ +gfrom.o getln.a byte_chr.o filedelivery.o ./load fastforward slurpclose.o coe.o strset.o qmail.o \ - auto_qmail.o getopt.a cdb.a env.a strerr.a substdio.a \ - stralloc.a alloc.a error.a case.a str.a fs.a sig.a wait.a \ - seek.a open.a fd.a + auto_qmail.o byte_chr.o filedelivery.o getopt.a cdb.a env.a \ + strerr.a substdio.a stralloc.a alloc.a error.a case.a str.a \ + fs.a sig.a wait.a seek.a open.a fd.a seek.a now.o lock.a \ + gfrom.o getln.a + +filedelivery.o: \ +compile filedelivery.c filedelivery.h + ./compile filedelivery.c fastforward.0: \ fastforward.1 @@ -165,7 +179,7 @@ compile fastforward.c stralloc.h gen_alloc.h substdio.h subfd.h \ substdio.h strset.h uint32.h sgetopt.h subgetopt.h readwrite.h exit.h \ strerr.h env.h sig.h qmail.h substdio.h fmt.h case.h alloc.h coe.h \ -seek.h wait.h fork.h +seek.h wait.h fork.h filedelivery.c filedelivery.h ./compile fastforward.c fd.a: \ @@ -185,6 +199,14 @@ cat auto-ccld.sh find-systype.sh > find-systype chmod 755 find-systype +fmt_str.o: \ +compile fmt_str.c fmt.h + ./compile fmt_str.c + +fmt_strn.o: \ +compile fmt_strn.c fmt.h + ./compile fmt_strn.c + fmt_ulong.o: \ compile fmt_ulong.c fmt.h ./compile fmt_ulong.c @@ -197,8 +219,8 @@ rm -f tryvfork.o tryvfork fs.a: \ -makelib fmt_ulong.o scan_ulong.o - ./makelib fs.a fmt_ulong.o scan_ulong.o +makelib fmt_ulong.o fmt_str.o fmt_strn.o scan_ulong.o + ./makelib fs.a fmt_ulong.o fmt_str.o fmt_strn.o scan_ulong.o getln.a: \ makelib getln.o getln2.o @@ -216,6 +238,17 @@ makelib subgetopt.o sgetopt.o ./makelib getopt.a subgetopt.o sgetopt.o +gfrom.o: \ +compile gfrom.c str.h gfrom.h + ./compile gfrom.c + +hasflock.h: \ +tryflock.c compile load + ( ( ./compile tryflock.c && ./load tryflock ) >/dev/null \ + 2>&1 \ + && echo \#define HASFLOCK 1 || exit 0 ) > hasflock.h + rm -f tryflock.o tryflock + hassgact.h: \ trysgact.c compile load ( ( ./compile trysgact.c && ./load trysgact ) >/dev/null \ @@ -223,6 +256,13 @@ && echo \#define HASSIGACTION 1 || exit 0 ) > hassgact.h rm -f trysgact.o trysgact +hassgprm.h: \ + trysgprm.c compile load + ( ( ./compile trysgprm.c && ./load trysgprm ) >/dev/null \ + 2>&1 \ + && echo \#define HASSIGPROCMASK 1 || exit 0 ) > hassgprm.h + rm -f trysgprm.o trysgprm + haswaitp.h: \ trywaitp.c compile load ( ( ./compile trywaitp.c && ./load trywaitp ) >/dev/null \ @@ -273,6 +313,14 @@ ( cat warn-auto.sh; ./make-load "`cat systype`" ) > load chmod 755 load +lock.a: \ +makelib lock_ex.o + ./makelib lock.a lock_ex.o + +lock_ex.o: \ +compile lock_ex.c hasflock.h lock.h + ./compile lock_ex.c + make-compile: \ make-compile.sh auto-ccld.sh cat auto-ccld.sh make-compile.sh > make-compile @@ -334,9 +382,13 @@ auto_qmail.h env.h ./compile newinclude.c +now.o: \ +compile now.c datetime.h now.h datetime.h + ./compile now.c + open.a: \ -makelib open_read.o open_trunc.o - ./makelib open.a open_read.o open_trunc.o +makelib open_read.o open_trunc.o open_excl.o open_append.o + ./makelib open.a open_read.o open_trunc.o open_excl.o open_append.o open_read.o: \ compile open_read.c open.h @@ -346,6 +398,14 @@ compile open_trunc.c open.h ./compile open_trunc.c +open_excl.o: \ +compile open_excl.c open.h + ./compile open_excl.c + +open_append.o: \ +compile open_append.c open.h + ./compile open_append.c + printforward: \ load printforward.o cdb.a strerr.a substdio.a stralloc.a alloc.a \ error.a str.a @@ -390,13 +450,25 @@ ./compile scan_ulong.c seek.a: \ -makelib seek_set.o - ./makelib seek.a seek_set.o +makelib seek_set.o seek_cur.o seek_end.o seek_trunc.o + ./makelib seek.a seek_set.o seek_cur.o seek_end.o seek_trunc.o seek_set.o: \ compile seek_set.c seek.h ./compile seek_set.c +seek_cur.o: \ +compile seek_cur.c seek.h + ./compile seek_cur.c + +seek_end.o: \ +compile seek_end.c seek.h + ./compile seek_end.c + +seek_trunc.o: \ +compile seek_trunc.c seek.h + ./compile seek_trunc.c + setforward: \ load setforward.o cdbmss.o cdbmake.a strerr.a substdio.a stralloc.a \ alloc.a error.a str.a seek.a open.a case.a @@ -438,8 +510,8 @@ ./compile sgetopt.c sig.a: \ -makelib sig_catch.o sig_pipe.o - ./makelib sig.a sig_catch.o sig_pipe.o +makelib sig_catch.o sig_pipe.o sig_alarm.o sig_block.o + ./makelib sig.a sig_catch.o sig_pipe.o sig_alarm.o sig_block.o sig_catch.o: \ compile sig_catch.c sig.h hassgact.h @@ -448,6 +520,14 @@ sig_pipe.o: \ compile sig_pipe.c sig.h ./compile sig_pipe.c + +sig_alarm.o: \ +compile sig_alarm.c sig.h + ./compile sig_alarm.c + +sig_block.o: \ +compile sig_block.c sig.h hassgprm.h + ./compile sig_block.c slurpclose.o: \ compile slurpclose.c stralloc.h gen_alloc.h readwrite.h slurpclose.h \ diff -r -P -u3 fastforward-0.51_orig/README.idx fastforward-0.51_my/README.idx --- fastforward-0.51_orig/README.idx Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/README.idx Tue Jun 15 21:27:51 1999 @@ -0,0 +1,43 @@ + +README +fastforward-idx-1.01.patch + +by David Harris + + Info + ---- + +See the web page for details on this patch. + +http://www.davideous.com/fastforward-idx/ + +This patch is licensed under GPL. + + + Disclaimer of Warranty + ---------------------- + +THIS SOFTWARE IS PROVIDED BY DAVID R. HARRIS "AS IS" AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAVID R. HARRIS OR HIS CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + + + Copyright + --------- + +Copyright (c) 1999 David R. Harris +All Rights Reserved. + +You may freely distributed this software under the Gnu Public Liscense (GPL). +The GPL is available from the GNU organization at www.gnu.org. + + + diff -r -P -u3 fastforward-0.51_orig/datetime.h fastforward-0.51_my/datetime.h --- fastforward-0.51_orig/datetime.h Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/datetime.h Tue Jun 15 00:20:19 1999 @@ -0,0 +1,20 @@ +#ifndef DATETIME_H +#define DATETIME_H + +struct datetime { + int hour; + int min; + int sec; + int wday; + int mday; + int yday; + int mon; + int year; +} ; + +typedef long datetime_sec; + +extern void datetime_tai(); +extern datetime_sec datetime_untai(); + +#endif diff -r -P -u3 fastforward-0.51_orig/env.c fastforward-0.51_my/env.c --- fastforward-0.51_orig/env.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/env.c Mon Jun 14 21:16:44 1999 @@ -0,0 +1,113 @@ +/* env.c, envread.c, env.h: environ library +Daniel J. Bernstein, djb@silverton.berkeley.edu. +Depends on str.h, alloc.h. +Requires environ. +19960113: rewrite. warning: interface is different. +No known patent problems. +*/ + +#include "str.h" +#include "alloc.h" +#include "env.h" + +int env_isinit = 0; /* if env_isinit: */ +static int ea; /* environ is a pointer to ea+1 char*'s. */ +static int en; /* the first en of those are ALLOCATED. environ[en] is 0. */ + +static void env_goodbye(i) int i; +{ + alloc_free(environ[i]); + environ[i] = environ[--en]; + environ[en] = 0; +} + +static char *null = 0; + +void env_clear() +{ + if (env_isinit) while (en) env_goodbye(0); + else environ = &null; +} + +static void env_unsetlen(s,len) char *s; int len; +{ + int i; + for (i = en - 1;i >= 0;--i) + if (!str_diffn(s,environ[i],len)) + if (environ[i][len] == '=') + env_goodbye(i); +} + +int env_unset(s) char *s; +{ + if (!env_isinit) if (!env_init()) return 0; + env_unsetlen(s,str_len(s)); + return 1; +} + +static int env_add(s) char *s; +{ + char *t; + t = env_findeq(s); + if (t) env_unsetlen(s,t - s); + if (en == ea) + { + ea += 30; + if (!alloc_re(&environ,(en + 1) * sizeof(char *),(ea + 1) * sizeof(char *))) + { ea = en; return 0; } + } + environ[en++] = s; + environ[en] = 0; + return 1; +} + +int env_put(s) char *s; +{ + char *u; + if (!env_isinit) if (!env_init()) return 0; + u = alloc(str_len(s) + 1); + if (!u) return 0; + str_copy(u,s); + if (!env_add(u)) { alloc_free(u); return 0; } + return 1; +} + +int env_put2(s,t) char *s; char *t; +{ + char *u; + int slen; + if (!env_isinit) if (!env_init()) return 0; + slen = str_len(s); + u = alloc(slen + str_len(t) + 2); + if (!u) return 0; + str_copy(u,s); + u[slen] = '='; + str_copy(u + slen + 1,t); + if (!env_add(u)) { alloc_free(u); return 0; } + return 1; +} + +int env_init() +{ + char **newenviron; + int i; + for (en = 0;environ[en];++en) ; + ea = en + 10; + newenviron = (char **) alloc((ea + 1) * sizeof(char *)); + if (!newenviron) return 0; + for (en = 0;environ[en];++en) + { + newenviron[en] = alloc(str_len(environ[en]) + 1); + if (!newenviron[en]) + { + for (i = 0;i < en;++i) alloc_free(newenviron[i]); + alloc_free(newenviron); + return 0; + } + str_copy(newenviron[en],environ[en]); + } + newenviron[en] = 0; + environ = newenviron; + env_isinit = 1; + return 1; +} diff -r -P -u3 fastforward-0.51_orig/error_temp.c fastforward-0.51_my/error_temp.c --- fastforward-0.51_orig/error_temp.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/error_temp.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,80 @@ +#include +#include "error.h" + +#define X(n) if (e == n) return 1; + +int error_temp(e) +int e; +{ + X(error_intr) + X(error_nomem) + X(error_txtbsy) + X(error_io) + X(error_timeout) + X(error_wouldblock) + X(error_again) +#ifdef EDEADLK + X(EDEADLK) +#endif +#ifdef EBUSY + X(EBUSY) +#endif +#ifdef ENFILE + X(ENFILE) +#endif +#ifdef EMFILE + X(EMFILE) +#endif +#ifdef EFBIG + X(EFBIG) +#endif +#ifdef ENOSPC + X(ENOSPC) +#endif +#ifdef ENETDOWN + X(ENETDOWN) +#endif +#ifdef ENETUNREACH + X(ENETUNREACH) +#endif +#ifdef ENETRESET + X(ENETRESET) +#endif +#ifdef ECONNABORTED + X(ECONNABORTED) +#endif +#ifdef ECONNRESET + X(ECONNRESET) +#endif +#ifdef ENOBUFS + X(ENOBUFS) +#endif +#ifdef ETOOMANYREFS + X(ETOOMANYREFS) +#endif +#ifdef ECONNREFUSED + X(ECONNREFUSED) +#endif +#ifdef EHOSTDOWN + X(EHOSTDOWN) +#endif +#ifdef EHOSTUNREACH + X(EHOSTUNREACH) +#endif +#ifdef EPROCLIM + X(EPROCLIM) +#endif +#ifdef EUSERS + X(EUSERS) +#endif +#ifdef EDQUOT + X(EDQUOT) +#endif +#ifdef ESTALE + X(ESTALE) +#endif +#ifdef ENOLCK + X(ENOLCK) +#endif + return 0; +} diff -r -P -u3 fastforward-0.51_orig/fastforward.c fastforward-0.51_my/fastforward.c --- fastforward-0.51_orig/fastforward.c Tue May 19 12:25:42 1998 +++ fastforward-0.51_my/fastforward.c Tue Jun 15 14:55:54 1999 @@ -19,6 +19,12 @@ #include "wait.h" #include "fork.h" +#define DELIVERY + +#ifdef DELIVERY +#include "filedelivery.h" +#endif + #define FATAL "fastforward: fatal: " void usage() @@ -49,6 +55,8 @@ } } +int flag99; + struct qmail qq; char qp[FMT_ULONG]; char qqbuf[1]; @@ -77,6 +85,11 @@ stralloc mailinglist = {0}; +stralloc env_default = {0}; +stralloc env_newsender = {0}; + +int have_setenv = 0; + void dofile(fn) char *fn; { @@ -112,62 +125,194 @@ } } +void deliver_mailfile(fn) +char *fn; +{ + if (!flagdeliver) { + print("mbox "); + printsafe(fn); + print("\n"); + substdio_flush(subfderr); + return; + } + +#ifdef DELIVERY + mailfile(fn); +#else + strerr_die4sys(111,FATAL,"can not deliver to mailfile ",fn,": feature not yet supported"); +#endif +} + +void deliver_maildir(fn) +char *fn; +{ + if (!flagdeliver) { + print("maildir "); + printsafe(fn); + print("\n"); + substdio_flush(subfderr); + return; + } + +#ifdef DELIVERY + maildir(fn); +#else + strerr_die4sys(111,FATAL,"can not deliver to maildir ",fn,": feature not yet supported"); +#endif +} + char *fncdb; int fdcdb; stralloc key = {0}; uint32 dlen; stralloc data = {0}; +stralloc user = {0}; void cdbreaderror() { strerr_die4sys(111,FATAL,"unable to read ",fncdb,": "); } -int findtarget(flagwild,prepend,addr) -int flagwild; +int findtarget(flagwild,setenv,prepend,addr) +int flagwild; +/* flagwild = 0 -- nowildcarding at all, + 1 -- normal, + 2 -- no -default wildcarding, + 3 -- no -default or @domain wildcarding */ +int setenv; char *prepend; char *addr; { int r; int at; + int i; + + /* NOTE -- Sat Jun 12 1999 David Harris + We match user@ records then @domain records, which is not the standard + fast forward behavior. We do this because each .domains file will + probably have more uses than domains.. so the @domain wildcard is much + more general (more entropy) than the user@ records. Matching should be + from general to specific, so we do user@domain then user@ then @domain. */ + + /* NOTE -- Sat Jun 12 1999 David Harris + We are going to take a leap off the wild end and implement + qmail-local style -default matching here, so that we can implement + ezmlm lists in the .domains file. I'm kind of cringing at all the cdb + lookups this creates, but it's a needed feature and cdb is fast anyway. */ + + /* clear the DEFAULT env var */ + + if (setenv) + if (!stralloc_copys(&env_default,"")) nomem(); + + /* find the @ and the username for use in the lookups */ + + at = str_rchr(addr,'@'); + if (!addr[at]) return 0; + if (!stralloc_copyb(&user,addr,at)) nomem(); + + /* check for user@domain records */ + if (!stralloc_copys(&key,prepend)) nomem(); if (!stralloc_cats(&key,addr)) nomem(); case_lowerb(key.s,key.len); r = cdb_seek(fdcdb,key.s,key.len,&dlen); if (r == -1) cdbreaderror(); - if (r) return 1; - if (!flagwild) return 0; - at = str_rchr(addr,'@'); - if (!addr[at]) return 0; + if (r) { + if (setenv) + if (user.len >= 7) + if (!byte_diff("default",7,user.s + user.len - 7)) + if (!stralloc_copys(&env_default,"default")) nomem(); + return 1; + } + + if (flagwild == 0) return 0; /* if no wildcarding, exit out */ + + /* check for user@domain -default records */ + + if (flagwild < 2) + for (i = user.len;i >= 0;--i) + if (user.s[i - 1] == '-') { + if (!stralloc_copys(&key,prepend)) nomem(); /* prepend part */ + if (!stralloc_catb(&key,user.s,i)) nomem(); /* stripped username with dash */ + if (!stralloc_cats(&key,"default")) nomem(); /* "default" */ + if (!stralloc_cats(&key,addr + at)) nomem(); /* @domain */ + case_lowerb(key.s,key.len); + + r = cdb_seek(fdcdb,key.s,key.len,&dlen); + if (r == -1) cdbreaderror(); + if (r) { + if (setenv) + if (i <= user.len) /* paranoia */ + if (!stralloc_copyb(&env_default,user.s + i,user.len - i)) nomem(); + return 1; + } + } + + /* check for user@ records */ if (!stralloc_copys(&key,prepend)) nomem(); - if (!stralloc_cats(&key,addr + at)) nomem(); + if (!stralloc_catb(&key,addr,at + 1)) nomem(); case_lowerb(key.s,key.len); r = cdb_seek(fdcdb,key.s,key.len,&dlen); if (r == -1) cdbreaderror(); - if (r) return 1; + + if (r) { + if (setenv) + if (user.len >= 7) + if (!byte_diff("default",7,user.s + user.len - 7)) + if (!stralloc_copys(&env_default,"default")) nomem(); + return 1; + } + + /* check for user@ -default records */ + + if (flagwild < 2) + for (i = user.len;i >= 0;--i) + if (user.s[i - 1] == '-') { + if (!stralloc_copys(&key,prepend)) nomem(); /* prepend part */ + if (!stralloc_catb(&key,user.s,i)) nomem(); /* stripped username with dash */ + if (!stralloc_cats(&key,"default@")) nomem(); /* "default@" */ + case_lowerb(key.s,key.len); + + r = cdb_seek(fdcdb,key.s,key.len,&dlen); + if (r == -1) cdbreaderror(); + if (r) { + if (setenv) + if (i <= user.len) /* paranoia */ + if (!stralloc_copyb(&env_default,user.s + i,user.len - i)) nomem(); + return 1; + } + } + + /* check for @domain records */ + + if (flagwild == 3) return 0; if (!stralloc_copys(&key,prepend)) nomem(); - if (!stralloc_catb(&key,addr,at + 1)) nomem(); + if (!stralloc_cats(&key,addr + at)) nomem(); case_lowerb(key.s,key.len); r = cdb_seek(fdcdb,key.s,key.len,&dlen); if (r == -1) cdbreaderror(); if (r) return 1; + /* alas.. nothing found */ + return 0; } -int gettarget(flagwild,prepend,addr) +int gettarget(flagwild,setenv,prepend,addr) int flagwild; +int setenv; char *prepend; char *addr; { - if (!findtarget(flagwild,prepend,addr)) return 0; + if (!findtarget(flagwild,setenv,prepend,addr)) return 0; if (!stralloc_ready(&data,(unsigned int) dlen)) nomem(); data.len = dlen; @@ -205,6 +350,19 @@ args[3] = 0; } + if (!have_setenv) { + if (!stralloc_0(&env_newsender)) nomem(); + if (!env_put2("NEWSENDER", env_newsender.s)) nomem(); + if (env_default.len != 0) { + if (!stralloc_0(&env_default)) nomem(); + if (!env_put2("DEFAULT", env_default.s)) nomem(); + } + else { + if (!env_unset("DEFAULT")) nomem(); + } + have_setenv = 1; + } + switch(child = vfork()) { case -1: strerr_die2sys(111,FATAL,"unable to fork: "); @@ -222,6 +380,7 @@ case 64: case 65: case 70: case 76: case 77: case 78: case 112: case 100: _exit(100); case 0: break; + case 99: flag99 = 1; break; default: _exit(111); } @@ -233,49 +392,88 @@ { int i; int j; - i = 0; - for (j = 0;j < data.len;++j) - if (!data.s[j]) { + flag99 = 0; + j = data.len - 1; + for (i = j ; i >= 0 ; i--) { + if (i==0 || !data.s[i-1]) { 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] == '$') { + if (data.s[j - 1] == '/') + deliver_maildir(data.s + i + 1); + else + deliver_mailfile(data.s + i + 1); + } else if ((data.s[i] == '&') && (j - i < 900)) { if (!stralloc_cats(&todo,data.s + i)) nomem(); if (!stralloc_0(&todo)) nomem(); } - i = j + 1; + j = i - 1; + if (flag99) return; } + } } -void dorecip(addr) -char *addr; -{ - - if (!findtarget(0,"?",addr)) - if (gettarget(0,":",addr)) { - dodata(); - return; - } - if (!stralloc_cats(&forward,addr)) nomem(); - if (!stralloc_0(&forward)) nomem(); -} +stralloc foo = {0}; +stralloc bar = {0}; void doorigrecip(addr) char *addr; { + + char *domain; + + /* apply the envelope sender rewriting */ + + /* NOTE -- Mon Jun 14 1999 David Harris + This code to rewrite the envelope sender is weird, but it's designed + to exactly mimic qmail-local. */ + 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 (gettarget(2,0,"?",addr)) + { + if (!stralloc_copy(&foo,&data)) nomem(); + for ( foo.len-- ; foo.len >= 0 ; foo.len-- ) if ( foo.s[foo.len] == '@' ) break; + for ( domain = addr ; *domain ; domain++ ) if ( *domain == '@' ) break; + + if (!stralloc_copy(&bar,&foo)) nomem(); + if (!stralloc_cats(&bar,"-default")) nomem(); + if (!stralloc_cats(&bar,domain)) nomem(); + if (!stralloc_0(&bar)) nomem(); + + if (gettarget(3,0,":",bar.s)) + { + if (!stralloc_copy(&sender,&foo)) nomem(); + if (!stralloc_cats(&sender,"-")) nomem(); + if (!stralloc_cats(&sender,domain)) nomem(); + if (!stralloc_cats(&sender,"-@[]")) nomem(); + } + else + { + if (!stralloc_copy(&sender,&foo)) nomem(); + if (!stralloc_cats(&sender,domain)) nomem(); + } + } + } + if (!stralloc_copy(&env_newsender,&sender)) nomem(); + + /* get and apply the forwarding data */ + if (!gettarget(1,1,":",addr)) if (flagpassthrough) _exit(0); else strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)"); dodata(); + +/* if (!stralloc_0(&env_default)) nomem(); */ +/* print("DEFAULT = "); print(env_default.s); print("\n"); */ } stralloc recipient = {0}; @@ -338,6 +536,8 @@ if (!strset_add(&done,x)) nomem(); doorigrecip(x); + if ( flag99 ) _exit(flagpassthrough ? 99 : 0); + while (todo.len) { i = todo.len - 1; while ((i > 0) && todo.s[i - 1]) --i; @@ -355,8 +555,10 @@ continue; else if ((*x == '.') || (*x == '/')) dofile(x); - else - dorecip(x + 1); + else { + if (!stralloc_cats(&forward,x + 1)) nomem(); + if (!stralloc_0(&forward)) nomem(); + } } if (!forward.len) { diff -r -P -u3 fastforward-0.51_orig/filedelivery.c fastforward-0.51_my/filedelivery.c --- fastforward-0.51_orig/filedelivery.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/filedelivery.c Tue Jun 15 00:32:58 1999 @@ -0,0 +1,224 @@ +#include +#include "seek.h" +#include "open.h" +#include "now.h" +#include "fmt.h" +#include "lock.h" +#include "gfrom.h" +#include "stralloc.h" +#include "qmail.h" +#include "readwrite.h" +#include "strerr.h" +#include "sig.h" +#include "error.h" +#include "wait.h" +#include "env.h" + +/* *********************************************************** */ +/* NOTE: This code was taken from qmail-1.03/qmail-local.c */ + +#define FATAL "filedelivery: fatal: " + +void temp_slowlock() +{ strerr_die1x(111,"File has been locked for 30 seconds straight. (#4.3.0)"); } +void temp_rewind() { strerr_die1x(111,"Unable to rewind message. (#4.3.0)"); } +void temp_fork() { strerr_die3x(111,"Unable to fork: ",error_str(errno),". (#4.3.0)"); } +void temp_childcrashed() { strerr_die1x(111,"Aack, child crashed. (#4.3.0)"); } + +stralloc filed_ufline = {0}; +stralloc filed_rpline = {0}; +stralloc filed_dtline = {0}; + +int filed_envread = 0; + +stralloc messline = {0}; + +char buf[1024]; +char outbuf[1024]; + +void filed_readenv() +{ + char * x; + + if (!filed_envread) { + + x = env_get("UFLINE"); + if (!x) strerr_die2x(100,FATAL,"$UFLINE must be set"); + if (!stralloc_copys(&filed_ufline,x)) nomem(); + + x = env_get("RPLINE"); + if (!x) strerr_die2x(100,FATAL,"$RPLINE must be set"); + if (!stralloc_copys(&filed_rpline,x)) nomem(); + + x = env_get("DTLINE"); + if (!x) strerr_die2x(100,FATAL,"$DTLINE must be set"); + if (!stralloc_copys(&filed_dtline,x)) nomem(); + + } +} + +/* child process */ + +char fntmptph[80 + FMT_ULONG * 2]; +char fnnewtph[80 + FMT_ULONG * 2]; +void tryunlinktmp() { unlink(fntmptph); } +void sigalrm() { tryunlinktmp(); _exit(3); } + +void maildir_child(dir) +char *dir; +{ + unsigned long pid; + unsigned long time; + char host[64]; + char *s; + int loop; + struct stat st; + int fd; + substdio ss; + substdio ssout; + + sig_alarmcatch(sigalrm); + if (chdir(dir) == -1) { if (error_temp(errno)) _exit(1); _exit(2); } + pid = getpid(); + host[0] = 0; + gethostname(host,sizeof(host)); + for (loop = 0;;++loop) + { + time = now(); + s = fntmptph; + s += fmt_str(s,"tmp/"); + s += fmt_ulong(s,time); *s++ = '.'; + s += fmt_ulong(s,pid); *s++ = '.'; + s += fmt_strn(s,host,sizeof(host)); *s++ = 0; + if (stat(fntmptph,&st) == -1) if (errno == error_noent) break; + /* really should never get to this point */ + if (loop == 2) _exit(1); + sleep(2); + } + str_copy(fnnewtph,fntmptph); + byte_copy(fnnewtph,3,"new"); + + alarm(86400); + fd = open_excl(fntmptph); + if (fd == -1) _exit(1); + + substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); + substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf)); + if (substdio_put(&ssout,filed_rpline.s,filed_rpline.len) == -1) goto fail; + if (substdio_put(&ssout,filed_dtline.s,filed_dtline.len) == -1) goto fail; + + switch(substdio_copy(&ssout,&ss)) + { + case -2: tryunlinktmp(); _exit(4); + case -3: goto fail; + } + + if (substdio_flush(&ssout) == -1) goto fail; + if (fsync(fd) == -1) goto fail; + if (close(fd) == -1) goto fail; /* NFS dorks */ + + if (link(fntmptph,fnnewtph) == -1) goto fail; + /* if it was error_exist, almost certainly successful; i hate NFS */ + tryunlinktmp(); _exit(0); + + fail: tryunlinktmp(); _exit(1); +} + +/* end child process */ + +void maildir(fn) +char *fn; +{ + int child; + int wstat; + + filed_readenv(); + + if (seek_begin(0) == -1) temp_rewind(); + + switch(child = fork()) + { + case -1: + temp_fork(); + case 0: + maildir_child(fn); + _exit(111); + } + + wait_pid(&wstat,child); + if (wait_crashed(wstat)) + temp_childcrashed(); + switch(wait_exitcode(wstat)) + { + case 0: break; + case 2: strerr_die1x(111,"Unable to chdir to maildir. (#4.2.1)"); + case 3: strerr_die1x(111,"Timeout on maildir delivery. (#4.3.0)"); + case 4: strerr_die1x(111,"Unable to read message. (#4.3.0)"); + default: strerr_die1x(111,"Temporary error on maildir delivery. (#4.3.0)"); + } +} + +void mailfile(fn) +char *fn; +{ + int fd; + substdio ss; + substdio ssout; + int match; + seek_pos pos; + int flaglocked; + + filed_readenv(); + + if (seek_begin(0) == -1) temp_rewind(); + + fd = open_append(fn); + if (fd == -1) + strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.2.1)"); + + sig_alarmcatch(temp_slowlock); + alarm(30); + flaglocked = (lock_ex(fd) != -1); + alarm(0); + sig_alarmdefault(); + + seek_end(fd); + pos = seek_cur(fd); + + substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); + substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf)); + if (substdio_put(&ssout,filed_ufline.s,filed_ufline.len)) goto writeerrs; + if (substdio_put(&ssout,filed_rpline.s,filed_rpline.len)) goto writeerrs; + if (substdio_put(&ssout,filed_dtline.s,filed_dtline.len)) goto writeerrs; + for (;;) + { + if (getln(&ss,&messline,&match,'\n') != 0) + { + strerr_warn3("Unable to read message: ",error_str(errno),". (#4.3.0)",0); + if (flaglocked) seek_trunc(fd,pos); close(fd); + _exit(111); + } + if (!match && !messline.len) break; + if (gfrom(messline.s,messline.len)) + if (substdio_bput(&ssout,">",1)) goto writeerrs; + if (substdio_bput(&ssout,messline.s,messline.len)) goto writeerrs; + if (!match) + { + if (substdio_bputs(&ssout,"\n")) goto writeerrs; + break; + } + } + if (substdio_bputs(&ssout,"\n")) goto writeerrs; + if (substdio_flush(&ssout)) goto writeerrs; + if (fsync(fd) == -1) goto writeerrs; + close(fd); + return; + + writeerrs: + strerr_warn5("Unable to write ",fn,": ",error_str(errno),". (#4.3.0)",0); + if (flaglocked) seek_trunc(fd,pos); + close(fd); + _exit(111); +} + + diff -r -P -u3 fastforward-0.51_orig/filedelivery.h fastforward-0.51_my/filedelivery.h --- fastforward-0.51_orig/filedelivery.h Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/filedelivery.h Tue Jun 15 00:32:58 1999 @@ -0,0 +1,7 @@ +#ifndef FILEDELIVERY_H +#define FILEDELIVERY_H + +extern void maildir(char * fn); +extern void mailfile(char * fn); + +#endif diff -r -P -u3 fastforward-0.51_orig/fmt_str.c fastforward-0.51_my/fmt_str.c --- fastforward-0.51_orig/fmt_str.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/fmt_str.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,12 @@ +#include "fmt.h" + +unsigned int fmt_str(s,t) +register char *s; register char *t; +{ + register unsigned int len; + char ch; + len = 0; + if (s) { while (ch = t[len]) s[len++] = ch; } + else while (t[len]) len++; + return len; +} diff -r -P -u3 fastforward-0.51_orig/fmt_strn.c fastforward-0.51_my/fmt_strn.c --- fastforward-0.51_orig/fmt_strn.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/fmt_strn.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,12 @@ +#include "fmt.h" + +unsigned int fmt_strn(s,t,n) +register char *s; register char *t; register unsigned int n; +{ + register unsigned int len; + char ch; + len = 0; + if (s) { while (n-- && (ch = t[len])) s[len++] = ch; } + else while (n-- && t[len]) len++; + return len; +} diff -r -P -u3 fastforward-0.51_orig/gfrom.c fastforward-0.51_my/gfrom.c --- fastforward-0.51_orig/gfrom.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/gfrom.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,10 @@ +#include "str.h" +#include "gfrom.h" + +int gfrom(s,len) +char *s; +int len; +{ + while ((len > 0) && (*s == '>')) { ++s; --len; } + return (len >= 5) && !str_diffn(s,"From ",5); +} diff -r -P -u3 fastforward-0.51_orig/gfrom.h fastforward-0.51_my/gfrom.h --- fastforward-0.51_orig/gfrom.h Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/gfrom.h Tue Jun 15 00:20:19 1999 @@ -0,0 +1,6 @@ +#ifndef GFROM_H +#define GFROM_H + +extern int gfrom(); + +#endif diff -r -P -u3 fastforward-0.51_orig/lock.h fastforward-0.51_my/lock.h --- fastforward-0.51_orig/lock.h Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/lock.h Tue Jun 15 00:20:19 1999 @@ -0,0 +1,8 @@ +#ifndef LOCK_H +#define LOCK_H + +extern int lock_ex(); +extern int lock_un(); +extern int lock_exnb(); + +#endif diff -r -P -u3 fastforward-0.51_orig/lock_ex.c fastforward-0.51_my/lock_ex.c --- fastforward-0.51_orig/lock_ex.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/lock_ex.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,11 @@ +#include +#include +#include +#include "hasflock.h" +#include "lock.h" + +#ifdef HASFLOCK +int lock_ex(fd) int fd; { return flock(fd,LOCK_EX); } +#else +int lock_ex(fd) int fd; { return lockf(fd,1,0); } +#endif diff -r -P -u3 fastforward-0.51_orig/newaliases.1 fastforward-0.51_my/newaliases.1 --- fastforward-0.51_orig/newaliases.1 Tue May 19 12:25:42 1998 +++ fastforward-0.51_my/newaliases.1 Tue Jun 15 23:27:19 1999 @@ -2,13 +2,16 @@ .SH NAME newaliases \- create a forwarding database from /etc/aliases .SH SYNOPSIS -.B newaliases +.B newaliases [ aliasfile ] .SH DESCRIPTION .B newaliases reads a table of sendmail-style forwarding instructions from .B /etc/aliases +(or +.I aliasfile +if provided) and converts them into a forwarding database in .BR /etc/aliases.cdb . The forwarding database can be used by @@ -60,12 +63,6 @@ and .BR bill . -.B COMPATIBILITY WARNING: -.B newaliases -does not support file deliveries. -You can use the file delivery mechanism described in -.B dot-qmail(5) -instead. .SH "SIMPLE ALIASES" The simplest type of forwarding instruction is a line of the form @@ -82,30 +79,6 @@ .I alias without regard to case. -Forwarding instructions are cumulative. -If -.I recip -is itself an alias, -messages to -.I alias -will be forwarded the same way as -messages to -.IR recip . -For example, with the following instructions, -messages to -.B postmaster@heaven.af.mil -or -.B root@heaven.af.mil -will be delivered to Bob: - -.EX - postmaster@heaven.af.mil: bob@heaven.af.mil -.EE -.br -.EX - root@heaven.af.mil: postmaster@heaven.af.mil -.EE - .B COMPATIBILITY WARNING: With sendmail, @@ -146,10 +119,35 @@ can have the form .I user@host.dom for one user at one host, -.I @host.dom -for all users at one host, or .I user -for one user at all hosts. +for one user at all hosts, or +.I @host.dom +for all users at one host. They match in this order. + +There is also wildcarding in the username field as +implemented by +.B qmail-local +with the +.I -default +postfix. For example, when looking up +.I foo-bar-baz +we first look for +.IR foo-bar-baz , +then for +.IR foo-bar-default , +then for +.IR foo-default . + +Here's an example that shows how the two types of wildcarding +relate. When looking up the incoming e-mail address +.I foo-bar@host.dom +we look for the following patterns in the following order: +.IR foo-bar@host.dom , +.IR foo-default@host.dom , +.IR foo-bar , +.IR foo-default , +then +.IR @host.dom . .B COMPATIBILITY WARNING: sendmail @@ -164,6 +162,14 @@ but it then treats it the same way as .IR user , applying to all local hosts and virtual domains. + +.B COMBATIBILITY WARNING: +sendmail does not support the +.B qmail-local +style +.I -default +username wildcards. + .SH "ADDRESS FORMATS" Addresses in .B /etc/aliases @@ -275,6 +281,31 @@ when a message arrives for .BR weather . +Before fastforward was patched with the +.I fastforward-idx +patch by dharris@drh.net, this used the program +.B preline +program to insert the +inserts +a UUCP-style +.B From_ +line, a +.B Return-Path +line, and a +.B Delivered-To +line at the top of each message. +Now, for compatability with +.I qmail-local +preline is not used. + +To use +.B preline +in this manner, begin the forwarding command with two vertical bars: + +.EX + weather: "||weather-server" +.EE + .B COMPATIBILITY WARNING: Internet addresses can legitimately start with a slash or vertical bar. @@ -287,6 +318,29 @@ .B COMPATIBILITY WARNING: .B newaliases does not allow a vertical bar before double quotes. + +.B COMPATIBILITY WARNING: +.B sendmail +does not allow the double vertical bar syntax. + +.SH "FILE DELIVERY" +A recipient address of the form +.B :file:\fIfile +causes the mail to be delivered to either a +.I maildir +or +.I mailbox +maildrop. +If +.I file +ends in a slash, then the the filename will be interpreted +as a +.IR maildirectory , +else a +.I mbox file +maildrop. + + .SH "INCLUDE FILES" A recipient address of the form .B :include:\fIfile @@ -347,6 +401,14 @@ .BR owner-\fIlist , so that bounces go back to .BR owner-\fIlist . + +The +.B list\fI-owner +and +.B list\fI-owner-default +alias owner rewriting as implemented by +.I qmail-local +is also supported by fastforward. .B COMPATIBILITY WARNING: When an alias includes the same recipient both inside and outside diff -r -P -u3 fastforward-0.51_orig/newaliases.c fastforward-0.51_my/newaliases.c --- fastforward-0.51_orig/newaliases.c Tue May 19 12:25:42 1998 +++ fastforward-0.51_my/newaliases.c Tue Jun 15 00:32:56 1999 @@ -101,6 +101,24 @@ if (!stralloc_0(&instr)) nomem(); } +void gotfile() +{ + token822_reverse(&tokaddr); + if (token822_unquote(&address,&tokaddr) != 1) nomem(); + tokaddr.len = 0; + + if (!address.len) + strerr_die2x(111,FATAL,"empty :file: filenames not permitted"); + if (byte_chr(address.s,address.len,'\0') < address.len) + strerr_die2x(111,FATAL,"NUL not permitted in :file: filenames"); + + if (!stralloc_cats(&instr,"$")) nomem(); + if ((address.s[0] != '.') && (address.s[0] != '/')) + if (!stralloc_cats(&instr,"./")) nomem(); + if (!stralloc_cat(&instr,&address)) nomem(); + if (!stralloc_0(&instr)) nomem(); +} + void gotaddr() { int i; @@ -131,10 +149,17 @@ if (address.s[0] == '|') { if (byte_chr(address.s,address.len,'\0') < address.len) strerr_die2x(111,FATAL,"NUL not permitted in program names"); - if (!stralloc_cats(&instr,"!")) nomem(); - if (!stralloc_catb(&instr,address.s + 1,address.len - 1)) nomem(); - if (!stralloc_0(&instr)) nomem(); - return; + if (address.s[1] != '|') { + if (!stralloc_cats(&instr,"|")) nomem(); + if (!stralloc_catb(&instr,address.s + 1,address.len - 1)) nomem(); + if (!stralloc_0(&instr)) nomem(); + return; + } else { + if (!stralloc_cats(&instr,"!")) nomem(); + if (!stralloc_catb(&instr,address.s + 2,address.len - 2)) nomem(); + if (!stralloc_0(&instr)) nomem(); + return; + } } @@ -206,11 +231,22 @@ if (t >= beginning + 2) if (t[-2].type == TOKEN822_COLON) if (t[-1].type == TOKEN822_ATOM) + { if (t[-1].slen == 7) + { if (!byte_diff(t[-1].s,7,"include")) { gotincl(); t -= 2; } + } + else if (t[-1].slen == 4) + { + if (!byte_diff(t[-1].s,4,"file")) { + gotfile(); + t -= 2; + } + } + } break; /*XXX*/ case TOKEN822_RIGHT: if (tokaddr.len) gotaddr(); @@ -250,6 +286,8 @@ void doit() { + int at; + if (!instr.len) { if (target.len) parseerr(); return; @@ -257,6 +295,21 @@ if (!target.len) parseerr(); + /* Add the envelope rewriting info to the CDB file */ + + /* NOTE -- Mon Jun 14 1999 David Harris + This code to rewrite the envelope sender is weird, but it's designed + to exactly mimic qmail-local. */ + + /* Note: It is possible to have both baz-owner and owner-baz, so that baz gets two + ownsership records. Because of the CDB internals, only the first will be recognized. */ + + /* Note: I changed the form of the data stored for the "&" records. The origional + fastforward implementation stored the first e-mail address specified in the rule. + Here we store the address of the rule that genereated the instruction... this way + the rule can consist of, say, programs and it will still work. Also, this is the way + that qmail-local does things. */ + if (stralloc_starts(&target,"owner-")) { if (!stralloc_copys(&key,"?")) nomem(); if (!stralloc_catb(&key,target.s + 6,target.len - 6)) nomem(); @@ -264,24 +317,61 @@ if (cdbmss_add(&cdbmss,key.s,key.len,fulltarget.s,fulltarget.len) == -1) writeerr(); } + for ( at = target.len - 1 ; at >= 0 ; at-- ) if ( target.s[at] == '@' ) break; + if (at >= 6 ) + if (!byte_diff(target.s + at - 6, 6, "-owner")) { + if (!stralloc_copys(&key,"?")) nomem(); + if (!stralloc_catb(&key,target.s,at - 6)) nomem(); + if (!stralloc_catb(&key,target.s + at,target.len - at)) nomem(); + case_lowerb(key.s,key.len); + if (cdbmss_add(&cdbmss,key.s,key.len,fulltarget.s,fulltarget.len) == -1) writeerr(); + } + + /* Add the instructions to the CDB file */ + if (!stralloc_copys(&key,":")) nomem(); if (!stralloc_cat(&key,&target)) nomem(); case_lowerb(key.s,key.len); if (cdbmss_add(&cdbmss,key.s,key.len,instr.s,instr.len) == -1) writeerr(); } -void main() +void main(argc,argv) +int argc; +int **argv; { int fd; + stralloc aliases = {0}; + stralloc tmp = {0}; + stralloc bin = {0}; + umask(033); readcontrols(); - fd = open_read("/etc/aliases"); + if ( argc < 1 ) + { + if (!stralloc_copys(&aliases, "/etc/aliases")) nomem(); + } + else + { + if (!stralloc_copys(&aliases, argv[1])) nomem(); + } + + if (!stralloc_copy(&tmp, &aliases)) nomem(); + if (!stralloc_cats(&tmp, ".tmp")) nomem(); + if (!stralloc_0(&tmp)) nomem(); + + if (!stralloc_copy(&bin, &aliases)) nomem(); + if (!stralloc_cats(&bin, ".cdb")) nomem(); + if (!stralloc_0(&bin)) nomem(); + + if (!stralloc_0(&aliases)) nomem(); + + fd = open_read(aliases.s); if (fd == -1) readerr(); substdio_fdbuf(&ssin,read,fd,inbuf,sizeof inbuf); - fd = open_trunc("/etc/aliases.tmp"); + fd = open_trunc(tmp.s); if (fd == -1) strerr_die2sys(111,FATAL,"unable to create /etc/aliases.tmp: "); if (cdbmss_start(&cdbmss,fd) == -1) writeerr(); @@ -314,7 +404,7 @@ if (fsync(fd) == -1) writeerr(); if (close(fd) == -1) writeerr(); /* NFS stupidity */ - if (rename("/etc/aliases.tmp","/etc/aliases.cdb") == -1) + if (rename(tmp.s,bin.s) == -1) strerr_die2sys(111,FATAL,"unable to move /etc/aliases.tmp to /etc/aliases.cdb: "); _exit(0); diff -r -P -u3 fastforward-0.51_orig/now.c fastforward-0.51_my/now.c --- fastforward-0.51_orig/now.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/now.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,8 @@ +#include +#include "datetime.h" +#include "now.h" + +datetime_sec now() +{ + return time((long *) 0); +} diff -r -P -u3 fastforward-0.51_orig/now.h fastforward-0.51_my/now.h --- fastforward-0.51_orig/now.h Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/now.h Tue Jun 15 00:20:19 1999 @@ -0,0 +1,8 @@ +#ifndef NOW_H +#define NOW_H + +#include "datetime.h" + +extern datetime_sec now(); + +#endif diff -r -P -u3 fastforward-0.51_orig/open_append.c fastforward-0.51_my/open_append.c --- fastforward-0.51_orig/open_append.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/open_append.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,6 @@ +#include +#include +#include "open.h" + +int open_append(fn) char *fn; +{ return open(fn,O_WRONLY | O_NDELAY | O_APPEND | O_CREAT,0600); } diff -r -P -u3 fastforward-0.51_orig/open_excl.c fastforward-0.51_my/open_excl.c --- fastforward-0.51_orig/open_excl.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/open_excl.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,6 @@ +#include +#include +#include "open.h" + +int open_excl(fn) char *fn; +{ return open(fn,O_WRONLY | O_EXCL | O_CREAT,0644); } diff -r -P -u3 fastforward-0.51_orig/printforward.c fastforward-0.51_my/printforward.c --- fastforward-0.51_orig/printforward.c Tue May 19 12:25:42 1998 +++ fastforward-0.51_my/printforward.c Sun Jun 13 00:10:58 1999 @@ -130,6 +130,11 @@ printsafe(data.s + i,j - i); print("\n"); } + else if (data.s[i] == '$') { + print(", "); + printsafe(data.s + i,j - i); + print("\n"); + } else badformat(); i = j + 1; } diff -r -P -u3 fastforward-0.51_orig/seek_cur.c fastforward-0.51_my/seek_cur.c --- fastforward-0.51_orig/seek_cur.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/seek_cur.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,7 @@ +#include +#include "seek.h" + +#define CUR 1 /* sigh */ + +seek_pos seek_cur(fd) int fd; +{ return lseek(fd,(off_t) 0,CUR); } diff -r -P -u3 fastforward-0.51_orig/seek_end.c fastforward-0.51_my/seek_end.c --- fastforward-0.51_orig/seek_end.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/seek_end.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,7 @@ +#include +#include "seek.h" + +#define END 2 /* sigh */ + +int seek_end(fd) int fd; +{ if (lseek(fd,(off_t) 0,END) == -1) return -1; return 0; } diff -r -P -u3 fastforward-0.51_orig/seek_trunc.c fastforward-0.51_my/seek_trunc.c --- fastforward-0.51_orig/seek_trunc.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/seek_trunc.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,5 @@ +#include +#include "seek.h" + +int seek_trunc(fd,pos) int fd; seek_pos pos; +{ return ftruncate(fd,(off_t) pos); } diff -r -P -u3 fastforward-0.51_orig/setforward.1 fastforward-0.51_my/setforward.1 --- fastforward-0.51_orig/setforward.1 Tue May 19 12:25:42 1998 +++ fastforward-0.51_my/setforward.1 Tue Jun 15 21:24:11 1999 @@ -32,6 +32,11 @@ alone. The forwarding database format is portable across machines. + +.B WARNING: The format this man page describes has been updated with the +.B fastforward-idx patch from dharris@drh.net, but i've not yet bothered +.B to update this man page. + .SH "INSTRUCTION FORMAT" A forwarding instruction contains a .I target\fR, diff -r -P -u3 fastforward-0.51_orig/setforward.c fastforward-0.51_my/setforward.c --- fastforward-0.51_orig/setforward.c Tue May 19 12:25:42 1998 +++ fastforward-0.51_my/setforward.c Sun Jun 13 00:10:57 1999 @@ -132,6 +132,10 @@ if (!stralloc_cat(&instr,&command)) nomem(); if (!stralloc_0(&instr)) nomem(); } + else if (command.s[0] == '$') { + if (!stralloc_cat(&instr,&command)) nomem(); + if (!stralloc_0(&instr)) nomem(); + } else { if (command.len > 800) longaddress(); if (command.s[0] != '&') diff -r -P -u3 fastforward-0.51_orig/sig_alarm.c fastforward-0.51_my/sig_alarm.c --- fastforward-0.51_orig/sig_alarm.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/sig_alarm.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,7 @@ +#include +#include "sig.h" + +void sig_alarmblock() { sig_block(SIGALRM); } +void sig_alarmunblock() { sig_unblock(SIGALRM); } +void sig_alarmcatch(f) void (*f)(); { sig_catch(SIGALRM,f); } +void sig_alarmdefault() { sig_catch(SIGALRM,SIG_DFL); } diff -r -P -u3 fastforward-0.51_orig/sig_block.c fastforward-0.51_my/sig_block.c --- fastforward-0.51_orig/sig_block.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/sig_block.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,40 @@ +#include +#include "sig.h" +#include "hassgprm.h" + +void sig_block(sig) +int sig; +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss,sig); + sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0); +#else + sigblock(1 << (sig - 1)); +#endif +} + +void sig_unblock(sig) +int sig; +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss,sig); + sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0); +#else + sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1))); +#endif +} + +void sig_blocknone() +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); +#else + sigsetmask(0); +#endif +} diff -r -P -u3 fastforward-0.51_orig/tryflock.c fastforward-0.51_my/tryflock.c --- fastforward-0.51_orig/tryflock.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/tryflock.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,8 @@ +#include +#include +#include + +void main() +{ + flock(0,LOCK_EX | LOCK_UN | LOCK_NB); +} diff -r -P -u3 fastforward-0.51_orig/trysgprm.c fastforward-0.51_my/trysgprm.c --- fastforward-0.51_orig/trysgprm.c Wed Dec 31 19:00:00 1969 +++ fastforward-0.51_my/trysgprm.c Tue Jun 15 00:20:19 1999 @@ -0,0 +1,10 @@ +#include + +void main() +{ + sigset_t ss; + + sigemptyset(&ss); + sigaddset(&ss,SIGCHLD); + sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); +}