sisimai 4.16.0-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

Files changed (574) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +182 -0
  5. data/.travis.yml +18 -0
  6. data/ANALYTICAL-PRECISION +56 -0
  7. data/Changes +36 -0
  8. data/Developers.mk +129 -0
  9. data/Gemfile +15 -0
  10. data/LICENSE +25 -0
  11. data/Makefile +70 -0
  12. data/README.md +361 -0
  13. data/Rakefile +12 -0
  14. data/Repository.mk +69 -0
  15. data/appveyor.yml +23 -0
  16. data/bin/console +14 -0
  17. data/bin/setup +7 -0
  18. data/lib/sisimai.rb +95 -0
  19. data/lib/sisimai/address.rb +224 -0
  20. data/lib/sisimai/arf.rb +338 -0
  21. data/lib/sisimai/data.rb +409 -0
  22. data/lib/sisimai/data/json.rb +40 -0
  23. data/lib/sisimai/data/yaml.rb +32 -0
  24. data/lib/sisimai/datetime.rb +511 -0
  25. data/lib/sisimai/mail.rb +82 -0
  26. data/lib/sisimai/mail/maildir.rb +82 -0
  27. data/lib/sisimai/mail/mbox.rb +69 -0
  28. data/lib/sisimai/mail/stdin.rb +53 -0
  29. data/lib/sisimai/mda.rb +152 -0
  30. data/lib/sisimai/message.rb +525 -0
  31. data/lib/sisimai/mime.rb +127 -0
  32. data/lib/sisimai/msp.rb +54 -0
  33. data/lib/sisimai/msp/de/einsundeins.rb +174 -0
  34. data/lib/sisimai/msp/de/gmx.rb +197 -0
  35. data/lib/sisimai/msp/jp/biglobe.rb +179 -0
  36. data/lib/sisimai/msp/jp/ezweb.rb +292 -0
  37. data/lib/sisimai/msp/jp/kddi.rb +195 -0
  38. data/lib/sisimai/msp/ru/mailru.rb +306 -0
  39. data/lib/sisimai/msp/ru/yandex.rb +241 -0
  40. data/lib/sisimai/msp/uk/messagelabs.rb +250 -0
  41. data/lib/sisimai/msp/us/amazonses.rb +248 -0
  42. data/lib/sisimai/msp/us/amazonworkmail.rb +224 -0
  43. data/lib/sisimai/msp/us/aol.rb +234 -0
  44. data/lib/sisimai/msp/us/bigfoot.rb +243 -0
  45. data/lib/sisimai/msp/us/facebook.rb +306 -0
  46. data/lib/sisimai/msp/us/google.rb +357 -0
  47. data/lib/sisimai/msp/us/office365.rb +273 -0
  48. data/lib/sisimai/msp/us/outlook.rb +242 -0
  49. data/lib/sisimai/msp/us/receivingses.rb +247 -0
  50. data/lib/sisimai/msp/us/sendgrid.rb +257 -0
  51. data/lib/sisimai/msp/us/verizon.rb +311 -0
  52. data/lib/sisimai/msp/us/yahoo.rb +178 -0
  53. data/lib/sisimai/msp/us/zoho.rb +198 -0
  54. data/lib/sisimai/mta.rb +54 -0
  55. data/lib/sisimai/mta/activehunter.rb +155 -0
  56. data/lib/sisimai/mta/apachejames.rb +194 -0
  57. data/lib/sisimai/mta/courier.rb +307 -0
  58. data/lib/sisimai/mta/domino.rb +209 -0
  59. data/lib/sisimai/mta/exchange.rb +314 -0
  60. data/lib/sisimai/mta/exim.rb +549 -0
  61. data/lib/sisimai/mta/imailserver.rb +227 -0
  62. data/lib/sisimai/mta/interscanmss.rb +167 -0
  63. data/lib/sisimai/mta/mailfoundry.rb +173 -0
  64. data/lib/sisimai/mta/mailmarshalsmtp.rb +206 -0
  65. data/lib/sisimai/mta/mcafee.rb +201 -0
  66. data/lib/sisimai/mta/messagingserver.rb +241 -0
  67. data/lib/sisimai/mta/mfilter.rb +190 -0
  68. data/lib/sisimai/mta/mxlogic.rb +283 -0
  69. data/lib/sisimai/mta/notes.rb +206 -0
  70. data/lib/sisimai/mta/opensmtpd.rb +225 -0
  71. data/lib/sisimai/mta/postfix.rb +306 -0
  72. data/lib/sisimai/mta/qmail.rb +335 -0
  73. data/lib/sisimai/mta/sendmail.rb +317 -0
  74. data/lib/sisimai/mta/surfcontrol.rb +193 -0
  75. data/lib/sisimai/mta/userdefined.rb +148 -0
  76. data/lib/sisimai/mta/v5sendmail.rb +232 -0
  77. data/lib/sisimai/mta/x1.rb +156 -0
  78. data/lib/sisimai/mta/x2.rb +157 -0
  79. data/lib/sisimai/mta/x3.rb +171 -0
  80. data/lib/sisimai/mta/x4.rb +365 -0
  81. data/lib/sisimai/mta/x5.rb +208 -0
  82. data/lib/sisimai/order.rb +220 -0
  83. data/lib/sisimai/reason.rb +234 -0
  84. data/lib/sisimai/reason/blocked.rb +105 -0
  85. data/lib/sisimai/reason/contenterror.rb +53 -0
  86. data/lib/sisimai/reason/exceedlimit.rb +60 -0
  87. data/lib/sisimai/reason/expired.rb +53 -0
  88. data/lib/sisimai/reason/filtered.rb +98 -0
  89. data/lib/sisimai/reason/hasmoved.rb +45 -0
  90. data/lib/sisimai/reason/hostunknown.rb +79 -0
  91. data/lib/sisimai/reason/mailboxfull.rb +118 -0
  92. data/lib/sisimai/reason/mailererror.rb +55 -0
  93. data/lib/sisimai/reason/mesgtoobig.rb +82 -0
  94. data/lib/sisimai/reason/networkerror.rb +58 -0
  95. data/lib/sisimai/reason/norelaying.rb +71 -0
  96. data/lib/sisimai/reason/notaccept.rb +63 -0
  97. data/lib/sisimai/reason/onhold.rb +45 -0
  98. data/lib/sisimai/reason/rejected.rb +101 -0
  99. data/lib/sisimai/reason/securityerror.rb +72 -0
  100. data/lib/sisimai/reason/spamdetected.rb +172 -0
  101. data/lib/sisimai/reason/suspend.rb +58 -0
  102. data/lib/sisimai/reason/systemerror.rb +69 -0
  103. data/lib/sisimai/reason/systemfull.rb +45 -0
  104. data/lib/sisimai/reason/toomanyconn.rb +73 -0
  105. data/lib/sisimai/reason/userunknown.rb +194 -0
  106. data/lib/sisimai/rfc2606.rb +24 -0
  107. data/lib/sisimai/rfc3464.rb +497 -0
  108. data/lib/sisimai/rfc3834.rb +150 -0
  109. data/lib/sisimai/rfc5322.rb +204 -0
  110. data/lib/sisimai/rhost.rb +47 -0
  111. data/lib/sisimai/rhost/googleapps.rb +237 -0
  112. data/lib/sisimai/smtp.rb +58 -0
  113. data/lib/sisimai/smtp/reply.rb +84 -0
  114. data/lib/sisimai/smtp/status.rb +758 -0
  115. data/lib/sisimai/string.rb +65 -0
  116. data/lib/sisimai/time.rb +11 -0
  117. data/lib/sisimai/version.rb +4 -0
  118. data/set-of-emails/README.md +35 -0
  119. data/set-of-emails/mailbox/mbox-0 +2467 -0
  120. data/set-of-emails/mailbox/mbox-1 +71 -0
  121. data/set-of-emails/maildir/bsd/README.md +261 -0
  122. data/set-of-emails/maildir/bsd/activehunter-01.eml +54 -0
  123. data/set-of-emails/maildir/bsd/activehunter-02.eml +53 -0
  124. data/set-of-emails/maildir/bsd/apachejames-01.eml +46 -0
  125. data/set-of-emails/maildir/bsd/arf-01.eml +66 -0
  126. data/set-of-emails/maildir/bsd/arf-02.eml +68 -0
  127. data/set-of-emails/maildir/bsd/arf-03.eml +56 -0
  128. data/set-of-emails/maildir/bsd/arf-04.eml +89 -0
  129. data/set-of-emails/maildir/bsd/arf-05.eml +82 -0
  130. data/set-of-emails/maildir/bsd/arf-06.eml +166 -0
  131. data/set-of-emails/maildir/bsd/arf-07.eml +59 -0
  132. data/set-of-emails/maildir/bsd/arf-08.eml +103 -0
  133. data/set-of-emails/maildir/bsd/arf-09.eml +104 -0
  134. data/set-of-emails/maildir/bsd/arf-10.eml +56 -0
  135. data/set-of-emails/maildir/bsd/arf-11.eml +37 -0
  136. data/set-of-emails/maildir/bsd/arf-12.eml +40 -0
  137. data/set-of-emails/maildir/bsd/arf-13.eml +76 -0
  138. data/set-of-emails/maildir/bsd/arf-14.eml +333 -0
  139. data/set-of-emails/maildir/bsd/arf-15.eml +66 -0
  140. data/set-of-emails/maildir/bsd/courier-01.eml +79 -0
  141. data/set-of-emails/maildir/bsd/courier-02.eml +83 -0
  142. data/set-of-emails/maildir/bsd/courier-03.eml +85 -0
  143. data/set-of-emails/maildir/bsd/courier-04.eml +87 -0
  144. data/set-of-emails/maildir/bsd/de-einsundeins-01.eml +38 -0
  145. data/set-of-emails/maildir/bsd/de-gmx-01.eml +52 -0
  146. data/set-of-emails/maildir/bsd/de-gmx-02.eml +51 -0
  147. data/set-of-emails/maildir/bsd/de-gmx-03.eml +56 -0
  148. data/set-of-emails/maildir/bsd/de-gmx-04.eml +51 -0
  149. data/set-of-emails/maildir/bsd/domino-01.eml +33 -0
  150. data/set-of-emails/maildir/bsd/domino-02.eml +83 -0
  151. data/set-of-emails/maildir/bsd/exchange-01.eml +31 -0
  152. data/set-of-emails/maildir/bsd/exchange-02.eml +67 -0
  153. data/set-of-emails/maildir/bsd/exchange-03.eml +52 -0
  154. data/set-of-emails/maildir/bsd/exchange-04.eml +28 -0
  155. data/set-of-emails/maildir/bsd/exchange-05.eml +56 -0
  156. data/set-of-emails/maildir/bsd/exchange-06.eml +151 -0
  157. data/set-of-emails/maildir/bsd/exim-01.eml +46 -0
  158. data/set-of-emails/maildir/bsd/exim-02.eml +41 -0
  159. data/set-of-emails/maildir/bsd/exim-03.eml +42 -0
  160. data/set-of-emails/maildir/bsd/exim-04.eml +46 -0
  161. data/set-of-emails/maildir/bsd/exim-05.eml +49 -0
  162. data/set-of-emails/maildir/bsd/exim-06.eml +44 -0
  163. data/set-of-emails/maildir/bsd/exim-07.eml +28 -0
  164. data/set-of-emails/maildir/bsd/exim-08.eml +42 -0
  165. data/set-of-emails/maildir/bsd/exim-09.eml +169 -0
  166. data/set-of-emails/maildir/bsd/exim-10.eml +718 -0
  167. data/set-of-emails/maildir/bsd/exim-11.eml +718 -0
  168. data/set-of-emails/maildir/bsd/exim-12.eml +75 -0
  169. data/set-of-emails/maildir/bsd/exim-13.eml +145 -0
  170. data/set-of-emails/maildir/bsd/exim-14.eml +32 -0
  171. data/set-of-emails/maildir/bsd/exim-15.eml +49 -0
  172. data/set-of-emails/maildir/bsd/exim-16.eml +98 -0
  173. data/set-of-emails/maildir/bsd/exim-17.eml +50 -0
  174. data/set-of-emails/maildir/bsd/exim-18.eml +96 -0
  175. data/set-of-emails/maildir/bsd/exim-19.eml +52 -0
  176. data/set-of-emails/maildir/bsd/exim-20.eml +159 -0
  177. data/set-of-emails/maildir/bsd/exim-21.eml +150 -0
  178. data/set-of-emails/maildir/bsd/exim-22.eml +50 -0
  179. data/set-of-emails/maildir/bsd/exim-23.eml +57 -0
  180. data/set-of-emails/maildir/bsd/exim-24.eml +107 -0
  181. data/set-of-emails/maildir/bsd/exim-25.eml +18 -0
  182. data/set-of-emails/maildir/bsd/exim-26.eml +111 -0
  183. data/set-of-emails/maildir/bsd/exim-27.eml +120 -0
  184. data/set-of-emails/maildir/bsd/exim-28.eml +148 -0
  185. data/set-of-emails/maildir/bsd/google-apps-01.eml +66 -0
  186. data/set-of-emails/maildir/bsd/imailserver-01.eml +27 -0
  187. data/set-of-emails/maildir/bsd/imailserver-02.eml +36 -0
  188. data/set-of-emails/maildir/bsd/imailserver-03.eml +28 -0
  189. data/set-of-emails/maildir/bsd/imailserver-04.eml +15 -0
  190. data/set-of-emails/maildir/bsd/imailserver-05.eml +92 -0
  191. data/set-of-emails/maildir/bsd/imailserver-06.eml +29 -0
  192. data/set-of-emails/maildir/bsd/interscanmss-01.eml +49 -0
  193. data/set-of-emails/maildir/bsd/interscanmss-02.eml +259 -0
  194. data/set-of-emails/maildir/bsd/jp-biglobe-01.eml +43 -0
  195. data/set-of-emails/maildir/bsd/jp-ezweb-01.eml +36 -0
  196. data/set-of-emails/maildir/bsd/jp-ezweb-02.eml +65 -0
  197. data/set-of-emails/maildir/bsd/jp-ezweb-03.eml +35 -0
  198. data/set-of-emails/maildir/bsd/jp-ezweb-04.eml +38 -0
  199. data/set-of-emails/maildir/bsd/jp-ezweb-05.eml +38 -0
  200. data/set-of-emails/maildir/bsd/jp-ezweb-06.eml +33 -0
  201. data/set-of-emails/maildir/bsd/jp-kddi-01.eml +49 -0
  202. data/set-of-emails/maildir/bsd/jp-kddi-02.eml +54 -0
  203. data/set-of-emails/maildir/bsd/jp-kddi-03.eml +54 -0
  204. data/set-of-emails/maildir/bsd/mailfoundry-01.eml +50 -0
  205. data/set-of-emails/maildir/bsd/mailfoundry-02.eml +49 -0
  206. data/set-of-emails/maildir/bsd/mailmarshalsmtp-01.eml +43 -0
  207. data/set-of-emails/maildir/bsd/mcafee-01.eml +63 -0
  208. data/set-of-emails/maildir/bsd/mcafee-02.eml +65 -0
  209. data/set-of-emails/maildir/bsd/mcafee-03.eml +59 -0
  210. data/set-of-emails/maildir/bsd/messagingserver-01.eml +102 -0
  211. data/set-of-emails/maildir/bsd/messagingserver-02.eml +72 -0
  212. data/set-of-emails/maildir/bsd/messagingserver-03.eml +70 -0
  213. data/set-of-emails/maildir/bsd/messagingserver-04.eml +102 -0
  214. data/set-of-emails/maildir/bsd/messagingserver-05.eml +98 -0
  215. data/set-of-emails/maildir/bsd/messagingserver-06.eml +101 -0
  216. data/set-of-emails/maildir/bsd/messagingserver-07.eml +129 -0
  217. data/set-of-emails/maildir/bsd/mfilter-01.eml +49 -0
  218. data/set-of-emails/maildir/bsd/mfilter-02.eml +48 -0
  219. data/set-of-emails/maildir/bsd/mfilter-03.eml +43 -0
  220. data/set-of-emails/maildir/bsd/mxlogic-01.eml +47 -0
  221. data/set-of-emails/maildir/bsd/mxlogic-02.eml +44 -0
  222. data/set-of-emails/maildir/bsd/mxlogic-03.eml +46 -0
  223. data/set-of-emails/maildir/bsd/notes-01.eml +42 -0
  224. data/set-of-emails/maildir/bsd/notes-02.eml +42 -0
  225. data/set-of-emails/maildir/bsd/notes-03.eml +38 -0
  226. data/set-of-emails/maildir/bsd/notes-04.eml +181 -0
  227. data/set-of-emails/maildir/bsd/opensmtpd-01.eml +33 -0
  228. data/set-of-emails/maildir/bsd/opensmtpd-02.eml +33 -0
  229. data/set-of-emails/maildir/bsd/opensmtpd-03.eml +36 -0
  230. data/set-of-emails/maildir/bsd/opensmtpd-04.eml +40 -0
  231. data/set-of-emails/maildir/bsd/opensmtpd-05.eml +36 -0
  232. data/set-of-emails/maildir/bsd/postfix-01.eml +60 -0
  233. data/set-of-emails/maildir/bsd/postfix-02.eml +78 -0
  234. data/set-of-emails/maildir/bsd/postfix-03.eml +71 -0
  235. data/set-of-emails/maildir/bsd/postfix-04.eml +89 -0
  236. data/set-of-emails/maildir/bsd/postfix-05.eml +78 -0
  237. data/set-of-emails/maildir/bsd/postfix-06.eml +72 -0
  238. data/set-of-emails/maildir/bsd/postfix-07.eml +74 -0
  239. data/set-of-emails/maildir/bsd/postfix-08.eml +78 -0
  240. data/set-of-emails/maildir/bsd/postfix-09.eml +76 -0
  241. data/set-of-emails/maildir/bsd/postfix-10.eml +73 -0
  242. data/set-of-emails/maildir/bsd/postfix-11.eml +86 -0
  243. data/set-of-emails/maildir/bsd/postfix-12.eml +71 -0
  244. data/set-of-emails/maildir/bsd/postfix-13.eml +81 -0
  245. data/set-of-emails/maildir/bsd/postfix-14.eml +68 -0
  246. data/set-of-emails/maildir/bsd/postfix-15.eml +69 -0
  247. data/set-of-emails/maildir/bsd/postfix-16.eml +73 -0
  248. data/set-of-emails/maildir/bsd/postfix-17.eml +68 -0
  249. data/set-of-emails/maildir/bsd/postfix-18.eml +121 -0
  250. data/set-of-emails/maildir/bsd/postfix-19.eml +105 -0
  251. data/set-of-emails/maildir/bsd/postfix-20.eml +231 -0
  252. data/set-of-emails/maildir/bsd/postfix-21.eml +60 -0
  253. data/set-of-emails/maildir/bsd/qmail-01.eml +40 -0
  254. data/set-of-emails/maildir/bsd/qmail-02.eml +35 -0
  255. data/set-of-emails/maildir/bsd/qmail-03.eml +22 -0
  256. data/set-of-emails/maildir/bsd/qmail-04.eml +31 -0
  257. data/set-of-emails/maildir/bsd/qmail-05.eml +31 -0
  258. data/set-of-emails/maildir/bsd/qmail-06.eml +39 -0
  259. data/set-of-emails/maildir/bsd/qmail-07.eml +22 -0
  260. data/set-of-emails/maildir/bsd/qmail-08.eml +23 -0
  261. data/set-of-emails/maildir/bsd/qmail-09.eml +103 -0
  262. data/set-of-emails/maildir/bsd/rfc3464-01.eml +60 -0
  263. data/set-of-emails/maildir/bsd/rfc3464-02.eml +43 -0
  264. data/set-of-emails/maildir/bsd/rfc3464-03.eml +40 -0
  265. data/set-of-emails/maildir/bsd/rfc3464-04.eml +50 -0
  266. data/set-of-emails/maildir/bsd/rfc3464-05.eml +63 -0
  267. data/set-of-emails/maildir/bsd/rfc3464-06.eml +48 -0
  268. data/set-of-emails/maildir/bsd/rfc3464-07.eml +88 -0
  269. data/set-of-emails/maildir/bsd/rfc3464-08.eml +70 -0
  270. data/set-of-emails/maildir/bsd/rfc3464-09.eml +93 -0
  271. data/set-of-emails/maildir/bsd/rfc3464-10.eml +467 -0
  272. data/set-of-emails/maildir/bsd/rfc3464-11.eml +1171 -0
  273. data/set-of-emails/maildir/bsd/rfc3464-12.eml +101 -0
  274. data/set-of-emails/maildir/bsd/rfc3464-13.eml +131 -0
  275. data/set-of-emails/maildir/bsd/rfc3464-14.eml +121 -0
  276. data/set-of-emails/maildir/bsd/rfc3464-15.eml +144 -0
  277. data/set-of-emails/maildir/bsd/rfc3464-16.eml +36 -0
  278. data/set-of-emails/maildir/bsd/rfc3464-17.eml +109 -0
  279. data/set-of-emails/maildir/bsd/rfc3464-18.eml +149 -0
  280. data/set-of-emails/maildir/bsd/rfc3464-19.eml +65 -0
  281. data/set-of-emails/maildir/bsd/rfc3464-20.eml +145 -0
  282. data/set-of-emails/maildir/bsd/rfc3464-21.eml +146 -0
  283. data/set-of-emails/maildir/bsd/rfc3464-22.eml +105 -0
  284. data/set-of-emails/maildir/bsd/rfc3464-23.eml +21 -0
  285. data/set-of-emails/maildir/bsd/rfc3464-24.eml +27 -0
  286. data/set-of-emails/maildir/bsd/rfc3464-25.eml +33 -0
  287. data/set-of-emails/maildir/bsd/rfc3464-26.eml +98 -0
  288. data/set-of-emails/maildir/bsd/rfc3464-27.eml +180 -0
  289. data/set-of-emails/maildir/bsd/rfc3464-28.eml +122 -0
  290. data/set-of-emails/maildir/bsd/rfc3834-01.eml +37 -0
  291. data/set-of-emails/maildir/bsd/rfc3834-02.eml +51 -0
  292. data/set-of-emails/maildir/bsd/rfc3834-03.eml +33 -0
  293. data/set-of-emails/maildir/bsd/ru-mailru-01.eml +54 -0
  294. data/set-of-emails/maildir/bsd/ru-mailru-02.eml +54 -0
  295. data/set-of-emails/maildir/bsd/ru-mailru-03.eml +62 -0
  296. data/set-of-emails/maildir/bsd/ru-mailru-04.eml +54 -0
  297. data/set-of-emails/maildir/bsd/ru-yandex-01.eml +102 -0
  298. data/set-of-emails/maildir/bsd/ru-yandex-02.eml +113 -0
  299. data/set-of-emails/maildir/bsd/ru-yandex-03.eml +101 -0
  300. data/set-of-emails/maildir/bsd/sendmail-01.eml +70 -0
  301. data/set-of-emails/maildir/bsd/sendmail-02.eml +82 -0
  302. data/set-of-emails/maildir/bsd/sendmail-03.eml +76 -0
  303. data/set-of-emails/maildir/bsd/sendmail-04.eml +63 -0
  304. data/set-of-emails/maildir/bsd/sendmail-05.eml +64 -0
  305. data/set-of-emails/maildir/bsd/sendmail-06.eml +67 -0
  306. data/set-of-emails/maildir/bsd/sendmail-07.eml +65 -0
  307. data/set-of-emails/maildir/bsd/sendmail-08.eml +62 -0
  308. data/set-of-emails/maildir/bsd/sendmail-09.eml +60 -0
  309. data/set-of-emails/maildir/bsd/sendmail-10.eml +82 -0
  310. data/set-of-emails/maildir/bsd/sendmail-11.eml +60 -0
  311. data/set-of-emails/maildir/bsd/sendmail-12.eml +62 -0
  312. data/set-of-emails/maildir/bsd/sendmail-13.eml +66 -0
  313. data/set-of-emails/maildir/bsd/sendmail-14.eml +64 -0
  314. data/set-of-emails/maildir/bsd/sendmail-15.eml +60 -0
  315. data/set-of-emails/maildir/bsd/sendmail-16.eml +69 -0
  316. data/set-of-emails/maildir/bsd/sendmail-17.eml +68 -0
  317. data/set-of-emails/maildir/bsd/sendmail-18.eml +64 -0
  318. data/set-of-emails/maildir/bsd/sendmail-19.eml +71 -0
  319. data/set-of-emails/maildir/bsd/sendmail-20.eml +120 -0
  320. data/set-of-emails/maildir/bsd/sendmail-21.eml +69 -0
  321. data/set-of-emails/maildir/bsd/sendmail-22.eml +73 -0
  322. data/set-of-emails/maildir/bsd/sendmail-23.eml +137 -0
  323. data/set-of-emails/maildir/bsd/sendmail-24.eml +66 -0
  324. data/set-of-emails/maildir/bsd/sendmail-25.eml +70 -0
  325. data/set-of-emails/maildir/bsd/sendmail-26.eml +71 -0
  326. data/set-of-emails/maildir/bsd/sendmail-27.eml +69 -0
  327. data/set-of-emails/maildir/bsd/sendmail-28.eml +69 -0
  328. data/set-of-emails/maildir/bsd/sendmail-29.eml +70 -0
  329. data/set-of-emails/maildir/bsd/sendmail-30.eml +68 -0
  330. data/set-of-emails/maildir/bsd/sendmail-31.eml +80 -0
  331. data/set-of-emails/maildir/bsd/sendmail-32.eml +71 -0
  332. data/set-of-emails/maildir/bsd/sendmail-33.eml +71 -0
  333. data/set-of-emails/maildir/bsd/sendmail-34.eml +75 -0
  334. data/set-of-emails/maildir/bsd/sendmail-35.eml +70 -0
  335. data/set-of-emails/maildir/bsd/sendmail-36.eml +71 -0
  336. data/set-of-emails/maildir/bsd/sendmail-37.eml +71 -0
  337. data/set-of-emails/maildir/bsd/sendmail-38.eml +167 -0
  338. data/set-of-emails/maildir/bsd/surfcontrol-01.eml +79 -0
  339. data/set-of-emails/maildir/bsd/surfcontrol-02.eml +70 -0
  340. data/set-of-emails/maildir/bsd/surfcontrol-03.eml +70 -0
  341. data/set-of-emails/maildir/bsd/uk-messagelabs-01.eml +76 -0
  342. data/set-of-emails/maildir/bsd/us-amazonses-01.eml +59 -0
  343. data/set-of-emails/maildir/bsd/us-amazonses-02.eml +177 -0
  344. data/set-of-emails/maildir/bsd/us-amazonses-03.eml +55 -0
  345. data/set-of-emails/maildir/bsd/us-amazonses-04.eml +55 -0
  346. data/set-of-emails/maildir/bsd/us-amazonworkmail-01.eml +156 -0
  347. data/set-of-emails/maildir/bsd/us-amazonworkmail-02.eml +160 -0
  348. data/set-of-emails/maildir/bsd/us-amazonworkmail-03.eml +161 -0
  349. data/set-of-emails/maildir/bsd/us-amazonworkmail-04.eml +156 -0
  350. data/set-of-emails/maildir/bsd/us-amazonworkmail-05.eml +157 -0
  351. data/set-of-emails/maildir/bsd/us-aol-01.eml +1258 -0
  352. data/set-of-emails/maildir/bsd/us-aol-02.eml +1257 -0
  353. data/set-of-emails/maildir/bsd/us-aol-03.eml +1264 -0
  354. data/set-of-emails/maildir/bsd/us-aol-04.eml +1260 -0
  355. data/set-of-emails/maildir/bsd/us-bigfoot-01.eml +64 -0
  356. data/set-of-emails/maildir/bsd/us-facebook-01.eml +40 -0
  357. data/set-of-emails/maildir/bsd/us-facebook-02.eml +42 -0
  358. data/set-of-emails/maildir/bsd/us-google-01.eml +70 -0
  359. data/set-of-emails/maildir/bsd/us-google-02.eml +50 -0
  360. data/set-of-emails/maildir/bsd/us-google-03.eml +51 -0
  361. data/set-of-emails/maildir/bsd/us-google-04.eml +82 -0
  362. data/set-of-emails/maildir/bsd/us-google-05.eml +50 -0
  363. data/set-of-emails/maildir/bsd/us-google-06.eml +56 -0
  364. data/set-of-emails/maildir/bsd/us-google-07.eml +42 -0
  365. data/set-of-emails/maildir/bsd/us-google-08.eml +59 -0
  366. data/set-of-emails/maildir/bsd/us-google-09.eml +76 -0
  367. data/set-of-emails/maildir/bsd/us-google-10.eml +69 -0
  368. data/set-of-emails/maildir/bsd/us-google-11.eml +68 -0
  369. data/set-of-emails/maildir/bsd/us-google-12.eml +76 -0
  370. data/set-of-emails/maildir/bsd/us-google-13.eml +79 -0
  371. data/set-of-emails/maildir/bsd/us-google-14.eml +304 -0
  372. data/set-of-emails/maildir/bsd/us-office365-01.eml +102 -0
  373. data/set-of-emails/maildir/bsd/us-outlook-01.eml +72 -0
  374. data/set-of-emails/maildir/bsd/us-outlook-02.eml +72 -0
  375. data/set-of-emails/maildir/bsd/us-outlook-03.eml +72 -0
  376. data/set-of-emails/maildir/bsd/us-outlook-04.eml +79 -0
  377. data/set-of-emails/maildir/bsd/us-outlook-05.eml +85 -0
  378. data/set-of-emails/maildir/bsd/us-outlook-06.eml +75 -0
  379. data/set-of-emails/maildir/bsd/us-outlook-07.eml +70 -0
  380. data/set-of-emails/maildir/bsd/us-receivingses-01.eml +74 -0
  381. data/set-of-emails/maildir/bsd/us-receivingses-02.eml +74 -0
  382. data/set-of-emails/maildir/bsd/us-receivingses-03.eml +74 -0
  383. data/set-of-emails/maildir/bsd/us-receivingses-04.eml +74 -0
  384. data/set-of-emails/maildir/bsd/us-receivingses-05.eml +74 -0
  385. data/set-of-emails/maildir/bsd/us-receivingses-06.eml +74 -0
  386. data/set-of-emails/maildir/bsd/us-receivingses-07.eml +74 -0
  387. data/set-of-emails/maildir/bsd/us-sendgrid-01.eml +95 -0
  388. data/set-of-emails/maildir/bsd/us-sendgrid-02.eml +98 -0
  389. data/set-of-emails/maildir/bsd/us-sendgrid-03.eml +100 -0
  390. data/set-of-emails/maildir/bsd/us-verizon-01.eml +31 -0
  391. data/set-of-emails/maildir/bsd/us-yahoo-01.eml +78 -0
  392. data/set-of-emails/maildir/bsd/us-yahoo-02.eml +79 -0
  393. data/set-of-emails/maildir/bsd/us-yahoo-03.eml +93 -0
  394. data/set-of-emails/maildir/bsd/us-yahoo-04.eml +94 -0
  395. data/set-of-emails/maildir/bsd/us-yahoo-05.eml +94 -0
  396. data/set-of-emails/maildir/bsd/us-zoho-01.eml +40 -0
  397. data/set-of-emails/maildir/bsd/us-zoho-02.eml +38 -0
  398. data/set-of-emails/maildir/bsd/us-zoho-03.eml +37 -0
  399. data/set-of-emails/maildir/bsd/us-zoho-04.eml +47 -0
  400. data/set-of-emails/maildir/bsd/us-zoho-05.eml +37 -0
  401. data/set-of-emails/maildir/bsd/v5sendmail-01.eml +24 -0
  402. data/set-of-emails/maildir/bsd/v5sendmail-02.eml +26 -0
  403. data/set-of-emails/maildir/bsd/v5sendmail-03.eml +29 -0
  404. data/set-of-emails/maildir/bsd/v5sendmail-04.eml +29 -0
  405. data/set-of-emails/maildir/bsd/v5sendmail-05.eml +42 -0
  406. data/set-of-emails/maildir/bsd/v5sendmail-06.eml +28 -0
  407. data/set-of-emails/maildir/bsd/v5sendmail-07.eml +35 -0
  408. data/set-of-emails/maildir/bsd/x1-01.eml +61 -0
  409. data/set-of-emails/maildir/bsd/x1-02.eml +62 -0
  410. data/set-of-emails/maildir/bsd/x2-01.eml +41 -0
  411. data/set-of-emails/maildir/bsd/x2-02.eml +46 -0
  412. data/set-of-emails/maildir/bsd/x2-03.eml +34 -0
  413. data/set-of-emails/maildir/bsd/x2-04.eml +0 -0
  414. data/set-of-emails/maildir/bsd/x2-05.eml +98 -0
  415. data/set-of-emails/maildir/bsd/x3-01.eml +61 -0
  416. data/set-of-emails/maildir/bsd/x3-02.eml +64 -0
  417. data/set-of-emails/maildir/bsd/x3-03.eml +59 -0
  418. data/set-of-emails/maildir/bsd/x3-04.eml +106 -0
  419. data/set-of-emails/maildir/bsd/x4-01.eml +92 -0
  420. data/set-of-emails/maildir/bsd/x4-02.eml +112 -0
  421. data/set-of-emails/maildir/bsd/x4-03.eml +245 -0
  422. data/set-of-emails/maildir/bsd/x4-04.eml +81 -0
  423. data/set-of-emails/maildir/bsd/x4-05.eml +121 -0
  424. data/set-of-emails/maildir/bsd/x4-06.eml +32 -0
  425. data/set-of-emails/maildir/bsd/x4-07.eml +153 -0
  426. data/set-of-emails/maildir/bsd/x5-01.eml +155 -0
  427. data/set-of-emails/maildir/dos/activehunter-01.eml +54 -0
  428. data/set-of-emails/maildir/dos/apachejames-01.eml +46 -0
  429. data/set-of-emails/maildir/dos/arf-01.eml +66 -0
  430. data/set-of-emails/maildir/dos/courier-01.eml +79 -0
  431. data/set-of-emails/maildir/dos/de-einsundeins-01.eml +38 -0
  432. data/set-of-emails/maildir/dos/de-gmx-01.eml +52 -0
  433. data/set-of-emails/maildir/dos/domino-01.eml +33 -0
  434. data/set-of-emails/maildir/dos/exchange-01.eml +31 -0
  435. data/set-of-emails/maildir/dos/exim-01.eml +46 -0
  436. data/set-of-emails/maildir/dos/google-apps-01.eml +66 -0
  437. data/set-of-emails/maildir/dos/imailserver-01.eml +27 -0
  438. data/set-of-emails/maildir/dos/interscanmss-01.eml +49 -0
  439. data/set-of-emails/maildir/dos/jp-biglobe-01.eml +43 -0
  440. data/set-of-emails/maildir/dos/jp-ezweb-01.eml +36 -0
  441. data/set-of-emails/maildir/dos/jp-kddi-01.eml +49 -0
  442. data/set-of-emails/maildir/dos/mailfoundry-01.eml +50 -0
  443. data/set-of-emails/maildir/dos/mailmarshalsmtp-01.eml +43 -0
  444. data/set-of-emails/maildir/dos/mcafee-01.eml +63 -0
  445. data/set-of-emails/maildir/dos/messagingserver-01.eml +102 -0
  446. data/set-of-emails/maildir/dos/mfilter-01.eml +49 -0
  447. data/set-of-emails/maildir/dos/mxlogic-01.eml +47 -0
  448. data/set-of-emails/maildir/dos/notes-01.eml +42 -0
  449. data/set-of-emails/maildir/dos/opensmtpd-01.eml +33 -0
  450. data/set-of-emails/maildir/dos/postfix-01.eml +60 -0
  451. data/set-of-emails/maildir/dos/qmail-01.eml +40 -0
  452. data/set-of-emails/maildir/dos/rfc3464-01.eml +59 -0
  453. data/set-of-emails/maildir/dos/rfc3834-01.eml +37 -0
  454. data/set-of-emails/maildir/dos/ru-mailru-01.eml +54 -0
  455. data/set-of-emails/maildir/dos/ru-yandex-01.eml +102 -0
  456. data/set-of-emails/maildir/dos/sendmail-01.eml +69 -0
  457. data/set-of-emails/maildir/dos/surfcontrol-01.eml +79 -0
  458. data/set-of-emails/maildir/dos/uk-messagelabs-01.eml +76 -0
  459. data/set-of-emails/maildir/dos/us-amazonses-01.eml +59 -0
  460. data/set-of-emails/maildir/dos/us-aol-01.eml +1258 -0
  461. data/set-of-emails/maildir/dos/us-bigfoot-01.eml +64 -0
  462. data/set-of-emails/maildir/dos/us-facebook-01.eml +40 -0
  463. data/set-of-emails/maildir/dos/us-google-01.eml +70 -0
  464. data/set-of-emails/maildir/dos/us-outlook-01.eml +72 -0
  465. data/set-of-emails/maildir/dos/us-receivingses-01.eml +74 -0
  466. data/set-of-emails/maildir/dos/us-sendgrid-01.eml +95 -0
  467. data/set-of-emails/maildir/dos/us-verizon-01.eml +31 -0
  468. data/set-of-emails/maildir/dos/us-yahoo-01.eml +78 -0
  469. data/set-of-emails/maildir/dos/us-zoho-01.eml +40 -0
  470. data/set-of-emails/maildir/dos/v5sendmail-01.eml +24 -0
  471. data/set-of-emails/maildir/dos/x1-01.eml +61 -0
  472. data/set-of-emails/maildir/dos/x2-01.eml +41 -0
  473. data/set-of-emails/maildir/dos/x3-01.eml +61 -0
  474. data/set-of-emails/maildir/dos/x4-01.eml +90 -0
  475. data/set-of-emails/maildir/dos/x5-01.eml +155 -0
  476. data/set-of-emails/maildir/err/make-test-01.eml +70 -0
  477. data/set-of-emails/maildir/err/make-test-02.eml +70 -0
  478. data/set-of-emails/maildir/err/make-test-03.eml +64 -0
  479. data/set-of-emails/maildir/err/make-test-04.eml +64 -0
  480. data/set-of-emails/maildir/err/make-test-05.eml +66 -0
  481. data/set-of-emails/maildir/err/make-test-06.eml +118 -0
  482. data/set-of-emails/maildir/err/make-test-07.eml +26 -0
  483. data/set-of-emails/maildir/err/make-test-08.eml +67 -0
  484. data/set-of-emails/maildir/err/make-test-09.eml +55 -0
  485. data/set-of-emails/maildir/err/make-test-10.eml +69 -0
  486. data/set-of-emails/maildir/err/make-test-11.eml +64 -0
  487. data/set-of-emails/maildir/err/make-test-12.eml +66 -0
  488. data/set-of-emails/maildir/err/make-test-13.eml +67 -0
  489. data/set-of-emails/maildir/err/make-test-14.eml +66 -0
  490. data/set-of-emails/maildir/err/make-test-15.eml +70 -0
  491. data/set-of-emails/maildir/err/make-test-16.eml +68 -0
  492. data/set-of-emails/maildir/err/make-test-17.eml +68 -0
  493. data/set-of-emails/maildir/err/make-test-18.eml +68 -0
  494. data/set-of-emails/maildir/err/make-test-19.eml +69 -0
  495. data/set-of-emails/maildir/err/make-test-20.eml +67 -0
  496. data/set-of-emails/maildir/err/make-test-21.eml +69 -0
  497. data/set-of-emails/maildir/err/make-test-22.eml +66 -0
  498. data/set-of-emails/maildir/err/make-test-23.eml +70 -0
  499. data/set-of-emails/maildir/err/make-test-24.eml +69 -0
  500. data/set-of-emails/maildir/err/make-test-25.eml +67 -0
  501. data/set-of-emails/maildir/err/make-test-26.eml +69 -0
  502. data/set-of-emails/maildir/err/make-test-27.eml +69 -0
  503. data/set-of-emails/maildir/err/make-test-28.eml +66 -0
  504. data/set-of-emails/maildir/err/make-test-29.eml +68 -0
  505. data/set-of-emails/maildir/err/make-test-30.eml +68 -0
  506. data/set-of-emails/maildir/err/make-test-31.eml +80 -0
  507. data/set-of-emails/maildir/err/make-test-32.eml +66 -0
  508. data/set-of-emails/maildir/err/make-test-33.eml +68 -0
  509. data/set-of-emails/maildir/err/make-test-34.eml +56 -0
  510. data/set-of-emails/maildir/err/make-test-35.eml +59 -0
  511. data/set-of-emails/maildir/err/make-test-36.eml +53 -0
  512. data/set-of-emails/maildir/err/make-test-37.eml +62 -0
  513. data/set-of-emails/maildir/mac/activehunter-01.eml +1 -2
  514. data/set-of-emails/maildir/mac/apachejames-01.eml +1 -4
  515. data/set-of-emails/maildir/mac/arf-01.eml +1 -3
  516. data/set-of-emails/maildir/mac/courier-01.eml +1 -6
  517. data/set-of-emails/maildir/mac/de-einsundeins-01.eml +1 -1
  518. data/set-of-emails/maildir/mac/de-gmx-01.eml +1 -1
  519. data/set-of-emails/maildir/mac/domino-01.eml +1 -0
  520. data/set-of-emails/maildir/mac/exchange-01.eml +1 -0
  521. data/set-of-emails/maildir/mac/exim-01.eml +1 -1
  522. data/set-of-emails/maildir/mac/google-apps-01.eml +1 -4
  523. data/set-of-emails/maildir/mac/imailserver-01.eml +1 -0
  524. data/set-of-emails/maildir/mac/interscanmss-01.eml +1 -2
  525. data/set-of-emails/maildir/mac/jp-biglobe-01.eml +1 -2
  526. data/set-of-emails/maildir/mac/jp-ezweb-01.eml +1 -1
  527. data/set-of-emails/maildir/mac/jp-kddi-01.eml +1 -2
  528. data/set-of-emails/maildir/mac/mailfoundry-01.eml +1 -2
  529. data/set-of-emails/maildir/mac/mailmarshalsmtp-01.eml +1 -2
  530. data/set-of-emails/maildir/mac/mcafee-01.eml +1 -4
  531. data/set-of-emails/maildir/mac/messagingserver-01.eml +1 -4
  532. data/set-of-emails/maildir/mac/mfilter-01.eml +1 -3
  533. data/set-of-emails/maildir/mac/mxlogic-01.eml +1 -1
  534. data/set-of-emails/maildir/mac/notes-01.eml +1 -2
  535. data/set-of-emails/maildir/mac/opensmtpd-01.eml +1 -0
  536. data/set-of-emails/maildir/mac/postfix-01.eml +1 -3
  537. data/set-of-emails/maildir/mac/qmail-01.eml +1 -1
  538. data/set-of-emails/maildir/mac/rfc3464-01.eml +1 -4
  539. data/set-of-emails/maildir/mac/rfc3834-01.eml +1 -0
  540. data/set-of-emails/maildir/mac/ru-mailru-01.eml +1 -1
  541. data/set-of-emails/maildir/mac/ru-yandex-01.eml +1 -4
  542. data/set-of-emails/maildir/mac/sendmail-01.eml +1 -4
  543. data/set-of-emails/maildir/mac/surfcontrol-01.eml +1 -5
  544. data/set-of-emails/maildir/mac/uk-messagelabs-01.eml +1 -4
  545. data/set-of-emails/maildir/mac/us-amazonses-01.eml +1 -4
  546. data/set-of-emails/maildir/mac/us-aol-01.eml +1 -15
  547. data/set-of-emails/maildir/mac/us-bigfoot-01.eml +1 -4
  548. data/set-of-emails/maildir/mac/us-facebook-01.eml +1 -4
  549. data/set-of-emails/maildir/mac/us-google-01.eml +1 -1
  550. data/set-of-emails/maildir/mac/us-outlook-01.eml +1 -4
  551. data/set-of-emails/maildir/mac/us-receivingses-01.eml +1 -4
  552. data/set-of-emails/maildir/mac/us-sendgrid-01.eml +1 -3
  553. data/set-of-emails/maildir/mac/us-verizon-01.eml +1 -2
  554. data/set-of-emails/maildir/mac/us-yahoo-01.eml +1 -1
  555. data/set-of-emails/maildir/mac/us-zoho-01.eml +1 -2
  556. data/set-of-emails/maildir/mac/v5sendmail-01.eml +1 -0
  557. data/set-of-emails/maildir/mac/x1-01.eml +1 -4
  558. data/set-of-emails/maildir/mac/x2-01.eml +1 -1
  559. data/set-of-emails/maildir/mac/x3-01.eml +1 -3
  560. data/set-of-emails/maildir/mac/x4-01.eml +1 -2
  561. data/set-of-emails/maildir/mac/x5-01.eml +1 -8
  562. data/set-of-emails/maildir/not/is-not-bounce-01.eml +25 -0
  563. data/set-of-emails/to-be-debugged-because/reason-is-onhold/onhold-0001.eml +85 -0
  564. data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0002.eml +27 -0
  565. data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0003.eml +78 -0
  566. data/set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet/cannot-parse-this-email-0002.eml +25 -0
  567. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-01.eml +79 -0
  568. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-02.eml +72 -0
  569. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-03.eml +68 -0
  570. data/set-of-emails/to-be-debugged-because/something-is-wrong/no-message-id-from-pr-150.eml +75 -0
  571. data/set-of-emails/to-be-parsed-for-test/README.md +20 -0
  572. data/sisimai-java.gemspec +29 -0
  573. data/sisimai.gemspec +28 -0
  574. metadata +680 -0
@@ -0,0 +1,82 @@
1
+ module Sisimai
2
+ # Sisimai::Mail is a handler of UNIX mbox or Maildir for reading each mail. It is
3
+ # wrapper class of Sisimai::Mail::Mbox and Sisimai::Mail::Maildir classes.
4
+ class Mail
5
+ # Imported from p5-Sisimail/lib/Sisimai/Mail.pm
6
+ @@roaccessors = [
7
+ :path, # [String] path to mbox or Maildir/
8
+ :type, # [String] Data type: mailbox, maildir, or stdin
9
+ ]
10
+ @@rwaccessors = [
11
+ :mail, # [Sisimai::Mail::Mbox, Sisimai::Mail::Maildir] Object
12
+ ]
13
+ @@roaccessors.each { |e| attr_reader e }
14
+ @@rwaccessors.each { |e| attr_accessor e }
15
+
16
+ # Constructor of Sisimai::Mail
17
+ # @param [String] argv1 Path to mbox or Maildir/
18
+ # @return [Sisimai::Mail, Nil] Object or Undef if the argument was wrong
19
+ def initialize(argv1)
20
+ classname = nil
21
+ parameter = { 'path' => argv1, 'type' => nil, 'mail' => nil }
22
+
23
+ if argv1.is_a?(::String)
24
+ # Path to mail or '<STDIN>' ?
25
+ if argv1 == '<STDIN>'
26
+ # Sisimai::Mail.new('<STDIN>')
27
+ classname = sprintf('%s::STDIN', self.class)
28
+ parameter['type'] = 'stdin'
29
+ parameter['path'] = $stdin
30
+
31
+ else
32
+ # The argumenet is a mailbox or a Maildir/.
33
+ mediatype = File.ftype(argv1)
34
+
35
+ if mediatype == 'file'
36
+ # The argument is a file, it is an mbox or email file in Maildir/
37
+ classname = sprintf('%s::Mbox', self.class)
38
+ parameter['type'] = 'mailbox'
39
+
40
+ elsif mediatype == 'directory'
41
+ # The agument is not a file, it is a Maildir/
42
+ classname = sprintf('%s::Maildir', self.class)
43
+ parameter['type'] = 'maildir'
44
+ end
45
+ end
46
+
47
+ elsif argv1.is_a?(IO)
48
+ # Read from STDIN
49
+ # The argument neither a mailbox nor a Maildir/.
50
+ classname = sprintf('%s::STDIN', self.class)
51
+ parameter['type'] = 'stdin'
52
+
53
+ end
54
+
55
+ return nil unless classname
56
+
57
+ classpath = classname.gsub('::', '/').downcase
58
+ require classpath
59
+ parameter['mail'] = Module.const_get(classname).new(parameter['path'])
60
+
61
+ @path = parameter['path']
62
+ @type = parameter['type']
63
+ @mail = parameter['mail']
64
+ end
65
+
66
+ # Mbox/Maildir reader, works as an iterator.
67
+ # @return [String] Contents of mbox/Maildir
68
+ def read
69
+ return nil unless mail
70
+ return mail.read
71
+ end
72
+
73
+ # Close the handle
74
+ # @return [True,False] true: Successfully closed the handle
75
+ # false: Mail handle is not defined
76
+ def close
77
+ return false unless mail.handle
78
+ mail.handle = nil
79
+ return true
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,82 @@
1
+ module Sisimai
2
+ class Mail
3
+ # Sisimai::Mail::Maildir is a reader for getting contents of each email in the
4
+ # Maildir/ directory.
5
+ class Maildir
6
+ # Imported from p5-Sisimail/lib/Sisimai/Mail/Maildir.pm
7
+ @@roaccessors = [
8
+ :dir, # [String] Path to Maildir/
9
+ :size, # [Integer] The number of entires in the directory
10
+ ]
11
+ @@rwaccessors = [
12
+ :path, # [String] Path to each file
13
+ :file, # [String] Each file name of a mail in the Maildir/
14
+ :inodes, # [Array] i-node List of files in the Maildir/
15
+ :offset, # [Integer] Offset position for seeking
16
+ :handle, # [IO::Dir] Directory handle
17
+ ]
18
+ @@roaccessors.each { |e| attr_reader e }
19
+ @@rwaccessors.each { |e| attr_accessor e }
20
+
21
+ # Constructor of Sisimai::Mail::Maildir
22
+ # @param [String] argvs Path to Maildir/
23
+ # @return [Sisimai::Mail::Maildir,Nil] Object or nil if the argument is
24
+ # not a directory or does not exist
25
+ def initialize(argv1)
26
+ raise Errno::ENOENT unless File.exist?(argv1)
27
+ raise Errno::ENOTDIR unless File.ftype(argv1) == 'directory'
28
+
29
+ @path = nil
30
+ @size = Dir.entries(argv1).size
31
+ @dir = argv1
32
+ @file = nil
33
+ @offset = 0
34
+ @inodes = {}
35
+ @handle = Dir.open(argv1)
36
+ end
37
+
38
+ # Maildir reader, works as a iterator.
39
+ # @return [String] Contents of file in Maildir/
40
+ def read
41
+ return nil unless self.offset < self.size
42
+
43
+ seekhandle = self.handle
44
+ readbuffer = ''
45
+
46
+ begin
47
+ while r = seekhandle.read do
48
+ # Read each file in the directory
49
+ self.offset = seekhandle.pos
50
+ next if r == '.' || r == '..'
51
+
52
+ emailindir = sprintf('%s/%s', self.dir, r)
53
+ emailindir = emailindir.squeeze('/')
54
+
55
+ next unless File.ftype(emailindir) == 'file'
56
+ next unless File.size(emailindir) > 0
57
+ next unless File.readable?(emailindir)
58
+
59
+ emailinode = File.stat(emailindir).ino
60
+ next if self.inodes.key?(emailinode)
61
+
62
+ filehandle = File.open(emailindir, 'r')
63
+ readbuffer = filehandle.read
64
+ filehandle.close
65
+
66
+ self.inodes[emailinode] = 1
67
+ self.path = emailindir
68
+ self.file = r
69
+
70
+ break
71
+ end
72
+
73
+ seekhandle.close unless self.offset < self.size
74
+ end
75
+
76
+ return readbuffer
77
+ end
78
+
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,69 @@
1
+ module Sisimai
2
+ class Mail
3
+ # Sisimai::Mail::Mbox is a mailbox file (UNIX mbox) reader.
4
+ class Mbox
5
+ # Imported from p5-Sisimail/lib/Sisimai/Mail/Mbox.pm
6
+ @@roaccessors = [
7
+ :dir, # [String] Directory name of the mbox
8
+ :file, # [String] File name of the mbox
9
+ :path, # [String] Path to mbox
10
+ :size, # [Integer] File size of the mbox
11
+ ]
12
+ @@rwaccessors = [
13
+ :offset, # [Integer] Offset position for seeking
14
+ :handle, # [IO::File] File handle
15
+ ]
16
+ @@roaccessors.each { |e| attr_reader e }
17
+ @@rwaccessors.each { |e| attr_accessor e }
18
+
19
+ # Constructor of Sisimai::Mail::Mbox
20
+ # @param [String] argv1 Path to mbox
21
+ # @return [Sisimai::Mail::Mbox,Nil] Object or nil if the argument is not
22
+ # specified or does not exist
23
+ def initialize(argv1)
24
+ raise Errno::ENOENT unless File.exist?(argv1)
25
+ raise 'is not a file' unless File.ftype(argv1) == 'file'
26
+
27
+ @path = argv1
28
+ @dir = File.dirname(argv1)
29
+ @file = File.basename(argv1)
30
+ @size = File.size(argv1)
31
+ @offset = 0
32
+ @handle = File.open(argv1, 'r')
33
+ end
34
+
35
+ # Mbox reader, works as an iterator.
36
+ # @return [String] Contents of mbox
37
+ def read
38
+ return nil unless self.offset < self.size
39
+
40
+ seekoffset = self.offset || 0
41
+ filehandle = self.handle
42
+ readbuffer = ''
43
+ frombuffer = ''
44
+
45
+ begin
46
+ seekoffset = 0 if seekoffset < 0
47
+ filehandle.seek(seekoffset, 0)
48
+
49
+ filehandle.each_line do |r|
50
+ # Read the UNIX mbox file from 'From ' to the next 'From '
51
+ if r[0, 5] == 'From ' && readbuffer.size > 0
52
+ frombuffer = r
53
+ break
54
+ end
55
+ readbuffer << r
56
+ end
57
+
58
+ seekoffset = filehandle.pos - frombuffer.bytesize
59
+ frombuffer = ''
60
+ self.offset = seekoffset
61
+ filehandle.close unless self.offset < self.size
62
+ end
63
+
64
+ return readbuffer.to_s
65
+ end
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,53 @@
1
+ module Sisimai
2
+ class Mail
3
+ # Sisimai::Mail::STDIN is a reader for getting contents of each email from
4
+ # STDIN
5
+ class STDIN
6
+ # Imported from p5-Sisimail/lib/Sisimai/Mail/STDIN.pm
7
+ @@roaccessors = [
8
+ :path, # [String] Path to mbox
9
+ :name, # [String] File name of the mbox
10
+ :size, # [Integer] File size of the mbox
11
+ ]
12
+ @@rwaccessors = [
13
+ :offset, # [Integer] Offset position for seeking
14
+ :handle, # [IO::File] File handle
15
+ ]
16
+ @@roaccessors.each do |e| attr_reader e end
17
+ @@rwaccessors.each do |e| attr_accessor e end
18
+
19
+ # Constructor of Sisimai::Mail::STDIN
20
+ # @param [IO::STDIN] stdin Standard-In
21
+ # @return [Sisimai::Mail::STDIN] Object
22
+ def initialize(stdin = $stdin)
23
+ raise 'is not an IO object' unless stdin.is_a?(IO)
24
+
25
+ @path = '<STDIN>'
26
+ @name = '<STDIN>'
27
+ @size = nil
28
+ @offset = 0
29
+ @handle = stdin
30
+ end
31
+
32
+ # Mbox reader, works as a iterator.
33
+ # @return [String] Contents of mbox
34
+ def read
35
+ readhandle = self.handle
36
+ readbuffer = ''
37
+
38
+ begin
39
+ readhandle = STDIN unless readhandle
40
+ while r = readhandle.gets
41
+ break if readbuffer.size > 0 && r[0, 5] == 'From '
42
+ readbuffer << r
43
+ end
44
+ ensure
45
+ readhandle.close
46
+ end
47
+
48
+ return readbuffer
49
+ end
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,152 @@
1
+ module Sisimai
2
+ # Sisimai::MDA - Error message parser for MDA
3
+ module MDA
4
+ # Imported from p5-Sisimail/lib/Sisimai/MDA.pm
5
+ class << self
6
+ Re0 = {
7
+ :from => %r/\A(?:Mail Delivery Subsystem|MAILER-DAEMON|postmaster)/i,
8
+ }
9
+ Re1 = {
10
+ # dovecot/src/deliver/deliver.c
11
+ # 11: #define DEFAULT_MAIL_REJECTION_HUMAN_REASON \
12
+ # 12: "Your message to <%t> was automatically rejected:%n%r"
13
+ 'dovecot' => %r/\AYour message to .+ was automatically rejected:\z/,
14
+ 'mail.local' => %r/\Amail[.]local: /,
15
+ 'procmail' => %r/\Aprocmail: /,
16
+ 'maildrop' => %r/\Amaildrop: /,
17
+ 'vpopmail' => %r/\Avdelivermail: /,
18
+ 'vmailmgr' => %r/\Avdeliver: /,
19
+ }
20
+ Re2 = %r{\A(?>
21
+ Your[ ]message[ ]to[ ].+[ ]was[ ]automatically[ ]rejected:\z
22
+ |(?:mail[.]local|procmail|maildrop|vdelivermail|vdeliver):[ ]
23
+ )
24
+ }x
25
+
26
+ # dovecot/src/deliver/mail-send.c:94
27
+ ReFailure = {
28
+ 'dovecot' => {
29
+ 'userunknown' => %r/\AMailbox doesn't exist: /i,
30
+ 'mailboxfull' => %r{\A(?:
31
+ Quota[ ]exceeded # Dovecot 1.2 dovecot/src/plugins/quota/quota.c
32
+ |Quota[ ]exceeded[ ][(]mailbox[ ]for[ ]user[ ]is[ ]full[)] # dovecot/src/plugins/quota/quota.c
33
+ |Not[ ]enough[ ]disk[ ]space
34
+ )
35
+ }xi,
36
+ },
37
+ 'mail.local' => {
38
+ 'userunknown' => %r{[:][ ](?:
39
+ unknown[ ]user[:]
40
+ |User[ ]unknown
41
+ |Invalid[ ]mailbox[ ]path
42
+ |User[ ]missing[ ]home[ ]directory
43
+ )
44
+ }xi,
45
+ 'mailboxfull' => %r{(?:
46
+ Disc[ ]quota[ ]exceeded
47
+ |Mailbox[ ]full[ ]or[ ]quota[ ]exceeded
48
+ )
49
+ }xi,
50
+ 'systemerror' => %r/Temporary file write error/i,
51
+ },
52
+ 'procmail' => {
53
+ 'mailboxfull' => %r/Quota exceeded while writing/i,
54
+ 'systemfull' => %r/No space left to finish writing/i,
55
+ },
56
+ 'maildrop' => {
57
+ 'userunknown' => %r{(?:
58
+ Invalid[ ]user[ ]specified[.]
59
+ |Cannot[ ]find[ ]system[ ]user
60
+ )
61
+ }xi,
62
+ 'mailboxfull' => %r/maildir over quota[.]\z/i,
63
+ },
64
+ 'vpopmail' => {
65
+ 'userunknown' => %r/Sorry, no mailbox here by that name[.]/i,
66
+ 'filtered' => %r{(?:
67
+ account[ ]is[ ]locked[ ]email[ ]bounced
68
+ |user[ ]does[ ]not[ ]exist,[ ]but[ ]will[ ]deliver[ ]to[ ]
69
+ )
70
+ }xi,
71
+ 'mailboxfull' => %r/(?:domain|user) is over quota/i,
72
+ },
73
+ 'vmailmgr' => {
74
+ 'userunknown' => %r{(?>
75
+ Invalid[ ]or[ ]unknown[ ](?:base[ ]user[ ]or[ ]domain|virtual[ ]user)
76
+ |User[ ]name[ ]does[ ]not[ ]refer[ ]to[ ]a[ ]virtual[ ]user/
77
+ )
78
+ }ix,
79
+ 'mailboxfull' => %r/Delivery failed due to system quota violation/i,
80
+ },
81
+ }
82
+
83
+ # Parse message body and return reason and text
84
+ # @param [Hash] mhead Message header of a bounce email
85
+ # @options mhead [String] from From header
86
+ # @options mhead [String] date Date header
87
+ # @options mhead [String] subject Subject header
88
+ # @options mhead [Array] received Received headers
89
+ # @options mhead [String] others Other required headers
90
+ # @param [String] mbody Message body of a bounce email
91
+ # @return [Hash, Nil] Bounce data list and message/rfc822 part
92
+ # or Undef if it failed to parse or the
93
+ # arguments are missing
94
+ def scan(mhead, mbody)
95
+ return nil unless mhead
96
+ return nil unless mbody
97
+ return nil if mhead.keys.size == 0
98
+ return nil if mbody.empty?
99
+
100
+ return nil unless mhead['from'] =~ Re0[:from]
101
+
102
+ agentname0 = '' # [String] MDA name
103
+ reasonname = '' # [String] Error reason
104
+ bouncemesg = '' # [String] Error message
105
+ hasdivided = mbody.split("\n")
106
+ linebuffer = []
107
+
108
+ hasdivided.each do |e|
109
+ # Check each line with each MDA's symbol regular expression.
110
+ if agentname0 == ''
111
+ # Try to match with each regular expression
112
+ next unless e.size > 0;
113
+ next unless e =~ Re2
114
+
115
+ Re1.each_key do |f|
116
+ # Detect the agent name from the line
117
+ next unless e =~ Re1[f]
118
+ agentname0 = f
119
+ break
120
+ end
121
+ end
122
+
123
+ # Append error message lines to @linebuffer
124
+ linebuffer << e
125
+ break unless e.size > 0
126
+ end
127
+
128
+ return nil unless agentname0.size > 0
129
+ return nil unless linebuffer.size > 0
130
+
131
+ ReFailure[agentname0].each_key do |e|
132
+ # Detect an error reason from message patterns of the MDA.
133
+ linebuffer.each do |f|
134
+ # Try to match with each regular expression
135
+ next unless f =~ ReFailure[agentname0][e]
136
+ reasonname = e
137
+ bouncemesg = f
138
+ break
139
+ end
140
+ break if bouncemesg.size > 0 && reasonname.size > 0
141
+ end
142
+
143
+ return {
144
+ 'mda' => agentname0,
145
+ 'reason' => reasonname || '',
146
+ 'message' => bouncemesg || '',
147
+ }
148
+ end
149
+ end
150
+ end
151
+ end
152
+
@@ -0,0 +1,525 @@
1
+ module Sisimai
2
+ # Sisimai::Message convert bounce email text to data structure. It resolve email
3
+ # text into an UNIX From line, the header part of the mail, delivery status, and
4
+ # RFC822 header part. When the email given as a argument of "new" method is not a
5
+ # bounce email, the method returns nil.
6
+ class Message
7
+ # Imported from p5-Sisimail/lib/Sisimai/Message.pm
8
+ require 'sisimai/arf'
9
+ require 'sisimai/mime'
10
+ require 'sisimai/order'
11
+ require 'sisimai/string'
12
+ require 'sisimai/rfc3834'
13
+ require 'sisimai/rfc5322'
14
+
15
+ @@rwaccessors = [
16
+ :from, # [String] UNIX From line
17
+ :header, # [Hash] Header part of a email
18
+ :ds, # [Array] Parsed data by Sisimai::MTA::*
19
+ :rfc822, # [Hash] Header part of the original message
20
+ ]
21
+ @@rwaccessors.each { |e| attr_accessor e }
22
+
23
+ EndOfEmail = Sisimai::String.EOM
24
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
25
+ RFC3834Set = Sisimai::RFC3834.headerlist.map { |e| e.downcase }
26
+ HeaderList = [
27
+ 'from', 'to', 'date', 'subject', 'content-type', 'reply-to', 'message-id',
28
+ 'received', 'content-transfer-encoding', 'return-path', 'x-mailer',
29
+ ]
30
+ MultiHeads = { 'received' => true }
31
+ IgnoreList = { 'dkim-signature' => true }
32
+ Indicators = {
33
+ :begin => (1 << 1),
34
+ :endof => (1 << 2),
35
+ }
36
+ DefaultSet = Sisimai::Order.another
37
+ PatternSet = Sisimai::Order.by('subject')
38
+ ExtHeaders = Sisimai::Order.headers
39
+
40
+ # Constructor of Sisimai::Message
41
+ # @param [String] data Email text data
42
+ # @param [Hash] argvs Module to be loaded
43
+ # @options argvs [String] data Entire email message
44
+ # @return [Sisimai::Message] Structured email data or Undef if each
45
+ # value of the arguments are missing
46
+ def initialize(data: '', **argvs)
47
+ return nil if data.empty?
48
+
49
+ email = data
50
+ email = email.scrub('?')
51
+ email = email.gsub("\r\n", "\n")
52
+ methodargv = { 'data' => email }
53
+
54
+ [:'load', :'order'].each do |e|
55
+ # Order of MTA, MSP modules
56
+ next unless argvs.key?(e)
57
+ next unless argvs[e].is_a? Array
58
+ next if argvs[e].empty?
59
+ methodargv[e.to_s] = argvs[e]
60
+ end
61
+
62
+ parameters = Sisimai::Message.make(methodargv)
63
+ return nil unless parameters
64
+ return nil unless parameters.key?('ds')
65
+
66
+ @from = parameters['from']
67
+ @header = parameters['header']
68
+ @ds = parameters['ds']
69
+ @rfc822 = parameters['rfc822']
70
+ end
71
+
72
+ # Check whether the object has valid content or not
73
+ # @return [True,False] returns true if the object is void
74
+ def void
75
+ return true unless @ds
76
+ return false
77
+ end
78
+
79
+ # Make data structure from the email message(a body part and headers)
80
+ # @param [Hash] argvs Email data
81
+ # @options argvs [String] data Entire email message
82
+ # @return [Hash] Resolved data structure
83
+ def self.make(argvs)
84
+ email = argvs['data']
85
+
86
+ processing = { 'from' => '', 'header' => {}, 'rfc822' => '', 'ds' => [] }
87
+ mtamodules = []
88
+ extheaders = ExtHeaders
89
+ tobeloaded = []
90
+ headerargv = {}
91
+
92
+ %w|load order|.each do |e|
93
+ # The order of MTA modules specified by user
94
+ next unless argvs.key?(e)
95
+ next unless argvs[e].is_a? Array
96
+ next if argvs[e].empty?
97
+
98
+ mtamodules.concat(argvs['order']) if e == 'order'
99
+ next unless e == 'load'
100
+
101
+ # Load user defined MTA module
102
+ argvs['load'].each do |v|
103
+ # Load user defined MTA module
104
+ begin
105
+ require v.to_s.gsub('::', '/').downcase
106
+ rescue LoadError
107
+ warn ' ***warning: Failed to load ' + v
108
+ next
109
+ end
110
+
111
+ Module.const_get(v).headerlist.each do |w|
112
+ # Get header name which required user defined MTA module
113
+ extheaders[w] ||= {}
114
+ extheaders[w][v] = 1
115
+ end
116
+ tobeloaded << v
117
+ end
118
+ end
119
+
120
+ mtamodules.each do |e|
121
+ # Append the custom order of MTA modules
122
+ next if tobeloaded.index(e)
123
+ tobeloaded << e
124
+ end
125
+
126
+ # 0. Split email data to headers and a body part.
127
+ aftersplit = Sisimai::Message.divideup(email)
128
+ return nil if aftersplit.empty?
129
+
130
+ # 1. Convert email headers from text to hash reference
131
+ headerargv['extheaders'] = extheaders
132
+ headerargv['tryonfirst'] = []
133
+ processing['from'] = aftersplit['from']
134
+ processing['header'] = Sisimai::Message.headers(aftersplit['header'], headerargv)
135
+
136
+ # 3. Check headers for detecting MTA/MSP module
137
+ if headerargv['tryonfirst'].empty?
138
+ headerargv['tryonfirst'].concat(Sisimai::Message.makeorder(processing['header']))
139
+ end
140
+
141
+ # 4. Rewrite message body for detecting the bounce reason
142
+ methodargv = {
143
+ 'mail' => processing,
144
+ 'body' => aftersplit['body'],
145
+ 'tryonfirst' => headerargv['tryonfirst'],
146
+ 'tobeloaded' => tobeloaded,
147
+ }
148
+ bouncedata = Sisimai::Message.parse(methodargv)
149
+
150
+ return nil unless bouncedata
151
+ return nil if bouncedata.empty?
152
+ processing['ds'] = bouncedata['ds']
153
+
154
+ # 5. Rewrite headers of the original message in the body part
155
+ rfc822part = bouncedata['rfc822']
156
+ rfc822part = aftersplit['body'] if rfc822part.empty?
157
+ processing['rfc822'] = Sisimai::Message.takeapart(rfc822part)
158
+
159
+ return processing
160
+ end
161
+
162
+ # Divide email data up headers and a body part.
163
+ # @param [String] email Email data
164
+ # @return [Hash] Email data after split
165
+ def self.divideup(email)
166
+ return {} if email.empty?
167
+
168
+ email = email.scrub('?')
169
+ email = email.gsub(/[ \t]+$/, '')
170
+ email = email.gsub(/^[ \t]+$/, '')
171
+ hasdivided = email.split("\n")
172
+ return {} if hasdivided.empty?
173
+
174
+ readcursor = 0
175
+ aftersplit = { 'from' => '', 'header' => '', 'body' => '' }
176
+ pseudofrom = 'MAILER-DAEMON Tue Feb 11 00:00:00 2014'
177
+
178
+ if hasdivided[0][0, 5] == 'From '
179
+ # From MAILER-DAEMON Tue Feb 11 00:00:00 2014
180
+ aftersplit['from'] = hasdivided.shift
181
+ aftersplit['from'] = aftersplit['from'].delete("\n").delete("\r")
182
+ end
183
+
184
+ # Split email data to headers and a body part.
185
+ hasdivided.each do |e|
186
+ # Split email data to headers and a body part.
187
+ e = e.delete("\r").delete("\n")
188
+ e = e.gsub(/[ \t]+\z/, '')
189
+
190
+ if readcursor & Indicators[:endof] > 0
191
+ # The body part of the email
192
+ aftersplit['body'] += e + "\n"
193
+
194
+ else
195
+ # The boundary for splitting headers and a body part does not
196
+ # appeare yet.
197
+ if e.empty?
198
+ # Blank line, it is a boundary of headers and a body part
199
+ readcursor |= Indicators[:endof] if readcursor & Indicators[:begin] > 0
200
+
201
+ else
202
+ # The header part of the email
203
+ aftersplit['header'] += e + "\n"
204
+ readcursor |= Indicators[:begin]
205
+ end
206
+ end
207
+ end
208
+ return {} if aftersplit['header'].empty?
209
+ return {} if aftersplit['body'].empty?
210
+
211
+ aftersplit['from'] = pseudofrom if aftersplit['from'].empty?
212
+ return aftersplit
213
+ end
214
+
215
+ # Convert email headers from text to hash reference
216
+ # @param [String] heads Email header data
217
+ # @param [Hash] argvs
218
+ # @param options extheaders [Array] External header table
219
+ # @return [Hash] Structured email header data
220
+ def self.headers(heads, argvs = {})
221
+ return nil unless heads
222
+
223
+ currheader = ''
224
+ allheaders = {}
225
+ structured = {}
226
+ extheaders = argvs['extheaders'] || []
227
+
228
+ HeaderList.each { |e| structured[e] = nil }
229
+ HeaderList.each { |e| allheaders[e] = true }
230
+ RFC3834Set.each { |e| allheaders[e] = true }
231
+ MultiHeads.each_key { |e| structured[e.downcase] = [] }
232
+ extheaders.each_key { |e| allheaders[e] = true }
233
+
234
+ heads.split("\n").each do |e|
235
+ # Convert email headers to hash
236
+ if cv = e.match(/\A([^ ]+?)[:][ ]*(.+?)\z/)
237
+ # split the line into a header name and a header content
238
+ lhs = cv[1]
239
+ rhs = cv[2]
240
+
241
+ currheader = lhs.downcase
242
+ next unless allheaders.key?(currheader)
243
+
244
+ if MultiHeads.key?(currheader)
245
+ # Such as 'Received' header, there are multiple headers in a single
246
+ # email message.
247
+ rhs = rhs.tr("\t", ' ')
248
+ rhs = rhs.squeeze(' ')
249
+ structured[currheader] << rhs
250
+
251
+ else
252
+ # Other headers except "Received" and so on
253
+ if extheaders[currheader]
254
+ # MTA specific header
255
+ extheaders[currheader].keys.each do |r|
256
+ next if argvs['tryonfirst'].index(r)
257
+ argvs['tryonfirst'] << r
258
+ end
259
+ end
260
+ structured[currheader] = rhs
261
+ end
262
+
263
+ elsif cv = e.match(/\A[ \t]+(.+?)\z/)
264
+ # Ignore header?
265
+ next if IgnoreList[currheader]
266
+
267
+ # Header line continued from the previous line
268
+ if structured[currheader].is_a? Array
269
+ # Concatenate a header which have multi-lines such as 'Received'
270
+ structured[currheader][-1] += ' ' + cv[1]
271
+
272
+ else
273
+ structured[currheader] ||= ''
274
+ structured[currheader] += ' ' + cv[1]
275
+ end
276
+ end
277
+ end
278
+ return structured
279
+ end
280
+
281
+ # Check headers for detecting MTA/MSP module and returns the order of modules
282
+ # @param [Hash] heads Email header data
283
+ # @return [Array] Order of MTA/MSP modules
284
+ def self.makeorder(heads)
285
+ return [] unless heads
286
+ return [] unless heads['subject']
287
+ return [] if heads['subject'].empty?
288
+ order = []
289
+
290
+ # Try to match the value of "Subject" with patterns generated by
291
+ # Sisimai::Order->by('subject') method
292
+ PatternSet.each_key do |e|
293
+ # Get MTA list from the subject header
294
+ next unless heads['subject'] =~ e
295
+
296
+ # Matched and push MTA list
297
+ order.concat(PatternSet[e])
298
+ break
299
+ end
300
+ return order
301
+ end
302
+
303
+ # Take each email header in the original message apart
304
+ # @param [String] heads The original message header
305
+ # @return [Hash] Structured message headers
306
+ def self.takeapart(heads)
307
+ return {} unless heads
308
+
309
+ # Convert from string to hash reference
310
+ heads = heads.gsub(/^[>]+[ ]/m, '')
311
+
312
+ takenapart = {}
313
+ hasdivided = heads.split("\n")
314
+ previousfn = '' # Previous field name
315
+ borderline = '__MIME_ENCODED_BOUNDARY__'
316
+ mimeborder = {}
317
+
318
+ hasdivided.each do |e|
319
+ # Header name as a key, The value of header as a value
320
+ if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*(.*)\z/)
321
+ # Header
322
+ lhs = cv[1].downcase
323
+ rhs = cv[2]
324
+ previousfn = ''
325
+
326
+ next unless RFC822Head.key?(lhs)
327
+ previousfn = lhs
328
+ takenapart[previousfn] = rhs unless takenapart[previousfn]
329
+
330
+ else
331
+ # Continued line from the previous line
332
+ next unless e =~ /\A[ \t]+/
333
+ next if previousfn.empty?
334
+
335
+ # Concatenate the line if it is the value of required header
336
+ if Sisimai::MIME.is_mimeencoded(e)
337
+ # The line is MIME-Encoded test
338
+ if previousfn == 'subject'
339
+ # Subject: header
340
+ takenapart[previousfn] += borderline + e
341
+
342
+ else
343
+ # Is not Subject header
344
+ takenapart[previousfn] += e
345
+ end
346
+ mimeborder[previousfn] = true
347
+
348
+ else
349
+ # ASCII Characters only: Not MIME-Encoded
350
+ e = e.lstrip
351
+ takenapart[previousfn] += e
352
+ mimeborder[previousfn] ||= false
353
+ end
354
+ end
355
+ end
356
+
357
+ if takenapart['subject']
358
+ # Convert MIME-Encoded subject
359
+ v = takenapart['subject']
360
+
361
+ if Sisimai::String.is_8bit(v)
362
+ # The value of ``Subject'' header is including multibyte character,
363
+ # is not MIME-Encoded text.
364
+ v = 'MULTIBYTE CHARACTERS HAVE BEEN REMOVED'
365
+
366
+ else
367
+ # MIME-Encoded subject field or ASCII characters only
368
+ r = []
369
+ if mimeborder['subject']
370
+ # split the value of Subject by $borderline
371
+ v.split(borderline).each do |m|
372
+ # Insert value to the array if the string is MIME encoded text
373
+ r << m if Sisimai::MIME.is_mimeencoded(m)
374
+ end
375
+ else
376
+ # Subject line is not MIME encoded
377
+ r << v
378
+ end
379
+ v = Sisimai::MIME.mimedecode(r)
380
+ end
381
+ takenapart['subject'] = v
382
+ end
383
+ return takenapart
384
+ end
385
+
386
+ # Parse bounce mail with each MTA/MSP module
387
+ # @param [Hash] argvs Processing message entity.
388
+ # @param options argvs [Hash] mail Email message entity
389
+ # @param options mail [String] from From line of mbox
390
+ # @param options mail [Hash] header Email header data
391
+ # @param options mail [String] rfc822 Original message part
392
+ # @param options mail [Array] ds Delivery status list(parsed data)
393
+ # @param options argvs [String] body Email message body
394
+ # @param options argvs [Array] tryonfirst MTA/MSP module list to load on first
395
+ # @param options argvs [Array] tobeloaded User defined MTA module list
396
+ # @return [Hash] Parsed and structured bounce mails
397
+ def self.parse(argvs)
398
+ mesgentity = argvs['mail']
399
+ bodystring = argvs['body']
400
+ tryonfirst = argvs['tryonfirst'] || []
401
+ tobeloaded = argvs['tobeloaded'] || []
402
+ mailheader = mesgentity['header']
403
+
404
+ return nil unless argvs['mail']
405
+ return nil unless argvs['body']
406
+
407
+ # PRECHECK_EACH_HEADER:
408
+ # Set empty string if the value is nil
409
+ mailheader['from'] ||= ''
410
+ mailheader['subject'] ||= ''
411
+ mailheader['content-type'] ||= ''
412
+
413
+ # Decode BASE64 Encoded message body, rewrite.
414
+ mesgformat = (mailheader['content-type'] || '').downcase
415
+ ctencoding = (mailheader['content-transfer-encoding'] || '').downcase
416
+
417
+ if mesgformat =~ %r|text/plain;|
418
+ # Content-Type: text/plain; charset=UTF-8
419
+ if ctencoding == 'base64' || ctencoding == 'quoted-printable'
420
+ # Content-Transfer-Encoding: base64
421
+ # Content-Transfer-Encoding: quoted-printable
422
+ if ctencoding == 'base64'
423
+ # Content-Transfer-Encoding: base64
424
+ bodystring = Sisimai::MIME.base64d(bodystring)
425
+
426
+ else
427
+ # Content-Transfer-Encoding: quoted-printable
428
+ bodystring = Sisimai::MIME.qprintd(bodystring)
429
+ end
430
+ end
431
+ end
432
+
433
+ # EXPAND_FORWARDED_MESSAGE:
434
+ # Check whether or not the message is a bounce mail.
435
+ # Pre-Process email body if it is a forwarded bounce message.
436
+ # Get the original text when the subject begins from 'fwd:' or 'fw:'
437
+ if mailheader['subject'] =~ /\A[ \t]*fwd?:/i
438
+ # Delete quoted strings, quote symbols(>)
439
+ bodystring = bodystring.gsub(/^[>]+[ ]/m, '')
440
+ bodystring = bodystring.gsub(/^[>]$/m, '')
441
+ end
442
+ bodystring += EndOfEmail
443
+ haveloaded = {}
444
+ scannedset = nil
445
+
446
+ catch :SCANNER do
447
+ loop do
448
+ # 1. Sisimai::ARF
449
+ # 2. User-Defined Module
450
+ # 3. MTA Module Candidates to be tried on first
451
+ # 4. Sisimai::MTA::* and MSP::*
452
+ # 5. Sisimai::RFC3464
453
+ # 6. Sisimai::RFC3834
454
+ #
455
+ if Sisimai::ARF.is_arf(mailheader)
456
+ # Feedback Loop message
457
+ scannedset = Sisimai::ARF.scan(mailheader, bodystring)
458
+ throw :SCANNER if scannedset
459
+ end
460
+
461
+ tobeloaded.each do |r|
462
+ # Call user defined MTA modules
463
+ next if haveloaded[r]
464
+ begin
465
+ require r.gsub('::', '/').downcase
466
+ rescue LoadError => ce
467
+ warn ' ***warning: Failed to load ' + ce.to_s
468
+ next
469
+ end
470
+ scannedset = Module.const_get(r).scan(mailheader, bodystring)
471
+ haveloaded[r] = true
472
+ throw :SCANNER if scannedset
473
+ end
474
+
475
+ tryonfirst.each do |r|
476
+ # Try MTA module candidates which are detected from MTA specific
477
+ # mail headers on first
478
+ next if haveloaded.key?(r)
479
+ begin
480
+ require r.gsub('::', '/').downcase
481
+ rescue LoadError => ce
482
+ warn ' ***warning: ' + ce.to_s
483
+ next
484
+ end
485
+ scannedset = Module.const_get(r).scan(mailheader, bodystring)
486
+ haveloaded[r] = true
487
+ throw :SCANNER if scannedset
488
+ end
489
+
490
+ DefaultSet.each do |r|
491
+ # MTA/MSP modules which does not have MTA specific header and did
492
+ # not match with any regular expressions of Subject header.
493
+ next if haveloaded.key?(r)
494
+ begin
495
+ scannedset = Module.const_get(r).scan(mailheader, bodystring)
496
+ haveloaded[r] = true
497
+ throw :SCANNER if scannedset
498
+ rescue => ce
499
+ warn ' ***warning: ' + ce.to_s
500
+ next
501
+ end
502
+
503
+ end
504
+
505
+ # When the all of Sisimai::MTA::* modules did not return bounce data,
506
+ # call Sisimai::RFC3464;
507
+ require 'sisimai/rfc3464'
508
+ scannedset = Sisimai::RFC3464.scan(mailheader, bodystring)
509
+ break if scannedset
510
+
511
+ # Try to parse the message as auto reply message defined in RFC3834
512
+ require 'sisimai/rfc3834'
513
+ scannedset = Sisimai::RFC3834.scan(mailheader, bodystring)
514
+ break if scannedset
515
+
516
+ # as of now, we have no sample email for coding this block
517
+ break
518
+ end
519
+ end
520
+ return scannedset
521
+ end
522
+
523
+ end
524
+ end
525
+