This commit is contained in:
2024-10-14 00:08:40 +02:00
parent dbfba56f66
commit 1462d52e13
4572 changed files with 2658864 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
package Sisimai::Reason::Blocked;
use feature ':5.10';
use strict;
use warnings;
sub text { 'blocked' }
sub description { 'Email rejected due to client IP address or a hostname' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $regex = qr{(?>
access[ ]denied[.][ ]ip[ ]name[ ]lookup[ ]failed
|access[ ]from[ ]ip[ ]address[ ].+[ ]blocked
|all[ ]mail[ ]servers[ ]must[ ]have[ ]a[ ]ptr[ ]record[ ]with[ ]a[ ]valid[ ]reverse[ ]dns[ ]entry
|bad[ ]sender[ ]ip[ ]address
|banned[ ]sending[ ]ip # Office365
|blacklisted[ ]by
|(?:blocked|refused)[ ]-[ ]see[ ]https?://
|blocked[ ]using[ ]
|can[']t[ ]determine[ ]purported[ ]responsible[ ]address
|cannot[ ](?:
find[ ]your[ ]hostname
|resolve[ ]your[ ]address
)
|client[ ]host[ ](?:
.+[ ]blocked[ ]using
|rejected:[ ](?:
abus[ ]detecte[ ]gu_eib_0[24] # SFR
|cannot[ ]find[ ]your[ ]hostname # Yahoo!
|may[ ]not[ ]be[ ]mail[ ]exchanger
|was[ ]not[ ]authenticated # Microsoft
)
)
|confirm[ ]this[ ]mail[ ]server
|connection[ ](?:
dropped
|refused[ ]by
|reset[ ]by[ ]peer
|was[ ]dropped[ ]by[ ]remote[ ]host
)
|connections[ ](?:
not[ ]accepted[ ]from[ ]ip[ ]addresses[ ]on[ ]spamhaus[ ]xbl
|will[ ]not[ ]be[ ]accepted[ ]from[ ].+because[ ]the[ ]ip[ ]is[ ]in[ ]spamhaus's[ ]list
)
|currently[ ]sending[ ]spam[ ]see:[ ]
|domain[ ](?:
.+[ ]mismatches[ ]client[ ]ip
|does[ ]not[ ]exist:
)
|dns[ ]lookup[ ]failure:[ ].+[ ]try[ ]again[ ]later
|dnsbl:attrbl
|dynamic/zombied/spam[ ]ips[ ]blocked
|email[ ]blocked[ ]by[ ](?:.+[.]barracudacentral[.]org|spamhaus)
|esmtp[ ]not[ ]accepting[ ]connections # icloud.com
|fix[ ]reverse[ ]dns[ ]for[ ].+
|go[ ]away
|helo[ ]command[ ]rejected:
|host[ ].+[ ]refused[ ]to[ ]talk[ ]to[ ]me:[ ]\d+[ ]blocked
|hosts[ ]with[ ]dynamic[ ]ip
|http://(?:
spf[.]pobox[.]com/why[.]html
|www[.]spamcop[.]net/bl[.]
)
|invalid[ ]ip[ ]for[ ]sending[ ]mail[ ]of[ ]domain
|ip[ ]\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}[ ]is[ ]blocked[ ]by[ ]earthlink # Earthlink
|ip[/]domain[ ]reputation[ ]problems
|ips[ ]with[ ]missing[ ]ptr[ ]records
|is[ ](?:
in[ ]a[ ]black[ ]list[ ]at[ ].+[.]
|in[ ]an[ ].*rbl[ ]on[ ].+
|not[ ]allowed[ ]to[ ]send[ ](?:
mail[ ]from
|from[ ].+[ ]per[ ]it's[ ]spf[ ]record
)
)
|mail[ ]server[ ]at[ ].+[ ]is[ ]blocked
|mail[ ]from[ ]\d+[.]\d+[.]\d+[.]\d[ ]refused:
|message[ ]from[ ].+[ ]rejected[ ]based[ ]on[ ]blacklist
|messages[ ]from[ ].+[ ]temporarily[ ]deferred[ ]due[ ]to[ ]user[ ]complaints # Yahoo!
|no[ ](?:
access[ ]from[ ]mail[ ]server
|ptr[ ]record[ ]found[.]
)
|not[ ]currently[ ]accepting[ ]mail[ ]from[ ]your[ ]ip # Microsoft
|part[ ]of[ ]their[ ]network[ ]is[ ]on[ ]our[ ]block[ ]list
|please[ ](?:
get[ ]a[ ]custom[ ]reverse[ ]dns[ ]name[ ]from[ ]your[ ]isp[ ]for[ ]your[ ]host
|inspect[ ]your[ ]spf[ ]settings
|use[ ]the[ ]smtp[ ]server[ ]of[ ]your[ ]isp
)
|ptr[ ]record[ ]setup
|rejecting[ ]open[ ]proxy # Sendmail(srvrsmtp.c)
|reverse[ ]dns[ ](?:
failed
|required
|lookup[ ]for[ ]host[ ].+[ ]failed[ ]permanently
)
|sender[ ]ip[ ](?:
address[ ]rejected
|reverse[ ]lookup[ ]rejected
)
|server[ ]access[ ](?:
.+[ ]forbidden[ ]by[ ]invalid[ ]rdns[ ]record[ ]of[ ]your[ ]mail[ ]server
|forbidden[ ]by[ ]your[ ]ip[ ]
)
|server[ ]ip[ ].+[ ]listed[ ]as[ ]abusive
|service[ ]permits[ ]\d+[ ]unverifyable[ ]sending[ ]ips
|smtp[ ]error[ ]from[ ]remote[ ]mail[ ]server[ ]after[ ]initial[ ]connection: # Exim
|sorry,[ ](?:
that[ ]domain[ ]isn'?t[ ]in[ ]my[ ]list[ ]of[ ]allowed[ ]rcpthosts
|your[ ]remotehost[ ]looks[ ]suspiciously[ ]like[ ]spammer
)
|spf[ ](?:
.+[ ]domain[ ]authentication[ ]fail
|record
|check:[ ]fail
)
|spf:[ ].+[ ]is[ ]not[ ]allowed[ ]to[ ]send[ ]mail.+[a-z]{3}.+401
|the[ ](?:email|domain|ip).+[ ]is[ ]blacklisted
|this[ ]system[ ]will[ ]not[ ]accept[ ]messages[ ]from[ ]servers[/]devices[ ]with[ ]no[ ]reverse[ ]dns
|too[ ]many[ ]spams[ ]from[ ]your[ ]ip # free.fr
|unresolvable[ ]relay[ ]host[ ]name
|veuillez[ ]essayer[ ]plus[ ]tard.+[a-z]{3}.+(?:103|510)
|your[ ](?:
network[ ]is[ ]temporary[ ]blacklisted
|sender's[ ]ip[ ]address[ ]is[ ]listed[ ]at[ ].+[.]abuseat[.]org
|server[ ]requires[ ]confirmation
)
|was[ ]blocked[ ]by[ ].+
|we[ ]do[ ]not[ ]accept[ ]mail[ ]from[ ](?: # @mail.ru
dynamic[ ]ips
|hosts[ ]with[ ]dynamic[ ]ip[ ]or[ ]generic[ ]dns[ ]ptr-records
)
|you[ ]are[ ](?:
not[ ]allowed[ ]to[ ]connect
|sending[ ]spam
)
|your[ ](?:
access[ ]to[ ]submit[ ]messages[ ]to[ ]this[ ]e-mail[ ]system[ ]has[ ]been[ ]rejected
|message[ ]was[ ]rejected[ ]for[ ]possible[ ]spam/virus[ ]content
)
)
}x;
return 1 if $argv1 =~ $regex;
return 0;
}
sub true {
# Rejected due to client IP address or hostname
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is blocked
# [Integer] 0: is not blocked by the client
# @see http://www.ietf.org/rfc/rfc2822.txt
# @since v4.0.0
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'blocked';
return 1 if Sisimai::SMTP::Status->name($argvs->deliverystatus) eq 'blocked';
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Blocked - Bounce reason is "blocked" or not.
=head1 SYNOPSIS
use Sisimai::Reason::Blocked;
print Sisimai::Reason::Blocked->match('Access from ip address 192.0.2.1 blocked'); # 1
=head1 DESCRIPTION
Sisimai::Reason::Blocked checks the bounce reason is "blocked" or not. This
class is called only Sisimai::Reason class.
This is the error that SMTP connection was rejected due to a client IP address
or a hostname, or the parameter of "HELO/EHLO" command. This reason has added
in Sisimai 4.0.0 and does not exist in any version of bounceHammer.
<kijitora@example.net>:
Connected to 192.0.2.112 but my name was rejected.
Remote host said: 501 5.0.0 Invalid domain name
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: "blocked".
print Sisimai::Reason::Blocked->text; # blocked
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::Blocked->match('Access from ip address 192.0.2.1 blocked'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is "blocked". The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,110 @@
package Sisimai::Reason::ContentError;
use feature ':5.10';
use strict;
use warnings;
sub text { 'contenterror' }
sub description { 'Email rejected due to a header format of the email' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'improper use of 8-bit data in message header',
'message header size, or recipient list, exceeds policy limit',
'message mime complexity exceeds the policy maximum',
'routing loop detected -- too many received: headers',
'this message contain invalid mime headers',
'this message contain improperly-formatted binary content',
'this message contain text that uses unnecessary base64 encoding',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Rejected email due to header format of the email
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: rejected due to content error
# 0: is not content error
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::ContentError - Bounce reason is C<contenterror> or not.
=head1 SYNOPSIS
use Sisimai::Reason::ContentError;
print Sisimai::Reason::ContentError->match('550 Message Filterd'); # 1
=head1 DESCRIPTION
Sisimai::Reason::ContentError checks the bounce reason is C<contenterror> or not.
This class is called only Sisimai::Reason class.
This is the error that a destination mail server has rejected email due to
header format of the email like the following. Sisimai will set C<contenterror>
to the reason of email bounce if the value of Status: field in a bounce email
is "5.6.*".
=over
=item - 8 bit data in message header
=item - Too many “Received” headers
=item - Invalid MIME headers
=back
... while talking to g5.example.net.:
>>> DATA
<<< 550 5.6.9 improper use of 8-bit data in message header
554 5.0.0 Service unavailable
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<contenterror>.
print Sisimai::Reason::ContentError->text; # contenterror
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::ContentError->match('550 Message Filterd'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<contenterror>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,67 @@
package Sisimai::Reason::Delivered;
use feature ':5.10';
use strict;
use warnings;
sub text { 'delivered' }
sub description { 'Email delivered successfully' }
sub match { return undef }
sub true { return undef }
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Delivered - Email delivered successfully
=head1 SYNOPSIS
use Sisimai::Reason::Delivered;
print Sisimai::Reason::Delivered->text; # delivered
=head1 DESCRIPTION
Sisimai::Reason::Delivered checks the email you sent is delivered successfully
or not by matching diagnostic messages with message patterns. Sisimai will set
"delivered" to the value of "reason" when Status: field in the bounce message
begins with "2" like following:
Final-Recipient: rfc822; kijitora@neko.nyaan.jp
Action: deliverable
Status: 2.1.5
Diagnostic-Code: SMTP; 250 2.1.5 OK
This class is called only Sisimai->reason method. This is NOT AN ERROR reason.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<delivered>.
print Sisimai::Reason::Delivered->text; # delivered
=head2 C<B<match(I<string>)>>
C<match()> always return undef
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> always return undef
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2016 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,112 @@
package Sisimai::Reason::ExceedLimit;
use feature ':5.10';
use strict;
use warnings;
sub text { 'exceedlimit' }
sub description { 'Email rejected due to an email exceeded the limit' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = ['message too large'];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Exceed limit or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: Exceeds the limit
# 0: Did not exceed the limit
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return undef unless $argvs->deliverystatus;
return 1 if $argvs->reason eq 'exceedlimit';
# Delivery status code points "exceedlimit".
# Status: 5.2.3
# Diagnostic-Code: SMTP; 552 5.2.3 Message size exceeds fixed maximum message size
return 1 if Sisimai::SMTP::Status->name($argvs->deliverystatus) eq 'exceedlimit';
# Check the value of Diagnosic-Code: header with patterns
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::ExceedLimit - Bounce reason is C<exceedlimit> or not.
=head1 SYNOPSIS
use Sisimai::Reason::ExceedLimit;
print Sisimai::Reason::ExceedLimit->match; # 0
=head1 DESCRIPTION
Sisimai::Reason::ExceedLimit checks the bounce reason is C<exceedlimit> or not.
This class is called only Sisimai::Reason class.
This is the error that a message was rejected due to an email exceeded the
limit. The value of D.S.N. is 5.2.3. This reason is almost the same as
C<MesgTooBig>, we think.
... while talking to mx.example.org.:
>>> MAIL From:<kijitora@example.co.jp> SIZE=16600348
<<< 552 5.2.3 Message size exceeds fixed maximum message size (10485760)
554 5.0.0 Service unavailable
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<exceedlimit>.
print Sisimai::Reason::ExceedLimit->text; # exceedlimit
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::ExceedLimit->match; # 0;
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<exceedlimit>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 SEE ALSO
=over
=item L<Sisimai::Reason::MesgTooBig> - Sisimai::Reason::MesgTooBig
=back
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,102 @@
package Sisimai::Reason::Expired;
use feature ':5.10';
use strict;
use warnings;
sub text { 'expired' }
sub description { 'Delivery time has expired due to a connection failure' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'connection timed out',
'could not find a gateway for',
'delivery time expired',
'failed to deliver to domain ',
'giving up on',
'has been delayed',
'it has not been collected after',
'message expired after sitting in queue for',
'message expired, connection refulsed',
'message timed out',
'retry time not reached for any host after a long failure period',
'server did not respond',
'this message has been in the queue too long',
'unable to deliver message after multiple retries',
'was not reachable within the allowed queue period',
'your message could not be delivered for more than',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Delivery expired due to connection failure or network error
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is expired
# 0: is not expired
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Expired - Bounce reason is C<expired> or not.
=head1 SYNOPSIS
use Sisimai::Reason::Expired;
print Sisimai::Reason::Expired->match('400 Delivery time expired'); # 1
=head1 DESCRIPTION
Sisimai::Reason::Expired checks the bounce reason is C<expired> or not. This
class is called only Sisimai::Reason class.
This is the error that delivery time has expired due to connection failure or
network error and the message you sent has been in the queue for long time.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<expired>.
print Sisimai::Reason::Expired->text; # expired
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::Expired->match('400 Delivery time expired'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<expired>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,59 @@
package Sisimai::Reason::Feedback;
use feature ':5.10';
use strict;
use warnings;
sub text { 'feedback' }
sub description { 'Email forwarded to the sender as a complaint message from your mailbox provider' }
sub match { return undef }
sub true { return undef }
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Feedback - Email forwarded as a complaint message
=head1 SYNOPSIS
use Sisimai::Reason::Feedback;
print Sisimai::Reason::Feedback->text; # feedback
=head1 DESCRIPTION
Sisimai::Reason::Feedback is for only returning text and description.
This class is called only from Sisimai->reason method and Sisimai::ARF class.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<feedback>.
print Sisimai::Reason::Feedback->text; # feedback
=head2 C<B<match(I<string>)>>
C<match()> always return undef
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> always return undef
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2016 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,129 @@
package Sisimai::Reason::Filtered;
use feature ':5.10';
use strict;
use warnings;
sub text { 'filtered' }
sub description { 'Email rejected due to a header content after SMTP DATA command' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'because the recipient is only accepting mail from specific email addresses', # AOL Phoenix
'bounced address', # SendGrid|a message to an address has previously been Bounced.
'due to extended inactivity new mail is not currently being accepted for this mailbox',
'has restricted sms e-mail', # AT&T
'is not accepting any mail',
'refused due to recipient preferences', # Facebook
'resolver.rst.notauthorized', # Microsoft Exchange
'this account is protected by',
'user not found', # Filter on MAIL.RU
'user reject',
'we failed to deliver mail because the following address recipient id refuse to receive mail', # Willcom
'you have been blocked by the recipient',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Rejected by domain or address filter ?
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is filtered
# 0: is not filtered
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'filtered';
require Sisimai::Reason::UserUnknown;
my $commandtxt = $argvs->smtpcommand // '';
my $diagnostic = lc $argvs->diagnosticcode // '';
my $tempreason = Sisimai::SMTP::Status->name($argvs->deliverystatus);
my $alterclass = 'Sisimai::Reason::UserUnknown';
return 0 if $tempreason eq 'suspend';
if( $tempreason eq 'filtered' ) {
# Delivery status code points "filtered".
return 1 if( $alterclass->match($diagnostic) || __PACKAGE__->match($diagnostic) );
} elsif( $commandtxt ne 'RCPT' && $commandtxt ne 'MAIL' ) {
# Check the value of Diagnostic-Code and the last SMTP command
return 1 if __PACKAGE__->match($diagnostic);
return 1 if $alterclass->match($diagnostic);
}
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Filtered - Bounce reason is C<filtered> or not.
=head1 SYNOPSIS
use Sisimai::Reason::Filtered;
print Sisimai::Reason::Filtered->match('550 5.1.2 User reject'); # 1
=head1 DESCRIPTION
Sisimai::Reason::Filtered checks the bounce reason is C<filtered> or not. This
class is called only Sisimai::Reason class.
This is the error that an email has been rejected by a header content after
SMTP DATA command.
In Japanese cellular phones, the error will incur that a sender's email address
or a domain is rejected by recipient's email configuration. Sisimai will set
C<filtered> to the reason of email bounce if the value of Status: field in a
bounce email is C<5.2.0> or C<5.2.1>.
This error reason is almost the same as UserUnknown.
... while talking to mfsmax.ntt.example.ne.jp.:
>>> DATA
<<< 550 Unknown user kijitora@ntt.example.ne.jp
554 5.0.0 Service unavailable
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<filtered>.
print Sisimai::Reason::Filtered->text; # filtered
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::Filtered->match('550 5.1.2 User reject'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<filtered>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,94 @@
package Sisimai::Reason::HasMoved;
use feature ':5.10';
use strict;
use warnings;
sub text { 'hasmoved' }
sub description { "Email rejected due to user's mailbox has moved and is not forwarded automatically" }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.1.25
my $class = shift;
my $argv1 = shift // return undef;
my $index = [' has been replaced by '];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Whether the address has moved or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: The address has moved
# 0: Has not moved
# @since v4.1.25
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'hasmoved';
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::HasMoved - Bounce reason is C<hasmoved> or not.
=head1 SYNOPSIS
use Sisimai::Reason::HasMoved;
print Sisimai::Reason::HasMoved->match('address neko@example.jp has been replaced by ...'); # 1
=head1 DESCRIPTION
Sisimai::Reason::HasMoved checks the bounce reason is C<hasmoved> or not. This
class is called only Sisimai::Reason class.
This is the error that a user's mailbox has moved (and is not forwarded
automatically). Sisimai will set C<hasmoved> to the reason of email bounce if
the value of Status: field in a bounce email is C<5.1.6>.
<kijitora@example.go.jp>: host mx1.example.go.jp[192.0.2.127] said: 550 5.1.6 recipient
no longer on server: kijitora@example.go.jp (in reply to RCPT TO command)
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<hasmoved>.
print Sisimai::Reason::HasMoved->text; # hasmoved
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::HasMoved->match('address cat@example.jp has been replaced by '); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<hasmoved>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2015-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,124 @@
package Sisimai::Reason::HostUnknown;
use feature ':5.10';
use strict;
use warnings;
sub text { 'hostunknown' }
sub description { "Delivery failed due to a domain part of a recipient's email address does not exist" }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'domain does not exist',
'domain is not reachable',
'domain must exist',
'host or domain name not found',
'host unknown',
'host unreachable',
'mail domain mentioned in email address is unknown',
'name or service not known',
'no such domain',
'recipient address rejected: unknown domain name',
'recipient domain must exist',
'the account or domain may not exist',
'unknown host',
'unrouteable address',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Whether the host is unknown or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is unknown host
# [Integer] 0: is not unknown host.
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'hostunknown';
my $statuscode = $argvs->deliverystatus // '';
my $diagnostic = lc $argvs->diagnosticcode // '';
if( Sisimai::SMTP::Status->name($statuscode) eq 'hostunknown' ) {
# Status: 5.1.2
# Diagnostic-Code: SMTP; 550 Host unknown
require Sisimai::Reason::NetworkError;
return 1 unless Sisimai::Reason::NetworkError->match($diagnostic);
} else {
# Check the value of Diagnosic-Code: header with patterns
return 1 if __PACKAGE__->match($diagnostic);
}
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::HostUnknown - Bounce reason is C<hostunknown> or not.
=head1 SYNOPSIS
use Sisimai::Reason::HostUnknown;
print Sisimai::Reason::HostUnknown->match('550 5.2.1 Host Unknown'); # 1
=head1 DESCRIPTION
Sisimai::Reason::HostUnknown checks the bounce reason is C<hostunknown> or not.
This class is called only Sisimai::Reason class.
This is the error that a domain part (Right hand side of @ sign) of a
recipient's email address does not exist. In many case, the domain part is
misspelled, or the domain name has been expired. Sisimai will set C<hostunknown>
to the reason of email bounce if the value of Status: field in a bounce mail is
C<5.1.2>.
Your message to the following recipients cannot be delivered:
<kijitora@example.cat>:
<<< No such domain.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<hostunknown>.
print Sisimai::Reason::HostUnknown->text; # hostunknown
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::HostUnknown->match('550 5.2.1 Host Unknown'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<hostunknown>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,149 @@
package Sisimai::Reason::MailboxFull;
use feature ':5.10';
use strict;
use warnings;
sub text { 'mailboxfull' }
sub description { "Email rejected due to a recipient's mailbox is full" }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'account disabled temporarly for exceeding receiving limits',
'account is exceeding their quota',
'account is over quota',
'account is temporarily over quota',
'boite du destinataire pleine',
'delivery failed: over quota',
'disc quota exceeded',
'does not have enough space',
'exceeded storage allocation',
'exceeding its mailbox quota',
'full mailbox',
'is over disk quota',
'is over quota temporarily',
'mail file size exceeds the maximum size allowed for mail delivery',
'mail quota exceeded',
'mailbox exceeded the local limit',
'mailbox full',
'mailbox has exceeded its disk space limit',
'mailbox is full',
'mailbox over quota',
'mailbox quota usage exceeded',
'mailbox size limit exceeded',
'maildir over quota',
'maildir delivery failed: userdisk quota ',
'maildir delivery failed: domaindisk quota ',
'mailfolder is full',
'not enough storage space in',
'over the allowed quota',
'quota exceeded',
'quota violation for',
'recipient reached disk quota',
'recipient rejected: mailbox would exceed maximum allowed storage',
'the recipient mailbox has exceeded its disk space limit',
"the user's space has been used up",
'the user you are trying to reach is over quota',
'too much mail data', # @docomo.ne.jp
'user has exceeded quota, bouncing mail',
'user has too many messages on the server',
'user is over quota',
'user is over the quota',
'user over quota',
'user over quota. (#5.1.1)', # qmail-toaster
'was automatically rejected: quota exceeded',
'would be over the allowed quota',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The envelope recipient's mailbox is full or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is mailbox full
# 0: is not mailbox full
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return undef unless $argvs->deliverystatus;
return 1 if $argvs->reason eq 'mailboxfull';
# Delivery status code points "mailboxfull".
# Status: 4.2.2
# Diagnostic-Code: SMTP; 450 4.2.2 <***@example.jp>... Mailbox Full
return 1 if Sisimai::SMTP::Status->name($argvs->deliverystatus) eq 'mailboxfull';
# Check the value of Diagnosic-Code: header with patterns
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::MailboxFull - Bounce reason is C<mailboxfull> or not.
=head1 SYNOPSIS
use Sisimai::Reason::MailboxFull;
print Sisimai::Reason::MailboxFull->match('400 4.2.3 Mailbox full'); # 1
=head1 DESCRIPTION
Sisimai::Reason::MailboxFull checks the bounce reason is C<mailboxfull> or not.
This class is called only Sisimai::Reason class.
This is the error that a recipient's mailbox is full. Sisimai will set
C<mailboxfull> to the reason of email bounce if the value of Status: field in a
bounce email is C<4.2.2> or C<5.2.2>.
Action: failed
Status: 5.2.2
Diagnostic-Code: smtp;550 5.2.2 <kijitora@example.jp>... Mailbox Full
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<mailboxfull>.
print Sisimai::Reason::MailboxFull->text; # mailboxfull
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::MailboxFull->match('400 4.2.3 Mailbox full'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<mailboxfull>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,100 @@
package Sisimai::Reason::MailerError;
use feature ':5.10';
use strict;
use warnings;
sub text { 'mailererror' }
sub description { 'Email returned due to a mailer program has not exited successfully' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $regex = qr{(?>
\Aprocmail:[ ] # procmail
|bin/(?:procmail|maildrop)
|command[ ](?:
failed:[ ]
|died[ ]with[ ]status[ ]\d+
|output:
)
|exit[ ]\d+
|mailer[ ]error
|pipe[ ]to[ ][|][/].+
|x[-]unix[;][ ]\d+ # X-UNIX; 127
)
}x;
return 1 if $argv1 =~ $regex;
return 0;
}
sub true {
# The bounce reason is mailer error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is mailer error
# 0: is not mailer error
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::MailerError - Bounce reason is C<mailererror> or not.
=head1 SYNOPSIS
use Sisimai::Reason::MailerError;
print Sisimai::Reason::MailerError->match('X-Unix; 255'); # 1
=head1 DESCRIPTION
Sisimai::Reason::MailerError checks the bounce reason is C<mailererror> or not.
This class is called only Sisimai::Reason class.
This is the error that a mailer program has not exited successfully or exited
unexpectedly on a destination mail server.
X-Actual-Recipient: X-Unix; |/home/kijitora/mail/catch.php
Diagnostic-Code: X-Unix; 255
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<mailererror>.
print Sisimai::Reason::MailerError->text; # mailererror
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::MailerError->match('X-Unix; 255'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<mailererror>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2017 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,127 @@
package Sisimai::Reason::MesgTooBig;
use feature ':5.10';
use strict;
use warnings;
sub text { 'mesgtoobig' }
sub description { 'Email rejected due to an email size is too big for a destination mail server' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'exceeded maximum inbound message size',
'line limit exceeded',
'max message size exceeded',
'message file too big',
'message length exceeds administrative limit',
'message size exceeds fixed limit',
'message size exceeds fixed maximum message size',
'message size exceeds maximum value',
'message too big',
'message too large for this ',
'size limit',
'taille limite du message atteinte',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The message size is too big for the remote host
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is too big message size
# 0: is not big
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'mesgtoobig';
my $statuscode = $argvs->deliverystatus // '';
my $tempreason = Sisimai::SMTP::Status->name($statuscode);
# Delivery status code points "mesgtoobig".
# Status: 5.3.4
# Diagnostic-Code: SMTP; 552 5.3.4 Error: message file too big
return 1 if $tempreason eq 'mesgtoobig';
# 5.2.3 Message length exceeds administrative limit
return 0 if( $tempreason eq 'exceedlimit' || $statuscode eq '5.2.3' );
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::MesgTooBig - Bounce reason is C<mesgtoobig> or not.
=head1 SYNOPSIS
use Sisimai::Reason::MesgTooBig;
print Sisimai::Reason::MesgTooBig->match('400 Message too big'); # 1
=head1 DESCRIPTION
Sisimai::Reason::MesgTooBig checks the bounce reason is C<mesgtoobig> or not.
This class is called only Sisimai::Reason class.
This is the error that a sent email size is too big for a destination mail
server. In many case, There are many attachment files with email, or the file
size is too large. Sisimai will set C<mesgtoobig> to the reason of email bounce
if the value of Status: field in a bounce email is C<5.3.4>.
Action: failure
Status: 553 Exceeded maximum inbound message size
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<mesgtoobig>.
print Sisimai::Reason::MesgTooBig->text; # mesgtoobig
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::MesgTooBig->match('400 Message too big'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<mesgtoobig>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 SEE ALSO
=over
=item L<Sisimai::Reason::ExceedLimit> - Sisimai::Reason::ExceedLimit
=back
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,107 @@
package Sisimai::Reason::NetworkError;
use feature ':5.10';
use strict;
use warnings;
sub text { 'networkerror' }
sub description { 'SMTP connection failed due to DNS look up failure or other network problems' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.1.12
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'could not connect and send the mail to',
'dns records for the destination computer could not be found',
'hop count exceeded - possible mail loop',
'host is unreachable',
'host not found, try again',
'mail forwarding loop for ',
'malformed name server reply',
'malformed or unexpected name server reply',
'maximum forwarding loop count exceeded',
'message looping',
'message probably in a routing loop',
'no route to host',
'too many hops',
'unable to resolve route ',
'unrouteable mail domain',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The bounce reason is network error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is network error
# 0: is not network error
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::NetworkError - Bounce reason is C<networkerror> or not.
=head1 SYNOPSIS
use Sisimai::Reason::NetworkError;
print Sisimai::Reason::NetworkError->match('554 5.4.6 Too many hops'); # 1
=head1 DESCRIPTION
Sisimai::Reason::NetworkError checks the bounce reason is C<networkerror> or not.
This class is called only Sisimai::Reason class.
This is the error that SMTP connection failed due to DNS look up failure or
other network problems. This reason has added in Sisimai 4.1.12 and does not
exist in any version of bounceHammer.
A message is delayed for more than 10 minutes for the following
list of recipients:
kijitora@neko.example.jp: Network error on destination MXs
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<networkerror>.
print Sisimai::Reason::NetworkError->text; # networkerror
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::NetworkError->match('5.3.5 System config error'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<networkerror>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,114 @@
package Sisimai::Reason::NoRelaying;
use feature ':5.10';
use strict;
use warnings;
sub text { 'norelaying' }
sub description { 'Email rejected with error message "Relaying Denied"' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'as a relay',
'insecure mail relay',
'mail server requires authentication when attempting to send to a non-local e-mail address', # MailEnable
'not allowed to relay through this machine',
'not an open relay, so get lost',
'relay access denied',
'relay denied',
'relay not permitted',
'relaying denied', # Sendmail
"that domain isn't in my list of allowed rcpthost",
'this system is not configured to relay mail',
'unable to relay for',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Whether the message is rejected by 'Relaying denied'
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: Rejected for "relaying denied"
# 0: is not
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
my $r = $argvs->reason // '';
if( $r ) {
# Do not overwrite the reason
return 0 if( $r eq 'securityerror' || $r eq 'systemerror' || $r eq 'undefined' );
} else {
# Check the value of Diagnosic-Code: header with patterns
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
}
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::NoRelaying - Bounce reason is C<norelaying> or not.
=head1 SYNOPSIS
use Sisimai::Reason::NoRelaying;
print Sisimai::Reason::NoRelaying->match('Relaying denied'); # 1
=head1 DESCRIPTION
Sisimai::Reason::NoRelaying checks the bounce reason is C<norelaying> or not.
This class is called only Sisimai::Reason class.
This is the error that SMTP connection rejected with error message
C<Relaying Denied>. This reason does not exist in any version of bounceHammer.
... while talking to mailin-01.mx.example.com.:
>>> RCPT To:<kijitora@example.org>
<<< 554 5.7.1 <kijitora@example.org>: Relay access denied
554 5.0.0 Service unavailable
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<norelaying>.
print Sisimai::Reason::NoRelaying->text; # norelaying
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::NoRelaying->match('Relaying denied'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<norelaying>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,102 @@
package Sisimai::Reason::NotAccept;
use feature ':5.10';
use strict;
use warnings;
sub text { 'notaccept' }
sub description { 'Delivery failed due to a destination mail server does not accept any email' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
# Destination mail server does not accept any message
my $index = [
'host/domain does not accept mail', # iCloud
'name server: .: host not found', # Sendmail
'no mx record found for domain=', # Oath(Yahoo!)
'smtp protocol returned a permanent error',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Remote host does not accept any message
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: Not accept
# 0: Accept
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'notaccept';
# SMTP Reply Code is 521, 554 or 556
return 1 if $argvs->replycode =~ /\A(?:521|554|556)\z/;
return 0 unless $argvs->smtpcommand eq 'MAIL';
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::NotAccept - Bounce reason is C<notaccept> or not.
=head1 SYNOPSIS
use Sisimai::Reason::NotAccept;
print Sisimai::Reason::NotAccept->match('domain does not exist:'); # 1
=head1 DESCRIPTION
Sisimai::Reason::NotAccept checks the bounce reason is C<notaccept> or not.
This class is called only Sisimai::Reason class.
This is the error that a destination mail server does ( or can ) not accept any
email. In many case, the server is high load or under the maintenance. Sisimai
will set C<notaccept> to the reason of email bounce if the value of Status:
field in a bounce email is C<5.3.2> or the value of SMTP reply code is 556.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<notaccept>.
print Sisimai::Reason::NotAccept->text; # notaccept
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::NotAccept->match('domain does not exist:'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<notaccept>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,86 @@
package Sisimai::Reason::OnHold;
use feature ':5.10';
use strict;
use warnings;
sub text { 'onhold' }
sub description { 'Sisimai could not decided the reason due to there is no (or less) detailed information for judging the reason' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
return 0;
}
sub true {
# On hold, Could not decide the bounce reason...
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: Status code is "onhold"
# 0: is not "onhold"
# @since v4.1.28
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return undef unless $argvs->deliverystatus;
return 1 if $argvs->reason eq 'onhold';
return 1 if Sisimai::SMTP::Status->name($argvs->deliverystatus) eq 'onhold';
return 0
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::OnHold - Bounce reason is C<onhold> or not.
=head1 SYNOPSIS
use Sisimai::Reason::OnHold;
print Sisimai::Reason::OnHold->match; # 0
=head1 DESCRIPTION
Sisimai::Reason::OnHold checks the bounce reason is C<onhold> or not. This class
is called only Sisimai::Reason class.
Sisimai will set C<onhold> to the reason of email bounce if there is no (or
less) detailed information about email bounce for judging the reason.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<onhold>.
print Sisimai::Reason::OnHold->text; # onhold
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::OnHold->match; # 0;
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<onhold>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,109 @@
package Sisimai::Reason::PolicyViolation;
use feature ':5.10';
use strict;
use warnings;
sub text { 'policyviolation' }
sub description { 'Email rejected due to policy violation on a destination host' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.22.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'because the recipient is not accepting mail with ', # AOL Phoenix
'closed mailing list',
'denied by policy',
'email not accepted for policy reasons',
# http://kb.mimecast.com/Mimecast_Knowledge_Base/Administration_Console/Monitoring/Mimecast_SMTP_Error_Codes#554
'email rejected due to security policies',
'header are not accepted',
'header error',
'message given low priority',
'message not accepted for policy reasons',
'messages with multiple addresses',
'rejected for policy reasons',
'protocol violation',
'the email address used to send your message is not subscribed to this group',
'you have exceeded the allowable number of posts without solving a captcha',
'you have exceeded the the allowable number of posts without solving a captcha',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The bounce reason is security error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is policy violation
# 0: is not policyviolation
# @since v4.22.0
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::PolicyViolation - Bounce reason is C<policyviolation> or not.
=head1 SYNOPSIS
use Sisimai::Reason::PolicyViolation;
print Sisimai::Reason::PolicyViolation->match('5.7.9 Header error'); # 1
=head1 DESCRIPTION
Sisimai::Reason::PolicyViolation checks the bounce reason is C<policyviolation>
or not. This class is called only Sisimai::Reason class.
This is the error that a policy violation was detected on a destination mail host.
When a header content or a format of the original message violates security policies,
or multiple addresses exist in the From: header, Sisimai will set C<policyviolation>.
Action: failed
Status: 5.7.9
Remote-MTA: DNS; mx.example.co.jp
Diagnostic-Code: SMTP; 554 5.7.9 Header error
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<policyviolation>.
print Sisimai::Reason::PolicyViolation->text; # policyviolation
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::PolicyViolation->match('5.7.9 Header error'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<policyviolation>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2017-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,161 @@
package Sisimai::Reason::Rejected;
use feature ':5.10';
use strict;
use warnings;
sub text { 'rejected' }
sub description { "Email rejected due to a sender's email address (envelope from)" }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $isnot = [
'5.1.0 address rejected',
'recipient address rejected',
'sender ip address rejected',
];
my $index = [
'<> invalid sender',
'address rejected',
'administrative prohibition',
'batv failed to verify', # SoniWall
'batv validation failure', # SoniWall
'backscatter protection detected an invalid or expired email address', # MDaemon
'bogus mail from', # IMail - block empty sender
'connections not accepted from servers without a valid sender domain',
'denied [bouncedeny]', # McAfee
'delivery not authorized, message refused',
'does not exist e2110',
'domain of sender address ',
'emetteur invalide',
'empty envelope senders not allowed',
'error: no third-party dsns', # SpamWall - block empty sender
'from: domain is invalid. please provide a valid from:',
'fully qualified email address required', # McAfee
'invalid domain, see <url:',
'mail from not owned by user',
'message rejected: email address is not verified',
'mx records for ',
'null sender is not allowed',
'recipient not accepted. (batv: no tag',
'returned mail not accepted here',
'rfc 1035 violation: recursive cname records for',
'rule imposed mailbox access for', # MailMarshal
'sender email address rejected',
'sender is spammer',
'sender not pre-approved',
'sender rejected',
'sender domain is empty',
'sender verify failed', # Exim callout
'syntax error: empty email address',
'the message has been rejected by batv defense',
'transaction failed unsigned dsn for',
'unroutable sender address',
'you are sending to/from an address that has been blacklisted',
];
return 0 if grep { rindex($argv1, $_) > -1 } @$isnot;
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Rejected by the envelope sender address or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is rejected
# 0: is not rejected by the sender
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
my $tempreason = Sisimai::SMTP::Status->name($argvs->deliverystatus) || 'undefined';
my $diagnostic = lc $argvs->diagnosticcode;
return 1 if $argvs->reason eq 'rejected';
return 1 if $tempreason eq 'rejected'; # Delivery status code points "rejected".
# Check the value of Diagnosic-Code: header with patterns
if( $argvs->smtpcommand eq 'MAIL' ) {
# The session was rejected at 'MAIL FROM' command
return 1 if __PACKAGE__->match($diagnostic);
} elsif( $argvs->smtpcommand eq 'DATA' ) {
# The session was rejected at 'DATA' command
if( $tempreason ne 'userunknown' ) {
# Except "userunknown"
return 1 if __PACKAGE__->match($diagnostic);
}
} elsif( $tempreason =~ /\A(?:onhold|undefined|securityerror|systemerror)\z/ ) {
# Try to match with message patterns when the temporary reason
# is "onhold", "undefined", "securityerror", or "systemerror"
return 1 if __PACKAGE__->match($diagnostic);
}
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Rejected - Bounce reason is C<rejected> or not.
=head1 SYNOPSIS
use Sisimai::Reason::Rejected;
print Sisimai::Reason::Rejected->match('550 Address rejected'); # 1
=head1 DESCRIPTION
Sisimai::Reason::Rejected checks the bounce reason is C<rejected> or not. This
class is called only Sisimai::Reason class.
This is the error that a connection to destination server was rejected by a
sender's email address (envelope from). Sisimai set C<rejected> to the reason
of email bounce if the value of Status: field in a bounce email is C<5.1.8> or
the connection has been rejected due to the argument of SMTP MAIL command.
<kijitora@example.org>:
Connected to 192.0.2.225 but sender was rejected.
Remote host said: 550 5.7.1 <root@nijo.example.jp>... Access denied
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<rejected>.
print Sisimai::Reason::Rejected->text; # rejected
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::Rejected->match('550 Address rejected'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<rejected>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,116 @@
package Sisimai::Reason::SecurityError;
use feature ':5.10';
use strict;
use warnings;
sub text { 'securityerror' }
sub description { 'Email rejected due to security violation was detected on a destination host' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $regex = qr{(?>
account[ ]not[ ]subscribed[ ]to[ ]ses
|authentication[ ](?:
credentials invalid
|failure
|failed;[ ]server[ ].+[ ]said: # Postfix
|required
|turned[ ]on[ ]in[ ]your[ ]email[ ]client
)
|authentification[ ]requise.+[a-z]{3}.+402
|\d+[ ]denied[ ]\[[a-z]+\][ ].+[(]mode:[ ].+[)]
|codes?[ ]d'?[ ]*authentification[ ]invalide.+[a-z]{3}.+305
|domain[ ].+[ ]is[ ]a[ ]dead[ ]domain
|executable[ ]files[ ]are[ ]not[ ]allowed[ ]in[ ]compressed[ ]files
|insecure[ ]mail[ ]relay
|recipient[ ]address[ ]rejected:[ ]access[ ]denied
|sorry,[ ]you[ ]don'?t[ ]authenticate[ ]or[ ]the[ ]domain[ ]isn'?t[ ]in[ ]
my[ ]list[ ]of[ ]allowed[ ]rcpthosts
|tls[ ]required[ ]but[ ]not[ ]supported # SendGrid:the recipient mailserver does not support TLS or have a valid certificate
|unauthenticated[ ]senders[ ]not[ ]allowed
|user[ ].+[ ]is[ ]not[ ]authorized[ ]to[ ]perform[ ]ses:sendrawemail[ ]on[ ]resource
|you[ ]are[ ]not[ ]authorized[ ]to[ ]send[ ]mail,[ ]authentication[ ]is[ ]required
|verification[ ]failure
)
}x;
return 1 if $argv1 =~ $regex;
return 0;
}
sub true {
# The bounce reason is security error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is security error
# 0: is not security error
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::SecurityError - Bounce reason is C<securityerror> or not.
=head1 SYNOPSIS
use Sisimai::Reason::SecurityError;
print Sisimai::Reason::SecurityError->match('570 5.7.0 Authentication failure'); # 1
=head1 DESCRIPTION
Sisimai::Reason::SecurityError checks the bounce reason is C<securityerror> or
not. This class is called only Sisimai::Reason class.
This is the error that a security violation was detected on a destination mail
server. Depends on the security policy on the server, a sender's email address
is camouflaged address. Sisimai will set C<securityerror> to the reason of email
bounce if the value of Status: field in a bounce email is C<5.7.*>.
Action: failed
Status: 5.7.0
Remote-MTA: DNS; gmail-smtp-in.l.google.com
Diagnostic-Code: SMTP; 552-5.7.0 Our system detected an illegal attachment on your message. Please
Last-Attempt-Date: Tue, 28 Apr 2009 11:02:45 +0900 (JST)
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<securityerror>.
print Sisimai::Reason::SecurityError->text; # securityerror
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::SecurityError->match('570 5.7.0 Authentication failure'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<securityerror>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,225 @@
package Sisimai::Reason::SpamDetected;
use feature ':5.10';
use strict;
use warnings;
sub text { 'spamdetected' }
sub description { 'Email rejected by spam filter running on the remote host' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.1.19
my $class = shift;
my $argv1 = shift // return undef;
my $regex = qr{(?>
["]the[ ]mail[ ]server[ ]detected[ ]your[ ]message[ ]as[ ]spam[ ]and[ ]
has[ ]prevented[ ]delivery[.]["] # CPanel/Exim with SA rejections on
|(?:\d[.]\d[.]\d|\d{3})[ ]spam\z
|appears[ ]to[ ]be[ ]unsolicited
|blacklisted[ ]url[ ]in[ ]message
|block[ ]for[ ]spam
|blocked[ ]by[ ](?:
policy:[ ]no[ ]spam[ ]please
|spamassassin # rejected by SpamAssassin
)
|blocked[ ]for[ ]abuse[.][ ]see[ ]http://att[.]net/blocks # AT&T
|bulk[ ]email
|content[ ]filter[ ]rejection
|cyberoam[ ]anti[ ]spam[ ]engine[ ]has[ ]identified[ ]this[ ]email[ ]as[ ]a[ ]bulk[ ]email
|denied[ ]due[ ]to[ ]spam[ ]list
|dt:spm[ ]mx.+[ ]http://mail[.]163[.]com/help/help_spam_16[.]htm
|greylisted.?.[ ]please[ ]try[ ]again[ ]in
|http://(?:www[.]spamhaus[.]org|dsbl[.]org)
|listed[ ]in[ ]work[.]drbl[.]imedia[.]ru
|mail[ ](?:
appears[ ]to[ ]be[ ]unsolicited # rejected due to spam
|content[ ]denied # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000726
|rejete.+[a-z]{3}.+506
)
|may[ ]consider[ ]spam
|message[ ](?:
considered[ ]as[ ]spam[ ]or[ ]virus
|content[ ]rejected
|filtered
|filtered[.][ ](?:
please[ ]see[ ]the[ ]faqs[ ]section[ ]on[ ]spam
|refer[ ]to[ ]the[ ]troubleshooting[ ]page[ ]at[ ]
)
|looks[ ]like[ ]spam
|not[ ]accepted[ ]for[ ]policy[ ]reasons[.][ ]see[ ]http: # Yahoo!
|refused[ ]by[ ]mailmarshal[ ]spamprofiler
|rejected[ ](?:
as[ ]spam
|because[ ]of[ ]unacceptable[ ]content
|due[ ]to[ ]suspected[ ]spam[ ]content
|for[ ]policy[ ]reasons
)
)
|our[ ](?:
email[ ]server[ ]thinks[ ]this[ ]email[ ]is[ ]spam
|filters[ ]rate[ ]at[ ]and[ ]above[ ].+[ ]percent[ ]probability[ ]of[ ]being[ ]spam
|system[ ]has[ ]detected[ ]that[ ]this[ ]message[ ]is
)
|permanent[ ]failure[ ]for[ ]one[ ]or[ ]more[ ]recipients[ ][(].+:blocked[)]
|probable[ ]spam
|reject[ ]bulk[.]advertising
|reject,.+[ ][-][ ]spam[.][ ]
|rejected(?:
:[ ]spamassassin[ ]score[ ]
|[ ]by[ ].+[ ][(]spam[)]
|[ ]due[ ]to[ ]spam[ ](?:classification|content)
)
|rejecting[ ]banned[ ]content
|related[ ]to[ ]content[ ]with[ ]spam[-]like[ ]characteristics
|rule[ ]imposed[ ]as[ ].+is[ ]blacklisted[ ]on # Mailmarshal RBLs
|sender[ ]domain[ ]listed[ ]at[ ].+
|sending[ ]address[ ]not[ ]accepted[ ]due[ ]to[ ]spam[ ]filter
|spam[ ](?:
.+[ ]exceeded
|blocked
|check
|content[ ]matched
|detected
|email
|email[ ]not[ ]accepted
|message[ ]rejected[.] # mail.ru
|not[ ]accepted
|refused
|rejection
|reporting[ ]address # SendGrid|a message to an address has previously been marked as Spam by the recipient.
|score[ ]
)
|spambouncer[ ]identified[ ]spam # SpamBouncer identified SPAM
|spamming[ ]not[ ]allowed
|too[ ]much[ ]spam[.] # Earthlink
|the[ ]message[ ](?:
has[ ]been[ ]rejected[ ]by[ ]spam[ ]filtering[ ]engine
|was[ ]rejected[ ]due[ ]to[ ]classification[ ]as[ ]bulk[ ]mail
)
|the[ ]content[ ]of[ ]this[ ]message[ ]looked[ ]like[ ]spam # SendGrid
|this[ ](?:e-mail|mail)[ ](?:
cannot[ ]be[ ]forwarded[ ]because[ ]it[ ]was[ ]detected[ ]as[ ]spam
|is[ ]classified[ ]as[ ]spam[ ]and[ ]is[ ]rejected
)
|this[ ]message[ ](?:
appears[ ]to[ ]be[ ]spam
|has[ ]been[ ](?:
identified[ ]as[ ]spam
|scored[ ]as[ ]spam[ ]with[ ]a[ ]probability
)
|scored[ ].+[ ]spam[ ]points
|was[ ]classified[ ]as[ ]spam
|was[ ]rejected[ ]by[ ]recurrent[ ]pattern[ ]detection[ ]system
)
|transaction[ ]failed[ ]spam[ ]message[ ]not[ ]queued # SendGrid
|we[ ]dont[ ]accept[ ]spam
|you're[ ]using[ ]a[ ]mass[ ]mailer
|your[ ](?:
email[ ](?:
appears[ ]similar[ ]to[ ]spam[ ]we[ ]have[ ]received[ ]before
|breaches[ ]local[ ]uribl[ ]policy
|had[ ]spam[-]like[ ]
|is[ ](?:considered|probably)[ ]spam
|was[ ]detected[ ]as[ ]spam
)
|message[ ](?:
as[ ]spam[ ]and[ ]has[ ]prevented[ ]delivery
|has[ ]been[ ](?:
temporarily[ ]blocked[ ]by[ ]our[ ]filter
|rejected[ ]because[ ]it[ ]appears[ ]to[ ]be[ ]spam
)
|has[ ]triggered[ ]a[ ]spam[ ]block
|may[ ]contain[ ]the[ ]spam[ ]contents
|failed[ ]several[ ]antispam[ ]checks
)
)
)
}x;
return 1 if $argv1 =~ $regex;
return 0;
}
sub true {
# Rejected due to spam content in the message
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: rejected due to spam
# 0: is not rejected due to spam
# @since v4.1.19
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return undef unless $argvs->deliverystatus;
return 1 if $argvs->reason eq 'spamdetected';
return 1 if Sisimai::SMTP::Status->name($argvs->deliverystatus) eq 'spamdetected';
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::SpamDetected - Bounce reason is C<spamdetected> due to Spam
content in the message or not.
=head1 SYNOPSIS
use Sisimai::Reason::SpamDetected;
print Sisimai::Reason::SpamDetected->match('550 spam detected'); # 1
=head1 DESCRIPTION
Sisimai::Reason::SpamDetected checks the bounce reason is C<spamdetected> due to
Spam content in the message or not. This class is called only Sisimai::Reason
class.
This is the error that the message you sent was rejected by C<spam> filter which
is running on the remote host. This reason has added in Sisimai 4.1.25 and does
not exist in any version of bounceHammer.
Action: failed
Status: 5.7.1
Diagnostic-Code: smtp; 550 5.7.1 Message content rejected, UBE, id=00000-00-000
Last-Attempt-Date: Thu, 9 Apr 2008 23:34:45 +0900 (JST)
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<spamdetected>.
print Sisimai::Reason::SpamDetected->text; # spamdetected
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::SpamDetected->match('550 Spam detected'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<rejected> due to Spam content in
the message. The argument must be Sisimai::Data object and this method is called
only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2015-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,106 @@
package Sisimai::Reason::Suspend;
use feature ':5.10';
use strict;
use warnings;
sub text { 'suspend' }
sub description { 'Email rejected due to a recipient account is being suspended' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
' is currently suspended',
' temporary locked',
'boite du destinataire archivee',
'email account that you tried to reach is disabled',
'invalid/inactive user',
'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
'mailbox currently suspended',
'mailbox unavailable or access denied',
'recipient rejected: temporarily inactive',
'recipient suspend the service',
'this account has been disabled or discontinued',
'user suspended', # http://mail.163.com/help/help_spam_16.htm
'vdelivermail: account is locked email bounced',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The envelope recipient's mailbox is suspended or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is mailbox suspended
# 0: is not suspended
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return undef unless $argvs->deliverystatus;
return 1 if $argvs->reason eq 'suspend';
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Suspend - Bounce reason is C<suspend> or not.
=head1 SYNOPSIS
use Sisimai::Reason::Suspend;
print Sisimai::Reason::Suspend->match('recipient suspend the service'); # 1
=head1 DESCRIPTION
Sisimai::Reason::Suspend checks the bounce reason is C<suspend> or not. This
class is called only Sisimai::Reason class.
This is the error that a recipient account is being suspended due to unpaid or
other reasons.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<suspend>.
print Sisimai::Reason::Suspend->text; # suspend
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::Suspend->match('recipient suspend the service'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<suspend>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,80 @@
package Sisimai::Reason::SyntaxError;
use feature ':5.10';
use strict;
use warnings;
sub text { 'syntaxerror' }
sub description { 'Email rejected due to syntax error at sent commands in SMTP session' }
sub match { return undef }
sub true {
# Connection rejected due to syntax error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: Rejected due to syntax error
# 0: is not syntax error
# @since v4.1.25
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'syntaxerror';
return 1 if $argvs->replycode =~ /\A[45]0[0-7]\z/;
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::SyntaxError - Bounce reason is C<syntaxerror> or not.
=head1 SYNOPSIS
use Sisimai::Reason::SyntaxError;
print Sisimai::Reason::SyntaxError->text; # syntaxerror
=head1 DESCRIPTION
Sisimai::Reason::SyntaxError checks the bounce reason is C<syntaxerror> or not.
This class is called only Sisimai::Reason class.
This is the error that a destination mail server could not recognize SMTP command
which is sent from a sender's MTA. Sisimai will set C<syntaxerror> to the reason
if the value of C<replycode> begins with "50" such as 502, or 503.
Action: failed
Status: 5.5.0
Diagnostic-Code: SMTP; 503 Improper sequence of commands
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<syntaxerror>.
print Sisimai::Reason::SyntaxError->text; # syntaxerror
=head2 C<B<match(I<string>)>>
C<match()> always return undef
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<syntaxerror>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2015-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,107 @@
package Sisimai::Reason::SystemError;
use feature ':5.10';
use strict;
use warnings;
sub text { 'systemerror' }
sub description { 'Email returned due to system error on the remote host' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
"can't create user output file",
'could not load drd for domain',
'internal error reading data', # Microsoft
'internal server error: operation now in progress', # Microsoft
'interrupted system call',
'it encountered an error while being processed',
'it would create a mail loop',
'local configuration error',
'local error in processing',
'loop was found in the mail exchanger',
'loops back to myself',
'mail system configuration error',
'server configuration error',
'service currently unavailable',
'system config error',
'temporary local problem',
'timeout waiting for input',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The bounce reason is system error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is system error
# 0: is not system error
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::SystemError - Bounce reason is C<systemerror> or not.
=head1 SYNOPSIS
use Sisimai::Reason::SystemError;
print Sisimai::Reason::SystemError->match('5.3.5 System config error'); # 1
=head1 DESCRIPTION
Sisimai::Reason::SystemError checks the bounce reason is C<systemerror> or not.
This class is called only Sisimai::Reason class.
This is the error that an email has bounced due to system error on the remote
host such as LDAP connection failure or other internal system error.
<kijitora@example.net>:
Unable to contact LDAP server. (#4.4.3)I'm not going to try again; this
message has been in the queue too long.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<systemerror>.
print Sisimai::Reason::SystemError->text; # systemerror
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::SystemError->match('5.3.5 System config error'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<systemerror>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,88 @@
package Sisimai::Reason::SystemFull;
use feature ':5.10';
use strict;
use warnings;
sub text { 'systemfull' }
sub description { "Email rejected due to a destination mail server's disk is full" }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'mail system full',
'requested mail action aborted: exceeded storage allocation', # MS Exchange
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The bounce reason is system full or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is system full
# 0: is not system full
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::SystemFull - Bounce reason is C<systemfull> or not.
=head1 SYNOPSIS
use Sisimai::Reason::SystemFull;
print Sisimai::Reason::SystemFull->match('Mail System Full'); # 1
=head1 DESCRIPTION
Sisimai::Reason::SystemFull checks the bounce reason is C<systemfull> or not.
This class is called only Sisimai::Reason class.
This is the error that a destination mail server's disk (or spool) is full.
Sisimai will set C<systemfull> to the reason of email bounce if the value of
Status: field in a bounce email is C<4.3.1> or C<5.3.1>.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<systemfull>.
print Sisimai::Reason::SystemFull->text; # systemfull
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::SystemFull->match('Mail System Full'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<systemfull>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,111 @@
package Sisimai::Reason::TooManyConn;
use feature ':5.10';
use strict;
use warnings;
sub text { 'toomanyconn' }
sub description { 'SMTP connection rejected temporarily due to too many concurrency connections to the remote host' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.1.26
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'all available ips are at maximum connection limit', # SendGrid
'connection rate limit exceeded',
'exceeds per-domain connection limit for',
'has exceeded the max emails per hour ',
'throttling failure: daily message quota exceeded',
'throttling failure: maximum sending rate exceeded',
'too many connections',
'too many connections from your host.', # Microsoft
'too many concurrent smtp connections', # Microsoft
'too many errors from your ip', # Free.fr
'too many smtp sessions for this host', # Sendmail(daemon.c)
'trop de connexions, ',
'we have already made numerous attempts to deliver this message',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# Blocked due to that connection rate limit exceeded
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: Too many connections(blocked)
# 0: Not many connections
# @since v4.1.26
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'toomanyconn';
return 1 if Sisimai::SMTP::Status->name($argvs->deliverystatus) eq 'toomanyconn';
return 1 if __PACKAGE__->match(lc $argvs->diagnosticcode);
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::TooManyConn - Bounced due to that too many connections.
=head1 SYNOPSIS
use Sisimai::Reason::TooManyConn;
print Sisimai::Reason::TooManyConn->match('Connection rate limit exceeded'); # 1
=head1 DESCRIPTION
Sisimai::Reason::TooManyConn checks the bounce reason is C<toomanyconn> or not.
This class is called only Sisimai::Reason class.
This is the error that SMTP connection was rejected temporarily due to too many
concurrency connections to the remote server. This reason has added in Sisimai
4.1.26 and does not exist in any version of bounceHammer.
<kijitora@example.ne.jp>: host mx02.example.ne.jp[192.0.1.20] said:
452 4.3.2 Connection rate limit exceeded. (in reply to MAIL FROM command)
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<toomanyconn>.
print Sisimai::Reason::TooManyConn->text; # toomanyconn
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::TooManyConn->match('Connection rate limit exceeded'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<toomanyconn>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,58 @@
package Sisimai::Reason::Undefined;
use feature ':5.10';
use strict;
use warnings;
sub text { 'undefined' }
sub description { 'Sisimai could not detect an error reason' }
sub match { return undef }
sub true { return undef }
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Undefined - Sisimai could not detect the error reason.
=head1 SYNOPSIS
use Sisimai::Reason::Undefined;
print Sisimai::Reason::Undefined->text; # undefined
=head1 DESCRIPTION
Sisimai::Reason::Undefined is for only returning text and description.
This class is called only from Sisimai->reason method.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<undefined>.
print Sisimai::Reason::Undefined->text; # undefined
=head2 C<B<match(I<string>)>>
C<match()> always return undef
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> always return undef
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2016 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,243 @@
package Sisimai::Reason::UserUnknown;
use feature ':5.10';
use strict;
use warnings;
sub text { 'userunknown' }
sub description { "Email rejected due to a local part of a recipient's email address does not exist" }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.0.0
my $class = shift;
my $argv1 = shift // return undef;
my $regex = qr{(?>
.+[ ]user[ ]unknown
|[#]5[.]1[.]1[ ]bad[ ]address
|[<].+[>][ ]not[ ]found
|[<].+[@].+[>][.][.][.][ ]blocked[ ]by[ ]
|5[.]0[.]0[.][ ]mail[ ]rejected[.]
|5[.]1[.]0[ ]address[ ]rejected[.]
|adresse[ ]d[ ]au[ ]moins[ ]un[ ]destinataire[ ]invalide.+[a-z]{3}.+(?:416|418)
|address[ ](?:does[ ]not[ ]exist|unknown)
|archived[ ]recipient
|bad[-_ \t]recipient
|can[']t[ ]accept[ ]user
|destination[ ](?:
addresses[ ]were[ ]unknown
|server[ ]rejected[ ]recipients
)
|email[ ]address[ ](?:does[ ]not[ ]exist|could[ ]not[ ]be[ ]found)
|invalid[ ](?:
address
|mailbox:
|mailbox[ ]path|recipient
)
|is[ ]not[ ](?:
a[ ]known[ ]user
|a[ ]valid[ ]mailbox
|an[ ]active[ ]address[ ]at[ ]this[ ]host
)
|mailbox[ ](?:
.+[ ]does[ ]not[ ]exist
|.+[@].+[ ]unavailable
|invalid
|is[ ](?:inactive|unavailable)
|not[ ](?:present|found)
|unavailable
)
|no[ ](?:
[ ].+[ ]in[ ]name[ ]directory
|account[ ]by[ ]that[ ]name[ ]here
|existe[ ](?:dicha[ ]persona|ese[ ]usuario[ ])
|mail[ ]box[ ]available[ ]for[ ]this[ ]user
|mailbox[ ](?:
by[ ]that[ ]name[ ]is[ ]currently[ ]available
|found
)
|matches[ ]to[ ]nameserver[ ]query
|such[ ](?:
address[ ]here
|mailbox
|person[ ]at[ ]this[ ]address
|recipient
|user(?:[ ]here)?
)
|thank[ ]you[ ]rejected:[ ]account[ ]unavailable:
|valid[ ]recipients[,][ ]bye # Microsoft
)
|non[- ]?existent[ ]user
|not[ ](?:
a[ ]valid[ ]user[ ]here
|a[ ]local[ ]address
|email[ ]addresses
)
|rcpt[ ][<].+[>][ ]does[ ]not[ ]exist
|rece?ipient[ ](?:
.+[ ]was[ ]not[ ]found[ ]in
|address[ ]rejected:[ ](?:
access[ ]denied
|invalid[ ]user
|user[ ].+[ ]does[ ]not[ ]exist
|user[ ]unknown[ ]in[ ].+[ ]table
|unknown[ ]user
)
|does[ ]not[ ]exist(?:[ ]on[ ]this[ ]system)?
|is[ ]not[ ]local
|not[ ](?:exist|found|ok)
|unknown
)
|requested[ ]action[ ]not[ ]taken:[ ]mailbox[ ]unavailable
|resolver[.]adr[.]recip(?:ient)notfound # Microsoft
|said:[ ]550[-[ ]]5[.]1[.]1[ ].+[ ]user[ ]unknown[ ]
|smtp[ ]error[ ]from[ ]remote[ ]mail[ ]server[ ]after[ ]end[ ]of[ ]data:[ ]553.+does[ ]not[ ]exist
|sorry,[ ](?:
user[ ]unknown
|badrcptto
|no[ ]mailbox[ ]here[ ]by[ ]that[ ]name
)
|the[ ](?:
email[ ]account[ ]that[ ]you[ ]tried[ ]to[ ]reach[ ]does[ ]not[ ]exist
|following[ ]recipients[ ]was[ ]undeliverable
|user[']s[ ]email[ ]name[ ]is[ ]not[ ]found
)
|there[ ]is[ ]no[ ]one[ ]at[ ]this[ ]address
|this[ ](?:
address[ ]no[ ]longer[ ]accepts[ ]mail
|email[ ]address[ ]is[ ]wrong[ ]or[ ]no[ ]longer[ ]valid
|spectator[ ]does[ ]not[ ]exist
|user[ ]doesn[']?t[ ]have[ ]a[ ].+[ ]account
)
|unknown[ ](?:
e[-]?mail[ ]address
|local[- ]part
|mailbox
|recipient
|user
)
|user[ ](?:
.+[ ]was[ ]not[ ]found
|.+[ ]does[ ]not[ ]exist
|does[ ]not[ ]exist
|missing[ ]home[ ]directory
|not[ ](?:active|found|known)
|unknown
)
|vdeliver:[ ]invalid[ ]or[ ]unknown[ ]virtual[ ]user
|your[ ]envelope[ ]recipient[ ]is[ ]in[ ]my[ ]badrcptto[ ]list
)
}x;
return 1 if $argv1 =~ $regex;
return 0;
}
sub true {
# Whether the address is "userunknown" or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: is unknown user
# 0: is not unknown user.
# @since v4.0.0
# @see http://www.ietf.org/rfc/rfc2822.txt
my $class = shift;
my $argvs = shift // return undef;
return 1 if $argvs->reason eq 'userunknown';
my $diagnostic = lc $argvs->diagnosticcode;
my $tempreason = Sisimai::SMTP::Status->name($argvs->deliverystatus);
return 0 if $tempreason eq 'suspend';
if( $tempreason eq 'userunknown' ) {
# *.1.1 = 'Bad destination mailbox address'
# Status: 5.1.1
# Diagnostic-Code: SMTP; 550 5.1.1 <***@example.jp>:
# Recipient address rejected: User unknown in local recipient table
my $prematches = [qw|NoRelaying Blocked MailboxFull HasMoved Blocked Rejected|];
my $matchother = 0;
my $modulepath = '';
for my $e ( @$prematches ) {
# Check the value of "Diagnostic-Code" with other error patterns.
my $p = 'Sisimai::Reason::'.$e;
($modulepath = $p) =~ s|::|/|g;
require $modulepath.'.pm';
next unless $p->match($diagnostic);
# Match with reason defined in Sisimai::Reason::* except UserUnknown.
$matchother = 1;
last;
}
return 1 if not $matchother; # Did not match with other message patterns
} elsif( $argvs->smtpcommand eq 'RCPT' ) {
# When the SMTP command is not "RCPT", the session rejected by other
# reason, maybe.
return 1 if __PACKAGE__->match($diagnostic);
}
return 0;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::UserUnknown - Bounce reason is C<userunknown> or not.
=head1 SYNOPSIS
use Sisimai::Reason::UserUnknown;
print Sisimai::Reason::UserUnknown->match('550 5.1.1 Unknown User'); # 1
=head1 DESCRIPTION
Sisimai::Reason::UserUnknown checks the bounce reason is C<userunknown> or not.
This class is called only Sisimai::Reason class.
This is the error that a local part (Left hand side of @ sign) of a recipient's
email address does not exist. In many case, a user has changed internet service
provider, or has quit company, or the local part is misspelled. Sisimai will set
C<userunknown> to the reason of email bounce if the value of Status: field in a
bounce email is C<5.1.1>, or connection was refused at SMTP RCPT command, or the
contents of Diagnostic-Code: field represents that it is unknown user.
<kijitora@example.co.jp>: host mx01.example.co.jp[192.0.2.8] said:
550 5.1.1 Address rejected kijitora@example.co.jp (in reply to
RCPT TO command)
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<userunknown>.
print Sisimai::Reason::UserUnknown->text; # userunknown
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
print Sisimai::Reason::UserUnknown->match('550 5.1.1 Unknown User'); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<userunknown>. The argument must be
Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2014-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,76 @@
package Sisimai::Reason::Vacation;
use feature ':5.10';
use strict;
use warnings;
sub text { 'vacation' }
sub description { 'Email replied automatically due to a recipient is out of office' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.22.3
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'i am away on vacation',
'i am away until',
'i am out of the office',
'i will be traveling for work on',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true { return undef }
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::Vacation - A recipient is out of office
=head1 SYNOPSIS
use Sisimai::Reason::Vacation;
print Sisimai::Reason::Vacation->text; # vacation
=head1 DESCRIPTION
Sisimai::Reason::Vacation is for only returning text and description.
This class is called only from Sisimai->reason method.
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<vacation>.
print Sisimai::Reason::Vacation->text; # vacation
=head2 C<B<match(I<string>)>>
C<match()> always return undef
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> always return undef
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2016-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut

View File

@@ -0,0 +1,98 @@
package Sisimai::Reason::VirusDetected;
use feature ':5.10';
use strict;
use warnings;
sub text { 'virusdetected' }
sub description { 'Email rejected due to a virus scanner on a destination host' }
sub match {
# Try to match that the given text and regular expressions
# @param [String] argv1 String to be matched with regular expressions
# @return [Integer] 0: Did not match
# 1: Matched
# @since v4.22.0
my $class = shift;
my $argv1 = shift // return undef;
my $index = [
'it has a potentially executable attachment',
'the message was rejected because it contains prohibited virus or spam content',
'this form of attachment has been used by recent viruses or other malware',
'your message was infected with a virus',
];
return 1 if grep { rindex($argv1, $_) > -1 } @$index;
return 0;
}
sub true {
# The bounce reason is security error or not
# @param [Sisimai::Data] argvs Object to be detected the reason
# @return [Integer] 1: virus detected
# 0: virus was not detected
# @since v4.22.0
# @see http://www.ietf.org/rfc/rfc2822.txt
return undef;
}
1;
__END__
=encoding utf-8
=head1 NAME
Sisimai::Reason::VirusDetected - Bounce reason is C<virusdetected> or not.
=head1 SYNOPSIS
use Sisimai::Reason::VirusDetected;
print Sisimai::Reason::VirusDetected->match('5.7.1 Email not accept'); # 1
=head1 DESCRIPTION
Sisimai::Reason::VirusDetected checks the bounce reason is C<virusdetected> or
not. This class is called only Sisimai::Reason class.
This is an error that any virus or trojan horse detected in the message by a
virus scanner program at a destination mail server. This reason has been divided
from C<securityerror> at Sisimai 4.22.0.
Your message was infected with a virus. You should download a virus
scanner and check your computer for viruses.
Sender: <sironeko@libsisimai.org>
Recipient: <kijitora@example.jp>
=head1 CLASS METHODS
=head2 C<B<text()>>
C<text()> returns string: C<virusdetected>.
print Sisimai::Reason::VirusDetected->text; # virusdetected
=head2 C<B<match(I<string>)>>
C<match()> returns 1 if the argument matched with patterns defined in this class.
my $v = 'Your message was infected with a virus. ...';
print Sisimai::Reason::VirusDetected->match($v); # 1
=head2 C<B<true(I<Sisimai::Data>)>>
C<true()> returns 1 if the bounce reason is C<virusdetected>. The argument must
be Sisimai::Data object and this method is called only from Sisimai::Reason class.
=head1 AUTHOR
azumakuniyuki
=head1 COPYRIGHT
Copyright (C) 2017-2018 azumakuniyuki, All rights reserved.
=head1 LICENSE
This software is distributed under The BSD 2-Clause License.
=cut