Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
# create a /tmp for here documents
2
rfork en
3
bind -c /mail/tmp /tmp
4
 
5
# caller should set KEY
6
 
7
USER=`{echo $1 | sed 's/local!//;s/[+\-].*//'}
8
if(! ~ $#KEY 1)
9
	KEY=plan9
10
 
11
cd /mail/box/$USER
12
RECIP=$1
13
MBOX=$2
14
PF=/mail/box/$USER/_pattern
15
TMP=/mail/tmp/$pid.$sysname
16
BIN=/bin/upas
17
D=/mail/fs/mbox/1
18
 
19
# clean up files on exit
20
fn sigexit {
21
	rm -f $TMP.*
22
}
23
 
24
fn log {
25
	if(~ $#USER 1)
26
		echo `{date} $* >>/mail/box/$USER/_log >[2]/dev/null
27
}
28
 
29
fn gonefishing {
30
	if (test -e gone.fishing) {
31
		MAILTO=`{cat $D/replyto}
32
		grep '^'$"MAILTO'$' gone.addrs >/dev/null >[2=1] || {
33
			echo $MAILTO >>gone.addrs
34
			message=gone.msg
35
			if (! test -e $message)
36
				message=/mail/lib/gone.msg
37
 
38
			# only respond if $USER is mentioned in To: or cc:
39
			# header.  this avoids autoresponding to mailing lists.
40
			tohdr=`{cat $D/to}
41
			cchdr=`{cat $D/cc}
42
			if (~ ' '^$"tohdr^' ' \
43
			      *' '^$USER@* *!$USER' '* *' '$USER' '* ||
44
			    ~ ' '^$"cchdr^' ' \
45
			      *' '^$USER@* *!$USER' '* *' '$USER' '*)
46
				mail $MAILTO <$message
47
			if not
48
				status=''
49
		}
50
	}
51
	if not
52
		status=''			# ensure good exit status
53
}
54
 
55
# deliver mail to a local file
56
fn spool {
57
	if(~ $#* 0)
58
		_mbox=$MBOX
59
	if not
60
		_mbox=$1
61
	$BIN/deliver $RECIP $D/from $_mbox < $D/raw || exit $status
62
	gonefishing
63
}
64
 
65
# spool but change the subject line to note spam
66
fn spool-tagged-spam {
67
	if(~ $#* 0)
68
		_mbox=$MBOX
69
	if not
70
		_mbox=$1
71
	{
72
		cat $D/rawheader | sed 's/^[Ss][Uu][Bb][Jj][Ee][Cc][Tt]:/& SPAM:/'
73
		if(! grep -si '^subject:' $D/rawheader)
74
			echo 'Subject: SPAM: '
75
		echo
76
		cat $D/rawbody
77
	} | $BIN/deliver $RECIP $D/from $_mbox || exit $status
78
	gonefishing
79
}
80
 
81
# forward mail to a list of addresses
82
fn forward {
83
	upasname=`{awk '{print $2}' $D/unixheader} cat $D/raw | upas/send $* || exit $status
84
}
85
 
86
# pipe mail through a command
87
fn pipe {
88
	if(~ $#* 0)
89
		exit 'bad pipe command'
90
	{cat $D/unixheader $D/raw; echo} | $* || exit $status
91
}
92
 
93
# add @domain to all unqualified addresses in the message
94
fn qualify {
95
	if(! ~ $#* 1){
96
		echo 'usage: qualify domain' >[1=2]
97
		exit bad-qualify
98
	}
99
	{
100
		sed 1q $TMP.msg
101
		cat $TMP.msg | sed 1d | upas/smtp -fh $1 a b
102
	} >$TMP.msg2 || exit $status
103
	mv $TMP.msg2 $TMP.msg || exit $status
104
	unmount /mail/fs
105
	upas/fs -pf $TMP.msg || exit $status
106
}
107
 
108
# classify message according to token-based white list 
109
fn tokenfilter {
110
	if($BIN/list check $PF $D/from $D/sender $D/replyto)
111
		echo match
112
	if not if(~ $status *!match*)
113
		echo !match
114
	if not if($BIN/token $KEY $D/subject)
115
		echo token
116
	if not
117
		echo new
118
}
119
 
120
# reject a message due to the token-based white list
121
fn tokenreply {
122
	TOKEN=`{upas/token $KEY}
123
	if(! ~ $#MAILTO 1)
124
		exit 'bad token reply: no MAILTO variable'
125
	{
126
		cat /mail/lib/token.msg |
127
		sed 's/TOKEN/'$TOKEN'/g;s/USER/'$USER'/g;s/MAILTO/'$MAILTO'/g'
128
		cat $D/raw
129
	} | upasname=/dev/null mail `{cat $D/replyto}
130
}
131
 
132
# add addresses in message to white list
133
fn listupdate {
134
	$BIN/list add $PF $D/from $D/to $D/cc $D/sender
135
}
136
 
137
# microsoft virus going around 9/22/2003
138
fn isvirus {
139
	virus=no
140
	if(grep -s '\.(exe|scr|bat|com)' $D/2/2/mimeheader >[2]/dev/null){
141
		s=`{ls -l $D/2/2/raw | awk '{print $6}'}
142
		if(~ $s 1440??) virus=yes
143
	}
144
	if(~ $virus yes)
145
		status=''
146
	if not
147
		status='not this virus'
148
}
149
 
150
fn hasgifattachment {
151
	gif=no
152
	if(grep -s '\.gif' $D/2/mimeheader >[2]/dev/null){
153
		gif=yes
154
	}
155
	if(~ $gif yes)
156
		status=''
157
	if not
158
		status='not this gif'
159
}
160
 
161
# bayesian spam filter.  alternative to token.  see /mail/lib/setup.bayes
162
fn isspam {
163
	for(i in _prof.mbox _prof.spam _bounced){
164
		if(! test -f $i){
165
			echo 'need '^$i >[1=2]
166
			exit 'need '^$i
167
		}
168
	}
169
	{
170
		echo '# hash table'
171
		upas/msgcat $TMP.msg | upas/msgtok |
172
			grep -v '^....................(.*)	' |
173
			sed 's/$/	1/'
174
	} >$TMP.tok
175
	x=`{upas/bayes -k _prof.mbox _prof.spam ~ $TMP.tok | sed 's/_prof.//'}
176
	where=$x(1)
177
	prob=$x(2)
178
	prob1000=`{echo $prob '*1000' | hoc | sed 's/\..*//'}
179
	echo `{sed 's/^From ([^ ]+) (.*)/\2 from \1/' $D/unixheader} $x >>_bounced
180
	if(~ $where spam && test $prob1000 -lt 999)
181
		where=mbox
182
	upas/addhash -o _prof.$where _prof.$where 1 $TMP.tok 1
183
	if(~ $where spam)
184
		where=''
185
	status=$where
186
}
187
 
188
 
189
# save and parse the mail file
190
sed '/^$/,$ s/^From / From /' >$TMP.msg
191
upas/fs -pf $TMP.msg || exit $status
192