sisimai 4.14.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sisimai might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +165 -0
- data/.travis.yml +21 -0
- data/ANALYTICAL-PRECISION +54 -0
- data/Changes +5 -0
- data/Developers.mk +129 -0
- data/Gemfile +9 -0
- data/LICENSE +26 -0
- data/Makefile +56 -0
- data/README.md +300 -0
- data/Rakefile +7 -0
- data/Repository.mk +69 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/sisimai.rb +60 -0
- data/lib/sisimai/address.rb +218 -0
- data/lib/sisimai/arf.rb +343 -0
- data/lib/sisimai/data.rb +413 -0
- data/lib/sisimai/data/json.rb +36 -0
- data/lib/sisimai/data/yaml.rb +32 -0
- data/lib/sisimai/datetime.rb +518 -0
- data/lib/sisimai/mail.rb +82 -0
- data/lib/sisimai/mail/maildir.rb +85 -0
- data/lib/sisimai/mail/mbox.rb +69 -0
- data/lib/sisimai/mail/stdin.rb +52 -0
- data/lib/sisimai/mda.rb +152 -0
- data/lib/sisimai/message.rb +510 -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/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/outlook.rb +243 -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 +55 -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 +217 -0
- data/lib/sisimai/reason.rb +235 -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 +74 -0
- data/lib/sisimai/reason/mailboxfull.rb +118 -0
- data/lib/sisimai/reason/mailererror.rb +55 -0
- data/lib/sisimai/reason/mesgtoobig.rb +77 -0
- data/lib/sisimai/reason/networkerror.rb +57 -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 +81 -0
- data/lib/sisimai/smtp/status.rb +755 -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/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/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-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-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.gemspec +25 -0
- metadata +647 -0
@@ -0,0 +1,198 @@
|
|
1
|
+
module Sisimai
|
2
|
+
module MSP::US
|
3
|
+
# Sisimai::MSP::US::Zoho parses a bounce email which created by Zoho Mail.
|
4
|
+
# Methods in the module are called from only Sisimai::Message.
|
5
|
+
module Zoho
|
6
|
+
# Imported from p5-Sisimail/lib/Sisimai/MSP/US/Zoho.pm
|
7
|
+
class << self
|
8
|
+
require 'sisimai/msp'
|
9
|
+
require 'sisimai/rfc5322'
|
10
|
+
|
11
|
+
Re0 = {
|
12
|
+
:'from' => %r/mailer-daemon[@]mail[.]zoho[.]com\z/,
|
13
|
+
:'subject' => %r{\A(?:
|
14
|
+
Undelivered[ ]Mail[ ]Returned[ ]to[ ]Sender
|
15
|
+
|Mail[ ]Delivery[ ]Status[ ]Notification
|
16
|
+
)
|
17
|
+
}x,
|
18
|
+
:'x-mailer' => %r/\AZoho Mail\z/,
|
19
|
+
}
|
20
|
+
Re1 = {
|
21
|
+
:begin => %r/\AThis message was created automatically by mail delivery/,
|
22
|
+
:rfc822 => %r/\AReceived:[ \t]*from mail[.]zoho[.]com/,
|
23
|
+
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
24
|
+
}
|
25
|
+
ReFailure = {
|
26
|
+
'expired' => %r/Host not reachable/
|
27
|
+
}
|
28
|
+
Indicators = Sisimai::MSP.INDICATORS
|
29
|
+
LongFields = Sisimai::RFC5322.LONGFIELDS
|
30
|
+
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
31
|
+
|
32
|
+
def description; return 'Zoho Mail: https://www.zoho.com'; end
|
33
|
+
def smtpagent; return 'US::Zoho'; end
|
34
|
+
|
35
|
+
# X-ZohoMail: Si CHF_MF_NL SS_10 UW48 UB48 FMWL UW48 UB48 SGR3_1_09124_42
|
36
|
+
# X-Zoho-Virus-Status: 2
|
37
|
+
# X-Mailer: Zoho Mail
|
38
|
+
def headerlist; return ['X-ZohoMail']; end
|
39
|
+
def pattern; return Re0; end
|
40
|
+
|
41
|
+
# Parse bounce messages from Zoho Mail
|
42
|
+
# @param [Hash] mhead Message header of a bounce email
|
43
|
+
# @options mhead [String] from From header
|
44
|
+
# @options mhead [String] date Date header
|
45
|
+
# @options mhead [String] subject Subject header
|
46
|
+
# @options mhead [Array] received Received headers
|
47
|
+
# @options mhead [String] others Other required headers
|
48
|
+
# @param [String] mbody Message body of a bounce email
|
49
|
+
# @return [Hash, Nil] Bounce data list and message/rfc822
|
50
|
+
# part or nil if it failed to parse or
|
51
|
+
# the arguments are missing
|
52
|
+
def scan(mhead, mbody)
|
53
|
+
return nil unless mhead
|
54
|
+
return nil unless mbody
|
55
|
+
return nil unless mhead['x-zohomail']
|
56
|
+
|
57
|
+
dscontents = []; dscontents << Sisimai::MSP.DELIVERYSTATUS
|
58
|
+
hasdivided = mbody.split("\n")
|
59
|
+
rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
|
60
|
+
rfc822part = '' # (String) message/rfc822-headers part
|
61
|
+
previousfn = '' # (String) Previous field name
|
62
|
+
readcursor = 0 # (Integer) Points the current cursor position
|
63
|
+
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
64
|
+
qprintable = false
|
65
|
+
v = nil
|
66
|
+
|
67
|
+
hasdivided.each do |e|
|
68
|
+
if readcursor == 0
|
69
|
+
# Beginning of the bounce message or delivery status part
|
70
|
+
if e =~ Re1[:begin]
|
71
|
+
readcursor |= Indicators[:'deliverystatus']
|
72
|
+
next
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
if readcursor & Indicators[:'message-rfc822'] == 0
|
77
|
+
# Beginning of the original message part
|
78
|
+
if e =~ Re1[:rfc822]
|
79
|
+
readcursor |= Indicators[:'message-rfc822']
|
80
|
+
next
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if readcursor & Indicators[:'message-rfc822'] > 0
|
85
|
+
# After "message/rfc822"
|
86
|
+
if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
|
87
|
+
# Get required headers only
|
88
|
+
lhs = cv[1].downcase
|
89
|
+
previousfn = ''
|
90
|
+
next unless RFC822Head.key?(lhs)
|
91
|
+
|
92
|
+
previousfn = lhs
|
93
|
+
rfc822part += e + "\n"
|
94
|
+
|
95
|
+
elsif e =~ /\A[ \t]+/
|
96
|
+
# Continued line from the previous line
|
97
|
+
next if rfc822next[previousfn]
|
98
|
+
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
99
|
+
|
100
|
+
else
|
101
|
+
# Check the end of headers in rfc822 part
|
102
|
+
next unless LongFields.key?(previousfn)
|
103
|
+
next unless e.empty?
|
104
|
+
rfc822next[previousfn] = true
|
105
|
+
end
|
106
|
+
|
107
|
+
else
|
108
|
+
# Before "message/rfc822"
|
109
|
+
next if readcursor & Indicators[:'deliverystatus'] == 0
|
110
|
+
next if e.empty?
|
111
|
+
|
112
|
+
# This message was created automatically by mail delivery software.
|
113
|
+
# A message that you sent could not be delivered to one or more of its recip=
|
114
|
+
# ients. This is a permanent error.=20
|
115
|
+
#
|
116
|
+
# kijitora@example.co.jp Invalid Address, ERROR_CODE :550, ERROR_CODE :5.1.=
|
117
|
+
# 1 <kijitora@example.co.jp>... User Unknown
|
118
|
+
|
119
|
+
# This message was created automatically by mail delivery software.
|
120
|
+
# A message that you sent could not be delivered to one or more of its recipients. This is a permanent error.
|
121
|
+
#
|
122
|
+
# shironeko@example.org Invalid Address, ERROR_CODE :550, ERROR_CODE :Requested action not taken: mailbox unavailable
|
123
|
+
v = dscontents[-1]
|
124
|
+
|
125
|
+
if cv = e.match(/\A([^ ]+[@][^ ]+)[ \t]+(.+)\z/)
|
126
|
+
# kijitora@example.co.jp Invalid Address, ERROR_CODE :550, ERROR_CODE :5.1.=
|
127
|
+
if v['recipient']
|
128
|
+
# There are multiple recipient addresses in the message body.
|
129
|
+
dscontents << Sisimai::MSP.DELIVERYSTATUS
|
130
|
+
v = dscontents[-1]
|
131
|
+
end
|
132
|
+
v['recipient'] = cv[1]
|
133
|
+
v['diagnosis'] = cv[2]
|
134
|
+
|
135
|
+
if v['diagnosis'] =~ /=\z/
|
136
|
+
# Quoted printable
|
137
|
+
v['diagnosis'] = v['diagnosis'].sub(/=\z/, '')
|
138
|
+
qprintable = true
|
139
|
+
end
|
140
|
+
recipients += 1
|
141
|
+
|
142
|
+
elsif cv = e.match(/\A\[Status: .+[<]([^ ]+[@][^ ]+)[>],/)
|
143
|
+
# Expired
|
144
|
+
# [Status: Error, Address: <kijitora@6kaku.example.co.jp>, ResponseCode 421, , Host not reachable.]
|
145
|
+
if v['recipient']
|
146
|
+
# There are multiple recipient addresses in the message body.
|
147
|
+
dscontents << Sisimai::MSP.DELIVERYSTATUS
|
148
|
+
v = dscontents[-1]
|
149
|
+
end
|
150
|
+
v['recipient'] = cv[1]
|
151
|
+
v['diagnosis'] = e
|
152
|
+
recipients += 1
|
153
|
+
|
154
|
+
else
|
155
|
+
# Continued line
|
156
|
+
next unless qprintable
|
157
|
+
v['diagnosis'] ||= ''
|
158
|
+
v['diagnosis'] += e
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
return nil if recipients == 0
|
165
|
+
require 'sisimai/string'
|
166
|
+
require 'sisimai/smtp/status'
|
167
|
+
|
168
|
+
dscontents.map do |e|
|
169
|
+
if mhead['received'].size > 0
|
170
|
+
# Get localhost and remote host name from Received header.
|
171
|
+
r0 = mhead['received']
|
172
|
+
['lhost', 'rhost'].each { |a| e[a] ||= '' }
|
173
|
+
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
174
|
+
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
175
|
+
end
|
176
|
+
e['diagnosis'] = e['diagnosis'].gsub(/\\n/, ' ')
|
177
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
178
|
+
|
179
|
+
ReFailure.each_key do |r|
|
180
|
+
# Verify each regular expression of session errors
|
181
|
+
next unless e['diagnosis'] =~ ReFailure[r]
|
182
|
+
e['reason'] = r
|
183
|
+
break
|
184
|
+
end
|
185
|
+
|
186
|
+
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
187
|
+
e['spec'] ||= 'SMTP'
|
188
|
+
e['agent'] = Sisimai::MSP::US::Zoho.smtpagent
|
189
|
+
end
|
190
|
+
|
191
|
+
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
data/lib/sisimai/mta.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Sisimai
|
2
|
+
# Sisimai::MTA - Base class for Sisimai::MTA::*
|
3
|
+
module MTA
|
4
|
+
class << self
|
5
|
+
# Imported from p5-Sisimail/lib/Sisimai/MTA.pm
|
6
|
+
require 'sisimai/rfc5322'
|
7
|
+
|
8
|
+
# Flags for position variable for
|
9
|
+
# @return [Hash] Position flag data
|
10
|
+
# @private
|
11
|
+
def INDICATORS
|
12
|
+
return {
|
13
|
+
:'deliverystatus' => ( 1 << 1 ),
|
14
|
+
:'message-rfc822' => ( 1 << 2 ),
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Data structure for parsed bounce messages
|
19
|
+
# @return [Hash] Data structure for delivery status
|
20
|
+
# @private
|
21
|
+
def DELIVERYSTATUS
|
22
|
+
return {
|
23
|
+
'spec' => nil, # Protocl specification
|
24
|
+
'date' => nil, # The value of Last-Attempt-Date header
|
25
|
+
'rhost' => nil, # The value of Remote-MTA header
|
26
|
+
'lhost' => nil, # The value of Received-From-MTA header
|
27
|
+
'alias' => nil, # The value of alias entry(RHS)
|
28
|
+
'agent' => nil, # MTA name
|
29
|
+
'action' => nil, # The value of Action header
|
30
|
+
'status' => nil, # The value of Status header
|
31
|
+
'reason' => nil, # Temporary reason of bounce
|
32
|
+
'command' => nil, # SMTP command in the message body
|
33
|
+
'diagnosis' => nil, # The value of Diagnostic-Code header
|
34
|
+
'recipient' => nil, # The value of Final-Recipient header
|
35
|
+
'softbounce' => nil, # Soft bounce or not
|
36
|
+
'feedbacktype' => nil, # Feedback Type
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
# MTA list
|
41
|
+
# @return [Array] MTA list with order
|
42
|
+
def index
|
43
|
+
return [
|
44
|
+
'Sendmail', 'Postfix', 'Qmail', 'Exim', 'Courier', 'OpenSMTPD',
|
45
|
+
'Exchange', 'MessagingServer', 'Domino', 'Notes', 'ApacheJames',
|
46
|
+
'McAfee', 'MXLogic', 'MailFoundry', 'IMailServer', 'MFILTER',
|
47
|
+
'Activehunter', 'InterScanMSS', 'SurfControl', 'MailMarshalSMTP',
|
48
|
+
'X1', 'X2', 'X3', 'X4', 'X5', 'V5sendmail',
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module Sisimai
|
2
|
+
module MTA
|
3
|
+
# Sisimai::MTA::Activehunter parses a bounce email which created by TransWARE
|
4
|
+
# Active!hunter. Methods in the module are called from only Sisimai::Message.
|
5
|
+
module Activehunter
|
6
|
+
# Imported from p5-Sisimail/lib/Sisimai/MTA/Activehunter.pm
|
7
|
+
class << self
|
8
|
+
require 'sisimai/mta'
|
9
|
+
require 'sisimai/rfc5322'
|
10
|
+
|
11
|
+
Re0 = {
|
12
|
+
:from => %r/\A"MAILER-DAEMON"/,
|
13
|
+
:subject => %r/FAILURE NOTICE :/,
|
14
|
+
}
|
15
|
+
Re1 = {
|
16
|
+
:begin => %r/\A ----- The following addresses had permanent fatal errors -----\z/,
|
17
|
+
:error => %r/\A ----- Transcript of session follows -----\z/,
|
18
|
+
:rfc822 => %r|\AContent-type: message/rfc822\z|,
|
19
|
+
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
20
|
+
}
|
21
|
+
Indicators = Sisimai::MTA.INDICATORS
|
22
|
+
LongFields = Sisimai::RFC5322.LONGFIELDS
|
23
|
+
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
24
|
+
|
25
|
+
def description; return 'TransWARE Active!hunter'; end
|
26
|
+
def smtpagent; return 'Activehunter'; end
|
27
|
+
def headerlist; return ['X-AHMAILID']; end
|
28
|
+
def pattern; return Re0; end
|
29
|
+
|
30
|
+
# Parse bounce messages from TransWARE Active!hunter
|
31
|
+
# @param [Hash] mhead Message header of a bounce email
|
32
|
+
# @options mhead [String] from From header
|
33
|
+
# @options mhead [String] date Date header
|
34
|
+
# @options mhead [String] subject Subject header
|
35
|
+
# @options mhead [Array] received Received headers
|
36
|
+
# @options mhead [String] others Other required headers
|
37
|
+
# @param [String] mbody Message body of a bounce email
|
38
|
+
# @return [Hash, Nil] Bounce data list and message/rfc822
|
39
|
+
# part or nil if it failed to parse or
|
40
|
+
# the arguments are missing
|
41
|
+
def scan(mhead, mbody)
|
42
|
+
return nil unless mhead
|
43
|
+
return nil unless mbody
|
44
|
+
return nil unless mhead['x-ahmailid']
|
45
|
+
|
46
|
+
dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
|
47
|
+
hasdivided = mbody.split("\n")
|
48
|
+
rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
|
49
|
+
rfc822part = '' # (String) message/rfc822-headers part
|
50
|
+
previousfn = '' # (String) Previous field name
|
51
|
+
readcursor = 0 # (Integer) Points the current cursor position
|
52
|
+
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
53
|
+
v = nil
|
54
|
+
|
55
|
+
hasdivided.each do |e|
|
56
|
+
if readcursor == 0
|
57
|
+
# Beginning of the bounce message or delivery status part
|
58
|
+
if e =~ Re1[:begin]
|
59
|
+
readcursor |= Indicators[:'deliverystatus']
|
60
|
+
next
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
if readcursor & Indicators[:'message-rfc822'] == 0
|
65
|
+
# Beginning of the original message part
|
66
|
+
if e =~ Re1[:rfc822]
|
67
|
+
readcursor |= Indicators[:'message-rfc822']
|
68
|
+
next
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if readcursor & Indicators[:'message-rfc822'] > 0
|
73
|
+
# After "message/rfc822"
|
74
|
+
if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
|
75
|
+
# Get required headers only
|
76
|
+
lhs = cv[1].downcase
|
77
|
+
previousfn = ''
|
78
|
+
next unless RFC822Head.key?(lhs)
|
79
|
+
|
80
|
+
previousfn = lhs
|
81
|
+
rfc822part += e + "\n"
|
82
|
+
|
83
|
+
elsif e =~ /\A[ \t]+/
|
84
|
+
# Continued line from the previous line
|
85
|
+
next if rfc822next[previousfn]
|
86
|
+
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
87
|
+
|
88
|
+
else
|
89
|
+
# Check the end of headers in rfc822 part
|
90
|
+
next unless LongFields.key?(previousfn)
|
91
|
+
next unless e.empty?
|
92
|
+
rfc822next[previousfn] = true
|
93
|
+
end
|
94
|
+
|
95
|
+
else
|
96
|
+
# Before "message/rfc822"
|
97
|
+
next if readcursor & Indicators[:'deliverystatus'] == 0
|
98
|
+
next if e.empty?
|
99
|
+
|
100
|
+
# ----- The following addresses had permanent fatal errors -----
|
101
|
+
#
|
102
|
+
# >>> kijitora@example.org <kijitora@example.org>
|
103
|
+
#
|
104
|
+
# ----- Transcript of session follows -----
|
105
|
+
# 550 sorry, no mailbox here by that name (#5.1.1 - chkusr)
|
106
|
+
v = dscontents[-1]
|
107
|
+
|
108
|
+
if cv = e.match(/\A[>]{3}[ \t]+.+[<]([^ ]+?[@][^ ]+?)[>]\z/)
|
109
|
+
# >>> kijitora@example.org <kijitora@example.org>
|
110
|
+
if v['recipient']
|
111
|
+
# There are multiple recipient addresses in the message body.
|
112
|
+
dscontents << Sisimai::MTA.DELIVERYSTATUS
|
113
|
+
v = dscontents[-1]
|
114
|
+
end
|
115
|
+
v['recipient'] = cv[1]
|
116
|
+
recipients += 1
|
117
|
+
|
118
|
+
else
|
119
|
+
# ----- Transcript of session follows -----
|
120
|
+
# 550 sorry, no mailbox here by that name (#5.1.1 - chkusr)
|
121
|
+
next unless e =~ /\A[0-9A-Za-z]+/
|
122
|
+
v['diagnosis'] = e
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
return nil if recipients == 0
|
128
|
+
require 'sisimai/string'
|
129
|
+
require 'sisimai/smtp/status'
|
130
|
+
|
131
|
+
dscontents.map do |e|
|
132
|
+
if mhead['received'].size > 0
|
133
|
+
# Get localhost and remote host name from Received header.
|
134
|
+
r0 = mhead['received']
|
135
|
+
['lhost', 'rhost'].each { |a| e[a] ||= '' }
|
136
|
+
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
137
|
+
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
138
|
+
end
|
139
|
+
|
140
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
141
|
+
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
142
|
+
e['spec'] = e['reason'] == 'mailererror' ? 'X-UNIX' : 'SMTP'
|
143
|
+
e['action'] = 'failed' if e['status'] =~ /\A[45]/
|
144
|
+
e['agent'] = Sisimai::MTA::Activehunter.smtpagent
|
145
|
+
e.each_key { |a| e[a] ||= '' }
|
146
|
+
end
|
147
|
+
|
148
|
+
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
@@ -0,0 +1,194 @@
|
|
1
|
+
module Sisimai
|
2
|
+
module MTA
|
3
|
+
# Sisimai::MTA::ApacheJames parses a bounce email which created by ApacheJames.
|
4
|
+
# Methods in the module are called from only Sisimai::Message.
|
5
|
+
module ApacheJames
|
6
|
+
# Imported from p5-Sisimail/lib/Sisimai/MTA/ApacheJames.pm
|
7
|
+
class << self
|
8
|
+
require 'sisimai/mta'
|
9
|
+
require 'sisimai/rfc5322'
|
10
|
+
|
11
|
+
Re0 = {
|
12
|
+
:'subject' => %r/\A\[BOUNCE\]\z/,
|
13
|
+
:'received' => %r/JAMES SMTP Server/,
|
14
|
+
:'message-id' => %r/\d+[.]JavaMail[.].+[@]/,
|
15
|
+
}
|
16
|
+
Re1 = {
|
17
|
+
# apache-james-2.3.2/src/java/org/apache/james/transport/mailets/
|
18
|
+
# AbstractNotify.java|124: out.println("Error message below:");
|
19
|
+
# AbstractNotify.java|128: out.println("Message details:");
|
20
|
+
:begin => %r/\AContent-Disposition:[ ]inline/,
|
21
|
+
:error => %r/\AError message below:\z/,
|
22
|
+
:rfc822 => %r|\AContent-Type: message/rfc822|,
|
23
|
+
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
|
24
|
+
}
|
25
|
+
Indicators = Sisimai::MTA.INDICATORS
|
26
|
+
LongFields = Sisimai::RFC5322.LONGFIELDS
|
27
|
+
RFC822Head = Sisimai::RFC5322.HEADERFIELDS
|
28
|
+
|
29
|
+
def description; return 'Java Apache Mail Enterprise Server'; end
|
30
|
+
def smtpagent; return 'ApacheJames'; end
|
31
|
+
def headerlist; return []; end
|
32
|
+
def pattern; return Re0; end
|
33
|
+
|
34
|
+
# Parse bounce messages from Apache James
|
35
|
+
# @param [Hash] mhead Message header of a bounce email
|
36
|
+
# @options mhead [String] from From header
|
37
|
+
# @options mhead [String] date Date header
|
38
|
+
# @options mhead [String] subject Subject header
|
39
|
+
# @options mhead [Array] received Received headers
|
40
|
+
# @options mhead [String] others Other required headers
|
41
|
+
# @param [String] mbody Message body of a bounce email
|
42
|
+
# @return [Hash, Nil] Bounce data list and message/rfc822
|
43
|
+
# part or nil if it failed to parse or
|
44
|
+
# the arguments are missing
|
45
|
+
def scan(mhead, mbody)
|
46
|
+
return nil unless mhead
|
47
|
+
return nil unless mbody
|
48
|
+
|
49
|
+
match = 0
|
50
|
+
match += 1 if mhead['subject'] =~ Re0[:subject]
|
51
|
+
match += 1 if mhead['message-id'] && mhead['message-id'] =~ Re0[:'message-id']
|
52
|
+
match += 1 if mhead['received'].find { |a| a =~ Re0[:received] }
|
53
|
+
return if match == 0
|
54
|
+
|
55
|
+
dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
|
56
|
+
hasdivided = mbody.split("\n")
|
57
|
+
rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
|
58
|
+
rfc822part = '' # (String) message/rfc822-headers part
|
59
|
+
previousfn = '' # (String) Previous field name
|
60
|
+
readcursor = 0 # (Integer) Points the current cursor position
|
61
|
+
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
62
|
+
diagnostic = '' # (String) Alternative diagnostic message
|
63
|
+
subjecttxt = nil # (String) Alternative Subject text
|
64
|
+
gotmessage = -1 # (Integer) Flag for error message
|
65
|
+
v = nil
|
66
|
+
|
67
|
+
hasdivided.each do |e|
|
68
|
+
|
69
|
+
if readcursor == 0
|
70
|
+
# Beginning of the bounce message or delivery status part
|
71
|
+
if e =~ Re1[:begin]
|
72
|
+
readcursor |= Indicators[:'deliverystatus']
|
73
|
+
next
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if readcursor & Indicators[:'message-rfc822'] == 0
|
78
|
+
# Beginning of the original message part
|
79
|
+
if e =~ Re1[:rfc822]
|
80
|
+
readcursor |= Indicators[:'message-rfc822']
|
81
|
+
next
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
if readcursor & Indicators[:'message-rfc822'] > 0
|
86
|
+
# After "message/rfc822"
|
87
|
+
if cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*.+\z/)
|
88
|
+
# Get required headers only
|
89
|
+
lhs = cv[1].downcase
|
90
|
+
previousfn = ''
|
91
|
+
next unless RFC822Head.key?(lhs)
|
92
|
+
|
93
|
+
previousfn = lhs
|
94
|
+
rfc822part += e + "\n"
|
95
|
+
|
96
|
+
elsif e =~ /\A[ \t]+/
|
97
|
+
# Continued line from the previous line
|
98
|
+
next if rfc822next[previousfn]
|
99
|
+
rfc822part += e + "\n" if LongFields.key?(previousfn)
|
100
|
+
|
101
|
+
else
|
102
|
+
# Check the end of headers in rfc822 part
|
103
|
+
next unless LongFields.key?(previousfn)
|
104
|
+
next unless e.empty?
|
105
|
+
rfc822next[previousfn] = true
|
106
|
+
end
|
107
|
+
|
108
|
+
else
|
109
|
+
# Before "message/rfc822"
|
110
|
+
next if readcursor & Indicators[:'deliverystatus'] == 0
|
111
|
+
next if e.empty?
|
112
|
+
|
113
|
+
# Message details:
|
114
|
+
# Subject: Nyaaan
|
115
|
+
# Sent date: Thu Apr 29 01:20:50 JST 2015
|
116
|
+
# MAIL FROM: shironeko@example.jp
|
117
|
+
# RCPT TO: kijitora@example.org
|
118
|
+
# From: Neko <shironeko@example.jp>
|
119
|
+
# To: kijitora@example.org
|
120
|
+
# Size (in bytes): 1024
|
121
|
+
# Number of lines: 64
|
122
|
+
v = dscontents[-1]
|
123
|
+
|
124
|
+
if cv = e.match(/\A[ ][ ]RCPT[ ]TO:[ ]([^ ]+[@][^ ]+)\z/)
|
125
|
+
# RCPT TO: kijitora@example.org
|
126
|
+
if v['recipient']
|
127
|
+
# There are multiple recipient addresses in the message body.
|
128
|
+
dscontents << Sisimai::MTA.DELIVERYSTATUS
|
129
|
+
v = dscontents[-1]
|
130
|
+
end
|
131
|
+
v['recipient'] = cv[1]
|
132
|
+
recipients += 1
|
133
|
+
|
134
|
+
elsif cv = e.match(/\A[ ][ ]Sent[ ]date:[ ](.+)\z/)
|
135
|
+
# Sent date: Thu Apr 29 01:20:50 JST 2015
|
136
|
+
v['date'] = cv[1]
|
137
|
+
|
138
|
+
elsif cv = e.match(/\A[ ][ ]Subject:[ ](.+)\z/)
|
139
|
+
# Subject: Nyaaan
|
140
|
+
subjecttxt = cv[1]
|
141
|
+
|
142
|
+
else
|
143
|
+
next if gotmessage == 1
|
144
|
+
if v['diagnosis']
|
145
|
+
# Get an error message text
|
146
|
+
if e =~ /\AMessage[ ]details:\z/
|
147
|
+
# Message details:
|
148
|
+
# Subject: nyaan
|
149
|
+
# ...
|
150
|
+
gotmessage = 1
|
151
|
+
else
|
152
|
+
# Append error message text like the followng:
|
153
|
+
# Error message below:
|
154
|
+
# 550 - Requested action not taken: no such user here
|
155
|
+
v['diagnosis'] ||= ''
|
156
|
+
v['diagnosis'] += ' ' + e
|
157
|
+
end
|
158
|
+
|
159
|
+
else
|
160
|
+
# Error message below:
|
161
|
+
# 550 - Requested action not taken: no such user here
|
162
|
+
v['diagnosis'] = e if e =~ Re1[:error]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
return nil if recipients == 0
|
169
|
+
require 'sisimai/string'
|
170
|
+
require 'sisimai/smtp/status'
|
171
|
+
|
172
|
+
dscontents.map do |e|
|
173
|
+
e['agent'] = Sisimai::MTA::ApacheJames.smtpagent
|
174
|
+
|
175
|
+
if mhead['received'].size > 0
|
176
|
+
# Get localhost and remote host name from Received header.
|
177
|
+
r0 = mhead['received']
|
178
|
+
['lhost', 'rhost'].each { |a| e[a] ||= '' }
|
179
|
+
e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
|
180
|
+
e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
|
181
|
+
end
|
182
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'] || diagnostic)
|
183
|
+
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
184
|
+
e.each_key { |a| e[a] ||= '' }
|
185
|
+
end
|
186
|
+
|
187
|
+
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|