File Coverage

lib/Sisimai/Lhost/X1.pm
Criterion Covered Total %
statement 44 47 93.6
branch 15 20 75.0
condition 4 6 66.6
subroutine 6 6 100.0
pod 2 2 100.0
total 71 81 87.6


line stmt bran cond sub pod time code
1             package Sisimai::Lhost::X1;
2 15     15   6073 use parent 'Sisimai::Lhost';
  15         35  
  15         86  
3 15     15   970 use feature ':5.10';
  15         38  
  15         1043  
4 15     15   88 use strict;
  15         34  
  15         329  
5 15     15   70 use warnings;
  15         22  
  15         8860  
6              
7 2     2 1 1207 sub description { 'Unknown MTA #1' }
8             sub make {
9             # Detect an error from Unknown MTA #1
10             # @param [Hash] mhead Message headers of a bounce email
11             # @param [String] mbody Message body of a bounce email
12             # @return [Hash] Bounce data list and message/rfc822 part
13             # @return [Undef] failed to parse or the arguments are missing
14             # @since v4.1.3
15 198     198 1 744 my $class = shift;
16 198   100     532 my $mhead = shift // return undef;
17 197   50     487 my $mbody = shift // return undef;
18              
19 197 100       835 return undef unless index($mhead->{'subject'}, 'Returned Mail: ') == 0;
20 11 50       52 return undef unless index($mhead->{'from'}, '"Mail Deliver System" ') == 0;
21              
22 11         45 state $indicators = __PACKAGE__->INDICATORS;
23 11         29 state $rebackbone = qr/^Received: from \d+[.]\d+[.]\d+[.]\d/m;
24 11         28 state $markingsof = { 'message' => qr/\AThe original message was received at (.+)\z/ };
25              
26 11         51 my $dscontents = [__PACKAGE__->DELIVERYSTATUS];
27 11         73 my $emailsteak = Sisimai::RFC5322->fillet($mbody, $rebackbone);
28 11         26 my $readcursor = 0; # (Integer) Points the current cursor position
29 11         20 my $recipients = 0; # (Integer) The number of 'Final-Recipient' header
30 11         25 my $datestring = ''; # (String) Date string
31 11         17 my $v = undef;
32              
33 11         72 for my $e ( split("\n", $emailsteak->[0]) ) {
34             # Read error messages and delivery status lines from the head of the email
35             # to the previous line of the beginning of the original message.
36 132 100       194 unless( $readcursor ) {
37             # Beginning of the bounce message or message/delivery-status part
38 33 100       181 $readcursor |= $indicators->{'deliverystatus'} if $e =~ $markingsof->{'message'};
39 33         50 next;
40             }
41 99 50       169 next unless $readcursor & $indicators->{'deliverystatus'};
42 99 100       159 next unless length $e;
43              
44             # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
45             # from shironeko@example.jp
46             #
47             # ---The following addresses had delivery errors---
48             #
49             # kijitora@example.co.jp [User unknown]
50 55         78 $v = $dscontents->[-1];
51              
52 55 100       301 if( $e =~ /\A([^ ]+?[@][^ ]+?)[ \t]+\[(.+)\]\z/ ) {
    50          
53             # kijitora@example.co.jp [User unknown]
54 11 50       39 if( $v->{'recipient'} ) {
55             # There are multiple recipient addresses in the message body.
56 0         0 push @$dscontents, __PACKAGE__->DELIVERYSTATUS;
57 0         0 $v = $dscontents->[-1];
58             }
59 11         34 $v->{'recipient'} = $1;
60 11         23 $v->{'diagnosis'} = $2;
61 11         41 $recipients++;
62              
63             } elsif( $e =~ $markingsof->{'message'} ) {
64             # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
65 0         0 $datestring = $1;
66             }
67             }
68 11 50       95 return undef unless $recipients;
69              
70 11         39 for my $e ( @$dscontents ) {
71 11         72 $e->{'diagnosis'} = Sisimai::String->sweep($e->{'diagnosis'});
72 11   50     109 $e->{'date'} = $datestring || '';
73             }
74 11         61 return { 'ds' => $dscontents, 'rfc822' => $emailsteak->[1] };
75             }
76              
77             1;
78             __END__