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,314 @@
1
+ module Sisimai
2
+ module MTA
3
+ # Sisimai::MTA::Exchange parses a bounce email which created by Microsoft
4
+ # Exchange Server. Methods in the module are called from only Sisimai::Message.
5
+ module Exchange
6
+ # Imported from p5-Sisimail/lib/Sisimai/MTA/Exchange.pm
7
+ class << self
8
+ require 'sisimai/mta'
9
+ require 'sisimai/rfc5322'
10
+
11
+ Re0 = {
12
+ # X-Mailer: Internet Mail Service (5.0.1461.28)
13
+ # X-Mailer: Microsoft Exchange Server Internet Mail Connector Version ...
14
+ :'x-mailer' => %r{\A(?:
15
+ Internet[ ]Mail[ ]Service[ ][(][\d.]+[)]\z
16
+ |Microsoft[ ]Exchange[ ]Server[ ]Internet[ ]Mail[ ]Connector
17
+ )
18
+ }x,
19
+ :'x-mimeole' => %r/\AProduced By Microsoft Exchange/,
20
+ # Received: by ***.**.** with Internet Mail Service (5.5.2657.72)
21
+ :'received' => %r/\Aby .+ with Internet Mail Service [(][\d.]+[)]/,
22
+ }
23
+ Re1 = {
24
+ :begin => %r/\AYour message/,
25
+ :error => %r/\Adid not reach the following recipient[(]s[)]:/,
26
+ :rfc822 => %r|\AContent-Type: message/rfc822|,
27
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
28
+ }
29
+ CodeTable = {
30
+ 'onhold' => [
31
+ '000B099C', # Host Unknown, Message exceeds size limit, ...
32
+ '000B09AA', # Unable to relay for, Message exceeds size limit,...
33
+ '000B09B6', # Error messages by remote MTA
34
+ ],
35
+ 'userunknown' => [
36
+ '000C05A6', # Unknown Recipient,
37
+ ],
38
+ 'systemerror' => [
39
+ '00010256', # Too many recipients.
40
+ '000D06B5', # No proxy for recipient (non-smtp mail?)
41
+ ],
42
+ 'networkerror' => [
43
+ '00120270', # Too Many Hops
44
+ ],
45
+ 'contenterr' => [
46
+ '00050311', # Conversion to Internet format failed
47
+ '000502CC', # Conversion to Internet format failed
48
+ ],
49
+ 'securityerr' => [
50
+ '000B0981', # 502 Server does not support AUTH
51
+ ],
52
+ 'filtered' => [
53
+ '000C0595', # Ambiguous Recipient
54
+ ],
55
+ }
56
+ Indicators = Sisimai::MTA.INDICATORS
57
+ LongFields = Sisimai::RFC5322.LONGFIELDS
58
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
59
+
60
+ def description; return 'Microsoft Exchange Server'; end
61
+ def smtpagent; return 'Exchange'; end
62
+ def headerlist; return ['X-MS-Embedded-Report', 'X-MimeOLE']; end
63
+ def pattern; return Re0; end
64
+
65
+ # Parse bounce messages from Microsoft Exchange Server
66
+ # @param [Hash] mhead Message header of a bounce email
67
+ # @options mhead [String] from From header
68
+ # @options mhead [String] date Date header
69
+ # @options mhead [String] subject Subject header
70
+ # @options mhead [Array] received Received headers
71
+ # @options mhead [String] others Other required headers
72
+ # @param [String] mbody Message body of a bounce email
73
+ # @return [Hash, Nil] Bounce data list and message/rfc822
74
+ # part or nil if it failed to parse or
75
+ # the arguments are missing
76
+ def scan(mhead, mbody)
77
+ return nil unless mhead
78
+ return nil unless mbody
79
+ match = 0
80
+
81
+ match += 1 if mhead['x-ms-embedded-report']
82
+ catch :EXCHANGE_OR_NOT do
83
+ loop do
84
+ throw :EXCHANGE_OR_NOT if match > 0
85
+
86
+ if mhead['x-mailer']
87
+ # X-Mailer: Microsoft Exchange Server Internet Mail Connector Version 4.0.994.63
88
+ # X-Mailer: Internet Mail Service (5.5.2232.9)
89
+ match += 1 if mhead['x-mailer'] =~ Re0[:'x-mailer']
90
+ throw :EXCHANGE_OR_NOT if match > 0
91
+ end
92
+
93
+ if mhead['x-mimeole']
94
+ # X-MimeOLE: Produced By Microsoft Exchange V6.5
95
+ match += 1 if mhead['x-mimeole'] =~ Re0[:'x-mimeole']
96
+ throw :EXCHANGE_OR_NOT if match > 0
97
+ end
98
+
99
+ throw :EXCHANGE_OR_NOT if mhead['received'].size == 0
100
+ mhead['received'].each do |e|
101
+ # Received: by ***.**.** with Internet Mail Service (5.5.2657.72)
102
+ next unless e =~ Re0[:'received']
103
+ match += 1
104
+ throw :EXCHANGE_OR_NOT
105
+ end
106
+ break
107
+ end
108
+ end
109
+ return nil if match == 0
110
+
111
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
112
+ hasdivided = mbody.split("\n")
113
+ rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
114
+ rfc822part = '' # (String) message/rfc822-headers part
115
+ previousfn = '' # (String) Previous field name
116
+ readcursor = 0 # (Integer) Points the current cursor position
117
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
118
+ statuspart = false # (Boolean) Flag, true = have got delivery status part.
119
+ connvalues = 0 # (Integer) Flag, 1 if all the value of $connheader have been set
120
+ connheader = {
121
+ 'to' => '', # The value of "To"
122
+ 'date' => '', # The value of "Date"
123
+ 'subject' => '', # The value of "Subject"
124
+ }
125
+ v = nil
126
+
127
+ hasdivided.each do |e|
128
+ if readcursor == 0
129
+ # Beginning of the bounce message or delivery status part
130
+ if e =~ Re1[:begin]
131
+ readcursor |= Indicators[:'deliverystatus']
132
+ next
133
+ end
134
+ end
135
+
136
+ if readcursor & Indicators[:'message-rfc822'] == 0
137
+ # Beginning of the original message part
138
+ if e =~ Re1[:rfc822]
139
+ readcursor |= Indicators[:'message-rfc822']
140
+ next
141
+ end
142
+ end
143
+
144
+ if readcursor & Indicators[:'message-rfc822'] > 0
145
+ # After "message/rfc822"
146
+ if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
147
+ # Get required headers only
148
+ lhs = cv[1].downcase
149
+ previousfn = ''
150
+ next unless RFC822Head.key?(lhs)
151
+
152
+ previousfn = lhs
153
+ rfc822part += e + "\n"
154
+
155
+ elsif e =~ /\A[ \t]+/
156
+ # Continued line from the previous line
157
+ next if rfc822next[previousfn]
158
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
159
+
160
+ else
161
+ # Check the end of headers in rfc822 part
162
+ next unless LongFields.key?(previousfn)
163
+ next unless e.empty?
164
+ rfc822next[previousfn] = true
165
+ end
166
+
167
+ else
168
+ # Before "message/rfc822"
169
+ next if readcursor & Indicators[:'deliverystatus'] == 0
170
+ next if statuspart
171
+
172
+ if connvalues == connheader.keys.size
173
+ # did not reach the following recipient(s):
174
+ #
175
+ # kijitora@example.co.jp on Thu, 29 Apr 2007 16:51:51 -0500
176
+ # The recipient name is not recognized
177
+ # The MTS-ID of the original message is: c=jp;a= ;p=neko
178
+ # ;l=EXCHANGE000000000000000000
179
+ # MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
180
+ # mikeneko@example.co.jp on Thu, 29 Apr 2007 16:51:51 -0500
181
+ # The recipient name is not recognized
182
+ # The MTS-ID of the original message is: c=jp;a= ;p=neko
183
+ # ;l=EXCHANGE000000000000000000
184
+ # MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
185
+ v = dscontents[-1]
186
+
187
+ if cv = e.match(/\A[ \t]*([^ ]+[@][^ ]+) on[ \t]*.*\z/) ||
188
+ cv = e.match(/\A[ \t]*.+(?:SMTP|smtp)=([^ ]+[@][^ ]+) on[ \t]*.*\z/)
189
+ # kijitora@example.co.jp on Thu, 29 Apr 2007 16:51:51 -0500
190
+ # kijitora@example.com on 4/29/99 9:19:59 AM
191
+ if v['recipient']
192
+ # There are multiple recipient addresses in the message body.
193
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
194
+ v = dscontents[-1]
195
+ end
196
+ v['recipient'] = cv[1]
197
+ v['msexch'] = false
198
+ recipients += 1
199
+
200
+ elsif cv = e.match(/\A[ \t]+(MSEXCH:.+)\z/)
201
+ # MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
202
+ v['diagnosis'] ||= ''
203
+ v['diagnosis'] += cv[1]
204
+
205
+ else
206
+ next if v['msexch']
207
+ if v['diagnosis'] =~ /\AMSEXCH:.+/
208
+ # Continued from MEEXCH in the previous line
209
+ v['msexch'] = true
210
+ v['diagnosis'] ||= ''
211
+ v['diagnosis'] += ' ' + e
212
+ statuspart = true
213
+
214
+ else
215
+ # Error message in the body part
216
+ v['alterrors'] ||= ''
217
+ v['alterrors'] += ' ' + e
218
+ end
219
+ end
220
+
221
+ else
222
+ # Your message
223
+ #
224
+ # To: shironeko@example.jp
225
+ # Subject: ...
226
+ # Sent: Thu, 29 Apr 2010 18:14:35 +0000
227
+ #
228
+ if cv = e.match(/\A[ \t]+To:[ \t]+(.+)\z/)
229
+ # To: shironeko@example.jp
230
+ next if connheader['to'].size > 0
231
+ connheader['to'] = cv[1]
232
+ connvalues += 1
233
+
234
+ elsif cv = e.match(/\A[ \t]+Subject:[ \t]+(.+)\z/)
235
+ # Subject: ...
236
+ next if connheader['subject'].size > 0
237
+ connheader['subject'] = cv[1]
238
+ connvalues += 1
239
+
240
+ elsif cv = e.match(%r|\A[ \t]+Sent:[ \t]+([A-Z][a-z]{2},.+[-+]\d{4})\z|) ||
241
+ cv = e.match(%r|\A[ \t]+Sent:[ \t]+(\d+[/]\d+[/]\d+[ \t]+\d+:\d+:\d+[ \t].+)|)
242
+ # Sent: Thu, 29 Apr 2010 18:14:35 +0000
243
+ # Sent: 4/29/99 9:19:59 AM
244
+ next if connheader['date'].size > 0
245
+ connheader['date'] = cv[1]
246
+ connvalues += 1
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+ return nil if recipients == 0
253
+ require 'sisimai/string'
254
+ require 'sisimai/smtp/status'
255
+
256
+ dscontents.map do |e|
257
+ if mhead['received'].size > 0
258
+ # Get localhost and remote host name from Received header.
259
+ r0 = mhead['received']
260
+ %w|lhost rhost|.each { |a| e[a] ||= '' }
261
+ e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
262
+ e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
263
+ end
264
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
265
+
266
+ if cv = e['diagnosis'].match(/\AMSEXCH:.+[ \t]*[(]([0-9A-F]{8})[)][ \t]*(.*)\z/)
267
+ # MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
268
+ capturedcode = cv[1]
269
+ errormessage = cv[2]
270
+ pseudostatus = ''
271
+
272
+ CodeTable.each_key do |r|
273
+ # Find captured code from the error code table
274
+ next unless CodeTable[r].index(capturedcode)
275
+ e['reason'] = r
276
+ pseudostatus = Sisimai::SMTP::Status.code(r)
277
+ e['status'] = pseudostatus if pseudostatus.size > 0
278
+ break
279
+ end
280
+ e['diagnosis'] = errormessage
281
+ end
282
+
283
+ unless e['reason']
284
+ # Could not detect the reason from the value of "diagnosis".
285
+ if e['alterrors']
286
+ # Copy alternative error message
287
+ e['diagnosis'] = e['alterrors'] + ' ' + e['diagnosis']
288
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
289
+ e.delete('alterrors')
290
+ end
291
+ end
292
+
293
+ e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
294
+ e['action'] = 'failed' if e['status'] =~ /\A[45]/
295
+ e['agent'] = Sisimai::MTA::Exchange.smtpagent
296
+ e.delete('msexch')
297
+ e.each_key { |a| e[a] ||= '' }
298
+ end
299
+
300
+ if rfc822part.empty?
301
+ # When original message does not included in the bounce message
302
+ rfc822part += sprintf("From: %s\n", connheader['to'])
303
+ rfc822part += sprintf("Date: %s\n", connheader['date'])
304
+ rfc822part += sprintf("Subject: %s\n", connheader['subject'])
305
+ end
306
+
307
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
308
+ end
309
+
310
+ end
311
+ end
312
+ end
313
+ end
314
+
@@ -0,0 +1,549 @@
1
+ module Sisimai
2
+ module MTA
3
+ # Sisimai::MTA::Exim parses a bounce email which created by Exim. Methods in
4
+ # the module are called from only Sisimai::Message.
5
+ module Exim
6
+ # Imported from p5-Sisimail/lib/Sisimai/MTA/Exim.pm
7
+ class << self
8
+ require 'sisimai/mta'
9
+ require 'sisimai/rfc5322'
10
+
11
+ ReE = {
12
+ :from => %r/[@].+[.]mail[.]ru[>]?/,
13
+ }
14
+ Re0 = {
15
+ :from => %r/\AMail Delivery System/,
16
+ :subject => %r{(?:
17
+ Mail[ ]delivery[ ]failed(:[ ]returning[ ]message[ ]to[ ]sender)?
18
+ |Warning:[ ]message[ ].+[ ]delayed[ ]+
19
+ |Delivery[ ]Status[ ]Notification
20
+ |Mail[ ]failure
21
+ |Message[ ]frozen
22
+ |error[(]s[)][ ]in[ ]forwarding[ ]or[ ]filtering
23
+ )
24
+ }x,
25
+ # :'message-id' => %r/\A[<]\w+[-]\w+[-]\w+[@].+\z/,
26
+ # Message-Id: <E1P1YNN-0003AD-Ga@example.org>
27
+ }
28
+
29
+ # Error text regular expressions which defined in exim/src/deliver.c
30
+ #
31
+ # deliver.c:6292| fprintf(f,
32
+ # deliver.c:6293|"This message was created automatically by mail delivery software.\n");
33
+ # deliver.c:6294| if (to_sender)
34
+ # deliver.c:6295| {
35
+ # deliver.c:6296| fprintf(f,
36
+ # deliver.c:6297|"\nA message that you sent could not be delivered to one or more of its\n"
37
+ # deliver.c:6298|"recipients. This is a permanent error. The following address(es) failed:\n");
38
+ # deliver.c:6299| }
39
+ # deliver.c:6300| else
40
+ # deliver.c:6301| {
41
+ # deliver.c:6302| fprintf(f,
42
+ # deliver.c:6303|"\nA message sent by\n\n <%s>\n\n"
43
+ # deliver.c:6304|"could not be delivered to one or more of its recipients. The following\n"
44
+ # deliver.c:6305|"address(es) failed:\n", sender_address);
45
+ # deliver.c:6306| }
46
+ #
47
+ # deliver.c:6423| if (bounce_return_body) fprintf(f,
48
+ # deliver.c:6424|"------ This is a copy of the message, including all the headers. ------\n");
49
+ # deliver.c:6425| else fprintf(f,
50
+ # deliver.c:6426|"------ This is a copy of the message's headers. ------\n");
51
+ Re1 = {
52
+ :alias => %r/\A([ ]+an[ ]undisclosed[ ]address)\z/,
53
+ :frozen => %r/\AMessage .+ (?:has been frozen|was frozen on arrival)/,
54
+ :rfc822 => %r{\A(?:
55
+ [-]+[ ]This[ ]is[ ]a[ ]copy[ ]of[ ]the[ ]message.+headers[.][ ][-]+
56
+ |Content-Type:[ ]*message/rfc822
57
+ )\z
58
+ }x,
59
+ :begin => %r{\A(?>
60
+ This[ ]message[ ]was[ ]created[ ]automatically[ ]by[ ]mail[ ]delivery[ ]software[.]
61
+ |A[ ]message[ ]that[ ]you[ ]sent[ ]was[ ]rejected[ ]by[ ]the[ ]local[ ]scanning[ ]code
62
+ |Message[ ].+[ ](?:has[ ]been[ ]frozen|was[ ]frozen[ ]on[ ]arrival)
63
+ |The[ ].+[ ]router[ ]encountered[ ]the[ ]following[ ]error[(]s[)]:
64
+ )
65
+ }x,
66
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
67
+ }
68
+
69
+ ReCommand = [
70
+ # transports/smtp.c:564| *message = US string_sprintf("SMTP error from remote mail server after %s%s: "
71
+ # transports/smtp.c:837| string_sprintf("SMTP error from remote mail server after RCPT TO:<%s>: "
72
+ %r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
73
+ %r/SMTP error from remote (?:mail server|mailer) after end of ([A-Za-z]{4})/,
74
+ %r/LMTP error after ([A-Za-z]{4})/,
75
+ %r/LMTP error after end of ([A-Za-z]{4})/,
76
+ ]
77
+
78
+ # find exim/ -type f -exec grep 'message = US' {} /dev/null \;
79
+ ReFailure = {
80
+ # route.c:1158| DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
81
+ 'userunknown' => %r/user[ ]not[ ]found/x,
82
+ # transports/smtp.c:3524| addr->message = US"all host address lookups failed permanently";
83
+ # routers/dnslookup.c:331| addr->message = US"all relevant MX records point to non-existent hosts";
84
+ # route.c:1826| uschar *message = US"Unrouteable address";
85
+ 'hostunknown' => %r{(?>
86
+ all[ ](?:
87
+ host[ ]address[ ]lookups[ ]failed[ ]permanently
88
+ |relevant[ ]MX[ ]records[ ]point[ ]to[ ]non[-]existent[ ]hosts
89
+ )
90
+ |Unrouteable[ ]address
91
+ )
92
+ }x,
93
+ # transports/appendfile.c:2567| addr->user_message = US"mailbox is full";
94
+ # transports/appendfile.c:3049| addr->message = string_sprintf("mailbox is full "
95
+ # transports/appendfile.c:3050| "(quota exceeded while writing to file %s)", filename);
96
+ 'mailboxfull' => %r/(?:mailbox[ ]is[ ]full:?|error:[ ]quota[ ]exceed)/x,
97
+ # routers/dnslookup.c:328| addr->message = US"an MX or SRV record indicated no SMTP service";
98
+ # transports/smtp.c:3502| addr->message = US"no host found for existing SMTP connection";
99
+ 'notaccept' => %r{(?:
100
+ an[ ]MX[ ]or[ ]SRV[ ]record[ ]indicated[ ]no[ ]SMTP[ ]service
101
+ |no[ ]host[ ]found[ ]for[ ]existing[ ]SMTP[ ]connection
102
+ )
103
+ }x,
104
+ # deliver.c:5614| addr->message = US"delivery to file forbidden";
105
+ # deliver.c:5624| addr->message = US"delivery to pipe forbidden";
106
+ # transports/pipe.c:1156| addr->user_message = US"local delivery failed";
107
+ 'systemerror' => %r{(?>
108
+ delivery[ ]to[ ](?:file|pipe)[ ]forbidden
109
+ |local[ ]delivery[ ]failed
110
+ |LMTP[ ]error[ ]after[ ]
111
+ )
112
+ }x,
113
+ # deliver.c:5425| new->message = US"Too many \"Received\" headers - suspected mail loop";
114
+ 'contenterror' => %r/Too[ ]many[ ]["]Received["][ ]headers/x,
115
+ }
116
+
117
+ # retry.c:902| addr->message = (addr->message == NULL)? US"retry timeout exceeded" :
118
+ # deliver.c:7475| "No action is required on your part. Delivery attempts will continue for\n"
119
+ # smtp.c:3508| US"retry time not reached for any host after a long failure period" :
120
+ # smtp.c:3508| US"all hosts have been failing for a long time and were last tried "
121
+ # "after this message arrived";
122
+ # deliver.c:7459| print_address_error(addr, f, US"Delay reason: ");
123
+ # deliver.c:7586| "Message %s has been frozen%s.\nThe sender is <%s>.\n", message_id,
124
+ # receive.c:4021| moan_tell_someone(freeze_tell, NULL, US"Message frozen on arrival",
125
+ # receive.c:4022| "Message %s was frozen on arrival by %s.\nThe sender is <%s>.\n",
126
+ ReDelayed = %r{(?:
127
+ retry[ ]timeout[ ]exceeded
128
+ |No[ ]action[ ]is[ ]required[ ]on[ ]your[ ]part
129
+ |retry[ ]time[ ]not[ ]reached[ ]for[ ]any[ ]host[ ]after[ ]a[ ]long[ ]failure[ ]period
130
+ |all[ ]hosts[ ]have[ ]been[ ]failing[ ]for[ ]a[ ]long[ ]time[ ]and[ ]were[ ]last[ ]tried
131
+ |Delay[ ]reason:[ ]
132
+ |Message[ ].+[ ](?:has[ ]been[ ]frozen|was[ ]frozen[ ]on[ ]arrival[ ]by[ ])
133
+ )
134
+ }x
135
+
136
+ Indicators = Sisimai::MTA.INDICATORS
137
+ LongFields = Sisimai::RFC5322.LONGFIELDS
138
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
139
+
140
+ def description; return 'Exim'; end
141
+ def smtpagent; return 'Exim'; end
142
+ def headerlist; return ['X-Failed-Recipients']; end
143
+ def pattern; return Re0; end
144
+
145
+ # Parse bounce messages from Exim
146
+ # @param [Hash] mhead Message header of a bounce email
147
+ # @options mhead [String] from From header
148
+ # @options mhead [String] date Date header
149
+ # @options mhead [String] subject Subject header
150
+ # @options mhead [Array] received Received headers
151
+ # @options mhead [String] others Other required headers
152
+ # @param [String] mbody Message body of a bounce email
153
+ # @return [Hash, Nil] Bounce data list and message/rfc822
154
+ # part or nil if it failed to parse or
155
+ # the arguments are missing
156
+ def scan(mhead, mbody)
157
+ return nil unless mhead
158
+ return nil unless mbody
159
+ return nil if mhead['from'] =~ ReE[:from]
160
+ return nil unless mhead['from'] =~ Re0[:from]
161
+ return nil unless mhead['subject'] =~ Re0[:subject]
162
+
163
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
164
+ hasdivided = mbody.split("\n")
165
+ rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
166
+ rfc822part = '' # (String) message/rfc822-headers part
167
+ previousfn = '' # (String) Previous field name
168
+ readcursor = 0 # (Integer) Points the current cursor position
169
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
170
+ localhost0 = '' # (String) Local MTA
171
+ boundary00 = '' # (String) Boundary string
172
+ v = nil
173
+
174
+ if mhead['content-type']
175
+ # Get the boundary string and set regular expression for matching with
176
+ # the boundary string.
177
+ require 'sisimai/mime'
178
+ boundary00 = Sisimai::MIME.boundary(mhead['content-type']) || ''
179
+ end
180
+
181
+ hasdivided.each do |e|
182
+ break if e =~ Re1[:endof]
183
+
184
+ if readcursor == 0
185
+ # Beginning of the bounce message or delivery status part
186
+ if e =~ Re1[:begin]
187
+ readcursor |= Indicators[:'deliverystatus']
188
+ next unless e =~ Re1[:frozen]
189
+ end
190
+ end
191
+
192
+ if readcursor & Indicators[:'message-rfc822'] == 0
193
+ # Beginning of the original message part
194
+ if e =~ Re1[:rfc822]
195
+ readcursor |= Indicators[:'message-rfc822']
196
+ next
197
+ end
198
+ end
199
+
200
+ if readcursor & Indicators[:'message-rfc822'] > 0
201
+ # After "message/rfc822"
202
+ if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
203
+ # Get required headers only
204
+ lhs = cv[1].downcase
205
+ previousfn = ''
206
+ next unless RFC822Head.key?(lhs)
207
+
208
+ previousfn = lhs
209
+ rfc822part += e + "\n"
210
+
211
+ elsif e =~ /\A[ \t]+/
212
+ # Continued line from the previous line
213
+ next if rfc822next[previousfn]
214
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
215
+
216
+ else
217
+ # Check the end of headers in rfc822 part
218
+ next unless LongFields.key?(previousfn)
219
+ next unless e.empty?
220
+ rfc822next[previousfn] = true
221
+ end
222
+
223
+ else
224
+ # Before "message/rfc822"
225
+ next if readcursor & Indicators[:'deliverystatus'] == 0
226
+ next if e.empty?
227
+
228
+ # This message was created automatically by mail delivery software.
229
+ #
230
+ # A message that you sent could not be delivered to one or more of its
231
+ # recipients. This is a permanent error. The following address(es) failed:
232
+ #
233
+ # kijitora@example.jp
234
+ # SMTP error from remote mail server after RCPT TO:<kijitora@example.jp>:
235
+ # host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
236
+ v = dscontents[-1]
237
+
238
+ if e =~ /[ \t]*This is a permanent error[.][ \t]*/
239
+ # deliver.c:6811| "recipients. This is a permanent error. The following address(es) failed:\n");
240
+ v['softbounce'] = 0
241
+
242
+ elsif cv = e.match(/\A[ ][ ]+([^ \t]+[@][^ \t]+[.][a-zA-Z]+)(:.+)?\z/) ||
243
+ cv = e.match(Re1[:alias])
244
+ # kijitora@example.jp
245
+ # sabineko@example.jp: forced freeze
246
+ #
247
+ # deliver.c:4549| printed = US"an undisclosed address";
248
+ # an undisclosed address
249
+ # (generated from kijitora@example.jp)
250
+ if v['recipient']
251
+ # There are multiple recipient addresses in the message body.
252
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
253
+ v = dscontents[-1]
254
+ end
255
+ v['recipient'] = cv[1]
256
+ recipients += 1
257
+
258
+ elsif cv = e.match(/\A[ ]+[(]generated[ ]from[ ](.+)[)]\z/) ||
259
+ cv = e.match(/\A[ ]+generated[ ]by[ ]([^ \t]+[@][^ \t]+)/)
260
+ # (generated from kijitora@example.jp)
261
+ # pipe to |/bin/echo "Some pipe output"
262
+ # generated by userx@myhost.test.ex
263
+ v['alias'] = cv[1]
264
+
265
+ else
266
+ next if e.empty?
267
+
268
+ if e =~ Re1[:frozen]
269
+ # Message *** has been frozen by the system filter.
270
+ # Message *** was frozen on arrival by ACL.
271
+ v['alterrors'] ||= ''
272
+ v['alterrors'] += e + ' '
273
+
274
+ else
275
+ if boundary00.size > 0
276
+ # --NNNNNNNNNN-eximdsn-MMMMMMMMMM
277
+ # Content-type: message/delivery-status
278
+ # ...
279
+ if cv = e.match(/\A[Rr]eporting-MTA:[ ]*(?:DNS|dns);[ ]*(.+)\z/)
280
+ # Reporting-MTA: dns; mx.example.jp
281
+ v['lhost'] = cv[1]
282
+
283
+ elsif cv = e.match(/\A[Aa]ction:[ ]*(.+)\z/)
284
+ # Action: failed
285
+ v['action'] = cv[1].downcase
286
+
287
+ elsif cv = e.match(/\A[Ss]tatus:[ ]*(\d[.]\d+[.]\d+)/)
288
+ # Status: 5.0.0
289
+ v['status'] = cv[1]
290
+
291
+ elsif cv = e.match(/\A[Dd]iagnostic-[Cc]ode:[ ]*(.+?);[ ]*(.+)\z/)
292
+ # Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
293
+ v['spec'] = cv[1].upcase
294
+ v['diagnosis'] = cv[2]
295
+
296
+ elsif cv = e.match(/\A[Ff]inal-[Rr]ecipient:[ ]*(?:RFC|rfc)822;[ ]*(.+)\z/)
297
+ # Final-Recipient: rfc822;|/bin/echo "Some pipe output"
298
+ v['spec'] ||= cv[1] =~ /[@]/ ? 'SMTP' : 'X-UNIX'
299
+
300
+ else
301
+ # Error message ?
302
+ v['alterrors'] ||= ''
303
+ v['alterrors'] += e + ' ' if e =~ /\A[ ]+/
304
+ end
305
+ else
306
+ if dscontents.size == recipients
307
+ # Error message
308
+ next unless e.size
309
+ v['diagnosis'] ||= ''
310
+ v['diagnosis'] += e + ' '
311
+
312
+ else
313
+ # Error message when email address above does not include '@'
314
+ # and domain part.
315
+ next unless e =~ /\A[ ]{4}/
316
+ v['alterrors'] ||= ''
317
+ v['alterrors'] += e + ' '
318
+ end
319
+ end
320
+ end
321
+ end
322
+ end
323
+ end
324
+
325
+ if recipients > 0
326
+ # Check "an undisclosed address", "unroutable address"
327
+ dscontents.map do |q|
328
+ # Replace the recipient address with the value of "alias"
329
+ next unless q['alias']
330
+ next unless q['alias'].size > 0
331
+ if q['recipient'].empty? || q['recipient'] !~ /[@]/
332
+ # The value of "recipient" is empty or does not include "@"
333
+ q['recipient'] = q['alias']
334
+ end
335
+ end
336
+
337
+ else
338
+ # Fallback for getting recipient addresses
339
+ if mhead['x-failed-recipients']
340
+ # X-Failed-Recipients: kijitora@example.jp
341
+ rcptinhead = mhead['x-failed-recipients'].split(',')
342
+ rcptinhead.each { |a| a.lstrip!; a.rstrip!; }
343
+ recipients = rcptinhead.size
344
+
345
+ rcptinhead.each do |e|
346
+ # Insert each recipient address into @$dscontents
347
+ dscontents[-1]['recipient'] = e
348
+ next if dscontents.size == recipients
349
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
350
+ end
351
+ end
352
+ end
353
+ return nil if recipients == 0
354
+
355
+ if mhead['received'].size > 0
356
+ # Get the name of local MTA
357
+ # Received: from marutamachi.example.org (c192128.example.net [192.0.2.128])
358
+ if cv = mhead['received'][-1].match(/from[ \t]([^ ]+)/)
359
+ localhost0 = cv[1]
360
+ end
361
+ end
362
+
363
+ require 'sisimai/string'
364
+ require 'sisimai/smtp/reply'
365
+ require 'sisimai/smtp/status'
366
+
367
+ dscontents.map do |e|
368
+ # Set default values if each value is empty.
369
+ e['agent'] = Sisimai::MTA::Exim.smtpagent
370
+ e['lhost'] ||= localhost0
371
+
372
+ unless e['diagnosis']
373
+ # Empty Diagnostic-Code: or error message
374
+ if boundary00.size > 0
375
+ # --NNNNNNNNNN-eximdsn-MMMMMMMMMM
376
+ # Content-type: message/delivery-status
377
+ #
378
+ # Reporting-MTA: dns; the.local.host.name
379
+ #
380
+ # Action: failed
381
+ # Final-Recipient: rfc822;/a/b/c
382
+ # Status: 5.0.0
383
+ #
384
+ # Action: failed
385
+ # Final-Recipient: rfc822;|/p/q/r
386
+ # Status: 5.0.0
387
+ e['diagnosis'] = dscontents[0]['diagnosis'] || ''
388
+ e['spec'] ||= dscontents[0]['spec']
389
+
390
+ if dscontents[0]['alterrors']
391
+ # The value of "alterrors" is also copied
392
+ e['alterrors'] = dscontents[0]['alterrors']
393
+ end
394
+ end
395
+ end
396
+
397
+ if e['alterrors'] && e['alterrors'].size > 0
398
+ # Copy alternative error message
399
+ e['diagnosis'] ||= e['alterrors']
400
+ if e['diagnosis'] =~ /\A[-]+/ || e['diagnosis'] =~ /__\z/
401
+ # Override the value of diagnostic code message
402
+ e['diagnosis'] = e['alterrors'] if e['alterrors'].size > 0
403
+
404
+ else
405
+ # Check the both value and try to match
406
+ if e['diagnosis'].size < e['alterrors'].size
407
+ # Check the value of alterrors
408
+ rxdiagnosis = %r/#{e['diagnosis']}/i
409
+ if e['alterrors'] =~ rxdiagnosis
410
+ # Override the value of diagnostic code message because
411
+ # the value of alterrors includes the value of diagnosis.
412
+ e['diagnosis'] = e['alterrors']
413
+ end
414
+ end
415
+ end
416
+ e.delete('alterrors')
417
+ end
418
+ e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
419
+ e['diagnosis'] = e['diagnosis'].sub(/\b__.+\z/, '')
420
+
421
+ unless e['rhost']
422
+ # Get the remote host name
423
+ if cv = e['diagnosis'].match(/host[ \t]+([^ \t]+)[ \t]\[.+\]:[ \t]/)
424
+ # host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
425
+ e['rhost'] = cv[1]
426
+ end
427
+
428
+ unless e['rhost']
429
+ if mhead['received'].size > 0
430
+ # Get localhost and remote host name from Received header.
431
+ e['rhost'] = Sisimai::RFC5322.received(mhead['received'][-1]).pop
432
+ end
433
+ end
434
+ end
435
+
436
+ unless e['command']
437
+ # Get the SMTP command name for the session
438
+ ReCommand.each do |r|
439
+ # Verify each regular expression of SMTP commands
440
+ if cv = e['diagnosis'].match(r)
441
+ e['command'] = cv[1].upcase
442
+ break
443
+ end
444
+ end
445
+
446
+ # Detect the reason of bounce
447
+ if e['command'] =~ /\A(?:HELO|EHLO)\z/
448
+ # HELO | Connected to 192.0.2.135 but my name was rejected.
449
+ e['reason'] = 'blocked'
450
+
451
+ elsif e['command'] == 'MAIL'
452
+ # MAIL | Connected to 192.0.2.135 but sender was rejected.
453
+ e['reason'] = 'onhold'
454
+
455
+ else
456
+ # Verify each regular expression of session errors
457
+ ReFailure.each_key do |r|
458
+ # Check each regular expression
459
+ next unless e['diagnosis'] =~ ReFailure[r]
460
+ e['reason'] = r
461
+ break
462
+ end
463
+
464
+ unless e['reason']
465
+ # The reason "expired"
466
+ e['reason'] = 'expired' if e['diagnosis'] =~ ReDelayed
467
+ end
468
+ end
469
+ end
470
+
471
+ # Prefer the value of smtp reply code in Diagnostic-Code:
472
+ # See eg/maildir-as-a-sample/new/exim-20.eml
473
+ # Action: failed
474
+ # Final-Recipient: rfc822;userx@test.ex
475
+ # Status: 5.0.0
476
+ # Remote-MTA: dns; 127.0.0.1
477
+ # Diagnostic-Code: smtp; 450 TEMPERROR: retry timeout exceeded
478
+ # The value of "Status:" indicates permanent error but the value
479
+ # of SMTP reply code in Diagnostic-Code: field is "TEMPERROR"!!!!
480
+ sv = Sisimai::SMTP::Status.find(e['diagnosis'])
481
+ rv = Sisimai::SMTP::Reply.find(e['diagnosis'])
482
+ s1 = 0 # First character of Status as integer
483
+ r1 = 0 # First character of SMTP reply code as integer
484
+
485
+ # "Status:" field did not exist in the bounce message
486
+ if sv.empty?
487
+ # Check SMTP reply code
488
+ if rv.size > 0
489
+ # Generate pseudo DSN code from SMTP reply code
490
+ r1 = rv[0, 1].to_i
491
+ if r1 == 4
492
+ # Get the internal DSN(temporary error)
493
+ sv = Sisimai::SMTP::Status.code(e['reason'], true)
494
+
495
+ elsif r1 == 5
496
+ # Get the internal DSN(permanent error)
497
+ sv = Sisimai::SMTP::Status.code(e['reason'], false)
498
+ end
499
+ end
500
+ end
501
+
502
+ s1 = sv[0, 1].to_i if sv.size > 0
503
+ v1 = s1 + r1
504
+ v1 += e['status'][0, 1].to_i if e['status']
505
+
506
+ if v1 > 0
507
+ # Status or SMTP reply code exists
508
+ if v1 % 5 == 0
509
+ # Both "Status" and SMTP reply code indicate permanent error
510
+ e['softbounce'] = 0
511
+
512
+ elsif v1 % 4 == 0
513
+ # Both "Status" and SMTP reply code indicate temporary error
514
+ e['softbounce'] = 1
515
+
516
+ else
517
+ # Mismatch error type...?
518
+ if r1 > 0
519
+ # Set pseudo DSN into the value of "status" accessor
520
+ e['status'] = sv
521
+ e['softbounce'] = r1 == 4 ? 1 : 0
522
+ end
523
+ end
524
+ else
525
+ # Neither Status nor SMTP reply code exist
526
+ if e['reason'] =~ /\A(?:expired|mailboxfull)/
527
+ # Set pseudo DSN (temporary error)
528
+ sv = Sisimai::SMTP::Status.code(e['reason'], true)
529
+ e['softbounce'] = 1
530
+
531
+ else
532
+ # Set pseudo DSN (permanent error)
533
+ sv = Sisimai::SMTP::Status.code(e['reason'], false)
534
+ e['softbounce'] = 0
535
+ end
536
+ end
537
+ e['status'] ||= sv
538
+ e['action'] ||= 'failed' if e['status'] =~ /\A[45]/
539
+ e.each_key { |a| e[a] ||= '' }
540
+ end
541
+
542
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
543
+ end
544
+
545
+ end
546
+ end
547
+ end
548
+ end
549
+