sisimai 4.16.0-java → 4.17.0-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/ANALYTICAL-PRECISION +7 -7
  4. data/Changes +15 -0
  5. data/Makefile +1 -1
  6. data/README.md +30 -28
  7. data/lib/sisimai.rb +20 -1
  8. data/lib/sisimai/address.rb +28 -9
  9. data/lib/sisimai/arf.rb +37 -46
  10. data/lib/sisimai/data.rb +67 -43
  11. data/lib/sisimai/datetime.rb +210 -210
  12. data/lib/sisimai/mda.rb +30 -30
  13. data/lib/sisimai/message.rb +3 -5
  14. data/lib/sisimai/msp/de/einsundeins.rb +14 -42
  15. data/lib/sisimai/msp/de/gmx.rb +17 -44
  16. data/lib/sisimai/msp/jp/biglobe.rb +15 -44
  17. data/lib/sisimai/msp/jp/ezweb.rb +20 -50
  18. data/lib/sisimai/msp/jp/kddi.rb +16 -43
  19. data/lib/sisimai/msp/ru/mailru.rb +20 -48
  20. data/lib/sisimai/msp/ru/yandex.rb +16 -50
  21. data/lib/sisimai/msp/uk/messagelabs.rb +17 -51
  22. data/lib/sisimai/msp/us/amazonses.rb +18 -40
  23. data/lib/sisimai/msp/us/amazonworkmail.rb +17 -35
  24. data/lib/sisimai/msp/us/aol.rb +17 -41
  25. data/lib/sisimai/msp/us/bigfoot.rb +15 -48
  26. data/lib/sisimai/msp/us/facebook.rb +63 -90
  27. data/lib/sisimai/msp/us/google.rb +15 -44
  28. data/lib/sisimai/msp/us/office365.rb +21 -46
  29. data/lib/sisimai/msp/us/outlook.rb +17 -50
  30. data/lib/sisimai/msp/us/receivingses.rb +20 -43
  31. data/lib/sisimai/msp/us/sendgrid.rb +13 -37
  32. data/lib/sisimai/msp/us/verizon.rb +30 -74
  33. data/lib/sisimai/msp/us/yahoo.rb +12 -40
  34. data/lib/sisimai/msp/us/zoho.rb +14 -42
  35. data/lib/sisimai/mta/activehunter.rb +11 -40
  36. data/lib/sisimai/mta/apachejames.rb +18 -40
  37. data/lib/sisimai/mta/courier.rb +20 -57
  38. data/lib/sisimai/mta/domino.rb +24 -56
  39. data/lib/sisimai/mta/exchange.rb +26 -54
  40. data/lib/sisimai/mta/exim.rb +20 -39
  41. data/lib/sisimai/mta/imailserver.rb +26 -71
  42. data/lib/sisimai/mta/interscanmss.rb +26 -44
  43. data/lib/sisimai/mta/mailfoundry.rb +12 -42
  44. data/lib/sisimai/mta/mailmarshalsmtp.rb +13 -43
  45. data/lib/sisimai/mta/mcafee.rb +17 -46
  46. data/lib/sisimai/mta/messagingserver.rb +14 -47
  47. data/lib/sisimai/mta/mfilter.rb +12 -35
  48. data/lib/sisimai/mta/mxlogic.rb +18 -42
  49. data/lib/sisimai/mta/notes.rb +22 -45
  50. data/lib/sisimai/mta/opensmtpd.rb +18 -48
  51. data/lib/sisimai/mta/postfix.rb +15 -45
  52. data/lib/sisimai/mta/qmail.rb +32 -60
  53. data/lib/sisimai/mta/sendmail.rb +13 -38
  54. data/lib/sisimai/mta/surfcontrol.rb +15 -44
  55. data/lib/sisimai/mta/userdefined.rb +14 -30
  56. data/lib/sisimai/mta/v5sendmail.rb +18 -40
  57. data/lib/sisimai/mta/x1.rb +12 -41
  58. data/lib/sisimai/mta/x2.rb +12 -41
  59. data/lib/sisimai/mta/x3.rb +12 -39
  60. data/lib/sisimai/mta/x4.rb +33 -66
  61. data/lib/sisimai/mta/x5.rb +15 -42
  62. data/lib/sisimai/reason.rb +8 -71
  63. data/lib/sisimai/reason/blocked.rb +3 -0
  64. data/lib/sisimai/reason/contenterror.rb +3 -0
  65. data/lib/sisimai/reason/delivered.rb +27 -0
  66. data/lib/sisimai/reason/exceedlimit.rb +3 -0
  67. data/lib/sisimai/reason/expired.rb +3 -0
  68. data/lib/sisimai/reason/feedback.rb +18 -0
  69. data/lib/sisimai/reason/filtered.rb +4 -0
  70. data/lib/sisimai/reason/hasmoved.rb +3 -0
  71. data/lib/sisimai/reason/hostunknown.rb +3 -0
  72. data/lib/sisimai/reason/mailboxfull.rb +3 -0
  73. data/lib/sisimai/reason/mailererror.rb +3 -0
  74. data/lib/sisimai/reason/mesgtoobig.rb +3 -0
  75. data/lib/sisimai/reason/networkerror.rb +3 -0
  76. data/lib/sisimai/reason/norelaying.rb +3 -0
  77. data/lib/sisimai/reason/notaccept.rb +3 -0
  78. data/lib/sisimai/reason/onhold.rb +3 -0
  79. data/lib/sisimai/reason/rejected.rb +3 -0
  80. data/lib/sisimai/reason/securityerror.rb +3 -0
  81. data/lib/sisimai/reason/spamdetected.rb +3 -0
  82. data/lib/sisimai/reason/suspend.rb +3 -0
  83. data/lib/sisimai/reason/syntaxerror.rb +41 -0
  84. data/lib/sisimai/reason/systemerror.rb +3 -0
  85. data/lib/sisimai/reason/systemfull.rb +3 -0
  86. data/lib/sisimai/reason/toomanyconn.rb +3 -0
  87. data/lib/sisimai/reason/undefined.rb +18 -0
  88. data/lib/sisimai/reason/userunknown.rb +3 -0
  89. data/lib/sisimai/reason/vacation.rb +18 -0
  90. data/lib/sisimai/rfc3464.rb +15 -40
  91. data/lib/sisimai/rfc3834.rb +1 -10
  92. data/lib/sisimai/rfc5322.rb +57 -19
  93. data/lib/sisimai/rhost/googleapps.rb +82 -82
  94. data/lib/sisimai/smtp/reply.rb +2 -1
  95. data/lib/sisimai/smtp/status.rb +154 -152
  96. data/lib/sisimai/string.rb +2 -3
  97. data/lib/sisimai/version.rb +1 -1
  98. data/set-of-emails/maildir/bsd/rfc3464-29.eml +60 -0
  99. data/set-of-emails/maildir/bsd/us-amazonworkmail-06.eml +156 -0
  100. data/set-of-emails/maildir/bsd/us-amazonworkmail-07.eml +158 -0
  101. data/set-of-emails/maildir/bsd/us-google-15.eml +97 -0
  102. data/set-of-emails/maildir/bsd/us-google-16.eml +99 -0
  103. data/set-of-emails/maildir/bsd/us-google-17.eml +104 -0
  104. data/set-of-emails/maildir/dos/apachejames-01.eml +4 -4
  105. data/set-of-emails/maildir/dos/us-amazonworkmail-01.eml +156 -0
  106. data/set-of-emails/maildir/dos/us-office365-01.eml +102 -0
  107. data/set-of-emails/maildir/mac/apachejames-01.eml +1 -9
  108. data/set-of-emails/maildir/mac/us-amazonworkmail-01.eml +1 -7
  109. data/set-of-emails/maildir/mac/us-office365-01.eml +1 -4
  110. metadata +17 -2
data/lib/sisimai/mda.rb CHANGED
@@ -10,12 +10,12 @@ module Sisimai
10
10
  # dovecot/src/deliver/deliver.c
11
11
  # 11: #define DEFAULT_MAIL_REJECTION_HUMAN_REASON \
12
12
  # 12: "Your message to <%t> was automatically rejected:%n%r"
13
- 'dovecot' => %r/\AYour message to .+ was automatically rejected:\z/,
14
- 'mail.local' => %r/\Amail[.]local: /,
15
- 'procmail' => %r/\Aprocmail: /,
16
- 'maildrop' => %r/\Amaildrop: /,
17
- 'vpopmail' => %r/\Avdelivermail: /,
18
- 'vmailmgr' => %r/\Avdeliver: /,
13
+ :'dovecot' => %r/\AYour message to .+ was automatically rejected:\z/,
14
+ :'mail.local' => %r/\Amail[.]local: /,
15
+ :'procmail' => %r/\Aprocmail: /,
16
+ :'maildrop' => %r/\Amaildrop: /,
17
+ :'vpopmail' => %r/\Avdelivermail: /,
18
+ :'vmailmgr' => %r/\Avdeliver: /,
19
19
  }
20
20
  Re2 = %r{\A(?>
21
21
  Your[ ]message[ ]to[ ].+[ ]was[ ]automatically[ ]rejected:\z
@@ -25,58 +25,58 @@ module Sisimai
25
25
 
26
26
  # dovecot/src/deliver/mail-send.c:94
27
27
  ReFailure = {
28
- 'dovecot' => {
29
- 'userunknown' => %r/\AMailbox doesn't exist: /i,
30
- 'mailboxfull' => %r{\A(?:
28
+ :'dovecot' => {
29
+ :userunknown => %r/\AMailbox doesn't exist: /i,
30
+ :mailboxfull => %r{\A(?:
31
31
  Quota[ ]exceeded # Dovecot 1.2 dovecot/src/plugins/quota/quota.c
32
32
  |Quota[ ]exceeded[ ][(]mailbox[ ]for[ ]user[ ]is[ ]full[)] # dovecot/src/plugins/quota/quota.c
33
33
  |Not[ ]enough[ ]disk[ ]space
34
34
  )
35
35
  }xi,
36
36
  },
37
- 'mail.local' => {
38
- 'userunknown' => %r{[:][ ](?:
37
+ :'mail.local' => {
38
+ :userunknown => %r{[:][ ](?:
39
39
  unknown[ ]user[:]
40
40
  |User[ ]unknown
41
41
  |Invalid[ ]mailbox[ ]path
42
42
  |User[ ]missing[ ]home[ ]directory
43
43
  )
44
44
  }xi,
45
- 'mailboxfull' => %r{(?:
45
+ :mailboxfull => %r{(?:
46
46
  Disc[ ]quota[ ]exceeded
47
47
  |Mailbox[ ]full[ ]or[ ]quota[ ]exceeded
48
48
  )
49
49
  }xi,
50
- 'systemerror' => %r/Temporary file write error/i,
50
+ :systemerror => %r/Temporary file write error/i,
51
51
  },
52
- 'procmail' => {
53
- 'mailboxfull' => %r/Quota exceeded while writing/i,
54
- 'systemfull' => %r/No space left to finish writing/i,
52
+ :'procmail' => {
53
+ :mailboxfull => %r/Quota exceeded while writing/i,
54
+ :systemfull => %r/No space left to finish writing/i,
55
55
  },
56
- 'maildrop' => {
57
- 'userunknown' => %r{(?:
56
+ :'maildrop' => {
57
+ :userunknown => %r{(?:
58
58
  Invalid[ ]user[ ]specified[.]
59
59
  |Cannot[ ]find[ ]system[ ]user
60
60
  )
61
61
  }xi,
62
- 'mailboxfull' => %r/maildir over quota[.]\z/i,
62
+ :mailboxfull => %r/maildir over quota[.]\z/i,
63
63
  },
64
- 'vpopmail' => {
65
- 'userunknown' => %r/Sorry, no mailbox here by that name[.]/i,
66
- 'filtered' => %r{(?:
64
+ :'vpopmail' => {
65
+ :userunknown => %r/Sorry, no mailbox here by that name[.]/i,
66
+ :filtered => %r{(?:
67
67
  account[ ]is[ ]locked[ ]email[ ]bounced
68
68
  |user[ ]does[ ]not[ ]exist,[ ]but[ ]will[ ]deliver[ ]to[ ]
69
69
  )
70
70
  }xi,
71
- 'mailboxfull' => %r/(?:domain|user) is over quota/i,
71
+ :mailboxfull => %r/(?:domain|user) is over quota/i,
72
72
  },
73
- 'vmailmgr' => {
74
- 'userunknown' => %r{(?>
73
+ :'vmailmgr' => {
74
+ :userunknown => %r{(?>
75
75
  Invalid[ ]or[ ]unknown[ ](?:base[ ]user[ ]or[ ]domain|virtual[ ]user)
76
76
  |User[ ]name[ ]does[ ]not[ ]refer[ ]to[ ]a[ ]virtual[ ]user/
77
77
  )
78
78
  }ix,
79
- 'mailboxfull' => %r/Delivery failed due to system quota violation/i,
79
+ :mailboxfull => %r/Delivery failed due to system quota violation/i,
80
80
  },
81
81
  }
82
82
 
@@ -115,7 +115,7 @@ module Sisimai
115
115
  Re1.each_key do |f|
116
116
  # Detect the agent name from the line
117
117
  next unless e =~ Re1[f]
118
- agentname0 = f
118
+ agentname0 = f.to_s
119
119
  break
120
120
  end
121
121
  end
@@ -128,12 +128,12 @@ module Sisimai
128
128
  return nil unless agentname0.size > 0
129
129
  return nil unless linebuffer.size > 0
130
130
 
131
- ReFailure[agentname0].each_key do |e|
131
+ ReFailure[agentname0.to_sym].each_key do |e|
132
132
  # Detect an error reason from message patterns of the MDA.
133
133
  linebuffer.each do |f|
134
134
  # Try to match with each regular expression
135
- next unless f =~ ReFailure[agentname0][e]
136
- reasonname = e
135
+ next unless f =~ ReFailure[agentname0.to_sym][e]
136
+ reasonname = e.to_s
137
137
  bouncemesg = f
138
138
  break
139
139
  end
@@ -166,8 +166,9 @@ module Sisimai
166
166
  return {} if email.empty?
167
167
 
168
168
  email = email.scrub('?')
169
- email = email.gsub(/[ \t]+$/, '')
170
- email = email.gsub(/^[ \t]+$/, '')
169
+ email = email.gsub(/\r\n/, "\n") if email =~ /\r\n/
170
+ email = email.gsub(/[ \t]+$/, '') if email =~ /[ \t]+$/
171
+
171
172
  hasdivided = email.split("\n")
172
173
  return {} if hasdivided.empty?
173
174
 
@@ -184,9 +185,6 @@ module Sisimai
184
185
  # Split email data to headers and a body part.
185
186
  hasdivided.each do |e|
186
187
  # Split email data to headers and a body part.
187
- e = e.delete("\r").delete("\n")
188
- e = e.gsub(/[ \t]+\z/, '')
189
-
190
188
  if readcursor & Indicators[:endof] > 0
191
189
  # The body part of the email
192
190
  aftersplit['body'] += e + "\n"
@@ -19,11 +19,9 @@ module Sisimai
19
19
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
20
20
  }
21
21
  ReFailure = {
22
- 'mesgtoobig' => %r/Mail[ ]size[ ]limit[ ]exceeded/x,
22
+ mesgtoobig: %r/Mail[ ]size[ ]limit[ ]exceeded/x,
23
23
  }
24
24
  Indicators = Sisimai::MSP.INDICATORS
25
- LongFields = Sisimai::RFC5322.LONGFIELDS
26
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
27
25
 
28
26
  def description; return '1&1: http://www.1and1.de'; end
29
27
  def smtpagent; return 'DE::EinsUndEins'; end
@@ -48,11 +46,10 @@ module Sisimai
48
46
  return nil unless mhead['from'] =~ Re0[:from]
49
47
  return nil unless mhead['subject'] =~ Re0[:subject]
50
48
 
51
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
49
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
52
50
  hasdivided = mbody.split("\n")
53
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
54
- rfc822part = '' # (String) message/rfc822-headers part
55
- previousfn = '' # (String) Previous field name
51
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
52
+ blanklines = 0 # (Integer) The number of blank lines
56
53
  readcursor = 0 # (Integer) Points the current cursor position
57
54
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
58
55
  v = nil
@@ -61,7 +58,7 @@ module Sisimai
61
58
  if readcursor == 0
62
59
  # Beginning of the bounce message or delivery status part
63
60
  if e =~ Re1[:begin]
64
- readcursor |= Indicators[:'deliverystatus']
61
+ readcursor |= Indicators[:deliverystatus]
65
62
  next
66
63
  end
67
64
  end
@@ -76,30 +73,16 @@ module Sisimai
76
73
 
77
74
  if readcursor & Indicators[:'message-rfc822'] > 0
78
75
  # After "message/rfc822"
79
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
80
- # Get required headers only
81
- lhs = cv[1].downcase
82
- previousfn = ''
83
- next unless RFC822Head.key?(lhs)
84
-
85
- previousfn = lhs
86
- rfc822part += e + "\n"
87
-
88
- elsif e =~ /\A[ \t]+/
89
- # Continued line from the previous line
90
- next if rfc822next[previousfn]
91
- rfc822part += e + "\n" if LongFields.key?(previousfn)
92
-
93
- else
94
- # Check the end of headers in rfc822 part
95
- next unless LongFields.key?(previousfn)
96
- next unless e.empty?
97
- rfc822next[previousfn] = true
76
+ if e.empty?
77
+ blanklines += 1
78
+ break if blanklines > 1
79
+ next
98
80
  end
81
+ rfc822list << e
99
82
 
100
83
  else
101
84
  # Before "message/rfc822"
102
- next if readcursor & Indicators[:'deliverystatus'] == 0
85
+ next if readcursor & Indicators[:deliverystatus] == 0
103
86
  next if e.empty?
104
87
 
105
88
  # The following address failed:
@@ -135,19 +118,11 @@ module Sisimai
135
118
  end
136
119
  end
137
120
  end
138
-
139
121
  return nil if recipients == 0
140
122
  require 'sisimai/string'
141
- require 'sisimai/smtp/status'
142
123
 
143
124
  dscontents.map do |e|
144
- if mhead['received'].size > 0
145
- # Get localhost and remote host name from Received header.
146
- r0 = mhead['received']
147
- %w|lhost rhost|.each { |a| e[a] ||= '' }
148
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
149
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
150
- end
125
+ e['agent'] = Sisimai::MSP::DE::EinsUndEins.smtpagent
151
126
  e['diagnosis'] ||= ''
152
127
  e['diagnosis'] = e['diagnosis'].gsub(/\A#{Re1[:error]}/, '')
153
128
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
@@ -155,15 +130,12 @@ module Sisimai
155
130
  ReFailure.each_key do |r|
156
131
  # Verify each regular expression of session errors
157
132
  next unless e['diagnosis'] =~ ReFailure[r]
158
- e['reason'] = r
133
+ e['reason'] = r.to_s
159
134
  break
160
135
  end
161
-
162
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
163
- e['spec'] = 'SMTP'
164
- e['agent'] = Sisimai::MSP::DE::EinsUndEins.smtpagent
165
136
  end
166
137
 
138
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
167
139
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
168
140
  end
169
141
 
@@ -18,11 +18,9 @@ module Sisimai
18
18
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
19
19
  }
20
20
  ReFailure = {
21
- 'expired' => %r/delivery[ ]retry[ ]timeout[ ]exceeded/x,
21
+ expired: %r/delivery[ ]retry[ ]timeout[ ]exceeded/x,
22
22
  }
23
23
  Indicators = Sisimai::MSP.INDICATORS
24
- LongFields = Sisimai::RFC5322.LONGFIELDS
25
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
26
24
 
27
25
  def description; return 'GMX: http://www.gmx.net'; end
28
26
  def smtpagent; return 'DE::GMX'; end
@@ -48,13 +46,12 @@ module Sisimai
48
46
  def scan(mhead, mbody)
49
47
  return nil unless mhead
50
48
  return nil unless mbody
51
- return nil unless mhead['x-gmx-antispam'];
49
+ return nil unless mhead['x-gmx-antispam']
52
50
 
53
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
51
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
54
52
  hasdivided = mbody.split("\n")
55
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
56
- rfc822part = '' # (String) message/rfc822-headers part
57
- previousfn = '' # (String) Previous field name
53
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
54
+ blanklines = 0 # (Integer) The number of blank lines
58
55
  readcursor = 0 # (Integer) Points the current cursor position
59
56
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
60
57
  v = nil
@@ -63,7 +60,7 @@ module Sisimai
63
60
  if readcursor == 0
64
61
  # Beginning of the bounce message or delivery status part
65
62
  if e =~ Re1[:begin]
66
- readcursor |= Indicators[:'deliverystatus']
63
+ readcursor |= Indicators[:deliverystatus]
67
64
  next
68
65
  end
69
66
  end
@@ -78,30 +75,16 @@ module Sisimai
78
75
 
79
76
  if readcursor & Indicators[:'message-rfc822'] > 0
80
77
  # After "message/rfc822"
81
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
82
- # Get required headers only
83
- lhs = cv[1].downcase
84
- previousfn = ''
85
- next unless RFC822Head.key?(lhs)
86
-
87
- previousfn = lhs
88
- rfc822part += e + "\n"
89
-
90
- elsif e =~ /\A[ \t]+/
91
- # Continued line from the previous line
92
- next if rfc822next[previousfn]
93
- rfc822part += e + "\n" if LongFields.key?(previousfn)
94
-
95
- else
96
- # Check the end of headers in rfc822 part
97
- next unless LongFields.key?(previousfn)
98
- next unless e.empty?
99
- rfc822next[previousfn] = true
78
+ if e.empty?
79
+ blanklines += 1
80
+ break if blanklines > 1
81
+ next
100
82
  end
83
+ rfc822list << e
101
84
 
102
85
  else
103
86
  # Before "message/rfc822"
104
- next if readcursor & Indicators[:'deliverystatus'] == 0
87
+ next if readcursor & Indicators[:deliverystatus] == 0
105
88
  next if e.empty?
106
89
 
107
90
  # This message was created automatically by mail delivery software.
@@ -116,8 +99,7 @@ module Sisimai
116
99
  # 5.1.1 <shironeko@example.jp>... User Unknown
117
100
  v = dscontents[-1]
118
101
 
119
- if cv = e.match(/\A["]([^ ]+[@][^ ]+)["]:\z/) ||
120
- cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]\z/)
102
+ if cv = e.match(/\A["]([^ ]+[@][^ ]+)["]:\z/) || e.match(/\A[<]([^ ]+[@][^ ]+)[>]\z/)
121
103
  # "shironeko@example.jp":
122
104
  # ---- OR ----
123
105
  # <kijitora@6jo.example.co.jp>
@@ -143,7 +125,7 @@ module Sisimai
143
125
  else
144
126
  # Get error message
145
127
  if e =~ /\b[45][.]\d[.]\d\b/ || e =~ /[<][^ ]+[@][^ ]+[>]/ || e =~ /\b[45]\d{2}\b/
146
- v['diagnosis'] ||= e;
128
+ v['diagnosis'] ||= e
147
129
 
148
130
  else
149
131
  next if e =~ /\A\z/
@@ -165,28 +147,19 @@ module Sisimai
165
147
  require 'sisimai/smtp/status'
166
148
 
167
149
  dscontents.map do |e|
168
- if mhead['received'].size > 0
169
- # Get localhost and remote host name from Received header.
170
- r0 = mhead['received']
171
- %w|lhost rhost|.each { |a| e[a] ||= '' }
172
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
173
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
174
- end
150
+ e['agent'] = Sisimai::MSP::DE::GMX.smtpagent
175
151
  e['diagnosis'] = e['diagnosis'].gsub(/\\n/, ' ')
176
152
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
177
153
 
178
154
  ReFailure.each_key do |r|
179
155
  # Verify each regular expression of session errors
180
156
  next unless e['diagnosis'] =~ ReFailure[r]
181
- e['reason'] = r
157
+ e['reason'] = r.to_s
182
158
  break
183
159
  end
184
-
185
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
186
- e['spec'] = 'SMTP'
187
- e['agent'] = Sisimai::MSP::DE::GMX.smtpagent
188
160
  end
189
161
 
162
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
190
163
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
191
164
  end
192
165
 
@@ -19,13 +19,10 @@ module Sisimai
19
19
  :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
20
20
  }
21
21
  ReFailure = {
22
- 'filtered' => %r/Mail Delivery Failed[.]+ User unknown/,
23
- 'mailboxfull' => %r/The number of messages in recipient's mailbox exceeded the local limit[.]/,
22
+ filtered: %r/Mail Delivery Failed[.]+ User unknown/,
23
+ mailboxfull: %r/The number of messages in recipient's mailbox exceeded the local limit[.]/,
24
24
  }
25
-
26
25
  Indicators = Sisimai::MSP.INDICATORS
27
- LongFields = Sisimai::RFC5322.LONGFIELDS
28
- RFC822Head = Sisimai::RFC5322.HEADERFIELDS
29
26
 
30
27
  def description; return 'BIGLOBE: http://www.biglobe.ne.jp'; end
31
28
  def smtpagent; return 'JP::Biglobe'; end
@@ -50,11 +47,10 @@ module Sisimai
50
47
  return nil unless mhead['subject'] =~ Re0[:subject]
51
48
 
52
49
  require 'sisimai/address'
53
- dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
50
+ dscontents = [Sisimai::MSP.DELIVERYSTATUS]
54
51
  hasdivided = mbody.split("\n")
55
- rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
56
- rfc822part = '' # (String) message/rfc822-headers part
57
- previousfn = '' # (String) Previous field name
52
+ rfc822list = [] # (Array) Each line in message/rfc822 part string
53
+ blanklines = 0 # (Integer) The number of blank lines
58
54
  readcursor = 0 # (Integer) Points the current cursor position
59
55
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
60
56
  v = nil
@@ -63,7 +59,7 @@ module Sisimai
63
59
  if readcursor == 0
64
60
  # Beginning of the bounce message or delivery status part
65
61
  if e =~ Re1[:begin]
66
- readcursor |= Indicators[:'deliverystatus']
62
+ readcursor |= Indicators[:deliverystatus]
67
63
  next
68
64
  end
69
65
  end
@@ -78,30 +74,16 @@ module Sisimai
78
74
 
79
75
  if readcursor & Indicators[:'message-rfc822'] > 0
80
76
  # After "message/rfc822"
81
- if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
82
- # Get required headers only
83
- lhs = cv[1].downcase
84
- previousfn = ''
85
- next unless RFC822Head.key?(lhs)
86
-
87
- previousfn = lhs
88
- rfc822part += e + "\n"
89
-
90
- elsif e =~ /\A[ \t]+/
91
- # Continued line from the previous line
92
- next if rfc822next[previousfn]
93
- rfc822part += e + "\n" if LongFields.key?(previousfn)
94
-
95
- else
96
- # Check the end of headers in rfc822 part
97
- next unless LongFields.key?(previousfn)
98
- next unless e.empty?
99
- rfc822next[previousfn] = true
77
+ if e.empty?
78
+ blanklines += 1
79
+ break if blanklines > 1
80
+ next
100
81
  end
82
+ rfc822list << e
101
83
 
102
84
  else
103
85
  # Before "message/rfc822"
104
- next if readcursor & Indicators[:'deliverystatus'] == 0
86
+ next if readcursor & Indicators[:deliverystatus] == 0
105
87
  next if e.empty?
106
88
 
107
89
  # This is a MIME-encapsulated message.
@@ -145,31 +127,20 @@ module Sisimai
145
127
 
146
128
  return nil if recipients == 0
147
129
  require 'sisimai/string'
148
- require 'sisimai/smtp/status'
149
130
 
150
131
  dscontents.map do |e|
151
- if mhead['received'].size > 0
152
- # Get localhost and remote host name from Received header.
153
- r0 = mhead['received']
154
- %w|lhost rhost|.each { |a| e[a] ||= '' }
155
- e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
156
- e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
157
- end
132
+ e['agent'] = Sisimai::MSP::JP::Biglobe.smtpagent
158
133
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
159
134
 
160
135
  ReFailure.each_key do |r|
161
136
  # Verify each regular expression of session errors
162
137
  next unless e['diagnosis'] =~ ReFailure[r]
163
- e['reason'] = r
138
+ e['reason'] = r.to_s
164
139
  break
165
140
  end
166
-
167
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
168
- e['spec'] = 'SMTP'
169
- e['action'] = 'failed' if e['status'] =~ /\A[45]/
170
- e['agent'] = Sisimai::MSP::JP::Biglobe.smtpagent
171
141
  end
172
142
 
143
+ rfc822part = Sisimai::RFC5322.weedout(rfc822list)
173
144
  return { 'ds' => dscontents, 'rfc822' => rfc822part }
174
145
  end
175
146