| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Sisimai::Lhost::ApacheJames; |
|
2
|
37
|
|
|
37
|
|
3976
|
use parent 'Sisimai::Lhost'; |
|
|
37
|
|
|
|
|
81
|
|
|
|
37
|
|
|
|
|
251
|
|
|
3
|
37
|
|
|
37
|
|
2903
|
use v5.26; |
|
|
37
|
|
|
|
|
148
|
|
|
4
|
37
|
|
|
37
|
|
213
|
use strict; |
|
|
37
|
|
|
|
|
82
|
|
|
|
37
|
|
|
|
|
1056
|
|
|
5
|
37
|
|
|
37
|
|
159
|
use warnings; |
|
|
37
|
|
|
|
|
111
|
|
|
|
37
|
|
|
|
|
31244
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
1
|
4
|
sub description { 'James: https://james.apache.org/' } |
|
8
|
|
|
|
|
|
|
sub inquire { |
|
9
|
|
|
|
|
|
|
# Detect an error from Apache James |
|
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 decode or the arguments are missing |
|
14
|
|
|
|
|
|
|
# @since v4.1.26 |
|
15
|
888
|
|
|
888
|
1
|
3715
|
my $class = shift; |
|
16
|
888
|
|
100
|
|
|
2528
|
my $mhead = shift // return undef; |
|
17
|
887
|
|
100
|
|
|
2726
|
my $mbody = shift // return undef; |
|
18
|
886
|
50
|
0
|
|
|
1607
|
my $match = 0; $match ||= 1 if $mhead->{'subject'} eq '[BOUNCE]'; |
|
|
886
|
|
|
|
|
3418
|
|
|
19
|
886
|
100
|
50
|
|
|
6042
|
$match ||= 1 if defined $mhead->{'message-id'} && rindex($mhead->{'message-id'}, '.JavaMail.') > -1; |
|
|
|
|
100
|
|
|
|
|
|
20
|
886
|
50
|
0
|
|
|
2176
|
$match ||= 1 if grep { rindex($_, 'JAMES SMTP Server') > -1 } $mhead->{'received'}->@*; |
|
|
1714
|
|
|
|
|
5883
|
|
|
21
|
886
|
100
|
|
|
|
3969
|
return undef unless $match; |
|
22
|
|
|
|
|
|
|
|
|
23
|
6
|
|
|
|
|
28
|
state $indicators = __PACKAGE__->INDICATORS; |
|
24
|
6
|
|
|
|
|
12
|
state $boundaries = ["Content-Type: message/rfc822"]; |
|
25
|
6
|
|
|
|
|
13
|
state $startingof = { |
|
26
|
|
|
|
|
|
|
# apache-james-2.3.2/src/java/org/apache/james/transport/mailets/ |
|
27
|
|
|
|
|
|
|
# AbstractNotify.java|124: out.println("Error message below:"); |
|
28
|
|
|
|
|
|
|
# AbstractNotify.java|128: out.println("Message details:"); |
|
29
|
|
|
|
|
|
|
"message" => ["Message details:"], |
|
30
|
|
|
|
|
|
|
}; |
|
31
|
|
|
|
|
|
|
|
|
32
|
6
|
|
|
|
|
35
|
my $dscontents = [__PACKAGE__->DELIVERYSTATUS]; my $v = $dscontents->[-1]; |
|
|
6
|
|
|
|
|
14
|
|
|
33
|
6
|
|
|
|
|
27
|
my $emailparts = Sisimai::RFC5322->part($mbody, $boundaries); |
|
34
|
6
|
|
|
|
|
10
|
my $readcursor = 0; # Points the current cursor position |
|
35
|
6
|
|
|
|
|
10
|
my $recipients = 0; # The number of 'Final-Recipient' header |
|
36
|
6
|
|
|
|
|
29
|
my $alternates = ["", "", "", ""]; # [Envelope-From, Header-From, Date, Subject] |
|
37
|
|
|
|
|
|
|
|
|
38
|
6
|
|
|
|
|
64
|
for my $e ( split("\n", $emailparts->[0]) ) { |
|
39
|
|
|
|
|
|
|
# Read error messages and delivery status lines from the head of the email to the previous |
|
40
|
|
|
|
|
|
|
# line of the beginning of the original message. |
|
41
|
84
|
100
|
|
|
|
118
|
unless( $readcursor ) { |
|
42
|
|
|
|
|
|
|
# Beginning of the bounce message or message/delivery-status part |
|
43
|
36
|
100
|
|
|
|
79
|
if( index($e, $startingof->{"message"}->[0]) == 0 ) { |
|
44
|
|
|
|
|
|
|
# Message details: |
|
45
|
|
|
|
|
|
|
# Subject: Nyaaan |
|
46
|
6
|
|
|
|
|
12
|
$readcursor |= $indicators->{"deliverystatus"}; next; |
|
|
6
|
|
|
|
|
11
|
|
|
47
|
|
|
|
|
|
|
} |
|
48
|
30
|
100
|
|
|
|
62
|
$v->{"diagnosis"} .= $e." " if $e ne ""; |
|
49
|
30
|
|
|
|
|
44
|
next; |
|
50
|
|
|
|
|
|
|
} |
|
51
|
48
|
50
|
33
|
|
|
113
|
next if ($readcursor & $indicators->{'deliverystatus'}) == 0 || $e eq ""; |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Message details: |
|
54
|
|
|
|
|
|
|
# Subject: Nyaaan |
|
55
|
|
|
|
|
|
|
# Sent date: Thu Apr 29 01:20:50 JST 2015 |
|
56
|
|
|
|
|
|
|
# MAIL FROM: shironeko@example.jp |
|
57
|
|
|
|
|
|
|
# RCPT TO: kijitora@example.org |
|
58
|
|
|
|
|
|
|
# From: Neko |
|
59
|
|
|
|
|
|
|
# To: kijitora@example.org |
|
60
|
|
|
|
|
|
|
# Size (in bytes): 1024 |
|
61
|
|
|
|
|
|
|
# Number of lines: 64 |
|
62
|
48
|
100
|
|
|
|
160
|
if( index($e, " RCPT TO: ") == 0 ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# RCPT TO: kijitora@example.org |
|
64
|
6
|
50
|
|
|
|
17
|
if( $v->{"recipient"} ) { |
|
65
|
|
|
|
|
|
|
# There are multiple recipient addresses in the message body. |
|
66
|
0
|
|
|
|
|
0
|
push @$dscontents, __PACKAGE__->DELIVERYSTATUS; |
|
67
|
0
|
|
|
|
|
0
|
$v = $dscontents->[-1]; |
|
68
|
|
|
|
|
|
|
} |
|
69
|
6
|
|
|
|
|
10
|
$v->{"recipient"} = substr($e, 12,); |
|
70
|
6
|
|
|
|
|
10
|
$recipients++; |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
} elsif( index($e, " Sent date: ") == 0 ) { |
|
73
|
|
|
|
|
|
|
# Sent date: Thu Apr 29 01:20:50 JST 2015 |
|
74
|
6
|
|
|
|
|
11
|
$v->{"date"} = substr($e, 13,); |
|
75
|
6
|
|
|
|
|
11
|
$alternates->[2] = $v->{"date"}; |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
} elsif( index($e, " Subject: ") == 0 ) { |
|
78
|
|
|
|
|
|
|
# Subject: Nyaaan |
|
79
|
6
|
|
|
|
|
21
|
$alternates->[3] = substr($e, 11,); |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
} elsif( index($e, " MAIL FROM: ") == 0 ) { |
|
82
|
|
|
|
|
|
|
# MAIL FROM: shironeko@example.jp |
|
83
|
6
|
|
|
|
|
13
|
$alternates->[0] = substr($e, 13,); |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
} elsif( index($e, " From: ") == 0 ) { |
|
86
|
|
|
|
|
|
|
# From: Neko |
|
87
|
6
|
|
|
|
|
12
|
$alternates->[1] = substr($e, 8,); |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
} |
|
90
|
6
|
50
|
|
|
|
30
|
return undef unless $recipients; |
|
91
|
|
|
|
|
|
|
|
|
92
|
6
|
50
|
|
|
|
18
|
if( $emailparts->[1] eq "" ) { |
|
93
|
|
|
|
|
|
|
# The original message is empty |
|
94
|
6
|
50
|
|
|
|
22
|
$emailparts->[1] .= sprintf("From: %s\n", $alternates->[1]) if $alternates->[1] ne ""; |
|
95
|
6
|
50
|
|
|
|
18
|
$emailparts->[1] .= sprintf("Date: %s\n", $alternates->[2]) if $alternates->[2] ne ""; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
6
|
50
|
|
|
|
46
|
if( index($emailparts->[1], "Return-Path: ") < 0 ) { |
|
98
|
|
|
|
|
|
|
# Set the envelope from address as a Return-Path: header |
|
99
|
6
|
50
|
|
|
|
20
|
$emailparts->[1] .= sprintf("Return-Path: <%s>\n", $alternates->[0]) if $alternates->[0] ne ""; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
6
|
50
|
|
|
|
40
|
if( index($emailparts->[1], "\nSubject: ") < 0 ) { |
|
102
|
|
|
|
|
|
|
# Set the envelope from address as a Return-Path: header |
|
103
|
6
|
50
|
|
|
|
33
|
$emailparts->[1] .= sprintf("Subject: %s\n", $alternates->[3]) if $alternates->[3] ne ""; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
6
|
|
|
|
|
38
|
$_->{"diagnosis"} = Sisimai::String->sweep($_->{"diagnosis"}) for @$dscontents; |
|
106
|
6
|
|
|
|
|
31
|
return {"ds" => $dscontents, "rfc822" => $emailparts->[1]}; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
1; |
|
110
|
|
|
|
|
|
|
__END__ |