sisimai 4.25.4 → 4.25.5

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/ChangeLog.md +50 -0
  4. data/README-JA.md +10 -37
  5. data/README.md +10 -37
  6. data/lib/sisimai.rb +15 -64
  7. data/lib/sisimai/address.rb +13 -17
  8. data/lib/sisimai/arf.rb +4 -4
  9. data/lib/sisimai/data.rb +3 -5
  10. data/lib/sisimai/lhost.rb +0 -14
  11. data/lib/sisimai/lhost/activehunter.rb +31 -55
  12. data/lib/sisimai/lhost/amavis.rb +41 -66
  13. data/lib/sisimai/lhost/amazonses.rb +189 -235
  14. data/lib/sisimai/lhost/amazonworkmail.rb +48 -71
  15. data/lib/sisimai/lhost/aol.rb +49 -75
  16. data/lib/sisimai/lhost/apachejames.rb +60 -83
  17. data/lib/sisimai/lhost/bigfoot.rb +61 -85
  18. data/lib/sisimai/lhost/biglobe.rb +40 -62
  19. data/lib/sisimai/lhost/courier.rb +60 -82
  20. data/lib/sisimai/lhost/domino.rb +50 -76
  21. data/lib/sisimai/lhost/einsundeins.rb +57 -55
  22. data/lib/sisimai/lhost/exchange2003.rb +79 -101
  23. data/lib/sisimai/lhost/exchange2007.rb +66 -74
  24. data/lib/sisimai/lhost/exim.rb +119 -142
  25. data/lib/sisimai/lhost/ezweb.rb +53 -73
  26. data/lib/sisimai/lhost/facebook.rb +49 -75
  27. data/lib/sisimai/lhost/fml.rb +25 -50
  28. data/lib/sisimai/lhost/gmx.rb +55 -79
  29. data/lib/sisimai/lhost/google.rb +39 -66
  30. data/lib/sisimai/lhost/gsuite.rb +74 -94
  31. data/lib/sisimai/lhost/imailserver.rb +34 -67
  32. data/lib/sisimai/lhost/interscanmss.rb +33 -67
  33. data/lib/sisimai/lhost/kddi.rb +30 -52
  34. data/lib/sisimai/lhost/mailfoundry.rb +35 -57
  35. data/lib/sisimai/lhost/mailmarshalsmtp.rb +66 -89
  36. data/lib/sisimai/lhost/mailru.rb +51 -76
  37. data/lib/sisimai/lhost/mcafee.rb +53 -79
  38. data/lib/sisimai/lhost/messagelabs.rb +49 -75
  39. data/lib/sisimai/lhost/messagingserver.rb +91 -113
  40. data/lib/sisimai/lhost/mfilter.rb +50 -70
  41. data/lib/sisimai/lhost/mxlogic.rb +38 -63
  42. data/lib/sisimai/lhost/notes.rb +53 -82
  43. data/lib/sisimai/lhost/office365.rb +64 -81
  44. data/lib/sisimai/lhost/opensmtpd.rb +30 -52
  45. data/lib/sisimai/lhost/outlook.rb +49 -75
  46. data/lib/sisimai/lhost/postfix.rb +116 -117
  47. data/lib/sisimai/lhost/qmail.rb +33 -55
  48. data/lib/sisimai/lhost/receivingses.rb +49 -75
  49. data/lib/sisimai/lhost/sendgrid.rb +68 -203
  50. data/lib/sisimai/lhost/sendmail.rb +101 -125
  51. data/lib/sisimai/lhost/surfcontrol.rb +53 -79
  52. data/lib/sisimai/lhost/userdefined.rb +15 -35
  53. data/lib/sisimai/lhost/v5sendmail.rb +59 -89
  54. data/lib/sisimai/lhost/verizon.rb +75 -124
  55. data/lib/sisimai/lhost/x1.rb +30 -54
  56. data/lib/sisimai/lhost/x2.rb +28 -52
  57. data/lib/sisimai/lhost/x3.rb +44 -68
  58. data/lib/sisimai/lhost/x4.rb +34 -58
  59. data/lib/sisimai/lhost/x5.rb +42 -70
  60. data/lib/sisimai/lhost/yahoo.rb +44 -68
  61. data/lib/sisimai/lhost/yandex.rb +59 -85
  62. data/lib/sisimai/lhost/zoho.rb +54 -78
  63. data/lib/sisimai/mail.rb +5 -9
  64. data/lib/sisimai/mail/maildir.rb +10 -14
  65. data/lib/sisimai/mail/mbox.rb +8 -12
  66. data/lib/sisimai/mail/memory.rb +5 -9
  67. data/lib/sisimai/mail/stdin.rb +7 -11
  68. data/lib/sisimai/mda.rb +2 -2
  69. data/lib/sisimai/message.rb +51 -154
  70. data/lib/sisimai/mime.rb +2 -2
  71. data/lib/sisimai/order.rb +2 -27
  72. data/lib/sisimai/reason.rb +3 -5
  73. data/lib/sisimai/rfc1894.rb +1 -1
  74. data/lib/sisimai/rfc3464.rb +29 -29
  75. data/lib/sisimai/rfc3834.rb +7 -6
  76. data/lib/sisimai/rfc5322.rb +20 -31
  77. data/lib/sisimai/rhost/franceptt.rb +120 -24
  78. data/lib/sisimai/rhost/iua.rb +1 -1
  79. data/lib/sisimai/smtp/error.rb +7 -7
  80. data/lib/sisimai/version.rb +1 -1
  81. data/set-of-emails/maildir/bsd/email-einsundeins-03.eml +66 -0
  82. data/set-of-emails/maildir/bsd/email-exchange2007-05.eml +1469 -0
  83. data/set-of-emails/maildir/bsd/email-exchange2007-06.eml +764 -0
  84. data/set-of-emails/maildir/bsd/email-postfix-64.eml +96 -0
  85. data/set-of-emails/maildir/bsd/rfc3834-03.eml +26 -0
  86. data/set-of-emails/maildir/bsd/rhost-franceptt-04.eml +66 -0
  87. data/set-of-emails/maildir/bsd/rhost-franceptt-05.eml +96 -0
  88. data/set-of-emails/maildir/bsd/rhost-franceptt-06.eml +100 -0
  89. data/set-of-emails/maildir/bsd/rhost-franceptt-07.eml +97 -0
  90. data/set-of-emails/maildir/bsd/rhost-franceptt-08.eml +78 -0
  91. data/set-of-emails/maildir/bsd/rhost-franceptt-10.eml +79 -0
  92. data/set-of-emails/maildir/bsd/rhost-franceptt-11.eml +96 -0
  93. metadata +14 -9
  94. data/lib/sisimai/bite.rb +0 -42
  95. data/lib/sisimai/bite/email.rb +0 -18
  96. data/lib/sisimai/bite/json.rb +0 -16
  97. data/lib/sisimai/message/email.rb +0 -26
  98. data/lib/sisimai/message/json.rb +0 -24
  99. data/lib/sisimai/order/email.rb +0 -20
  100. data/lib/sisimai/order/json.rb +0 -16
@@ -8,8 +8,8 @@ module Sisimai::Lhost
8
8
  require 'sisimai/lhost'
9
9
 
10
10
  Indicators = Sisimai::Lhost.INDICATORS
11
+ ReBackbone = %r<^(?:Content-type:[ ]*message/rfc822|Return-path:[ ]*)>.freeze
11
12
  StartingOf = { message: ['This report relates to a message you sent with the following header fields:'] }.freeze
12
- MarkingsOf = { rfc822: %r!\A(?:Content-type:[ ]*message/rfc822|Return-path:[ ]*)! }.freeze
13
13
  MessagesOf = { 'hostunknown' => ['Illegal host/domain name found'] }.freeze
14
14
 
15
15
  def description; return 'Oracle Communications Messaging Server'; end
@@ -35,130 +35,109 @@ module Sisimai::Lhost
35
35
  return nil unless match > 0
36
36
 
37
37
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
38
- hasdivided = mbody.split("\n")
39
- rfc822list = [] # (Array) Each line in message/rfc822 part string
40
- blanklines = 0 # (Integer) The number of blank lines
38
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
39
+ bodyslices = emailsteak[0].split("\n")
41
40
  readcursor = 0 # (Integer) Points the current cursor position
42
41
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
43
42
  v = nil
44
43
 
45
- while e = hasdivided.shift do
44
+ while e = bodyslices.shift do
45
+ # Read error messages and delivery status lines from the head of the email
46
+ # to the previous line of the beginning of the original message.
46
47
  if readcursor == 0
47
48
  # Beginning of the bounce message or delivery status part
48
- if e.start_with?(StartingOf[:message][0])
49
- readcursor |= Indicators[:deliverystatus]
50
- next
51
- end
49
+ readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
50
+ next
52
51
  end
53
-
54
- if (readcursor & Indicators[:'message-rfc822']) == 0
55
- # Beginning of the original message part
56
- if e =~ MarkingsOf[:rfc822]
57
- readcursor |= Indicators[:'message-rfc822']
58
- next
52
+ next if (readcursor & Indicators[:deliverystatus]) == 0
53
+ next if e.empty?
54
+
55
+ # --Boundary_(ID_0000000000000000000000)
56
+ # Content-type: text/plain; charset=us-ascii
57
+ # Content-language: en-US
58
+ #
59
+ # This report relates to a message you sent with the following header fields:
60
+ #
61
+ # Message-id: <CD8C6134-C312-41D5-B083-366F7FA1D752@me.example.com>
62
+ # Date: Fri, 21 Nov 2014 23:34:45 +0900
63
+ # From: Shironeko <shironeko@me.example.com>
64
+ # To: kijitora@example.jp
65
+ # Subject: Nyaaaaaaaaaaaaaaaaaaaaaan
66
+ #
67
+ # Your message cannot be delivered to the following recipients:
68
+ #
69
+ # Recipient address: kijitora@example.jp
70
+ # Reason: Remote SMTP server has rejected address
71
+ # Diagnostic code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
72
+ # Remote system: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25) (6jo.example.jp ESMTP SENDMAIL-VM)
73
+ v = dscontents[-1]
74
+
75
+ if cv = e.match(/\A[ \t]+Recipient address:[ \t]*([^ ]+[@][^ ]+)\z/)
76
+ # Recipient address: kijitora@example.jp
77
+ if v['recipient']
78
+ # There are multiple recipient addresses in the message body.
79
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
80
+ v = dscontents[-1]
59
81
  end
60
- end
82
+ v['recipient'] = Sisimai::Address.s3s4(cv[1])
83
+ recipients += 1
61
84
 
62
- if readcursor & Indicators[:'message-rfc822'] > 0
63
- # Inside of the original message part
64
- if e.empty?
65
- blanklines += 1
66
- break if blanklines > 1
67
- next
68
- end
69
- rfc822list << e
70
- else
71
- # Error message part
72
- next if (readcursor & Indicators[:deliverystatus]) == 0
73
- next if e.empty?
85
+ elsif cv = e.match(/\A[ \t]+Original address:[ \t]*([^ ]+[@][^ ]+)\z/)
86
+ # Original address: kijitora@example.jp
87
+ v['recipient'] = Sisimai::Address.s3s4(cv[1])
74
88
 
75
- # --Boundary_(ID_0000000000000000000000)
76
- # Content-type: text/plain; charset=us-ascii
77
- # Content-language: en-US
78
- #
79
- # This report relates to a message you sent with the following header fields:
80
- #
81
- # Message-id: <CD8C6134-C312-41D5-B083-366F7FA1D752@me.example.com>
89
+ elsif cv = e.match(/\A[ \t]+Date:[ \t]*(.+)\z/)
82
90
  # Date: Fri, 21 Nov 2014 23:34:45 +0900
83
- # From: Shironeko <shironeko@me.example.com>
84
- # To: kijitora@example.jp
85
- # Subject: Nyaaaaaaaaaaaaaaaaaaaaaan
86
- #
87
- # Your message cannot be delivered to the following recipients:
88
- #
89
- # Recipient address: kijitora@example.jp
91
+ v['date'] = cv[1]
92
+
93
+ elsif cv = e.match(/\A[ \t]+Reason:[ \t]*(.+)\z/)
90
94
  # Reason: Remote SMTP server has rejected address
95
+ v['diagnosis'] = cv[1]
96
+
97
+ elsif cv = e.match(/\A[ \t]+Diagnostic code:[ \t]*([^ ]+);(.+)\z/)
91
98
  # Diagnostic code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
92
- # Remote system: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25) (6jo.example.jp ESMTP SENDMAIL-VM)
93
- v = dscontents[-1]
94
-
95
- if cv = e.match(/\A[ \t]+Recipient address:[ \t]*([^ ]+[@][^ ]+)\z/)
96
- # Recipient address: kijitora@example.jp
97
- if v['recipient']
98
- # There are multiple recipient addresses in the message body.
99
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
100
- v = dscontents[-1]
101
- end
102
- v['recipient'] = Sisimai::Address.s3s4(cv[1])
103
- recipients += 1
104
-
105
- elsif cv = e.match(/\A[ \t]+Original address:[ \t]*([^ ]+[@][^ ]+)\z/)
106
- # Original address: kijitora@example.jp
107
- v['recipient'] = Sisimai::Address.s3s4(cv[1])
108
-
109
- elsif cv = e.match(/\A[ \t]+Date:[ \t]*(.+)\z/)
110
- # Date: Fri, 21 Nov 2014 23:34:45 +0900
111
- v['date'] = cv[1]
112
-
113
- elsif cv = e.match(/\A[ \t]+Reason:[ \t]*(.+)\z/)
114
- # Reason: Remote SMTP server has rejected address
115
- v['diagnosis'] = cv[1]
116
-
117
- elsif cv = e.match(/\A[ \t]+Diagnostic code:[ \t]*([^ ]+);(.+)\z/)
118
- # Diagnostic code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
119
- v['spec'] = cv[1].upcase
120
- v['diagnosis'] = cv[2]
121
-
122
- elsif cv = e.match(/\A[ \t]+Remote system:[ ]*dns;([^ ]+)[ ]*([^ ]+)[ ]*.+\z/)
123
- # Remote system: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25)
124
- # (6jo.example.jp ESMTP SENDMAIL-VM)
125
- remotehost = cv[1] # remote host
126
- sessionlog = cv[2] # smtp session
127
- v['rhost'] = remotehost
128
-
129
- # The value does not include ".", use IP address instead.
130
- # (TCP|17.111.174.67|47323|192.0.2.225|25)
131
- next unless cv = sessionlog.match(/\A[(]TCP|(.+)|\d+|(.+)|\d+[)]/)
132
- v['lhost'] = cv[1]
133
- v['rhost'] = cv[2] unless remotehost =~ /[^.]+[.][^.]+/
134
- else
135
- # Original-envelope-id: 0NFC009FLKOUVMA0@mr21p30im-asmtp004.me.com
136
- # Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
137
- # Arrival-date: Thu, 29 Apr 2014 23:34:45 +0000 (GMT)
138
- #
139
- # Original-recipient: rfc822;kijitora@example.jp
140
- # Final-recipient: rfc822;kijitora@example.jp
141
- # Action: failed
99
+ v['spec'] = cv[1].upcase
100
+ v['diagnosis'] = cv[2]
101
+
102
+ elsif cv = e.match(/\A[ \t]+Remote system:[ ]*dns;([^ ]+)[ ]*([^ ]+)[ ]*.+\z/)
103
+ # Remote system: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25)
104
+ # (6jo.example.jp ESMTP SENDMAIL-VM)
105
+ remotehost = cv[1] # remote host
106
+ sessionlog = cv[2] # smtp session
107
+ v['rhost'] = remotehost
108
+
109
+ # The value does not include ".", use IP address instead.
110
+ # (TCP|17.111.174.67|47323|192.0.2.225|25)
111
+ next unless cv = sessionlog.match(/\A[(]TCP|(.+)|\d+|(.+)|\d+[)]/)
112
+ v['lhost'] = cv[1]
113
+ v['rhost'] = cv[2] unless remotehost =~ /[^.]+[.][^.]+/
114
+ else
115
+ # Original-envelope-id: 0NFC009FLKOUVMA0@mr21p30im-asmtp004.me.com
116
+ # Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
117
+ # Arrival-date: Thu, 29 Apr 2014 23:34:45 +0000 (GMT)
118
+ #
119
+ # Original-recipient: rfc822;kijitora@example.jp
120
+ # Final-recipient: rfc822;kijitora@example.jp
121
+ # Action: failed
122
+ # Status: 5.1.1 (Remote SMTP server has rejected address)
123
+ # Remote-MTA: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25)
124
+ # (6jo.example.jp ESMTP SENDMAIL-VM)
125
+ # Diagnostic-code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
126
+ #
127
+ if cv = e.match(/\AStatus:[ ]*(\d[.]\d[.]\d)[ ]*[(](.+)[)]\z/)
142
128
  # Status: 5.1.1 (Remote SMTP server has rejected address)
143
- # Remote-MTA: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25)
144
- # (6jo.example.jp ESMTP SENDMAIL-VM)
145
- # Diagnostic-code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
146
- #
147
- if cv = e.match(/\AStatus:[ ]*(\d[.]\d[.]\d)[ ]*[(](.+)[)]\z/)
148
- # Status: 5.1.1 (Remote SMTP server has rejected address)
149
- v['status'] = cv[1]
150
- v['diagnosis'] ||= cv[2]
151
-
152
- elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
153
- # Arrival-date: Thu, 29 Apr 2014 23:34:45 +0000 (GMT)
154
- v['date'] ||= cv[1]
155
-
156
- elsif cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
157
- # Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
158
- localhost = cv[1]
159
- v['lhost'] ||= localhost
160
- v['lhost'] = localhost unless v['lhost'] =~ /[^.]+[.][^ ]+/
161
- end
129
+ v['status'] = cv[1]
130
+ v['diagnosis'] ||= cv[2]
131
+
132
+ elsif cv = e.match(/\AArrival-Date:[ ]*(.+)\z/)
133
+ # Arrival-date: Thu, 29 Apr 2014 23:34:45 +0000 (GMT)
134
+ v['date'] ||= cv[1]
135
+
136
+ elsif cv = e.match(/\AReporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
137
+ # Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
138
+ localhost = cv[1]
139
+ v['lhost'] ||= localhost
140
+ v['lhost'] = localhost unless v['lhost'] =~ /[^.]+[.][^ ]+/
162
141
  end
163
142
  end
164
143
  end
@@ -177,8 +156,7 @@ module Sisimai::Lhost
177
156
  e.each_key { |a| e[a] ||= '' }
178
157
  end
179
158
 
180
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
181
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
159
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
182
160
  end
183
161
 
184
162
  end
@@ -8,10 +8,10 @@ module Sisimai::Lhost
8
8
  require 'sisimai/lhost'
9
9
 
10
10
  Indicators = Sisimai::Lhost.INDICATORS
11
+ ReBackbone = %r/^-------original[ ](?:message|mail[ ]info)/.freeze
11
12
  StartingOf = {
12
13
  error: ['-------server message'],
13
14
  command: ['-------SMTP command'],
14
- rfc822: ['-------original message', '-------original mail info'],
15
15
  }.freeze
16
16
  MarkingsOf = { message: %r/\A[^ ]+[@][^ ]+[.][a-zA-Z]+\z/ }.freeze
17
17
 
@@ -36,89 +36,70 @@ module Sisimai::Lhost
36
36
  return nil unless mhead['subject'] == 'failure notice'
37
37
 
38
38
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
39
- hasdivided = mbody.split("\n")
40
- rfc822list = [] # (Array) Each line in message/rfc822 part string
41
- blanklines = 0 # (Integer) The number of blank lines
39
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
40
+ bodyslices = emailsteak[0].split("\n")
42
41
  readcursor = 0 # (Integer) Points the current cursor position
43
42
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
44
43
  markingset = { 'diagnosis' => false, 'command' => false }
45
44
  v = nil
46
45
 
47
- while e = hasdivided.shift do
46
+ while e = bodyslices.shift do
47
+ # Read error messages and delivery status lines from the head of the email
48
+ # to the previous line of the beginning of the original message.
48
49
  if readcursor == 0
49
50
  # Beginning of the bounce message or delivery status part
50
51
  readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
51
52
  end
52
-
53
- if (readcursor & Indicators[:'message-rfc822']) == 0
54
- # Beginning of the original message part
55
- if e.start_with?(StartingOf[:rfc822][0], StartingOf[:rfc822][1])
56
- readcursor |= Indicators[:'message-rfc822']
57
- next
58
- end
59
- end
60
-
61
- if readcursor & Indicators[:'message-rfc822'] > 0
62
- # Inside of the original message part
63
- if e.empty?
64
- blanklines += 1
65
- break if blanklines > 1
66
- next
67
- end
68
- rfc822list << e
69
- else
70
- # Error message part
71
- next if (readcursor & Indicators[:deliverystatus]) == 0
72
- next if e.empty?
73
-
74
- # このメールは「m-FILTER」が自動的に生成して送信しています。
75
- # メールサーバーとの通信中、下記の理由により
76
- # このメールは送信できませんでした。
77
- #
53
+ next if (readcursor & Indicators[:deliverystatus]) == 0
54
+ next if e.empty?
55
+
56
+ # このメールは「m-FILTER」が自動的に生成して送信しています。
57
+ # メールサーバーとの通信中、下記の理由により
58
+ # このメールは送信できませんでした。
59
+ #
60
+ # 以下のメールアドレスへの送信に失敗しました。
61
+ # kijitora@example.jp
62
+ #
63
+ #
64
+ # -------server message
65
+ # 550 5.1.1 unknown user <kijitora@example.jp>
66
+ #
67
+ # -------SMTP command
68
+ # DATA
69
+ #
70
+ # -------original message
71
+ v = dscontents[-1]
72
+
73
+ if cv = e.match(/\A([^ ]+[@][^ ]+)\z/)
78
74
  # 以下のメールアドレスへの送信に失敗しました。
79
75
  # kijitora@example.jp
80
- #
81
- #
82
- # -------server message
83
- # 550 5.1.1 unknown user <kijitora@example.jp>
84
- #
76
+ if v['recipient']
77
+ # There are multiple recipient addresses in the message body.
78
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
79
+ v = dscontents[-1]
80
+ end
81
+ v['recipient'] = cv[1]
82
+ recipients += 1
83
+
84
+ elsif e =~ /\A[A-Z]{4}/
85
85
  # -------SMTP command
86
86
  # DATA
87
- #
88
- # -------original message
89
- v = dscontents[-1]
90
-
91
- if cv = e.match(/\A([^ ]+[@][^ ]+)\z/)
92
- # 以下のメールアドレスへの送信に失敗しました。
93
- # kijitora@example.jp
94
- if v['recipient']
95
- # There are multiple recipient addresses in the message body.
96
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
97
- v = dscontents[-1]
98
- end
99
- v['recipient'] = cv[1]
100
- recipients += 1
87
+ next if v['command']
88
+ v['command'] = e if markingset['command']
89
+ else
90
+ # Get error message and SMTP command
91
+ if e == StartingOf[:error][0]
92
+ # -------server message
93
+ markingset['diagnosis'] = true
101
94
 
102
- elsif e =~ /\A[A-Z]{4}/
95
+ elsif e == StartingOf[:command][0]
103
96
  # -------SMTP command
104
- # DATA
105
- next if v['command']
106
- v['command'] = e if markingset['command']
97
+ markingset['command'] = true
107
98
  else
108
- # Get error message and SMTP command
109
- if e == StartingOf[:error][0]
110
- # -------server message
111
- markingset['diagnosis'] = true
112
-
113
- elsif e == StartingOf[:command][0]
114
- # -------SMTP command
115
- markingset['command'] = true
116
- else
117
- # 550 5.1.1 unknown user <kijitora@example.jp>
118
- next if e.start_with?('-')
119
- next if v['diagnosis']
120
- v['diagnosis'] = e
121
- end
99
+ # 550 5.1.1 unknown user <kijitora@example.jp>
100
+ next if e.start_with?('-')
101
+ next if v['diagnosis']
102
+ v['diagnosis'] = e
122
103
  end
123
104
  end
124
105
  end
@@ -142,8 +123,7 @@ module Sisimai::Lhost
142
123
  end
143
124
  end
144
125
 
145
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
146
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
126
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
147
127
  end
148
128
 
149
129
  end
@@ -9,11 +9,8 @@ module Sisimai::Lhost
9
9
  require 'sisimai/lhost'
10
10
 
11
11
  Indicators = Sisimai::Lhost.INDICATORS
12
- StartingOf = {
13
- message: ['This message was created automatically by mail delivery software.'],
14
- rfc822: ['Included is a copy of the message header:'],
15
- }.freeze
16
-
12
+ ReBackbone = %r|^Included is a copy of the message header:|.freeze
13
+ StartingOf = { message: ['This message was created automatically by mail delivery software.'] }.freeze
17
14
  ReCommands = [
18
15
  %r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
19
16
  %r/SMTP error from remote (?:mail server|mailer) after end of ([A-Za-z]{4})/,
@@ -106,73 +103,52 @@ module Sisimai::Lhost
106
103
  return nil unless match > 0
107
104
 
108
105
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
109
- hasdivided = mbody.split("\n")
110
- rfc822list = [] # (Array) Each line in message/rfc822 part string
111
- blanklines = 0 # (Integer) The number of blank lines
106
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
107
+ bodyslices = emailsteak[0].split("\n")
112
108
  readcursor = 0 # (Integer) Points the current cursor position
113
109
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
114
110
  localhost0 = '' # (String) Local MTA
115
111
  v = nil
116
112
 
117
- while e = hasdivided.shift do
113
+ while e = bodyslices.shift do
114
+ # Read error messages and delivery status lines from the head of the email
115
+ # to the previous line of the beginning of the original message.
118
116
  if readcursor == 0
119
117
  # Beginning of the bounce message or delivery status part
120
- if e == StartingOf[:message][0]
121
- readcursor |= Indicators[:deliverystatus]
122
- next
123
- end
118
+ readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
119
+ next
124
120
  end
125
-
126
- if (readcursor & Indicators[:'message-rfc822']) == 0
127
- # Beginning of the original message part
128
- if e == StartingOf[:rfc822][0]
129
- readcursor |= Indicators[:'message-rfc822']
130
- next
121
+ next if (readcursor & Indicators[:deliverystatus]) == 0
122
+ next if e.empty?
123
+
124
+ # This message was created automatically by mail delivery software.
125
+ #
126
+ # A message that you sent could not be delivered to one or more of its
127
+ # recipients. This is a permanent error. The following address(es) failed:
128
+ #
129
+ # kijitora@example.jp
130
+ # SMTP error from remote mail server after RCPT TO:<kijitora@example.jp>:
131
+ # host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
132
+ v = dscontents[-1]
133
+
134
+ if cv = e.match(/\A[ \t]*[<]([^ ]+[@][^ ]+)[>]:(.+)\z/)
135
+ # A message that you have sent could not be delivered to one or more
136
+ # recipients. This is a permanent error. The following address failed:
137
+ #
138
+ # <kijitora@example.co.jp>: 550 5.1.1 ...
139
+ if v['recipient']
140
+ # There are multiple recipient addresses in the message body.
141
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
142
+ v = dscontents[-1]
131
143
  end
132
- end
144
+ v['recipient'] = cv[1]
145
+ v['diagnosis'] = cv[2]
146
+ recipients += 1
133
147
 
134
- if readcursor & Indicators[:'message-rfc822'] > 0
135
- # Inside of the original message part
136
- if e.empty?
137
- blanklines += 1
138
- break if blanklines > 1
139
- next
140
- end
141
- rfc822list << e
142
- else
143
- # Error message part
144
- next if (readcursor & Indicators[:deliverystatus]) == 0
148
+ elsif dscontents.size == recipients
149
+ # Error message
145
150
  next if e.empty?
146
-
147
- # This message was created automatically by mail delivery software.
148
- #
149
- # A message that you sent could not be delivered to one or more of its
150
- # recipients. This is a permanent error. The following address(es) failed:
151
- #
152
- # kijitora@example.jp
153
- # SMTP error from remote mail server after RCPT TO:<kijitora@example.jp>:
154
- # host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
155
- v = dscontents[-1]
156
-
157
- if cv = e.match(/\A[ \t]*[<]([^ ]+[@][^ ]+)[>]:(.+)\z/)
158
- # A message that you have sent could not be delivered to one or more
159
- # recipients. This is a permanent error. The following address failed:
160
- #
161
- # <kijitora@example.co.jp>: 550 5.1.1 ...
162
- if v['recipient']
163
- # There are multiple recipient addresses in the message body.
164
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
165
- v = dscontents[-1]
166
- end
167
- v['recipient'] = cv[1]
168
- v['diagnosis'] = cv[2]
169
- recipients += 1
170
-
171
- elsif dscontents.size == recipients
172
- # Error message
173
- next if e.empty?
174
- v['diagnosis'] << e + ' '
175
- end
151
+ v['diagnosis'] << e + ' '
176
152
  end
177
153
  end
178
154
  return nil unless recipients > 0
@@ -235,8 +211,7 @@ module Sisimai::Lhost
235
211
  e.each_key { |a| e[a] ||= '' }
236
212
  end
237
213
 
238
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
239
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
214
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
240
215
  end
241
216
 
242
217
  end