sisimai 5.0.3-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 (258) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codecovio.yml +3 -1
  3. data/.github/workflows/rake-test.yml +7 -3
  4. data/ChangeLog.md +136 -0
  5. data/Makefile +4 -2
  6. data/README-JA.md +32 -22
  7. data/README.md +31 -21
  8. data/lib/sisimai/arf.rb +124 -213
  9. data/lib/sisimai/fact/json.rb +2 -2
  10. data/lib/sisimai/fact/yaml.rb +2 -2
  11. data/lib/sisimai/fact.rb +208 -173
  12. data/lib/sisimai/lda.rb +98 -0
  13. data/lib/sisimai/lhost/activehunter.rb +5 -4
  14. data/lib/sisimai/lhost/amazonses.rb +189 -305
  15. data/lib/sisimai/lhost/apachejames.rb +52 -55
  16. data/lib/sisimai/lhost/biglobe.rb +5 -6
  17. data/lib/sisimai/lhost/courier.rb +14 -12
  18. data/lib/sisimai/lhost/domino.rb +29 -29
  19. data/lib/sisimai/lhost/dragonfly.rb +113 -0
  20. data/lib/sisimai/lhost/einsundeins.rb +7 -8
  21. data/lib/sisimai/lhost/exchange2003.rb +10 -11
  22. data/lib/sisimai/lhost/exchange2007.rb +115 -104
  23. data/lib/sisimai/lhost/exim.rb +236 -246
  24. data/lib/sisimai/lhost/ezweb.rb +47 -55
  25. data/lib/sisimai/lhost/fml.rb +6 -7
  26. data/lib/sisimai/lhost/gmail.rb +36 -32
  27. data/lib/sisimai/lhost/gmx.rb +8 -20
  28. data/lib/sisimai/lhost/googlegroups.rb +13 -12
  29. data/lib/sisimai/lhost/googleworkspace.rb +94 -0
  30. data/lib/sisimai/lhost/imailserver.rb +11 -19
  31. data/lib/sisimai/lhost/interscanmss.rb +6 -5
  32. data/lib/sisimai/lhost/kddi.rb +7 -8
  33. data/lib/sisimai/lhost/mailfoundry.rb +6 -9
  34. data/lib/sisimai/lhost/mailmarshalsmtp.rb +6 -6
  35. data/lib/sisimai/lhost/messagingserver.rb +19 -17
  36. data/lib/sisimai/lhost/mfilter.rb +8 -7
  37. data/lib/sisimai/lhost/notes.rb +6 -8
  38. data/lib/sisimai/lhost/opensmtpd.rb +11 -9
  39. data/lib/sisimai/lhost/postfix.rb +29 -31
  40. data/lib/sisimai/lhost/qmail.rb +136 -112
  41. data/lib/sisimai/lhost/sendmail.rb +23 -22
  42. data/lib/sisimai/lhost/v5sendmail.rb +93 -64
  43. data/lib/sisimai/lhost/verizon.rb +6 -6
  44. data/lib/sisimai/lhost/x1.rb +4 -4
  45. data/lib/sisimai/lhost/x2.rb +4 -5
  46. data/lib/sisimai/lhost/x3.rb +5 -5
  47. data/lib/sisimai/lhost/x6.rb +4 -4
  48. data/lib/sisimai/lhost/zoho.rb +6 -6
  49. data/lib/sisimai/lhost.rb +21 -24
  50. data/lib/sisimai/mail/maildir.rb +1 -1
  51. data/lib/sisimai/mail/stdin.rb +1 -1
  52. data/lib/sisimai/message.rb +100 -153
  53. data/lib/sisimai/order.rb +22 -77
  54. data/lib/sisimai/reason/authfailure.rb +1 -4
  55. data/lib/sisimai/reason/badreputation.rb +3 -3
  56. data/lib/sisimai/reason/blocked.rb +7 -10
  57. data/lib/sisimai/reason/contenterror.rb +7 -1
  58. data/lib/sisimai/reason/exceedlimit.rb +1 -4
  59. data/lib/sisimai/reason/failedstarttls.rb +42 -0
  60. data/lib/sisimai/reason/filtered.rb +5 -4
  61. data/lib/sisimai/reason/hasmoved.rb +1 -2
  62. data/lib/sisimai/reason/hostunknown.rb +3 -3
  63. data/lib/sisimai/reason/mailboxfull.rb +2 -4
  64. data/lib/sisimai/reason/mailererror.rb +1 -2
  65. data/lib/sisimai/reason/mesgtoobig.rb +2 -4
  66. data/lib/sisimai/reason/norelaying.rb +3 -3
  67. data/lib/sisimai/reason/notaccept.rb +2 -3
  68. data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
  69. data/lib/sisimai/reason/rejected.rb +2 -1
  70. data/lib/sisimai/reason/requireptr.rb +2 -2
  71. data/lib/sisimai/reason/securityerror.rb +1 -3
  72. data/lib/sisimai/reason/spamdetected.rb +6 -8
  73. data/lib/sisimai/reason/speeding.rb +1 -2
  74. data/lib/sisimai/reason/suppressed.rb +36 -0
  75. data/lib/sisimai/reason/suspend.rb +1 -3
  76. data/lib/sisimai/reason/systemerror.rb +5 -0
  77. data/lib/sisimai/reason/toomanyconn.rb +1 -2
  78. data/lib/sisimai/reason/userunknown.rb +1 -1
  79. data/lib/sisimai/reason/virusdetected.rb +5 -6
  80. data/lib/sisimai/reason.rb +82 -78
  81. data/lib/sisimai/rfc1123.rb +152 -0
  82. data/lib/sisimai/rfc1894.rb +102 -62
  83. data/lib/sisimai/rfc2045.rb +2 -1
  84. data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
  85. data/lib/sisimai/rfc3464.rb +224 -345
  86. data/lib/sisimai/rfc3834.rb +3 -3
  87. data/lib/sisimai/rfc5322.rb +7 -17
  88. data/lib/sisimai/rfc791.rb +69 -0
  89. data/lib/sisimai/rhost/aol.rb +36 -0
  90. data/lib/sisimai/rhost/apple.rb +95 -0
  91. data/lib/sisimai/rhost/cox.rb +84 -34
  92. data/lib/sisimai/rhost/facebook.rb +100 -0
  93. data/lib/sisimai/rhost/franceptt.rb +87 -83
  94. data/lib/sisimai/rhost/godaddy.rb +208 -45
  95. data/lib/sisimai/rhost/google.rb +22 -22
  96. data/lib/sisimai/rhost/gsuite.rb +42 -0
  97. data/lib/sisimai/rhost/iua.rb +5 -5
  98. data/lib/sisimai/rhost/kddi.rb +9 -7
  99. data/lib/sisimai/rhost/messagelabs.rb +37 -0
  100. data/lib/sisimai/rhost/microsoft.rb +60 -54
  101. data/lib/sisimai/rhost/mimecast.rb +44 -31
  102. data/lib/sisimai/rhost/nttdocomo.rb +5 -4
  103. data/lib/sisimai/rhost/outlook.rb +36 -0
  104. data/lib/sisimai/rhost/spectrum.rb +102 -41
  105. data/lib/sisimai/rhost/tencent.rb +48 -26
  106. data/lib/sisimai/rhost/yahooinc.rb +111 -0
  107. data/lib/sisimai/rhost.rb +65 -42
  108. data/lib/sisimai/smtp/command.rb +31 -21
  109. data/lib/sisimai/smtp/failure.rb +103 -0
  110. data/lib/sisimai/smtp/reply.rb +29 -24
  111. data/lib/sisimai/smtp/status.rb +36 -19
  112. data/lib/sisimai/smtp/transcript.rb +18 -18
  113. data/lib/sisimai/string.rb +0 -46
  114. data/lib/sisimai/version.rb +1 -1
  115. data/lib/sisimai.rb +0 -6
  116. data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
  117. data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
  118. data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
  119. data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
  120. data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
  121. data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
  122. data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
  123. data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
  124. data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
  125. data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
  126. data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
  127. data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
  128. data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
  129. data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
  130. data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
  131. data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
  132. data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
  133. data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
  134. data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
  135. data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
  136. data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
  137. data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
  138. data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
  139. data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
  140. data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
  141. data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
  142. data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
  143. data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
  144. data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
  145. data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
  146. data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
  147. data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
  148. data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
  149. data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
  150. data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
  151. data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
  152. data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
  153. data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
  154. data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
  155. data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
  156. data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
  157. data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
  158. data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
  159. data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
  160. data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
  161. data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
  162. data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
  163. data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
  164. data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
  165. data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
  166. data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
  167. data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
  168. data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
  169. data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
  170. data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
  171. data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
  172. data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
  173. data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
  174. data/set-of-emails/maildir/bsd/rhost-apple-01.eml +79 -0
  175. data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
  176. data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
  177. data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
  178. data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
  179. data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
  180. data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
  181. data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
  182. data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
  183. data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
  184. data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
  185. data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
  186. data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
  187. data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
  188. data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
  189. data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
  190. data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
  191. data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
  192. data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
  193. data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
  194. data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
  195. data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
  196. data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
  197. data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
  198. data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
  199. data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
  200. data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
  201. data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
  202. data/set-of-emails/maildir/bsd/rhost-yahooinc-01.eml +80 -0
  203. data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
  204. data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -0
  205. data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
  206. data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
  207. data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
  208. data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
  209. metadata +136 -56
  210. data/lib/sisimai/lhost/amavis.rb +0 -163
  211. data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
  212. data/lib/sisimai/lhost/aol.rb +0 -125
  213. data/lib/sisimai/lhost/barracuda.rb +0 -92
  214. data/lib/sisimai/lhost/bigfoot.rb +0 -125
  215. data/lib/sisimai/lhost/facebook.rb +0 -188
  216. data/lib/sisimai/lhost/gsuite.rb +0 -194
  217. data/lib/sisimai/lhost/mailru.rb +0 -214
  218. data/lib/sisimai/lhost/mcafee.rb +0 -109
  219. data/lib/sisimai/lhost/messagelabs.rb +0 -119
  220. data/lib/sisimai/lhost/mxlogic.rb +0 -198
  221. data/lib/sisimai/lhost/office365.rb +0 -252
  222. data/lib/sisimai/lhost/outlook.rb +0 -129
  223. data/lib/sisimai/lhost/powermta.rb +0 -118
  224. data/lib/sisimai/lhost/receivingses.rb +0 -126
  225. data/lib/sisimai/lhost/sendgrid.rb +0 -150
  226. data/lib/sisimai/lhost/surfcontrol.rb +0 -105
  227. data/lib/sisimai/lhost/x4.rb +0 -269
  228. data/lib/sisimai/lhost/x5.rb +0 -112
  229. data/lib/sisimai/lhost/yahoo.rb +0 -102
  230. data/lib/sisimai/lhost/yandex.rb +0 -118
  231. data/lib/sisimai/mda.rb +0 -121
  232. data/lib/sisimai/smtp/error.rb +0 -119
  233. /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
  234. /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
  235. /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
  236. /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
  237. /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
  238. /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
  239. /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
  240. /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
  241. /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
  242. /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
  243. /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
  244. /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
  245. /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
  246. /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
  247. /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
  248. /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
  249. /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
  250. /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
  251. /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
  252. /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
  253. /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
  254. /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
  255. /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
  256. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
  257. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
  258. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
@@ -1,129 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Outlook parses a bounce email which created by Microsoft Outlook.com. Methods in
3
- # the module are called from only Sisimai::Message.
4
- module Outlook
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: message/rfc822'].freeze
10
- StartingOf = { message: ['This is an automatically generated Delivery Status Notification'] }.freeze
11
- MessagesOf = {
12
- 'hostunknown' => ['The mail could not be delivered to the recipient because the domain is not reachable'],
13
- 'userunknown' => ['Requested action not taken: mailbox unavailable'],
14
- }.freeze
15
-
16
- # Parse bounce messages from Microsoft Outlook.com
17
- # @param [Hash] mhead Message headers of a bounce email
18
- # @param [String] mbody Message body of a bounce email
19
- # @return [Hash] Bounce data list and message/rfc822 part
20
- # @return [Nil] it failed to parse or the arguments are missing
21
- def inquire(mhead, mbody)
22
- # X-Message-Delivery: Vj0xLjE7RD0wO0dEPTA7U0NMPTk7bD0xO3VzPTE=
23
- # X-Message-Info: AuEzbeVr9u5fkDpn2vR5iCu5wb6HBeY4iruBjnutBzpStnUabbM...
24
- match = 0
25
- match += 1 if mhead['subject'].start_with?('Delivery Status Notification')
26
- match += 1 if mhead['x-message-delivery']
27
- match += 1 if mhead['x-message-info']
28
- match += 1 if mhead['received'].any? { |a| a.include?('.hotmail.com') }
29
- return nil if match < 2
30
-
31
- fieldtable = Sisimai::RFC1894.FIELDTABLE
32
- permessage = {} # (Hash) Store values of each Per-Message field
33
-
34
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
35
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
36
- bodyslices = emailparts[0].split("\n")
37
- readslices = ['']
38
- readcursor = 0 # (Integer) Points the current cursor position
39
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
40
- v = nil
41
-
42
- while e = bodyslices.shift do
43
- # Read error messages and delivery status lines from the head of the email to the previous
44
- # line of the beginning of the original message.
45
- readslices << e # Save the current line for the next loop
46
-
47
- if readcursor == 0
48
- # Beginning of the bounce message or message/delivery-status part
49
- readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
50
- next
51
- end
52
- next if (readcursor & Indicators[:deliverystatus]) == 0
53
- next if e.empty?
54
-
55
- if f = Sisimai::RFC1894.match(e)
56
- # "e" matched with any field defined in RFC3464
57
- next unless o = Sisimai::RFC1894.field(e)
58
- v = dscontents[-1]
59
-
60
- if o[-1] == 'addr'
61
- # Final-Recipient: rfc822; kijitora@example.jp
62
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
63
- if o[0] == 'final-recipient'
64
- # Final-Recipient: rfc822; kijitora@example.jp
65
- if v['recipient']
66
- # There are multiple recipient addresses in the message body.
67
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
68
- v = dscontents[-1]
69
- end
70
- v['recipient'] = o[2]
71
- recipients += 1
72
- else
73
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
74
- v['alias'] = o[2]
75
- end
76
- elsif o[-1] == 'code'
77
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
78
- v['spec'] = o[1]
79
- v['diagnosis'] = o[2]
80
- else
81
- # Other DSN fields defined in RFC3464
82
- next unless fieldtable[o[0]]
83
- v[fieldtable[o[0]]] = o[2]
84
-
85
- next unless f
86
- permessage[fieldtable[o[0]]] = o[2]
87
- end
88
- else
89
- # Continued line of the value of Diagnostic-Code field
90
- next unless readslices[-2].start_with?('Diagnostic-Code:')
91
- next unless e.start_with?(' ')
92
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
93
- readslices[-1] = 'Diagnostic-Code: ' << e
94
- end
95
- end
96
- return nil unless recipients > 0
97
-
98
- dscontents.each do |e|
99
- # Set default values if each value is empty.
100
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
101
-
102
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
103
- if e['diagnosis'].empty?
104
- # No message in 'diagnosis'
105
- if e['action'] == 'delayed'
106
- # Set pseudo diagnostic code message for delaying
107
- e['diagnosis'] = 'Delivery to the following recipients has been delayed.'
108
- else
109
- # Set pseudo diagnostic code message
110
- e['diagnosis'] = 'Unable to deliver message to the following recipients, '
111
- e['diagnosis'] << 'due to being unable to connect successfully to the destination mail server.'
112
- end
113
- end
114
-
115
- MessagesOf.each_key do |r|
116
- # Verify each regular expression of session errors
117
- next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
118
- e['reason'] = r
119
- break
120
- end
121
- end
122
-
123
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
124
- end
125
- def description; return 'Microsoft Outlook.com: https://www.outlook.com/'; end
126
- end
127
- end
128
- end
129
-
@@ -1,118 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::PowerMTA parses a bounce email which created by PowerMTA. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module PowerMTA
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: text/rfc822-headers'].freeze
10
- StartingOf = { message: ['Hello, this is the mail server on '] }.freeze
11
- Categories = {
12
- 'bad-domain' => 'hostunknown',
13
- 'bad-mailbox' => 'userunknown',
14
- 'inactive-mailbox' => 'disabled',
15
- 'message-expired' => 'expired',
16
- 'no-answer-from-host' => 'networkerror',
17
- 'policy-related' => 'policyviolation',
18
- 'quota-issues' => 'mailboxfull',
19
- 'routing-errors' => 'systemerror',
20
- 'spam-related' => 'spamdetected',
21
- }.freeze
22
-
23
- # Parse bounce messages from PowerMTA
24
- # @param [Hash] mhead Message headers of a bounce email
25
- # @param [String] mbody Message body of a bounce email
26
- # @return [Hash] Bounce data list and message/rfc822 part
27
- # @return [Nil] it failed to parse or the arguments are missing
28
- # @since v4.25.6
29
- def inquire(mhead, mbody)
30
- return nil unless mhead['subject'].to_s.start_with?('Delivery report')
31
-
32
- fieldtable = Sisimai::RFC1894.FIELDTABLE
33
- permessage = {} # (Hash) Store values of each Per-Message field
34
-
35
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
36
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
37
- bodyslices = emailparts[0].split("\n")
38
- readcursor = 0 # (Integer) Points the current cursor position
39
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
40
- v = nil
41
-
42
- while e = bodyslices.shift do
43
- # Read error messages and delivery status lines from the head of the email to the previous
44
- # line of the beginning of the original message.
45
- if readcursor == 0
46
- # Beginning of the bounce message or message/delivery-status part
47
- readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
48
- next
49
- end
50
- next if (readcursor & Indicators[:deliverystatus]) == 0
51
- next if e.empty?
52
-
53
- if f = Sisimai::RFC1894.match(e)
54
- # "e" matched with any field defined in RFC3464
55
- next unless o = Sisimai::RFC1894.field(e)
56
- v = dscontents[-1]
57
-
58
- if o[-1] == 'addr'
59
- # Final-Recipient: rfc822; kijitora@example.jp
60
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
61
- if o[0] == 'final-recipient'
62
- # Final-Recipient: rfc822; kijitora@example.jp
63
- if v['recipient']
64
- # There are multiple recipient addresses in the message body.
65
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
66
- v = dscontents[-1]
67
- end
68
- v['recipient'] = o[2]
69
- recipients += 1
70
- else
71
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
72
- v['alias'] = o[2]
73
- end
74
- elsif o[-1] == 'code'
75
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
76
- v['spec'] = o[1]
77
- v['diagnosis'] = o[2]
78
- else
79
- # Other DSN fields defined in RFC3464
80
- next unless fieldtable[o[0]]
81
- v[fieldtable[o[0]]] = o[2]
82
-
83
- next unless f
84
- permessage[fieldtable[o[0]]] = o[2]
85
- end
86
- else
87
- # Hello, this is the mail server on neko2.example.org.
88
- #
89
- # I am sending you this message to inform you on the delivery status of a
90
- # message you previously sent. Immediately below you will find a list of
91
- # the affected recipients; also attached is a Delivery Status Notification
92
- # (DSN) report in standard format, as well as the headers of the original
93
- # message.
94
- #
95
- # <kijitora@example.jp> delivery failed; will not continue trying
96
- #
97
- if e.start_with?('X-PowerMTA-BounceCategory: ')
98
- # X-PowerMTA-BounceCategory: bad-mailbox
99
- v['category'] = e[e.index(':') + 2, e.size]
100
- end
101
- end
102
- end
103
- return nil unless recipients > 0
104
-
105
- dscontents.each do |e|
106
- # Set default values if each value is empty.
107
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
108
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].to_s.tr("\n", ' '))
109
- e['reason'] = Categories[e['category']] || ''
110
- end
111
-
112
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
113
- end
114
- def description; return 'PowerMTA: https://www.sparkpost.com/powermta/'; end
115
- end
116
- end
117
- end
118
-
@@ -1,126 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::ReceivingSES parses a bounce email which created by Amazon Simple Email Service.
3
- # Methods in the module are called from only Sisimai::Message.
4
- module ReceivingSES
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- # https://aws.amazon.com/ses/
9
- Indicators = Sisimai::Lhost.INDICATORS
10
- Boundaries = ['Content-Type: text/rfc822-headers'].freeze
11
- StartingOf = { message: ['This message could not be delivered.'] }.freeze
12
- MessagesOf = {
13
- # The followings are error messages in Rule sets/*/Actions/Template
14
- 'filtered' => ['Mailbox does not exist'],
15
- 'mesgtoobig' => ['Message too large'],
16
- 'mailboxfull' => ['Mailbox full'],
17
- 'contenterror' => ['Message content rejected'],
18
- }.freeze
19
-
20
- # Parse bounce messages from Amazon SES/Receiving
21
- # @param [Hash] mhead Message headers of a bounce email
22
- # @param [String] mbody Message body of a bounce email
23
- # @return [Hash] Bounce data list and message/rfc822 part
24
- # @return [Nil] it failed to parse or the arguments are missing
25
- def inquire(mhead, mbody)
26
- # X-SES-Outgoing: 2015.10.01-54.240.27.7
27
- # Feedback-ID: 1.us-west-2.HX6/J9OVlHTadQhEu1+wdF9DBj6n6Pa9sW5Y/0pSOi8=:AmazonSES
28
- return nil unless mhead['x-ses-outgoing']
29
-
30
- fieldtable = Sisimai::RFC1894.FIELDTABLE
31
- permessage = {} # (Hash) Store values of each Per-Message field
32
-
33
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
34
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
35
- bodyslices = emailparts[0].split("\n")
36
- readslices = ['']
37
- readcursor = 0 # (Integer) Points the current cursor position
38
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
39
- v = nil
40
-
41
- while e = bodyslices.shift do
42
- # Read error messages and delivery status lines from the head of the email to the previous
43
- # line of the beginning of the original message.
44
- readslices << e # Save the current line for the next loop
45
-
46
- if readcursor == 0
47
- # Beginning of the bounce message or message/delivery-status part
48
- readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
49
- next
50
- end
51
- next if (readcursor & Indicators[:deliverystatus]) == 0
52
- next if e.empty?
53
-
54
- if f = Sisimai::RFC1894.match(e)
55
- # "e" matched with any field defined in RFC3464
56
- next unless o = Sisimai::RFC1894.field(e)
57
- v = dscontents[-1]
58
-
59
- if o[-1] == 'addr'
60
- # Final-Recipient: rfc822; kijitora@example.jp
61
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
62
- if o[0] == 'final-recipient'
63
- # Final-Recipient: rfc822; kijitora@example.jp
64
- if v['recipient']
65
- # There are multiple recipient addresses in the message body.
66
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
67
- v = dscontents[-1]
68
- end
69
- v['recipient'] = o[2]
70
- recipients += 1
71
- else
72
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
73
- v['alias'] = o[2]
74
- end
75
- elsif o[-1] == 'code'
76
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
77
- v['spec'] = o[1]
78
- v['diagnosis'] = o[2]
79
- else
80
- # Other DSN fields defined in RFC3464
81
- next unless fieldtable[o[0]]
82
- v[fieldtable[o[0]]] = o[2]
83
-
84
- next unless f
85
- permessage[fieldtable[o[0]]] = o[2]
86
- end
87
- else
88
- # Continued line of the value of Diagnostic-Code field
89
- next unless readslices[-2].start_with?('Diagnostic-Code:')
90
- next unless e.start_with?(' ')
91
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
92
- readslices[-1] = 'Diagnostic-Code: ' << e
93
- end
94
- end
95
- return nil unless recipients > 0
96
-
97
- dscontents.each do |e|
98
- # Set default values if each value is empty.
99
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
100
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
101
-
102
- if e['status'].to_s.start_with?('5.0.0', '5.1.0', '4.0.0', '4.1.0')
103
- # Get other D.S.N. value from the error message
104
- errormessage = e['diagnosis']
105
- p1 = e['diagnosis'].index("-'"); p1 = e['diagnosis'].index('-"') unless p1
106
- p2 = e['diagnosis'].rindex("' "); p2 = e['diagnosis'].rindex('" ') unless p2
107
- errormessage = e['diagnosis'][p1 + 2, p2 - p1 - 2] if p1 && p2
108
- e['status'] = Sisimai::SMTP::Status.find(errormessage) || e['status']
109
- end
110
-
111
- MessagesOf.each_key do |r|
112
- # Verify each regular expression of session errors
113
- next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
114
- e['reason'] = r
115
- break
116
- end
117
- e['reason'] ||= Sisimai::SMTP::Status.name(e['status']) || ''
118
- end
119
-
120
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
121
- end
122
- def description; return 'Amazon SES(Receiving): https://aws.amazon.com/ses/'; end
123
- end
124
- end
125
- end
126
-
@@ -1,150 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::SendGrid parses a bounce email which created by SendGrid. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module SendGrid
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: message/rfc822'].freeze
10
- StartingOf = { message: ['This is an automatically generated message from SendGrid.'] }.freeze
11
-
12
- # Parse bounce messages from SendGrid
13
- # @param [Hash] mhead Message headers of a bounce email
14
- # @param [String] mbody Message body of a bounce email
15
- # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
17
- def inquire(mhead, mbody)
18
- # Return-Path: <apps@sendgrid.net>
19
- # X-Mailer: MIME-tools 5.502 (Entity 5.502)
20
- return nil unless mhead['return-path']
21
- return nil unless mhead['return-path'] == '<apps@sendgrid.net>'
22
- return nil unless mhead['subject'] == 'Undelivered Mail Returned to Sender'
23
-
24
- require 'sisimai/smtp/command'
25
- fieldtable = Sisimai::RFC1894.FIELDTABLE
26
- permessage = {} # (Hash) Store values of each Per-Message field
27
-
28
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
29
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
30
- bodyslices = emailparts[0].split("\n")
31
- readslices = ['']
32
- readcursor = 0 # (Integer) Points the current cursor position
33
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
34
- thecommand = '' # (String) SMTP Command name begin with the string '>>>'
35
- v = nil
36
-
37
- while e = bodyslices.shift do
38
- # Read error messages and delivery status lines from the head of the email to the previous
39
- # line of the beginning of the original message.
40
- readslices << e # Save the current line for the next loop
41
-
42
- if readcursor == 0
43
- # Beginning of the bounce message or message/delivery-status part
44
- readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
45
- next
46
- end
47
- next if (readcursor & Indicators[:deliverystatus]) == 0
48
- next if e.empty?
49
-
50
- if f = Sisimai::RFC1894.match(e)
51
- # "e" matched with any field defined in RFC3464
52
- o = Sisimai::RFC1894.field(e)
53
- v = dscontents[-1]
54
-
55
- unless o
56
- # Fallback code for empty value or invalid formatted value
57
- # - Status: (empty)
58
- # - Diagnostic-Code: 550 5.1.1 ... (No "diagnostic-type" sub field)
59
- v['diagnosis'] = e[e.index(':') + 2, e.size] if e.start_with?('Diagnostic-Code: ')
60
- next
61
- end
62
-
63
- if o[-1] == 'addr'
64
- # Final-Recipient: rfc822; kijitora@example.jp
65
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
66
- if o[0] == 'final-recipient'
67
- # Final-Recipient: rfc822; kijitora@example.jp
68
- if v['recipient']
69
- # There are multiple recipient addresses in the message body.
70
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
71
- v = dscontents[-1]
72
- end
73
- v['recipient'] = o[2]
74
- recipients += 1
75
- else
76
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
77
- v['alias'] = o[2]
78
- end
79
- elsif o[-1] == 'code'
80
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
81
- v['spec'] = o[1]
82
- v['diagnosis'] = o[2]
83
- elsif o[-1] == 'date'
84
- # Arrival-Date: 2012-12-31 23-59-59
85
- next unless e.start_with?('Arrival-Date: ')
86
- cf = e[e.index(': ') + 2, e.size].split(' '); next unless cf.size == 2
87
- cw = cf[0].split('-'); next unless cw.size == 3
88
- ce = cf[1].split('-'); next unless ce.size == 3
89
-
90
- o[1] << 'Thu, ' << cw[2] + ' '
91
- o[1] << Sisimai::DateTime.monthname(false)[cw[1].to_i - 1]
92
- o[1] << ' ' << cw[0] + ' ' << ce.join(':')
93
- o[1] << ' ' << Sisimai::DateTime.abbr2tz('CDT')
94
- else
95
- # Other DSN fields defined in RFC3464
96
- next unless fieldtable[o[0]]
97
- v[fieldtable[o[0]]] = o[2]
98
-
99
- next unless f
100
- permessage[fieldtable[o[0]]] = o[2]
101
- end
102
- else
103
- # The line does not begin with a DSN field defined in RFC3464
104
- if cv = Sisimai::SMTP::Command.find(e)
105
- # in RCPT TO, in MAIL FROM, end of DATA
106
- thecommand = cv
107
- elsif e.start_with?('Diagnostic-Code: ')
108
- # Diagnostic-Code: 550 5.1.1 <kijitora@example.jp>... User Unknown
109
- v['diagnosis'] = e[e.index(':') + 2, e.size]
110
- else
111
- # Continued line of the value of Diagnostic-Code field
112
- next unless readslices[-2].start_with?('Diagnostic-Code:')
113
- next unless e.start_with?(' ')
114
- v['diagnosis'] ||= ''
115
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
116
- readslices[-1] = 'Diagnostic-Code: ' << e
117
- end
118
- end
119
- end
120
- return nil unless recipients > 0
121
-
122
- dscontents.each do |e|
123
- # Get the value of SMTP status code as a pseudo D.S.N.
124
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
125
- e['replycode'] = Sisimai::SMTP::Reply.find(e['diagnosis']) || ''
126
- e['status'] = e['replycode'][0, 1] + '.0.0' if e['replycode'].size == 3
127
- e['command'] = thecommand
128
-
129
- if e['status'] == '5.0.0' || e['status'] == '4.0.0'
130
- # Get the value of D.S.N. from the error message or the value of Diagnostic-Code header.
131
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || e['status']
132
- end
133
-
134
- if e['action'] == 'expired'
135
- # Action: expired
136
- e['reason'] = 'expired'
137
- if !e['status'] || e['status'].end_with?('.0.0')
138
- # Set pseudo Status code value if the value of Status is not defined or 4.0.0 or 5.0.0.
139
- e['status'] = Sisimai::SMTP::Status.code('expired') || e['status']
140
- end
141
- end
142
- end
143
-
144
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
145
- end
146
- def description; return 'SendGrid: https://sendgrid.com/'; end
147
- end
148
- end
149
- end
150
-
@@ -1,105 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::SurfControl parses a bounce email which created by WebSense SurfControl.
3
- # Methods in the module are called from only Sisimai::Message.
4
- module SurfControl
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: message/rfc822'].freeze
10
- StartingOf = { message: ['Your message could not be sent.'] }.freeze
11
-
12
- # Parse bounce messages from SurfControl
13
- # @param [Hash] mhead Message headers of a bounce email
14
- # @param [String] mbody Message body of a bounce email
15
- # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
17
- def inquire(mhead, mbody)
18
- # X-SEF-ZeroHour-RefID: fgs=000000000
19
- # X-SEF-Processed: 0_0_0_000__2010_04_29_23_34_45
20
- # X-Mailer: SurfControl E-mail Filter
21
- return nil unless mhead['x-sef-processed']
22
- return nil unless mhead['x-mailer']
23
- return nil unless mhead['x-mailer'] == 'SurfControl E-mail Filter'
24
-
25
- fieldtable = Sisimai::RFC1894.FIELDTABLE
26
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
27
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
28
- bodyslices = emailparts[0].split("\n")
29
- readslices = ['']
30
- readcursor = 0 # (Integer) Points the current cursor position
31
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
32
- v = nil
33
-
34
- while e = bodyslices.shift do
35
- # Read error messages and delivery status lines from the head of the email to the previous
36
- # line of the beginning of the original message.
37
- readslices << e # Save the current line for the next loop
38
-
39
- if readcursor == 0
40
- # Beginning of the bounce message or delivery status part
41
- readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
42
- next
43
- end
44
- next if (readcursor & Indicators[:deliverystatus]) == 0
45
- next if e.empty?
46
-
47
- # Your message could not be sent.
48
- # A transcript of the attempts to send the message follows.
49
- # The number of attempts made: 1
50
- # Addressed To: kijitora@example.com
51
- #
52
- # Thu 29 Apr 2010 23:34:45 +0900
53
- # Failed to send to identified host,
54
- # kijitora@example.com: [192.0.2.5], 550 kijitora@example.com... No such user
55
- # --- Message non-deliverable.
56
- v = dscontents[-1]
57
-
58
- if e.start_with?('Addressed To:') && e.index('@') > 1
59
- # Addressed To: kijitora@example.com
60
- if v['recipient']
61
- # There are multiple recipient addresses in the message body.
62
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
63
- v = dscontents[-1]
64
- end
65
- v['recipient'] = Sisimai::Address.s3s4(e[e.index(':') + 2, e.size])
66
- recipients += 1
67
-
68
- elsif %w[Sun Mon Tue Wed Thu Fri Sat].any? { |a| e.start_with?(a) }
69
- # Thu 29 Apr 2010 23:34:45 +0900
70
- v['date'] = e
71
-
72
- elsif Sisimai::String.aligned(e, ['@', ':', ' ', '[', '],', '...'])
73
- # kijitora@example.com: [192.0.2.5], 550 kijitora@example.com... No such user
74
- p1 = e.index('[')
75
- p2 = e.index('],', p1 + 1)
76
- v['rhost'] = e[p1 + 1, p2 - p1 - 1]
77
- v['diagnosis'] = Sisimai::String.sweep(e[p2 + 2, e.size])
78
-
79
- else
80
- # Fallback, parse RFC3464 headers.
81
- if f = Sisimai::RFC1894.match(e)
82
- # "e" matched with any field defined in RFC3464
83
- next unless o = Sisimai::RFC1894.field(e)
84
- next if o[1] == 'final-recipient'
85
- next unless fieldtable[o[0]]
86
- v[fieldtable[o[0]]] = o[2]
87
- else
88
- # Continued line of the value of Diagnostic-Code field
89
- next unless readslices[-2].start_with?('Diagnostic-Code:')
90
- next unless e.start_with?(' ')
91
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
92
- readslices[-1] = 'Diagnostic-Code: ' << e
93
- end
94
- end
95
- end
96
- return nil unless recipients > 0
97
-
98
- dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
99
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
100
- end
101
- def description; return 'WebSense SurfControl'; end
102
- end
103
- end
104
- end
105
-