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,6 +8,7 @@ module Sisimai::Lhost
8
8
  require 'sisimai/lhost'
9
9
 
10
10
  Indicators = Sisimai::Lhost.INDICATORS
11
+ ReBackbone = %r/^[ ]+-----[ ](?:Unsent[ ]message[ ]follows|No[ ]message[ ]was[ ]collected)[ ]-----/.freeze
11
12
  StartingOf = { message: ['----- Transcript of session follows -----'] }
12
13
  MarkingsOf = {
13
14
  # Error text regular expressions which defined in src/savemail.c
@@ -27,11 +28,6 @@ module Sisimai::Lhost
27
28
  # savemail.c:498| putline(buf, fp, m);
28
29
  # savemail.c:499| (void) fclose(xfile);
29
30
  error: %r/\A[.]+ while talking to .+[:]\z/,
30
- rfc822: %r{\A[ \t]+-----[ ](?:
31
- Unsent[ ]message[ ]follows
32
- |No[ ]message[ ]was[ ]collected
33
- )[ ]-----
34
- }x,
35
31
  }.freeze
36
32
 
37
33
  def description; return 'Sendmail version 5'; end
@@ -53,10 +49,11 @@ module Sisimai::Lhost
53
49
  # :from => %r/\AMail Delivery Subsystem/,
54
50
  return nil unless mhead['subject'] =~ /\AReturned mail: [A-Z]/
55
51
 
52
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
53
+ return nil if emailsteak[1].empty?
54
+
56
55
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
57
- hasdivided = mbody.split("\n")
58
- rfc822list = [] # (Array) Each line in message/rfc822 part string
59
- blanklines = 0 # (Integer) The number of blank lines
56
+ bodyslices = emailsteak[0].split("\n")
60
57
  readcursor = 0 # (Integer) Points the current cursor position
61
58
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
62
59
  responding = [] # (Array) Responses from remote server
@@ -65,96 +62,70 @@ module Sisimai::Lhost
65
62
  errorindex = -1 # (Integer)
66
63
  v = nil
67
64
 
68
- while e = hasdivided.shift do
65
+ while e = bodyslices.shift do
66
+ # Read error messages and delivery status lines from the head of the email
67
+ # to the previous line of the beginning of the original message.
69
68
  if readcursor == 0
70
69
  # Beginning of the bounce message or delivery status part
71
- if e.include?(StartingOf[:message][0])
72
- readcursor |= Indicators[:deliverystatus]
73
- next
74
- end
70
+ readcursor |= Indicators[:deliverystatus] if e.include?(StartingOf[:message][0])
71
+ next
75
72
  end
76
-
77
- if (readcursor & Indicators[:'message-rfc822']) == 0
78
- # Beginning of the original message part
79
- if e =~ MarkingsOf[:rfc822]
80
- readcursor |= Indicators[:'message-rfc822']
81
- next
73
+ next if (readcursor & Indicators[:deliverystatus]) == 0
74
+ next if e.empty?
75
+
76
+ # ----- Transcript of session follows -----
77
+ # While talking to smtp.example.com:
78
+ # >>> RCPT To:<kijitora@example.org>
79
+ # <<< 550 <kijitora@example.org>, User Unknown
80
+ # 550 <kijitora@example.org>... User unknown
81
+ # 421 example.org (smtp)... Deferred: Connection timed out during user open with example.org
82
+ v = dscontents[-1]
83
+
84
+ if cv = e.match(/\A\d{3}[ ]+[<]([^ ]+[@][^ ]+)[>][.]{3}[ ]*(.+)\z/)
85
+ # 550 <kijitora@example.org>... User unknown
86
+ if v['recipient']
87
+ # There are multiple recipient addresses in the message body.
88
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
89
+ v = dscontents[-1]
82
90
  end
83
- end
91
+ v['recipient'] = cv[1]
92
+ v['diagnosis'] = cv[2]
84
93
 
85
- if readcursor & Indicators[:'message-rfc822'] > 0
86
- # Inside of the original message part
87
- if e.empty?
88
- blanklines += 1
89
- break if blanklines > 1
94
+ # Concatenate the response of the server and error message
95
+ v['diagnosis'] << ': ' << responding[recipients] if responding[recipients]
96
+ recipients += 1
97
+
98
+ elsif cv = e.match(/\A[>]{3}[ ]*([A-Z]{4})[ ]*/)
99
+ # >>> RCPT To:<kijitora@example.org>
100
+ commandset[recipients] = cv[1]
101
+
102
+ elsif cv = e.match(/\A[<]{3}[ ]+(.+)\z/)
103
+ # <<< Response
104
+ # <<< 501 <shironeko@example.co.jp>... no access from mail server [192.0.2.55] which is an open relay.
105
+ # <<< 550 Requested User Mailbox not found. No such user here.
106
+ responding[recipients] = cv[1]
107
+ else
108
+ # Detect SMTP session error or connection error
109
+ next if v['sessionerr']
110
+
111
+ if e =~ MarkingsOf[:error]
112
+ # ----- Transcript of session follows -----
113
+ # ... while talking to mta.example.org.:
114
+ v['sessionerr'] = true
90
115
  next
91
116
  end
92
- rfc822list << e
93
- else
94
- # Error message part
95
- next if (readcursor & Indicators[:deliverystatus]) == 0
96
- next if e.empty?
97
117
 
98
- # ----- Transcript of session follows -----
99
- # While talking to smtp.example.com:
100
- # >>> RCPT To:<kijitora@example.org>
101
- # <<< 550 <kijitora@example.org>, User Unknown
102
- # 550 <kijitora@example.org>... User unknown
103
- # 421 example.org (smtp)... Deferred: Connection timed out during user open with example.org
104
- v = dscontents[-1]
105
-
106
- if cv = e.match(/\A\d{3}[ ]+[<]([^ ]+[@][^ ]+)[>][.]{3}[ ]*(.+)\z/)
107
- # 550 <kijitora@example.org>... User unknown
108
- if v['recipient']
109
- # There are multiple recipient addresses in the message body.
110
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
111
- v = dscontents[-1]
112
- end
113
- v['recipient'] = cv[1]
114
- v['diagnosis'] = cv[2]
115
-
116
- # Concatenate the response of the server and error message
117
- v['diagnosis'] << ': ' << responding[recipients] if responding[recipients]
118
- recipients += 1
119
-
120
- elsif cv = e.match(/\A[>]{3}[ ]*([A-Z]{4})[ ]*/)
121
- # >>> RCPT To:<kijitora@example.org>
122
- commandset[recipients] = cv[1]
123
-
124
- elsif cv = e.match(/\A[<]{3}[ ]+(.+)\z/)
125
- # <<< Response
126
- # <<< 501 <shironeko@example.co.jp>... no access from mail server [192.0.2.55] which is an open relay.
127
- # <<< 550 Requested User Mailbox not found. No such user here.
128
- responding[recipients] = cv[1]
129
- else
130
- # Detect SMTP session error or connection error
131
- next if v['sessionerr']
132
-
133
- if e =~ MarkingsOf[:error]
134
- # ----- Transcript of session follows -----
135
- # ... while talking to mta.example.org.:
136
- v['sessionerr'] = true
137
- next
138
- end
139
-
140
- if cv = e.match(/\A\d{3}[ ]+.+[.]{3}[ \t]*(.+)\z/)
141
- # 421 example.org (smtp)... Deferred: Connection timed out during user open with example.org
142
- anotherset['diagnosis'] = cv[1]
143
- end
118
+ if cv = e.match(/\A\d{3}[ ]+.+[.]{3}[ \t]*(.+)\z/)
119
+ # 421 example.org (smtp)... Deferred: Connection timed out during user open with example.org
120
+ anotherset['diagnosis'] = cv[1]
144
121
  end
145
122
  end
146
123
  end
147
- return nil if (readcursor & Indicators[:'message-rfc822']) == 0
148
-
149
- if recipients == 0
150
- # Get the recipient address from the original message
151
- rfc822list.each do |e|
152
- # The value of To: header in the original message
153
- next unless cv = e.match(/^To: (.+)$/m)
154
- dscontents[0]['recipient'] = Sisimai::Address.s3s4(cv[1])
155
- recipients = 1
156
- break
157
- end
124
+
125
+ if recipients == 0 && cv = emailsteak[1].match(/^To:[ ]*(.+)$/)
126
+ # Get the recipient address from "To:" header at the original message
127
+ dscontents[0]['recipient'] = Sisimai::Address.s3s4(cv[1])
128
+ recipients = 1
158
129
  end
159
130
  return nil unless recipients > 0
160
131
 
@@ -183,8 +154,7 @@ module Sisimai::Lhost
183
154
  e.each_key { |a| e[a] ||= '' }
184
155
  end
185
156
 
186
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
187
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
157
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
188
158
  end
189
159
 
190
160
  end
@@ -36,9 +36,7 @@ module Sisimai::Lhost
36
36
  return nil if match < 0
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
+ rebackbone = /^__BOUNDARY_STRING_HERE__/
42
40
  readcursor = 0 # (Integer) Points the current cursor position
43
41
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
44
42
  senderaddr = '' # (String) Sender address in the message body
@@ -51,157 +49,111 @@ module Sisimai::Lhost
51
49
 
52
50
  if match == 1
53
51
  # vtext.com
54
- markingsof = {
55
- message: %r/\AError:[ \t]/,
56
- rfc822: %r/\A__BOUNDARY_STRING_HERE__\z/,
57
- }
52
+ markingsof = { message: %r/\AError:[ \t]/ }
58
53
  messagesof = {
59
54
  # The attempted recipient address does not exist.
60
55
  'userunknown' => ['550 - Requested action not taken: no such user here'],
61
56
  }
62
57
  boundary00 = Sisimai::MIME.boundary(mhead['content-type']) || ''
63
- markingsof[:rfc822] = Regexp.new('\A' << Regexp.escape('--' << boundary00 << '--') << '\z') unless boundary00.empty?
58
+ rebackbone = Regexp.new('^' << Regexp.escape('--' << boundary00 << '--')) unless boundary00.empty?
59
+ emailsteak = Sisimai::RFC5322.fillet(mbody, rebackbone)
60
+ bodyslices = emailsteak[0].split("\n")
64
61
 
65
- while e = hasdivided.shift do
62
+ while e = bodyslices.shift do
63
+ # Read error messages and delivery status lines from the head of the email
64
+ # to the previous line of the beginning of the original message.
66
65
  if readcursor == 0
67
66
  # Beginning of the bounce message or delivery status part
68
- if e =~ markingsof[:message]
69
- readcursor |= Indicators[:deliverystatus]
70
- next
71
- end
67
+ readcursor |= Indicators[:deliverystatus] if e =~ markingsof[:message]
68
+ next
72
69
  end
73
-
74
- if (readcursor & Indicators[:'message-rfc822']) == 0
75
- # Beginning of the original message part
76
- if e =~ markingsof[:rfc822]
77
- readcursor |= Indicators[:'message-rfc822']
78
- next
70
+ next if (readcursor & Indicators[:deliverystatus]) == 0
71
+ next if e.empty?
72
+
73
+ # Message details:
74
+ # Subject: Test message
75
+ # Sent date: Wed Jun 12 02:21:53 GMT 2013
76
+ # MAIL FROM: *******@hg.example.com
77
+ # RCPT TO: *****@vtext.com
78
+ v = dscontents[-1]
79
+ if cv = e.match(/\A[ \t]+RCPT TO: (.*)\z/)
80
+ if v['recipient']
81
+ # There are multiple recipient addresses in the message body.
82
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
83
+ v = dscontents[-1]
79
84
  end
80
- end
81
85
 
82
- if readcursor & Indicators[:'message-rfc822'] > 0
83
- # Inside of the original message part
84
- if e.empty?
85
- blanklines += 1
86
- break if blanklines > 1
87
- next
88
- end
89
- rfc822list << e
90
- else
91
- # Error message part
92
- next if (readcursor & Indicators[:deliverystatus]) == 0
93
- next if e.empty?
86
+ v['recipient'] = cv[1]
87
+ recipients += 1
88
+ next
94
89
 
95
- # Message details:
96
- # Subject: Test message
97
- # Sent date: Wed Jun 12 02:21:53 GMT 2013
90
+ elsif cv = e.match(/\A[ \t]+MAIL FROM:[ \t](.+)\z/)
98
91
  # MAIL FROM: *******@hg.example.com
99
- # RCPT TO: *****@vtext.com
100
- v = dscontents[-1]
101
- if cv = e.match(/\A[ \t]+RCPT TO: (.*)\z/)
102
- if v['recipient']
103
- # There are multiple recipient addresses in the message body.
104
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
105
- v = dscontents[-1]
106
- end
107
-
108
- v['recipient'] = cv[1]
109
- recipients += 1
110
- next
111
-
112
- elsif cv = e.match(/\A[ \t]+MAIL FROM:[ \t](.+)\z/)
113
- # MAIL FROM: *******@hg.example.com
114
- senderaddr = cv[1] if senderaddr.empty?
115
-
116
- elsif cv = e.match(/\A[ \t]+Subject:[ \t](.+)\z/)
117
- # Subject:
118
- subjecttxt = cv[1] if subjecttxt.empty?
119
- else
120
- # 550 - Requested action not taken: no such user here
121
- v['diagnosis'] = e if e =~ /\A(\d{3})[ \t][-][ \t](.*)\z/
122
- end
92
+ senderaddr = cv[1] if senderaddr.empty?
93
+
94
+ elsif cv = e.match(/\A[ \t]+Subject:[ \t](.+)\z/)
95
+ # Subject:
96
+ subjecttxt = cv[1] if subjecttxt.empty?
97
+ else
98
+ # 550 - Requested action not taken: no such user here
99
+ v['diagnosis'] = e if e =~ /\A(\d{3})[ \t][-][ \t](.*)\z/
123
100
  end
124
101
  end
125
-
126
102
  else
127
103
  # vzwpix.com
128
104
  startingof = { message: ['Message could not be delivered to mobile'] }
129
- markingsof = { rfc822: %r/\A__BOUNDARY_STRING_HERE__\z/ }
130
105
  messagesof = { 'userunknown' => ['No valid recipients for this MM'] }
131
106
  boundary00 = Sisimai::MIME.boundary(mhead['content-type'])
132
- markingsof[:rfc822] = Regexp.new('\A' << Regexp.escape('--' << boundary00 << '--') << '\z') unless boundary00.empty?
107
+ rebackbone = Regexp.new('^' << Regexp.escape('--' << boundary00 << '--')) unless boundary00.empty?
108
+ emailsteak = Sisimai::RFC5322.fillet(mbody, rebackbone)
109
+ bodyslices = emailsteak[0].split("\n")
133
110
 
134
- while e = hasdivided.shift do
111
+ while e = bodyslices.shift do
112
+ # Read error messages and delivery status lines from the head of the email
113
+ # to the previous line of the beginning of the original message.
135
114
  if readcursor == 0
136
115
  # Beginning of the bounce message or delivery status part
137
- if e.start_with?(startingof[:message][0])
138
- readcursor |= Indicators[:deliverystatus]
139
- next
140
- end
116
+ readcursor |= Indicators[:deliverystatus] if e.start_with?(startingof[:message][0])
117
+ next
141
118
  end
142
-
143
- if (readcursor & Indicators[:'message-rfc822']) == 0
144
- # Beginning of the original message part
145
- if e =~ markingsof[:rfc822]
146
- readcursor |= Indicators[:'message-rfc822']
147
- next
119
+ next if (readcursor & Indicators[:deliverystatus]) == 0
120
+ next if e.empty?
121
+
122
+ # Original Message:
123
+ # From: kijitora <kijitora@example.jp>
124
+ # To: 0000000000@vzwpix.com
125
+ # Subject: test for bounce
126
+ # Date: Wed, 20 Jun 2013 10:29:52 +0000
127
+ v = dscontents[-1]
128
+ if cv = e.match(/\ATo:[ \t]+(.*)\z/)
129
+ if v['recipient']
130
+ # There are multiple recipient addresses in the message body.
131
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
132
+ v = dscontents[-1]
148
133
  end
149
- end
150
-
151
- if readcursor & Indicators[:'message-rfc822'] > 0
152
- # Inside of the original message part
153
- if e.empty?
154
- blanklines += 1
155
- break if blanklines > 1
156
- next
157
- end
158
- rfc822list << e
159
- else
160
- # Error message part
161
- next if (readcursor & Indicators[:deliverystatus]) == 0
162
- next if e.empty?
134
+ v['recipient'] = Sisimai::Address.s3s4(cv[1])
135
+ recipients += 1
136
+ next
163
137
 
164
- # Original Message:
138
+ elsif cv = e.match(/\AFrom:[ \t](.+)\z/)
165
139
  # From: kijitora <kijitora@example.jp>
166
- # To: 0000000000@vzwpix.com
167
- # Subject: test for bounce
168
- # Date: Wed, 20 Jun 2013 10:29:52 +0000
169
- v = dscontents[-1]
170
- if cv = e.match(/\ATo:[ \t]+(.*)\z/)
171
- if v['recipient']
172
- # There are multiple recipient addresses in the message body.
173
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
174
- v = dscontents[-1]
175
- end
176
- v['recipient'] = Sisimai::Address.s3s4(cv[1])
177
- recipients += 1
178
- next
179
-
180
- elsif cv = e.match(/\AFrom:[ \t](.+)\z/)
181
- # From: kijitora <kijitora@example.jp>
182
- senderaddr = Sisimai::Address.s3s4(cv[1]) if senderaddr.empty?
183
-
184
- elsif cv = e.match(/\ASubject:[ \t](.+)\z/)
185
- # Subject:
186
- subjecttxt = cv[1] if subjecttxt.empty?
187
- else
188
- # Message could not be delivered to mobile.
189
- # Error: No valid recipients for this MM
190
- v['diagnosis'] = e if e =~ /\AError:[ \t]+(.+)\z/
191
- end
140
+ senderaddr = Sisimai::Address.s3s4(cv[1]) if senderaddr.empty?
141
+
142
+ elsif cv = e.match(/\ASubject:[ \t](.+)\z/)
143
+ # Subject:
144
+ subjecttxt = cv[1] if subjecttxt.empty?
145
+ else
146
+ # Message could not be delivered to mobile.
147
+ # Error: No valid recipients for this MM
148
+ v['diagnosis'] = e if e =~ /\AError:[ \t]+(.+)\z/
192
149
  end
193
150
  end
194
151
  end
195
152
  return nil unless recipients > 0
196
153
 
197
- if rfc822list.none? { |a| a.start_with?('From: ') }
198
- # Set the value of "MAIL FROM:" or "From:"
199
- rfc822list << ('From: ' << senderaddr)
200
-
201
- elsif rfc822list.none? { |a| a.start_with?('Subject: ') }
202
- # Set the value of "Subject:"
203
- rfc822list << ('Subject: ' << subjecttxt)
204
- end
154
+ # Set the value of "MAIL FROM:" and "From:"
155
+ emailsteak[1] << ('From: ' << senderaddr << "\n") unless emailsteak[1] =~ /^From: /
156
+ emailsteak[1] << ('Subject: ' << subjecttxt << "\n") unless emailsteak[1] =~ /^Subject: /
205
157
 
206
158
  dscontents.each do |e|
207
159
  e['agent'] = self.smtpagent
@@ -215,8 +167,7 @@ module Sisimai::Lhost
215
167
  end
216
168
  end
217
169
 
218
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
219
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
170
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
220
171
  end
221
172
 
222
173
  end
@@ -7,10 +7,8 @@ module Sisimai::Lhost
7
7
  require 'sisimai/lhost'
8
8
 
9
9
  Indicators = Sisimai::Lhost.INDICATORS
10
- MarkingsOf = {
11
- message: %r/\AThe original message was received at (.+)\z/,
12
- rfc822: %r/\AReceived: from \d+[.]\d+[.]\d+[.]\d/,
13
- }.freeze
10
+ ReBackbone = %r|^Received: from \d+[.]\d+[.]\d+[.]\d|.freeze
11
+ MarkingsOf = { message: %r/\AThe original message was received at (.+)\z/ }.freeze
14
12
 
15
13
  def description; return 'Unknown MTA #1'; end
16
14
  def smtpagent; return Sisimai::Lhost.smtpagent(self); end
@@ -32,67 +30,46 @@ module Sisimai::Lhost
32
30
  return nil unless mhead['from'].start_with?('"Mail Deliver System" ')
33
31
 
34
32
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
35
- hasdivided = mbody.split("\n")
36
- rfc822list = [] # (Array) Each line in message/rfc822 part string
37
- blanklines = 0 # (Integer) The number of blank lines
33
+ emailsteak = Sisimai::RFC5322.fillet(mbody, ReBackbone)
34
+ bodyslices = emailsteak[0].split("\n")
38
35
  readcursor = 0 # (Integer) Points the current cursor position
39
36
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
40
37
  datestring = '' # (String) Date string
41
38
  v = nil
42
39
 
43
- while e = hasdivided.shift do
40
+ while e = bodyslices.shift do
41
+ # Read error messages and delivery status lines from the head of the email
42
+ # to the previous line of the beginning of the original message.
44
43
  if readcursor == 0
45
44
  # Beginning of the bounce message or delivery status part
46
- if e =~ MarkingsOf[:message]
47
- readcursor |= Indicators[:deliverystatus]
48
- next
49
- end
45
+ readcursor |= Indicators[:deliverystatus] if e =~ MarkingsOf[:message]
46
+ next
50
47
  end
48
+ next if (readcursor & Indicators[:deliverystatus]) == 0
49
+ next if e.empty?
51
50
 
52
- if (readcursor & Indicators[:'message-rfc822']) == 0
53
- # Beginning of the original message part
54
- if e =~ MarkingsOf[:rfc822]
55
- readcursor |= Indicators[:'message-rfc822']
56
- next
57
- end
58
- end
51
+ # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
52
+ # from shironeko@example.jp
53
+ #
54
+ # ---The following addresses had delivery errors---
55
+ #
56
+ # kijitora@example.co.jp [User unknown]
57
+ v = dscontents[-1]
59
58
 
60
- if readcursor & Indicators[:'message-rfc822'] > 0
61
- # Inside of the original message part
62
- if e.empty?
63
- blanklines += 1
64
- break if blanklines > 1
65
- next
59
+ if cv = e.match(/\A([^ ]+?[@][^ ]+?)[ ]+\[(.+)\]\z/)
60
+ # kijitora@example.co.jp [User unknown]
61
+ if v['recipient']
62
+ # There are multiple recipient addresses in the message body.
63
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
64
+ v = dscontents[-1]
66
65
  end
67
- rfc822list << e
68
- else
69
- # Error message part
70
- next if (readcursor & Indicators[:deliverystatus]) == 0
71
- next if e.empty?
66
+ v['recipient'] = cv[1]
67
+ v['diagnosis'] = cv[2]
68
+ recipients += 1
72
69
 
70
+ elsif cv = e.match(MarkingsOf[:message])
73
71
  # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
74
- # from shironeko@example.jp
75
- #
76
- # ---The following addresses had delivery errors---
77
- #
78
- # kijitora@example.co.jp [User unknown]
79
- v = dscontents[-1]
80
-
81
- if cv = e.match(/\A([^ ]+?[@][^ ]+?)[ ]+\[(.+)\]\z/)
82
- # kijitora@example.co.jp [User unknown]
83
- if v['recipient']
84
- # There are multiple recipient addresses in the message body.
85
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
86
- v = dscontents[-1]
87
- end
88
- v['recipient'] = cv[1]
89
- v['diagnosis'] = cv[2]
90
- recipients += 1
91
-
92
- elsif cv = e.match(MarkingsOf[:message])
93
- # The original message was received at Thu, 29 Apr 2010 23:34:45 +0900 (JST)
94
- datestring = cv[1]
95
- end
72
+ datestring = cv[1]
96
73
  end
97
74
  end
98
75
  return nil unless recipients > 0
@@ -104,8 +81,7 @@ module Sisimai::Lhost
104
81
  e.each_key { |a| e[a] ||= '' }
105
82
  end
106
83
 
107
- rfc822part = Sisimai::RFC5322.weedout(rfc822list)
108
- return { 'ds' => dscontents, 'rfc822' => rfc822part }
84
+ return { 'ds' => dscontents, 'rfc822' => emailsteak[1] }
109
85
  end
110
86
 
111
87
  end