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,338 @@
1
+ module Sisimai
2
+ # Sisimai::ARF is a parser for email returned as a FeedBack Loop report message.
3
+ module ARF
4
+ # Imported from p5-Sisimail/lib/Sisimai/Message.pm
5
+ class << self
6
+ require 'sisimai/mta'
7
+ require 'sisimai/rfc5322'
8
+
9
+ Re0 = {
10
+ :'content-type' => %r|multipart/mixed|,
11
+ :'report-type' => %r/report-type=["]?feedback-report["]?/,
12
+ :'from' => %r{(?:
13
+ staff[@]hotmail[.]com\z
14
+ |complaints[@]email-abuse[.]amazonses[.]com\z
15
+ )
16
+ }x,
17
+ :'subject' => %r/complaint[ ]about[ ]message[ ]from[ ]/,
18
+ }
19
+ # http://tools.ietf.org/html/rfc5965
20
+ # http://en.wikipedia.org/wiki/Feedback_loop_(email)
21
+ # http://en.wikipedia.org/wiki/Abuse_Reporting_Format
22
+ #
23
+ # Netease DMARC uses: This is a spf/dkim authentication-failure report for an email message received from IP
24
+ # OpenDMARC 1.3.0 uses: This is an authentication failure report for an email message received from IP
25
+ # Abusix ARF uses this is an autogenerated email abuse complaint regarding your network.
26
+ Re1 = {
27
+ :begin => %r{\A(?>
28
+ [Tt]his[ ]is[ ].+[ ]email[ ]abuse[ ]report
29
+ |[Tt]his[ ]is[ ](?:
30
+ an[ ]autogenerated[ ]email[ ]abuse[ ]complaint
31
+ |an?[ ].+[ ]report[ ]for
32
+ |a[ ].+[ ]authentication[ -]failure[ ]report[ ]for
33
+ )
34
+ )
35
+ }x,
36
+ :rfc822 => %r[\AContent-Type: (:?message/rfc822|text/rfc822-headers)],
37
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
38
+ }
39
+ Indicators = Sisimai::MTA.INDICATORS
40
+ LongFields = Sisimai::RFC5322.LONGFIELDS
41
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
42
+
43
+ def description; return 'Abuse Feedback Reporting Format'; end
44
+ def smtpagent; return 'FeedBack-Loop'; end
45
+ def headerlist; return []; end
46
+ def pattern; return Re0; end
47
+
48
+ # Email is a Feedback-Loop message or not
49
+ # @param [Hash] heads Email header including "Content-Type", "From",
50
+ # and "Subject" field
51
+ # @return [True,False] true: Feedback Loop
52
+ # false: is not Feedback loop
53
+ def is_arf(heads)
54
+ return false unless heads
55
+ match = false
56
+
57
+ if heads['content-type'] =~ Re0[:'report-type']
58
+ # Content-Type: multipart/report; report-type=feedback-report; ...
59
+ match = true
60
+
61
+ elsif heads['content-type'] =~ Re0[:'content-type']
62
+ # Microsoft (Hotmail, MSN, Live, Outlook) uses its own report format.
63
+ # Amazon SES Complaints bounces
64
+ if heads['from'] =~ Re0[:'from'] && heads['subject'] =~ Re0[:'subject']
65
+ # From: staff@hotmail.com
66
+ # From: complaints@email-abuse.amazonses.com
67
+ # Subject: complaint about message from 192.0.2.1
68
+ match = true
69
+ end
70
+ end
71
+ return match
72
+ end
73
+
74
+ # Detect an error for Feedback Loop
75
+ # @param [Hash] mhead Message header of a bounce email
76
+ # @options mhead [String] from From header
77
+ # @options mhead [String] date Date header
78
+ # @options mhead [String] subject Subject header
79
+ # @options mhead [Array] received Received headers
80
+ # @options mhead [String] others Other required headers
81
+ # @param [String] mbody Message body of a bounce email
82
+ # @return [Hash, Nil] Bounce data list and message/rfc822 part
83
+ # or Undef if it failed to parse or the
84
+ # arguments are missing
85
+ def scan(mhead, mbody)
86
+ return nil unless self.is_arf(mhead)
87
+
88
+ require 'sisimai/address'
89
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
90
+ hasdivided = mbody.split("\n")
91
+ rfc822part = '' # (String) message/rfc822-headers part
92
+ previousfn = '' # (String) Previous field name
93
+ readcursor = 0 # (Integer) Points the current cursor position
94
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
95
+ rcptintext = '' # (String) Recipient address in the message body
96
+ commondata = {
97
+ 'diagnosis' => '', # Error message
98
+ 'from' => '', # Original-Mail-From:
99
+ 'rhost' => '', # Reporting-MTA:
100
+ }
101
+ arfheaders = {
102
+ 'feedbacktype' => nil, # FeedBack-Type:
103
+ 'rhost' => nil, # Source-IP:
104
+ 'agent' => nil, # User-Agent:
105
+ 'date' => nil, # Arrival-Date:
106
+ 'authres' => nil, # Authentication-Results:
107
+ }
108
+ v = nil
109
+
110
+ # 3.1. Required Fields
111
+ #
112
+ # The following report header fields MUST appear exactly once:
113
+ #
114
+ # o "Feedback-Type" contains the type of feedback report (as defined
115
+ # in the corresponding IANA registry and later in this memo). This
116
+ # is intended to let report parsers distinguish among different
117
+ # types of reports.
118
+ #
119
+ # o "User-Agent" indicates the name and version of the software
120
+ # program that generated the report. The format of this field MUST
121
+ # follow section 14.43 of [HTTP]. This field is for documentation
122
+ # only; there is no registry of user agent names or versions, and
123
+ # report receivers SHOULD NOT expect user agent names to belong to a
124
+ # known set.
125
+ #
126
+ # o "Version" indicates the version of specification that the report
127
+ # generator is using to generate the report. The version number in
128
+ # this specification is set to "1".
129
+ #
130
+ hasdivided.each do |e|
131
+ if readcursor == 0
132
+ # Beginning of the bounce message or delivery status part
133
+ if e =~ Re1[:begin]
134
+ readcursor |= Indicators[:'deliverystatus']
135
+ next
136
+ end
137
+ end
138
+
139
+ if readcursor & Indicators[:'message-rfc822'] == 0
140
+ # Beginning of the original message part
141
+ if e =~ Re1[:rfc822]
142
+ readcursor |= Indicators[:'message-rfc822']
143
+ next
144
+ end
145
+ end
146
+
147
+ if readcursor & Indicators[:'message-rfc822'] > 0
148
+ # After "message/rfc822"
149
+ if cv = e.match(/X-HmXmrOriginalRecipient:[ ]*(.+)\z/)
150
+ # Microsoft ARF: original recipient.
151
+ dscontents[-1]['recipient'] = Sisimai::Address.s3s4(cv[1])
152
+ recipients += 1
153
+
154
+ # The "X-HmXmrOriginalRecipient" header appears only once so
155
+ # we take this opportunity to hard-code ARF headers missing in
156
+ # Microsoft's implementation.
157
+ arfheaders['feedbacktype'] = 'abuse'
158
+ arfheaders['agent'] = 'Microsoft Junk Mail Reporting Program'
159
+
160
+ elsif cv = e.match(/\AFrom:[ ]*(.+)\z/)
161
+ # Microsoft ARF: original sender.
162
+ if commondata['from'].empty?
163
+ commondata['from'] = Sisimai::Address.s3s4(cv[1])
164
+ end
165
+
166
+ elsif cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*(.+)\z/)
167
+ # Get required headers only
168
+ lhs = cv[1].downcase
169
+ rhs = cv[2]
170
+
171
+ previousfn = ''
172
+ next unless RFC822Head.key?(lhs)
173
+
174
+ previousfn = lhs
175
+ rfc822part += e + "\n"
176
+ rcptintext = rhs if lhs == 'to'
177
+
178
+ elsif e =~ /\A[ \t]+/
179
+ # Continued line from the previous line
180
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
181
+ next if e.size > 0
182
+ rcptintext += e if previousfn == 'to'
183
+ end
184
+
185
+ else
186
+ # Before "message/rfc822"
187
+ next unless readcursor & Indicators[:'deliverystatus'] > 0
188
+ next unless e.size > 0
189
+
190
+ # Feedback-Type: abuse
191
+ # User-Agent: SomeGenerator/1.0
192
+ # Version: 0.1
193
+ # Original-Mail-From: <somespammer@example.net>
194
+ # Original-Rcpt-To: <kijitora@example.jp>
195
+ # Received-Date: Thu, 29 Apr 2009 00:00:00 JST
196
+ # Source-IP: 192.0.2.1
197
+ v = dscontents[-1]
198
+
199
+ if cv = e.match(/\AOriginal-Rcpt-To:[ ]+[<]?(.+)[>]?\z/) ||
200
+ cv = e.match(/\ARedacted-Address:[ ]([^ ].+[@])\z/)
201
+ # Original-Rcpt-To header field is optional and may appear any
202
+ # number of times as appropriate:
203
+ # Original-Rcpt-To: <user@example.com>
204
+ # Redacted-Address: localpart@
205
+ if v['recipient']
206
+ # There are multiple recipient addresses in the message body.
207
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
208
+ v = dscontents[-1]
209
+ end
210
+ v['recipient'] = Sisimai::Address.s3s4(cv[1])
211
+ recipients += 1
212
+
213
+ elsif cv = e.match(/\AFeedback-Type:[ ]*([^ ]+)\z/)
214
+ # The header field MUST appear exactly once.
215
+ # Feedback-Type: abuse
216
+ arfheaders['feedbacktype'] = cv[1]
217
+
218
+ elsif cv = e.match(/\AAuthentication-Results:[ ]*(.+)\z/)
219
+ # "Authentication-Results" indicates the result of one or more
220
+ # authentication checks run by the report generator.
221
+ #
222
+ # Authentication-Results: mail.example.com;
223
+ # spf=fail smtp.mail=somespammer@example.com
224
+ arfheaders['authres'] = cv[1]
225
+
226
+ elsif cv = e.match(/\AUser-Agent:[ ]*(.+)\z/)
227
+ # The header field MUST appear exactly once.
228
+ # User-Agent: SomeGenerator/1.0
229
+ arfheaders['agent'] = cv[1]
230
+
231
+ elsif cv = e.match(/\A(?:Received|Arrival)-Date:[ ]*(.+)\z/)
232
+ # Arrival-Date header is optional and MUST NOT appear more than
233
+ # once.
234
+ # Received-Date: Thu, 29 Apr 2010 00:00:00 JST
235
+ # Arrival-Date: Thu, 29 Apr 2010 00:00:00 +0000
236
+ arfheaders['date'] = cv[1]
237
+
238
+ elsif cv = e.match(/\AReporting-MTA:[ ]*dns;[ ]*(.+)\z/)
239
+ # The header is optional and MUST NOT appear more than once.
240
+ # Reporting-MTA: dns; mx.example.jp
241
+ commondata['rhost'] = cv[1]
242
+
243
+ elsif cv = e.match(/\ASource-IP:[ ]*(.+)\z/)
244
+ # The header is optional and MUST NOT appear more than once.
245
+ # Source-IP: 192.0.2.45
246
+ arfheaders['rhost'] = cv[1]
247
+
248
+ elsif cv = e.match(/\AOriginal-Mail-From:[ ]*(.+)\z/)
249
+ # the header is optional and MUST NOT appear more than once.
250
+ # Original-Mail-From: <somespammer@example.net>
251
+ if commondata['from'].empty?
252
+ commondata['from'] = Sisimai::Address.s3s4(cv[1])
253
+ end
254
+
255
+ elsif e =~ Re1[:begin]
256
+ # This is an email abuse report for an email message with the
257
+ # message-id of 0000-000000000000000000000000000000000@mx
258
+ # received from IP address 192.0.2.1 on
259
+ # Thu, 29 Apr 2010 00:00:00 +0900 (JST)
260
+ commondata['diagnosis'] = e
261
+ end
262
+ end
263
+ end
264
+
265
+ if arfheaders['feedbacktype'] == 'auth-failure' && arfheaders['authres']
266
+ # Append the value of Authentication-Results header
267
+ commondata['diagnosis'] += ' ' + arfheaders['authres']
268
+ end
269
+
270
+ if recipients == 0
271
+ # Insert pseudo recipient address when there is no valid recipient
272
+ # address in the message.
273
+ dscontents[-1]['recipient'] = Sisimai::Address.undisclosed('r')
274
+ recipients = 1
275
+ end
276
+
277
+ unless rfc822part =~ /\bFrom: [^ ]+[@][^ ]+\b/
278
+ # There is no "From:" header in the original message
279
+ if commondata['from'].size > 0
280
+ # Append the value of "Original-Mail-From" value as a sender address.
281
+ rfc822part += sprintf("From: %s\n", commondata['from'])
282
+ end
283
+ end
284
+
285
+ if cv = mhead['subject'].match(/complaint about message from (\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3})/)
286
+ # Microsoft ARF: remote host address.
287
+ arfheaders['rhost'] = cv[1]
288
+ commondata['diagnosis'] = sprintf(
289
+ 'This is a Microsoft email abuse report for an email message received from IP %s on %s',
290
+ arfheaders['rhost'], mhead['date'])
291
+ end
292
+
293
+ dscontents.map do |e|
294
+ if e['recipient'] =~ /\A[^ ]+[@]\z/
295
+ # AOL = http://forums.cpanel.net/f43/aol-brutal-work-71473.html
296
+ e['recipient'] = Sisimai::Address.s3s4(rcptintext)
297
+ end
298
+ arfheaders.each_key { |a| e[a] ||= arfheaders[a] || '' }
299
+ e.delete('authres')
300
+
301
+ e['softbounce'] = -1
302
+ e['diagnosis'] = commondata['diagnosis'] unless e['diagnosis']
303
+ e['date'] = mhead['date'] if e['date'].empty?
304
+
305
+ if e['rhost'].empty?
306
+ # Get the remote IP address from the message body
307
+ if commondata['rhost'].size > 0
308
+ # The value of "Reporting-MTA" header
309
+ e['rhost'] = commondata['rhost']
310
+
311
+ elsif cv = e['diagnosis'].match(/\breceived from IP address ([^ ]+)/)
312
+ # This is an email abuse report for an email message received
313
+ # from IP address 24.64.1.1 on Thu, 29 Apr 2010 00:00:00 +0000
314
+ e['rhost'] = cv[1]
315
+ end
316
+ end
317
+
318
+ if mhead['received'].size > 0
319
+ # Get localhost and remote host name from Received header.
320
+ r0 = mhead['received']
321
+ %w|lhost rhost|.each { |a| e[a] ||= '' }
322
+ e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
323
+ e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
324
+ end
325
+
326
+ e['spec'] = 'SMTP'
327
+ e['action'] = 'failed'
328
+ e['reason'] = 'feedback'
329
+ e['command'] = ''
330
+ e['status'] = ''
331
+ e['alias'] = ''
332
+ e['agent'] = self.smtpagent if e['agent'].empty?
333
+ end
334
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
335
+ end
336
+ end
337
+ end
338
+ end
@@ -0,0 +1,409 @@
1
+ module Sisimai
2
+ # Sisimai::Data generate parsed data from Sisimai::Message object.
3
+ class Data
4
+ # Imported from p5-Sisimail/lib/Sisimai/Data.pm
5
+ require 'sisimai/address'
6
+ require 'sisimai/rfc5322'
7
+ require 'sisimai/smtp/reply'
8
+ require 'sisimai/smtp/status'
9
+ require 'sisimai/string'
10
+ require 'sisimai/reason'
11
+ require 'sisimai/rhost'
12
+ require 'sisimai/time'
13
+ require 'sisimai/datetime'
14
+
15
+ @@rwaccessors = [
16
+ :token, # [String] Message token/MD5 Hex digest value
17
+ :lhost, # [String] local host name/Local MTA
18
+ :rhost, # [String] Remote host name/Remote MTA
19
+ :alias, # [String] Alias of the recipient address
20
+ :listid, # [String] List-Id header of each ML
21
+ :reason, # [String] Bounce reason
22
+ :action, # [String] The value of Action: header
23
+ :subject, # [String] UTF-8 Subject text
24
+ :timestamp, # [Sisimai::Time] Date: header in the original message
25
+ :addresser, # [Sisimai::Address] From address
26
+ :recipient, # [Sisimai::Address] Recipient address which bounced
27
+ :messageid, # [String] Message-Id: header
28
+ :replycode, # [String] SMTP Reply Code
29
+ :smtpagent, # [String] MTA name
30
+ :softbounce, # [Integer] 1 = Soft bounce, 0 = Hard bounce, -1 = ?
31
+ :smtpcommand, # [String] The last SMTP command
32
+ :destination, # [String] The domain part of the "recipinet"
33
+ :senderdomain, # [String] The domain part of the "addresser"
34
+ :feedbacktype, # [String] Feedback Type
35
+ :diagnosticcode, # [String] Diagnostic-Code: Header
36
+ :diagnostictype, # [String] The 1st part of Diagnostic-Code: Header
37
+ :deliverystatus, # [String] Delivery Status(DSN)
38
+ :timezoneoffset, # [Integer] Time zone offset(seconds)
39
+ ]
40
+ @@rwaccessors.each { |e| attr_accessor e }
41
+
42
+ EndOfEmail = Sisimai::String.EOM
43
+ RetryIndex = Sisimai::Reason.retry
44
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS('all')
45
+ AddrHeader = {
46
+ 'addresser' => RFC822Head['addresser'],
47
+ 'recipient' => RFC822Head['recipient'],
48
+ }
49
+
50
+ # Constructor of Sisimai::Data
51
+ # @param [Hash] argvs Data
52
+ # @return [Sisimai::Data] Structured email data
53
+ def initialize(argvs)
54
+ thing = {}
55
+
56
+ # Create email address object
57
+ x0 = Sisimai::Address.parse([argvs['addresser']])
58
+ y0 = Sisimai::Address.parse([argvs['recipient']])
59
+ v0 = nil
60
+
61
+ if x0.is_a? Array
62
+ v0 = Sisimai::Address.new(x0.shift)
63
+ if v0.is_a? Sisimai::Address
64
+ thing['addresser'] = v0
65
+ thing['senderdomain'] = v0.host
66
+ end
67
+ end
68
+
69
+ if y0.is_a? Array
70
+ v0 = Sisimai::Address.new(y0.shift)
71
+ if v0.is_a? Sisimai::Address
72
+ thing['recipient'] = v0
73
+ thing['destination'] = v0.host
74
+ thing['alias'] = argvs['alias'] || ''
75
+ end
76
+ end
77
+ return nil unless thing['recipient'].is_a? Sisimai::Address
78
+ return nil unless thing['addresser'].is_a? Sisimai::Address
79
+ return nil if thing['recipient'].void
80
+ return nil if thing['addresser'].void
81
+
82
+ @addresser = thing['addresser']
83
+ @senderdomain = thing['senderdomain']
84
+ @recipient = thing['recipient']
85
+ @destination = thing['destination']
86
+ @alias = thing['alias']
87
+
88
+ @token = Sisimai::String.token(@addresser.address, @recipient.address, argvs['timestamp'])
89
+ @timestamp = Sisimai::Time.parse(::Time.at(argvs['timestamp']).to_s)
90
+ @timezoneoffset = argvs['timezoneoffset'] || '+0000'
91
+ @lhost = argvs['lhost'] || ''
92
+ @rhost = argvs['rhost'] || ''
93
+ @reason = argvs['reason'] || ''
94
+ @listid = argvs['listid'] || ''
95
+ @subject = argvs['subject'] || ''
96
+ @messageid = argvs['messageid'] || ''
97
+ @smtpagent = argvs['smtpagent'] || ''
98
+ @diagnosticcode = argvs['diagnosticcode'] || ''
99
+ @diagnostictype = argvs['diagnostictype'] || ''
100
+ @deliverystatus = argvs['deliverystatus'] || ''
101
+ @smtpcommand = argvs['smtpcommand'] || ''
102
+ @feedbacktype = argvs['feedbacktype'] || ''
103
+ @action = argvs['action'] || ''
104
+ @replycode = Sisimai::SMTP::Reply.find(argvs['diagnosticcode'])
105
+ @softbounce = argvs['softbounce'] || ''
106
+ @softbounce = 1 if @replycode =~ /\A4/
107
+
108
+ if cv = @action.match(/\A(.+?) .+/)
109
+ @action = cv[1]
110
+ end
111
+
112
+ if @replycode.size > 0 && @deliverystatus.size > 0
113
+ # The first digits did not match: 5.1.1 250
114
+ @replycode = '' unless @replycode[0, 1] == @deliverystatus[0, 1]
115
+ end
116
+
117
+ end
118
+
119
+ # Another constructor of Sisimai::Data
120
+ # @param [Sisimai::Message] data Data Object
121
+ # @param [Hash] argvs Parser options
122
+ # @options argvs [Boolean] delivered true: Including "delivered" reason
123
+ # @return [Array, Nil] List of Sisimai::Data or Nil if the
124
+ # argument is not Sisimai::Message object
125
+ def self.make(data: nil, **argvs)
126
+ return nil unless data
127
+ return nil unless data.is_a? Sisimai::Message
128
+
129
+ messageobj = data
130
+ rfc822data = messageobj.rfc822
131
+ fieldorder = { 'recipient' => [], 'addresser' => [] }
132
+ objectlist = []
133
+ rxcommands = %r/\A(?:EHLO|HELO|MAIL|RCPT|DATA|QUIT)\z/
134
+ givenorder = argvs['order'] || {}
135
+ delivered1 = argvs[:delivered] || false
136
+
137
+ return nil unless messageobj.ds
138
+ return nil unless messageobj.rfc822
139
+ require 'sisimai/smtp'
140
+
141
+ # Decide the order of email headers: user specified or system default.
142
+ if givenorder.is_a?(Hash) && givenorder.keys.size > 0
143
+ # If the order of headers for searching is specified, use the order
144
+ # for detecting an email address.
145
+ fieldorder.each_key do |e|
146
+ # The order should be "Array Reference".
147
+ next unless givenorder[e]
148
+ next unless givenorder[e].is_a? Array
149
+ next unless givenorder[e].size > 0
150
+ fieldorder[e].concat(givenorder[e])
151
+ end
152
+ end
153
+
154
+ fieldorder.each_key do |e|
155
+ # If the order is empty, use default order.
156
+ if fieldorder[e].empty?
157
+ # Load default order of each accessor.
158
+ fieldorder[e] = AddrHeader[e]
159
+ end
160
+ end
161
+
162
+ messageobj.ds.each do |e|
163
+ # Create parameters for new() constructor.
164
+ o = nil # Sisimai::Data Object
165
+ r = nil # Reason text
166
+ p = {
167
+ 'lhost' => e['lhost'] || '',
168
+ 'rhost' => e['rhost'] || '',
169
+ 'alias' => e['alias'] || '',
170
+ 'action' => e['action'] || '',
171
+ 'reason' => e['reason'] || '',
172
+ 'smtpagent' => e['agent'] || '',
173
+ 'recipient' => e['recipient'] || '',
174
+ 'softbounce' => e['softbounce'] || '',
175
+ 'smtpcommand' => e['command'] || '',
176
+ 'feedbacktype' => e['feedbacktype'] || '',
177
+ 'diagnosticcode' => e['diagnosis'] || '',
178
+ 'diagnostictype' => e['spec'] || '',
179
+ 'deliverystatus' => e['status'] || '',
180
+ }
181
+ unless delivered1
182
+ # Skip if the value of "deliverystatus" begins with "2." such as 2.1.5
183
+ next if p['deliverystatus'] =~ /\A2[.]/
184
+ end
185
+
186
+ # EMAIL_ADDRESS:
187
+ # Detect email address from message/rfc822 part
188
+ fieldorder['addresser'].each do |f|
189
+ # Check each header in message/rfc822 part
190
+ h = f.downcase
191
+ next unless rfc822data.key?(h)
192
+ next unless rfc822data[h].size > 0
193
+ next unless Sisimai::RFC5322.is_emailaddress(rfc822data[h])
194
+ p['addresser'] = rfc822data[h]
195
+ break
196
+ end
197
+
198
+ # Fallback: Get the sender address from the header of the bounced
199
+ # email if the address is not set at loop above.
200
+ p['addresser'] ||= ''
201
+ p['addresser'] = messageobj.header['to'] if p['addresser'].empty?
202
+
203
+ next unless p['addresser']
204
+ next unless p['recipient']
205
+
206
+ # TIMESTAMP:
207
+ # Convert from a time stamp or a date string to a machine time.
208
+ datestring = nil
209
+ zoneoffset = 0
210
+ datevalues = []
211
+ if e['date'] && e['date'].size > 0
212
+ datevalues << e['date']
213
+ end
214
+
215
+ # Date information did not exist in message/delivery-status part,...
216
+ RFC822Head['date'].each do |f|
217
+ # Get the value of Date header or other date related header.
218
+ next unless rfc822data[f.downcase]
219
+ datevalues << rfc822data[f.downcase]
220
+ end
221
+
222
+ if datevalues.size < 2
223
+ # Set "date" getting from the value of "Date" in the bounce message
224
+ datevalues << messageobj.header['date']
225
+ end
226
+
227
+ datevalues.each do |v|
228
+ # Parse each date value in the array
229
+ datestring = Sisimai::DateTime.parse(v)
230
+ break if datestring
231
+ end
232
+
233
+ if datestring
234
+ # Get the value of timezone offset from $datestring
235
+ if cv = datestring.match(/\A(.+)[ ]+([-+]\d{4})\z/)
236
+ # Wed, 26 Feb 2014 06:05:48 -0500
237
+ datestring = cv[1]
238
+ zoneoffset = Sisimai::DateTime.tz2second(cv[2])
239
+ p['timezoneoffset'] = cv[2]
240
+ end
241
+ end
242
+
243
+ begin
244
+ # Convert from the date string to an object then calculate time
245
+ # zone offset.
246
+ t = Sisimai::Time.strptime(datestring, '%a, %d %b %Y %T')
247
+ p['timestamp'] = (t.to_time.to_i - zoneoffset) || nil
248
+ rescue
249
+ warn ' ***warning: Failed to strptime ' + datestring.to_s
250
+ end
251
+ next unless p['timestamp']
252
+
253
+ # OTHER_TEXT_HEADERS:
254
+ # Remove square brackets and curly brackets from the host variable
255
+ %w|rhost lhost|.each do |v|
256
+ p[v] = p[v].delete('[]()') # Remove square brackets and curly brackets from the host variable
257
+ p[v] = p[v].sub(/\A.+=/, '') # Remove string before "="
258
+ p[v] = p[v].gsub(/\r\z/, '') # Remove CR at the end of the value
259
+
260
+ # Check space character in each value
261
+ if p[v] =~ / /
262
+ # Get the first element
263
+ p[v] = p[v].split(' ', 2).shift
264
+ end
265
+ end
266
+
267
+ # Subject: header of the original message
268
+ p['subject'] = rfc822data['subject'] || ''
269
+ p['subject'] = p['subject'].gsub(/\r\z/, '')
270
+
271
+ # The value of "List-Id" header
272
+ p['listid'] = rfc822data['list-id'] || ''
273
+ if p['listid'].size > 0
274
+ # Get the value of List-Id header
275
+ if cv = p['listid'].match(/\A.*([<].+[>]).*\z/)
276
+ # List name <list-id@example.org>
277
+ p['listid'] = cv[1]
278
+ end
279
+ p['listid'] = p['listid'].delete('<>')
280
+ p['listid'] = p['listid'].gsub(/\r\z/, '')
281
+ p['listid'] = '' if p['listid'] =~ / /
282
+ end
283
+
284
+ # The value of "Message-Id" header
285
+ p['messageid'] = rfc822data['message-id'] || ''
286
+ if p['messageid'].size > 0
287
+ # Remove angle brackets
288
+ if cv = p['messageid'].match(/\A([^ ]+)[ ].*/)
289
+ p['messageid'] = cv[1]
290
+ end
291
+ p['messageid'] = p['messageid'].delete('<>')
292
+ p['messageid'] = p['messageid'].gsub(/\r\z/, '')
293
+ end
294
+
295
+ # CHECK_DELIVERY_STATUS_VALUE:
296
+ # Cleanup the value of "Diagnostic-Code:" header
297
+ p['diagnosticcode'] = p['diagnosticcode'].sub(/[ \t]+#{EndOfEmail}/, '')
298
+ d = Sisimai::SMTP::Status.find(p['diagnosticcode'])
299
+ if d =~ /\A[45][.][1-9][.][1-9]\z/
300
+ # Use the DSN value in Diagnostic-Code:
301
+ p['deliverystatus'] = d
302
+ end
303
+
304
+ # Check the value of SMTP command
305
+ p['smtpcommand'] = '' unless p['smtpcommand'] =~ rxcommands
306
+
307
+ o = Sisimai::Data.new(p)
308
+ next unless o.recipient
309
+
310
+ if o.reason.empty? || RetryIndex.index(o.reason)
311
+ # Decide the reason of email bounce
312
+ r = ''
313
+ if Sisimai::Rhost.match(o.rhost)
314
+ # Remote host dependent error
315
+ r = Sisimai::Rhost.get(o)
316
+ end
317
+ r = Sisimai::Reason.get(o) if r.empty?
318
+ r = 'undefined' if r.empty?
319
+ o.reason = r
320
+ end
321
+
322
+ if o.reason != 'feedback' && o.reason != 'vacation'
323
+ # Bounce message which reason is "feedback" or "vacation" does
324
+ # not have the value of "deliverystatus".
325
+ if o.softbounce.to_s.empty?
326
+ # The value is not set yet
327
+ %w|deliverystatus diagnosticcode|.each do |v|
328
+ # Set the value of softbounce
329
+ next unless p[v].size > 0
330
+ r = Sisimai::SMTP.is_softbounce(p[v])
331
+ if r.nil?
332
+ o.softbounce = -1
333
+ else
334
+ o.softbounce = r ? 1 : 0
335
+ end
336
+ break if o.softbounce > -1
337
+ end
338
+ o.softbounce = -1 if o.softbounce.to_s.empty?
339
+ end
340
+
341
+ if o.deliverystatus.empty?
342
+ # Set pseudo status code
343
+ torp = o.softbounce == 1 ? true : false
344
+ pdsv = Sisimai::SMTP::Status.code(o.reason, torp)
345
+
346
+ if pdsv.size > 0
347
+ # Set the value of "deliverystatus" and "softbounce".
348
+ o.deliverystatus = pdsv
349
+ if o.softbounce == -1
350
+ # Check the value of "softbounce" again
351
+ torp = Sisimai::SMTP.is_softbounce(pdsv)
352
+ if torp.nil?
353
+ o.softbounce = -1
354
+ else
355
+ o.softbounce = torp ? 1 : 0
356
+ end
357
+ end
358
+ end
359
+ end
360
+ else
361
+ # The value of reason is "vacation" or "feedback"
362
+ o.softbounce = -1
363
+ end
364
+ objectlist << o
365
+ end
366
+ return objectlist
367
+ end
368
+
369
+ # Convert from object to hash reference
370
+ # @return [Hash] Data in Hash reference
371
+ def damn
372
+ data = {}
373
+ @@rwaccessors.each do |e|
374
+ next if e.to_s =~ /(?:addresser|recipient|timestamp)/
375
+ data[e.to_s] = self.send(e) || ''
376
+ end
377
+ data['addresser'] = self.addresser.address
378
+ data['recipient'] = self.recipient.address
379
+ data['timestamp'] = self.timestamp.to_time.to_i
380
+ return data
381
+ end
382
+ alias :to_hash :damn
383
+
384
+ # Data dumper
385
+ # @param [String] type Data format: json, yaml
386
+ # @return [String, Undef] Dumped data or Undef if the value of first
387
+ # argument is neither "json" nor "yaml"
388
+ def dump(type = 'json')
389
+ return nil unless %w|json yaml|.index(type)
390
+ referclass = sprintf('Sisimai::Data::%s', type.upcase)
391
+
392
+ begin
393
+ require referclass.downcase.gsub('::', '/')
394
+ rescue
395
+ warn '***warning: Failed to load' + referclass
396
+ end
397
+
398
+ dumpeddata = Module.const_get(referclass).dump(self)
399
+ return dumpeddata
400
+ end
401
+
402
+ # JSON handler
403
+ # @return [String] JSON string converted from Sisimai::Data
404
+ def to_json(*)
405
+ return self.dump('json')
406
+ end
407
+
408
+ end
409
+ end