sisimai 5.1.0-java → 5.2.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake-test.yml +1 -1
  3. data/ChangeLog.md +102 -0
  4. data/Makefile +4 -2
  5. data/README-JA.md +23 -16
  6. data/README.md +22 -15
  7. data/lib/sisimai/arf.rb +121 -210
  8. data/lib/sisimai/fact.rb +208 -158
  9. data/lib/sisimai/lda.rb +98 -0
  10. data/lib/sisimai/lhost/activehunter.rb +1 -1
  11. data/lib/sisimai/lhost/amazonses.rb +185 -301
  12. data/lib/sisimai/lhost/apachejames.rb +48 -51
  13. data/lib/sisimai/lhost/biglobe.rb +1 -2
  14. data/lib/sisimai/lhost/courier.rb +10 -8
  15. data/lib/sisimai/lhost/domino.rb +25 -25
  16. data/lib/sisimai/lhost/dragonfly.rb +3 -4
  17. data/lib/sisimai/lhost/einsundeins.rb +3 -4
  18. data/lib/sisimai/lhost/exchange2003.rb +6 -8
  19. data/lib/sisimai/lhost/exchange2007.rb +111 -101
  20. data/lib/sisimai/lhost/exim.rb +232 -242
  21. data/lib/sisimai/lhost/ezweb.rb +43 -51
  22. data/lib/sisimai/lhost/fml.rb +2 -3
  23. data/lib/sisimai/lhost/gmail.rb +32 -28
  24. data/lib/sisimai/lhost/gmx.rb +4 -16
  25. data/lib/sisimai/lhost/googlegroups.rb +9 -8
  26. data/lib/sisimai/lhost/googleworkspace.rb +94 -0
  27. data/lib/sisimai/lhost/imailserver.rb +7 -16
  28. data/lib/sisimai/lhost/interscanmss.rb +1 -1
  29. data/lib/sisimai/lhost/kddi.rb +3 -4
  30. data/lib/sisimai/lhost/mailfoundry.rb +2 -5
  31. data/lib/sisimai/lhost/mailmarshalsmtp.rb +1 -2
  32. data/lib/sisimai/lhost/messagingserver.rb +14 -13
  33. data/lib/sisimai/lhost/mfilter.rb +4 -3
  34. data/lib/sisimai/lhost/notes.rb +2 -4
  35. data/lib/sisimai/lhost/opensmtpd.rb +2 -2
  36. data/lib/sisimai/lhost/postfix.rb +25 -27
  37. data/lib/sisimai/lhost/qmail.rb +130 -106
  38. data/lib/sisimai/lhost/sendmail.rb +19 -18
  39. data/lib/sisimai/lhost/v5sendmail.rb +88 -60
  40. data/lib/sisimai/lhost/verizon.rb +2 -2
  41. data/lib/sisimai/lhost/x1.rb +1 -1
  42. data/lib/sisimai/lhost/x2.rb +1 -2
  43. data/lib/sisimai/lhost/x3.rb +2 -2
  44. data/lib/sisimai/lhost/x6.rb +1 -1
  45. data/lib/sisimai/lhost/zoho.rb +2 -2
  46. data/lib/sisimai/lhost.rb +18 -21
  47. data/lib/sisimai/message.rb +93 -146
  48. data/lib/sisimai/order.rb +21 -77
  49. data/lib/sisimai/reason/authfailure.rb +1 -4
  50. data/lib/sisimai/reason/badreputation.rb +2 -2
  51. data/lib/sisimai/reason/blocked.rb +7 -10
  52. data/lib/sisimai/reason/contenterror.rb +7 -1
  53. data/lib/sisimai/reason/exceedlimit.rb +1 -4
  54. data/lib/sisimai/reason/failedstarttls.rb +42 -0
  55. data/lib/sisimai/reason/filtered.rb +5 -4
  56. data/lib/sisimai/reason/hasmoved.rb +1 -2
  57. data/lib/sisimai/reason/hostunknown.rb +3 -3
  58. data/lib/sisimai/reason/mailboxfull.rb +2 -4
  59. data/lib/sisimai/reason/mailererror.rb +1 -2
  60. data/lib/sisimai/reason/mesgtoobig.rb +2 -4
  61. data/lib/sisimai/reason/norelaying.rb +2 -3
  62. data/lib/sisimai/reason/notaccept.rb +2 -3
  63. data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
  64. data/lib/sisimai/reason/rejected.rb +1 -1
  65. data/lib/sisimai/reason/requireptr.rb +2 -2
  66. data/lib/sisimai/reason/securityerror.rb +1 -3
  67. data/lib/sisimai/reason/spamdetected.rb +6 -8
  68. data/lib/sisimai/reason/speeding.rb +1 -2
  69. data/lib/sisimai/reason/suppressed.rb +36 -0
  70. data/lib/sisimai/reason/suspend.rb +1 -3
  71. data/lib/sisimai/reason/systemerror.rb +5 -0
  72. data/lib/sisimai/reason/toomanyconn.rb +1 -2
  73. data/lib/sisimai/reason/userunknown.rb +1 -1
  74. data/lib/sisimai/reason/virusdetected.rb +5 -6
  75. data/lib/sisimai/reason.rb +77 -73
  76. data/lib/sisimai/rfc1123.rb +152 -0
  77. data/lib/sisimai/rfc1894.rb +102 -62
  78. data/lib/sisimai/rfc2045.rb +2 -1
  79. data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
  80. data/lib/sisimai/rfc3464.rb +222 -343
  81. data/lib/sisimai/rfc3834.rb +1 -1
  82. data/lib/sisimai/rfc5322.rb +7 -17
  83. data/lib/sisimai/rfc791.rb +69 -0
  84. data/lib/sisimai/rhost/aol.rb +36 -0
  85. data/lib/sisimai/rhost/apple.rb +5 -2
  86. data/lib/sisimai/rhost/cox.rb +3 -2
  87. data/lib/sisimai/rhost/facebook.rb +100 -0
  88. data/lib/sisimai/rhost/franceptt.rb +3 -2
  89. data/lib/sisimai/rhost/godaddy.rb +3 -2
  90. data/lib/sisimai/rhost/google.rb +19 -17
  91. data/lib/sisimai/rhost/gsuite.rb +42 -0
  92. data/lib/sisimai/rhost/iua.rb +3 -3
  93. data/lib/sisimai/rhost/kddi.rb +3 -2
  94. data/lib/sisimai/rhost/messagelabs.rb +37 -0
  95. data/lib/sisimai/rhost/microsoft.rb +56 -49
  96. data/lib/sisimai/rhost/mimecast.rb +29 -27
  97. data/lib/sisimai/rhost/nttdocomo.rb +4 -3
  98. data/lib/sisimai/rhost/outlook.rb +36 -0
  99. data/lib/sisimai/rhost/spectrum.rb +3 -2
  100. data/lib/sisimai/rhost/tencent.rb +3 -2
  101. data/lib/sisimai/rhost/yahooinc.rb +4 -3
  102. data/lib/sisimai/rhost.rb +69 -39
  103. data/lib/sisimai/smtp/command.rb +31 -21
  104. data/lib/sisimai/smtp/failure.rb +103 -0
  105. data/lib/sisimai/smtp/reply.rb +29 -25
  106. data/lib/sisimai/smtp/status.rb +36 -19
  107. data/lib/sisimai/smtp/transcript.rb +15 -15
  108. data/lib/sisimai/string.rb +0 -46
  109. data/lib/sisimai/version.rb +1 -1
  110. data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
  111. data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
  112. data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
  113. data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
  114. data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
  115. data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
  116. data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
  117. data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
  118. data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
  119. data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
  120. data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
  121. data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
  122. data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
  123. data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
  124. data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
  125. data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
  126. data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
  127. data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
  128. data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
  129. data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
  130. data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
  131. data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
  132. data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
  133. data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
  134. data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
  135. data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
  136. data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
  137. data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
  138. data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
  139. data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
  140. data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
  141. data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
  142. data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
  143. metadata +73 -56
  144. data/lib/sisimai/lhost/amavis.rb +0 -163
  145. data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
  146. data/lib/sisimai/lhost/aol.rb +0 -125
  147. data/lib/sisimai/lhost/barracuda.rb +0 -92
  148. data/lib/sisimai/lhost/bigfoot.rb +0 -125
  149. data/lib/sisimai/lhost/facebook.rb +0 -188
  150. data/lib/sisimai/lhost/gsuite.rb +0 -194
  151. data/lib/sisimai/lhost/mailru.rb +0 -214
  152. data/lib/sisimai/lhost/mcafee.rb +0 -109
  153. data/lib/sisimai/lhost/messagelabs.rb +0 -120
  154. data/lib/sisimai/lhost/mxlogic.rb +0 -198
  155. data/lib/sisimai/lhost/office365.rb +0 -252
  156. data/lib/sisimai/lhost/outlook.rb +0 -129
  157. data/lib/sisimai/lhost/powermta.rb +0 -118
  158. data/lib/sisimai/lhost/receivingses.rb +0 -126
  159. data/lib/sisimai/lhost/sendgrid.rb +0 -150
  160. data/lib/sisimai/lhost/surfcontrol.rb +0 -105
  161. data/lib/sisimai/lhost/x4.rb +0 -269
  162. data/lib/sisimai/lhost/x5.rb +0 -112
  163. data/lib/sisimai/lhost/yahoo.rb +0 -102
  164. data/lib/sisimai/lhost/yandex.rb +0 -118
  165. data/lib/sisimai/mda.rb +0 -121
  166. data/lib/sisimai/smtp/error.rb +0 -119
  167. /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
  168. /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
  169. /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
  170. /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
  171. /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
  172. /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
  177. /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
  178. /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
  179. /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
  180. /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
  181. /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
  182. /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
  183. /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
  184. /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
  185. /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
  186. /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
  187. /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
  188. /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
  189. /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
  190. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
  191. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
  192. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
@@ -8,37 +8,53 @@ module Sisimai::Lhost
8
8
 
9
9
  Indicators = Sisimai::Lhost.INDICATORS
10
10
  Boundaries = [
11
- 'Original message headers:', # en-US
11
+ "Original Message Headers",
12
+ "Original message headers:", # en-US
12
13
  "tes de message d'origine :", # fr-FR/En-têtes de message d'origine
13
- 'Intestazioni originali del messaggio:', # it-CH
14
+ "Intestazioni originali del messaggio:", # it-CH
15
+ "Ursprungshuvuden:", # sv-SE
14
16
  ].freeze
15
- MarkingsOf = {
17
+ StartingOf = {
18
+ error: [" RESOLVER.", " QUEUE."],
16
19
  message: [
17
- 'Diagnostic information for administrators:', # en-US
18
- 'Informations de diagnostic pour les administrateurs', # fr-FR
19
- 'Informazioni di diagnostica per gli amministratori', # it-CH
20
+ "Error Details",
21
+ "Diagnostic information for administrators:", # en-US
22
+ "Informations de diagnostic pour les administrateurs", # fr-FR
23
+ "Informazioni di diagnostica per gli amministratori", # it-CH
24
+ "Diagnostisk information f", # sv-SE
20
25
  ],
21
- error: [' RESOLVER.', ' QUEUE.'],
22
26
  rhost: [
23
- 'Generating server', # en-US
24
- 'Serveur de g', # fr-FR/Serveur de g�Hn�Hration
25
- 'Server di generazione', # it-CH
27
+ "DSN generated by:",
28
+ "Generating server", # en-US
29
+ "Serveur de g", # fr-FR/Serveur de g�Hn�Hration
30
+ "Server di generazione", # it-CH
31
+ "Genererande server", # sv-SE
26
32
  ]
27
33
  }.freeze
28
34
  NDRSubject = {
29
- 'SMTPSEND.DNS.NonExistentDomain' => 'hostunknown', # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
30
- 'SMTPSEND.DNS.MxLoopback' => 'networkerror', # 554 5.4.4 SMTPSEND.DNS.MxLoopback
31
- 'RESOLVER.ADR.BadPrimary' => 'systemerror', # 550 5.2.0 RESOLVER.ADR.BadPrimary
32
- 'RESOLVER.ADR.RecipNotFound' => 'userunknown', # 550 5.1.1 RESOLVER.ADR.RecipNotFound
33
- 'RESOLVER.ADR.ExRecipNotFound' => 'userunknown', # 550 5.1.1 RESOLVER.ADR.ExRecipNotFound
34
- 'RESOLVER.ADR.RecipLimit' => 'toomanyconn', # 550 5.5.3 RESOLVER.ADR.RecipLimit
35
- 'RESOLVER.ADR.InvalidInSmtp' => 'systemerror', # 550 5.1.0 RESOLVER.ADR.InvalidInSmtp
36
- 'RESOLVER.ADR.Ambiguous' => 'systemerror', # 550 5.1.4 RESOLVER.ADR.Ambiguous, 420 4.2.0 RESOLVER.ADR.Ambiguous
37
- 'RESOLVER.RST.AuthRequired' => 'securityerror', # 550 5.7.1 RESOLVER.RST.AuthRequired
38
- 'RESOLVER.RST.NotAuthorized' => 'rejected', # 550 5.7.1 RESOLVER.RST.NotAuthorized
39
- 'RESOLVER.RST.RecipSizeLimit' => 'mesgtoobig', # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
40
- 'QUEUE.Expired' => 'expired', # 550 4.4.7 QUEUE.Expired
35
+ "SMTPSEND.DNS.NonExistentDomain" => "hostunknown", # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
36
+ "SMTPSEND.DNS.MxLoopback" => "networkerror", # 554 5.4.4 SMTPSEND.DNS.MxLoopback
37
+ "RESOLVER.ADR.BadPrimary" => "systemerror", # 550 5.2.0 RESOLVER.ADR.BadPrimary
38
+ "RESOLVER.ADR.RecipNotFound" => "userunknown", # 550 5.1.1 RESOLVER.ADR.RecipNotFound
39
+ "RESOLVER.ADR.RecipientNotFound" => "userunknown", # 550 5.1.1 RESOLVER.ADR.RecipientNotFound
40
+ "RESOLVER.ADR.ExRecipNotFound" => "userunknown", # 550 5.1.1 RESOLVER.ADR.ExRecipNotFound
41
+ "RESOLVER.ADR.RecipLimit" => "toomanyconn", # 550 5.5.3 RESOLVER.ADR.RecipLimit
42
+ "RESOLVER.ADR.InvalidInSmtp" => "systemerror", # 550 5.1.0 RESOLVER.ADR.InvalidInSmtp
43
+ "RESOLVER.ADR.Ambiguous" => "systemerror", # 550 5.1.4 RESOLVER.ADR.Ambiguous, 420 4.2.0 RESOLVER.ADR.Ambiguous
44
+ "RESOLVER.RST.AuthRequired" => "securityerror", # 550 5.7.1 RESOLVER.RST.AuthRequired
45
+ "RESOLVER.RST.NotAuthorized" => "rejected", # 550 5.7.1 RESOLVER.RST.NotAuthorized
46
+ "RESOLVER.RST.RecipSizeLimit" => "exceedlimit", # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
47
+ "QUEUE.Expired" => "expired", # 550 4.4.7 QUEUE.Expired
41
48
  }.freeze
49
+ MailSender = ["postmaster@outlook.com", ".onmicrosoft.com"].freeze
50
+ EmailTitle = [
51
+ # Subject: Content-Language:
52
+ "Undeliverable", # en-US
53
+ "Non_remis_", # fr-FR
54
+ "Non remis ", # fr-FR
55
+ "Non recapitabile", # it-CH
56
+ "Olevererbart", # sv-SE
57
+ ].freeze
42
58
 
43
59
  # @abstract Decodes the bounce message from Microsoft Exchange Server 2007
44
60
  # @param [Hash] mhead Message headers of a bounce email
@@ -46,118 +62,112 @@ module Sisimai::Lhost
46
62
  # @return [Hash] Bounce data list and message/rfc822 part
47
63
  # @return [Nil] it failed to decode or the arguments are missing
48
64
  def inquire(mhead, mbody)
49
- # Content-Language: en-US, fr-FR
50
- match = nil
51
- match ||= 1 if mhead['subject'].start_with?('Undeliverable')
52
- match ||= 1 if mhead['subject'].start_with?('Non_remis_')
53
- match ||= 1 if mhead['subject'].start_with?('Non recapitabile')
54
- return nil unless match
55
- return nil unless mhead['content-language']
56
-
57
- match += 1 if mhead['content-language'].size == 2 # JP
58
- match += 1 if mhead['content-language'].size == 5 # ja-JP
59
- return nil unless match > 1
60
-
61
- # These headers exist only a bounce mail from Office365
62
- return nil if mhead['x-ms-exchange-crosstenant-originalarrivaltime']
63
- return nil if mhead['x-ms-exchange-crosstenant-fromentityheader']
65
+ proceedsto = 0
66
+ proceedsto += 1 if EmailTitle.any? { |a| mhead["subject"].include?(a) }
67
+ proceedsto += 1 if MailSender.any? { |a| mhead["from"].include?(a) }
68
+ proceedsto += 1 if mhead["content-language"]
69
+ return nil if proceedsto < 2
64
70
 
71
+ require "sisimai/rfc1123"
72
+ require "sisimai/smtp/reply"
73
+ require "sisimai/smtp/status"
65
74
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
66
75
  emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
67
76
  bodyslices = emailparts[0].split("\n")
68
77
  readcursor = 0 # (Integer) Points the current cursor position
69
78
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
70
- connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
71
- connheader = {
72
- 'rhost' => '', # The value of Reporting-MTA header or "Generating Server:"
73
- }
74
- v = nil
75
79
 
76
80
  while e = bodyslices.shift do
77
81
  # Read error messages and delivery status lines from the head of the email to the previous
78
82
  # line of the beginning of the original message.
79
83
  if readcursor == 0
80
84
  # Beginning of the bounce message or delivery status part
81
- readcursor |= Indicators[:deliverystatus] if MarkingsOf[:message].any? { |a| e.start_with?(a) }
85
+ readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| e.start_with?(a) }
82
86
  next
83
87
  end
84
88
  next if (readcursor & Indicators[:deliverystatus]) == 0
89
+ next if e == ""
85
90
 
86
- if connvalues == connheader.keys.size
87
- # Diagnostic information for administrators:
88
- #
89
- # Generating server: mta2.neko.example.jp
90
- #
91
- # kijitora@example.jp
92
- # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
93
- #
94
- # Original message headers:
95
- v = dscontents[-1]
91
+ # Diagnostic information for administrators:
92
+ #
93
+ # Generating server: mta2.neko.example.jp
94
+ #
95
+ # kijitora@example.jp
96
+ # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
97
+ #
98
+ # Original message headers:
99
+ v = dscontents[-1]
96
100
 
97
- if e.include?('@') && e.include?(' ') == false
98
- # kijitora@example.jp
99
- if v['recipient']
100
- # There are multiple recipient addresses in the message body.
101
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
102
- v = dscontents[-1]
103
- end
104
- v['recipient'] = Sisimai::Address.s3s4(e)
105
- v['diagnosis'] = ''
106
- recipients += 1
101
+ if e.include?('@') && e.include?(' ') == false
102
+ # kijitora@example.jp
103
+ if v["recipient"] != ""
104
+ # There are multiple recipient addresses in the message body.
105
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
106
+ v = dscontents[-1]
107
+ end
108
+ v["recipient"] = Sisimai::Address.s3s4(e)
109
+ v["diagnosis"] = ""
110
+ recipients += 1
107
111
 
112
+ else
113
+ # Try to pick the remote hostname and status code, reply code from the error message
114
+ if StartingOf[:rhost].any? { |a| e.start_with?(a) }
115
+ # Generating server: SG2APC01HT234.mail.protection.outlook.com
116
+ # DSN generated by: NEKONYAAN0022.apcprd01.prod.exchangelabs.com
117
+ cv = Sisimai::RFC1123.find(e)
118
+ v["rhost"] = cv if Sisimai::RFC1123.is_internethost(cv)
108
119
  else
109
- # Continued line of error messages
110
- cr = Sisimai::SMTP::Reply.find(e)
111
- cs = Sisimai::SMTP::Status.find(e)
112
- if cr || cs
113
- # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
114
- # #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
120
+ # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
121
+ # #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
122
+ cr = Sisimai::SMTP::Reply.find(e) || ""
123
+ cs = Sisimai::SMTP::Status.find(e) || ""
124
+ if cr != "" || cs != "" || e.include?("Remote Server ")
115
125
  # Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
116
126
  # 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
117
- v['replycode'] = cr || ''
118
- v['status'] = cs || ''
119
- v['diagnosis'] = e
120
- else
121
- # Continued line of error messages
122
- next if v['diagnosis'].to_s.empty?
123
- next unless v['diagnosis'].end_with?('=')
124
- v['diagnosis'] = v['diagnosis'].chomp('=')
125
- v['diagnosis'] << e
127
+ v["replycode"] = cr
128
+ v["status"] = cs
129
+ v["diagnosis"] << e << " "
126
130
  end
127
131
  end
128
- else
129
- # Diagnostic information for administrators:
130
- #
131
- # Generating server: mta22.neko.example.org
132
- next unless MarkingsOf[:rhost].any? { |a| e.start_with?(a) }
133
- next unless connheader['rhost'].empty?
134
- connheader['rhost'] = e[e.index(':') + 1, e.size]
135
- connvalues += 1
136
132
  end
137
133
  end
134
+
135
+ while recipients == 0
136
+ # Try to pick the recipient address from the following formatted bounce message:
137
+ # Original Message Details
138
+ # Created Date: 4/29/2017 11:23:34 PM
139
+ # Sender Address: neko@example.com
140
+ # Recipient Address: kijitora-nyaan@neko.kyoto.example.jp
141
+ # Subject: Nyaan?
142
+ p1 = emailparts[0].index("Original Message Details"); break if p1.nil?
143
+ p2 = emailparts[0].index("\nRecipient Address: "); break if p2.nil?
144
+ p3 = emailparts[0].index("\n", p2 + 20); break if p3.nil?
145
+ cv = Sisimai::Address.s3s4(emailparts[0][p2 + 20, p3 - p2 - 20])
146
+
147
+ break unless Sisimai::Address.is_emailaddress(cv)
148
+ dscontents[0]["recipient"] = cv
149
+ recipients += 1
150
+ end
138
151
  return nil unless recipients > 0
139
152
 
140
153
  dscontents.each do |e|
141
- p = -1
142
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
143
- MarkingsOf[:error].each do |q|
144
- # Find an error message, get an error code.
145
- p = e['diagnosis'].index(q) || -1
146
- break if p > -1
154
+ # Tidy up the error message in $e->{'diagnosis'}, Try to detect the bounce reason.
155
+ e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
156
+
157
+ p0 = -1; StartingOf[:error].each do |r|
158
+ # Try to find the NDR subject string such as "RESOLVER.ADR.RecipientNotFound" from the
159
+ # error message
160
+ p0 = e["diagnosis"].index(r); break if p0.nil? == false
147
161
  end
148
- next unless p > 0
162
+ next if p0.nil?
149
163
 
150
164
  # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
151
- f = e['diagnosis'][p + 1, e['diagnosis'].index(';') - p - 1]
152
- NDRSubject.each_key do |r|
153
- # Try to match with error subject strings
154
- next unless f == r
155
- e['reason'] = NDRSubject[r]
156
- break
157
- end
165
+ cv = e["diagnosis"][p0 + 1, e["diagnosis"].index(";") - p0 - 1]
166
+ next if NDRSubject.has_key?(cv) == false
167
+ e["reason"] = NDRSubject[cv]
158
168
  end
159
169
 
160
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
170
+ return { "ds" => dscontents, "rfc822" => emailparts[1] }
161
171
  end
162
172
  def description; return 'Microsoft Exchange Server 2007'; end
163
173
  end