sisimai 4.14.2

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 (562) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +165 -0
  5. data/.travis.yml +21 -0
  6. data/ANALYTICAL-PRECISION +54 -0
  7. data/Changes +5 -0
  8. data/Developers.mk +129 -0
  9. data/Gemfile +9 -0
  10. data/LICENSE +26 -0
  11. data/Makefile +56 -0
  12. data/README.md +300 -0
  13. data/Rakefile +7 -0
  14. data/Repository.mk +69 -0
  15. data/bin/console +14 -0
  16. data/bin/setup +7 -0
  17. data/lib/sisimai.rb +60 -0
  18. data/lib/sisimai/address.rb +218 -0
  19. data/lib/sisimai/arf.rb +343 -0
  20. data/lib/sisimai/data.rb +413 -0
  21. data/lib/sisimai/data/json.rb +36 -0
  22. data/lib/sisimai/data/yaml.rb +32 -0
  23. data/lib/sisimai/datetime.rb +518 -0
  24. data/lib/sisimai/mail.rb +82 -0
  25. data/lib/sisimai/mail/maildir.rb +85 -0
  26. data/lib/sisimai/mail/mbox.rb +69 -0
  27. data/lib/sisimai/mail/stdin.rb +52 -0
  28. data/lib/sisimai/mda.rb +152 -0
  29. data/lib/sisimai/message.rb +510 -0
  30. data/lib/sisimai/mime.rb +127 -0
  31. data/lib/sisimai/msp.rb +54 -0
  32. data/lib/sisimai/msp/de/einsundeins.rb +174 -0
  33. data/lib/sisimai/msp/de/gmx.rb +197 -0
  34. data/lib/sisimai/msp/jp/biglobe.rb +179 -0
  35. data/lib/sisimai/msp/jp/ezweb.rb +292 -0
  36. data/lib/sisimai/msp/jp/kddi.rb +195 -0
  37. data/lib/sisimai/msp/ru/mailru.rb +306 -0
  38. data/lib/sisimai/msp/ru/yandex.rb +241 -0
  39. data/lib/sisimai/msp/uk/messagelabs.rb +250 -0
  40. data/lib/sisimai/msp/us/amazonses.rb +248 -0
  41. data/lib/sisimai/msp/us/aol.rb +234 -0
  42. data/lib/sisimai/msp/us/bigfoot.rb +243 -0
  43. data/lib/sisimai/msp/us/facebook.rb +306 -0
  44. data/lib/sisimai/msp/us/google.rb +357 -0
  45. data/lib/sisimai/msp/us/outlook.rb +243 -0
  46. data/lib/sisimai/msp/us/receivingses.rb +247 -0
  47. data/lib/sisimai/msp/us/sendgrid.rb +257 -0
  48. data/lib/sisimai/msp/us/verizon.rb +311 -0
  49. data/lib/sisimai/msp/us/yahoo.rb +178 -0
  50. data/lib/sisimai/msp/us/zoho.rb +198 -0
  51. data/lib/sisimai/mta.rb +55 -0
  52. data/lib/sisimai/mta/activehunter.rb +155 -0
  53. data/lib/sisimai/mta/apachejames.rb +194 -0
  54. data/lib/sisimai/mta/courier.rb +307 -0
  55. data/lib/sisimai/mta/domino.rb +209 -0
  56. data/lib/sisimai/mta/exchange.rb +314 -0
  57. data/lib/sisimai/mta/exim.rb +549 -0
  58. data/lib/sisimai/mta/imailserver.rb +227 -0
  59. data/lib/sisimai/mta/interscanmss.rb +167 -0
  60. data/lib/sisimai/mta/mailfoundry.rb +173 -0
  61. data/lib/sisimai/mta/mailmarshalsmtp.rb +206 -0
  62. data/lib/sisimai/mta/mcafee.rb +201 -0
  63. data/lib/sisimai/mta/messagingserver.rb +241 -0
  64. data/lib/sisimai/mta/mfilter.rb +190 -0
  65. data/lib/sisimai/mta/mxlogic.rb +283 -0
  66. data/lib/sisimai/mta/notes.rb +206 -0
  67. data/lib/sisimai/mta/opensmtpd.rb +225 -0
  68. data/lib/sisimai/mta/postfix.rb +306 -0
  69. data/lib/sisimai/mta/qmail.rb +335 -0
  70. data/lib/sisimai/mta/sendmail.rb +317 -0
  71. data/lib/sisimai/mta/surfcontrol.rb +193 -0
  72. data/lib/sisimai/mta/userdefined.rb +148 -0
  73. data/lib/sisimai/mta/v5sendmail.rb +232 -0
  74. data/lib/sisimai/mta/x1.rb +156 -0
  75. data/lib/sisimai/mta/x2.rb +157 -0
  76. data/lib/sisimai/mta/x3.rb +171 -0
  77. data/lib/sisimai/mta/x4.rb +365 -0
  78. data/lib/sisimai/mta/x5.rb +208 -0
  79. data/lib/sisimai/order.rb +217 -0
  80. data/lib/sisimai/reason.rb +235 -0
  81. data/lib/sisimai/reason/blocked.rb +105 -0
  82. data/lib/sisimai/reason/contenterror.rb +53 -0
  83. data/lib/sisimai/reason/exceedlimit.rb +60 -0
  84. data/lib/sisimai/reason/expired.rb +53 -0
  85. data/lib/sisimai/reason/filtered.rb +98 -0
  86. data/lib/sisimai/reason/hasmoved.rb +45 -0
  87. data/lib/sisimai/reason/hostunknown.rb +74 -0
  88. data/lib/sisimai/reason/mailboxfull.rb +118 -0
  89. data/lib/sisimai/reason/mailererror.rb +55 -0
  90. data/lib/sisimai/reason/mesgtoobig.rb +77 -0
  91. data/lib/sisimai/reason/networkerror.rb +57 -0
  92. data/lib/sisimai/reason/norelaying.rb +71 -0
  93. data/lib/sisimai/reason/notaccept.rb +63 -0
  94. data/lib/sisimai/reason/onhold.rb +45 -0
  95. data/lib/sisimai/reason/rejected.rb +101 -0
  96. data/lib/sisimai/reason/securityerror.rb +72 -0
  97. data/lib/sisimai/reason/spamdetected.rb +172 -0
  98. data/lib/sisimai/reason/suspend.rb +58 -0
  99. data/lib/sisimai/reason/systemerror.rb +69 -0
  100. data/lib/sisimai/reason/systemfull.rb +45 -0
  101. data/lib/sisimai/reason/toomanyconn.rb +73 -0
  102. data/lib/sisimai/reason/userunknown.rb +194 -0
  103. data/lib/sisimai/rfc2606.rb +24 -0
  104. data/lib/sisimai/rfc3464.rb +497 -0
  105. data/lib/sisimai/rfc3834.rb +150 -0
  106. data/lib/sisimai/rfc5322.rb +204 -0
  107. data/lib/sisimai/rhost.rb +47 -0
  108. data/lib/sisimai/rhost/googleapps.rb +237 -0
  109. data/lib/sisimai/smtp.rb +58 -0
  110. data/lib/sisimai/smtp/reply.rb +81 -0
  111. data/lib/sisimai/smtp/status.rb +755 -0
  112. data/lib/sisimai/string.rb +65 -0
  113. data/lib/sisimai/time.rb +11 -0
  114. data/lib/sisimai/version.rb +4 -0
  115. data/set-of-emails/README.md +35 -0
  116. data/set-of-emails/mailbox/mbox-0 +2467 -0
  117. data/set-of-emails/mailbox/mbox-1 +71 -0
  118. data/set-of-emails/maildir/bsd/README.md +261 -0
  119. data/set-of-emails/maildir/bsd/activehunter-01.eml +54 -0
  120. data/set-of-emails/maildir/bsd/activehunter-02.eml +53 -0
  121. data/set-of-emails/maildir/bsd/apachejames-01.eml +46 -0
  122. data/set-of-emails/maildir/bsd/arf-01.eml +66 -0
  123. data/set-of-emails/maildir/bsd/arf-02.eml +68 -0
  124. data/set-of-emails/maildir/bsd/arf-03.eml +56 -0
  125. data/set-of-emails/maildir/bsd/arf-04.eml +89 -0
  126. data/set-of-emails/maildir/bsd/arf-05.eml +82 -0
  127. data/set-of-emails/maildir/bsd/arf-06.eml +166 -0
  128. data/set-of-emails/maildir/bsd/arf-07.eml +59 -0
  129. data/set-of-emails/maildir/bsd/arf-08.eml +103 -0
  130. data/set-of-emails/maildir/bsd/arf-09.eml +104 -0
  131. data/set-of-emails/maildir/bsd/arf-10.eml +56 -0
  132. data/set-of-emails/maildir/bsd/arf-11.eml +37 -0
  133. data/set-of-emails/maildir/bsd/arf-12.eml +40 -0
  134. data/set-of-emails/maildir/bsd/arf-13.eml +76 -0
  135. data/set-of-emails/maildir/bsd/arf-14.eml +333 -0
  136. data/set-of-emails/maildir/bsd/arf-15.eml +66 -0
  137. data/set-of-emails/maildir/bsd/courier-01.eml +79 -0
  138. data/set-of-emails/maildir/bsd/courier-02.eml +83 -0
  139. data/set-of-emails/maildir/bsd/courier-03.eml +85 -0
  140. data/set-of-emails/maildir/bsd/courier-04.eml +87 -0
  141. data/set-of-emails/maildir/bsd/de-einsundeins-01.eml +38 -0
  142. data/set-of-emails/maildir/bsd/de-gmx-01.eml +52 -0
  143. data/set-of-emails/maildir/bsd/de-gmx-02.eml +51 -0
  144. data/set-of-emails/maildir/bsd/de-gmx-03.eml +56 -0
  145. data/set-of-emails/maildir/bsd/de-gmx-04.eml +51 -0
  146. data/set-of-emails/maildir/bsd/domino-01.eml +33 -0
  147. data/set-of-emails/maildir/bsd/domino-02.eml +83 -0
  148. data/set-of-emails/maildir/bsd/exchange-01.eml +31 -0
  149. data/set-of-emails/maildir/bsd/exchange-02.eml +67 -0
  150. data/set-of-emails/maildir/bsd/exchange-03.eml +52 -0
  151. data/set-of-emails/maildir/bsd/exchange-04.eml +28 -0
  152. data/set-of-emails/maildir/bsd/exchange-05.eml +56 -0
  153. data/set-of-emails/maildir/bsd/exchange-06.eml +151 -0
  154. data/set-of-emails/maildir/bsd/exim-01.eml +46 -0
  155. data/set-of-emails/maildir/bsd/exim-02.eml +41 -0
  156. data/set-of-emails/maildir/bsd/exim-03.eml +42 -0
  157. data/set-of-emails/maildir/bsd/exim-04.eml +46 -0
  158. data/set-of-emails/maildir/bsd/exim-05.eml +49 -0
  159. data/set-of-emails/maildir/bsd/exim-06.eml +44 -0
  160. data/set-of-emails/maildir/bsd/exim-07.eml +28 -0
  161. data/set-of-emails/maildir/bsd/exim-08.eml +42 -0
  162. data/set-of-emails/maildir/bsd/exim-09.eml +169 -0
  163. data/set-of-emails/maildir/bsd/exim-10.eml +718 -0
  164. data/set-of-emails/maildir/bsd/exim-11.eml +718 -0
  165. data/set-of-emails/maildir/bsd/exim-12.eml +75 -0
  166. data/set-of-emails/maildir/bsd/exim-13.eml +145 -0
  167. data/set-of-emails/maildir/bsd/exim-14.eml +32 -0
  168. data/set-of-emails/maildir/bsd/exim-15.eml +49 -0
  169. data/set-of-emails/maildir/bsd/exim-16.eml +98 -0
  170. data/set-of-emails/maildir/bsd/exim-17.eml +50 -0
  171. data/set-of-emails/maildir/bsd/exim-18.eml +96 -0
  172. data/set-of-emails/maildir/bsd/exim-19.eml +52 -0
  173. data/set-of-emails/maildir/bsd/exim-20.eml +159 -0
  174. data/set-of-emails/maildir/bsd/exim-21.eml +150 -0
  175. data/set-of-emails/maildir/bsd/exim-22.eml +50 -0
  176. data/set-of-emails/maildir/bsd/exim-23.eml +57 -0
  177. data/set-of-emails/maildir/bsd/exim-24.eml +107 -0
  178. data/set-of-emails/maildir/bsd/exim-25.eml +18 -0
  179. data/set-of-emails/maildir/bsd/exim-26.eml +111 -0
  180. data/set-of-emails/maildir/bsd/exim-27.eml +120 -0
  181. data/set-of-emails/maildir/bsd/exim-28.eml +148 -0
  182. data/set-of-emails/maildir/bsd/google-apps-01.eml +66 -0
  183. data/set-of-emails/maildir/bsd/imailserver-01.eml +27 -0
  184. data/set-of-emails/maildir/bsd/imailserver-02.eml +36 -0
  185. data/set-of-emails/maildir/bsd/imailserver-03.eml +28 -0
  186. data/set-of-emails/maildir/bsd/imailserver-04.eml +15 -0
  187. data/set-of-emails/maildir/bsd/imailserver-05.eml +92 -0
  188. data/set-of-emails/maildir/bsd/imailserver-06.eml +29 -0
  189. data/set-of-emails/maildir/bsd/interscanmss-01.eml +49 -0
  190. data/set-of-emails/maildir/bsd/interscanmss-02.eml +259 -0
  191. data/set-of-emails/maildir/bsd/jp-biglobe-01.eml +43 -0
  192. data/set-of-emails/maildir/bsd/jp-ezweb-01.eml +36 -0
  193. data/set-of-emails/maildir/bsd/jp-ezweb-02.eml +65 -0
  194. data/set-of-emails/maildir/bsd/jp-ezweb-03.eml +35 -0
  195. data/set-of-emails/maildir/bsd/jp-ezweb-04.eml +38 -0
  196. data/set-of-emails/maildir/bsd/jp-ezweb-05.eml +38 -0
  197. data/set-of-emails/maildir/bsd/jp-ezweb-06.eml +33 -0
  198. data/set-of-emails/maildir/bsd/jp-kddi-01.eml +49 -0
  199. data/set-of-emails/maildir/bsd/jp-kddi-02.eml +54 -0
  200. data/set-of-emails/maildir/bsd/jp-kddi-03.eml +54 -0
  201. data/set-of-emails/maildir/bsd/mailfoundry-01.eml +50 -0
  202. data/set-of-emails/maildir/bsd/mailfoundry-02.eml +49 -0
  203. data/set-of-emails/maildir/bsd/mailmarshalsmtp-01.eml +43 -0
  204. data/set-of-emails/maildir/bsd/mcafee-01.eml +63 -0
  205. data/set-of-emails/maildir/bsd/mcafee-02.eml +65 -0
  206. data/set-of-emails/maildir/bsd/mcafee-03.eml +59 -0
  207. data/set-of-emails/maildir/bsd/messagingserver-01.eml +102 -0
  208. data/set-of-emails/maildir/bsd/messagingserver-02.eml +72 -0
  209. data/set-of-emails/maildir/bsd/messagingserver-03.eml +70 -0
  210. data/set-of-emails/maildir/bsd/messagingserver-04.eml +102 -0
  211. data/set-of-emails/maildir/bsd/messagingserver-05.eml +98 -0
  212. data/set-of-emails/maildir/bsd/messagingserver-06.eml +101 -0
  213. data/set-of-emails/maildir/bsd/messagingserver-07.eml +129 -0
  214. data/set-of-emails/maildir/bsd/mfilter-01.eml +49 -0
  215. data/set-of-emails/maildir/bsd/mfilter-02.eml +48 -0
  216. data/set-of-emails/maildir/bsd/mfilter-03.eml +43 -0
  217. data/set-of-emails/maildir/bsd/mxlogic-01.eml +47 -0
  218. data/set-of-emails/maildir/bsd/mxlogic-02.eml +44 -0
  219. data/set-of-emails/maildir/bsd/mxlogic-03.eml +46 -0
  220. data/set-of-emails/maildir/bsd/notes-01.eml +42 -0
  221. data/set-of-emails/maildir/bsd/notes-02.eml +42 -0
  222. data/set-of-emails/maildir/bsd/notes-03.eml +38 -0
  223. data/set-of-emails/maildir/bsd/notes-04.eml +181 -0
  224. data/set-of-emails/maildir/bsd/opensmtpd-01.eml +33 -0
  225. data/set-of-emails/maildir/bsd/opensmtpd-02.eml +33 -0
  226. data/set-of-emails/maildir/bsd/opensmtpd-03.eml +36 -0
  227. data/set-of-emails/maildir/bsd/opensmtpd-04.eml +40 -0
  228. data/set-of-emails/maildir/bsd/opensmtpd-05.eml +36 -0
  229. data/set-of-emails/maildir/bsd/postfix-01.eml +60 -0
  230. data/set-of-emails/maildir/bsd/postfix-02.eml +78 -0
  231. data/set-of-emails/maildir/bsd/postfix-03.eml +71 -0
  232. data/set-of-emails/maildir/bsd/postfix-04.eml +89 -0
  233. data/set-of-emails/maildir/bsd/postfix-05.eml +78 -0
  234. data/set-of-emails/maildir/bsd/postfix-06.eml +72 -0
  235. data/set-of-emails/maildir/bsd/postfix-07.eml +74 -0
  236. data/set-of-emails/maildir/bsd/postfix-08.eml +78 -0
  237. data/set-of-emails/maildir/bsd/postfix-09.eml +76 -0
  238. data/set-of-emails/maildir/bsd/postfix-10.eml +73 -0
  239. data/set-of-emails/maildir/bsd/postfix-11.eml +86 -0
  240. data/set-of-emails/maildir/bsd/postfix-12.eml +71 -0
  241. data/set-of-emails/maildir/bsd/postfix-13.eml +81 -0
  242. data/set-of-emails/maildir/bsd/postfix-14.eml +68 -0
  243. data/set-of-emails/maildir/bsd/postfix-15.eml +69 -0
  244. data/set-of-emails/maildir/bsd/postfix-16.eml +73 -0
  245. data/set-of-emails/maildir/bsd/postfix-17.eml +68 -0
  246. data/set-of-emails/maildir/bsd/postfix-18.eml +121 -0
  247. data/set-of-emails/maildir/bsd/postfix-19.eml +105 -0
  248. data/set-of-emails/maildir/bsd/postfix-20.eml +231 -0
  249. data/set-of-emails/maildir/bsd/postfix-21.eml +60 -0
  250. data/set-of-emails/maildir/bsd/qmail-01.eml +40 -0
  251. data/set-of-emails/maildir/bsd/qmail-02.eml +35 -0
  252. data/set-of-emails/maildir/bsd/qmail-03.eml +22 -0
  253. data/set-of-emails/maildir/bsd/qmail-04.eml +31 -0
  254. data/set-of-emails/maildir/bsd/qmail-05.eml +31 -0
  255. data/set-of-emails/maildir/bsd/qmail-06.eml +39 -0
  256. data/set-of-emails/maildir/bsd/qmail-07.eml +22 -0
  257. data/set-of-emails/maildir/bsd/qmail-08.eml +23 -0
  258. data/set-of-emails/maildir/bsd/qmail-09.eml +103 -0
  259. data/set-of-emails/maildir/bsd/rfc3464-01.eml +60 -0
  260. data/set-of-emails/maildir/bsd/rfc3464-02.eml +43 -0
  261. data/set-of-emails/maildir/bsd/rfc3464-03.eml +40 -0
  262. data/set-of-emails/maildir/bsd/rfc3464-04.eml +50 -0
  263. data/set-of-emails/maildir/bsd/rfc3464-05.eml +63 -0
  264. data/set-of-emails/maildir/bsd/rfc3464-06.eml +48 -0
  265. data/set-of-emails/maildir/bsd/rfc3464-07.eml +88 -0
  266. data/set-of-emails/maildir/bsd/rfc3464-08.eml +70 -0
  267. data/set-of-emails/maildir/bsd/rfc3464-09.eml +93 -0
  268. data/set-of-emails/maildir/bsd/rfc3464-10.eml +467 -0
  269. data/set-of-emails/maildir/bsd/rfc3464-11.eml +1171 -0
  270. data/set-of-emails/maildir/bsd/rfc3464-12.eml +101 -0
  271. data/set-of-emails/maildir/bsd/rfc3464-13.eml +131 -0
  272. data/set-of-emails/maildir/bsd/rfc3464-14.eml +121 -0
  273. data/set-of-emails/maildir/bsd/rfc3464-15.eml +144 -0
  274. data/set-of-emails/maildir/bsd/rfc3464-16.eml +36 -0
  275. data/set-of-emails/maildir/bsd/rfc3464-17.eml +109 -0
  276. data/set-of-emails/maildir/bsd/rfc3464-18.eml +149 -0
  277. data/set-of-emails/maildir/bsd/rfc3464-19.eml +65 -0
  278. data/set-of-emails/maildir/bsd/rfc3464-20.eml +145 -0
  279. data/set-of-emails/maildir/bsd/rfc3464-21.eml +146 -0
  280. data/set-of-emails/maildir/bsd/rfc3464-22.eml +105 -0
  281. data/set-of-emails/maildir/bsd/rfc3464-23.eml +21 -0
  282. data/set-of-emails/maildir/bsd/rfc3464-24.eml +27 -0
  283. data/set-of-emails/maildir/bsd/rfc3464-25.eml +33 -0
  284. data/set-of-emails/maildir/bsd/rfc3464-26.eml +98 -0
  285. data/set-of-emails/maildir/bsd/rfc3464-27.eml +180 -0
  286. data/set-of-emails/maildir/bsd/rfc3834-01.eml +37 -0
  287. data/set-of-emails/maildir/bsd/rfc3834-02.eml +51 -0
  288. data/set-of-emails/maildir/bsd/rfc3834-03.eml +33 -0
  289. data/set-of-emails/maildir/bsd/ru-mailru-01.eml +54 -0
  290. data/set-of-emails/maildir/bsd/ru-mailru-02.eml +54 -0
  291. data/set-of-emails/maildir/bsd/ru-mailru-03.eml +62 -0
  292. data/set-of-emails/maildir/bsd/ru-mailru-04.eml +54 -0
  293. data/set-of-emails/maildir/bsd/ru-yandex-01.eml +102 -0
  294. data/set-of-emails/maildir/bsd/ru-yandex-02.eml +113 -0
  295. data/set-of-emails/maildir/bsd/ru-yandex-03.eml +101 -0
  296. data/set-of-emails/maildir/bsd/sendmail-01.eml +70 -0
  297. data/set-of-emails/maildir/bsd/sendmail-02.eml +82 -0
  298. data/set-of-emails/maildir/bsd/sendmail-03.eml +76 -0
  299. data/set-of-emails/maildir/bsd/sendmail-04.eml +63 -0
  300. data/set-of-emails/maildir/bsd/sendmail-05.eml +64 -0
  301. data/set-of-emails/maildir/bsd/sendmail-06.eml +67 -0
  302. data/set-of-emails/maildir/bsd/sendmail-07.eml +65 -0
  303. data/set-of-emails/maildir/bsd/sendmail-08.eml +62 -0
  304. data/set-of-emails/maildir/bsd/sendmail-09.eml +60 -0
  305. data/set-of-emails/maildir/bsd/sendmail-10.eml +82 -0
  306. data/set-of-emails/maildir/bsd/sendmail-11.eml +60 -0
  307. data/set-of-emails/maildir/bsd/sendmail-12.eml +62 -0
  308. data/set-of-emails/maildir/bsd/sendmail-13.eml +66 -0
  309. data/set-of-emails/maildir/bsd/sendmail-14.eml +64 -0
  310. data/set-of-emails/maildir/bsd/sendmail-15.eml +60 -0
  311. data/set-of-emails/maildir/bsd/sendmail-16.eml +69 -0
  312. data/set-of-emails/maildir/bsd/sendmail-17.eml +68 -0
  313. data/set-of-emails/maildir/bsd/sendmail-18.eml +64 -0
  314. data/set-of-emails/maildir/bsd/sendmail-19.eml +71 -0
  315. data/set-of-emails/maildir/bsd/sendmail-20.eml +120 -0
  316. data/set-of-emails/maildir/bsd/sendmail-21.eml +69 -0
  317. data/set-of-emails/maildir/bsd/sendmail-22.eml +73 -0
  318. data/set-of-emails/maildir/bsd/sendmail-23.eml +137 -0
  319. data/set-of-emails/maildir/bsd/sendmail-24.eml +66 -0
  320. data/set-of-emails/maildir/bsd/sendmail-25.eml +70 -0
  321. data/set-of-emails/maildir/bsd/sendmail-26.eml +71 -0
  322. data/set-of-emails/maildir/bsd/sendmail-27.eml +69 -0
  323. data/set-of-emails/maildir/bsd/sendmail-28.eml +69 -0
  324. data/set-of-emails/maildir/bsd/sendmail-29.eml +70 -0
  325. data/set-of-emails/maildir/bsd/sendmail-30.eml +68 -0
  326. data/set-of-emails/maildir/bsd/sendmail-31.eml +80 -0
  327. data/set-of-emails/maildir/bsd/sendmail-32.eml +71 -0
  328. data/set-of-emails/maildir/bsd/sendmail-33.eml +71 -0
  329. data/set-of-emails/maildir/bsd/sendmail-34.eml +75 -0
  330. data/set-of-emails/maildir/bsd/sendmail-35.eml +70 -0
  331. data/set-of-emails/maildir/bsd/sendmail-36.eml +71 -0
  332. data/set-of-emails/maildir/bsd/sendmail-37.eml +71 -0
  333. data/set-of-emails/maildir/bsd/surfcontrol-01.eml +79 -0
  334. data/set-of-emails/maildir/bsd/surfcontrol-02.eml +70 -0
  335. data/set-of-emails/maildir/bsd/surfcontrol-03.eml +70 -0
  336. data/set-of-emails/maildir/bsd/uk-messagelabs-01.eml +76 -0
  337. data/set-of-emails/maildir/bsd/us-amazonses-01.eml +59 -0
  338. data/set-of-emails/maildir/bsd/us-amazonses-02.eml +177 -0
  339. data/set-of-emails/maildir/bsd/us-amazonses-03.eml +55 -0
  340. data/set-of-emails/maildir/bsd/us-amazonses-04.eml +55 -0
  341. data/set-of-emails/maildir/bsd/us-aol-01.eml +1258 -0
  342. data/set-of-emails/maildir/bsd/us-aol-02.eml +1257 -0
  343. data/set-of-emails/maildir/bsd/us-aol-03.eml +1264 -0
  344. data/set-of-emails/maildir/bsd/us-aol-04.eml +1260 -0
  345. data/set-of-emails/maildir/bsd/us-bigfoot-01.eml +64 -0
  346. data/set-of-emails/maildir/bsd/us-facebook-01.eml +40 -0
  347. data/set-of-emails/maildir/bsd/us-facebook-02.eml +42 -0
  348. data/set-of-emails/maildir/bsd/us-google-01.eml +70 -0
  349. data/set-of-emails/maildir/bsd/us-google-02.eml +50 -0
  350. data/set-of-emails/maildir/bsd/us-google-03.eml +51 -0
  351. data/set-of-emails/maildir/bsd/us-google-04.eml +82 -0
  352. data/set-of-emails/maildir/bsd/us-google-05.eml +50 -0
  353. data/set-of-emails/maildir/bsd/us-google-06.eml +56 -0
  354. data/set-of-emails/maildir/bsd/us-google-07.eml +42 -0
  355. data/set-of-emails/maildir/bsd/us-google-08.eml +59 -0
  356. data/set-of-emails/maildir/bsd/us-google-09.eml +76 -0
  357. data/set-of-emails/maildir/bsd/us-google-10.eml +69 -0
  358. data/set-of-emails/maildir/bsd/us-google-11.eml +68 -0
  359. data/set-of-emails/maildir/bsd/us-google-12.eml +76 -0
  360. data/set-of-emails/maildir/bsd/us-google-13.eml +79 -0
  361. data/set-of-emails/maildir/bsd/us-google-14.eml +304 -0
  362. data/set-of-emails/maildir/bsd/us-outlook-01.eml +72 -0
  363. data/set-of-emails/maildir/bsd/us-outlook-02.eml +72 -0
  364. data/set-of-emails/maildir/bsd/us-outlook-03.eml +72 -0
  365. data/set-of-emails/maildir/bsd/us-outlook-04.eml +79 -0
  366. data/set-of-emails/maildir/bsd/us-outlook-05.eml +85 -0
  367. data/set-of-emails/maildir/bsd/us-outlook-06.eml +75 -0
  368. data/set-of-emails/maildir/bsd/us-outlook-07.eml +70 -0
  369. data/set-of-emails/maildir/bsd/us-receivingses-01.eml +74 -0
  370. data/set-of-emails/maildir/bsd/us-receivingses-02.eml +74 -0
  371. data/set-of-emails/maildir/bsd/us-receivingses-03.eml +74 -0
  372. data/set-of-emails/maildir/bsd/us-receivingses-04.eml +74 -0
  373. data/set-of-emails/maildir/bsd/us-receivingses-05.eml +74 -0
  374. data/set-of-emails/maildir/bsd/us-receivingses-06.eml +74 -0
  375. data/set-of-emails/maildir/bsd/us-receivingses-07.eml +74 -0
  376. data/set-of-emails/maildir/bsd/us-sendgrid-01.eml +95 -0
  377. data/set-of-emails/maildir/bsd/us-sendgrid-02.eml +98 -0
  378. data/set-of-emails/maildir/bsd/us-sendgrid-03.eml +100 -0
  379. data/set-of-emails/maildir/bsd/us-verizon-01.eml +31 -0
  380. data/set-of-emails/maildir/bsd/us-yahoo-01.eml +78 -0
  381. data/set-of-emails/maildir/bsd/us-yahoo-02.eml +79 -0
  382. data/set-of-emails/maildir/bsd/us-yahoo-03.eml +93 -0
  383. data/set-of-emails/maildir/bsd/us-yahoo-04.eml +94 -0
  384. data/set-of-emails/maildir/bsd/us-yahoo-05.eml +94 -0
  385. data/set-of-emails/maildir/bsd/us-zoho-01.eml +40 -0
  386. data/set-of-emails/maildir/bsd/us-zoho-02.eml +38 -0
  387. data/set-of-emails/maildir/bsd/us-zoho-03.eml +37 -0
  388. data/set-of-emails/maildir/bsd/us-zoho-04.eml +47 -0
  389. data/set-of-emails/maildir/bsd/us-zoho-05.eml +37 -0
  390. data/set-of-emails/maildir/bsd/v5sendmail-01.eml +24 -0
  391. data/set-of-emails/maildir/bsd/v5sendmail-02.eml +26 -0
  392. data/set-of-emails/maildir/bsd/v5sendmail-03.eml +29 -0
  393. data/set-of-emails/maildir/bsd/v5sendmail-04.eml +29 -0
  394. data/set-of-emails/maildir/bsd/v5sendmail-05.eml +42 -0
  395. data/set-of-emails/maildir/bsd/v5sendmail-06.eml +28 -0
  396. data/set-of-emails/maildir/bsd/v5sendmail-07.eml +35 -0
  397. data/set-of-emails/maildir/bsd/x1-01.eml +61 -0
  398. data/set-of-emails/maildir/bsd/x1-02.eml +62 -0
  399. data/set-of-emails/maildir/bsd/x2-01.eml +41 -0
  400. data/set-of-emails/maildir/bsd/x2-02.eml +46 -0
  401. data/set-of-emails/maildir/bsd/x2-03.eml +34 -0
  402. data/set-of-emails/maildir/bsd/x2-04.eml +0 -0
  403. data/set-of-emails/maildir/bsd/x2-05.eml +98 -0
  404. data/set-of-emails/maildir/bsd/x3-01.eml +61 -0
  405. data/set-of-emails/maildir/bsd/x3-02.eml +64 -0
  406. data/set-of-emails/maildir/bsd/x3-03.eml +59 -0
  407. data/set-of-emails/maildir/bsd/x3-04.eml +106 -0
  408. data/set-of-emails/maildir/bsd/x4-01.eml +92 -0
  409. data/set-of-emails/maildir/bsd/x4-02.eml +112 -0
  410. data/set-of-emails/maildir/bsd/x4-03.eml +245 -0
  411. data/set-of-emails/maildir/bsd/x4-04.eml +81 -0
  412. data/set-of-emails/maildir/bsd/x4-05.eml +121 -0
  413. data/set-of-emails/maildir/bsd/x4-06.eml +32 -0
  414. data/set-of-emails/maildir/bsd/x4-07.eml +153 -0
  415. data/set-of-emails/maildir/bsd/x5-01.eml +155 -0
  416. data/set-of-emails/maildir/dos/activehunter-01.eml +54 -0
  417. data/set-of-emails/maildir/dos/apachejames-01.eml +46 -0
  418. data/set-of-emails/maildir/dos/arf-01.eml +66 -0
  419. data/set-of-emails/maildir/dos/courier-01.eml +79 -0
  420. data/set-of-emails/maildir/dos/de-einsundeins-01.eml +38 -0
  421. data/set-of-emails/maildir/dos/de-gmx-01.eml +52 -0
  422. data/set-of-emails/maildir/dos/domino-01.eml +33 -0
  423. data/set-of-emails/maildir/dos/exchange-01.eml +31 -0
  424. data/set-of-emails/maildir/dos/exim-01.eml +46 -0
  425. data/set-of-emails/maildir/dos/google-apps-01.eml +66 -0
  426. data/set-of-emails/maildir/dos/imailserver-01.eml +27 -0
  427. data/set-of-emails/maildir/dos/interscanmss-01.eml +49 -0
  428. data/set-of-emails/maildir/dos/jp-biglobe-01.eml +43 -0
  429. data/set-of-emails/maildir/dos/jp-ezweb-01.eml +36 -0
  430. data/set-of-emails/maildir/dos/jp-kddi-01.eml +49 -0
  431. data/set-of-emails/maildir/dos/mailfoundry-01.eml +50 -0
  432. data/set-of-emails/maildir/dos/mailmarshalsmtp-01.eml +43 -0
  433. data/set-of-emails/maildir/dos/mcafee-01.eml +63 -0
  434. data/set-of-emails/maildir/dos/messagingserver-01.eml +102 -0
  435. data/set-of-emails/maildir/dos/mfilter-01.eml +49 -0
  436. data/set-of-emails/maildir/dos/mxlogic-01.eml +47 -0
  437. data/set-of-emails/maildir/dos/notes-01.eml +42 -0
  438. data/set-of-emails/maildir/dos/opensmtpd-01.eml +33 -0
  439. data/set-of-emails/maildir/dos/postfix-01.eml +60 -0
  440. data/set-of-emails/maildir/dos/qmail-01.eml +40 -0
  441. data/set-of-emails/maildir/dos/rfc3464-01.eml +59 -0
  442. data/set-of-emails/maildir/dos/rfc3834-01.eml +37 -0
  443. data/set-of-emails/maildir/dos/ru-mailru-01.eml +54 -0
  444. data/set-of-emails/maildir/dos/ru-yandex-01.eml +102 -0
  445. data/set-of-emails/maildir/dos/sendmail-01.eml +69 -0
  446. data/set-of-emails/maildir/dos/surfcontrol-01.eml +79 -0
  447. data/set-of-emails/maildir/dos/uk-messagelabs-01.eml +76 -0
  448. data/set-of-emails/maildir/dos/us-amazonses-01.eml +59 -0
  449. data/set-of-emails/maildir/dos/us-aol-01.eml +1258 -0
  450. data/set-of-emails/maildir/dos/us-bigfoot-01.eml +64 -0
  451. data/set-of-emails/maildir/dos/us-facebook-01.eml +40 -0
  452. data/set-of-emails/maildir/dos/us-google-01.eml +70 -0
  453. data/set-of-emails/maildir/dos/us-outlook-01.eml +72 -0
  454. data/set-of-emails/maildir/dos/us-receivingses-01.eml +74 -0
  455. data/set-of-emails/maildir/dos/us-sendgrid-01.eml +95 -0
  456. data/set-of-emails/maildir/dos/us-verizon-01.eml +31 -0
  457. data/set-of-emails/maildir/dos/us-yahoo-01.eml +78 -0
  458. data/set-of-emails/maildir/dos/us-zoho-01.eml +40 -0
  459. data/set-of-emails/maildir/dos/v5sendmail-01.eml +24 -0
  460. data/set-of-emails/maildir/dos/x1-01.eml +61 -0
  461. data/set-of-emails/maildir/dos/x2-01.eml +41 -0
  462. data/set-of-emails/maildir/dos/x3-01.eml +61 -0
  463. data/set-of-emails/maildir/dos/x4-01.eml +90 -0
  464. data/set-of-emails/maildir/dos/x5-01.eml +155 -0
  465. data/set-of-emails/maildir/err/make-test-01.eml +70 -0
  466. data/set-of-emails/maildir/err/make-test-02.eml +70 -0
  467. data/set-of-emails/maildir/err/make-test-03.eml +64 -0
  468. data/set-of-emails/maildir/err/make-test-04.eml +64 -0
  469. data/set-of-emails/maildir/err/make-test-05.eml +66 -0
  470. data/set-of-emails/maildir/err/make-test-06.eml +118 -0
  471. data/set-of-emails/maildir/err/make-test-07.eml +26 -0
  472. data/set-of-emails/maildir/err/make-test-08.eml +67 -0
  473. data/set-of-emails/maildir/err/make-test-09.eml +55 -0
  474. data/set-of-emails/maildir/err/make-test-10.eml +69 -0
  475. data/set-of-emails/maildir/err/make-test-11.eml +64 -0
  476. data/set-of-emails/maildir/err/make-test-12.eml +66 -0
  477. data/set-of-emails/maildir/err/make-test-13.eml +67 -0
  478. data/set-of-emails/maildir/err/make-test-14.eml +66 -0
  479. data/set-of-emails/maildir/err/make-test-15.eml +70 -0
  480. data/set-of-emails/maildir/err/make-test-16.eml +68 -0
  481. data/set-of-emails/maildir/err/make-test-17.eml +68 -0
  482. data/set-of-emails/maildir/err/make-test-18.eml +68 -0
  483. data/set-of-emails/maildir/err/make-test-19.eml +69 -0
  484. data/set-of-emails/maildir/err/make-test-20.eml +67 -0
  485. data/set-of-emails/maildir/err/make-test-21.eml +69 -0
  486. data/set-of-emails/maildir/err/make-test-22.eml +66 -0
  487. data/set-of-emails/maildir/err/make-test-23.eml +70 -0
  488. data/set-of-emails/maildir/err/make-test-24.eml +69 -0
  489. data/set-of-emails/maildir/err/make-test-25.eml +67 -0
  490. data/set-of-emails/maildir/err/make-test-26.eml +69 -0
  491. data/set-of-emails/maildir/err/make-test-27.eml +69 -0
  492. data/set-of-emails/maildir/err/make-test-28.eml +66 -0
  493. data/set-of-emails/maildir/err/make-test-29.eml +68 -0
  494. data/set-of-emails/maildir/err/make-test-30.eml +68 -0
  495. data/set-of-emails/maildir/err/make-test-31.eml +80 -0
  496. data/set-of-emails/maildir/err/make-test-32.eml +66 -0
  497. data/set-of-emails/maildir/err/make-test-33.eml +68 -0
  498. data/set-of-emails/maildir/err/make-test-34.eml +56 -0
  499. data/set-of-emails/maildir/err/make-test-35.eml +59 -0
  500. data/set-of-emails/maildir/err/make-test-36.eml +53 -0
  501. data/set-of-emails/maildir/err/make-test-37.eml +62 -0
  502. data/set-of-emails/maildir/mac/activehunter-01.eml +1 -2
  503. data/set-of-emails/maildir/mac/apachejames-01.eml +1 -4
  504. data/set-of-emails/maildir/mac/arf-01.eml +1 -3
  505. data/set-of-emails/maildir/mac/courier-01.eml +1 -6
  506. data/set-of-emails/maildir/mac/de-einsundeins-01.eml +1 -1
  507. data/set-of-emails/maildir/mac/de-gmx-01.eml +1 -1
  508. data/set-of-emails/maildir/mac/domino-01.eml +1 -0
  509. data/set-of-emails/maildir/mac/exchange-01.eml +1 -0
  510. data/set-of-emails/maildir/mac/exim-01.eml +1 -1
  511. data/set-of-emails/maildir/mac/google-apps-01.eml +1 -4
  512. data/set-of-emails/maildir/mac/imailserver-01.eml +1 -0
  513. data/set-of-emails/maildir/mac/interscanmss-01.eml +1 -2
  514. data/set-of-emails/maildir/mac/jp-biglobe-01.eml +1 -2
  515. data/set-of-emails/maildir/mac/jp-ezweb-01.eml +1 -1
  516. data/set-of-emails/maildir/mac/jp-kddi-01.eml +1 -2
  517. data/set-of-emails/maildir/mac/mailfoundry-01.eml +1 -2
  518. data/set-of-emails/maildir/mac/mailmarshalsmtp-01.eml +1 -2
  519. data/set-of-emails/maildir/mac/mcafee-01.eml +1 -4
  520. data/set-of-emails/maildir/mac/messagingserver-01.eml +1 -4
  521. data/set-of-emails/maildir/mac/mfilter-01.eml +1 -3
  522. data/set-of-emails/maildir/mac/mxlogic-01.eml +1 -1
  523. data/set-of-emails/maildir/mac/notes-01.eml +1 -2
  524. data/set-of-emails/maildir/mac/opensmtpd-01.eml +1 -0
  525. data/set-of-emails/maildir/mac/postfix-01.eml +1 -3
  526. data/set-of-emails/maildir/mac/qmail-01.eml +1 -1
  527. data/set-of-emails/maildir/mac/rfc3464-01.eml +1 -4
  528. data/set-of-emails/maildir/mac/rfc3834-01.eml +1 -0
  529. data/set-of-emails/maildir/mac/ru-mailru-01.eml +1 -1
  530. data/set-of-emails/maildir/mac/ru-yandex-01.eml +1 -4
  531. data/set-of-emails/maildir/mac/sendmail-01.eml +1 -4
  532. data/set-of-emails/maildir/mac/surfcontrol-01.eml +1 -5
  533. data/set-of-emails/maildir/mac/uk-messagelabs-01.eml +1 -4
  534. data/set-of-emails/maildir/mac/us-amazonses-01.eml +1 -4
  535. data/set-of-emails/maildir/mac/us-aol-01.eml +1 -15
  536. data/set-of-emails/maildir/mac/us-bigfoot-01.eml +1 -4
  537. data/set-of-emails/maildir/mac/us-facebook-01.eml +1 -4
  538. data/set-of-emails/maildir/mac/us-google-01.eml +1 -1
  539. data/set-of-emails/maildir/mac/us-outlook-01.eml +1 -4
  540. data/set-of-emails/maildir/mac/us-receivingses-01.eml +1 -4
  541. data/set-of-emails/maildir/mac/us-sendgrid-01.eml +1 -3
  542. data/set-of-emails/maildir/mac/us-verizon-01.eml +1 -2
  543. data/set-of-emails/maildir/mac/us-yahoo-01.eml +1 -1
  544. data/set-of-emails/maildir/mac/us-zoho-01.eml +1 -2
  545. data/set-of-emails/maildir/mac/v5sendmail-01.eml +1 -0
  546. data/set-of-emails/maildir/mac/x1-01.eml +1 -4
  547. data/set-of-emails/maildir/mac/x2-01.eml +1 -1
  548. data/set-of-emails/maildir/mac/x3-01.eml +1 -3
  549. data/set-of-emails/maildir/mac/x4-01.eml +1 -2
  550. data/set-of-emails/maildir/mac/x5-01.eml +1 -8
  551. data/set-of-emails/maildir/not/is-not-bounce-01.eml +25 -0
  552. data/set-of-emails/to-be-debugged-because/reason-is-onhold/onhold-0001.eml +85 -0
  553. data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0002.eml +27 -0
  554. data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0003.eml +78 -0
  555. data/set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet/cannot-parse-this-email-0002.eml +25 -0
  556. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-01.eml +79 -0
  557. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-02.eml +72 -0
  558. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-03.eml +68 -0
  559. data/set-of-emails/to-be-debugged-because/something-is-wrong/no-message-id-from-pr-150.eml +75 -0
  560. data/set-of-emails/to-be-parsed-for-test/README.md +20 -0
  561. data/sisimai.gemspec +25 -0
  562. metadata +647 -0
@@ -0,0 +1,206 @@
1
+ module Sisimai
2
+ module MTA
3
+ # Sisimai::MTA::Notes parses a bounce email which created by Lotus Notes
4
+ # Server. Methods in the module are called from only Sisimai::Message.
5
+ module Notes
6
+ # Imported from p5-Sisimail/lib/Sisimai/MTA/Notes.pm
7
+ class << self
8
+ require 'sisimai/mta'
9
+ require 'sisimai/rfc5322'
10
+
11
+ Re0 = {
12
+ :'subject' => %r/\AUndeliverable message/,
13
+ }
14
+ Re1 = {
15
+ :begin => %r/\A[-]+[ ]+Failure Reasons[ ]+[-]+\z/,
16
+ :rfc822 => %r/^[-]+[ ]+Returned Message[ ]+[-]+$/,
17
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
18
+ }
19
+ ReFailure = {
20
+ 'userunknown' => %r{(?:
21
+ User[ ]not[ ]listed[ ]in[ ]public[ ]Name[ ][&][ ]Address[ ]Book
22
+ |ディレクトリのリストにありません
23
+ )
24
+ }x,
25
+ 'networkerror' => %r/Message has exceeded maximum hop count/,
26
+ }
27
+ Indicators = Sisimai::MTA.INDICATORS
28
+ LongFields = Sisimai::RFC5322.LONGFIELDS
29
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
30
+
31
+ def description; return 'Lotus Notes'; end
32
+ def smtpagent; return 'Notes'; end
33
+ def headerlist; return []; end
34
+ def pattern; return Re0; end
35
+
36
+ # Parse bounce messages from Lotus Notes
37
+ # @param [Hash] mhead Message header of a bounce email
38
+ # @options mhead [String] from From header
39
+ # @options mhead [String] date Date header
40
+ # @options mhead [String] subject Subject header
41
+ # @options mhead [Array] received Received headers
42
+ # @options mhead [String] others Other required headers
43
+ # @param [String] mbody Message body of a bounce email
44
+ # @return [Hash, Nil] Bounce data list and message/rfc822
45
+ # part or nil if it failed to parse or
46
+ # the arguments are missing
47
+ def scan(mhead, mbody)
48
+ return nil unless mhead
49
+ return nil unless mbody
50
+ return nil unless mhead['subject'] =~ Re0[:subject]
51
+
52
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
53
+ hasdivided = mbody.split("\n")
54
+ rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
55
+ rfc822part = '' # (String) message/rfc822-headers part
56
+ previousfn = '' # (String) Previous field name
57
+ readcursor = 0 # (Integer) Points the current cursor position
58
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
59
+ characters = '' # (String) Character set name of the bounce mail
60
+ removedmsg = 'MULTIBYTE CHARACTERS HAVE BEEN REMOVED'
61
+ encodedmsg = ''
62
+ v = nil
63
+
64
+ hasdivided.each do |e|
65
+ if readcursor == 0
66
+ # Beginning of the bounce message or delivery status part
67
+ if e =~ Re1[:begin]
68
+ readcursor |= Indicators[:'deliverystatus']
69
+ next
70
+ end
71
+ end
72
+
73
+ if readcursor & Indicators[:'message-rfc822'] == 0
74
+ # Beginning of the original message part
75
+ if e =~ Re1[:rfc822]
76
+ readcursor |= Indicators[:'message-rfc822']
77
+ next
78
+ end
79
+ end
80
+
81
+ if characters.empty?
82
+ # Get character set name
83
+ if cv = mhead['content-type'].match(/\A.+;[ ]*charset=(.+)\z/)
84
+ # Content-Type: text/plain; charset=ISO-2022-JP
85
+ characters = cv[1].downcase
86
+ end
87
+ end
88
+
89
+ if readcursor & Indicators[:'message-rfc822'] > 0
90
+ # After "message/rfc822"
91
+ if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
92
+ # Get required headers only
93
+ lhs = cv[1].downcase
94
+ previousfn = ''
95
+ next unless RFC822Head.key?(lhs)
96
+
97
+ previousfn = lhs
98
+ rfc822part += e + "\n"
99
+
100
+ elsif e =~ /\A[ \t]+/
101
+ # Continued line from the previous line
102
+ next if rfc822next[previousfn]
103
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
104
+
105
+ else
106
+ # Check the end of headers in rfc822 part
107
+ next unless LongFields.key?(previousfn)
108
+ next unless e.empty?
109
+ rfc822next[previousfn] = true
110
+ end
111
+
112
+ else
113
+ # Before "message/rfc822"
114
+ next if readcursor & Indicators[:'deliverystatus'] == 0
115
+
116
+ # ------- Failure Reasons --------
117
+ #
118
+ # User not listed in public Name & Address Book
119
+ # kijitora@notes.example.jp
120
+ #
121
+ # ------- Returned Message --------
122
+ v = dscontents[-1]
123
+ if e =~ /\A[^ ]+[@][^ ]+/
124
+ # kijitora@notes.example.jp
125
+ if v['recipient']
126
+ # There are multiple recipient addresses in the message body.
127
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
128
+ v = dscontents[-1]
129
+ end
130
+ v['recipient'] ||= e
131
+ recipients += 1
132
+
133
+ else
134
+ next if e =~ /\A\z/
135
+ next if e =~ /\A[-]+/
136
+
137
+ if e =~ /[^\x20-\x7e]/
138
+ # Error message is not ISO-8859-1
139
+ if characters.size > 0
140
+ # Try to convert string
141
+ begin
142
+ encodedmsg = e.encode('UTF-8', characters)
143
+ rescue
144
+ # Failed to convert
145
+ encodedmsg = removedmsg
146
+ end
147
+ else
148
+ # No character set in Content-Type header
149
+ encodedmsg = removedmsg
150
+ end
151
+ v['diagnosis'] ||= ''
152
+ v['diagnosis'] += encodedmsg
153
+ else
154
+ # Error message does not include multi-byte character
155
+ v['diagnosis'] ||= ''
156
+ v['diagnosis'] += e
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ if recipients == 0
163
+ # Fallback: Get the recpient address from RFC822 part
164
+ if cv = rfc822part.match(/^To:[ ]*(.+)$/m)
165
+ v['recipient'] = Sisimai::Address.s3s4(cv[1])
166
+ recipients += 1 if v['recipient'].size > 0
167
+ end
168
+ end
169
+
170
+ return nil if recipients == 0
171
+ require 'sisimai/string'
172
+ require 'sisimai/smtp/status'
173
+
174
+ dscontents.map do |e|
175
+ e['agent'] = Sisimai::MTA::Notes.smtpagent
176
+
177
+ if mhead['received'].size > 0
178
+ # Get localhost and remote host name from Received header.
179
+ r0 = mhead['received']
180
+ ['lhost', 'rhost'].each { |a| e[a] ||= '' }
181
+ e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
182
+ e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
183
+ end
184
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
185
+ e['recipient'] = Sisimai::Address.s3s4(e['recipient'])
186
+
187
+ ReFailure.each_key do |r|
188
+ # Check each regular expression of Notes error messages
189
+ next unless e['diagnosis'] =~ ReFailure[r]
190
+ e['reason'] = r
191
+ pseudostatus = Sisimai::SMTP::Status.code(r)
192
+ e['status'] = pseudostatus if pseudostatus.size > 0
193
+ break
194
+ end
195
+ e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
196
+ e['action'] = 'failed' if e['status'] =~ /\A[45]/
197
+ e.each_key { |a| e[a] ||= '' }
198
+ end
199
+
200
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
201
+ end
202
+
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,225 @@
1
+ module Sisimai
2
+ module MTA
3
+ # Sisimai::MTA::OpenSMTPD parses a bounce email which created by OpenSMTPD.
4
+ # Methods in the module are called from only Sisimai::Message.
5
+ module OpenSMTPD
6
+ # Imported from p5-Sisimail/lib/Sisimai/MTA/OpenSMTPD.pm
7
+ class << self
8
+ require 'sisimai/mta'
9
+ require 'sisimai/rfc5322'
10
+
11
+ Re0 = {
12
+ :from => %r/\AMailer Daemon [<][^ ]+[@]/,
13
+ :subject => %r/\ADelivery status notification/,
14
+ :received => %r/[ ][(]OpenSMTPD[)][ ]with[ ]/,
15
+ }
16
+ # http://www.openbsd.org/cgi-bin/man.cgi?query=smtpd&sektion=8
17
+ # opensmtpd-5.4.2p1/smtpd/
18
+ # bounce.c/317:#define NOTICE_INTRO \
19
+ # bounce.c/318: " Hi!\n\n" \
20
+ # bounce.c/319: " This is the MAILER-DAEMON, please DO NOT REPLY to this e-mail.\n"
21
+ # bounce.c/320:
22
+ # bounce.c/321:const char *notice_error =
23
+ # bounce.c/322: " An error has occurred while attempting to deliver a message for\n"
24
+ # bounce.c/323: " the following list of recipients:\n\n";
25
+ # bounce.c/324:
26
+ # bounce.c/325:const char *notice_warning =
27
+ # bounce.c/326: " A message is delayed for more than %s for the following\n"
28
+ # bounce.c/327: " list of recipients:\n\n";
29
+ # bounce.c/328:
30
+ # bounce.c/329:const char *notice_warning2 =
31
+ # bounce.c/330: " Please note that this is only a temporary failure report.\n"
32
+ # bounce.c/331: " The message is kept in the queue for up to %s.\n"
33
+ # bounce.c/332: " You DO NOT NEED to re-send the message to these recipients.\n\n";
34
+ # bounce.c/333:
35
+ # bounce.c/334:const char *notice_success =
36
+ # bounce.c/335: " Your message was successfully delivered to these recipients.\n\n";
37
+ # bounce.c/336:
38
+ # bounce.c/337:const char *notice_relay =
39
+ # bounce.c/338: " Your message was relayed to these recipients.\n\n";
40
+ # bounce.c/339:
41
+ Re1 = {
42
+ :begin => %r/\A[ \t]*This is the MAILER-DAEMON, please DO NOT REPLY to this e-mail[.]\z/,
43
+ :rfc822 => %r/\A[ \t]*Below is a copy of the original message:\z/,
44
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
45
+ }
46
+ ReFailure = {
47
+ 'expired' => %r{
48
+ # smtpd/queue.c:221| envelope_set_errormsg(&evp, "Envelope expired");
49
+ Envelope[ ]expired
50
+ }x,
51
+ 'hostunknown' => %r{(?:
52
+ # smtpd/mta.c:976| relay->failstr = "Invalid domain name";
53
+ Invalid[ ]domain[ ]name
54
+ # smtpd/mta.c:980| relay->failstr = "Domain does not exist";
55
+ |Domain[ ]does[ ]not[ ]exist
56
+ )
57
+ }x,
58
+ 'notaccept' => %r{
59
+ # smtp/mta.c:1085| relay->failstr = "Destination seem to reject all mails";
60
+ Destination[ ]seem[ ]to[ ]reject[ ]all[ ]mails
61
+ }x,
62
+ 'networkerror' => %r{(?>
63
+ # smtpd/mta.c:972| relay->failstr = "Temporary failure in MX lookup";
64
+ Address[ ]family[ ]mismatch[ ]on[ ]destination[ ]MXs
65
+ |All[ ]routes[ ]to[ ]destination[ ]blocked
66
+ |bad[ ]DNS[ ]lookup[ ]error[ ]code
67
+ |Could[ ]not[ ]retrieve[ ]source[ ]address
68
+ |Loop[ ]detected
69
+ |Network[ ]error[ ]on[ ]destination[ ]MXs
70
+ |No[ ](?>
71
+ MX[ ]found[ ]for[ ](?:domain|destination)
72
+ |valid[ ]route[ ]to[ ](?:remote[ ]MX|destination)
73
+ )
74
+ |Temporary[ ]failure[ ]in[ ]MX[ ]lookup
75
+ )
76
+ }x,
77
+ 'securityerror' => %r{
78
+ # smtpd/mta.c:1013| relay->failstr = "Could not retrieve credentials";
79
+ Could[ ]not[ ]retrieve[ ]credentials
80
+ }x,
81
+ }
82
+ Indicators = Sisimai::MTA.INDICATORS
83
+ LongFields = Sisimai::RFC5322.LONGFIELDS
84
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
85
+
86
+ def description; return 'OpenSMTPD'; end
87
+ def smtpagent; return 'OpenSMTPD'; end
88
+ def headerlist; return []; end
89
+ def pattern; return Re0; end
90
+
91
+ # Parse bounce messages from OpenSMTPD
92
+ # @param [Hash] mhead Message header of a bounce email
93
+ # @options mhead [String] from From header
94
+ # @options mhead [String] date Date header
95
+ # @options mhead [String] subject Subject header
96
+ # @options mhead [Array] received Received headers
97
+ # @options mhead [String] others Other required headers
98
+ # @param [String] mbody Message body of a bounce email
99
+ # @return [Hash, Nil] Bounce data list and message/rfc822
100
+ # part or nil if it failed to parse or
101
+ # the arguments are missing
102
+ def scan(mhead, mbody)
103
+ return nil unless mhead
104
+ return nil unless mbody
105
+ return nil unless mhead['subject'] =~ Re0[:subject]
106
+ return nil unless mhead['from'] =~ Re0[:from]
107
+ return nil unless mhead['received'].find { |a| a =~ Re0[:received] }
108
+
109
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
110
+ hasdivided = mbody.split("\n")
111
+ rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
112
+ rfc822part = '' # (String) message/rfc822-headers part
113
+ previousfn = '' # (String) Previous field name
114
+ readcursor = 0 # (Integer) Points the current cursor position
115
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
116
+ v = nil
117
+
118
+ hasdivided.each do |e|
119
+ if readcursor == 0
120
+ # Beginning of the bounce message or delivery status part
121
+ if e =~ Re1[:begin]
122
+ readcursor |= Indicators[:'deliverystatus']
123
+ next
124
+ end
125
+ end
126
+
127
+ if readcursor & Indicators[:'message-rfc822'] == 0
128
+ # Beginning of the original message part
129
+ if e =~ Re1[:rfc822]
130
+ readcursor |= Indicators[:'message-rfc822']
131
+ next
132
+ end
133
+ end
134
+
135
+ if readcursor & Indicators[:'message-rfc822'] > 0
136
+ # After "message/rfc822"
137
+ if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
138
+ # Get required headers only
139
+ lhs = cv[1].downcase
140
+ previousfn = ''
141
+ next unless RFC822Head.key?(lhs)
142
+
143
+ previousfn = lhs
144
+ rfc822part += e + "\n"
145
+
146
+ elsif e =~ /\A[ \t]+/
147
+ # Continued line from the previous line
148
+ next if rfc822next[previousfn]
149
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
150
+
151
+ else
152
+ # Check the end of headers in rfc822 part
153
+ next unless LongFields.key?(previousfn)
154
+ next unless e.empty?
155
+ rfc822next[previousfn] = true
156
+ end
157
+
158
+ else
159
+ # Before "message/rfc822"
160
+ next if readcursor & Indicators[:'deliverystatus'] == 0
161
+ next if e.empty?
162
+
163
+ # Hi!
164
+ #
165
+ # This is the MAILER-DAEMON, please DO NOT REPLY to this e-mail.
166
+ #
167
+ # An error has occurred while attempting to deliver a message for
168
+ # the following list of recipients:
169
+ #
170
+ # kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
171
+ #
172
+ # Below is a copy of the original message:
173
+ v = dscontents[-1]
174
+
175
+ if cv = e.match(/\A([^ ]+?[@][^ ]+?):?[ ](.+)\z/)
176
+ # kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
177
+ if v['recipient']
178
+ # There are multiple recipient addresses in the message body.
179
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
180
+ v = dscontents[-1]
181
+ end
182
+ v['recipient'] = cv[1]
183
+ v['diagnosis'] = cv[2]
184
+ recipients += 1
185
+ end
186
+ end
187
+ end
188
+
189
+ return nil if recipients == 0
190
+ require 'sisimai/string'
191
+ require 'sisimai/smtp/status'
192
+
193
+ dscontents.map do |e|
194
+ e['agent'] = Sisimai::MTA::OpenSMTPD.smtpagent
195
+
196
+ if mhead['received'].size > 0
197
+ # Get localhost and remote host name from Received header.
198
+ r0 = mhead['received']
199
+ ['lhost', 'rhost'].each { |a| e[a] ||= '' }
200
+ e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
201
+ e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
202
+ end
203
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
204
+
205
+ ReFailure.each_key do |r|
206
+ # Verify each regular expression of session errors
207
+ next unless e['diagnosis'] =~ ReFailure[r]
208
+ e['reason'] = r
209
+ break
210
+ end
211
+
212
+ e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
213
+ e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
214
+ e['action'] = 'failed' if e['status'] =~ /\A[45]/
215
+ e.each_key { |a| e[a] ||= '' }
216
+ end
217
+
218
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
219
+ end
220
+
221
+ end
222
+ end
223
+ end
224
+ end
225
+
@@ -0,0 +1,306 @@
1
+ module Sisimai
2
+ module MTA
3
+ # Sisimai::MTA::Postfix parses a bounce email which created by Postfix.
4
+ # Methods in the module are called from only Sisimai::Message.
5
+ module Postfix
6
+ # Imported from p5-Sisimail/lib/Sisimai/MTA/Postfix.pm
7
+ class << self
8
+ require 'sisimai/mta'
9
+ require 'sisimai/rfc5322'
10
+
11
+ # Postfix manual - bounce(5) - http://www.postfix.org/bounce.5.html
12
+ Re0 = {
13
+ :from => %r/ [(]Mail Delivery System[)]\z/,
14
+ :subject => %r/\AUndelivered Mail Returned to Sender\z/,
15
+ }
16
+ Re1 = {
17
+ :begin => %r{\A(?>
18
+ [ ]+The[ ](?:
19
+ Postfix[ ](?:
20
+ program\z # The Postfix program
21
+ |on[ ].+[ ]program\z # The Postfix on <os name> program
22
+ )
23
+ |\w+[ ]Postfix[ ]program\z # The <name> Postfix program
24
+ |mail[ \t]system\z # The mail system
25
+ |\w+[ \t]program\z # The <custmized-name> program
26
+ )
27
+ |This[ ]is[ ]the[ ](?:
28
+ Postfix[ ]program # This is the Postfix program
29
+ |\w+[ ]Postfix[ ]program # This is the <name> Postfix program
30
+ |\w+[ ]program # This is the <customized-name> Postfix program
31
+ |mail[ ]system[ ]at[ ]host # This is the mail system at host <hostname>.
32
+ )
33
+ )
34
+ }x,
35
+ :rfc822 => %r!\AContent-Type:[ \t]*(?:message/rfc822|text/rfc822-headers)\z!x,
36
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
37
+ }
38
+ Indicators = Sisimai::MTA.INDICATORS
39
+ LongFields = Sisimai::RFC5322.LONGFIELDS
40
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
41
+
42
+ def description; return 'Postfix'; end
43
+ def smtpagent; return 'Postfix'; end
44
+ def headerlist; return []; end
45
+ def pattern; return Re0; end
46
+
47
+ # Parse bounce messages from Postfix
48
+ # @param [Hash] mhead Message header of a bounce email
49
+ # @options mhead [String] from From header
50
+ # @options mhead [String] date Date header
51
+ # @options mhead [String] subject Subject header
52
+ # @options mhead [Array] received Received headers
53
+ # @options mhead [String] others Other required headers
54
+ # @param [String] mbody Message body of a bounce email
55
+ # @return [Hash, Nil] Bounce data list and message/rfc822
56
+ # part or nil if it failed to parse or
57
+ # the arguments are missing
58
+ def scan(mhead, mbody)
59
+ return nil unless mhead
60
+ return nil unless mbody
61
+ return nil unless mhead['subject'] =~ Re0[:subject]
62
+
63
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
64
+ hasdivided = mbody.split("\n")
65
+ havepassed = [''];
66
+ rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
67
+ rfc822part = '' # (String) message/rfc822-headers part
68
+ previousfn = '' # (String) Previous field name
69
+ readcursor = 0 # (Integer) Points the current cursor position
70
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
71
+ commandset = [] # (Array) ``in reply to * command'' list
72
+ connvalues = 0 # (Integer) Flag, 1 if all the value of $connheader have been set
73
+ connheader = {
74
+ 'date' => '', # The value of Arrival-Date header
75
+ 'lhost' => '', # The value of Received-From-MTA header
76
+ }
77
+ anotherset = {} # Another error information
78
+ v = nil
79
+
80
+ hasdivided.each do |e|
81
+ # Save the current line for the next loop
82
+ havepassed << e; p = havepassed[-2]
83
+
84
+ if readcursor == 0
85
+ # Beginning of the bounce message or delivery status part
86
+ if e =~ Re1[:begin]
87
+ readcursor |= Indicators[:'deliverystatus']
88
+ next
89
+ end
90
+ end
91
+
92
+ if readcursor & Indicators[:'message-rfc822'] == 0
93
+ # Beginning of the original message part
94
+ if e =~ Re1[:rfc822]
95
+ readcursor |= Indicators[:'message-rfc822']
96
+ next
97
+ end
98
+ end
99
+
100
+ if readcursor & Indicators[:'message-rfc822'] > 0
101
+ # After "message/rfc822"
102
+ if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.*\z/)
103
+ # Get required headers only
104
+ lhs = cv[1].downcase
105
+ previousfn = ''
106
+ next unless RFC822Head.key?(lhs)
107
+
108
+ previousfn = lhs
109
+ rfc822part += e + "\n"
110
+
111
+ elsif e =~ /\A[ \t]+/
112
+ # Continued line from the previous line
113
+ next if rfc822next[previousfn]
114
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
115
+
116
+ else
117
+ # Check the end of headers in rfc822 part
118
+ next unless LongFields.key?(previousfn)
119
+ next unless e.empty?
120
+ rfc822next[previousfn] = true
121
+ end
122
+
123
+ else
124
+ # Before "message/rfc822"
125
+ next if readcursor & Indicators[:'deliverystatus'] == 0
126
+ next if e.empty?
127
+
128
+ if connvalues == connheader.keys.size
129
+ # Final-Recipient: RFC822; userunknown@example.jp
130
+ # X-Actual-Recipient: RFC822; kijitora@example.co.jp
131
+ # Action: failed
132
+ # Status: 5.1.1
133
+ # Remote-MTA: DNS; mx.example.jp
134
+ # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
135
+ # Last-Attempt-Date: Fri, 14 Feb 2014 12:30:08 -0500
136
+ v = dscontents[-1]
137
+ if cv = e.match(/\A[Ff]inal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*(.+)\z/)
138
+ # Final-Recipient: RFC822; userunknown@example.jp
139
+ if v['recipient']
140
+ # There are multiple recipient addresses in the message body.
141
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
142
+ v = dscontents[-1]
143
+ end
144
+ v['recipient'] = cv[1]
145
+ recipients += 1
146
+
147
+ elsif cv = e.match(/\A[Xx]-[Aa]ctual-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/) ||
148
+ cv = e.match(/\A[Oo]riginal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*([^ ]+)\z/)
149
+ # X-Actual-Recipient: RFC822; kijitora@example.co.jp
150
+ # Original-Recipient: rfc822;kijitora@example.co.jp
151
+ v['alias'] = cv[1]
152
+
153
+ elsif cv = e.match(/\A[Aa]ction:[ ]*(.+)\z/)
154
+ # Action: failed
155
+ v['action'] = cv[1].downcase
156
+
157
+ elsif cv = e.match(/\A[Ss]tatus:[ ]*(\d[.]\d+[.]\d+)/)
158
+ # Status: 5.1.1
159
+ # Status:5.2.0
160
+ # Status: 5.1.0 (permanent failure)
161
+ v['status'] = cv[1]
162
+
163
+ elsif cv = e.match(/\A[Rr]emote-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
164
+ # Remote-MTA: DNS; mx.example.jp
165
+ v['rhost'] = cv[1].downcase
166
+
167
+ elsif cv = e.match(/\A[Ll]ast-[Aa]ttempt-[Dd]ate:[ ]*(.+)\z/)
168
+ # Last-Attempt-Date: Fri, 14 Feb 2014 12:30:08 -0500
169
+ #
170
+ # src/bounce/bounce_notify_util.c:
171
+ # 681 #if 0
172
+ # 682 if (dsn->time > 0)
173
+ # 683 post_mail_fprintf(bounce, "Last-Attempt-Date: %s",
174
+ # 684 mail_date(dsn->time));
175
+ # 685 #endif
176
+ v['date'] = cv[1]
177
+
178
+ else
179
+ if cv = e.match(/\A[Dd]iagnostic-[Cc]ode:[ ]*(.+?);[ ]*(.+)\z/)
180
+ # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
181
+ v['spec'] = cv[1].upcase
182
+ v['diagnosis'] = cv[2]
183
+ v['spec'] = 'SMTP' if v['spec'] == 'X-POSTFIX'
184
+
185
+ elsif p =~ /\A[Dd]iagnostic-[Cc]ode:[ ]*/ && cv = e.match(/\A[ \t]+(.+)\z/)
186
+ # Continued line of the value of Diagnostic-Code header
187
+ v['diagnosis'] ||= ''
188
+ v['diagnosis'] += ' ' + cv[1]
189
+ havepassed[-1] = 'Diagnostic-Code: ' + e
190
+ end
191
+ end
192
+
193
+ else
194
+ # If you do so, please include this problem report. You can
195
+ # delete your own text from the attached returned message.
196
+ #
197
+ # The mail system
198
+ #
199
+ # <userunknown@example.co.jp>: host mx.example.co.jp[192.0.2.153] said: 550
200
+ # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
201
+ # command)
202
+ if cv = e.match(/[ \t][(]in reply to ([A-Z]{4}).*/)
203
+ # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
204
+ commandset << cv[1]
205
+
206
+ elsif cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
207
+ # to MAIL command)
208
+ commandset << cv[1]
209
+
210
+ else
211
+ if cv = e.match(/\A[Rr]eporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
212
+ # Reporting-MTA: dns; mx.example.jp
213
+ next if connheader['lhost'].size > 0
214
+ connheader['lhost'] = cv[1].downcase
215
+ connvalues += 1
216
+
217
+ elsif cv = e.match(/\A[Aa]rrival-[Dd]ate:[ ]*(.+)\z/)
218
+ # Arrival-Date: Wed, 29 Apr 2009 16:03:18 +0900
219
+ next if connheader['date'].size > 0
220
+ connheader['date'] = 1
221
+ connvalues += 1
222
+
223
+ elsif cv = e.match(/\A(X-Postfix-Sender):[ ]*rfc822;[ ]*(.+)\z/)
224
+ # X-Postfix-Sender: rfc822; shironeko@example.org
225
+ rfc822part += sprintf('%s: %s\n', cv[1], cv[2])
226
+
227
+ else
228
+ # Alternative error message and recipient
229
+ if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>] [(]expanded from [<](.+)[>][)]:[ \t]*(.+)\z/)
230
+ # <r@example.ne.jp> (expanded from <kijitora@example.org>): user ...
231
+ anotherset['recipient'] = cv[1]
232
+ anotherset['alias'] = cv[2]
233
+ anotherset['diagnosis'] = cv[3]
234
+
235
+ elsif cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>]:(.*)\z/)
236
+ # <kijitora@exmaple.jp>: ...
237
+ anotherset['recipient'] = cv[1]
238
+ anotherset['diagnosis'] = cv[2]
239
+
240
+ else
241
+ # Get error message continued from the previous line
242
+ next unless anotherset['diagnosis']
243
+ if e =~ /\A[ \t]{4}(.+)\z/
244
+ # host mx.example.jp said:...
245
+ anotherset['diagnosis'] += ' ' + e
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end # End of if: rfc822
252
+ end
253
+
254
+ if recipients == 0
255
+ # Fallback: set recipient address from error message
256
+ if anotherset['recipient'] && anotherset['recipient'].size > 0
257
+ # Set recipient address
258
+ dscontents[-1]['recipient'] = anotherset['recipient']
259
+ recipients += 1
260
+ end
261
+ end
262
+ return nil if recipients == 0
263
+
264
+ require 'sisimai/string'
265
+ require 'sisimai/smtp'
266
+ require 'sisimai/smtp/status'
267
+
268
+ dscontents.map do |e|
269
+ # Set default values if each value is empty.
270
+ connheader.each_key { |a| e[a] ||= connheader[a] || '' }
271
+
272
+ e['agent'] = Sisimai::MTA::Postfix.smtpagent
273
+ e['command'] = commandset.shift || ''
274
+
275
+ if anotherset['diagnosis']
276
+ # Copy alternative error message
277
+ e['diagnosis'] = anotherset['diagnosis'] unless e['diagnosis']
278
+ e['diagnosis'] = anotherset['diagnosis'] if e['diagnosis'] =~ /\A\d+\z/
279
+ end
280
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
281
+ e['spec'] ||= 'SMTP' if e['diagnosis'] =~ /host .+ said:/
282
+ e['status'] ||= ''
283
+
284
+ if mhead['received'].size > 0
285
+ # Get localhost and remote host name from Received header.
286
+ r0 = mhead['received']
287
+ ['lhost', 'rhost'].each { |a| e[a] ||= '' }
288
+ e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
289
+ e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
290
+ end
291
+
292
+ if e['status'].empty? || e['status'] =~ /\A\d[.]0[.]0\z/
293
+ # There is no value of Status header or the value is 5.0.0, 4.0.0
294
+ r = Sisimai::SMTP::Status.find(e['diagnosis'])
295
+ e['status'] = r if r.size > 0
296
+ end
297
+ e.each_key { |a| e[a] ||= '' }
298
+ end
299
+
300
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
301
+ end
302
+
303
+ end
304
+ end
305
+ end
306
+ end