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,6 +1,7 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::V5sendmail parses a bounce email which created by Sendmail version 5. Methods in
3
- # the module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::V5sendmail decodes a bounce email which created by Sendmail version 5 or any
3
+ # email appliances based on Sendmail version 5.
4
+ # Methods in the module are called from only Sisimai::Message.
4
5
  module V5sendmail
5
6
  class << self
6
7
  require 'sisimai/lhost'
@@ -24,15 +25,15 @@ module Sisimai::Lhost
24
25
  # savemail.c:497| while (fgets(buf, sizeof buf, xfile) != NULL)
25
26
  # savemail.c:498| putline(buf, fp, m);
26
27
  # savemail.c:499| (void) fclose(xfile);
27
- error: [' while talking to '],
28
+ error: ['While talking to '],
28
29
  message: ['----- Transcript of session follows -----'],
29
30
  }.freeze
30
31
 
31
- # Parse bounce messages from Sendmail version 5
32
+ # @abstract Decodes the bounce message from Sendmail version 5
32
33
  # @param [Hash] mhead Message headers of a bounce email
33
34
  # @param [String] mbody Message body of a bounce email
34
35
  # @return [Hash] Bounce data list and message/rfc822 part
35
- # @return [Nil] it failed to parse or the arguments are missing
36
+ # @return [Nil] it failed to decode or the arguments are missing
36
37
  def inquire(mhead, mbody)
37
38
  # :from => %r/\AMail Delivery Subsystem/,
38
39
  return nil unless mhead['subject'].start_with?('Returned mail: ')
@@ -40,15 +41,15 @@ module Sisimai::Lhost
40
41
  emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
41
42
  return nil unless emailparts[1].size > 0
42
43
 
44
+ require 'sisimai/rfc1123'
43
45
  require 'sisimai/smtp/command'
44
46
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
45
47
  bodyslices = emailparts[0].split("\n")
46
48
  readcursor = 0 # (Integer) Points the current cursor position
47
49
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
48
- anotherset = {} # (Hash) Another error information
49
- responding = [] # (Array) Responses from remote server
50
- commandset = [] # (Array) SMTP command which is sent to remote server
51
- errorindex = -1 # (Integer)
50
+ anotherone = {} # (Hash) Another error information
51
+ remotehost = "" # The last remote hostname
52
+ curcommand = "" # The last SMTP command
52
53
  v = nil
53
54
 
54
55
  while e = bodyslices.shift do
@@ -69,75 +70,103 @@ module Sisimai::Lhost
69
70
  # 550 <kijitora@example.org>... User unknown
70
71
  # 421 example.org (smtp)... Deferred: Connection timed out during user open with example.org
71
72
  v = dscontents[-1]
73
+ curcommand = Sisimai::SMTP::Command.find(e) if e.start_with?(">>> ")
72
74
 
73
- if e.start_with?('5', '4') && Sisimai::String.aligned(e, [' <', '@', '>...'])
75
+ if Sisimai::String.aligned(e, [' <', '@', '>...']) || e.upcase.include?(">>> RCPT TO:")
74
76
  # 550 <kijitora@example.org>... User unknown
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
- p1 = e.index('<', 0)
81
- p2 = e.index('>...')
82
- v['recipient'] = e[p1 + 1, p2 - p1 - 1]
83
- v['diagnosis'] = e[p2 + 5, e.size]
84
-
85
- # Concatenate the response of the server and error message
86
- v['diagnosis'] << ': ' << responding[recipients] if responding[recipients]
87
- recipients += 1
88
-
89
- elsif e.start_with?('>>> ')
90
77
  # >>> RCPT To:<kijitora@example.org>
91
- cv = Sisimai::SMTP::Command.find(e); commandset[recipients] = cv if cv
92
-
93
- elsif e.start_with?('<<< ')
94
- # <<< Response
95
- # <<< 501 <shironeko@example.co.jp>... no access from mail server [192.0.2.55] which is an open relay.
96
- # <<< 550 Requested User Mailbox not found. No such user here.
97
- responding[recipients] = e[4, e.size]
78
+ p0 = e.index(" ")
79
+ p1 = e.index("<", p0)
80
+ p2 = e.index(">", p1)
81
+ cv = Sisimai::Address.s3s4(e[p1, p2 - p1 + 1])
82
+
83
+ if remotehost == ""
84
+ # Keep error messages before "While talking to ..." line
85
+ anotherone[recipients] ||= ""; anotherone[recipients] << " " << e
86
+ next
87
+ end
98
88
 
89
+ if cv == v["recipient"] || (curcommand == "MAIL" && e.start_with?("<<< "))
90
+ # The recipient address is the same address with the last appeared address
91
+ # like "550 <mikeneko@example.co.jp>... User unknown"
92
+ # Append this line to the string which is keeping error messages
93
+ v["diagnosis"] << " " << e
94
+ v["replycode"] = Sisimai::SMTP::Reply.find(e)
95
+ curcommand = ""
96
+ else
97
+ # The recipient address in this line differs from the last appeared address
98
+ # or is the first recipient address in this bounce message
99
+ if v["recipient"] != ""
100
+ # There are multiple recipient addresses in the message body.
101
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
102
+ v = dscontents[-1]
103
+ end
104
+ recipients += 1
105
+ v["recipient"] = cv
106
+ v["rhost"] = remotehost
107
+ v["replycode"] = Sisimai::SMTP::Reply.find(e)
108
+ v["diagnosis"] << " " << e
109
+ v["command"] = curcommand if v["command"].empty?
110
+ end
99
111
  else
100
- # Detect SMTP session error or connection error
101
- next if v['sessionerr']
102
-
112
+ # This line does not include a recipient address
103
113
  if e.include?(StartingOf[:error][0])
104
- # ----- Transcript of session follows -----
105
114
  # ... while talking to mta.example.org.:
106
- v['sessionerr'] = true
107
- next
108
- end
109
-
110
- if e.start_with?('4', '5') && e.include?('... ')
111
- # 421 example.org (smtp)... Deferred: Connection timed out during user open with example.org
112
- anotherset['replycode'] = e[0, 3]
113
- anotherset['diagnosis'] = e[e.index('... ') + 4, e.size]
115
+ cv = Sisimai::RFC1123.find(e)
116
+ remotehost = cv if Sisimai::RFC1123.is_internethost(cv)
117
+ else
118
+ # Append this line into the error message string
119
+ if e.start_with?(">>> ", "<<< ")
120
+ # >>> DATA
121
+ # <<< 550 Your E-Mail is redundant. You cannot send E-Mail to yourself (shironeko@example.jp).
122
+ # >>> QUIT
123
+ # <<< 421 dns.example.org Sorry, unable to contact destination SMTP daemon.
124
+ # <<< 550 Requested User Mailbox not found. No such user here.
125
+ v["diagnosis"] << " " << e
126
+ else
127
+ # 421 Other error message
128
+ anotherone[recipients] ||= ""; anotherone[recipients] << " " << e
129
+ end
114
130
  end
115
131
  end
116
132
  end
117
133
 
118
- p1 = emailparts[1].index("\nTo: ") || -1
119
- p2 = emailparts[1].index("\n", p1 + 6) || -1
120
- if recipients == 0 && p1 > 0
121
- # Get the recipient address from "To:" header at the original message
122
- dscontents[0]['recipient'] = Sisimai::Address.s3s4(emailparts[1][p1, p2 - p1 - 5])
123
- recipients = 1
134
+ if recipients == 0
135
+ # There is no recipient address in the error message
136
+ anotherone.each_key do |e|
137
+ # Try to pick an recipient address, a reply code, and error messages
138
+ cv = Sisimai::Address.s3s4(anotherone[e]); next unless Sisimai::Address.is_emailaddress(cv)
139
+ cr = Sisimai::SMTP::Reply.find(anotherone[e])
140
+
141
+ dscontents[e]["recipient"] = cv
142
+ dscontents[e]["replycode"] = cr
143
+ dscontents[e]["diagnosis"] = anotherone[e]
144
+ recipients += 1
145
+ end
146
+
147
+ if recipients == 0
148
+ # Try to pick an recipient address from the original message
149
+ p1 = emailparts[1].index("\nTo: ") || -1
150
+ p2 = emailparts[1].index("\n", p1 + 6) || -1
151
+
152
+ if p1 > 0
153
+ # Get the recipient address from "To:" header at the original message
154
+ cv = Sisimai::Address.s3s4(emailparts[1][p1, p2 - p1 - 5])
155
+ return nil unless Sisimai::Address.is_emailaddress(cv)
156
+ dscontents[0]["recipient"] = cv
157
+ recipients += 1
158
+ end
159
+ end
124
160
  end
125
161
  return nil unless recipients > 0
126
162
 
127
- dscontents.each do |e|
128
- errorindex += 1
129
- e.delete('sessionerr')
130
-
131
- e['diagnosis'] ||= if anotherset['diagnosis'].to_s.size > 0
132
- # Copy alternative error message
133
- anotherset['diagnosis']
134
- else
135
- # Set server response as a error message
136
- responding[errorindex]
137
- end
138
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
139
- e['replycode'] = Sisimai::SMTP::Reply.find(e['diagnosis']) || anotherset['replycode']
140
- e['command'] = commandset[errorindex] || Sisimai::SMTP::Command.find(e['diagnosis']) || ''
163
+ j = 0; dscontents.each do |e|
164
+ # Tidy up the error message in e.Diagnosis
165
+ e["diagnosis"] = anotherone[j] if e["diagnosis"].empty?
166
+ e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
167
+ e["command"] = Sisimai::SMTP::Command.find(e["diagnosis"]) if e["command"].empty?
168
+ e["replycode"] = Sisimai::SMTP::Reply.find(e["diagnosis"])
169
+ e["replycode"] = Sisimai::SMTP::Reply.find(anotherone[j]) if e["replycode"].empty?
141
170
 
142
171
  # @example.jp, no local part
143
172
  # Get email address from the value of Diagnostic-Code header
@@ -1,16 +1,16 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Verizon parses a bounce email which created by Verizon Wireless. Methods in the
3
- # module are called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Verizon decodes a bounce email which created by Verizon https://www.verizon.com/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Verizon
5
5
  class << self
6
6
  require 'sisimai/lhost'
7
7
  Indicators = Sisimai::Lhost.INDICATORS
8
8
 
9
- # Parse bounce messages from Verizon
9
+ # @abstract Decodes the bounce message from Verizon
10
10
  # @param [Hash] mhead Message headers of a bounce email
11
11
  # @param [String] mbody Message body of a bounce email
12
12
  # @return [Hash] Bounce data list and message/rfc822 part
13
- # @return [Nil] it failed to parse or the arguments are missing
13
+ # @return [Nil] it failed to decode or the arguments are missing
14
14
  def inquire(mhead, mbody)
15
15
  match = -1
16
16
  while true
@@ -64,7 +64,7 @@ module Sisimai::Lhost
64
64
  # RCPT TO: *****@vtext.com
65
65
  v = dscontents[-1]
66
66
  if e.start_with?(' RCPT TO: ')
67
- if v['recipient']
67
+ if v["recipient"] != ""
68
68
  # There are multiple recipient addresses in the message body.
69
69
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
70
70
  v = dscontents[-1]
@@ -112,7 +112,7 @@ module Sisimai::Lhost
112
112
  # Date: Wed, 20 Jun 2013 10:29:52 +0000
113
113
  v = dscontents[-1]
114
114
  if e.start_with?('To: ')
115
- if v['recipient']
115
+ if v["recipient"] != ""
116
116
  # There are multiple recipient addresses in the message body.
117
117
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
118
118
  v = dscontents[-1]
@@ -1,5 +1,5 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X1 parses a bounce email which created by Unknown MTA #1. Methods in the module
2
+ # Sisimai::Lhost::X1 decodes a bounce email which created by Unknown MTA #1. Methods in the module
3
3
  # are called from only Sisimai::Message.
4
4
  module X1
5
5
  class << self
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['Received: from '].freeze
10
10
  MarkingsOf = { message: ['The original message was received at '] }.freeze
11
11
 
12
- # Parse bounce messages from Unknown MTA #1
12
+ # @abstract Decodes the bounce message from Unknown MTA #1
13
13
  # @param [Hash] mhead Message headers of a bounce email
14
14
  # @param [String] mbody Message body of a bounce email
15
15
  # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
16
+ # @return [Nil] it failed to decode or the arguments are missing
17
17
  def inquire(mhead, mbody)
18
18
  return nil unless mhead['subject'].start_with?('Returned Mail: ')
19
19
  return nil unless mhead['from'].start_with?('"Mail Deliver System" ')
@@ -47,7 +47,7 @@ module Sisimai::Lhost
47
47
 
48
48
  if Sisimai::String.aligned(e, ['@', ' [', ']'])
49
49
  # kijitora@example.co.jp [User unknown]
50
- if v['recipient']
50
+ if v["recipient"] != ""
51
51
  # There are multiple recipient addresses in the message body.
52
52
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
53
53
  v = dscontents[-1]
@@ -1,5 +1,5 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X2 parses a bounce email which created by Unknown MTA #2. Methods in the module
2
+ # Sisimai::Lhost::X2 decodes a bounce email which created by Unknown MTA #2. Methods in the module
3
3
  # are called from only Sisimai::Message.
4
4
  module X2
5
5
  class << self
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['--- Original message follows.'].freeze
10
10
  StartingOf = { message: ['Unable to deliver message to the following address'] }.freeze
11
11
 
12
- # Parse bounce messages from Unknown MTA #2
12
+ # @abstract Decodes the bounce message from Unknown MTA #2
13
13
  # @param [Hash] mhead Message headers of a bounce email
14
14
  # @param [String] mbody Message body of a bounce email
15
15
  # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
16
+ # @return [Nil] it failed to decode or the arguments are missing
17
17
  def inquire(mhead, mbody)
18
18
  match = nil
19
19
  match ||= 1 if mhead['from'].include?('MAILER-DAEMON@')
@@ -49,7 +49,7 @@ module Sisimai::Lhost
49
49
 
50
50
  if e.start_with?('<') && Sisimai::String.aligned(e, ['<', '@', '>', ':'])
51
51
  # <kijitora@example.com>:
52
- if v['recipient']
52
+ if v["recipient"] != ""
53
53
  # There are multiple recipient addresses in the message body.
54
54
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
55
55
  v = dscontents[-1]
@@ -58,7 +58,6 @@ module Sisimai::Lhost
58
58
  recipients += 1
59
59
  else
60
60
  # This user doesn't have a example.com account (kijitora@example.com) [0]
61
- v['diagnosis'] ||= ''
62
61
  v['diagnosis'] << ' ' << e
63
62
  end
64
63
  end
@@ -1,5 +1,5 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X3 parses a bounce email which created by Unknown MTA #3. Methods in the module
2
+ # Sisimai::Lhost::X3 decodes a bounce email which created by Unknown MTA #3. Methods in the module
3
3
  # are called from only Sisimai::Message.
4
4
  module X3
5
5
  class << self
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['Content-Type: message/rfc822'].freeze
10
10
  StartingOf = { message: [' This is an automatically generated Delivery Status Notification.'] }.freeze
11
11
 
12
- # Parse bounce messages from Unknown MTA #3
12
+ # @abstract Decodes the bounce message from Unknown MTA #3
13
13
  # @param [Hash] mhead Message headers of a bounce email
14
14
  # @param [String] mbody Message body of a bounce email
15
15
  # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
16
+ # @return [Nil] it failed to decode or the arguments are missing
17
17
  def inquire(mhead, mbody)
18
18
  return nil unless mhead['subject'].start_with?('Delivery status notification')
19
19
  return nil unless mhead['from'].start_with?('Mail Delivery System')
@@ -56,7 +56,7 @@ module Sisimai::Lhost
56
56
 
57
57
  if e.include?(' * ') && e.include?('@')
58
58
  # * kijitora@example.com
59
- if v['recipient']
59
+ if v["recipient"] != ""
60
60
  # There are multiple recipient addresses in the message body.
61
61
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
62
62
  v = dscontents[-1]
@@ -84,7 +84,7 @@ module Sisimai::Lhost
84
84
 
85
85
  dscontents.each do |e|
86
86
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
87
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
87
+ e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
88
88
  end
89
89
 
90
90
  return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
@@ -1,5 +1,5 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::X6 parses a bounce email which created by Unknown MTA #6. Methods in the module
2
+ # Sisimai::Lhost::X6 decodes a bounce email which created by Unknown MTA #6. Methods in the module
3
3
  # are called from only Sisimai::Message.
4
4
  module X6
5
5
  class << self
@@ -9,11 +9,11 @@ module Sisimai::Lhost
9
9
  Boundaries = ['The attachment contains the original mail headers'].freeze
10
10
  StartingOf = { message: ['We had trouble delivering your message. Full details follow:'] }.freeze
11
11
 
12
- # Parse bounce messages from Unknown MTA #6
12
+ # @abstract Decodes the bounce message from Unknown MTA #6
13
13
  # @param [Hash] mhead Message headers of a bounce email
14
14
  # @param [String] mbody Message body of a bounce email
15
15
  # @return [Hash] Bounce data list and message/rfc822 part
16
- # @return [Nil] it failed to parse or the arguments are missing
16
+ # @return [Nil] it failed to decode or the arguments are missing
17
17
  # @since v4.25.6
18
18
  def inquire(mhead, mbody)
19
19
  return nil unless mhead['subject'].start_with?('There was an error sending your mail')
@@ -52,7 +52,7 @@ module Sisimai::Lhost
52
52
  if p1 == 0 || p2 == 0
53
53
  # SMTP Server <mta2.example.jp> rejected recipient <kijitora@examplejp>
54
54
  # The following recipients returned permanent errors: neko@example.jp.
55
- if v['recipient']
55
+ if v["recipient"] != ""
56
56
  # There are multiple recipient addresses in the message body.
57
57
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
58
58
  v = dscontents[-1]
@@ -1,6 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Zoho parses a bounce email which created by Zoho Mail. Methods in the module are
3
- # called from only Sisimai::Message.
2
+ # Sisimai::Lhost::Zoho decodes a bounce email which created by Zoho Mail https://www.zoho.com/mail/.
3
+ # Methods in the module are called from only Sisimai::Message.
4
4
  module Zoho
5
5
  class << self
6
6
  require 'sisimai/lhost'
@@ -10,11 +10,11 @@ module Sisimai::Lhost
10
10
  StartingOf = { message: ['This message was created automatically by mail delivery'] }.freeze
11
11
  MessagesOf = { 'expired' => ['Host not reachable'] }.freeze
12
12
 
13
- # Parse bounce messages from Zoho Mail
13
+ # @abstract Decodes the bounce message from Zoho Mail
14
14
  # @param [Hash] mhead Message headers of a bounce email
15
15
  # @param [String] mbody Message body of a bounce email
16
16
  # @return [Hash] Bounce data list and message/rfc822 part
17
- # @return [Nil] it failed to parse or the arguments are missing
17
+ # @return [Nil] it failed to decode or the arguments are missing
18
18
  def inquire(mhead, mbody)
19
19
  # X-ZohoMail: Si CHF_MF_NL SS_10 UW48 UB48 FMWL UW48 UB48 SGR3_1_09124_42
20
20
  # X-Zoho-Virus-Status: 2
@@ -55,7 +55,7 @@ module Sisimai::Lhost
55
55
 
56
56
  if Sisimai::String.aligned(e, ['@', ' ', 'ERROR_CODE :'])
57
57
  # kijitora@example.co.jp Invalid Address, ERROR_CODE :550, ERROR_CODE :5.1.=
58
- if v['recipient']
58
+ if v["recipient"] != ""
59
59
  # There are multiple recipient addresses in the message body.
60
60
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
61
61
  v = dscontents[-1]
@@ -73,7 +73,7 @@ module Sisimai::Lhost
73
73
  elsif e.start_with?('[Status: ')
74
74
  # Expired
75
75
  # [Status: Error, Address: <kijitora@6kaku.example.co.jp>, ResponseCode 421, , Host not reachable.]
76
- if v['recipient']
76
+ if v["recipient"] != ""
77
77
  # There are multiple recipient addresses in the message body.
78
78
  dscontents << Sisimai::Lhost.DELIVERYSTATUS
79
79
  v = dscontents[-1]
data/lib/sisimai/lhost.rb CHANGED
@@ -4,26 +4,25 @@ module Sisimai
4
4
  class << self
5
5
  require 'sisimai/rfc5322'
6
6
 
7
- # Data structure for parsed bounce messages
7
+ # @abstract Returns the data structure for decoded bounce messages
8
8
  # @return [Hash] Data structure for delivery status
9
9
  # @private
10
10
  def DELIVERYSTATUS
11
11
  return {
12
- 'spec' => nil, # Protocl specification
13
- 'date' => nil, # The value of Last-Attempt-Date header
14
- 'rhost' => nil, # The value of Remote-MTA header
15
- 'lhost' => nil, # The value of Received-From-MTA header
16
- 'alias' => nil, # The value of alias entry(RHS)
17
- 'agent' => nil, # MTA module name
18
- 'action' => nil, # The value of Action header
19
- 'status' => nil, # The value of Status header
20
- 'reason' => nil, # Temporary reason of bounce
21
- 'command' => nil, # SMTP command in the message body
22
- 'replycode' => nil, # SMTP Reply code
23
- 'diagnosis' => nil, # The value of Diagnostic-Code header
24
- 'recipient' => nil, # The value of Final-Recipient header
25
- 'hardbounce' => nil, # Hard bounce or not
26
- 'feedbacktype' => nil, # Feedback Type
12
+ 'spec' => "", # Protocl specification
13
+ 'date' => "", # The value of Last-Attempt-Date header
14
+ 'rhost' => "", # The value of Remote-MTA header
15
+ 'lhost' => "", # The value of Received-From-MTA header
16
+ 'alias' => "", # The value of alias entry(RHS)
17
+ 'agent' => "", # MTA module name
18
+ 'action' => "", # The value of Action header
19
+ 'status' => "", # The value of Status header
20
+ 'reason' => "", # Temporary reason of bounce
21
+ 'command' => "", # SMTP command in the message body
22
+ 'replycode' => "", # SMTP Reply code
23
+ 'diagnosis' => "", # The value of Diagnostic-Code header
24
+ 'recipient' => "", # The value of Final-Recipient header
25
+ 'feedbacktype' => "", # Feedback Type
27
26
  }
28
27
  end
29
28
 
@@ -41,12 +40,10 @@ module Sisimai
41
40
  # @return [Array] MTA list with order
42
41
  def index
43
42
  return %w[
44
- Activehunter Amavis AmazonSES AmazonWorkMail Aol ApacheJames Barracuda Bigfoot Biglobe
45
- Courier Domino EZweb EinsUndEins Exchange2003 Exchange2007 Exim FML Facebook GMX GSuite
46
- GoogleGroups Gmail IMailServer InterScanMSS KDDI MXLogic MailFoundry MailMarshalSMTP
47
- MailRu McAfee MessageLabs MessagingServer Notes Office365 OpenSMTPD Outlook Postfix
48
- PowerMTA ReceivingSES SendGrid Sendmail SurfControl V5sendmail Verizon X1 X2 X3 X4 X5 X6
49
- Yahoo Yandex Zoho MFILTER Qmail
43
+ Activehunter AmazonSES ApacheJames Biglobe Courier Domino DragonFly EZweb EinsUndEins Exchange2003
44
+ Exchange2007 Exim FML GMX GoogleWorkspace GoogleGroups Gmail IMailServer InterScanMSS KDDI
45
+ MailFoundry MailMarshalSMTP MessagingServer Notes OpenSMTPD Postfix Sendmail V5sendmail
46
+ Verizon X1 X2 X3 X6 Zoho MFILTER Qmail
50
47
  ]
51
48
  end
52
49
 
@@ -64,11 +61,11 @@ module Sisimai
64
61
  return table
65
62
  end
66
63
 
67
- # @abstract Parse bounce messages
64
+ # @abstract decode bounce messages
68
65
  # @param [Hash] mhead Message headers of a bounce email
69
66
  # @param [String] mbody Message body of a bounce email
70
67
  # @return [Hash] Bounce data list and message/rfc822 part
71
- # @return [Nil] it failed to parse or the arguments are missing
68
+ # @return [Nil] it failed to decode or the arguments are missing
72
69
  def inquire; return nil; end
73
70
  def description; return ''; end
74
71
  end
@@ -27,7 +27,7 @@ module Sisimai
27
27
  @handle = Dir.open(argv1)
28
28
  end
29
29
 
30
- # Maildir reader, works as a iterator.
30
+ # Maildir reader, works as an iterator.
31
31
  # @return [String] Contents of file in Maildir/
32
32
  def read
33
33
  return nil unless self.offset < self.size
@@ -21,7 +21,7 @@ module Sisimai
21
21
  @handle = stdin
22
22
  end
23
23
 
24
- # Mbox reader, works as a iterator.
24
+ # Mbox reader, works as an iterator.
25
25
  # @return [String] Contents of mbox
26
26
  def read
27
27
  readhandle = self.handle