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,163 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Amavis parses a bounce email which created by amavsid-new. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module Amavis
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: text/rfc822-headers'].freeze
10
- StartingOf = { message: ['The message '] }.freeze
11
- MessagesOf = {
12
- # amavisd-new-2.11.1/amavisd:1840|%smtp_reason_by_ccat = (
13
- # amavisd-new-2.11.1/amavisd:1840| # currently only used for blocked messages only, status 5xx
14
- # amavisd-new-2.11.1/amavisd:1840| # a multiline message will produce a valid multiline SMTP response
15
- # amavisd-new-2.11.1/amavisd:1840| CC_VIRUS, 'id=%n - INFECTED: %V',
16
- # amavisd-new-2.11.1/amavisd:1840| CC_BANNED, 'id=%n - BANNED: %F',
17
- # amavisd-new-2.11.1/amavisd:1840| CC_UNCHECKED.',1', 'id=%n - UNCHECKED: encrypted',
18
- # amavisd-new-2.11.1/amavisd:1840| CC_UNCHECKED.',2', 'id=%n - UNCHECKED: over limits',
19
- # amavisd-new-2.11.1/amavisd:1840| CC_UNCHECKED, 'id=%n - UNCHECKED',
20
- # amavisd-new-2.11.1/amavisd:1840| CC_SPAM, 'id=%n - spam',
21
- # amavisd-new-2.11.1/amavisd:1840| CC_SPAMMY.',1', 'id=%n - spammy (tag3)',
22
- # amavisd-new-2.11.1/amavisd:1840| CC_SPAMMY, 'id=%n - spammy',
23
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',1', 'id=%n - BAD HEADER: MIME error',
24
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',2', 'id=%n - BAD HEADER: nonencoded 8-bit character',
25
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',3', 'id=%n - BAD HEADER: contains invalid control character',
26
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',4', 'id=%n - BAD HEADER: line made up entirely of whitespace',
27
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',5', 'id=%n - BAD HEADER: line longer than RFC 5322 limit',
28
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',6', 'id=%n - BAD HEADER: syntax error',
29
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',7', 'id=%n - BAD HEADER: missing required header field',
30
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH.',8', 'id=%n - BAD HEADER: duplicate header field',
31
- # amavisd-new-2.11.1/amavisd:1840| CC_BADH, 'id=%n - BAD HEADER',
32
- # amavisd-new-2.11.1/amavisd:1840| CC_OVERSIZED, 'id=%n - Message size exceeds recipient\'s size limit',
33
- # amavisd-new-2.11.1/amavisd:1840| CC_MTA.',1', 'id=%n - Temporary MTA failure on relaying',
34
- # amavisd-new-2.11.1/amavisd:1840| CC_MTA.',2', 'id=%n - Rejected by next-hop MTA on relaying',
35
- # amavisd-new-2.11.1/amavisd:1840| CC_MTA, 'id=%n - Unable to relay message back to MTA',
36
- # amavisd-new-2.11.1/amavisd:1840| CC_CLEAN, 'id=%n - CLEAN',
37
- # amavisd-new-2.11.1/amavisd:1840| CC_CATCHALL, 'id=%n - OTHER', # should not happen
38
- # ...
39
- # amavisd-new-2.11.1/amavisd:15289|my $status = setting_by_given_contents_category(
40
- # amavisd-new-2.11.1/amavisd:15289| $blocking_ccat,
41
- # amavisd-new-2.11.1/amavisd:15289| { CC_VIRUS, "554 5.7.0",
42
- # amavisd-new-2.11.1/amavisd:15289| CC_BANNED, "554 5.7.0",
43
- # amavisd-new-2.11.1/amavisd:15289| CC_UNCHECKED, "554 5.7.0",
44
- # amavisd-new-2.11.1/amavisd:15289| CC_SPAM, "554 5.7.0",
45
- # amavisd-new-2.11.1/amavisd:15289| CC_SPAMMY, "554 5.7.0",
46
- # amavisd-new-2.11.1/amavisd:15289| CC_BADH.",2", "554 5.6.3", # nonencoded 8-bit character
47
- # amavisd-new-2.11.1/amavisd:15289| CC_BADH, "554 5.6.0",
48
- # amavisd-new-2.11.1/amavisd:15289| CC_OVERSIZED, "552 5.3.4",
49
- # amavisd-new-2.11.1/amavisd:15289| CC_MTA, "550 5.3.5",
50
- # amavisd-new-2.11.1/amavisd:15289| CC_CATCHALL, "554 5.7.0",
51
- # amavisd-new-2.11.1/amavisd:15289| });
52
- # ...
53
- # amavisd-new-2.11.1/amavisd:15332|my $response = sprintf("%s %s%s%s", $status,
54
- # amavisd-new-2.11.1/amavisd:15333| ($final_destiny == D_PASS ? "Ok" :
55
- # amavisd-new-2.11.1/amavisd:15334| $final_destiny == D_DISCARD ? "Ok, discarded" :
56
- # amavisd-new-2.11.1/amavisd:15335| $final_destiny == D_REJECT ? "Reject" :
57
- # amavisd-new-2.11.1/amavisd:15336| $final_destiny == D_BOUNCE ? "Bounce" :
58
- # amavisd-new-2.11.1/amavisd:15337| $final_destiny == D_TEMPFAIL ? "Temporary failure" :
59
- # amavisd-new-2.11.1/amavisd:15338| "Not ok ($final_destiny)" ),
60
- 'spamdetected' => [' - spam'],
61
- 'virusdetected' => [' - infected'],
62
- 'contenterror' => [' - bad header:'],
63
- 'exceedlimit' => [' - message size exceeds recipient'],
64
- 'systemerror' => [
65
- ' - temporary mta failure on relaying',
66
- ' - rejected by next-hop mta on relaying',
67
- ' - unable to relay message back to mta',
68
- ],
69
- }.freeze
70
-
71
- # Parse bounce messages from amavisd-new
72
- # @param [Hash] mhead Message headers of a bounce email
73
- # @param [String] mbody Message body of a bounce email
74
- # @return [Hash] Bounce data list and message/rfc822 part
75
- # @return [Nil] it failed to parse or the arguments are missing
76
- # @since v4.25.0
77
- def inquire(mhead, mbody)
78
- # From: "Content-filter at neko1.example.jp" <postmaster@neko1.example.jp>
79
- # Subject: Undeliverable mail, MTA-BLOCKED
80
- return nil unless mhead['from'].to_s.start_with?('"Content-filter at ')
81
-
82
- fieldtable = Sisimai::RFC1894.FIELDTABLE
83
- permessage = {} # (Hash) Store values of each Per-Message field
84
-
85
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
86
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
87
- bodyslices = emailparts[0].split("\n")
88
- readcursor = 0 # (Integer) Points the current cursor position
89
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
90
- v = nil
91
-
92
- while e = bodyslices.shift do
93
- # Read error messages and delivery status lines from the head of the email to the previous
94
- # line of the beginning of the original message.
95
-
96
- if readcursor == 0
97
- # Beginning of the bounce message or message/delivery-status part
98
- readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
99
- next
100
- end
101
- next if (readcursor & Indicators[:deliverystatus]) == 0
102
- next if e.empty?
103
- next unless f = Sisimai::RFC1894.match(e)
104
-
105
- # "e" matched with any field defined in RFC3464
106
- next unless o = Sisimai::RFC1894.field(e)
107
- v = dscontents[-1]
108
-
109
- if o[-1] == 'addr'
110
- # Final-Recipient: rfc822; kijitora@example.jp
111
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
112
- if o[0] == 'final-recipient'
113
- # Final-Recipient: rfc822; kijitora@example.jp
114
- if v['recipient']
115
- # There are multiple recipient addresses in the message body.
116
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
117
- v = dscontents[-1]
118
- end
119
- v['recipient'] = o[2]
120
- recipients += 1
121
- else
122
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
123
- v['alias'] = o[2]
124
- end
125
- elsif o[-1] == 'code'
126
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
127
- v['spec'] = o[1]
128
- v['diagnosis'] = o[2]
129
- else
130
- # Other DSN fields defined in RFC3464
131
- next unless fieldtable[o[0]]
132
- v[fieldtable[o[0]]] = o[2]
133
-
134
- next unless f
135
- permessage[fieldtable[o[0]]] = o[2]
136
- end
137
- end
138
- return nil unless recipients > 0
139
-
140
- dscontents.each do |e|
141
- # Set default values if each value is empty.
142
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
143
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].to_s.tr("\n", ' '))
144
- q = e['diagnosis'].downcase
145
- catch :DETECT_REASON do
146
- MessagesOf.each_key do |p|
147
- # Try to detect an error reason
148
- MessagesOf[p].each do |r|
149
- # Try to find an error message including lower-cased string defined in MessagesOf constant
150
- next unless q.include?(r)
151
- e['reason'] = p
152
- throw :DETECT_REASON
153
- end
154
- end
155
- end
156
- end
157
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
158
- end
159
- def description; return 'amavisd-new: https://www.amavis.org/'; end
160
- end
161
- end
162
- end
163
-
@@ -1,127 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::AmazonWorkMail parses a bounce email which created by Amazon WorkMail. Methods
3
- # in the module are called from only Sisimai::Message.
4
- module AmazonWorkMail
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- # https://aws.amazon.com/workmail/
9
- Indicators = Sisimai::Lhost.INDICATORS
10
- Boundaries = ['Content-Type: message/rfc822'].freeze
11
- StartingOf = { message: ['Technical report:'] }.freeze
12
-
13
- # Parse bounce messages from Amazon WorkMail
14
- # @param [Hash] mhead Message headers of a bounce email
15
- # @param [String] mbody Message body of a bounce email
16
- # @return [Hash] Bounce data list and message/rfc822 part
17
- # @return [Nil] it failed to parse or the arguments are missing
18
- def inquire(mhead, mbody)
19
- # X-Mailer: Amazon WorkMail
20
- # X-Original-Mailer: Amazon WorkMail
21
- # X-Ses-Outgoing: 2016.01.14-54.240.27.159
22
- match = 0
23
- xmail = mhead['x-original-mailer'] || mhead['x-mailer'] || ''
24
-
25
- match += 1 if mhead['x-ses-outgoing']
26
- unless xmail.empty?
27
- # X-Mailer: Amazon WorkMail
28
- # X-Original-Mailer: Amazon WorkMail
29
- match += 1 if xmail == 'Amazon WorkMail'
30
- end
31
- return nil if match < 2
32
-
33
- require 'sisimai/rfc1894'
34
- fieldtable = Sisimai::RFC1894.FIELDTABLE
35
- permessage = {} # (Hash) Store values of each Per-Message field
36
-
37
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
38
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
39
- bodyslices = emailparts[0].split("\n")
40
- readcursor = 0 # (Integer) Points the current cursor position
41
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
42
- v = nil
43
-
44
- while e = bodyslices.shift do
45
- # Read error messages and delivery status lines from the head of the email to the previous
46
- # line of the beginning of the original message.
47
-
48
- if readcursor == 0
49
- # Beginning of the bounce message or message/delivery-status part
50
- readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
51
- next
52
- end
53
- next if (readcursor & Indicators[:deliverystatus]) == 0
54
- next if e.empty?
55
-
56
- if f = Sisimai::RFC1894.match(e)
57
- # "e" matched with any field defined in RFC3464
58
- o = Sisimai::RFC1894.field(e) || next
59
- v = dscontents[-1]
60
-
61
- if o[-1] == 'addr'
62
- # Final-Recipient: rfc822; kijitora@example.jp
63
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
64
- if o[0] == 'final-recipient'
65
- # Final-Recipient: rfc822; kijitora@example.jp
66
- if v['recipient']
67
- # There are multiple recipient addresses in the message body.
68
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
69
- v = dscontents[-1]
70
- end
71
- v['recipient'] = o[2]
72
- recipients += 1
73
- else
74
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
75
- v['alias'] = o[2]
76
- end
77
- elsif o[-1] == 'code'
78
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
79
- v['spec'] = o[1]
80
- v['diagnosis'] = o[2]
81
- else
82
- # Other DSN fields defined in RFC3464
83
- next unless fieldtable[o[0]]
84
- v[fieldtable[o[0]]] = o[2]
85
-
86
- next unless f
87
- permessage[fieldtable[o[0]]] = o[2]
88
- end
89
- end
90
-
91
- # <!DOCTYPE HTML><html>
92
- # <head>
93
- # <meta name="Generator" content="Amazon WorkMail v3.0-2023.77">
94
- # <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
95
- break if e.start_with?('<!DOCTYPE HTML><html>')
96
- end
97
- return nil unless recipients > 0
98
-
99
- dscontents.each do |e|
100
- # Set default values if each value is empty.
101
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
102
-
103
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
104
- if e['status'].to_s.end_with?('.0.0', '.1.0')
105
- # Get other D.S.N. value from the error message
106
- errormessage = e['diagnosis']
107
-
108
- if cv = e['diagnosis'].match(/["'](\d[.]\d[.]\d.+)['"]/)
109
- # 5.1.0 - Unknown address error 550-'5.7.1 ...
110
- errormessage = cv[1]
111
- end
112
- e['status'] = Sisimai::SMTP::Status.find(errormessage) || e['status']
113
- end
114
-
115
- # 554 4.4.7 Message expired: unable to deliver in 840 minutes.
116
- # <421 4.4.2 Connection timed out>
117
- e['replycode'] = Sisimai::SMTP::Reply.find(e['diagnosis']) || ''
118
- e['reason'] ||= Sisimai::SMTP::Status.name(e['status']) || ''
119
- end
120
-
121
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
122
- end
123
- def description; return 'Amazon WorkMail: https://aws.amazon.com/workmail/'; end
124
- end
125
- end
126
- end
127
-
@@ -1,125 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Aol parses a bounce email which created by Aol Mail. Methods in the module are
3
- # called from only Sisimai::Message.
4
- module Aol
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: message/rfc822'].freeze
10
- StartingOf = { message: ['Content-Type: message/delivery-status'] }.freeze
11
- MessagesOf = {
12
- 'hostunknown' => ['Host or domain name not found'],
13
- 'notaccept' => ['type=MX: Malformed or unexpected name server reply'],
14
- }.freeze
15
-
16
- # Parse bounce messages from Aol Mail
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-AOL-IP: 192.0.2.135
23
- # X-AOL-VSS-INFO: 5600.1067/98281
24
- # X-AOL-VSS-CODE: clean
25
- # x-aol-sid: 3039ac1afc14546fb98a0945
26
- # X-AOL-SCOLL-EIL: 1
27
- # x-aol-global-disposition: G
28
- # x-aol-sid: 3039ac1afd4d546fb97d75c6
29
- # X-BounceIO-Id: 9D38DE46-21BC-4309-83E1-5F0D788EFF1F.1_0
30
- # X-Outbound-Mail-Relay-Queue-ID: 07391702BF4DC
31
- # X-Outbound-Mail-Relay-Sender: rfc822; shironeko@aol.example.jp
32
- return nil unless mhead['x-aol-ip']
33
-
34
- fieldtable = Sisimai::RFC1894.FIELDTABLE
35
- permessage = {} # (Hash) Store values of each Per-Message field
36
-
37
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
38
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
39
- bodyslices = emailparts[0].split("\n")
40
- readslices = ['']
41
- readcursor = 0 # (Integer) Points the current cursor position
42
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
43
- v = nil
44
-
45
- while e = bodyslices.shift do
46
- # Read error messages and delivery status lines from the head of the email to the previous
47
- # line of the beginning of the original message.
48
- readslices << e # Save the current line for the next loop
49
-
50
- if readcursor == 0
51
- # Beginning of the bounce message or message/delivery-status part
52
- readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
53
- next
54
- end
55
- next if (readcursor & Indicators[:deliverystatus]) == 0
56
- next if e.empty?
57
-
58
- if f = Sisimai::RFC1894.match(e)
59
- # "e" matched with any field defined in RFC3464
60
- next unless o = Sisimai::RFC1894.field(e)
61
- v = dscontents[-1]
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
- else
84
- # Other DSN fields defined in RFC3464
85
- next unless fieldtable[o[0]]
86
- v[fieldtable[o[0]]] = o[2]
87
-
88
- next unless f
89
- permessage[fieldtable[o[0]]] = o[2]
90
- end
91
- else
92
- # Continued line of the value of Diagnostic-Code field
93
- next unless readslices[-2].start_with?('Diagnostic-Code:')
94
- next unless e.start_with?(' ')
95
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
96
- readslices[-1] = 'Diagnostic-Code: ' << e
97
- end
98
- end
99
- return nil unless recipients > 0
100
-
101
- dscontents.each do |e|
102
- # Set default values if each value is empty.
103
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
104
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
105
-
106
- MessagesOf.each_key do |r|
107
- # Verify each regular expression of session errors
108
- next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
109
- e['reason'] = r
110
- break
111
- end
112
-
113
- if e['status'].empty? || e['status'].end_with?('.0.0')
114
- # There is no value of Status header or the value is 5.0.0, 4.0.0
115
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
116
- end
117
- end
118
-
119
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
120
- end
121
- def description; return 'Aol Mail: https://www.aol.com'; end
122
- end
123
- end
124
- end
125
-
@@ -1,92 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Barracuda parses a bounce email which created by Barracuda. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module Barracuda
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: text/rfc822-headers'].freeze
10
- StartingOf = { message: ['Your message to:'] }.freeze
11
-
12
- # Parse bounce messages from Barracuda
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
- # @since v4.25.6
18
- def inquire(mhead, mbody)
19
- # Subject: **Message you sent blocked by our bulk email filter**
20
- return nil unless mhead['subject'].to_s.end_with?('our bulk email filter**')
21
-
22
- fieldtable = Sisimai::RFC1894.FIELDTABLE
23
- permessage = {} # (Hash) Store values of each Per-Message field
24
-
25
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
26
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
27
- bodyslices = emailparts[0].split("\n")
28
- readcursor = 0 # (Integer) Points the current cursor position
29
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
30
- v = nil
31
-
32
- while e = bodyslices.shift do
33
- # Read error messages and delivery status lines from the head of the email to the previous
34
- # line of the beginning of the original message.
35
- if readcursor == 0
36
- # Beginning of the bounce message or message/delivery-status part
37
- readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
38
- next
39
- end
40
- next if (readcursor & Indicators[:deliverystatus]) == 0
41
- next if e.empty?
42
-
43
- if f = Sisimai::RFC1894.match(e)
44
- # "e" matched with any field defined in RFC3464
45
- next unless o = Sisimai::RFC1894.field(e)
46
- v = dscontents[-1]
47
-
48
- if o[-1] == 'addr'
49
- # Final-Recipient: rfc822; kijitora@example.jp
50
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
51
- if o[0] == 'final-recipient'
52
- # Final-Recipient: rfc822; kijitora@example.jp
53
- if v['recipient']
54
- # There are multiple recipient addresses in the message body.
55
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
56
- v = dscontents[-1]
57
- end
58
- v['recipient'] = o[2]
59
- recipients += 1
60
- else
61
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
62
- v['alias'] = o[2]
63
- end
64
- elsif o[-1] == 'code'
65
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
66
- v['spec'] = o[1]
67
- v['diagnosis'] = o[2]
68
- else
69
- # Other DSN fields defined in RFC3464
70
- next unless fieldtable[o[0]]
71
- v[fieldtable[o[0]]] = o[2]
72
-
73
- next unless f
74
- permessage[fieldtable[o[0]]] = o[2]
75
- end
76
- end
77
- end
78
- return nil unless recipients > 0
79
-
80
- dscontents.each do |e|
81
- # Set default values if each value is empty.
82
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
83
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].to_s.tr("\n", ' '))
84
- end
85
-
86
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
87
- end
88
- def description; return 'Barracuda: https://www.barracuda.com'; end
89
- end
90
- end
91
- end
92
-
@@ -1,125 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Bigfoot parses a bounce email which created by Bigfoot. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module Bigfoot
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['Content-Type: message/partial'].freeze
10
- MarkingsOf = { message: ' ----- Transcript of session follows -----' }.freeze
11
-
12
- # Parse bounce messages from Bigfoot
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
- # :subject => %r/\AReturned mail: /,
19
- match = 0
20
- match += 1 if mhead['from'].include?('@bigfoot.com>')
21
- match += 1 if mhead['received'].any? { |a| a.include?('.bigfoot.com') }
22
- return nil unless match > 0
23
-
24
- require 'sisimai/smtp/command'
25
- require 'sisimai/rfc1894'
26
- fieldtable = Sisimai::RFC1894.FIELDTABLE
27
- permessage = {} # (Hash) Store values of each Per-Message field
28
-
29
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
30
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
31
- bodyslices = emailparts[0].split("\n")
32
- readslices = ['']
33
- readcursor = 0 # (Integer) Points the current cursor position
34
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
35
- thecommand = '' # (String) SMTP Command name begin with the string '>>>'
36
- esmtpreply = '' # (String) Reply from remote server on SMTP session
37
- v = nil
38
-
39
- while e = bodyslices.shift do
40
- # Read error messages and delivery status lines from the head of the email to the previous
41
- # line of the beginning of the original message.
42
- readslices << e # Save the current line for the next loop
43
-
44
- if readcursor == 0
45
- # Beginning of the bounce message or message/delivery-status part
46
- readcursor |= Indicators[:deliverystatus] if e.start_with?(MarkingsOf[:message])
47
- next
48
- end
49
- next if (readcursor & Indicators[:deliverystatus]) == 0
50
- next if e.empty?
51
-
52
- if f = Sisimai::RFC1894.match(e)
53
- # "e" matched with any field defined in RFC3464
54
- next unless o = Sisimai::RFC1894.field(e)
55
- v = dscontents[-1]
56
-
57
- if o[-1] == 'addr'
58
- # Final-Recipient: rfc822; kijitora@example.jp
59
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
60
- if o[0] == 'final-recipient'
61
- # Final-Recipient: rfc822; kijitora@example.jp
62
- if v['recipient']
63
- # There are multiple recipient addresses in the message body.
64
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
65
- v = dscontents[-1]
66
- end
67
- v['recipient'] = o[2]
68
- recipients += 1
69
- else
70
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
71
- v['alias'] = o[2]
72
- end
73
- elsif o[-1] == 'code'
74
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
75
- v['spec'] = o[1]
76
- v['diagnosis'] = o[2]
77
- else
78
- # Other DSN fields defined in RFC3464
79
- next unless fieldtable[o[0]]
80
- v[fieldtable[o[0]]] = o[2]
81
-
82
- next unless f
83
- permessage[fieldtable[o[0]]] = o[2]
84
- end
85
- else
86
- # The line does not begin with a DSN field defined in RFC3464
87
- unless e.start_with?(' ')
88
- # ----- Transcript of session follows -----
89
- # >>> RCPT TO:<destinaion@example.net>
90
- # <<< 553 Invalid recipient destinaion@example.net (Mode: normal)
91
- if e.start_with?('>>> ')
92
- # >>> DATA
93
- thecommand = Sisimai::SMTP::Command.find(e)
94
- elsif e.start_with?('<<< ')
95
- # <<< Response
96
- esmtpreply = e[4, e.size - 4]
97
- end
98
- else
99
- # Continued line of the value of Diagnostic-Code field
100
- next unless readslices[-2].start_with?('Diagnostic-Code:')
101
- next unless e.start_with?(' ')
102
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e[1, e.size])
103
- readslices[-1] = 'Diagnostic-Code: ' << e
104
- end
105
- end
106
- end
107
- return nil unless recipients > 0
108
-
109
- dscontents.each do |e|
110
- # Set default values if each value is empty.
111
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
112
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
113
- e['command'] = thecommand || ''
114
- if e['command'].empty?
115
- e['command'] = 'EHLO' unless esmtpreply.empty?
116
- end
117
- end
118
-
119
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
120
- end
121
- def description; return 'Bigfoot: http://www.bigfoot.com'; end
122
- end
123
- end
124
- end
125
-