File Coverage

lib/Sisimai/LDA.pm
Criterion Covered Total %
statement 28 28 100.0
branch 10 10 100.0
condition 7 7 100.0
subroutine 4 4 100.0
pod 0 1 0.0
total 49 50 98.0


line stmt bran cond sub pod time code
1             package Sisimai::LDA;
2 87     87   118864 use v5.26;
  87         226  
3 87     87   319 use strict;
  87         115  
  87         1485  
4 87     87   259 use warnings;
  87         150  
  87         33225  
5              
6             state $LocalAgent = {
7             # Each error message should be a lower-cased string
8             # dovecot/src/deliver/deliver.c
9             # 11: #define DEFAULT_MAIL_REJECTION_HUMAN_REASON \
10             # 12: "Your message to <%t> was automatically rejected:%n%r"
11             "dovecot" => ["Your message to <", "> was automatically rejected:"],
12             "mail.local" => ["mail.local: "],
13             "procmail" => ["procmail: ", "/procmail "],
14             "maildrop" => ["maildrop: "],
15             "vpopmail" => ["vdelivermail: "],
16             "vmailmgr" => ["vdeliver: "],
17             };
18              
19             state $MessagesOf = {
20             # Each error message should be a lower-cased string
21             "dovecot" => {
22             # dovecot/src/deliver/mail-send.c:94
23             "mailboxfull" => [
24             "not enough disk space",
25             "quota exceeded", # Dovecot 1.2 dovecot/src/plugins/quota/quota.c
26             "quota exceeded (mailbox for user is full)", # dovecot/src/plugins/quota/quota.c
27             ],
28             "userunknown" => ["mailbox doesn't exist: "],
29             },
30             "mail.local" => {
31             "mailboxfull" => ["disc quota exceeded", "mailbox full or quota exceeded"],
32             "systemerror" => ["temporary file write error"],
33             "userunknown" => [
34             ": invalid mailbox path",
35             ": unknown user:",
36             ": user missing home directory",
37             ": user unknown",
38             ],
39             },
40             "procmail" => {
41             "mailboxfull" => ["quota exceeded while writing", "user over quota"],
42             "systemerror" => ["service unavailable"],
43             "systemfull" => ["no space left to finish writing"],
44             },
45             "maildrop" => {
46             "mailboxfull" => ["maildir over quota."],
47             "userunknown" => ["invalid user specified.", "cannot find system user"],
48             },
49             "vpopmail" => {
50             "filtered" => ["user does not exist, but will deliver to "],
51             "mailboxfull" => ["domain is over quota", "user is over quota"],
52             "suspend" => ["account is locked email bounced"],
53             "userunknown" => ["sorry, no mailbox here by that name."],
54             },
55             "vmailmgr" => {
56             "mailboxfull" => ["delivery failed due to system quota violation"],
57             "userunknown" => [
58             "invalid or unknown base user or domain",
59             "invalid or unknown virtual user",
60             "user name does not refer to a virtual user"
61             ],
62             },
63             };
64              
65             sub find {
66             # Decode the message body and return a bounce reason detected by the error message of LDA
67             # @param [Sisimai::Fact] argvs Decoded email object
68             # @return [String] The value of bounce reason
69 3366     3366 0 9040 my $class = shift;
70 3366   100     6160 my $argvs = shift // return "";
71              
72 3365 100       6758 return "" unless length $argvs->{"diagnosticcode"};
73 3355 100 100     10544 return "" unless $argvs->{"command"} eq "" || $argvs->{"command"} eq "DATA";
74              
75 2349         2394 my $deliversby = ""; # [String] Local Delivery Agent name
76 2349         2601 my $reasontext = ""; # [String] Detected bounce reason
77 2349         4611 my $issuedcode = lc $argvs->{"diagnosticcode"};
78              
79 2349         6910 for my $e ( keys %$LocalAgent ) {
80             # Find a local delivery agent name from the lower-cased error message
81 14014 100       15984 next unless grep { index($issuedcode, $_) > -1 } $LocalAgent->{ $e }->@*;
  18701         30476  
82 37         59 $deliversby = $e; last;
  37         44  
83             }
84 2349 100       7786 return "" unless $deliversby;
85              
86 37         122 for my $e ( keys $MessagesOf->{ $deliversby }->%* ) {
87             # The key nane is a bounce reason name
88 71 100       115 next unless grep { index($issuedcode, $_) > -1 } $MessagesOf->{ $deliversby }->{ $e }->@*;
  117         239  
89 25         37 $reasontext = $e; last;
  25         28  
90             }
91              
92 37   100     92 $reasontext ||= "mailererror"; # procmail: Couldn't create "/var/mail/tmp.nekochan.22"
93 37         85 return $reasontext;
94             }
95              
96             1;
97             __END__