4 # Copyright (C) 2002-2003 Jan Kratochvil <project-PerlMail@jankratochvil.net>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 package PerlMail::Config;
22 use vars qw($VERSION);
23 $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
28 use vars qw(@ISA @EXPORT);
32 $Mail @ValidUsers $IdleMax $MaxBodySMS @SMSwebRcpt $SMSwebRcpt_username
33 $Lock_pathname $PeerAddr $Socket_timeout $DB_table $DBI_database $DBI_user $DBI_pwd
34 $clamscan_waitpid_timeout
35 $sendmail_orig @addr_addon &FromAddress @h_rcpt @h_from
36 %audit_profile @sms_squeezes @alternates_host @dnsbl_whitelist
38 $Audit $is_pgp $opt_F $procmailFROM_MAILER $store_ignore $store_ignorenewmail
43 use Carp qw(confess cluck);
47 for (qw(headerhas writeto store headeris did dnsbl store_muttrc_alternates Received_for parts_linear mime_type
48 body_first body_simple is_multipart mimehead mimebody spamassassin clamscan header_remap lmtp_deliver)) {
49 eval 'sub '.$_.' { return ::'.$_.'(@_); }';
54 # perlmail-accept & perlmail-sendmail
56 # Various configuration files location is derived from it:
57 our $HOME="/home/lace";
63 our $Mail="$HOME/Mail";
64 # Users respected for the 'idle' state (see $IdleMax):
65 our @ValidUsers=qw(root lace short kratochvil _local);
66 # Maximum number of local console idle seconds while still considered as 'active user':
68 # Maxium number of bytes to pass to Lingua::EN::Squeeze (performance optimization):
69 our $MaxBodySMS=0x1000;
70 # Telephone number to send SMSes by WWW::SMS to:
71 our @SMSwebRcpt=qw(420 602 431329);
72 # Some WWW::SMS modules require username:
73 our $SMSwebRcpt_username="lace2";
74 our $lmtp_admin="cyrus";
78 open F,"$HOME/priv/lmtp.${lmtp_admin}.pwd" or die;
83 our $lmtp_user_from="lace";
84 our $lmtp_user_to="lacemail";
85 our $clamscan_waitpid_timeout=3;
90 # Global system lock for exclusive $DB_table access:
91 our $Lock_pathname="/tmp/PerlMail.lock";
92 # 'workstation' hostname and port. Hostname may be dyndns:
93 our $PeerAddr="kashome.dyn.jankratochvil.net.:852";
94 #our $PeerAddr="127.0.0.1:2852";
95 # 15sec is NOT enough as the remote peer must complete mail store:
96 our $Socket_timeout=7600;
98 our $DB_table="PerlMail_folder";
99 # MySQL database name:
100 our $DBI_database="short";
102 our $DBI_user="short";
103 # MySQL user password:
104 our $DBI_pwd=$HOME."/priv/mysql.".$DBI_user.".pwd";
109 # Lists where <rcpt-USER.AT.HOST@jankratochvil.net> address is generated:
111 tacplus-l@disaster.com
116 ros-general@reactos.com
117 ros-kernel@reactos.com
120 4cinfo@atrey.karlin.mff.cuni.cz
122 libtool-patches@gnu.org
123 wine-license@winehq.org
124 gtk-devel-list@gnome.org
125 gnome-vfs-list@gnome.org
126 captive-announce-list@jankratochvil.net
127 captive-list@jankratochvil.net
128 captive-devel-list@jankratochvil.net
129 linux-ntfs-announce@lists.sourceforge.net
130 linux-ntfs-dev@lists.sourceforge.net
135 autoconf-patches@gnu.org
136 wget-patches@sunsite.dk
141 asterisk-perl@lists.gnuinter.net
142 isdn4linux@listserv.isdn4linux.de
143 libc-alpha@sources.redhat.com
144 squid-dev@squid-cache.org
148 # Pathname of the original sendmail(8) binary:
149 our $sendmail_orig=(-x ($_="/usr/sbin/sendmail-orig") ? $_ : "/usr/sbin/sendmail");
150 # List of addresses to locally Bcc all mails to:
151 # Mail-Alias-1.12 defaults to "/etc/mail/aliases" which does not exist on RedHat sendmail-8.12.5-7
152 # Mail-Alias-1.12 will clutter $_ !
153 our @addr_addon=(Mail::Alias->new("/etc/aliases")->exists("sentout") ? ("sentout") : ());
155 our $opt_F; # imported
156 our $is_pgp; # imported
157 my %lists=map(($_=>1),@lists);
158 # Generate new From address for the target $rcpt of type Mail::Address.
159 # $iserror is true for "MAIL FROM" RFC821 address, false for "From:" RFC822 address.
160 # Returns: Mail::Address instance.
163 my($rcpt,$iserror)=@_;
165 my $phrase=(defined $opt_F ? $opt_F : "Jan Kratochvil");
171 my $filename="$HOME/.gnupg/options";
172 open F,$filename or do { warn "Open \"$filename\": $!"; last; };
174 my @keys=map((/^\s*default-key\s+(\S+)\s*$/),<F>);
175 @keys==1 or do { warn "Found ".scalar(@keys)." 'default-key's in your \"$filename\", ignoring"; last; };
176 close F or warn "Close \"$filename\": $!";
177 my $default_key=$keys[0];
178 $default_key=~/^[[:xdigit:]]{8}$/ or do { warn "Invalid 'default-key', ignoring: $default_key"; last; };
179 return Mail::Address->new(
181 'pgp-'.uc($default_key).'@jankratochvil.net',
184 return Mail::Address->new($phrase,'lace@jankratochvil.net') if !$lists{$rcpt->address()};
185 return Mail::Address->new(
189 .(defined($rcpt->user()) ? $rcpt->user() : "NOUSER")
191 .(defined($rcpt->host()) ? $rcpt->host() : "LOCAL")
192 .'@jankratochvil.net',
196 # RedHat sendmail-8.9.3-20/src/conf.c/HdrInfo[]/\Q/* destination fields */\E
197 # FIXME: Recognize "Resent-$_" headers for -t but when we are in 'resent' mode?
198 our @h_rcpt=( # case in-sensitive!
204 # ordering matters; first header found is substituted
205 # last header is subsituted if no one is found
214 # Setup profile names.
215 # First element of /^=/ form copies it referenced profile to be extended.
216 # 'did' =>did() subroutine will return true for it.
217 # 'syslog' =>Use syslog(3).
218 # 'bell' =>Bell sound.
219 # 'sms=\d+'=>Send SMS by WWW::SMS with specified maximum # of parts
222 "silent"=>["=btw" ,"did"],
223 "log" =>["=silent","syslog"],
224 "bell" =>["=log" ,"bell"],
225 "sms" =>["=bell" ,"sms=1"],
226 "crit" =>["=sms" ,"sms=3"],
228 # Try the squeezing methods in this order:
230 { "SqueezeControl"=>"noconv" },
231 { "SqueezeControl"=>"conv" ,"SQZ_OPTIMIZE_LEVEL"=>0 },
232 { "SqueezeControl"=>"conv" ,"SQZ_OPTIMIZE_LEVEL"=>1 },
233 { "SqueezeControl"=>"med" ,"SQZ_OPTIMIZE_LEVEL"=>0 },
234 { "SqueezeControl"=>"med" ,"SQZ_OPTIMIZE_LEVEL"=>1 },
235 { "SqueezeControl"=>"max" ,"SQZ_OPTIMIZE_LEVEL"=>0 },
236 { "SqueezeControl"=>"max" ,"SQZ_OPTIMIZE_LEVEL"=>1 },
238 # Hostnames where we had alternate e-mail addresses:
239 our @alternates_host=(
240 "jabberwock.ucw.cz", # short@ucw.cz
241 "atrey.karlin.mff.cuni.cz", # short@atrey.karlin.mff.cuni.cz
242 "k332.feld.cvut.cz", # short@k332.feld.cvut.cz
244 # Override DNS blacklists:
245 our @dnsbl_whitelist=(
246 "195.250.128.83", # smtp3.vol.cz; vol.cz.multistage.blackholes.five-ten-sg.com.
247 "64.49.222.22", # mail.pm.org: rackspace.com.spam-support.blackholes.five-ten-sg.com.
248 "208.147.243.5", # gambit.liquidcomm.net: cw.net.spam-support.blackholes.five-ten-sg.com.
249 "213.235.135.70", # smtp.tiscali.cz: tiscali.cz.multistage.blackholes.five-ten-sg.com.
250 "205.139.198.11", # eniac.disaster.com: cw.net.spam-support.blackholes.five-ten-sg.com.
251 "127.0.0.2", # 2.0.0.127.relays.ordb.org.
252 "65.113.40.131", # bozo.vmware.com: qwest.net.spam-support.blackholes.five-ten-sg.com.
253 "66.218.85.33", # mta2.wss.scd.yahoo.com: yahoo.com.spam.blackholes.five-ten-sg.com.
254 "212.80.76.42", # mx2.seznam.cz: seznam.cz.free.blackholes.five-ten-sg.com.
255 "64.110.204.63", # hsdbrg64-110-204-63.sasknet.sk.ca: 64.110.202.181.sasknet.sk.ca.misc.spam.blackholes.five-ten-sg.com.
256 "212.80.76.44", # mx1.seznam.cz: 44.76.80.212.blackholes.five-ten-sg.com.
257 "212.80.76.29", # prace.seznam.cz: 212.80.76.42.seznam.cz.free.blackholes.five-ten-sg.com
258 "193.252.22.30", # smtp1.wanadoo.fr: 30.22.252.193.blackholes.five-ten-sg.com
259 "213.151.87.16", # posta.dobnet.cz: 16.87.151.213.relays.ordb.org
267 for my $alias ("",qw(admin bounces confirm join leave owner request subscribe unsubscribe)) {
268 my $head=$list.($alias?"-$alias":"");
269 my $mail=$head.'@jankratochvil.net';
270 if (headerhas("To",$mail)||headerhas("Cc",$mail)) {
271 writeto "|/usr/lib64/mailman/mail/lace/mailmanlace ".($alias||"post")." $list";
272 ###writeto "|/usr/sbin/sendmail $head".'@localhost.localdomain';
279 our $Audit; # imported
280 our $procmailFROM_MAILER; # imported
281 our $store_ignorenewmail; # imported
282 our $store_profile; # imported
283 our $store_ignore; # imported
286 $store_profile=undef();
288 # never spawn new mail if FROM_MAILER
289 # $isFROM_MAILER postponed after maillists as they may look as FROM_MAILER
291 my $isFROM_MAILER=$Audit->header()=~/$procmailFROM_MAILER/mio;
292 $store_ignorenewmail=(0
294 || headerhas "From",'<Regexp:^owner->'
297 return if did sub { store "=spy","log" if headeris "From",'<spy@jankratochvil.net>'; };
299 return if did sub { store "=hotelgatespam","log" if headeris("To",'<postmaster@hotelgate.hotelnet>'); };
303 $whitelist||=headeris("From",'<amapi11@seznam.cz>');
304 $whitelist||=headeris("From",'<llucie0@seznam.cz>');
305 $whitelist||=headeris("From",'<aaaanetka@seznamka.cz>');
306 $whitelist||=headeris("From",'<luciseksieber@centrum.cz>');
307 $whitelist||=headeris("From",'<lagica@azet.sk>');
312 return if $whitelist;
313 # Do not local $store_file as it is our-imported
314 $store_profile="silent";
315 store "=spam" if grep /^\Qshort\@k332.feld.cvut.cz\E/i,Received_for();
316 # TODO: foreign violation of RFC 822 section 4.4.4, Subject:.*Automatick.+odpov.+v.+nep.+tomnosti
317 store "=spam" if headeris "From",'<ghandchi@hotmail.com>';
318 store "=spam" if headeris "From",'<newsletter@levnapc.cz>';
319 store "=spam" if headeris "From",'<Tomas@dtpstudio.cz>';
320 store "=spam" if headeris "From",'<BNcom@email.bn.com>';
321 store "=spam" if headeris "From",'<e4luck@lists.opt4email.com>';
322 store "=spam" if headeris "From",'<mailcontests@lists.servitall.com>';
323 store "=spam" if headeris "From",'<canda@lica.cz>';
324 store "=spam" if headeris "From",'<newsletter@thecareernews.com>';
325 store "=spam" if headeris "From",'<newsletter@jobseekerweekly.com>';
326 store "=spam" if headeris "From",'<newsletter@jobmarketweekly.com>';
327 store "=spam" if headeris "From",'<newsletter@career-digest.com>';
328 store "=spam" if $Audit->subject() eq "Virus intercepted"
329 && body_simple()=~/^A message sent from\s.*\sto\s.*\scontained .* and has not been delivered[.]$/;
330 store "=spam" if headeris "From",'<supportmrswing@mrswing.com>';
331 store "=spam" if headeris "From",'<mrswing@mrswing.com>';
332 store "=spam" if headeris "From",'<root@filmcity.cz>';
333 store "=spam" if headeris "To" ,'<web-www.filmcity.cz@jankratochvil.net>';
335 return if headeris("From",'<oznameni@aukro.cz>');
336 for my $header (qw(To Cc)) {
337 store "=spam" if headerhas $header,'<st@jankratochvil.net>';
338 store "=spam" if headerhas $header,'<est@jankratochvil.net>';
339 store "=spam" if headerhas $header,'<uest@jankratochvil.net>';
340 store "=spam" if headerhas $header,'<kratochvil.net@jankratochvil.net>';
343 # weak detection: files with text/html w/o text/plain are usually a spam
344 my @types_linear=map({ mime_type($_); } parts_linear());
345 store "=spam" if grep({ $_ eq "text/html"; } @types_linear) && !grep({ $_ eq "text/plain"; } @types_linear);
347 store "=spam" if ($_=mimehead(body_first())->mime_attr("Content-Type.charset")) && /^big5/i;
349 $store_profile=undef();
352 '<captive-admin@>'=>"=caperr",
353 '<captive-devel-admin@>'=>"=caperr",
354 '<captive-announce-admin@>'=>"=caperr",
355 '<4c-admin@>'=>"=4cerr",
359 while ((my($mailaddr,$folder)=each(%mailman))) {
360 (my $maillistaddr=$mailaddr)=~s/-admin/-list$&/;
361 store $folder,"log" if (headeris("From",'<mailman-owner@vellum.cz>')&&headeris("To",$mailaddr))
362 || headeris("From",$maillistaddr)
363 || headeris("To",$maillistaddr)
364 || headeris("From",$mailaddr);
367 store "=cap","bell" if headeris "List-Id" ,'<captive-list.jankratochvil.net>';
368 store "=capd","bell" if headeris "List-Id" ,'<captive-devel-list.jankratochvil.net>';
369 store "=capann","bell" if headeris "List-Id" ,'<captive-announce-list.jankratochvil.net>';
370 store "=4c","bell" if headeris "List-Id" ,'<4c-list.vellum.cz>';
376 if ($Audit->header()!~/for <(?:4c|vmezihori1XXX)-(?:admin|owner|bounces)@/) {
377 for my $list qw(vmezihori1) {
378 $mailed+=dolist $list;
386 # It is too expensive to scan the huge =caperr announcements by spamassassin(1).
387 return if $whitelist;
388 ### return if headeris("From",qr/^captive-[a-z]*@/);
389 return if headeris("From",'<logwatch@jankratochvil.net>');
390 # Do not local $store_file as it is our-imported
391 $store_profile="log";
393 ### store "=spam".";virus=$_" if $_=clamscan();
394 store "=spam".";spamassassin".($_ eq 1 ? "" : "=$_") if $_=spamassassin();
396 ### store "=spam".";$_" if $_=dnsbl '.relays.ordb.org.' ,1; # all hosts
398 store "=spam".";$_" if $_=dnsbl '.blackholes.mail-abuse.org.' ,1; # all hosts
399 # we don't check all hosts as they can be "dialup" category, FIXME: check for it
400 # store "=spam".";$_" if $_=dnsbl '.blackholes.five-ten-sg.com.',0; # just first
402 # I don't send viruses but viruses propagate mails of mine
403 store "=spam".";ravmd" if headeris "X-Mailer",'ravmd/8.3.2';
404 store "=spam".';short@ucw.cz+MAILER' if $isFROM_MAILER && headeris("To",'<short@ucw.cz>');
405 if (!is_multipart()) {
406 local $_=mimebody(body_first());
407 my %sites=map(($_=>1),qw(
408 brandenburg.rz.fhtw-berlin.de
411 www.aufenthaltstitel.de
413 www.deutschlandchronik.de
415 www.leverkusener-aufbruch.com
417 www.mjoelnirsseite.de
427 while (m{http://([^/]+)/}g) {
428 do { $found=1; next; } if $sites{$1};
432 $found=1 if /^\s*Lese selbst:\n/s;
433 store "=spam".';german-news' if $found;
436 $store_profile=undef();
439 store "=err","bell" and return if headerhas \&Received_for,'<short+err@>';
441 # ppl-wished foreign remapping, Reply-To is left untouched!
442 # FIXME: modifications are now being dropped by &write_message!
443 header_remap("From",{
444 'kerere@post.cz' =>'kamzik@k332.feld.cvut.cz',
445 'profes@mbox.vol.cz' =>'kratochvilova@egp.cz',
446 'jkrouzek@mbox.vol.cz' =>'krouzek@mbox.fsv.cuni.cz',
447 'jakub.gorner@lidovky.cz' =>'tonda@disnet.cz',
448 'jan.kolar@videoprogress.cz' =>'jenda.kolar@volny.cz',
449 'daniel.rulicek@cponline.cz' =>'daniel.rulicek@cpress.cz',
450 'pavel@suse.cz' =>'pavel@ucw.cz',
453 # My obsolete e-mail addresses
454 store_muttrc_alternates "=redirect-","btw";
456 # nasty public lists with $store_ignore
458 # Do not local $store_file as it is our-imported
459 $store_profile="log";
461 $store_ignore="smsmail" if 1==$Audit->body() && length(join "",$Audit->body())<180; # SMS mail
462 $store_ignore="sms OS" if $Audit->subject()=~/^Email pro: /; # "^Email pro: gsm@sh\.cvut\.cz$";
463 $store_ignore="list-moron" if grep { headeris "From",$_; } qw(
469 <satko@quanto.nr.sanet.sk>
470 <vithous@attorney.cz> <viroman@attorney.cz>
476 store "=gsm" if headeris "X-BeenThere",'<gsm@lists.sh.cvut.cz>';
477 store "=gsmpand" if headeris "List-Post",'<gsm@pandora.cz>';
478 store "=9kc","log" if headeris "List-Post",'<n9k@pandora.cz>';
479 store "=9kcd","log" if headeris "List-Post",'<dev9k@pandora.cz>';
481 $store_profile=undef();
483 return if headeris "From" ,'<surprise-dev-bounces@lists.sourceforge.net>';
486 store "=mozillabug","log" if headeris "From" ,'<bugzilla-daemon@mozilla.org>';
487 store "=9ku","log" if headeris "List-Id" ,'<9000.listman.net>';
488 store "=9kd","log" if headeris "Sender" ,'<owner-9000-developers@geekstuff.co.uk>';
489 store "=spong","log" if headeris "List-Id" ,'<spong-users.lists.sourceforge.net>';
490 store "=gtkd","silent" if headeris "List-Id" ,'<gtk-devel-list.gnome.org>';
491 store "=gnomevfs","log" if headeris "List-Id" ,'<gnome-vfs-list.gnome.org>';
492 store "=mffstatnice","bell" if headeris "List-Post",'<statnice@atrey.karlin.mff.cuni.cz>';
493 store "=hw","log" if headeris "List-Post",'<hw-news@list.gin.cz>';
494 store "=gnokii","log" if headeris "List-Id" ,'<gnokii-users.mail.freesoftware.fsf.org>';
495 store "=winelic","silent" if headeris "List-Id" ,'<wine-license.winehq.org>';
496 store "=wined","silent" if headeris "List-Id" ,'<wine-devel.winehq.org>';
497 store "=winepat","silent" if headeris "List-Id" ,'<wine-patches.winehq.org>';
498 store "=winecvs","silent" if headeris "List-Id" ,'<wine-cvs.winehq.org>';
499 store "=wineann","silent" if headeris "List-Id" ,'<wine-announce.winehq.org>';
500 store "=wineconf","silent" if headeris "List-Id" ,'<wineconf.winehq.org>';
501 store "=ros","silent" if headeris "List-Id" ,'<ros-general.reactos.com>';
502 store "=roskernel","silent" if headeris "List-Id" ,'<ros-kernel.reactos.com>';
503 store "=rosd","silent" if headeris "List-Id" ,'<ros-dev.reactos.com>';
504 store "=roscvs","silent" if headeris "List-Id" ,'<ros-cvs.reactos.com>';
505 store "=rossvn","silent" if headeris "List-Id" ,'<ros-svn.reactos.com>';
506 store "=rosbug","silent" if headeris "Reply-To" ,'<scarab@reactos.wox.org>';
507 store "=fsd","silent" if headeris "X-Mailing-List",'<linux-fsdevel@vger.kernel.org>';
508 store "=kernel","silent" if headeris "X-Mailing-List",'<linux-kernel@vger.kernel.org>';
509 store "=kernelnet","silent" if headeris "X-Mailing-List",'<linux-net@vger.kernel.org>';
510 store "=ia64","silent" if headeris "X-Mailing-List",'<linux-ia64@vger.kernel.org>';
511 store "=linuxjap","silent" if headeris "X-Mailing-List",'<linux-japanese@vger.kernel.org>';
512 store "=kernelann","silent" if headeris "X-Mailing-List",'<linux-kernel-announce@vger.kernel.org>';
513 store "=sparse","silent" if headeris "X-Mailing-List",'<linux-sparse@vger.kernel.org>';
514 store "=smp","silent" if headeris "X-Mailing-List",'<linux-smp@vger.kernel.org>';
515 store "=surprise","sms" if headeris "List-Post",'<surprise@atrey.karlin.mff.cuni.cz>';
516 store "=surprisesuse","sms" if headeris "Sender" ,'<owner-surprise@suse.cz>';
517 store "=tacacs","silent" if headeris "Sender" ,'<tacplus-l@disaster.com>';
518 store "=tacacs","silent" if headeris "Sender" ,'<owner-tacplus-l@disaster.com>';
519 store "=tacacs","silent" if headeris "List-Id" ,'<devel.lists.tacplus.org>';
520 store "=pm","log" if headeris "List-Id" ,'<prague-pm.pm.org>';
521 store "=radary","log" if headeris "Reply-To" ,'<pha@radary.cz>';
522 store "=dnet","log" if headeris "Sender" ,'<@lists.distributed.net>';
523 store "=linux-input","log" if headeris "List-Post",'<linux-input@atrey.karlin.mff.cuni.cz>';
524 store "=strom","bell" if headeris "List-Post",'<vodni-strom@atrey.karlin.mff.cuni.cz>';
525 store "=netinfo","log" if headeris "Sender" ,'<owner-netinfo-l@vol.cz>';
526 store "=saintmj","log" if headeris "From" ,'<nagios@kam-enterprise.ms.mff.cuni.cz>';
527 store "=saintmj","log" if headeris "From" ,'<nagios@kam.mff.cuni.cz>';
528 store "=saintmj","log" if headeris "From" ,'<netsaint@kam.mff.cuni.cz>';
529 store "=saintjk","log" if headeris "From" ,'<nagios@gw.jklabs.cz>';
530 store "=saintjk","log" if (headeris("From" ,'<jklabs@manon.vellum.cz>')
531 || headeris("From" ,'<jklabs@ollie.vellum.cz>'))
532 && headeris("To" ,'<jklabs-nagios@jankratochvil.net>');
533 store "=4cerr","bell" if headeris "From" ,'<owner-4cinfo@atrey.karlin.mff.cuni.cz>';
534 store "=4c","sms" if headeris "List-Post",'<4cinfo@atrey.karlin.mff.cuni.cz>';
535 store "=slashdot","bell" if headeris "From" ,'<slashdot@slashdot.org>';
536 store "=freshmeat","bell" if headeris "From" ,'<noreply@freshmeat.net>';
537 store "=sourceforge","bell" if headeris "From" ,'<noreply@sourceforge.net>';
538 store "=gsmperlcvs","silent" if headeris("From" ,'<johan@intra.tektonica.com>')
539 && $Audit->subject()=~/^'.*' has been updated!$/;
540 store "=libtoold","silent" if headeris "List-Id" ,'<libtool.gnu.org>';
541 store "=libtoolpat","silent" if headeris "List-Id" ,'<libtool-patches.gnu.org>';
542 store "=automake","silent" if headeris "List-Id" ,'<automake.gnu.org>';
543 store "=autoconf","log" if headeris "List-Id" ,'<autoconf.gnu.org>';
544 store "=autoconfpat","log" if headeris "List-Id" ,'<autoconf-patches.gnu.org>';
545 store "=hurd","log" if headeris "List-Id" ,'<l4-hurd.gnu.org>';
546 store "=gccbug","silent" if headeris "List-Post",'<gcc-bugs@gcc.gnu.org>';
547 store "=gccann","log" if headeris "List-Post",'<gcc-announce@gcc.gnu.org>';
548 store "=gcc","silent" if headeris "List-Post",'<gcc@gcc.gnu.org>';
549 store "=gccpat","silent" if headeris "List-Post",'<gcc-patches@gcc.gnu.org>';
550 store "=ntfsann","silent" if headeris "List-Id" ,'<linux-ntfs-announce.lists.sourceforge.net>';
551 store "=ntfsd","silent" if headeris "List-Id" ,'<linux-ntfs-dev.lists.sourceforge.net>';
552 store "=orbit","silent" if headeris "List-Id" ,'<orbit-list.gnome.org>';
553 store "=kannel","log" if headeris "List-Id" ,'<users.kannel.org>';
554 store "=kanneld","log" if headeris "List-Id" ,'<devel.kannel.org>';
555 store "=mailmand","silent" if headeris "List-Id" ,'<mailman-developers.python.org>';
556 store "=asterisk-perl","log" if headeris "List-Post",'<asterisk-perl@lists.gnuinter.net>';
557 store "=i4l","silent" if headeris "List-Id" ,'<isdn4linux.listserv.isdn4linux.de>';
558 store "=glibc","silent" if headeris "List-Post",'<libc-alpha@sourceware.org>';
559 store "=fedann","bell" if headeris "List-Id" ,'<fedora-announce-list.redhat.com>';
560 store "=fedpkg","bell" if headeris "List-Id" ,'<fedora-package-announce.redhat.com>';
561 store "=fedtools","log" if headeris "List-Id" ,'<fedora-tools-list.redhat.com>';
562 store "=fedd","log" if headeris "List-Id" ,'<fedora-devel-list.redhat.com>';
563 store "=bashbug","log" if headeris "List-Id" ,'<bug-bash.gnu.org>';
564 store "=zaurus","silent" if headeris "List-Id" ,'<openzaurus-users.lists.sourceforge.net>';
565 store "=zaurusann","log" if headeris "List-Id" ,'<openzaurus-announce.lists.sourceforge.net>';
566 store "=zaurusd","silent" if headeris "List-Id" ,'<openzaurus-devel.lists.sourceforge.net>';
567 store "=zaurussoft","silent" if headeris "List-Id" ,'<openzaurus-software.lists.sourceforge.net>';
568 store "=iptperl","silent" if headeris "List-Id" ,'<iptperl-general.lists.sourceforge.net>';
570 store "=energie","bell" if headeris "From" ,qr/^EnergieWeb/;
571 store "=ats","log" if headeris("From" ,'<root@ms.atspraha.cz>')
572 || (headeris("From",'<online@ringier.cz>') && headerhas("To",'<blesk@atspraha.cz>'));
573 store "=atscasablanca","log" if headeris "From" ,'<casablanca@ms.atspraha.cz>';
574 store "=www-sms","log" if headeris "List-Id" ,'<www-sms-developers.lists.sourceforge.net>';
575 store "=httpdd","log" if headeris "list-post",'<dev@httpd.apache.org>';
576 store "=mms2log","log" if headeris "Return-Path",'<root@node0.mms2.org>';
577 store "=hotelgatelog","log" if headeris("Return-Path",'<root@hotelgate.hotelnet>')
578 # `SMART error' should not be matched.
579 && headeris("Subject" ,qr/^(?:Cron|Anacron|LogWatch) /);
580 store "=imja","log" if headeris "List-Id" ,'<im-ja-devel.lists.sourceforge.net>';
581 store "=wince","log" if headeris "List-Post",'<wince@pandora.cz>';
582 store "=mysqlperl","log" if headeris "List-Id" ,'<perl.mysql.com>';
583 store "=whiteann","log" if headeris "List-Id" ,'<whitebox-announce.beau.org>';
584 store "=white","log" if headeris "List-Id" ,'<whitebox-users.beau.org>';
585 store "=centos","log" if headeris "List-Id" ,'<centos.centos.org>';
586 store "=modperldoc","log" if headeris "List-Id" ,'<docs-dev.perl.apache.org>';
587 store "=qemud","log" if headeris "List-Id" ,'<qemu-devel.nongnu.org>';
588 store "=diamond","log" if headeris "X-Replicator-Inst",'"www.diamondcard.us"';
589 store "=soap","log" if headeris "Sender" ,'<owner-soap@DISCUSS.DEVELOP.COM>';
590 store "=nagiosd","log" if headeris "List-Id" ,'<nagios-devel.lists.sourceforge.net>';
591 store "=nagios","log" if headeris "List-Id" ,'<nagios-users.lists.sourceforge.net>';
592 store "=grub","log" if headeris "List-Id" ,'<grub-devel.gnu.org>';
593 store "=gdb","log" if headeris "Mailing-List",'contact gdb-help@sourceware.org; run by ezmlm';
594 store "=gdbpr","log" if headeris "Mailing-List",'contact gdb-prs-help@sourceware.org; run by ezmlm';
595 store "=gdbpat","log" if headeris "Mailing-List",'contact gdb-patches-help@sourceware.org; run by ezmlm';
596 store "=gdbann","log" if headeris "Mailing-List",'contact gdb-announce-help@sourceware.org; run by ezmlm';
597 store "=binutils","log" if headeris "Mailing-List",'contact binutils-help@sourceware.org; run by ezmlm';
598 store "=binutilsbug","log" if headeris "List-Id" ,'<bug-binutils.gnu.org>';
599 store "=4c","bell" if headeris "List-Id" ,'<4c.jankratochvil.net>';
600 store "=dup","log" if headeris "List-Id" ,'<duplicity-talk.nongnu.org>';
601 store "=dupbug","log" if headeris "List-Id" ,'<duplicity-tracker.nongnu.org>';
602 store "=sue","log" if headeris "Subject" ,'Cron <lace@manon> $HOME/secure/sue';
603 store "=linkedin","log" if headeris "From" ,'<updates@linkedin.com>';
605 # Petr Koutecky does not mark his Stuff
606 store "=koutecky","log" if headeris "Return-Path",'<velkyhroch@seznam.cz>';
607 store "=koutecky","log" if headeris "Return-Path",'<pk.petr@centrum.cz>';
608 store "=koutecky","log" if headeris "Return-Path",'<petr.koutecky@premisa.cz>';
609 store "=koutecky","log" if headeris "Return-Path",'<Petr.Koutecky@pr4.pm.ds.mfcr.cz>';
611 store "=host0log","log" if headeris("From" ,'<logwatch@jankratochvil.net>')
612 && headeris("Return-Path",'<root@jankratochvil.net>');
613 store "=host1log","log" if headeris("From" ,'<logwatch@host1.dyn.jankratochvil.net>')
614 && headeris("Return-Path",'<root@host1.dyn.jankratochvil.net>');
616 if (headeris("To" ,'<lace@jankratochvil.net>')
617 && headeris("Return-Path",'<nobody@tangens.sinus.cz>')) {
618 if (body_simple()=~/^SIP request received from <sip:2143[@]tangens.sinus.cz>.* for 2143$/o) {
619 store "=callme","log";
627 if ($Audit->header()!~/for <(?:4c|vmezihori1)-(?:admin|owner|bounces)@/) {
628 for my $list qw(mailman 4c) {
629 $mailed+=dolist $list;
635 if (($isFROM_MAILER && !did) || !did) {
636 # lmtp_deliver $lmtp_admin,$lmtp_pwd,$lmtp_user_from,$lmtp_user_to;
639 store "=errm","bell" if $isFROM_MAILER && !did()
640 # qr/daemon@/ makes $isFROM_MAILER positive.
641 && !headeris("From",'<bugzilla-daemon@bugzilla.gnome.org>');
645 # FIXME: What to do with it?
646 ### spamassassin "sa-learn --ham";
650 sub audit_sms_address
654 my $address=$obj->address();
655 if (my $alternates=muttrc_get("alternates")) {
656 return "I" if $address=~/$alternates/si;
658 my %aliases=muttrc_aliases();
659 if (my $alias=$aliases{lc $address}) {
661 s/\b(Bus)siness$/$1/i;
677 my $from=(@{$args{"from"}} ? join(",",map({ audit_sms_address($_); } @{$args{"from"}})) : "?");
682 s/(?:Re|Aw|Odp|Fw|Fwd|OT)(?:\[\d+\])?://ig;
685 s/\[\s*WAS:.*\]\s*$//i;
692 # max. 9 lines of .sig
693 s/\n-- (?:\n[^\n]*){0,9}$//gs;
694 # "Original Message"/"Puvodni zprava" etc. up to empty line
695 # "- - - Original message: - - -" is by "Lotus Notes Release 5.0.5 September 22, 2000"
696 s/(^|\n)[\s^\n]*(?:-----[\w\s]*-----|- - - Original message: - - -)[\s^\n]*(?:\n[^\n]+)*\n{2,}(?:\s*[^>\s].*$)?/\n/gs;
697 # Remove "..." lines (is it used by anyone except me?)
700 s/^(?:\s*[[:upper:]]{0,3}>)+.*$/*/gm;
701 s/(?:^|\n)(?:\*\n+)+/\n*\n/gs;
703 s/^.*\b(?:wrote|writes|napsal jste):\s*$//gm;
706 return [$from,"($subject)$body"];