diff -rcN sendmail-8.8.8-orig/COPYING.SPAMCAN sendmail-8.8.8-spamcan-96/COPYING.SPAMCAN
*** sendmail-8.8.8-orig/COPYING.SPAMCAN	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/COPYING.SPAMCAN	Wed Oct 29 21:38:04 1997
***************
*** 0 ****
--- 1,2 ----
+ 
+ This version is hereby in the public domain.  There is no warranty.
diff -rcN sendmail-8.8.8-orig/COPYRIGHT.SPAMCAN sendmail-8.8.8-spamcan-96/COPYRIGHT.SPAMCAN
*** sendmail-8.8.8-orig/COPYRIGHT.SPAMCAN	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/COPYRIGHT.SPAMCAN	Wed Oct 29 21:38:04 1997
***************
*** 0 ****
--- 1,8 ----
+ For all software in this distribution:
+ 
+ 	Copyright 1997 Timothy Berger -- All Rights Reserved
+ 
+ This program is free software; distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ 
diff -rcN sendmail-8.8.8-orig/INSTALL.SPAMCAN sendmail-8.8.8-spamcan-96/INSTALL.SPAMCAN
*** sendmail-8.8.8-orig/INSTALL.SPAMCAN	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/INSTALL.SPAMCAN	Wed Oct 29 23:30:23 1997
***************
*** 0 ****
--- 1,36 ----
+ 
+  The Distribution and documentation is available from
+  http://consult.ml.org/~timb/spamcan
+ 
+  1) Apply context diff to clean Sendmail 8.8.8 distribution.
+ 	You might need gnu patch.
+ 
+ 	Eg: 
+ 	tar xzvf sendmail.8.8.8.tar.gz
+ 	tar xzvf spamcan.tar.gz
+ 	cd sendmail-8.8.8
+ 	patch -p1 < ../spamcan_for_v888_diff.patch
+ 
+  2) Do NOT use gnu rx unless your system is missing some form
+ 	of regex.  I have observed segmentation faults in the rx
+ 	library	on systems with regexec and regcomp in the system's 
+ 	libc.  Sorry for previously recommending this on solaris.
+ 
+  3) Tailor spamcan.c to suit your environment.  Chose the type 
+ 	of messages you'd like to pass through un-scanned.  This is documented
+ 	in the source code.
+ 
+  4) Copy sample-spamcan.cf to /etc/spamcan.cf and edit to suit.
+         Some expressions may not be appropriate for your site.
+         Be sure to review them.
+ 
+  5) Create /etc/spamcan-exceptins.cf.  Optionally put some regular expressions
+     there.  Note, this exceptions file does not understand header names.  Because
+     of added overhead, I decided this did not add much value.
+ 
+  6) Touch /var/spool/mail/spamcan on linux or /var/mail/spamcan on Solaris.
+     Make it writable by daemon or root on solaris or by mail on linux.
+ 
+  7) Make and install sendmail.
+ 
+ -tim
diff -rcN sendmail-8.8.8-orig/NEWS.SPAMCAN sendmail-8.8.8-spamcan-96/NEWS.SPAMCAN
*** sendmail-8.8.8-orig/NEWS.SPAMCAN	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/NEWS.SPAMCAN	Wed Oct 29 23:17:15 1997
***************
*** 0 ****
--- 1,54 ----
+ 
+ Since spamcan .95
+ -----------------
+ * Version .96 is released to support sendmail-8.8.8.
+ * There are no other changes other than the bundled
+   spam filters are a bit newer; edit to suit.  They 
+   may not be approprite for your site.
+ 
+ Since spamcan .94
+ -----------------
+ * Version .95 is a pretty minor release for sendmail-8.8.7.
+   It will not be back-patched for 8.8.6.
+ * Has an exceptions list feature.
+ * Fixes a buffer overflow problem.
+ * Conversion from net byte order to host byte order for hosts where this
+   differs.  Contributed by toivo@ucs.uwa.edu.au.
+ 
+ Since spamcan .92
+ -----------------
+ * There were some spam catching problems with this version.
+   Fixed this.
+ * Added user-ownable spamcan support.  If a user touches
+   /var/spool/mail/username.spam, caught spam will be
+   sent there.  As with .nospamcan.username, this has to 
+   be owned by the appropriate user.
+ * Added support for using the header name in the regular
+   expression.
+ 
+ Since spamcan .90
+ -----------------
+ * Fixed possible segmentation fault problem if ctladdr is NULL
+ 
+ Since spamcan .87
+ -----------------
+ * users can now disable spam catching if they touch
+   /var/spool/mail/.nospamcan.username
+ * fixed possible problem where delivery to the spamcan would not
+   work if the recipient was a file.
+ * misc. bug fixes.
+ * added logging all over the place.  commented much of it out though.
+   this should be #ifdef'd
+ * learned not to use the rx package.  yes, this bit me.
+ * seems over-all much more stable
+ 
+ Since spamcan .86
+ -----------------
+ * got rid of x-spamcan-to and x-spamcan-from headers; not useful for much
+ * included simple report script
+ * make context diff
+ * small change to use the right path for spamcan file
+ 
+ Since spamcan .85
+ -------------------
+ * fixed documentation bug 
diff -rcN sendmail-8.8.8-orig/TODO.SPAMCAN sendmail-8.8.8-spamcan-96/TODO.SPAMCAN
*** sendmail-8.8.8-orig/TODO.SPAMCAN	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/TODO.SPAMCAN	Wed Oct 29 21:38:04 1997
***************
*** 0 ****
--- 1,37 ----
+ spamcan TODO list
+ ------------------
+ 
+ * Impliment a scoring system.  Assign points to regular expressions.
+   Add up the points for a mail message; if this number reaches some 
+   threashold, identify the message as spam.  Otherwise deliver mail
+   with an X-Spamlevel header with the number of points as the header
+   value.  For example, procmail's ~/.procmailrc would look like so:
+ 
+ :0 h
+ SPAMLEVEL=|formail -xX-Spamlevel:
+ 
+ :0
+ * ? test $SPAMLEVEL -gt 60
+ Mail/spamorama
+ 
+ :0
+ * ? test $SPAMLEVEL -gt 40
+ Mail/spam
+ :0
+ 
+ * ? test $SPAMLEVEL -gt 30
+ Mail/junk
+ 
+ :0
+ * ? test $SPAMLEVLE -gt 20
+ Mail/junk_lists
+ 
+ :0
+ * ? test $SPAMLEVEL -gt 10
+ Mail/lists
+ 
+ * Assign spamlevel on a per message basis rather than on a per-recipient
+   basis.  This should speed things up slightly for multiple hits.
+ 
+ * Fix X-Spamcan-Reason header.  Sometimes the wrong recipient is shown if
+   there were multiple hits.
diff -rcN sendmail-8.8.8-orig/sample-spamcan.cf sendmail-8.8.8-spamcan-96/sample-spamcan.cf
*** sendmail-8.8.8-orig/sample-spamcan.cf	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/sample-spamcan.cf	Wed Oct 29 23:12:04 1997
***************
*** 0 ****
--- 1,118 ----
+ (^(From|To): [0-9]{8}@)
+ x-advertisement
+ ((ireport|amailformetoo|mis-mail|novatechsolutions|notthere|lostvegas|dollar|tnlb|hitmasters|universe|fortune|datablast|myownemail|pleaseread|workathome|getonthe|quadxzad|jimsonstin|1stfamily|fundsrecovery|contactdata|outgoing|internetmedia|websites|4younow|hitsrus|bonghits|onestopshop|thisitscook|success|ldelivery|willametteweb|first\.amendment|showplaceintl|thehitman|NaturalInstincts|cprvid|mailermachine|just4u|owlsnest|45neter!|anywhere|killer9780home|sixdegrees|everywhere|24hrplaymates|asianmktplace|getrichclick|idp|contestsource|mary-world|globaltech2000|shoppingplanet|answerme|yourdomain|ispam|devotion|quantcom|savetrees|anydomain|nowhere)\.(com|org|net|edu))
+ ((timeisnow|INVALID_ADDRESS|-marketing|clubmail|prdfjk|metasales|whynotu|TRWLies|weightloss44|loverslife434|euroschool|forsale|email4all|srhot|foryou|vip|mailman|postman|succeed|success|everyon|megaweb|emailers?|getrichclick|allinternetusers|market|(friend(s)?))@[a-z0-9.-_]*\.(jp|org|net|com|edu))
+ (@(marketing)\.net)
+ we-deliver\.net
+ @griff\.net
+ Compucash
+ c-flash\.net
+ \$\$\$\$
+ free.*software.*!
+ make.*money.*!
+ business@mail\.t-1net\.com
+ Your Turn To Win
+ [0-9]{3,5}.*search engines
+ greathomebiz\.com
+ qualhost\.com
+ (\$.* (per|a) .* (day|month|year) .*!.*!)
+ global-impact\.com
+ pericom-usa\.com
+ 206\.45\.233\.1
+ \[207\.217\.28\.56\]
+ \[204\.246\.12\.107\]
+ \[206\.175\.223\.177\]
+ \[208\.144\.78\.230\]
+ \[206\.170\.68\.53\]
+ \[208\.128\.162\.46\]
+ 207\.92\.171\.120
+ (123|Party79333|Hangman37|balo|Onsales|HockeyUBet)@aol\.com
+ Received: from \(\[ \. \. \. \]\)
+ kohui27@compuserve\.com
+ To: .*\.{12,}
+ To:.*[ <]you@
+ Received: from xxxxxxxxxxxxxxxx
+ number18\.tierranet\.com
+ Your Listing on Yahoo
+ inetdatax\.com
+ greenharvest@t-1net\.com
+ random@random\.com
+ everyone@your\.net
+ \[12\.64\.37\.204\]
+ planetall\.com
+ Financial Freedom
+ Debt Management Club
+ 208\.211\.205\.88
+ ^Received: .*http://
+ (^Reply-to: .*noreply.*)
+ (\[000\.000\.000\.000\])
+ (\[38\.12\.123\.80\])
+ (\[205\.252\.149\.206\])
+ group mail [0-9]\.[0-9]
+ you.*profit.*from
+ extractor pro
+ keepmailing
+ money.*!{3,8}
+ get@noticed\.now
+ money.*fast
+ glenfinnan
+ marathon4com
+ fresh.*addresses
+ mega-mailer
+ mass.*mailer
+ corporate.*marketing.*lists
+ marketing .*make.*you.*rich
+ mail .*for.*sale
+ million .*messages.*per.*hour
+ message.*millions.*hour
+ bulk e?-?mail
+ jerrysp@sunspot
+ d564390\.com
+ @.*(answer)[a-z0-9.-_]*\.(com|net|org|edu)
+ ((cyber|web)(suburb|market|shop|promo|gold))
+ 4u2c?\.com
+ (mail|internet).*marketing
+ for name removal information
+ Last Chance to save
+ billy@bongo\.com
+ greatnewbooks
+ udeservelove
+ plrsssrprdtss
+ the.*internet.*! 
+ adult.*!.*!
+ marketing secrets
+ first\.amendment\.protects\.us
+ ppp3128\.on\.sympatico\.ca
+ master-graphics
+ (^Subject: .*\$.*per.*month)
+ (^Subject: .*\$.*a.*minute)
+ E-X-P-0-S-E
+ major.*credit.*card
+ credit.*card.*!.*!
+ New Web Site.*free
+ --- CLOAKED! ---
+ Internet\.Mail\.Delivery
+ low.*cost.*service
+ (long.*distance.*(service|rates))
+ you@.*ibm\.net
+ mykabot\.net
+ Adult Advertisement
+ Adults Only
+ US Ghetto AID
+ lolac@worldnet\.att\.net
+ international.*rates
+ international shop
+ VideoSex
+ Floodgate pro
+ save.*over.*[0-9]+%
+ (save the [a-z]+.*((!(!)+)|\*\*\*))
+ 212@212\.net
+ online Sex
+ sex.*!.*!.*!
+ phone.*sex
+ make.*\$.*(in|every).*days
+ Internet.*Advertis
+ sexboy24
+ distrib@usa\.net
+ --- unknown host ---
+ Smartdata\.Inc
diff -rcN sendmail-8.8.8-orig/spamcan-exceptions.cf sendmail-8.8.8-spamcan-96/spamcan-exceptions.cf
*** sendmail-8.8.8-orig/spamcan-exceptions.cf	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/spamcan-exceptions.cf	Wed Oct 29 23:12:04 1997
***************
*** 0 ****
--- 1,20 ----
+ midiworld\.com
+ dizzinews@samurai\.com
+ menieres_talk@smtp\.cochlea\.com
+ owner-dxpc@mcfeeley\.cc\.utexas\.edu
+ nationjob\.com
+ pagemart\.net
+ wheeltowheel
+ autofs@linux\.kernel\.org
+ bb@taex001\.tamu\.edu
+ SunSolve-EarlyNotifier
+ smtpgate\.norand\.com
+ bolero\.rahul\.net
+ plaidworks\.com
+ bywc@zytor
+ sun\.com
+ microsoft\.com
+ fool\.com
+ lists\.Stanford\.EDU
+ planetall\.com
+ usenix\.ORG
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.Linux sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.Linux
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.Linux	Thu Aug  7 12:29:55 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.Linux	Wed Oct 29 21:38:04 1997
***************
*** 24,30 ****
  #
  
  # use O=-O (usual) or O=-g (debugging)
! O=	-O
  
  # define the database mechanisms available for map & alias lookups:
  #	-DNDBM -- use new DBM
--- 24,30 ----
  #
  
  # use O=-O (usual) or O=-g (debugging)
! O=	-g
  
  # define the database mechanisms available for map & alias lookups:
  #	-DNDBM -- use new DBM
***************
*** 61,67 ****
  HFDIR=	${DESTDIR}/usr/lib
  
  # additional .o files needed
! OBJADD=
  
  # additional pseudo-sources needed
  BEFORE=
--- 61,67 ----
  HFDIR=	${DESTDIR}/usr/lib
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # additional pseudo-sources needed
  BEFORE=
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.1 sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.1
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.1	Thu Aug  7 12:29:57 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.1	Wed Oct 29 21:38:04 1997
***************
*** 32,45 ****
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
! LIBS=	-lresolv -l44bsd -lsocket -lnsl -lelf
  
  # location of sendmail binary (usually /usr/sbin or /usr/lib)
  BINDIR=	${DESTDIR}/usr/lib
--- 32,45 ----
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include -I/usr/local/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib -L/usr/local/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
! LIBS=	-lresolv -l44bsd -lsocket -lnsl -lelf 
  
  # location of sendmail binary (usually /usr/sbin or /usr/lib)
  BINDIR=	${DESTDIR}/usr/lib
***************
*** 51,57 ****
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD=
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
--- 51,57 ----
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.2 sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.2
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.2	Thu Aug  7 12:29:57 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.2	Wed Oct 29 21:38:04 1997
***************
*** 32,45 ****
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
! LIBS=	-lresolv -l44bsd -lsocket -lnsl -lelf
  
  # location of sendmail binary (usually /usr/sbin or /usr/lib)
  BINDIR=	${DESTDIR}/usr/lib
--- 32,46 ----
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include  -I/usr/local/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib -L/usr/local/lib
! 
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
! LIBS=	-lresolv -l44bsd -lsocket -lnsl -lelf 
  
  # location of sendmail binary (usually /usr/sbin or /usr/lib)
  BINDIR=	${DESTDIR}/usr/lib
***************
*** 51,57 ****
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD=
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
--- 52,58 ----
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.3 sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.3
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.3	Thu Aug  7 12:29:56 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.3	Wed Oct 29 21:38:04 1997
***************
*** 31,40 ****
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
--- 31,40 ----
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include -I/usr/local/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib  -L/usr/local/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
***************
*** 50,56 ****
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD=
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
--- 50,56 ----
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.4 sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.4
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.4	Thu Aug  7 12:29:56 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.4	Wed Oct 29 21:38:04 1997
***************
*** 33,42 ****
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
--- 33,42 ----
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include  -I/usr/local/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib -L/usr/local/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
***************
*** 53,59 ****
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD=
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
--- 53,59 ----
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.5 sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.5
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.5	Thu Aug  7 12:29:57 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.5	Wed Oct 29 21:38:04 1997
***************
*** 12,18 ****
  
  # use O=-O (usual) or O=-g (debugging)
  # warning: do not use -O with versions of gcc prior to 2.6
! O=	-O
  
  CC=	gcc
  
--- 12,18 ----
  
  # use O=-O (usual) or O=-g (debugging)
  # warning: do not use -O with versions of gcc prior to 2.6
! O=	-g
  
  CC=	gcc
  
***************
*** 23,29 ****
  # The really old (V7) DBM library is no longer supported.
  # See READ_ME for a description of how these flags interact.
  #
! DBMDEF=	-DNDBM -DNIS -DNISPLUS
  
  # environment definitions (e.g., -D_AIX3)
  ENVDEF=	-DSOLARIS=20500
--- 23,29 ----
  # The really old (V7) DBM library is no longer supported.
  # See READ_ME for a description of how these flags interact.
  #
! DBMDEF=	-DNDBM -DNIS
  
  # environment definitions (e.g., -D_AIX3)
  ENVDEF=	-DSOLARIS=20500
***************
*** 31,45 ****
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
  #  add -ldb if you add -DNEWDB above (in DBMDEF)
! LIBS=	-lresolv -l44bsd -lsocket -lnsl -lkstat
  
  # location of sendmail binary (usually /usr/sbin or /usr/lib)
  BINDIR=	${DESTDIR}/usr/lib
--- 31,45 ----
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include -I/usr/local/include 
  
  # library directories
! LIBDIRS=-L/usr/sww/lib -L/usr/local/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
  #  add -ldb if you add -DNEWDB above (in DBMDEF)
! LIBS=	-lresolv -lsocket -lnsl -lkstat
  
  # location of sendmail binary (usually /usr/sbin or /usr/lib)
  BINDIR=	${DESTDIR}/usr/lib
***************
*** 51,57 ****
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD=
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
--- 51,57 ----
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
diff -rcN sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.6 sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.6
*** sendmail-8.8.8-orig/src/Makefiles/Makefile.SunOS.5.6	Thu Aug  7 12:29:57 1997
--- sendmail-8.8.8-spamcan-96/src/Makefiles/Makefile.SunOS.5.6	Wed Oct 29 21:38:04 1997
***************
*** 31,40 ****
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include
  
  # library directories
! LIBDIRS=-L/usr/sww/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
--- 31,40 ----
  # see also conf.h for additional compilation flags
  
  # include directories
! INCDIRS=-I/usr/sww/include -I/usr/local/include 
  
  # library directories
! LIBDIRS=-L/usr/sww/lib  -L/usr/local/lib
  
  # libraries required on your system
  #  delete -l44bsd if you are not running BIND 4.9.x
***************
*** 50,56 ****
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD=
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
--- 50,56 ----
  HFDIR=	${DESTDIR}/etc/mail
  
  # additional .o files needed
! OBJADD= spamcan.o
  
  # things to be made before compilation begins
  BEFORE=	sysexits.h
diff -rcN sendmail-8.8.8-orig/src/conf.c sendmail-8.8.8-spamcan-96/src/conf.c
*** sendmail-8.8.8-orig/src/conf.c	Mon Oct 20 08:41:38 1997
--- sendmail-8.8.8-spamcan-96/src/conf.c	Wed Oct 29 21:38:05 1997
***************
*** 1001,1010 ****
  */
  
  int
! checkcompat(to, e)
  	register ADDRESS *to;
  	register ENVELOPE *e;
  {
  # ifdef lint
  	if (to == NULL)
  		to++;
--- 1001,1020 ----
  */
  
  int
! checkcompat(to, e, is_spam)
  	register ADDRESS *to;
  	register ENVELOPE *e;
+ 	int *is_spam;
  {
+   int spamcan(ADDRESS *to, ENVELOPE *e, int *is_spam );
+   int retval;
+ 
+   retval = spamcan(to, e, is_spam);
+ 
+   if (retval != EX_OK)
+     return( retval );
+ 
+ 
  # ifdef lint
  	if (to == NULL)
  		to++;
***************
*** 1014,1019 ****
--- 1024,1030 ----
  		printf("checkcompat(to=%s, from=%s)\n",
  			to->q_paddr, e->e_from.q_paddr);
  
+ 
  # ifdef EXAMPLE_CODE
  	/* this code is intended as an example only */
  	register STAB *s;
***************
*** 1973,1979 ****
  
  /* Non Apollo stuff removed by Don Lewis 11/15/93 */
  #ifndef lint
! static char  rcsid[] = "@(#)$Id: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
  #endif /* !lint */
  
  #ifdef apollo
--- 1984,1990 ----
  
  /* Non Apollo stuff removed by Don Lewis 11/15/93 */
  #ifndef lint
! static char  rcsid[] = "@(#)$Id: conf.c,v 1.2 1997/07/18 07:31:18 timb Exp timb $";
  #endif /* !lint */
  
  #ifdef apollo
***************
*** 2939,2945 ****
   * causing nast effects.
   **************************************************************/
  
! /*static char _id[] = "$Id: snprintf.c,v 1.2 1995/10/09 11:19:47 roberto Exp $";*/
  static void	sm_dopr();
  static char	*DoprEnd;
  static int	SnprfOverflow;
--- 2950,2956 ----
   * causing nast effects.
   **************************************************************/
  
! /*static char _id[] = "$Id: conf.c,v 1.2 1997/07/18 07:31:18 timb Exp timb $";*/
  static void	sm_dopr();
  static char	*DoprEnd;
  static int	SnprfOverflow;
diff -rcN sendmail-8.8.8-orig/src/deliver.c sendmail-8.8.8-spamcan-96/src/deliver.c
*** sendmail-8.8.8-orig/src/deliver.c	Wed Oct 22 13:12:02 1997
--- sendmail-8.8.8-spamcan-96/src/deliver.c	Wed Oct 29 23:08:30 1997
***************
*** 846,851 ****
--- 846,852 ----
  	char rpathbuf[MAXNAME + 1];	/* translated return path */
  	extern int checkcompat();
  	extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int));
+ 	int is_spam;
  
  	errno = 0;
  	if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags))
***************
*** 1013,1018 ****
--- 1014,1020 ----
  
  		user = to->q_user;
  		e->e_to = to->q_paddr;
+ 
  		if (tTd(10, 5))
  		{
  			printf("deliver: QDONTSEND ");
***************
*** 1043,1057 ****
  				e->e_from.q_paddr, to->q_paddr, e);
  		if (rcode == EX_OK)
  		{
! 			/* do in-code checking */
! 			rcode = checkcompat(to, e);
! 		}
! 		if (rcode != EX_OK)
! 		{
! 			markfailure(e, to, NULL, rcode);
! 			giveresponse(rcode, m, NULL, ctladdr, xstart, e);
! 			continue;
! 		}
  
  		/*
  		**  Strip quote bits from names if the mailer is dumb
--- 1045,1065 ----
  				e->e_from.q_paddr, to->q_paddr, e);
  		if (rcode == EX_OK)
  		{
! 		  /* do in-code checking */
! 		  rcode = checkcompat(to, e, &is_spam);
! 		  /*		  sm_syslog(LOG_DEBUG, e->e_id, "Ran checkcompat"); */
! 		}
!                 if (rcode != EX_OK)
!                 {
! 		  sm_syslog(LOG_DEBUG, e->e_id, "Bad code from checkcompat, rcode = %d", rcode);
! 		  markfailure(e, to, NULL, rcode);
! 		  giveresponse(rcode, m, NULL, ctladdr, xstart, e);
! 		  continue;
!                 }
! 		
! 		/* reset because spamcan modifies these */
! 		user = to->q_user; 
! 		m = to->q_mailer;
  
  		/*
  		**  Strip quote bits from names if the mailer is dumb
***************
*** 1065,1072 ****
  		}
  
  		/* hack attack -- delivermail compatibility */
! 		if (m == ProgMailer && *user == '|')
! 			user++;
  
  		/*
  		**  If an error message has already been given, don't
--- 1073,1081 ----
  		}
  
  		/* hack attack -- delivermail compatibility */
! 		if (m == ProgMailer && *user == '|') {
! 		  user++;
! 		}
  
  		/*
  		**  If an error message has already been given, don't
***************
*** 1078,1084 ****
  		*/
  
  		if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
! 			continue;
  
  		/*
  		**  See if this user name is "special".
--- 1087,1093 ----
  		*/
  
  		if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
! 		  continue;
  
  		/*
  		**  See if this user name is "special".
***************
*** 1090,1096 ****
  
  		if (strcmp(m->m_mailer, "[FILE]") == 0)
  		{
! 			rcode = mailfile(user, ctladdr, SFF_CREAT, e);
  			giveresponse(rcode, m, NULL, ctladdr, xstart, e);
  			e->e_nsent++;
  			if (rcode == EX_OK)
--- 1099,1106 ----
  
  		if (strcmp(m->m_mailer, "[FILE]") == 0)
  		{
! 
! 		  rcode = mailfile(user, ctladdr, SFF_CREAT, e, is_spam);
  			giveresponse(rcode, m, NULL, ctladdr, xstart, e);
  			e->e_nsent++;
  			if (rcode == EX_OK)
***************
*** 1545,1550 ****
--- 1555,1561 ----
  			(void) setsignal(SIGHUP, SIG_IGN);
  			(void) setsignal(SIGTERM, SIG_DFL);
  
+ 
  			if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
  				stb.st_mode = 0;
  
***************
*** 3092,3108 ****
  static void	mailfiletimeout();
  
  int
! mailfile(filename, ctladdr, sfflags, e)
  	char *volatile filename;
  	ADDRESS *ctladdr;
  	volatile int sfflags;
  	register ENVELOPE *e;
  {
  	register FILE *f;
  	register pid_t pid = -1;
  	volatile int mode = ST_MODE_NOFILE;
  	bool suidwarn = geteuid() == 0;
  	EVENT *ev;
  
  	if (tTd(11, 1))
  	{
--- 3103,3121 ----
  static void	mailfiletimeout();
  
  int
! mailfile(filename, ctladdr, sfflags, e, is_spam)
  	char *volatile filename;
  	ADDRESS *ctladdr;
  	volatile int sfflags;
  	register ENVELOPE *e;
+ 	int is_spam;
  {
  	register FILE *f;
  	register pid_t pid = -1;
  	volatile int mode = ST_MODE_NOFILE;
  	bool suidwarn = geteuid() == 0;
  	EVENT *ev;
+ 	int spamcan_exists = 0;
  
  	if (tTd(11, 1))
  	{
***************
*** 3168,3176 ****
  			mode = FileMode;
  			oflags |= O_CREAT|O_EXCL;
  		}
! 		else if (bitset(0111, stb.st_mode) || stb.st_nlink != 1 ||
  			 (SafeFileEnv != NULL && !S_ISREG(stb.st_mode)))
  			exit(EX_CANTCREAT);
  		if (mode == ST_MODE_NOFILE)
  			mode = stb.st_mode;
  
--- 3181,3192 ----
  			mode = FileMode;
  			oflags |= O_CREAT|O_EXCL;
  		}
! 		else {
! 		  if (bitset(0111, stb.st_mode) || stb.st_nlink != 1 ||
  			 (SafeFileEnv != NULL && !S_ISREG(stb.st_mode)))
  			exit(EX_CANTCREAT);
+ 		  spamcan_exists = is_spam; 
+ 		}
  		if (mode == ST_MODE_NOFILE)
  			mode = stb.st_mode;
  
***************
*** 3197,3206 ****
  			}
  		}
  
  		/* select a new user to run as */
  		if (!bitset(SFF_RUNASREALUID, sfflags))
  		{
! 			if (bitset(S_ISUID, mode))
  			{
  				RealUserName = NULL;
  				RealUid = stb.st_uid;
--- 3213,3231 ----
  			}
  		}
  
+ 
+ 		/* set uid and gid for spam file */
+ 
+ 		if ( is_spam ) {
+ 		  sfflags |= SFF_ROOTOK;
+ 		}
+ 
  		/* select a new user to run as */
+ 
  		if (!bitset(SFF_RUNASREALUID, sfflags))
  		{
! 		  
! 			if (bitset(S_ISUID, mode) || spamcan_exists)
  			{
  				RealUserName = NULL;
  				RealUid = stb.st_uid;
***************
*** 3212,3217 ****
--- 3237,3243 ----
  				else
  					RealUserName = ctladdr->q_user;
  				RealUid = ctladdr->q_uid;
+ 
  			}
  			else if (FileMailer != NULL && FileMailer->m_uid != 0)
  			{
***************
*** 3225,3238 ****
  			}
  
  			/* select a new group to run as */
! 			if (bitset(S_ISGID, mode))
  				RealGid = stb.st_gid;
! 			else if (ctladdr != NULL && ctladdr->q_uid != 0)
  				RealGid = ctladdr->q_gid;
! 			else if (FileMailer != NULL && FileMailer->m_gid != 0)
  				RealGid = FileMailer->m_gid;
! 			else
  				RealGid = DefGid;
  		}
  
  		/* last ditch */
--- 3251,3281 ----
  			}
  
  			/* select a new group to run as */
! 			if ( bitset(S_ISGID, mode) || spamcan_exists ) {
  				RealGid = stb.st_gid;
! 			}
! 			else if (ctladdr != NULL && ctladdr->q_uid != 0) {
  				RealGid = ctladdr->q_gid;
! 				if (is_spam && LogLevel > 15)
! 				  sm_syslog(LOG_DEBUG, e->e_id, 
! 					    "using cltaddr gid %d", ctladdr->q_gid);
! 			}
! 			else if (FileMailer != NULL && FileMailer->m_gid != 0) {
  				RealGid = FileMailer->m_gid;
! 				sm_syslog(LOG_DEBUG, e->e_id,
! 					  "using filemailer gid %d", FileMailer->m_gid);
! 			}
! 			else {
  				RealGid = DefGid;
+ 				sm_syslog(LOG_DEBUG, e->e_id,
+ 					  "using default gid %d", DefGid);
+ 			}
+ 
+                         /* spamcan diag */
+ 			if (is_spam && LogLevel > 12)
+ 			  sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: selected owner (%d, %d) for %s",
+ 				    RealUid, RealGid, filename);
+ 				  
  		}
  
  		/* last ditch */
diff -rcN sendmail-8.8.8-orig/src/savemail.c sendmail-8.8.8-spamcan-96/src/savemail.c
*** sendmail-8.8.8-orig/src/savemail.c	Wed Oct 22 19:30:27 1997
--- sendmail-8.8.8-spamcan-96/src/savemail.c	Wed Oct 29 21:38:05 1997
***************
*** 368,374 ****
  			expand("\201z/dead.letter", buf, sizeof buf, e);
  			flags = SFF_NOLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
  			e->e_to = buf;
! 			if (mailfile(buf, NULL, flags, e) == EX_OK)
  			{
  				int oldverb = Verbose;
  
--- 368,374 ----
  			expand("\201z/dead.letter", buf, sizeof buf, e);
  			flags = SFF_NOLINK|SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID;
  			e->e_to = buf;
! 			if (mailfile(buf, NULL, flags, e, 0) == EX_OK)
  			{
  				int oldverb = Verbose;
  
diff -rcN sendmail-8.8.8-orig/src/sendmail.h sendmail-8.8.8-spamcan-96/src/sendmail.h
*** sendmail-8.8.8-orig/src/sendmail.h	Wed Oct 22 13:12:02 1997
--- sendmail-8.8.8-spamcan-96/src/sendmail.h	Wed Oct 29 21:38:05 1997
***************
*** 1412,1418 ****
  extern void	markstats __P((ENVELOPE *, ADDRESS *));
  extern void	poststats __P((char *));
  extern char	*arpadate __P((char *));
! extern int	mailfile __P((char *, ADDRESS *, int, ENVELOPE *));
  extern void	loseqfile __P((ENVELOPE *, char *));
  extern int	prog_open __P((char **, int *, ENVELOPE *));
  extern bool	getcanonname __P((char *, int, bool));
--- 1412,1418 ----
  extern void	markstats __P((ENVELOPE *, ADDRESS *));
  extern void	poststats __P((char *));
  extern char	*arpadate __P((char *));
! extern int	mailfile __P((char *, ADDRESS *, int, ENVELOPE *, int));
  extern void	loseqfile __P((ENVELOPE *, char *));
  extern int	prog_open __P((char **, int *, ENVELOPE *));
  extern bool	getcanonname __P((char *, int, bool));
diff -rcN sendmail-8.8.8-orig/src/spamcan.c sendmail-8.8.8-spamcan-96/src/spamcan.c
*** sendmail-8.8.8-orig/src/spamcan.c	Wed Dec 31 16:00:00 1969
--- sendmail-8.8.8-spamcan-96/src/spamcan.c	Wed Oct 29 23:17:27 1997
***************
*** 0 ****
--- 1,612 ----
+ /*
+ 
+  Tim Berger
+  timb@consult.ml.org
+  
+  Capture mail messages having regular expression matches with any
+  header.
+ 
+  Version 0.96
+ 
+  **
+ 
+  Copyright 1997 Timothy Berger - All Rights Reserved
+ 
+  This program is free software distributed in the hope that it will be
+  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ 
+  **
+ 
+  */
+ 
+ 
+ # include "sendmail.h"
+ # include "pathnames.h"
+ # include <sys/ioctl.h>
+ # include <sys/param.h>
+ # include <sys/stat.h>
+ 
+ # ifdef __linux__
+ #   include <rx.h>
+ #   define SPOOL_DIR "/var/spool/mail/"
+ # else
+ #   include <regex.h>
+ #   define SPOOL_DIR "/var/mail/"
+ # endif
+ 
+ /* concat the spool directory with the following filename */
+ 
+ #define SPAMCAN SPOOL_DIR  "spamcan"
+ 
+ /* enable personal spam mail files */
+ 
+ #define PERSONAL_SPAMCAN
+ 
+ /* You probably shouldn't have too many regular expressions.
+  This default is probably way to big.  */
+ 
+ #define SPAMCAN_MAX_REGEX_COUNT 4096
+ 
+ /* for concat of header name with value */
+ 
+ #define MAX_HEADER_LENGTH 4096
+ 
+ /* The max string lengh of any regular expression.  I imagine regcomp
+    would barf on a 4k regular expression. */
+ 
+ #define SPAMCAN_MAX_REGEX_STRLEN 4096
+ 
+ /* Allow users to disable spam capture bound for them. */
+ 
+ #define USER_CONTROL
+ 
+ /* Set FILTER_DISCRIMNATION to ONE OF THESE to decide what types of
+    messages you don't wish to filter.  Breifly, 
+ 
+    NO_DISCRIMINATION will make spamcan scan every mail message
+    connecting to your sendmail daemon.
+ 
+    RELAY_DISCRIMINATION will make spamcan only scan messages
+    originating from discrimination_mask.
+ 
+    SUBNET_DISCRIMINATION will make spamcan only scan messages not
+    originating from the subnet your specify in discrimination_mask.
+    Standard stuff from the O'Rielly Sendmail book.
+ 
+    LOCALHOST_DISCRIMINATION will make spamcan scan all messages not
+    originating from the local machine.
+ 
+    */
+ 
+ #define NO_DISCRIMINATION		0
+ #define RELAY_DISCRIMINATION		1
+ #define SUBNET_DISCRIMINATION           2
+ #define LOCALHOST_DISCRIMINATION        3
+ 
+ #define FILTER_DISCRIMNATION		LOCALHOST_DISCRIMINATION
+ 
+ #define SPRINTF_BUFFSIZE                512
+ 
+ 
+ /*
+ 
+   here is an example of how to convert your ip or netmask to hex:
+   echo 24.1.16.108 | awk -F. '{printf("0x%02x%02x%02x%02x\n", $1, $2, $3, $4)}'
+ 
+   The following discrimination mask is only used if  FILTER_DISCRIMNATION	
+   is defined as SUBNET_DISCRIMINATION
+ 
+ */
+ 
+ #define SUBNET_MASK 0xffffff00
+ 
+ /* set this to your relay, local ip, or subnet mask */
+ 
+ static long discrimination_mask = 0x1801106c;
+ 
+ /* the regular expression buffer */
+ static char *spamcan_cf = "/etc/spamcan.cf";
+ regex_t spamcan_regex_list[SPAMCAN_MAX_REGEX_COUNT];
+ static int spamcan_regex_count = 0;
+ static int spamcan_mtime = 0;
+ 
+ /* regular expressions that let mail pass through */
+ static char *spamcan_exceptions = "/etc/spamcan-exceptions.cf";
+ regex_t spamcan_exceptions_list[SPAMCAN_MAX_REGEX_COUNT];
+ static int spamcan_rx_exceptions_count = 0;
+ static int spamcan_exceptions_mtime = 0;
+ 
+ void spamcan_load_regex(filename, explist, expcount, filename_mtime ) 
+      char *filename;
+      regex_t *explist;
+      int *expcount, *filename_mtime;
+ {
+ 
+   int loop;
+   FILE *fp;
+   struct stat st;
+   int error;
+   char regex_message[SPAMCAN_MAX_REGEX_STRLEN];
+   char regexbuff[SPAMCAN_MAX_REGEX_STRLEN];
+ 
+   if (stat(filename, &st) == -1) {
+     sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: Can't stat %s", filename);
+     return;
+   }
+ 
+   if ( st.st_mtime > *filename_mtime ) {
+     *filename_mtime = st.st_mtime;
+   }
+   else {
+     return;
+   }
+ 
+   if ( ! (fp = fopen(filename, "r")) ) {
+     sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: Problem reading %s", filename);
+     return;
+   }
+ 
+   if (LogLevel > 12)
+     sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: Loading spam file %s", filename);
+ 
+   loop = 0;
+   while( (fgets(regexbuff, SPAMCAN_MAX_REGEX_STRLEN, fp) != NULL) && loop < SPAMCAN_MAX_REGEX_COUNT ) {
+     *(regexbuff + strlen(regexbuff) -1 ) = '\0';
+     if (strlen(regexbuff) < 4) {
+       sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: expression [%s] from [%s] is too small, possible typo", 
+ 		regexbuff, filename);
+       continue;
+     }
+     if (LogLevel > 19)
+       sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: read expression %s", regexbuff);
+     if ( (error=regcomp(& explist[loop], regexbuff, REG_EXTENDED|REG_ICASE)) ) {
+       regerror(error, & explist[loop], regex_message, (size_t)SPAMCAN_MAX_REGEX_STRLEN);
+       sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: unable to compile expression [%s] from [%s].  index = %d, %s", 
+ 		regexbuff, filename, loop, regex_message);
+     }
+     else {
+       if (LogLevel > 12)
+ 	sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: compiled expression [%s] to index %d",
+ 		  regexbuff, loop);
+       loop++;
+     }
+   }
+ 
+   fclose (fp);
+ 
+   *expcount = loop;
+ 
+   if (LogLevel > 12) 
+     sm_syslog(LOG_DEBUG, NOQID, "SPAMCAN: Compiled %d regular expressions",  
+ 	      *expcount); 
+ 
+ 
+ }
+ 
+ void spamcan_mark_to_save(to, e, reason, to_username, to_uid)
+      ADDRESS *to;
+      ENVELOPE *e;
+      char *reason;
+      char *to_username;
+      uid_t to_uid;
+ {
+ 
+   char *spamcap;
+   HDR *header;
+   int found;
+   char *personal_spamcan;
+   struct stat st;
+ 
+   personal_spamcan = NULL;
+ 
+ #if defined(PERSONAL_SPAMCAN)
+ 
+   if (to_username != NULL) {
+     personal_spamcan = (char*) 
+       malloc( strlen(SPOOL_DIR) + strlen(to_username) + strlen(".spam") + 1 );
+ 
+     if (personal_spamcan == NULL) {
+       sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: out of memory");
+       return;
+     }
+ 
+     strcpy(personal_spamcan, SPOOL_DIR);
+     strcat(personal_spamcan, to_username);
+     strcat(personal_spamcan, ".spam");
+     if (stat(personal_spamcan, &st) == 0) {
+       if (to_uid == st.st_uid) {
+ 	to->q_user = personal_spamcan;
+ 	to->q_mailer = FileMailer;
+       }
+       else {
+ 	sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s exists, but has wrong ownership %d",
+ 		  personal_spamcan, st.st_uid);
+       }
+     }
+   }
+   else {
+     sm_syslog(LOG_DEBUG, e->e_id, "username is NULL");
+   }
+ 
+ #endif
+   
+   if (personal_spamcan != to->q_user) {
+     spamcap = (char *)malloc( strlen(SPAMCAN ) + 1 );
+ 
+     if (spamcap == NULL) {
+       sm_syslog(LOG_DEBUG, e->e_id, "out of memory");
+       return;
+     }
+ 
+     strcpy (spamcap, SPAMCAN);
+     to->q_user = spamcap;
+     to->q_mailer = FileMailer;
+   }
+ 
+   if (LogLevel > 9)
+     sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: selected spamcan %s",
+ 	      to->q_user);
+ 
+   for(header = e->e_header, found = 0; header && !found; header = header->h_link) {
+     if ( strcasecmp("X-Spamcan-Reason", header->h_field) == 0) {
+        header->h_value = reason;
+       found = 1;
+     }
+   }
+ 
+   if ( !found ) {
+     addheader("X-Spamcan-Reason", reason, &e->e_header);
+   }
+ 
+ }
+ 
+ int spamcan_find_header(e, name, value)
+      ENVELOPE *e;
+      char *name, **value;
+ {
+ HDR *h_ptr;
+ int found = 0;
+ 
+ for(h_ptr = e->e_header;h_ptr != NULL; h_ptr = h_ptr->h_link) {
+   if (strcasecmp(name, h_ptr->h_field) == 0) {
+     *value = h_ptr->h_value;
+     return (1);
+   }
+ }
+ return(0);
+ 
+ }
+ 
+ 
+   /* This is completely incompatable with most mailing lists.
+    Forget this for now.  May use some of this code in a future release */
+ 
+ int sanity_check(to, e, to_username, to_uid)
+      ADDRESS *to;
+      ENVELOPE *e;
+      char *to_username;
+      uid_t to_uid;
+ {
+   char *print_to;
+   HDR *h_ptr;
+   char *from_header, *to_header, *reply_header, *sender_header;
+   char *reason_alloc;
+   char reason[SPRINTF_BUFFSIZE];
+   ADDRESS *ctladdr;
+ 
+   reason_alloc = (char*)malloc(SPRINTF_BUFFSIZE);
+ 
+   if ( reason_alloc == NULL) {
+     sm_syslog(LOG_DEBUG, e->e_id, "out of memory");
+     return(0);
+   }
+ 
+ 
+   if (to_username != NULL) {
+     print_to = to_username;
+   }
+   else {
+     print_to = to->q_user;
+     ctladdr = getctladdr(to);
+     if ( ctladdr != NULL ) {
+       if (ctladdr->q_user != NULL) {
+ 	print_to =  ctladdr->q_user;
+       }
+     }
+   }
+ 
+ 
+   /* don't accept outside mail without to header */
+ 
+   if( !spamcan_find_header(e, "To", &to_header) ) {
+     sprintf(reason, "No \"To\" header from [%s] to [%s]",
+ 	    e->e_from.q_paddr, print_to );
+     strcpy(reason_alloc, reason);
+     sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s", reason_alloc);
+     spamcan_mark_to_save(to, e, reason_alloc, to_username, to_uid);
+     return (1);
+   }
+ 
+   /* don't accept outside mail without from header */
+ 
+   if ( !spamcan_find_header(e, "From", &from_header) ) {
+     sprintf(reason, "No \"From\" header from [%s] to [%s]",
+ 	    e->e_from.q_paddr, print_to );
+     strcpy(reason_alloc, reason);
+     sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s", reason_alloc);
+     spamcan_mark_to_save(to, e, reason_alloc, to_username, to_uid);
+     return (1);
+   }
+ 
+   /* check if to matches from */
+ 
+   if ( strcasecmp(from_header, to_header) == 0) {
+     sprintf(reason, "Identical headers \"From\" and \"To\" from [%s] to [%s]",
+ 	    e->e_from.q_paddr, print_to );
+     strcpy(reason_alloc, reason);
+     sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s", reason_alloc);
+     spamcan_mark_to_save(to, e, reason_alloc, to_username, to_uid);
+     return(1);
+   }
+ 
+   /* check if to matches reply-to */
+ 
+   if ( spamcan_find_header(e, "Reply-To", &reply_header)) {
+     if ( strcasecmp(to_header, reply_header) == 0) {
+       sprintf(reason, "Identical headers \"Reply-To\" and \"To\" from [%s] to [%s]",
+ 	      e->e_from.q_paddr, print_to );
+       strcpy(reason_alloc, reason);
+       sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s", reason_alloc);
+       spamcan_mark_to_save(to, e, reason_alloc, to_username, to_uid);
+       return(1);
+     }
+   }
+ 
+   /* check if sender maches to */
+ 
+   if ( spamcan_find_header(e, "Sender", &sender_header)) {
+     if ( strcasecmp(to_header, sender_header) == 0) {
+       sprintf(reason, "Identical headers \"Sender\" and \"To\" from [%s] to [%s]",
+ 	      e->e_from.q_paddr, print_to );
+       strcpy(reason_alloc, reason);
+       sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s", reason_alloc);
+       spamcan_mark_to_save(to, e, reason_alloc, to_username, to_uid);
+       return(1);
+     }
+   }
+ 
+ 
+   return (0);
+ 
+ }
+ 
+   
+ int spamcan_match ( name, substr, e, to, to_username, to_uid )
+ char *name;
+ char *substr;
+ ENVELOPE *e;
+ ADDRESS *to;
+ char *to_username;
+ uid_t to_uid;
+ 
+ {
+ 
+   int loop, error;
+   regmatch_t pmatch[1];
+   char reason_prime[SPRINTF_BUFFSIZE], reason[SPRINTF_BUFFSIZE], *reason_alloc;
+   char *print_to;
+   ADDRESS *ctladdr;
+ 
+   reason_alloc = (char*)malloc(SPRINTF_BUFFSIZE);
+ 
+   if ( reason_alloc == NULL) {
+     sm_syslog(LOG_DEBUG, e->e_id, "out of memory");
+     return(0);
+   }
+ 
+  if (to_username != NULL) {
+     print_to = to_username;
+   }
+   else {
+     print_to = to->q_user;
+     ctladdr = getctladdr(to);
+     if ( ctladdr != NULL ) {
+       if (ctladdr->q_user != NULL) {
+ 	print_to =  ctladdr->q_user;
+       }
+     }
+   }
+   
+ 
+ 
+   for(loop = 0; loop < spamcan_regex_count; ++loop) {
+     
+     /* sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: looking at string [%s]", substr);  */
+     
+     if ( (error=regexec(& spamcan_regex_list[loop],
+ 			substr, 1, &pmatch[0], 0)) == 0) {
+       /*      sm_syslog(LOG_DEBUG, e->e_id, "there was a match"); */
+       snprintf(reason_prime, SPRINTF_BUFFSIZE,
+ 	       "substring [%%.%ds] matched [%%s] with expression [#%%d] from [%s] to [%s]",
+ 	       pmatch[0].rm_eo - pmatch[0].rm_so,
+ 	       e->e_from.q_paddr,
+ 	       print_to );
+       snprintf(reason,  SPRINTF_BUFFSIZE, reason_prime,
+ 	       substr  + pmatch[0].rm_so, name, loop);
+ 
+       sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s", reason);
+       strcpy(reason_alloc, reason);
+       spamcan_mark_to_save(to, e, reason_alloc, to_username, to_uid);
+       return( 1 );
+     }
+     else {
+       /*      sm_syslog(LOG_DEBUG, e->e_id, "No match with regex #%d", loop);  */
+     }
+   }
+ 
+   return( 0 );
+ 
+ }
+ 
+ int spamcan(to, e, is_spam )
+      register ADDRESS *to;
+      register ENVELOPE *e;
+      int *is_spam;
+ 
+ {
+   HDR *h_ptr;
+   struct stat st;
+   char user_disable_spamcan_file[512];
+   char *to_username;
+   struct passwd *pwent;
+   ADDRESS *alist;
+   int username_found;
+   uid_t to_uid;
+   char full_header[MAX_HEADER_LENGTH];
+   struct in_addr natural_in;
+   int loop;
+ 
+   *is_spam = 0;
+ 
+   if ( RealHostAddr.sa.sa_family != AF_INET )
+     return (EX_OK);
+ 
+   if( RealHostAddr.sin.sin_addr.s_addr == 0x7f000001 )
+     return( EX_OK );
+ 
+   /* Convert net byte order to host byte order - toivo@ucs.uwa.edu.au */
+   natural_in.s_addr = ntohl(RealHostAddr.sin.sin_addr.s_addr);
+ 
+     /* pass through locally generated mail - check specific ip address */
+ 
+   if ( FILTER_DISCRIMNATION == LOCALHOST_DISCRIMINATION &&
+        natural_in.s_addr == discrimination_mask )
+     return( EX_OK );
+ 
+     /* don't filter mail unless from relay */
+ 
+   if ( FILTER_DISCRIMNATION == RELAY_DISCRIMINATION &&
+ 	 natural_in.s_addr != discrimination_mask)
+       return ( EX_OK );
+   
+   /* don't filter mail generated from specified subnet */
+   if (  FILTER_DISCRIMNATION == SUBNET_DISCRIMINATION &&
+ 	(natural_in.s_addr & SUBNET_MASK) == discrimination_mask
+ 	)
+     return ( EX_OK );
+ 
+   /* pass through mail with In-Reply-To header */
+   for(h_ptr = e->e_header;h_ptr != NULL; h_ptr = h_ptr->h_link) {
+     if ( (strcasecmp("In-reply-to", h_ptr->h_field) == 0) )
+       return (EX_OK);
+   }
+ 
+   username_found = 0;
+   to_username = NULL;
+   alist = to;
+   while ( alist && ! username_found) {
+     pwent = getpwnam(alist->q_user);
+     if (pwent != NULL) {
+       to_username = alist->q_user;
+       to_uid = pwent->pw_uid;
+       username_found = 1;
+     }
+     alist = alist->q_alias;
+   }
+ 
+ #if defined(USER_CONTROL)
+ 
+   /* Need to know username here.  If I knew how to get this reliably any 
+    other way this wouldn't be necessary.  */
+ 
+   strcpy(user_disable_spamcan_file, SPOOL_DIR ".nospamcan.");
+   if ( username_found ) {
+     strcat(user_disable_spamcan_file, to_username);
+     if (LogLevel > 12) 
+       sm_syslog(LOG_DEBUG, e->e_id, 
+ 		"SPAMCAN: Checking for file %s", user_disable_spamcan_file);
+   }
+ 
+   if( stat(user_disable_spamcan_file, &st) == 0 && to_username != NULL) {
+     if( to_uid == st.st_uid) {
+       sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s exists, not capturing mail for %s",
+ 		user_disable_spamcan_file, to_username);
+       return (EX_OK);
+     }
+     else {
+        sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: %s exists but has wrong ownership %d",
+ 		user_disable_spamcan_file,  st.st_uid);
+     }
+   }
+ 
+ #endif
+ 
+   spamcan_load_regex(spamcan_cf, spamcan_regex_list, &spamcan_regex_count,
+ 		     &spamcan_mtime);
+ 
+   /* load exceptions */
+ 
+   spamcan_load_regex(spamcan_exceptions, spamcan_exceptions_list, 
+ 		     &spamcan_rx_exceptions_count, &spamcan_exceptions_mtime);
+ 
+     for(h_ptr = e->e_header; h_ptr != NULL; h_ptr = h_ptr->h_link) {
+       for(loop=0; loop < spamcan_rx_exceptions_count; ++loop) {
+ 	if ( h_ptr->h_value != NULL &&
+ 	     regexec( &spamcan_exceptions_list[loop], h_ptr->h_value,
+ 		      0, NULL, 0) == 0) {
+ 	  if (LogLevel > 12)
+ 	    sm_syslog(LOG_DEBUG, e->e_id, "SPAMCAN: Passing message through");
+ 	  return(EX_OK);
+ 	}
+       }
+     }
+ 
+   /* check each header for a match */
+ 
+   for(h_ptr = e->e_header; h_ptr != NULL; h_ptr = h_ptr->h_link) {
+     
+     /* skip the message id header, it contains nothing useful
+      and may cause filtering problems */
+ 
+     if ( (strcasecmp( "Message-Id", h_ptr->h_field) == 0) )
+       continue;
+ 
+     if ( (strcasecmp( "Resent-Message-Id", h_ptr->h_field) == 0) )
+       continue;
+ 
+     /* terminate last byte with null character in the event that we run out of space */
+ 
+     *( full_header +  MAX_HEADER_LENGTH - 1 ) = '\0';
+ 
+     strncpy(full_header, h_ptr->h_field, MAX_HEADER_LENGTH - 1);
+ 
+     strncpy(full_header + strlen(full_header), ": ", 
+ 	    MAX_HEADER_LENGTH - 1 - strlen(full_header) );
+ 
+     if ( h_ptr->h_value != NULL ) {
+       strncpy(full_header + strlen(full_header), h_ptr->h_value, 
+ 	      MAX_HEADER_LENGTH - 1 - strlen(full_header));
+     }
+ 
+ 
+     if ( spamcan_match(h_ptr->h_field, full_header, e, to, to_username, to_uid) ) {
+       *is_spam = 1;
+       return( EX_OK);
+     }
+ 
+   }
+ 
+   /* skip possibly null ? value for envelope sender */
+ 
+   if (e->e_from.q_paddr == NULL) {
+     return(EX_OK);
+   }
+ 
+   if ( spamcan_match("Sender from Envelope", e->e_from.q_paddr, e, to, to_username, to_uid) ) {
+     *is_spam = 1;
+     return ( EX_OK );
+   }
+ 
+   return(EX_OK);
+ }
