123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- # create a /tmp for here documents
- rfork en
- bind -c /mail/tmp /tmp
- # caller should set KEY
- USER=`{echo $1 | sed 's/local!//;s/[+\-].*//'}
- if(! ~ $#KEY 1)
- KEY=plan9
- cd /mail/box/$USER
- RECIP=$1
- MBOX=$2
- PF=/mail/box/$USER/_pattern
- TMP=/mail/tmp/$pid.$sysname
- BIN=/bin/upas
- D=/mail/fs/mbox/1
- # clean up files on exit
- fn sigexit {
- rm -f $TMP.*
- }
- fn log {
- if(~ $#USER 1)
- echo `{date} $* >>/mail/box/$USER/_log >[2]/dev/null
- }
- fn gonefishing {
- if (test -e gone.fishing) {
- MAILTO=`{cat $D/replyto}
- grep '^'$"MAILTO'$' gone.addrs >/dev/null >[2=1] || {
- echo $MAILTO >>gone.addrs
- message=gone.msg
- if (! test -e $message)
- message=/mail/lib/gone.msg
- # only respond if $USER is mentioned in To: or cc:
- # header. this avoids autoresponding to mailing lists.
- tohdr=`{cat $D/to}
- cchdr=`{cat $D/cc}
- if (~ ' '^$"tohdr^' ' \
- *' '^$USER@* *!$USER' '* *' '$USER' '* ||
- ~ ' '^$"cchdr^' ' \
- *' '^$USER@* *!$USER' '* *' '$USER' '*)
- mail $MAILTO <$message
- if not
- status=''
- }
- }
- if not
- status='' # ensure good exit status
- }
- # deliver mail to a local file
- fn spool {
- if(~ $#* 0)
- _mbox=$MBOX
- if not
- _mbox=$1
- $BIN/deliver $RECIP $D/from $_mbox < $D/raw || exit $status
- gonefishing
- }
- # spool but change the subject line to note spam
- fn spool-tagged-spam {
- if(~ $#* 0)
- _mbox=$MBOX
- if not
- _mbox=$1
- {
- cat $D/rawheader | sed 's/^[Ss][Uu][Bb][Jj][Ee][Cc][Tt]:/& SPAM:/'
- if(! grep -si '^subject:' $D/rawheader)
- echo 'Subject: SPAM: '
- echo
- cat $D/rawbody
- } | $BIN/deliver $RECIP $D/from $_mbox || exit $status
- gonefishing
- }
- # forward mail to a list of addresses
- fn forward {
- upasname=`{awk '{print $2}' $D/unixheader} cat $D/raw | upas/send $* || exit $status
- }
- # pipe mail through a command
- fn pipe {
- if(~ $#* 0)
- exit 'bad pipe command'
- {cat $D/unixheader $D/raw; echo} | $* || exit $status
- }
- # add @domain to all unqualified addresses in the message
- fn qualify {
- if(! ~ $#* 1){
- echo 'usage: qualify domain' >[1=2]
- exit bad-qualify
- }
- {
- sed 1q $TMP.msg
- cat $TMP.msg | sed 1d | upas/smtp -fh $1 a b
- } >$TMP.msg2 || exit $status
- mv $TMP.msg2 $TMP.msg || exit $status
- unmount /mail/fs
- upas/fs -pf $TMP.msg || exit $status
- }
- # classify message according to token-based white list
- fn tokenfilter {
- if($BIN/list check $PF $D/from $D/sender $D/replyto)
- echo match
- if not if(~ $status *!match*)
- echo !match
- if not if($BIN/token $KEY $D/subject)
- echo token
- if not
- echo new
- }
- # reject a message due to the token-based white list
- fn tokenreply {
- TOKEN=`{upas/token $KEY}
- if(! ~ $#MAILTO 1)
- exit 'bad token reply: no MAILTO variable'
- {
- cat /mail/lib/token.msg |
- sed 's/TOKEN/'$TOKEN'/g;s/USER/'$USER'/g;s/MAILTO/'$MAILTO'/g'
- cat $D/raw
- } | upasname=/dev/null mail `{cat $D/replyto}
- }
- # add addresses in message to white list
- fn listupdate {
- $BIN/list add $PF $D/from $D/to $D/cc $D/sender
- }
- # microsoft virus going around 9/22/2003
- fn isvirus {
- virus=no
- if(grep -s '\.(exe|scr|bat|com)' $D/2/2/mimeheader >[2]/dev/null){
- s=`{ls -l $D/2/2/raw | awk '{print $6}'}
- if(~ $s 1440??) virus=yes
- }
- if(~ $virus yes)
- status=''
- if not
- status='not this virus'
- }
- fn hasgifattachment {
- gif=no
- if(grep -s '\.gif' $D/2/mimeheader >[2]/dev/null){
- gif=yes
- }
- if(~ $gif yes)
- status=''
- if not
- status='not this gif'
- }
- # bayesian spam filter. alternative to token. see /mail/lib/setup.bayes
- fn isspam {
- for(i in _prof.mbox _prof.spam _bounced){
- if(! test -f $i){
- echo 'need '^$i >[1=2]
- exit 'need '^$i
- }
- }
- {
- echo '# hash table'
- upas/msgcat $TMP.msg | upas/msgtok |
- grep -v '^....................(.*) ' |
- sed 's/$/ 1/'
- } >$TMP.tok
- x=`{upas/bayes -k _prof.mbox _prof.spam ~ $TMP.tok | sed 's/_prof.//'}
- where=$x(1)
- prob=$x(2)
- prob1000=`{echo $prob '*1000' | hoc | sed 's/\..*//'}
- echo `{sed 's/^From ([^ ]+) (.*)/\2 from \1/' $D/unixheader} $x >>_bounced
- if(~ $where spam && test $prob1000 -lt 999)
- where=mbox
- upas/addhash -o _prof.$where _prof.$where 1 $TMP.tok 1
- if(~ $where spam)
- where=''
- status=$where
- }
- # save and parse the mail file
- sed '/^$/,$ s/^From / From /' >$TMP.msg
- upas/fs -pf $TMP.msg || exit $status
|