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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +182 -0
- data/.travis.yml +18 -0
- data/ANALYTICAL-PRECISION +56 -0
- data/Changes +36 -0
- data/Developers.mk +129 -0
- data/Gemfile +15 -0
- data/LICENSE +25 -0
- data/Makefile +70 -0
- data/README.md +361 -0
- data/Rakefile +12 -0
- data/Repository.mk +69 -0
- data/appveyor.yml +23 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/sisimai.rb +95 -0
- data/lib/sisimai/address.rb +224 -0
- data/lib/sisimai/arf.rb +338 -0
- data/lib/sisimai/data.rb +409 -0
- data/lib/sisimai/data/json.rb +40 -0
- data/lib/sisimai/data/yaml.rb +32 -0
- data/lib/sisimai/datetime.rb +511 -0
- data/lib/sisimai/mail.rb +82 -0
- data/lib/sisimai/mail/maildir.rb +82 -0
- data/lib/sisimai/mail/mbox.rb +69 -0
- data/lib/sisimai/mail/stdin.rb +53 -0
- data/lib/sisimai/mda.rb +152 -0
- data/lib/sisimai/message.rb +525 -0
- data/lib/sisimai/mime.rb +127 -0
- data/lib/sisimai/msp.rb +54 -0
- data/lib/sisimai/msp/de/einsundeins.rb +174 -0
- data/lib/sisimai/msp/de/gmx.rb +197 -0
- data/lib/sisimai/msp/jp/biglobe.rb +179 -0
- data/lib/sisimai/msp/jp/ezweb.rb +292 -0
- data/lib/sisimai/msp/jp/kddi.rb +195 -0
- data/lib/sisimai/msp/ru/mailru.rb +306 -0
- data/lib/sisimai/msp/ru/yandex.rb +241 -0
- data/lib/sisimai/msp/uk/messagelabs.rb +250 -0
- data/lib/sisimai/msp/us/amazonses.rb +248 -0
- data/lib/sisimai/msp/us/amazonworkmail.rb +224 -0
- data/lib/sisimai/msp/us/aol.rb +234 -0
- data/lib/sisimai/msp/us/bigfoot.rb +243 -0
- data/lib/sisimai/msp/us/facebook.rb +306 -0
- data/lib/sisimai/msp/us/google.rb +357 -0
- data/lib/sisimai/msp/us/office365.rb +273 -0
- data/lib/sisimai/msp/us/outlook.rb +242 -0
- data/lib/sisimai/msp/us/receivingses.rb +247 -0
- data/lib/sisimai/msp/us/sendgrid.rb +257 -0
- data/lib/sisimai/msp/us/verizon.rb +311 -0
- data/lib/sisimai/msp/us/yahoo.rb +178 -0
- data/lib/sisimai/msp/us/zoho.rb +198 -0
- data/lib/sisimai/mta.rb +54 -0
- data/lib/sisimai/mta/activehunter.rb +155 -0
- data/lib/sisimai/mta/apachejames.rb +194 -0
- data/lib/sisimai/mta/courier.rb +307 -0
- data/lib/sisimai/mta/domino.rb +209 -0
- data/lib/sisimai/mta/exchange.rb +314 -0
- data/lib/sisimai/mta/exim.rb +549 -0
- data/lib/sisimai/mta/imailserver.rb +227 -0
- data/lib/sisimai/mta/interscanmss.rb +167 -0
- data/lib/sisimai/mta/mailfoundry.rb +173 -0
- data/lib/sisimai/mta/mailmarshalsmtp.rb +206 -0
- data/lib/sisimai/mta/mcafee.rb +201 -0
- data/lib/sisimai/mta/messagingserver.rb +241 -0
- data/lib/sisimai/mta/mfilter.rb +190 -0
- data/lib/sisimai/mta/mxlogic.rb +283 -0
- data/lib/sisimai/mta/notes.rb +206 -0
- data/lib/sisimai/mta/opensmtpd.rb +225 -0
- data/lib/sisimai/mta/postfix.rb +306 -0
- data/lib/sisimai/mta/qmail.rb +335 -0
- data/lib/sisimai/mta/sendmail.rb +317 -0
- data/lib/sisimai/mta/surfcontrol.rb +193 -0
- data/lib/sisimai/mta/userdefined.rb +148 -0
- data/lib/sisimai/mta/v5sendmail.rb +232 -0
- data/lib/sisimai/mta/x1.rb +156 -0
- data/lib/sisimai/mta/x2.rb +157 -0
- data/lib/sisimai/mta/x3.rb +171 -0
- data/lib/sisimai/mta/x4.rb +365 -0
- data/lib/sisimai/mta/x5.rb +208 -0
- data/lib/sisimai/order.rb +220 -0
- data/lib/sisimai/reason.rb +234 -0
- data/lib/sisimai/reason/blocked.rb +105 -0
- data/lib/sisimai/reason/contenterror.rb +53 -0
- data/lib/sisimai/reason/exceedlimit.rb +60 -0
- data/lib/sisimai/reason/expired.rb +53 -0
- data/lib/sisimai/reason/filtered.rb +98 -0
- data/lib/sisimai/reason/hasmoved.rb +45 -0
- data/lib/sisimai/reason/hostunknown.rb +79 -0
- data/lib/sisimai/reason/mailboxfull.rb +118 -0
- data/lib/sisimai/reason/mailererror.rb +55 -0
- data/lib/sisimai/reason/mesgtoobig.rb +82 -0
- data/lib/sisimai/reason/networkerror.rb +58 -0
- data/lib/sisimai/reason/norelaying.rb +71 -0
- data/lib/sisimai/reason/notaccept.rb +63 -0
- data/lib/sisimai/reason/onhold.rb +45 -0
- data/lib/sisimai/reason/rejected.rb +101 -0
- data/lib/sisimai/reason/securityerror.rb +72 -0
- data/lib/sisimai/reason/spamdetected.rb +172 -0
- data/lib/sisimai/reason/suspend.rb +58 -0
- data/lib/sisimai/reason/systemerror.rb +69 -0
- data/lib/sisimai/reason/systemfull.rb +45 -0
- data/lib/sisimai/reason/toomanyconn.rb +73 -0
- data/lib/sisimai/reason/userunknown.rb +194 -0
- data/lib/sisimai/rfc2606.rb +24 -0
- data/lib/sisimai/rfc3464.rb +497 -0
- data/lib/sisimai/rfc3834.rb +150 -0
- data/lib/sisimai/rfc5322.rb +204 -0
- data/lib/sisimai/rhost.rb +47 -0
- data/lib/sisimai/rhost/googleapps.rb +237 -0
- data/lib/sisimai/smtp.rb +58 -0
- data/lib/sisimai/smtp/reply.rb +84 -0
- data/lib/sisimai/smtp/status.rb +758 -0
- data/lib/sisimai/string.rb +65 -0
- data/lib/sisimai/time.rb +11 -0
- data/lib/sisimai/version.rb +4 -0
- data/set-of-emails/README.md +35 -0
- data/set-of-emails/mailbox/mbox-0 +2467 -0
- data/set-of-emails/mailbox/mbox-1 +71 -0
- data/set-of-emails/maildir/bsd/README.md +261 -0
- data/set-of-emails/maildir/bsd/activehunter-01.eml +54 -0
- data/set-of-emails/maildir/bsd/activehunter-02.eml +53 -0
- data/set-of-emails/maildir/bsd/apachejames-01.eml +46 -0
- data/set-of-emails/maildir/bsd/arf-01.eml +66 -0
- data/set-of-emails/maildir/bsd/arf-02.eml +68 -0
- data/set-of-emails/maildir/bsd/arf-03.eml +56 -0
- data/set-of-emails/maildir/bsd/arf-04.eml +89 -0
- data/set-of-emails/maildir/bsd/arf-05.eml +82 -0
- data/set-of-emails/maildir/bsd/arf-06.eml +166 -0
- data/set-of-emails/maildir/bsd/arf-07.eml +59 -0
- data/set-of-emails/maildir/bsd/arf-08.eml +103 -0
- data/set-of-emails/maildir/bsd/arf-09.eml +104 -0
- data/set-of-emails/maildir/bsd/arf-10.eml +56 -0
- data/set-of-emails/maildir/bsd/arf-11.eml +37 -0
- data/set-of-emails/maildir/bsd/arf-12.eml +40 -0
- data/set-of-emails/maildir/bsd/arf-13.eml +76 -0
- data/set-of-emails/maildir/bsd/arf-14.eml +333 -0
- data/set-of-emails/maildir/bsd/arf-15.eml +66 -0
- data/set-of-emails/maildir/bsd/courier-01.eml +79 -0
- data/set-of-emails/maildir/bsd/courier-02.eml +83 -0
- data/set-of-emails/maildir/bsd/courier-03.eml +85 -0
- data/set-of-emails/maildir/bsd/courier-04.eml +87 -0
- data/set-of-emails/maildir/bsd/de-einsundeins-01.eml +38 -0
- data/set-of-emails/maildir/bsd/de-gmx-01.eml +52 -0
- data/set-of-emails/maildir/bsd/de-gmx-02.eml +51 -0
- data/set-of-emails/maildir/bsd/de-gmx-03.eml +56 -0
- data/set-of-emails/maildir/bsd/de-gmx-04.eml +51 -0
- data/set-of-emails/maildir/bsd/domino-01.eml +33 -0
- data/set-of-emails/maildir/bsd/domino-02.eml +83 -0
- data/set-of-emails/maildir/bsd/exchange-01.eml +31 -0
- data/set-of-emails/maildir/bsd/exchange-02.eml +67 -0
- data/set-of-emails/maildir/bsd/exchange-03.eml +52 -0
- data/set-of-emails/maildir/bsd/exchange-04.eml +28 -0
- data/set-of-emails/maildir/bsd/exchange-05.eml +56 -0
- data/set-of-emails/maildir/bsd/exchange-06.eml +151 -0
- data/set-of-emails/maildir/bsd/exim-01.eml +46 -0
- data/set-of-emails/maildir/bsd/exim-02.eml +41 -0
- data/set-of-emails/maildir/bsd/exim-03.eml +42 -0
- data/set-of-emails/maildir/bsd/exim-04.eml +46 -0
- data/set-of-emails/maildir/bsd/exim-05.eml +49 -0
- data/set-of-emails/maildir/bsd/exim-06.eml +44 -0
- data/set-of-emails/maildir/bsd/exim-07.eml +28 -0
- data/set-of-emails/maildir/bsd/exim-08.eml +42 -0
- data/set-of-emails/maildir/bsd/exim-09.eml +169 -0
- data/set-of-emails/maildir/bsd/exim-10.eml +718 -0
- data/set-of-emails/maildir/bsd/exim-11.eml +718 -0
- data/set-of-emails/maildir/bsd/exim-12.eml +75 -0
- data/set-of-emails/maildir/bsd/exim-13.eml +145 -0
- data/set-of-emails/maildir/bsd/exim-14.eml +32 -0
- data/set-of-emails/maildir/bsd/exim-15.eml +49 -0
- data/set-of-emails/maildir/bsd/exim-16.eml +98 -0
- data/set-of-emails/maildir/bsd/exim-17.eml +50 -0
- data/set-of-emails/maildir/bsd/exim-18.eml +96 -0
- data/set-of-emails/maildir/bsd/exim-19.eml +52 -0
- data/set-of-emails/maildir/bsd/exim-20.eml +159 -0
- data/set-of-emails/maildir/bsd/exim-21.eml +150 -0
- data/set-of-emails/maildir/bsd/exim-22.eml +50 -0
- data/set-of-emails/maildir/bsd/exim-23.eml +57 -0
- data/set-of-emails/maildir/bsd/exim-24.eml +107 -0
- data/set-of-emails/maildir/bsd/exim-25.eml +18 -0
- data/set-of-emails/maildir/bsd/exim-26.eml +111 -0
- data/set-of-emails/maildir/bsd/exim-27.eml +120 -0
- data/set-of-emails/maildir/bsd/exim-28.eml +148 -0
- data/set-of-emails/maildir/bsd/google-apps-01.eml +66 -0
- data/set-of-emails/maildir/bsd/imailserver-01.eml +27 -0
- data/set-of-emails/maildir/bsd/imailserver-02.eml +36 -0
- data/set-of-emails/maildir/bsd/imailserver-03.eml +28 -0
- data/set-of-emails/maildir/bsd/imailserver-04.eml +15 -0
- data/set-of-emails/maildir/bsd/imailserver-05.eml +92 -0
- data/set-of-emails/maildir/bsd/imailserver-06.eml +29 -0
- data/set-of-emails/maildir/bsd/interscanmss-01.eml +49 -0
- data/set-of-emails/maildir/bsd/interscanmss-02.eml +259 -0
- data/set-of-emails/maildir/bsd/jp-biglobe-01.eml +43 -0
- data/set-of-emails/maildir/bsd/jp-ezweb-01.eml +36 -0
- data/set-of-emails/maildir/bsd/jp-ezweb-02.eml +65 -0
- data/set-of-emails/maildir/bsd/jp-ezweb-03.eml +35 -0
- data/set-of-emails/maildir/bsd/jp-ezweb-04.eml +38 -0
- data/set-of-emails/maildir/bsd/jp-ezweb-05.eml +38 -0
- data/set-of-emails/maildir/bsd/jp-ezweb-06.eml +33 -0
- data/set-of-emails/maildir/bsd/jp-kddi-01.eml +49 -0
- data/set-of-emails/maildir/bsd/jp-kddi-02.eml +54 -0
- data/set-of-emails/maildir/bsd/jp-kddi-03.eml +54 -0
- data/set-of-emails/maildir/bsd/mailfoundry-01.eml +50 -0
- data/set-of-emails/maildir/bsd/mailfoundry-02.eml +49 -0
- data/set-of-emails/maildir/bsd/mailmarshalsmtp-01.eml +43 -0
- data/set-of-emails/maildir/bsd/mcafee-01.eml +63 -0
- data/set-of-emails/maildir/bsd/mcafee-02.eml +65 -0
- data/set-of-emails/maildir/bsd/mcafee-03.eml +59 -0
- data/set-of-emails/maildir/bsd/messagingserver-01.eml +102 -0
- data/set-of-emails/maildir/bsd/messagingserver-02.eml +72 -0
- data/set-of-emails/maildir/bsd/messagingserver-03.eml +70 -0
- data/set-of-emails/maildir/bsd/messagingserver-04.eml +102 -0
- data/set-of-emails/maildir/bsd/messagingserver-05.eml +98 -0
- data/set-of-emails/maildir/bsd/messagingserver-06.eml +101 -0
- data/set-of-emails/maildir/bsd/messagingserver-07.eml +129 -0
- data/set-of-emails/maildir/bsd/mfilter-01.eml +49 -0
- data/set-of-emails/maildir/bsd/mfilter-02.eml +48 -0
- data/set-of-emails/maildir/bsd/mfilter-03.eml +43 -0
- data/set-of-emails/maildir/bsd/mxlogic-01.eml +47 -0
- data/set-of-emails/maildir/bsd/mxlogic-02.eml +44 -0
- data/set-of-emails/maildir/bsd/mxlogic-03.eml +46 -0
- data/set-of-emails/maildir/bsd/notes-01.eml +42 -0
- data/set-of-emails/maildir/bsd/notes-02.eml +42 -0
- data/set-of-emails/maildir/bsd/notes-03.eml +38 -0
- data/set-of-emails/maildir/bsd/notes-04.eml +181 -0
- data/set-of-emails/maildir/bsd/opensmtpd-01.eml +33 -0
- data/set-of-emails/maildir/bsd/opensmtpd-02.eml +33 -0
- data/set-of-emails/maildir/bsd/opensmtpd-03.eml +36 -0
- data/set-of-emails/maildir/bsd/opensmtpd-04.eml +40 -0
- data/set-of-emails/maildir/bsd/opensmtpd-05.eml +36 -0
- data/set-of-emails/maildir/bsd/postfix-01.eml +60 -0
- data/set-of-emails/maildir/bsd/postfix-02.eml +78 -0
- data/set-of-emails/maildir/bsd/postfix-03.eml +71 -0
- data/set-of-emails/maildir/bsd/postfix-04.eml +89 -0
- data/set-of-emails/maildir/bsd/postfix-05.eml +78 -0
- data/set-of-emails/maildir/bsd/postfix-06.eml +72 -0
- data/set-of-emails/maildir/bsd/postfix-07.eml +74 -0
- data/set-of-emails/maildir/bsd/postfix-08.eml +78 -0
- data/set-of-emails/maildir/bsd/postfix-09.eml +76 -0
- data/set-of-emails/maildir/bsd/postfix-10.eml +73 -0
- data/set-of-emails/maildir/bsd/postfix-11.eml +86 -0
- data/set-of-emails/maildir/bsd/postfix-12.eml +71 -0
- data/set-of-emails/maildir/bsd/postfix-13.eml +81 -0
- data/set-of-emails/maildir/bsd/postfix-14.eml +68 -0
- data/set-of-emails/maildir/bsd/postfix-15.eml +69 -0
- data/set-of-emails/maildir/bsd/postfix-16.eml +73 -0
- data/set-of-emails/maildir/bsd/postfix-17.eml +68 -0
- data/set-of-emails/maildir/bsd/postfix-18.eml +121 -0
- data/set-of-emails/maildir/bsd/postfix-19.eml +105 -0
- data/set-of-emails/maildir/bsd/postfix-20.eml +231 -0
- data/set-of-emails/maildir/bsd/postfix-21.eml +60 -0
- data/set-of-emails/maildir/bsd/qmail-01.eml +40 -0
- data/set-of-emails/maildir/bsd/qmail-02.eml +35 -0
- data/set-of-emails/maildir/bsd/qmail-03.eml +22 -0
- data/set-of-emails/maildir/bsd/qmail-04.eml +31 -0
- data/set-of-emails/maildir/bsd/qmail-05.eml +31 -0
- data/set-of-emails/maildir/bsd/qmail-06.eml +39 -0
- data/set-of-emails/maildir/bsd/qmail-07.eml +22 -0
- data/set-of-emails/maildir/bsd/qmail-08.eml +23 -0
- data/set-of-emails/maildir/bsd/qmail-09.eml +103 -0
- data/set-of-emails/maildir/bsd/rfc3464-01.eml +60 -0
- data/set-of-emails/maildir/bsd/rfc3464-02.eml +43 -0
- data/set-of-emails/maildir/bsd/rfc3464-03.eml +40 -0
- data/set-of-emails/maildir/bsd/rfc3464-04.eml +50 -0
- data/set-of-emails/maildir/bsd/rfc3464-05.eml +63 -0
- data/set-of-emails/maildir/bsd/rfc3464-06.eml +48 -0
- data/set-of-emails/maildir/bsd/rfc3464-07.eml +88 -0
- data/set-of-emails/maildir/bsd/rfc3464-08.eml +70 -0
- data/set-of-emails/maildir/bsd/rfc3464-09.eml +93 -0
- data/set-of-emails/maildir/bsd/rfc3464-10.eml +467 -0
- data/set-of-emails/maildir/bsd/rfc3464-11.eml +1171 -0
- data/set-of-emails/maildir/bsd/rfc3464-12.eml +101 -0
- data/set-of-emails/maildir/bsd/rfc3464-13.eml +131 -0
- data/set-of-emails/maildir/bsd/rfc3464-14.eml +121 -0
- data/set-of-emails/maildir/bsd/rfc3464-15.eml +144 -0
- data/set-of-emails/maildir/bsd/rfc3464-16.eml +36 -0
- data/set-of-emails/maildir/bsd/rfc3464-17.eml +109 -0
- data/set-of-emails/maildir/bsd/rfc3464-18.eml +149 -0
- data/set-of-emails/maildir/bsd/rfc3464-19.eml +65 -0
- data/set-of-emails/maildir/bsd/rfc3464-20.eml +145 -0
- data/set-of-emails/maildir/bsd/rfc3464-21.eml +146 -0
- data/set-of-emails/maildir/bsd/rfc3464-22.eml +105 -0
- data/set-of-emails/maildir/bsd/rfc3464-23.eml +21 -0
- data/set-of-emails/maildir/bsd/rfc3464-24.eml +27 -0
- data/set-of-emails/maildir/bsd/rfc3464-25.eml +33 -0
- data/set-of-emails/maildir/bsd/rfc3464-26.eml +98 -0
- data/set-of-emails/maildir/bsd/rfc3464-27.eml +180 -0
- data/set-of-emails/maildir/bsd/rfc3464-28.eml +122 -0
- data/set-of-emails/maildir/bsd/rfc3834-01.eml +37 -0
- data/set-of-emails/maildir/bsd/rfc3834-02.eml +51 -0
- data/set-of-emails/maildir/bsd/rfc3834-03.eml +33 -0
- data/set-of-emails/maildir/bsd/ru-mailru-01.eml +54 -0
- data/set-of-emails/maildir/bsd/ru-mailru-02.eml +54 -0
- data/set-of-emails/maildir/bsd/ru-mailru-03.eml +62 -0
- data/set-of-emails/maildir/bsd/ru-mailru-04.eml +54 -0
- data/set-of-emails/maildir/bsd/ru-yandex-01.eml +102 -0
- data/set-of-emails/maildir/bsd/ru-yandex-02.eml +113 -0
- data/set-of-emails/maildir/bsd/ru-yandex-03.eml +101 -0
- data/set-of-emails/maildir/bsd/sendmail-01.eml +70 -0
- data/set-of-emails/maildir/bsd/sendmail-02.eml +82 -0
- data/set-of-emails/maildir/bsd/sendmail-03.eml +76 -0
- data/set-of-emails/maildir/bsd/sendmail-04.eml +63 -0
- data/set-of-emails/maildir/bsd/sendmail-05.eml +64 -0
- data/set-of-emails/maildir/bsd/sendmail-06.eml +67 -0
- data/set-of-emails/maildir/bsd/sendmail-07.eml +65 -0
- data/set-of-emails/maildir/bsd/sendmail-08.eml +62 -0
- data/set-of-emails/maildir/bsd/sendmail-09.eml +60 -0
- data/set-of-emails/maildir/bsd/sendmail-10.eml +82 -0
- data/set-of-emails/maildir/bsd/sendmail-11.eml +60 -0
- data/set-of-emails/maildir/bsd/sendmail-12.eml +62 -0
- data/set-of-emails/maildir/bsd/sendmail-13.eml +66 -0
- data/set-of-emails/maildir/bsd/sendmail-14.eml +64 -0
- data/set-of-emails/maildir/bsd/sendmail-15.eml +60 -0
- data/set-of-emails/maildir/bsd/sendmail-16.eml +69 -0
- data/set-of-emails/maildir/bsd/sendmail-17.eml +68 -0
- data/set-of-emails/maildir/bsd/sendmail-18.eml +64 -0
- data/set-of-emails/maildir/bsd/sendmail-19.eml +71 -0
- data/set-of-emails/maildir/bsd/sendmail-20.eml +120 -0
- data/set-of-emails/maildir/bsd/sendmail-21.eml +69 -0
- data/set-of-emails/maildir/bsd/sendmail-22.eml +73 -0
- data/set-of-emails/maildir/bsd/sendmail-23.eml +137 -0
- data/set-of-emails/maildir/bsd/sendmail-24.eml +66 -0
- data/set-of-emails/maildir/bsd/sendmail-25.eml +70 -0
- data/set-of-emails/maildir/bsd/sendmail-26.eml +71 -0
- data/set-of-emails/maildir/bsd/sendmail-27.eml +69 -0
- data/set-of-emails/maildir/bsd/sendmail-28.eml +69 -0
- data/set-of-emails/maildir/bsd/sendmail-29.eml +70 -0
- data/set-of-emails/maildir/bsd/sendmail-30.eml +68 -0
- data/set-of-emails/maildir/bsd/sendmail-31.eml +80 -0
- data/set-of-emails/maildir/bsd/sendmail-32.eml +71 -0
- data/set-of-emails/maildir/bsd/sendmail-33.eml +71 -0
- data/set-of-emails/maildir/bsd/sendmail-34.eml +75 -0
- data/set-of-emails/maildir/bsd/sendmail-35.eml +70 -0
- data/set-of-emails/maildir/bsd/sendmail-36.eml +71 -0
- data/set-of-emails/maildir/bsd/sendmail-37.eml +71 -0
- data/set-of-emails/maildir/bsd/sendmail-38.eml +167 -0
- data/set-of-emails/maildir/bsd/surfcontrol-01.eml +79 -0
- data/set-of-emails/maildir/bsd/surfcontrol-02.eml +70 -0
- data/set-of-emails/maildir/bsd/surfcontrol-03.eml +70 -0
- data/set-of-emails/maildir/bsd/uk-messagelabs-01.eml +76 -0
- data/set-of-emails/maildir/bsd/us-amazonses-01.eml +59 -0
- data/set-of-emails/maildir/bsd/us-amazonses-02.eml +177 -0
- data/set-of-emails/maildir/bsd/us-amazonses-03.eml +55 -0
- data/set-of-emails/maildir/bsd/us-amazonses-04.eml +55 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-01.eml +156 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-02.eml +160 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-03.eml +161 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-04.eml +156 -0
- data/set-of-emails/maildir/bsd/us-amazonworkmail-05.eml +157 -0
- data/set-of-emails/maildir/bsd/us-aol-01.eml +1258 -0
- data/set-of-emails/maildir/bsd/us-aol-02.eml +1257 -0
- data/set-of-emails/maildir/bsd/us-aol-03.eml +1264 -0
- data/set-of-emails/maildir/bsd/us-aol-04.eml +1260 -0
- data/set-of-emails/maildir/bsd/us-bigfoot-01.eml +64 -0
- data/set-of-emails/maildir/bsd/us-facebook-01.eml +40 -0
- data/set-of-emails/maildir/bsd/us-facebook-02.eml +42 -0
- data/set-of-emails/maildir/bsd/us-google-01.eml +70 -0
- data/set-of-emails/maildir/bsd/us-google-02.eml +50 -0
- data/set-of-emails/maildir/bsd/us-google-03.eml +51 -0
- data/set-of-emails/maildir/bsd/us-google-04.eml +82 -0
- data/set-of-emails/maildir/bsd/us-google-05.eml +50 -0
- data/set-of-emails/maildir/bsd/us-google-06.eml +56 -0
- data/set-of-emails/maildir/bsd/us-google-07.eml +42 -0
- data/set-of-emails/maildir/bsd/us-google-08.eml +59 -0
- data/set-of-emails/maildir/bsd/us-google-09.eml +76 -0
- data/set-of-emails/maildir/bsd/us-google-10.eml +69 -0
- data/set-of-emails/maildir/bsd/us-google-11.eml +68 -0
- data/set-of-emails/maildir/bsd/us-google-12.eml +76 -0
- data/set-of-emails/maildir/bsd/us-google-13.eml +79 -0
- data/set-of-emails/maildir/bsd/us-google-14.eml +304 -0
- data/set-of-emails/maildir/bsd/us-office365-01.eml +102 -0
- data/set-of-emails/maildir/bsd/us-outlook-01.eml +72 -0
- data/set-of-emails/maildir/bsd/us-outlook-02.eml +72 -0
- data/set-of-emails/maildir/bsd/us-outlook-03.eml +72 -0
- data/set-of-emails/maildir/bsd/us-outlook-04.eml +79 -0
- data/set-of-emails/maildir/bsd/us-outlook-05.eml +85 -0
- data/set-of-emails/maildir/bsd/us-outlook-06.eml +75 -0
- data/set-of-emails/maildir/bsd/us-outlook-07.eml +70 -0
- data/set-of-emails/maildir/bsd/us-receivingses-01.eml +74 -0
- data/set-of-emails/maildir/bsd/us-receivingses-02.eml +74 -0
- data/set-of-emails/maildir/bsd/us-receivingses-03.eml +74 -0
- data/set-of-emails/maildir/bsd/us-receivingses-04.eml +74 -0
- data/set-of-emails/maildir/bsd/us-receivingses-05.eml +74 -0
- data/set-of-emails/maildir/bsd/us-receivingses-06.eml +74 -0
- data/set-of-emails/maildir/bsd/us-receivingses-07.eml +74 -0
- data/set-of-emails/maildir/bsd/us-sendgrid-01.eml +95 -0
- data/set-of-emails/maildir/bsd/us-sendgrid-02.eml +98 -0
- data/set-of-emails/maildir/bsd/us-sendgrid-03.eml +100 -0
- data/set-of-emails/maildir/bsd/us-verizon-01.eml +31 -0
- data/set-of-emails/maildir/bsd/us-yahoo-01.eml +78 -0
- data/set-of-emails/maildir/bsd/us-yahoo-02.eml +79 -0
- data/set-of-emails/maildir/bsd/us-yahoo-03.eml +93 -0
- data/set-of-emails/maildir/bsd/us-yahoo-04.eml +94 -0
- data/set-of-emails/maildir/bsd/us-yahoo-05.eml +94 -0
- data/set-of-emails/maildir/bsd/us-zoho-01.eml +40 -0
- data/set-of-emails/maildir/bsd/us-zoho-02.eml +38 -0
- data/set-of-emails/maildir/bsd/us-zoho-03.eml +37 -0
- data/set-of-emails/maildir/bsd/us-zoho-04.eml +47 -0
- data/set-of-emails/maildir/bsd/us-zoho-05.eml +37 -0
- data/set-of-emails/maildir/bsd/v5sendmail-01.eml +24 -0
- data/set-of-emails/maildir/bsd/v5sendmail-02.eml +26 -0
- data/set-of-emails/maildir/bsd/v5sendmail-03.eml +29 -0
- data/set-of-emails/maildir/bsd/v5sendmail-04.eml +29 -0
- data/set-of-emails/maildir/bsd/v5sendmail-05.eml +42 -0
- data/set-of-emails/maildir/bsd/v5sendmail-06.eml +28 -0
- data/set-of-emails/maildir/bsd/v5sendmail-07.eml +35 -0
- data/set-of-emails/maildir/bsd/x1-01.eml +61 -0
- data/set-of-emails/maildir/bsd/x1-02.eml +62 -0
- data/set-of-emails/maildir/bsd/x2-01.eml +41 -0
- data/set-of-emails/maildir/bsd/x2-02.eml +46 -0
- data/set-of-emails/maildir/bsd/x2-03.eml +34 -0
- data/set-of-emails/maildir/bsd/x2-04.eml +0 -0
- data/set-of-emails/maildir/bsd/x2-05.eml +98 -0
- data/set-of-emails/maildir/bsd/x3-01.eml +61 -0
- data/set-of-emails/maildir/bsd/x3-02.eml +64 -0
- data/set-of-emails/maildir/bsd/x3-03.eml +59 -0
- data/set-of-emails/maildir/bsd/x3-04.eml +106 -0
- data/set-of-emails/maildir/bsd/x4-01.eml +92 -0
- data/set-of-emails/maildir/bsd/x4-02.eml +112 -0
- data/set-of-emails/maildir/bsd/x4-03.eml +245 -0
- data/set-of-emails/maildir/bsd/x4-04.eml +81 -0
- data/set-of-emails/maildir/bsd/x4-05.eml +121 -0
- data/set-of-emails/maildir/bsd/x4-06.eml +32 -0
- data/set-of-emails/maildir/bsd/x4-07.eml +153 -0
- data/set-of-emails/maildir/bsd/x5-01.eml +155 -0
- data/set-of-emails/maildir/dos/activehunter-01.eml +54 -0
- data/set-of-emails/maildir/dos/apachejames-01.eml +46 -0
- data/set-of-emails/maildir/dos/arf-01.eml +66 -0
- data/set-of-emails/maildir/dos/courier-01.eml +79 -0
- data/set-of-emails/maildir/dos/de-einsundeins-01.eml +38 -0
- data/set-of-emails/maildir/dos/de-gmx-01.eml +52 -0
- data/set-of-emails/maildir/dos/domino-01.eml +33 -0
- data/set-of-emails/maildir/dos/exchange-01.eml +31 -0
- data/set-of-emails/maildir/dos/exim-01.eml +46 -0
- data/set-of-emails/maildir/dos/google-apps-01.eml +66 -0
- data/set-of-emails/maildir/dos/imailserver-01.eml +27 -0
- data/set-of-emails/maildir/dos/interscanmss-01.eml +49 -0
- data/set-of-emails/maildir/dos/jp-biglobe-01.eml +43 -0
- data/set-of-emails/maildir/dos/jp-ezweb-01.eml +36 -0
- data/set-of-emails/maildir/dos/jp-kddi-01.eml +49 -0
- data/set-of-emails/maildir/dos/mailfoundry-01.eml +50 -0
- data/set-of-emails/maildir/dos/mailmarshalsmtp-01.eml +43 -0
- data/set-of-emails/maildir/dos/mcafee-01.eml +63 -0
- data/set-of-emails/maildir/dos/messagingserver-01.eml +102 -0
- data/set-of-emails/maildir/dos/mfilter-01.eml +49 -0
- data/set-of-emails/maildir/dos/mxlogic-01.eml +47 -0
- data/set-of-emails/maildir/dos/notes-01.eml +42 -0
- data/set-of-emails/maildir/dos/opensmtpd-01.eml +33 -0
- data/set-of-emails/maildir/dos/postfix-01.eml +60 -0
- data/set-of-emails/maildir/dos/qmail-01.eml +40 -0
- data/set-of-emails/maildir/dos/rfc3464-01.eml +59 -0
- data/set-of-emails/maildir/dos/rfc3834-01.eml +37 -0
- data/set-of-emails/maildir/dos/ru-mailru-01.eml +54 -0
- data/set-of-emails/maildir/dos/ru-yandex-01.eml +102 -0
- data/set-of-emails/maildir/dos/sendmail-01.eml +69 -0
- data/set-of-emails/maildir/dos/surfcontrol-01.eml +79 -0
- data/set-of-emails/maildir/dos/uk-messagelabs-01.eml +76 -0
- data/set-of-emails/maildir/dos/us-amazonses-01.eml +59 -0
- data/set-of-emails/maildir/dos/us-aol-01.eml +1258 -0
- data/set-of-emails/maildir/dos/us-bigfoot-01.eml +64 -0
- data/set-of-emails/maildir/dos/us-facebook-01.eml +40 -0
- data/set-of-emails/maildir/dos/us-google-01.eml +70 -0
- data/set-of-emails/maildir/dos/us-outlook-01.eml +72 -0
- data/set-of-emails/maildir/dos/us-receivingses-01.eml +74 -0
- data/set-of-emails/maildir/dos/us-sendgrid-01.eml +95 -0
- data/set-of-emails/maildir/dos/us-verizon-01.eml +31 -0
- data/set-of-emails/maildir/dos/us-yahoo-01.eml +78 -0
- data/set-of-emails/maildir/dos/us-zoho-01.eml +40 -0
- data/set-of-emails/maildir/dos/v5sendmail-01.eml +24 -0
- data/set-of-emails/maildir/dos/x1-01.eml +61 -0
- data/set-of-emails/maildir/dos/x2-01.eml +41 -0
- data/set-of-emails/maildir/dos/x3-01.eml +61 -0
- data/set-of-emails/maildir/dos/x4-01.eml +90 -0
- data/set-of-emails/maildir/dos/x5-01.eml +155 -0
- data/set-of-emails/maildir/err/make-test-01.eml +70 -0
- data/set-of-emails/maildir/err/make-test-02.eml +70 -0
- data/set-of-emails/maildir/err/make-test-03.eml +64 -0
- data/set-of-emails/maildir/err/make-test-04.eml +64 -0
- data/set-of-emails/maildir/err/make-test-05.eml +66 -0
- data/set-of-emails/maildir/err/make-test-06.eml +118 -0
- data/set-of-emails/maildir/err/make-test-07.eml +26 -0
- data/set-of-emails/maildir/err/make-test-08.eml +67 -0
- data/set-of-emails/maildir/err/make-test-09.eml +55 -0
- data/set-of-emails/maildir/err/make-test-10.eml +69 -0
- data/set-of-emails/maildir/err/make-test-11.eml +64 -0
- data/set-of-emails/maildir/err/make-test-12.eml +66 -0
- data/set-of-emails/maildir/err/make-test-13.eml +67 -0
- data/set-of-emails/maildir/err/make-test-14.eml +66 -0
- data/set-of-emails/maildir/err/make-test-15.eml +70 -0
- data/set-of-emails/maildir/err/make-test-16.eml +68 -0
- data/set-of-emails/maildir/err/make-test-17.eml +68 -0
- data/set-of-emails/maildir/err/make-test-18.eml +68 -0
- data/set-of-emails/maildir/err/make-test-19.eml +69 -0
- data/set-of-emails/maildir/err/make-test-20.eml +67 -0
- data/set-of-emails/maildir/err/make-test-21.eml +69 -0
- data/set-of-emails/maildir/err/make-test-22.eml +66 -0
- data/set-of-emails/maildir/err/make-test-23.eml +70 -0
- data/set-of-emails/maildir/err/make-test-24.eml +69 -0
- data/set-of-emails/maildir/err/make-test-25.eml +67 -0
- data/set-of-emails/maildir/err/make-test-26.eml +69 -0
- data/set-of-emails/maildir/err/make-test-27.eml +69 -0
- data/set-of-emails/maildir/err/make-test-28.eml +66 -0
- data/set-of-emails/maildir/err/make-test-29.eml +68 -0
- data/set-of-emails/maildir/err/make-test-30.eml +68 -0
- data/set-of-emails/maildir/err/make-test-31.eml +80 -0
- data/set-of-emails/maildir/err/make-test-32.eml +66 -0
- data/set-of-emails/maildir/err/make-test-33.eml +68 -0
- data/set-of-emails/maildir/err/make-test-34.eml +56 -0
- data/set-of-emails/maildir/err/make-test-35.eml +59 -0
- data/set-of-emails/maildir/err/make-test-36.eml +53 -0
- data/set-of-emails/maildir/err/make-test-37.eml +62 -0
- data/set-of-emails/maildir/mac/activehunter-01.eml +1 -2
- data/set-of-emails/maildir/mac/apachejames-01.eml +1 -4
- data/set-of-emails/maildir/mac/arf-01.eml +1 -3
- data/set-of-emails/maildir/mac/courier-01.eml +1 -6
- data/set-of-emails/maildir/mac/de-einsundeins-01.eml +1 -1
- data/set-of-emails/maildir/mac/de-gmx-01.eml +1 -1
- data/set-of-emails/maildir/mac/domino-01.eml +1 -0
- data/set-of-emails/maildir/mac/exchange-01.eml +1 -0
- data/set-of-emails/maildir/mac/exim-01.eml +1 -1
- data/set-of-emails/maildir/mac/google-apps-01.eml +1 -4
- data/set-of-emails/maildir/mac/imailserver-01.eml +1 -0
- data/set-of-emails/maildir/mac/interscanmss-01.eml +1 -2
- data/set-of-emails/maildir/mac/jp-biglobe-01.eml +1 -2
- data/set-of-emails/maildir/mac/jp-ezweb-01.eml +1 -1
- data/set-of-emails/maildir/mac/jp-kddi-01.eml +1 -2
- data/set-of-emails/maildir/mac/mailfoundry-01.eml +1 -2
- data/set-of-emails/maildir/mac/mailmarshalsmtp-01.eml +1 -2
- data/set-of-emails/maildir/mac/mcafee-01.eml +1 -4
- data/set-of-emails/maildir/mac/messagingserver-01.eml +1 -4
- data/set-of-emails/maildir/mac/mfilter-01.eml +1 -3
- data/set-of-emails/maildir/mac/mxlogic-01.eml +1 -1
- data/set-of-emails/maildir/mac/notes-01.eml +1 -2
- data/set-of-emails/maildir/mac/opensmtpd-01.eml +1 -0
- data/set-of-emails/maildir/mac/postfix-01.eml +1 -3
- data/set-of-emails/maildir/mac/qmail-01.eml +1 -1
- data/set-of-emails/maildir/mac/rfc3464-01.eml +1 -4
- data/set-of-emails/maildir/mac/rfc3834-01.eml +1 -0
- data/set-of-emails/maildir/mac/ru-mailru-01.eml +1 -1
- data/set-of-emails/maildir/mac/ru-yandex-01.eml +1 -4
- data/set-of-emails/maildir/mac/sendmail-01.eml +1 -4
- data/set-of-emails/maildir/mac/surfcontrol-01.eml +1 -5
- data/set-of-emails/maildir/mac/uk-messagelabs-01.eml +1 -4
- data/set-of-emails/maildir/mac/us-amazonses-01.eml +1 -4
- data/set-of-emails/maildir/mac/us-aol-01.eml +1 -15
- data/set-of-emails/maildir/mac/us-bigfoot-01.eml +1 -4
- data/set-of-emails/maildir/mac/us-facebook-01.eml +1 -4
- data/set-of-emails/maildir/mac/us-google-01.eml +1 -1
- data/set-of-emails/maildir/mac/us-outlook-01.eml +1 -4
- data/set-of-emails/maildir/mac/us-receivingses-01.eml +1 -4
- data/set-of-emails/maildir/mac/us-sendgrid-01.eml +1 -3
- data/set-of-emails/maildir/mac/us-verizon-01.eml +1 -2
- data/set-of-emails/maildir/mac/us-yahoo-01.eml +1 -1
- data/set-of-emails/maildir/mac/us-zoho-01.eml +1 -2
- data/set-of-emails/maildir/mac/v5sendmail-01.eml +1 -0
- data/set-of-emails/maildir/mac/x1-01.eml +1 -4
- data/set-of-emails/maildir/mac/x2-01.eml +1 -1
- data/set-of-emails/maildir/mac/x3-01.eml +1 -3
- data/set-of-emails/maildir/mac/x4-01.eml +1 -2
- data/set-of-emails/maildir/mac/x5-01.eml +1 -8
- data/set-of-emails/maildir/not/is-not-bounce-01.eml +25 -0
- data/set-of-emails/to-be-debugged-because/reason-is-onhold/onhold-0001.eml +85 -0
- data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0002.eml +27 -0
- data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0003.eml +78 -0
- data/set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet/cannot-parse-this-email-0002.eml +25 -0
- data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-01.eml +79 -0
- data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-02.eml +72 -0
- data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-03.eml +68 -0
- data/set-of-emails/to-be-debugged-because/something-is-wrong/no-message-id-from-pr-150.eml +75 -0
- data/set-of-emails/to-be-parsed-for-test/README.md +20 -0
- data/sisimai-java.gemspec +29 -0
- data/sisimai.gemspec +28 -0
- 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
|
+
|