pipeto.lib 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. # create a /tmp for here documents
  2. rfork en
  3. bind -c /mail/tmp /tmp
  4. # caller should set KEY and USER
  5. if(! ~ $#USER 1)
  6. USER=`{echo $1 | sed 's/local!//;s/[+\-].*//'}
  7. if(! ~ $#KEY 1)
  8. KEY=plan9
  9. cd /mail/box/$USER
  10. RECIP=$1
  11. MBOX=$2
  12. PF=/mail/box/$USER/_pattern
  13. TMP=/mail/tmp/$pid.$sysname
  14. BIN=/bin/upas
  15. D=/mail/fs/mbox/1
  16. # clean up files on exit
  17. fn sigexit {
  18. rm -f $TMP.*
  19. }
  20. fn log {
  21. if(~ $#USER 1)
  22. echo `{date} $* >>/mail/box/$USER/_log >[2]/dev/null
  23. }
  24. # deliver mail to a local file
  25. fn spool {
  26. if(~ $#* 0)
  27. _mbox=$MBOX
  28. if not
  29. _mbox=$1
  30. $BIN/deliver $RECIP $D/from $_mbox < $D/raw || exit $status
  31. }
  32. # spool but change the subject line to note spam
  33. fn spool-tagged-spam {
  34. if(~ $#* 0)
  35. _mbox=$MBOX
  36. if not
  37. _mbox=$1
  38. {
  39. cat $D/rawheader | sed 's/^[Ss][Uu][Bb][Jj][Ee][Cc][Tt]:/& SPAM:/'
  40. echo
  41. cat $D/rawbody
  42. } | $BIN/deliver $RECIP $D/from $_mbox || exit $status
  43. }
  44. # forward mail to a list of addresses
  45. fn forward {
  46. upasname=`{awk '{print $2}' $D/unixheader} cat $D/raw | upas/send $* || exit $status
  47. }
  48. # pipe mail through a command
  49. fn pipe {
  50. if(~ $#* 0)
  51. exit 'bad pipe command'
  52. {cat $D/unixheader $D/raw; echo} | $* || exit $status
  53. }
  54. # add @domain to all unqualified addresses in the message
  55. fn qualify {
  56. if(! ~ $#* 1){
  57. echo 'usage: qualify domain' >[1=2]
  58. exit bad-qualify
  59. }
  60. {
  61. sed 1q $TMP.msg
  62. cat $TMP.msg | sed 1d | upas/smtp -fh $1 a b
  63. } >$TMP.msg2 || exit $status
  64. mv $TMP.msg2 $TMP.msg || exit $status
  65. unmount /mail/fs
  66. upas/fs -f $TMP.msg || exit $status
  67. }
  68. # classify message according to token-based white list
  69. fn tokenfilter {
  70. if($BIN/list check $PF $D/from $D/sender $D/replyto)
  71. echo match
  72. if not if(~ $status *!match*)
  73. echo !match
  74. if not if($BIN/token $KEY $D/subject)
  75. echo token
  76. if not
  77. echo new
  78. }
  79. # reject a message due to the token-based white list
  80. fn tokenreply {
  81. TOKEN=`{upas/token $KEY}
  82. if(! ~ $#MAILTO 1)
  83. exit 'bad token reply: no MAILTO variable'
  84. {
  85. cat /mail/lib/token.msg |
  86. sed 's/TOKEN/'$TOKEN'/g;s/USER/'$USER'/g;s/MAILTO/'$MAILTO'/g'
  87. cat $D/raw
  88. } | upasname=/dev/null mail `{cat $D/replyto}
  89. }
  90. # add addresses in message to white list
  91. fn listupdate {
  92. $BIN/list add $PF $D/from $D/to $D/cc $D/sender
  93. }
  94. # bayesian spam filter. alternative to token. see /mail/lib/bayes.setup
  95. fn isspam {
  96. for(i in _prof.mbox _prof.spam _bounced){
  97. if(! test -f $i){
  98. echo 'need '^$i >[1=2]
  99. exit 'need '^$i
  100. }
  101. }
  102. {
  103. echo '# hash table'
  104. upas/msgcat $TMP.msg | upas/msgtok |
  105. grep -v '^....................(.*) ' |
  106. sed 's/$/ 1/'
  107. } >$TMP.tok
  108. x=`{upas/bayes -k _prof.mbox _prof.spam ~ $TMP.tok | sed 's/_prof.//'}
  109. where=$x(1)
  110. prob=$x(2)
  111. prob1000=`{echo $prob '*1000' | hoc | sed 's/\..*//'}
  112. echo `{sed 's/^From ([^ ]+) (.*)/\2 from \1/' $D/unixheader} $x >>_bounced
  113. if(~ $where spam && test $prob1000 -lt 999)
  114. where=mbox
  115. upas/addhash -o _prof.$where _prof.$where 1 $TMP.tok 1
  116. if(~ $where spam)
  117. where=''
  118. status=$where
  119. }
  120. # save and parse the mail file
  121. sed '/^$/,$ s/^From / From /' >$TMP.msg
  122. upas/fs -f $TMP.msg || exit $status