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
@@ -33,7 +33,7 @@ module Sisimai
33
33
  # @param [Hash] mhead Message headers of a bounce email
34
34
  # @param [String] mbody Message body of a bounce email
35
35
  # @return [Hash] Bounce data list and message/rfc822 part
36
- # @return [Nil] it failed to parse or the arguments are missing
36
+ # @return [Nil] it failed to decode or the arguments are missing
37
37
  def inquire(mhead, mbody)
38
38
  leave = 0
39
39
  match = 0
@@ -85,7 +85,7 @@ module Sisimai
85
85
  break
86
86
  end
87
87
 
88
- if v['recipient']
88
+ if v["recipient"] != ""
89
89
  # Clean-up the recipient address
90
90
  v['recipient'] = Sisimai::Address.s3s4(v['recipient'])
91
91
  recipients += 1
@@ -98,7 +98,7 @@ module Sisimai
98
98
  MarkingsOf[:boundary] = q unless q.empty?
99
99
  end
100
100
 
101
- # BODY_PARSER: Get vacation message
101
+ # MESSAGE_BODY: Get the vacation message
102
102
  while e = bodyslices.shift do
103
103
  # Read the first 5 lines except a blank line
104
104
  countuntil += 1 if e.include?(MarkingsOf[:boundary])
@@ -2,7 +2,7 @@ module Sisimai
2
2
  # Sisimai::RFC5322 provide methods for checking email address.
3
3
  module RFC5322
4
4
  class << self
5
- require 'sisimai/string'
5
+ require 'sisimai/rfc791'
6
6
  require 'sisimai/address'
7
7
  HeaderTable = {
8
8
  :messageid => %w[message-id],
@@ -12,16 +12,7 @@ module Sisimai
12
12
  :addresser => %w[from return-path reply-to errors-to reverse-path x-postfix-sender envelope-from x-envelope-from],
13
13
  :recipient => %w[to delivered-to forward-path envelope-to x-envelope-to resent-to apparently-to],
14
14
  }.freeze
15
-
16
- build_flatten_rfc822header_list = lambda do
17
- # Convert HEADER: structured hash table to flatten hash table for being called from Sisimai::Lhost::*
18
- fv = {}
19
- HeaderTable.each_value do |e|
20
- e.each { |ee| fv[ee] = true }
21
- end
22
- return fv
23
- end
24
- HeaderIndex = build_flatten_rfc822header_list.call
15
+ def HEADERTABLE; return HeaderTable; end
25
16
 
26
17
  def FIELDINDEX
27
18
  return %w[
@@ -35,11 +26,10 @@ module Sisimai
35
26
 
36
27
  # Grouped RFC822 headers
37
28
  # @param [Symbol] group RFC822 Header group name
38
- # @return [Array,Hash] RFC822 Header list
29
+ # @return [Array] RFC822 Header list
39
30
  def HEADERFIELDS(group = '')
40
- return HeaderIndex if group.empty?
41
31
  return HeaderTable[group] if HeaderTable[group]
42
- return HeaderTable
32
+ return []
43
33
  end
44
34
 
45
35
  # Fields that might be long
@@ -129,7 +119,7 @@ module Sisimai
129
119
  next if token[e].nil?
130
120
  next if token[e].empty?
131
121
  next unless token[e].start_with?('[')
132
- token[e] = Sisimai::String.ipv4(token[e]).shift || ''
122
+ token[e] = Sisimai::RFC791.find(token[e]).shift || ''
133
123
  end
134
124
  token['from'] ||= ''
135
125
 
@@ -138,7 +128,7 @@ module Sisimai
138
128
  break if token['from'] == 'localhost'
139
129
  break if token['from'] == 'localhost.localdomain'
140
130
  break unless token['from'].include?('.') # A hostname without a domain name
141
- break unless Sisimai::String.ipv4(token['from']).empty?
131
+ break unless Sisimai::RFC791.find(token['from']).empty?
142
132
 
143
133
  # No need to rewrite token['from']
144
134
  right = true
@@ -223,7 +213,7 @@ module Sisimai
223
213
  # 1. Remove leading blank lines
224
214
  # 2. Remove text after the first blank line: \n\n
225
215
  # 3. Append "\n" at the end of test block when the last character is not "\n"
226
- latterpart.sub!(/\A[\r\n\s]+/, '')
216
+ latterpart.sub!(/\A\s+/, '')
227
217
  if keeps == false
228
218
  # Remove text after the first blank line: \n\n when "keeps" is false
229
219
  latterpart = latterpart[0, latterpart.index("\n\n")] if latterpart.include?("\n\n")
@@ -0,0 +1,69 @@
1
+ module Sisimai
2
+ # Sisimai::RFC791 is a class related to the Internet host
3
+ module RFC791
4
+ class << self
5
+ # Returns 1 if the argument is an IPv4 address
6
+ # @param [String] argv1 IPv4 address like "192.0.2.25"
7
+ # @return [Bool] 1: is an IPv4 address
8
+ # @since v5.2.0
9
+ def is_ipv4address(argv0)
10
+ return false if argv0.nil? || argv0.size < 7
11
+ octet = argv0.split(/[.]/); return false if octet.size != 4
12
+
13
+ octet.each do |e|
14
+ # Check each octet is between 0 and 255
15
+ return false unless e =~ /\A[0-9]{1,3}\z/
16
+ v = e.to_i
17
+ return false if v < 0 || v > 255
18
+ end
19
+ return true
20
+ end
21
+ # Find an IPv4 address from the given string
22
+ # @param [String] argv1 String including an IPv4 address
23
+ # @return [Array] List of IPv4 addresses
24
+ # @since v5.0.0
25
+ def find(argv0)
26
+ return nil if argv0.to_s.empty?
27
+ return [] if argv0.size < 7
28
+
29
+ ipv4a = []
30
+ %w|( ) [ ] ,|.each do |e|
31
+ # Rewrite: "mx.example.jp[192.0.2.1]" => "mx.example.jp 192.0.2.1"
32
+ p0 = argv0.index(e); next unless p0
33
+ argv0[p0, 1] = ' '
34
+ end
35
+
36
+ argv0.split(' ').each do |e|
37
+ # Find string including an IPv4 address
38
+ next unless e.index('.') # IPv4 address must include "." character
39
+
40
+ lx = e.size; next if lx < 7 || lx > 17 # 0.0.0.0 = 7, [255.255.255.255] = 17
41
+ cu = 0 # Cursor for seeking each octet of an IPv4 address
42
+ as = '' # ASCII Code of each character
43
+ eo = '' # Buffer of each octet of IPv4 Address
44
+
45
+ while cu < lx
46
+ # Check whether each character is a number or "." or not
47
+ as = e[cu, 1].ord
48
+ cu += 1
49
+
50
+ if as < 48 || as > 57
51
+ # The character is not a number(0-9)
52
+ break if as != 46 # The character is not "."
53
+ next if eo == '' # The current buffer is empty
54
+ break if eo.to_i > 255 # The current buffer is greater than 255
55
+ eo = ''
56
+ next
57
+ end
58
+ eo << as.chr
59
+ break if eo.to_i > 255
60
+ end
61
+ ipv4a << e if eo.size > 0 && eo.to_i < 256
62
+ end
63
+ return ipv4a
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,36 @@
1
+ module Sisimai
2
+ module Rhost
3
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
4
+ # of find() method when the value of "rhost" of the object is "*.aol.com". This class is called
5
+ # only from Sisimai::Fact class.
6
+ module Aol
7
+ class << self
8
+ MessagesOf = {
9
+ "hostunknown" => ["Host or domain name not found"],
10
+ "notaccept" => ["type=MX: Malformed or unexpected name server reply"],
11
+ }.freeze
12
+
13
+ # Detect bounce reason from Aol Mail: https://www.aol.com
14
+ # @param [Sisimai::Fact] argvs Decoded email object
15
+ # @return [String] The bounce reason for Aol
16
+ # @since v5.2.0
17
+ def find(argvs)
18
+ return "" if argvs["diagnosticcode"].empty?
19
+ issuedcode = argvs["diagnosticcode"]
20
+ reasontext = ""
21
+
22
+ MessagesOf.each_key do |e|
23
+ # Try to match the error message with message patterns defined in $MessagesOf
24
+ next unless MessagesOf[e].any? { |a| issuedcode.include?(a) }
25
+ reasontext = e
26
+ break
27
+ end
28
+
29
+ return reasontext
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,95 @@
1
+ module Sisimai
2
+ module Rhost
3
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
4
+ # of find() method when the value of "destination" of the object is "mail.icloud.com" or "apple.com".
5
+ # This class is called only Sisimai::Fact class.
6
+ module Apple
7
+ class << self
8
+ MessagesOf = {
9
+ 'authfailure' => [
10
+ # - 554 5.7.1 Your message was rejected due to example.jp's DMARC policy.
11
+ # See https://support.apple.com/en-us/HT204137 for
12
+ # - 554 5.7.1 [HME1] This message was blocked for failing both SPF and DKIM authentication
13
+ # checks. See https://support.apple.com/en-us/HT204137 for mailing best practices
14
+ 's dmarc policy',
15
+ 'blocked for failing both spf and dkim autentication checks',
16
+ ],
17
+ 'blocked' => [
18
+ # - 550 5.7.0 Blocked - see https://support.proofpoint.com/dnsbl-lookup.cgi?ip=192.0.1.2
19
+ # - 550 5.7.1 Your email was rejected due to having a domain present in the Spamhaus
20
+ # DBL -- see https://www.spamhaus.org/dbl/
21
+ # - 550 5.7.1 Mail from IP 192.0.2.1 was rejected due to listing in Spamhaus SBL.
22
+ # For details please see http://www.spamhaus.org/query/bl?ip=x.x.x.x
23
+ # - 554 ****-smtpin001.me.com ESMTP not accepting connections
24
+ 'rejected due to having a domain present in the spamhaus',
25
+ 'rejected due to listing in spamhaus',
26
+ 'blocked - see https://support.proofpoint.com/dnsbl-lookup',
27
+ 'not accepting connections',
28
+ ],
29
+ 'hasmoved' => [
30
+ # - 550 5.1.6 recipient no longer on server: *****@icloud.com
31
+ 'recipient no longer on server',
32
+ ],
33
+ 'mailboxfull' => [
34
+ # - 552 5.2.2 <****@icloud.com>: user is over quota (in reply to RCPT TO command)
35
+ 'user is over quota',
36
+ ],
37
+ 'norelaying' => [
38
+ # - 554 5.7.1 <*****@icloud.com>: Relay access denied
39
+ 'relay access denied',
40
+ ],
41
+ 'notaccept' => ['host/domain does not accept mail'],
42
+ 'policyviolation' => [
43
+ # - 550 5.7.1 [CS01] Message rejected due to local policy.
44
+ # Please visit https://support.apple.com/en-us/HT204137
45
+ 'due to local policy',
46
+ ],
47
+ 'rejected' => [
48
+ # - 450 4.1.8 <kijitora@example.jp>: Sender address rejected: Domain not found
49
+ 'sender address rejected',
50
+ ],
51
+ 'speeding' => [
52
+ # - 421 4.7.1 Messages to ****@icloud.com deferred due to excessive volume.
53
+ # Try again later - https://support.apple.com/en-us/HT204137
54
+ 'due to excessive volume',
55
+ ],
56
+ 'userunknown' => [
57
+ # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
58
+ # - 550 5.1.1 unknown or illegal alias: ****@icloud.com
59
+ 'inactive email address',
60
+ 'user does not exist',
61
+ 'unknown or illegal alias',
62
+ ],
63
+ }.freeze
64
+
65
+ # Detect bounce reason from Apple iCloud Mail
66
+ # @param [Sisimai::Fact] argvs Decoded email object
67
+ # @return [String] The bounce reason for Apple
68
+ # @see https://support.apple.com/en-us/102322
69
+ # https://www.postmastery.com/icloud-postmastery-page/
70
+ # https://smtpfieldmanual.com/provider/apple
71
+ # @since v5.1.0
72
+ def find(argvs)
73
+ return '' unless argvs
74
+ return '' unless argvs['diagnosticcode'].size > 0
75
+
76
+ issuedcode = argvs['diagnosticcode'].downcase
77
+ reasontext = ''
78
+
79
+ MessagesOf.each_key do |e|
80
+ MessagesOf[e].each do |f|
81
+ next unless issuedcode.include?(f)
82
+ reasontext = e
83
+ break
84
+ end
85
+ break if reasontext.size > 0
86
+ end
87
+
88
+ return reasontext
89
+ end
90
+
91
+ end
92
+ end
93
+ end
94
+ end
95
+
@@ -1,21 +1,59 @@
1
1
  module Sisimai
2
2
  module Rhost
3
3
  # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
4
- # of get() method when the value of "destination" of the object is "charter.net". This class is
4
+ # of find() method when the value of "destination" of the object is "charter.net". This class is
5
5
  # called only Sisimai::Fact class.
6
6
  module Cox
7
7
  class << self
8
8
  ErrorCodes = {
9
- # https://www.cox.com/residential/support/email-error-codes.html
10
- 'CXBL' => 'blocked', # The sending IP address has been blocked by Cox due to exhibiting spam-like behavior.
9
+ # CXBL
10
+ # - The sending IP address has been blocked by Cox due to exhibiting spam-like behavior.
11
+ # - Send an email request to Cox to ask for a sending IP address be unblocked.
12
+ # Note: Cox has sole discretion whether to unblock the sending IP address.
13
+ 'CXBL' => 'blocked',
14
+
15
+ # CXDNS
16
+ # - There was an issue with the connecting IP address Domain Name System (DNS).
17
+ # - The Reverse DNS (rDNS) lookup for your IP address is failing.
18
+ # - Confirm the IP address that sends your email.
19
+ # - Check the rDNS of that IP address. If it passes, then wait 24 hours and try resending
20
+ # your email.
21
+ 'CXDNS' => 'requireptr',
22
+
23
+ # CXSNDR
24
+ # - There was a problem with the sender's domain.
25
+ # - Your email failed authentication checks against your sending domain's SPF, DomainKeys,
26
+ # or DKIM policy.
27
+ 'CXSNDR' => 'authfailure',
28
+
29
+ # CXSMTP
30
+ # - There was a violation of SMTP protocol.
31
+ # - Your email wasn't delivered because Cox was unable to verify that it came from a
32
+ # legitimate email sender.
33
+ 'CXSMTP' => 'rejected',
34
+
35
+ # CXCNCT
36
+ # - There was a connection issue from the IP address.
37
+ # - There is a limit to the number of concurrent SMTP connections per IP address to
38
+ # protect the systems against attack. Ensure that the sending email server is not
39
+ # opening more than 10 concurrent connections to avoid reaching this limit.
40
+ 'CXCNCT' => 'toomanyconn',
41
+
42
+ # CXMXRT
43
+ # - The sender has sent email to too many recipients and needs to wait before sending
44
+ # more email.
45
+ # - The email sender has exceeded the maximum number of sent email allowed.
46
+ 'CXMXRT' => 'toomanyconn',
47
+
48
+ # CDRBL
49
+ # - The sending IP address has been temporarily blocked by Cox due to exhibiting spam-like
50
+ # behavior.
51
+ # - The block duration varies depending on reputation and other factors, but will not exceed
52
+ # 24 hours. Inspect email traffic for potential spam, and retry email delivery.
53
+ 'CDRBL' => 'blocked',
54
+
11
55
  'CXTHRT' => 'securityerror', # Email sending limited due to suspicious account activity.
12
56
  'CXMJ' => 'securityerror', # Email sending blocked due to suspicious account activity on primary Cox account.
13
- 'CXDNS' => 'blocked', # There was an issue with the connecting IP address Domain Name System (DNS).
14
- 'CXSNDR' => 'rejected', # There was a problem with the sender's domain.
15
- 'CXSMTP' => 'rejected', # Your email wasn't delivered because Cox was unable to verify that it came from a legitimate email sender.
16
- 'CXCNCT' => 'toomanyconn', # There is a limit to the number of concurrent SMTP connections per IP address
17
- 'CXMXRT' => 'toomanyconn', # The email sender has exceeded the maximum number of sent email allowed.
18
- 'CDRBL' => 'blocked', # The sending IP address has been temporarily blocked by Cox due to exhibiting spam-like behavior.
19
57
  'IPBL0001' => 'blocked', # The sending IP address is listed in the Spamhaus Zen DNSBL.
20
58
  'IPBL0010' => 'blocked', # The sending IP is listed in the Return Path DNSBL.
21
59
  'IPBL0100' => 'blocked', # The sending IP is listed in the Invaluement ivmSIP DNSBL.
@@ -32,6 +70,7 @@ module Sisimai
32
70
  'IPBL1110' => 'blocked', # The sending IP is in the Cloudmark CSI, Return Path and Invaluement ivmSIP DNSBLs.
33
71
  'IPBL1111' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
34
72
  'IPBL00001' => 'blocked', # The sending IP address is listed on a Spamhaus blacklist. Check your status at Spamhaus.
73
+
35
74
  'URLBL011' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and Spamhaus DBL.
36
75
  'URLBL101' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and ivmURI.
37
76
  'URLBL110' => 'spamdetected', # A URL within the body of the message was found on blocklists Spamhaus DBL and ivmURI.
@@ -39,63 +78,74 @@ module Sisimai
39
78
  }.freeze
40
79
  MessagesOf = {
41
80
  'blocked' => [
42
- # Cox requires that all connecting email servers contain valid reverse DNS PTR records.
43
- 'rejected - no rDNS',
44
- # An email client has repeatedly sent bad commands or invalid passwords resulting in a three-hour block of the client's IP address.
81
+ # - An email client has repeatedly sent bad commands or invalid passwords resulting in
82
+ # a three-hour block of the client's IP address.
83
+ # - The sending IP address has exceeded the threshold of invalid recipients and has
84
+ # been blocked.
45
85
  'cox too many bad commands from',
46
- # The reverse DNS check of the sending server IP address has failed.
47
- 'DNS check failure - try again later',
48
- # The sending IP address has exceeded the threshold of invalid recipients and has been blocked.
49
- 'Too many invalid recipients',
86
+ 'too many invalid recipients',
50
87
  ],
51
- 'notaccept' => [
52
- # Our systems are experiencing an issue which is causing a temporary inability to accept new email.
53
- 'ESMTP server temporarily not available',
88
+ 'requireptr' => [
89
+ # - The reverse DNS check of the sending server IP address has failed.
90
+ # - Cox requires that all connecting email servers contain valid reverse DNS PTR records.
91
+ 'dns check failure - try again later',
92
+ 'rejected - no rdns',
54
93
  ],
55
94
  'policyviolation' => [
56
- # The sending server has attempted to communicate too soon within the SMTP transaction
57
- 'ESMTP no data before greeting',
58
- # The message has been rejected because it contains an attachment with one of the following prohibited
59
- # file types, which commonly contain viruses: .shb, .shs, .vbe, .vbs, .wsc, .wsf, .wsh, .pif, .msc,
60
- # .msi, .msp, .reg, .sct, .bat, .chm, .isp, .cpl, .js, .jse, .scr, .exe.
95
+ # - The sending server has attempted to communicate too soon within the SMTP transaction
96
+ # - The message has been rejected because it contains an attachment with one of the
97
+ # following prohibited file types, which commonly contain viruses: .shb, .shs, .vbe,
98
+ # .vbs, .wsc, .wsf, .wsh, .pif, .msc, .msi, .msp, .reg, .sct, .bat, .chm, .isp, .cpl,
99
+ # .js, .jse, .scr, .exe.
100
+ 'esmtp no data before greeting',
61
101
  'attachment extension is forbidden',
62
102
  ],
63
103
  'rejected' => [
64
104
  # Cox requires that all sender domains resolve to a valid MX or A-record within DNS.
65
105
  'sender rejected',
66
106
  ],
107
+ 'systemerror' => [
108
+ # - Our systems are experiencing an issue which is causing a temporary inability to
109
+ # accept new email.
110
+ 'esmtp server temporarily not available',
111
+ ],
67
112
  'toomanyconn' => [
68
- # The sending IP address has exceeded the five maximum concurrent connection limit.
113
+ # - The sending IP address has exceeded the five maximum concurrent connection limit.
114
+ # - The SMTP connection has exceeded the 100 email message threshold and was disconnected.
115
+ # - The sending IP address has exceeded one of these rate limits and has been temporarily
116
+ # blocked.
69
117
  'too many sessions from',
70
- # The SMTP connection has exceeded the 100 email message threshold and was disconnected.
71
118
  'requested action aborted: try again later',
72
- # The sending IP address has exceeded one of these rate limits and has been temporarily blocked.
73
- 'Message threshold exceeded',
119
+ 'message threshold exceeded',
74
120
  ],
75
121
  'userunknown' => [
76
- 'recipient rejected', # The intended recipient is not a valid Cox Email account.
122
+ # - The intended recipient is not a valid Cox Email account.
123
+ 'recipient rejected',
77
124
  ],
78
125
  }.freeze
79
126
 
80
127
  # Detect bounce reason from https://cox.com/
81
- # @param [Sisimai::Fact] argvs Parsed email object
128
+ # @param [Sisimai::Fact] argvs Decoded email object
82
129
  # @return [String, Nil] The bounce reason at Cox
130
+ # @see https://www.cox.com/residential/support/email-error-codes.html
83
131
  # @since v4.25.8
84
- def get(argvs)
85
- statusmesg = argvs['diagnosticcode']
132
+ def find(argvs)
133
+ return "" if argvs["diagnosticcode"].empty?
134
+ issuedcode = argvs['diagnosticcode']
86
135
  codenumber = 0
87
136
 
88
- if cv = statusmesg.match(/AUP#([0-9A-Z]+)/)
137
+ if cv = issuedcode.match(/AUP#([0-9A-Z]+)/)
89
138
  # Capture the numeric part of the error code
90
139
  codenumber = cv[1]
91
140
  end
92
141
  reasontext = ErrorCodes[codenumber] || ''
93
142
 
143
+ issuedcode = argvs['diagnosticcode'].downcase
94
144
  if reasontext.empty?
95
145
  # The error code was not found in ErrorCodes
96
146
  MessagesOf.each_key do |e|
97
147
  # Try to find with each error message defined in MessagesOf
98
- next unless MessagesOf[e].any? { |a| statusmesg.include?(a) }
148
+ next unless MessagesOf[e].any? { |a| issuedcode.include?(a) }
99
149
  reasontext = e
100
150
  break
101
151
  end
@@ -0,0 +1,100 @@
1
+ module Sisimai
2
+ module Rhost
3
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
4
+ # of find() method when the value of "rhost" of the object is "*.facebook.com". This class is
5
+ # called only from Sisimai::Fact class.
6
+ module Facebook
7
+ class << self
8
+ ErrorCodes = {
9
+ # http://postmaster.facebook.com/response_codes
10
+ # NOT TESTD EXCEPT RCP-P2
11
+ "authfailure" => [
12
+ "POL-P7", # The message does not comply with Facebook's Domain Authentication requirements.
13
+ ],
14
+ "blocked" => [
15
+ "POL-P1", # Your mail server's IP Address is listed on the Spamhaus PBL.
16
+ "POL-P2", # Facebook will no longer accept mail from your mail server's IP Address.
17
+ "POL-P3", # Facebook is not accepting messages from your mail server. This will persist for 4 to 8 hours.
18
+ "POL-P4", # Facebook is not accepting messages from your mail server. This will persist for 24 to 48 hours.
19
+ "POL-T1", # Facebook is not accepting messages from your mail server, but they may be retried later. This will persist for 1 to 2 hours.
20
+ "POL-T2", # Facebook is not accepting messages from your mail server, but they may be retried later. This will persist for 4 to 8 hours.
21
+ "POL-T3", # Facebook is not accepting messages from your mail server, but they may be retried later. This will persist for 24 to 48 hours.
22
+ ],
23
+ "contenterror" => [
24
+ "MSG-P2", # The message contains an attachment type that Facebook does not accept.
25
+ ],
26
+ "filtered" => [
27
+ "RCP-P2", # The attempted recipient's preferences prevent messages from being delivered.
28
+ "RCP-P3", # The attempted recipient's privacy settings blocked the delivery.
29
+ ],
30
+ "mesgtoobig" => [
31
+ "MSG-P1", # The message exceeds Facebook's maximum allowed size.
32
+ "INT-P2", # The message exceeds Facebook's maximum allowed size.
33
+ ],
34
+ "notcompliantrfc" => [
35
+ "MSG-P3", # The message contains multiple instances of a header field that can only be present once.
36
+ ],
37
+ "rejected" => [
38
+ "DNS-P1", # Your SMTP MAIL FROM domain does not exist.
39
+ "DNS-P2", # Your SMTP MAIL FROM domain does not have an MX record.
40
+ "DNS-T1", # Your SMTP MAIL FROM domain exists but does not currently resolve.
41
+ ],
42
+ "requireptr" => [
43
+ "DNS-P3", # Your mail server does not have a reverse DNS record.
44
+ "DNS-T2", # You mail server's reverse DNS record does not currently resolve.
45
+ ],
46
+ "spamdetected" => [
47
+ "POL-P6", # The message contains a url that has been blocked by Facebook.
48
+ "POL-P7", # The message does not comply with Facebook's abuse policies and will not be accepted.
49
+ ],
50
+ "suspend" => [
51
+ "RCP-T4", # The attempted recipient address is currently deactivated. The user may or may not reactivate it.
52
+ ],
53
+ "systemerror" => [
54
+ "RCP-T1", # The attempted recipient address is not currently available due to an internal system issue. This is a temporary condition.
55
+ ],
56
+ "toomanyconn" => [
57
+ "CON-T1", # Facebook's mail server currently has too many connections open to allow another one.
58
+ "CON-T2", # Your mail server currently has too many connections open to Facebook's mail servers.
59
+ "CON-T3", # Your mail server has opened too many new connections to Facebook's mail servers in a short period of time.
60
+ "CON-T4", # Your mail server has exceeded the maximum number of recipients for its current connection.
61
+ "MSG-T1", # The number of recipients on the message exceeds Facebook's allowed maximum.
62
+ ],
63
+ "userunknown" => [
64
+ "RCP-P1", # The attempted recipient address does not exist.
65
+ "INT-P1", # The attempted recipient address does not exist.
66
+ "INT-P3", # The attempted recpient group address does not exist.
67
+ "INT-P4", # The attempted recipient address does not exist.
68
+ ],
69
+ "virusdetected" => [
70
+ "POL-P5", # The message contains a virus.
71
+ ],
72
+ }.freeze
73
+
74
+ # Detect bounce reason from Facebook
75
+ # @param [Sisimai::Fact] argvs Decoded email object
76
+ # @return [String] The bounce reason for Facebook
77
+ # @since v5.2.0
78
+ def find(argvs)
79
+ return "" if argvs["diagnosticcode"].empty?
80
+ return "" if argvs["diagnosticcode"].include?("-") == false
81
+
82
+ errorindex = argvs["diagnosticcode"].index("-")
83
+ errorlabel = argvs["diagnosticcode"][errorindex - 3, 6]
84
+ reasontext = ''
85
+
86
+ ErrorCodes.each_key do |e|
87
+ # The key is a bounce reason name
88
+ next unless ErrorCodes[e].any? { |a| errorlabel == a }
89
+ reasontext = e
90
+ break
91
+ end
92
+
93
+ return reasontext
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end
100
+