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,269 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::X4 parses a bounce email which created by some qmail clone. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module X4
5
- class << self
6
- # MTA module for qmail clones
7
- require 'sisimai/lhost'
8
-
9
- Indicators = Sisimai::Lhost.INDICATORS
10
- Boundaries = ['--- Below this line is a copy of the message.', 'Original message follows.'].freeze
11
- StartingOf = {
12
- # qmail-remote.c:248| if (code >= 500) {
13
- # qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
14
- # qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
15
- # qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
16
- #
17
- # Characters: K,Z,D in qmail-qmqpc.c, qmail-send.c, qmail-rspawn.c
18
- # K = success, Z = temporary error, D = permanent error
19
- error: ['Remote host said:'],
20
- message: [
21
- 'He/Her is not ',
22
- 'unable to deliver your message to the following addresses',
23
- 'Su mensaje no pudo ser entregado',
24
- 'This is the machine generated message from mail service',
25
- 'This is the mail delivery agent at',
26
- 'Unable to deliver message to the following address',
27
- 'Unfortunately, your mail was not delivered to the following address:',
28
- 'Your mail message to the following address',
29
- 'Your message to the following addresses',
30
- "We're sorry.",
31
- ],
32
- rhost: ['Giving up on ', 'Connected to ', 'remote host '],
33
- }.freeze
34
- CommandSet = {
35
- # Error text regular expressions which defined in qmail-remote.c
36
- # qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
37
- 'conn' => [' but greeting failed.'],
38
- # qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
39
- 'ehlo' => [' but my name was rejected.'],
40
- # qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
41
- # reason = rejected
42
- 'mail' => [' but sender was rejected.'],
43
- # qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
44
- # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
45
- # reason = userunknown
46
- 'rcpt' => [' does not like recipient.'],
47
- # qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
48
- # qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
49
- # qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
50
- # qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
51
- 'data' => [' failed on DATA command', ' failed after I sent the message'],
52
- }.freeze
53
-
54
- ReSMTP = {
55
- # Error text regular expressions which defined in qmail-remote.c
56
- # qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
57
- 'conn' => %r/(?:Error:)?Connected to [^ ]+ but greeting failed[.]/,
58
- # qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
59
- 'ehlo' => %r/(?:Error:)?Connected to [^ ]+ but my name was rejected[.]/,
60
- # qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
61
- # reason = rejected
62
- 'mail' => %r/(?:Error:)?Connected to [^ ]+ but sender was rejected[.]/,
63
- # qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
64
- # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
65
- # reason = userunknown
66
- 'rcpt' => %r/(?:Error:)?[^ ]+ does not like recipient[.]/,
67
- # qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
68
- # qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
69
- # qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
70
- # qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
71
- 'data' => %r{(?:
72
- (?:Error:)?[^ ]+[ ]failed[ ]on[ ]DATA[ ]command[.]
73
- |(?:Error:)?[^ ]+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
74
- )
75
- }x,
76
- }.freeze
77
-
78
- # qmail-send.c:922| ... (&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem();
79
- HasExpired = 'this message has been in the queue too long.'
80
- OnHoldPair = [' does not like recipient.', 'this message has been in the queue too long.'].freeze
81
- FailOnLDAP = {
82
- # qmail-ldap-1.03-20040101.patch:19817 - 19866
83
- 'suspend' => ['Mailaddress is administrative?le?y disabled'], # 5.2.1
84
- 'userunknown' => ['Sorry, no mailbox here by that name'], # 5.1.1
85
- 'exceedlimit' => ['The message exeeded the maximum size the user accepts'], # 5.2.3
86
- 'systemerror' => [
87
- 'Automatic homedir creator crashed', # 4.3.0
88
- 'Illegal value in LDAP attribute', # 5.3.5
89
- 'LDAP attribute is not given but mandatory', # 5.3.5
90
- 'Timeout while performing search on LDAP server', # 4.4.3
91
- 'Too many results returned but needs to be unique', # 5.3.5
92
- 'Permanent error while executing qmail-forward', # 5.4.4
93
- 'Temporary error in automatic homedir creation', # 4.3.0 or 5.3.0
94
- 'Temporary error while executing qmail-forward', # 4.4.4
95
- 'Temporary failure in LDAP lookup', # 4.4.3
96
- 'Unable to contact LDAP server', # 4.4.3
97
- 'Unable to login into LDAP server, bad credentials',# 4.4.3
98
- ],
99
- }.freeze
100
- MessagesOf = {
101
- # qmail-local.c:589| strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)");
102
- # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
103
- 'userunknown' => ['no mailbox here by that name', 'does not like recipient.'],
104
- # error_str.c:192| X(EDQUOT,"disk quota exceeded")
105
- 'mailboxfull' => ['disk quota exceeded'],
106
- # qmail-qmtpd.c:233| ... result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";
107
- # qmail-smtpd.c:391| ... out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return;
108
- 'mesgtoobig' => ['Message size exceeds fixed maximum message size:'],
109
- # qmail-remote.c:68| Sorry, I couldn't find any host by that name. (#4.1.2)\n"); zerodie();
110
- # qmail-remote.c:78| Sorry, I couldn't find any host named ");
111
- 'hostunknown' => ["Sorry, I couldn't find any host "],
112
- 'systemfull' => ['Requested action not taken: mailbox unavailable (not enough free space)'],
113
- 'systemerror' => [
114
- 'bad interpreter: No such file or directory',
115
- 'system error',
116
- 'Unable to',
117
- ],
118
- 'networkerror' => [
119
- "Sorry, I wasn't able to establish an SMTP connection",
120
- "Sorry, I couldn't find a mail exchanger or IP address",
121
- "Sorry. Although I'm listed as a best-preference MX or A for that host",
122
- ],
123
- }.freeze
124
-
125
- # Parse bounce messages from Unknown MTA #4
126
- # @param [Hash] mhead Message headers of a bounce email
127
- # @param [String] mbody Message body of a bounce email
128
- # @return [Hash] Bounce data list and message/rfc822 part
129
- # @return [Nil] it failed to parse or the arguments are missing
130
- def inquire(mhead, mbody)
131
- # Pre process email headers and the body part of the message which generated by qmail, see
132
- # https://cr.yp.to/qmail.html
133
- # e.g.) Received: (qmail 12345 invoked for bounce); 29 Apr 2009 12:34:56 -0000
134
- # Subject: failure notice
135
- tryto = [['(qmail ', 'invoked for bounce)'], ['(qmail ', 'invoked from ', 'network)']].freeze
136
- match = 0
137
- match += 1 if mhead['subject'].start_with?('failure notice', 'Permanent Delivery Failure')
138
- mhead['received'].each do |e|
139
- # Received: (qmail 2222 invoked for bounce);29 Apr 2017 23:34:45 +0900
140
- # Received: (qmail 2202 invoked from network); 29 Apr 2018 00:00:00 +0900
141
- match += 1 if tryto.any? { |a| Sisimai::String.aligned(e, a) }
142
- end
143
- return nil unless match > 0
144
-
145
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
146
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
147
- bodyslices = emailparts[0].split("\n")
148
- readcursor = 0 # (Integer) Points the current cursor position
149
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
150
- v = nil
151
-
152
- while e = bodyslices.shift do
153
- # Read error messages and delivery status lines from the head of the email to the previous
154
- # line of the beginning of the original message.
155
- if readcursor == 0
156
- # Beginning of the bounce message or delivery status part
157
- readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| e.include?(a) }
158
- next
159
- end
160
- next if (readcursor & Indicators[:deliverystatus]) == 0
161
- next if e.empty?
162
-
163
- # <kijitora@example.jp>:
164
- # 192.0.2.153 does not like recipient.
165
- # Remote host said: 550 5.1.1 <kijitora@example.jp>... User Unknown
166
- # Giving up on 192.0.2.153.
167
- v = dscontents[-1]
168
-
169
- if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '>', ':'])
170
- # <kijitora@example.jp>:
171
- if v['recipient']
172
- # There are multiple recipient addresses in the message body.
173
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
174
- v = dscontents[-1]
175
- end
176
- v['recipient'] = Sisimai::Address.s3s4(e[e.index('<'), e.size])
177
- recipients += 1
178
-
179
- elsif dscontents.size == recipients
180
- # Append error message
181
- next if e.empty?
182
- v['diagnosis'] ||= ''
183
- v['diagnosis'] << e + ' '
184
- v['alterrors'] = e if e.start_with?(StartingOf[:error][0])
185
-
186
- next if v['rhost']
187
- StartingOf[:rhost].each do |r|
188
- # Find a remote host name
189
- p1 = e.index(r); next unless p1
190
- cm = r.size
191
- p2 = e.index(' ', p1 + cm + 1) || p2 = e.rindex('.')
192
-
193
- v['rhost'] = e[p1 + cm, p2 - p1 - cm]
194
- break
195
- end
196
- end
197
- end
198
- return nil unless recipients > 0
199
-
200
- dscontents.each do |e|
201
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
202
-
203
- unless e['command']
204
- # Get the SMTP command name for the session
205
- CommandSet.each_key do |r|
206
- # Verify each regular expression of SMTP commands
207
- next unless CommandSet[r].any? { |a| e['diagnosis'].include?(a) }
208
- e['command'] = r.upcase
209
- break
210
- end
211
-
212
- if e['diagnosis'].include?('Sorry, no SMTP connection got far enough; most progress was ')
213
- # Get the last SMTP command:from the error message
214
- e['command'] ||= Sisimai::SMTP::Command.find(e['diagnosis']) || ''
215
- end
216
- end
217
-
218
- # Detect the reason of bounce
219
- if e['command'] == 'MAIL'
220
- # MAIL | Connected to 192.0.2.135 but sender was rejected.
221
- e['reason'] = 'rejected'
222
-
223
- elsif %w[HELO EHLO].index(e['command'])
224
- # HELO | Connected to 192.0.2.135 but my name was rejected.
225
- e['reason'] = 'blocked'
226
- else
227
- # Try to match with each error message in the table
228
- if Sisimai::String.aligned(e['diagnosis'], OnHoldPair)
229
- # To decide the reason require pattern match with Sisimai::Reason::* modules
230
- e['reason'] = 'onhold'
231
- else
232
- MessagesOf.each_key do |r|
233
- # Verify each regular expression of session errors
234
- if e['alterrors']
235
- # Check the value of "alterrors"
236
- next unless MessagesOf[r].any? { |a| e['alterrors'].include?(a) }
237
- e['reason'] = r
238
- end
239
- break if e['reason']
240
-
241
- next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
242
- e['reason'] = r
243
- break
244
- end
245
-
246
- unless e['reason']
247
- FailOnLDAP.each_key do |r|
248
- # Verify each regular expression of LDAP errors
249
- next unless FailOnLDAP[r].any? { |a| e['diagnosis'].include?(a) }
250
- e['reason'] = r
251
- break
252
- end
253
- end
254
-
255
- unless e['reason']
256
- e['reason'] = 'expired' if e['diagnosis'].include?(HasExpired)
257
- end
258
- end
259
- end
260
- e['command'] ||= Sisimai::SMTP::Command.find(e['diagnosis'])
261
- end
262
-
263
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
264
- end
265
- def description; return 'Unknown MTA #4'; end
266
- end
267
- end
268
- end
269
-
@@ -1,112 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::X5 parses a bounce email which created by Unknown MTA #5. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module X5
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
-
12
- # Parse bounce messages from Unknown MTA #5
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
- match = 0
19
- match += 1 if mhead['to'].to_s.include?('NotificationRecipients')
20
- if mhead['from'].include?('TWFpbCBEZWxpdmVyeSBTdWJzeXN0ZW0')
21
- # From: "=?iso-2022-jp?B?TWFpbCBEZWxpdmVyeSBTdWJzeXN0ZW0=?=" <...>
22
- # Mail Delivery Subsystem
23
- mhead['from'].split(' ').each do |f|
24
- # Check each element of From: header
25
- next unless Sisimai::RFC2045.is_encoded(f)
26
- match += 1 if Sisimai::RFC2045.decodeH([f]).include?('Mail Delivery Subsystem')
27
- break
28
- end
29
- end
30
-
31
- if Sisimai::RFC2045.is_encoded(mhead['subject'])
32
- # Subject: =?iso-2022-jp?B?UmV0dXJuZWQgbWFpbDogVXNlciB1bmtub3du?=
33
- plain = Sisimai::RFC2045.decodeH([mhead['subject']])
34
- match += 1 if plain.include?('Mail Delivery Subsystem')
35
- end
36
- return nil if match < 2
37
-
38
- fieldtable = Sisimai::RFC1894.FIELDTABLE
39
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
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
- # Pick the second message/rfc822 part because the format of email-x5-*.eml is nested structure
46
- cutsbefore = mbody.split(Boundaries[0], 2)
47
- cutsbefore[1] = cutsbefore[1][cutsbefore[1].index("\n\n") + 2, cutsbefore[1].size]
48
- emailparts = Sisimai::RFC5322.part(cutsbefore[1], Boundaries)
49
- bodyslices = emailparts[0].split("\n")
50
-
51
- while e = bodyslices.shift do
52
- # Read error messages and delivery status lines from the head of the email to the previous
53
- # line of the beginning of the original message.
54
- readslices << e # Save the current line for the next loop
55
-
56
- if readcursor == 0
57
- # Beginning of the bounce message or message/delivery-status part
58
- readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
59
- next
60
- end
61
- next if (readcursor & Indicators[:deliverystatus]) == 0
62
- next if e.empty?
63
-
64
- v = dscontents[-1]
65
- if f = Sisimai::RFC1894.match(e)
66
- # "e" matched with any field defined in RFC3464
67
- next unless o = Sisimai::RFC1894.field(e)
68
- v = dscontents[-1]
69
-
70
- if o[-1] == 'addr'
71
- # Final-Recipient: rfc822; kijitora@example.jp
72
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
73
- if o[0] == 'final-recipient'
74
- # Final-Recipient: rfc822; kijitora@example.jp
75
- if v['recipient']
76
- # There are multiple recipient addresses in the message body.
77
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
78
- v = dscontents[-1]
79
- end
80
- v['recipient'] = o[2]
81
- recipients += 1
82
- else
83
- # X-Actual-Recipient: rfc822; kijitora@example.co.jp
84
- v['alias'] = o[2]
85
- end
86
- elsif o[-1] == 'code'
87
- # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
88
- v['spec'] = o[1]
89
- v['diagnosis'] = o[2]
90
- else
91
- # Other DSN fields defined in RFC3464
92
- next unless fieldtable[o[0]]
93
- v[fieldtable[o[0]]] = o[2]
94
- end
95
- else
96
- # Continued line of the value of Diagnostic-Code field
97
- next unless readslices[-2].start_with?('Diagnostic-Code:')
98
- next unless e.start_with?(' ')
99
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
100
- readslices[-1] = 'Diagnostic-Code: ' << e
101
- end
102
- end
103
- return nil unless recipients > 0
104
-
105
- dscontents.each { |e| e['diagnosis'] ||= Sisimai::String.sweep(e['diagnosis']) }
106
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
107
- end
108
- def description; return 'Unknown MTA #5'; end
109
- end
110
- end
111
- end
112
-
@@ -1,102 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Yahoo parses a bounce email which created by Yahoo! MAIL. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module Yahoo
5
- class << self
6
- require 'sisimai/lhost'
7
-
8
- Indicators = Sisimai::Lhost.INDICATORS
9
- Boundaries = ['--- Below this line is a copy of the message.'].freeze
10
- StartingOf = { message: ['Sorry, we were unable to deliver your message'] }.freeze
11
-
12
- # Parse bounce messages from Yahoo! MAIL
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-YMailISG: YtyUVyYWLDsbDh...
19
- # X-YMail-JAS: Pb65aU4VM1mei...
20
- # X-YMail-OSG: bTIbpDEVM1lHz...
21
- # X-Originating-IP: [192.0.2.9]
22
- return nil unless mhead['x-ymailisg']
23
-
24
- require 'sisimai/smtp/command'
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 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
- # Sorry, we were unable to deliver your message to the following address.
44
- #
45
- # <kijitora@example.org>:
46
- # Remote host said: 550 5.1.1 <kijitora@example.org>... User Unknown [RCPT_TO]
47
- v = dscontents[-1]
48
-
49
- if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '>:'])
50
- # <kijitora@example.org>:
51
- if v['recipient']
52
- # There are multiple recipient addresses in the message body.
53
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
54
- v = dscontents[-1]
55
- end
56
- v['recipient'] = Sisimai::Address.s3s4(e[0, e.index('>:')])
57
- v['diagnosis'] = ''
58
- recipients += 1
59
-
60
- else
61
- if e.start_with?('Remote host said:')
62
- # Remote host said: 550 5.1.1 <kijitora@example.org>... User Unknown [RCPT_TO]
63
- v['diagnosis'] = e
64
-
65
- # Get SMTP command from the value of "Remote host said:"
66
- v['command'] = Sisimai::SMTP::Command.find(e)
67
- else
68
- # <mailboxfull@example.jp>:
69
- # Remote host said:
70
- # 550 5.2.2 <mailboxfull@example.jp>... Mailbox Full
71
- # [RCPT_TO]
72
- if v['diagnosis'].start_with?('Remote host said:')
73
- # Remote host said:
74
- # 550 5.2.2 <mailboxfull@example.jp>... Mailbox Full
75
- if cv = Sisimai::SMTP::Command.find(e)
76
- # [RCPT_TO]
77
- v['command'] = cv
78
- else
79
- # 550 5.2.2 <mailboxfull@example.jp>... Mailbox Full
80
- v['diagnosis'] = e
81
- end
82
- else
83
- # Error message which does not start with 'Remote host said:'
84
- v['diagnosis'] << ' ' << e
85
- end
86
- end
87
- end
88
- end
89
- return nil unless recipients > 0
90
-
91
- dscontents.each do |e|
92
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].gsub(/\\n/, ' '))
93
- e['command'] ||= 'RCPT' if Sisimai::String.aligned(e['diagnosis'], ['<', '@', '>'])
94
- end
95
-
96
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
97
- end
98
- def description; return 'Yahoo! MAIL: https://www.yahoo.com'; end
99
- end
100
- end
101
- end
102
-
@@ -1,118 +0,0 @@
1
- module Sisimai::Lhost
2
- # Sisimai::Lhost::Yandex parses a bounce email which created by Yandex.Mail. Methods in the module
3
- # are called from only Sisimai::Message.
4
- module Yandex
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 the mail system at host yandex.ru.'] }.freeze
11
-
12
- # Parse bounce messages from Yandex.Mail
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-Yandex-Front: mxback1h.mail.yandex.net
19
- # X-Yandex-TimeMark: 1417885948
20
- # X-Yandex-Uniq: 92309766-f1c8-4bd4-92bc-657c75766587
21
- # X-Yandex-Spam: 1
22
- # X-Yandex-Forward: 10104c00ad0726da5f37374723b1e0c8
23
- # X-Yandex-Queue-ID: 367D79E130D
24
- # X-Yandex-Sender: rfc822; shironeko@yandex.example.com
25
- return nil unless mhead['x-yandex-uniq']
26
- return nil unless mhead['from'] == 'mailer-daemon@yandex.ru'
27
-
28
- fieldtable = Sisimai::RFC1894.FIELDTABLE
29
- permessage = {} # (Hash) Store values of each Per-Message field
30
-
31
- dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
32
- emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
33
- bodyslices = emailparts[0].split("\n")
34
- readslices = ['']
35
- readcursor = 0 # (Integer) Points the current cursor position
36
- recipients = 0 # (Integer) The number of 'Final-Recipient' header
37
- commandset = [] # (Array) ``in reply to * command'' list
38
- v = nil
39
-
40
- while e = bodyslices.shift do
41
- # Read error messages and delivery status lines from the head of the email to the previous
42
- # line of the beginning of the original message.
43
- readslices << e # Save the current line for the next loop
44
-
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
- # The line does not begin with a DSN field defined in RFC3464
88
- if e.include?(' (in reply to ') || e.include?('command)')
89
- # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
90
- cv = Sisimai::SMTP::Command.find(e)
91
- commandset << cv if cv
92
-
93
- else
94
- # Continued line of the value of Diagnostic-Code field
95
- next unless readslices[-2].start_with?('Diagnostic-Code:')
96
- next unless e.start_with?(' ')
97
- v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
98
- readslices[-1] = 'Diagnostic-Code: ' << e
99
- end
100
- end
101
- end
102
- return nil unless recipients > 0
103
-
104
- dscontents.each do |e|
105
- # Set default values if each value is empty.
106
- permessage.each_key { |a| e[a] ||= permessage[a] || '' }
107
-
108
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
109
- e['command'] ||= commandset.shift || Sisimai::SMTP::Command.find(e['diagnosis']) || ''
110
- end
111
-
112
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
113
- end
114
- def description; return 'Yandex.Mail: https://www.yandex.ru'; end
115
- end
116
- end
117
- end
118
-