Download | Plain Text | No Line Numbers
- --- autoresponder-0.8.pl 2025-09-12 10:36:21.235780551 +0200
- +++ autoresponder-0.8.pl 2025-09-12 10:38:44.924798079 +0200
- @@ -1,8 +1,7 @@
- #!/usr/bin/perl
- #
- -# Copyright (C) 2008-2016 Manuel Mausz (manuel@mausz.at)
- +# Copyright (C) 2008-2025 Manuel Mausz (manuel@mausz.at)
- # http://manuel.mausz.at/coding/autoresponder/
- -# Origin code copyright (c) 2004-2008 Parallels GmbH (http://www.parallels.com)
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- @@ -30,9 +29,10 @@
- use strict;
- use warnings;
- use utf8;
- +use v5.38;
- binmode(STDOUT, ':utf8');
-
- -my $VERSION = '0.7';
- +my $VERSION = '0.8';
-
- #-------------------------------------------------------------------------------
- # DATABASE TABLE LAYOUT
- @@ -88,7 +88,7 @@
-
- # this/these header/s will be added to every generated reply
- # and checked to detect some loops more easily
- -my %myheader = ('X-Mailer' => 'Confixx Autoresponder');
- +my %myheader = ('X-Mailer' => 'UD::Autoresponder');
-
- # this can be enabled if its important to exit with exitcode 0 (=success)
- # on all errors. this means "mail sent successfully" although an error occured.
- @@ -107,7 +107,7 @@
- #-------------------------------------------------------------------------------
-
- my %args = ();
- -my $getopt = new Getopt::Long::Parser();
- +my $getopt = Getopt::Long::Parser->new();
- $getopt->configure('prefix_pattern=--|-');
- $getopt->getoptions(
- \%args,
- @@ -130,7 +130,7 @@
- # create logger
- $args{'d'} = $args{'d'} || $debuglvl || 0;
- $args{'l'} = $args{'l'} || $logfile || undef;
- -our $log = new Logger(($args{'l'}) ? (file => $args{'l'}) : (handle => \*STDERR), level => $args{'d'})
- +our $log = Logger->new(($args{'l'}) ? (file => $args{'l'}) : (handle => \*STDERR), level => $args{'d'})
- or die("Couldn't create logger: $!");
-
- # fetch ident
- @@ -169,7 +169,7 @@
- ) or die("Unable to execute database query: ", DBI->errstr);
- if (scalar($cnt[0]) > 0)
- {
- - $log->info("Loop detected.", $/);
- + $log->warning("Loop detected.", $/);
- exit(0);
- }
-
- @@ -201,11 +201,11 @@
- # send mail via mailer executable
- $log->debug("Sending reply...", $/);
- my @args = ($mailer, '-ti', '-f', $reply->{'from'}->address());
- -open(MAIL, '|-') || exec { $args[0] } @args
- +open(my $mailfh, '|-') || exec { $args[0] } @args
- or die("Unable to open mailer: $!");
- -binmode(MAIL, ':utf8');
- -$reply->{'reply'}->print(\*MAIL);
- -close(MAIL);
- +$mailfh->binmode(':utf8');
- +$reply->{'reply'}->print($mailfh);
- +$mailfh->close;
-
- # insert sender into database
- $log->debug("Inserting sender into database...", $/);
- @@ -246,11 +246,11 @@
- if ($hvalue = $headers->get($hname))
- {
- chomp($hvalue);
- - die("Message is either invalid, bounced or from a mailer daemon.")
- + die("Message is either invalid, bounced or from a mailer daemon.\n")
- if ($hvalue eq '<>' || $hvalue eq "#@[]" || $hvalue =~ /MAILER-DAEMON$/i);
- - die("Unable to parse mail address.")
- + die("Unable to parse mail address.\n")
- if (!(@addrs = Mail::Address->parse($hvalue)));
- - die("Value isn't exactly one mail address.")
- + die("Value isn't exactly one mail address.\n")
- if (scalar(@addrs) != 1);
- push(@sender, $addrs[0]);
- }
- @@ -258,14 +258,14 @@
- # check From
- $hname = 'From';
- $headers->unfold($hname);
- - die("No value.")
- + die("No value.\n")
- if (!($hvalue = $headers->get($hname)));
- chomp($hvalue);
- - die("Message is either invalid or from a mailer daemon.")
- + die("Message is either invalid or from a mailer daemon.\n")
- if ($hvalue =~ /MAILER-DAEMON$/i || $hvalue =~ /Mail Delivery (?:Sub)?(?:system|service)/i);
- - die("Unable to parse mail address.")
- + die("Unable to parse mail address.\n")
- if (!(@addrs = Mail::Address->parse($hvalue)));
- - die("Value isn't exactly one mail address.")
- + die("Value isn't exactly one mail address.\n")
- if (scalar(@addrs) != 1);
- push(@sender, $addrs[0]);
-
- @@ -275,17 +275,27 @@
- if ($hvalue = $headers->get($hname))
- {
- chomp($hvalue);
- - die("Message is either junk, bulk or from mailing list.")
- + die("Message is either junk, bulk or from mailing list.\n")
- if ($hvalue =~ /(?:junk|list|bulk|autoreply)/i);
- }
-
- + # check Auto-Submitted
- + $hname = 'Auto-Submitted';
- + $headers->unfold($hname);
- + if ($hvalue = $headers->get($hname))
- + {
- + chomp($hvalue);
- + die("Message is flagged as auto submitted.\n")
- + if ($hvalue !~ /no/i);
- + }
- +
- # check X-Auto-Response-Suppress
- $hname = 'X-Auto-Response-Suppress';
- $headers->unfold($hname);
- if ($hvalue = $headers->get($hname))
- {
- chomp($hvalue);
- - die("Message is has auto response suppress header.")
- + die("Message has active uto response suppression.\n")
- if ($hvalue =~ /(?:all|oof|autoreply)/i);
- }
-
- @@ -295,7 +305,7 @@
- if ($hvalue = $headers->get($hname))
- {
- chomp($hvalue);
- - die("Message is junk.")
- + die("Message is junk.\n")
- if ($hvalue =~ /yes/i);
- }
-
- @@ -305,7 +315,7 @@
- 'X-Mailing-List', 'X-ML-Name', 'X-List')
- {
- $hname = $_; # explicit assignment needed
- - die("Message is from mailing list.")
- + die("Message is from mailing list.\n")
- if (($hvalue = $headers->get($hname)) && chomp($hvalue));
- }
-
- @@ -315,16 +325,16 @@
- if ($hvalue = $headers->get($hname))
- {
- chomp($hvalue);
- - die("Message is bounced.")
- + die("Message is bounced.\n")
- if ($hvalue =~ /^Delivery Status Notification \(Failure\)$/i || $hvalue =~ /Automated reply/i);
- $subject = $hvalue;
- }
-
- # check my own headers
- - foreach (keys(%$myheader))
- + foreach (keys($myheader->%*))
- {
- $hname = $_; # explicit assignment needed
- - die("Message is signed by myself. Probably looping.")
- + die("Message is signed by myself. Probably looping.\n")
- if (($hvalue = $headers->get($hname)) && chomp($hvalue) && $hvalue eq $myheader->{$hname});
- }
-
- @@ -342,7 +352,7 @@
- if ($@)
- {
- my $error = $@;
- - $log->info("Invalid header '", $hname, "': ", $error);
- + $log->warning("Unexpected header value '", $hname, "': ", $error);
- $log->debug("Header value: '", $hvalue, "'.", $/);
- exit(0);
- };
- @@ -403,6 +413,9 @@
- Type => 'text/plain; charset=UTF-8',
- ) or die("Unable to create reply object.");
-
- + # remove MIME::Lite added header
- + $reply->delete('X-Mailer');
- +
- # create message-id + threading
- my ($seconds, $microseconds) = gettimeofday();
- my $messageid = sprintf("<%x.%06d.%x@%s>", $seconds, $microseconds,
- @@ -414,10 +427,8 @@
- if (length($hdata->{'references'}) || length($hdata->{'messageid'}));
-
- # add some other headers
- - foreach (keys(%$myheader))
- - {
- - $reply->add($_ = $myheader->{$_});
- - }
- + $reply->add($_, $myheader->{$_})
- + foreach (keys($myheader->%*));
- $reply->add('Precedence', 'bulk');
- $reply->add('Auto-Submitted', 'auto-replied');
- $reply->add('X-Auto-Response-Suppress', 'All');
- @@ -440,6 +451,7 @@
- use Carp;
- use strict;
- use warnings;
- +use v5.38;
- use constant ERROR => 0;
- use constant WARNING => 1;
- use constant INFO => 2;
- @@ -455,26 +467,26 @@
-
- bless($self, $class);
-
- - @{$self->{'handles'}} = ();
- + $self->{'handles'}->@* = ();
- if (defined($args{'handle'}))
- {
- - my $fh = new IO::Handle();
- + my $fh = IO::Handle->new();
- $fh->fdopen($args{'handle'}, 'w')
- or return undef;
- binmode($fh, ':utf8');
- - push(@{$self->{'handles'}}, $fh);
- + push($self->{'handles'}->@*, $fh);
- }
- if (defined($args{'file'}))
- {
- - my $fh = new IO::File($args{'file'}, "a")
- + my $fh = IO::File->new($args{'file'}, "a")
- or return undef;
- # this is needed for standard confixx qmail installation
- chmod(0660, $args{'file'});
- binmode($fh, ':utf8');
- - push(@{$self->{'handles'}}, $fh);
- + push($self->{'handles'}->@*, $fh);
- }
- croak("No logging destination defined")
- - if (scalar(@{$self->{'handles'}}) <= 0);
- + if (scalar($self->{'handles'}->@*) <= 0);
-
- $self->{'level'} = (defined($args{'level'})) ? $args{'level'} : WARNING;
-
- @@ -484,10 +496,8 @@
- sub print
- {
- my ($self) = shift;
- - foreach my $fh (@{$self->{'handles'}})
- - {
- - $fh->print(POSIX::strftime("[%Y.%m.%d-%H:%M:%S] ", localtime(time)), @_);
- - }
- + $_->print(POSIX::strftime("[%Y.%m.%d-%H:%M:%S] ", localtime(time)), @_)
- + foreach ($self->{'handles'}->@*);
- return 1;
- }
-
- @@ -507,10 +517,8 @@
- sub close
- {
- my ($self) = shift;
- - foreach my $fh (@{$self->{'handles'}})
- - {
- - $fh->close();
- - }
- + $_->close()
- + foreach ($self->{'handles'}->@*);
- }
-
- #-------------------------------------------------------------------------------
-