sisimai 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog.md +12 -0
- data/Makefile +3 -2
- data/README-JA.md +2 -2
- data/README.md +6 -6
- data/lib/sisimai/address.rb +45 -56
- data/lib/sisimai/arf.rb +11 -16
- data/lib/sisimai/datetime.rb +16 -50
- data/lib/sisimai/fact/json.rb +5 -5
- data/lib/sisimai/fact/yaml.rb +3 -3
- data/lib/sisimai/fact.rb +11 -12
- data/lib/sisimai/lda.rb +3 -3
- data/lib/sisimai/lhost/activehunter.rb +4 -6
- data/lib/sisimai/lhost/amazonses.rb +5 -6
- data/lib/sisimai/lhost/apachejames.rb +7 -9
- data/lib/sisimai/lhost/biglobe.rb +3 -5
- data/lib/sisimai/lhost/courier.rb +4 -6
- data/lib/sisimai/lhost/domino.rb +4 -5
- data/lib/sisimai/lhost/dragonfly.rb +3 -5
- data/lib/sisimai/lhost/einsundeins.rb +6 -8
- data/lib/sisimai/lhost/exchange2003.rb +10 -12
- data/lib/sisimai/lhost/exchange2007.rb +4 -5
- data/lib/sisimai/lhost/exim.rb +6 -8
- data/lib/sisimai/lhost/ezweb.rb +10 -12
- data/lib/sisimai/lhost/fml.rb +2 -3
- data/lib/sisimai/lhost/gmail.rb +4 -6
- data/lib/sisimai/lhost/gmx.rb +6 -8
- data/lib/sisimai/lhost/googlegroups.rb +1 -2
- data/lib/sisimai/lhost/googleworkspace.rb +3 -4
- data/lib/sisimai/lhost/imailserver.rb +6 -7
- data/lib/sisimai/lhost/interscanmss.rb +1 -2
- data/lib/sisimai/lhost/kddi.rb +5 -8
- data/lib/sisimai/lhost/mailfoundry.rb +4 -7
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +4 -6
- data/lib/sisimai/lhost/messagingserver.rb +5 -7
- data/lib/sisimai/lhost/mfilter.rb +4 -6
- data/lib/sisimai/lhost/notes.rb +7 -9
- data/lib/sisimai/lhost/opensmtpd.rb +2 -4
- data/lib/sisimai/lhost/postfix.rb +8 -11
- data/lib/sisimai/lhost/qmail.rb +5 -8
- data/lib/sisimai/lhost/sendmail.rb +7 -10
- data/lib/sisimai/lhost/v5sendmail.rb +15 -17
- data/lib/sisimai/lhost/verizon.rb +9 -14
- data/lib/sisimai/lhost/x1.rb +4 -6
- data/lib/sisimai/lhost/x2.rb +5 -7
- data/lib/sisimai/lhost/x3.rb +3 -4
- data/lib/sisimai/lhost/x6.rb +4 -6
- data/lib/sisimai/lhost/zoho.rb +6 -8
- data/lib/sisimai/lhost.rb +1 -1
- data/lib/sisimai/mail/mbox.rb +1 -1
- data/lib/sisimai/mail/memory.rb +1 -1
- data/lib/sisimai/mail.rb +8 -8
- data/lib/sisimai/message.rb +11 -13
- data/lib/sisimai/reason/authfailure.rb +10 -10
- data/lib/sisimai/reason/badreputation.rb +4 -6
- data/lib/sisimai/reason/blocked.rb +6 -8
- data/lib/sisimai/reason/contenterror.rb +5 -6
- data/lib/sisimai/reason/delivered.rb +2 -2
- data/lib/sisimai/reason/exceedlimit.rb +7 -8
- data/lib/sisimai/reason/expired.rb +6 -7
- data/lib/sisimai/reason/failedstarttls.rb +5 -7
- data/lib/sisimai/reason/feedback.rb +2 -2
- data/lib/sisimai/reason/filtered.rb +7 -10
- data/lib/sisimai/reason/hasmoved.rb +4 -5
- data/lib/sisimai/reason/hostunknown.rb +6 -7
- data/lib/sisimai/reason/mailboxfull.rb +7 -8
- data/lib/sisimai/reason/mailererror.rb +5 -8
- data/lib/sisimai/reason/mesgtoobig.rb +5 -6
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +4 -5
- data/lib/sisimai/reason/notaccept.rb +5 -8
- data/lib/sisimai/reason/notcompliantrfc.rb +5 -6
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +6 -9
- data/lib/sisimai/reason/rejected.rb +5 -6
- data/lib/sisimai/reason/requireptr.rb +6 -7
- data/lib/sisimai/reason/securityerror.rb +6 -9
- data/lib/sisimai/reason/spamdetected.rb +8 -9
- data/lib/sisimai/reason/speeding.rb +6 -7
- data/lib/sisimai/reason/suppressed.rb +3 -7
- data/lib/sisimai/reason/suspend.rb +5 -7
- data/lib/sisimai/reason/syntaxerror.rb +3 -5
- data/lib/sisimai/reason/systemerror.rb +6 -9
- data/lib/sisimai/reason/systemfull.rb +5 -8
- data/lib/sisimai/reason/toomanyconn.rb +5 -6
- data/lib/sisimai/reason/undefined.rb +2 -2
- data/lib/sisimai/reason/userunknown.rb +8 -9
- data/lib/sisimai/reason/vacation.rb +4 -5
- data/lib/sisimai/reason/virusdetected.rb +4 -5
- data/lib/sisimai/reason.rb +13 -13
- data/lib/sisimai/rfc1123.rb +4 -8
- data/lib/sisimai/rfc1894.rb +5 -6
- data/lib/sisimai/rfc2045.rb +27 -31
- data/lib/sisimai/rfc3464/thirdparty.rb +1 -1
- data/lib/sisimai/rfc3464.rb +7 -9
- data/lib/sisimai/rfc3834.rb +5 -9
- data/lib/sisimai/rfc5322.rb +8 -26
- data/lib/sisimai/rfc791.rb +6 -4
- data/lib/sisimai/rhost/google.rb +8 -0
- data/lib/sisimai/rhost/microsoft.rb +17 -5
- data/lib/sisimai/rhost.rb +2 -2
- data/lib/sisimai/smtp/command.rb +1 -1
- data/lib/sisimai/smtp/failure.rb +5 -12
- data/lib/sisimai/smtp/reply.rb +3 -5
- data/lib/sisimai/smtp/status.rb +14 -24
- data/lib/sisimai/smtp/transcript.rb +1 -10
- data/lib/sisimai/string.rb +20 -30
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +11 -11
- data/set-of-emails/maildir/bsd/rhost-microsoft-06.eml +45 -0
- metadata +3 -2
    
        data/lib/sisimai/fact/yaml.rb
    CHANGED
    
    | @@ -10,8 +10,8 @@ module Sisimai | |
| 10 10 | 
             
                    # @param    [Sisimai::Fact] argvs Object
         | 
| 11 11 | 
             
                    # @return   [String, nil]         Dumped data or nil if the argument is missing
         | 
| 12 12 | 
             
                    def dump(argvs)
         | 
| 13 | 
            -
                      return  | 
| 14 | 
            -
                      return  | 
| 13 | 
            +
                      return "" unless argvs
         | 
| 14 | 
            +
                      return "" unless argvs.is_a? Sisimai::Fact
         | 
| 15 15 |  | 
| 16 16 | 
             
                      damneddata = argvs.damn
         | 
| 17 17 | 
             
                      yamlstring = nil
         | 
| @@ -19,7 +19,7 @@ module Sisimai | |
| 19 19 | 
             
                      begin
         | 
| 20 20 | 
             
                        yamlstring = ::YAML.dump(damneddata)
         | 
| 21 21 | 
             
                      rescue StandardError => ce
         | 
| 22 | 
            -
                        warn '***warning: Failed to YAML.dump: '  | 
| 22 | 
            +
                        warn '***warning: Failed to YAML.dump: ' + ce.to_s
         | 
| 23 23 | 
             
                      end
         | 
| 24 24 |  | 
| 25 25 | 
             
                      return yamlstring
         | 
    
        data/lib/sisimai/fact.rb
    CHANGED
    
    | @@ -48,7 +48,7 @@ module Sisimai | |
| 48 48 |  | 
| 49 49 | 
             
                RetryIndex = Sisimai::Reason.retry
         | 
| 50 50 | 
             
                RFC822Head = Sisimai::RFC5322.HEADERTABLE
         | 
| 51 | 
            -
                ActionList = { | 
| 51 | 
            +
                ActionList = {delayed: 1, delivered: 1, expanded: 1, failed: 1, relayed: 1};
         | 
| 52 52 |  | 
| 53 53 | 
             
                if RUBY_PLATFORM.start_with?('java')
         | 
| 54 54 | 
             
                  # [WORKAROUND] #159 #267 JRuby seems to fail and throws exception at strptime(), but this
         | 
| @@ -108,7 +108,7 @@ module Sisimai | |
| 108 108 | 
             
                  return nil unless argvs.is_a? Hash
         | 
| 109 109 |  | 
| 110 110 | 
             
                  email = argvs[:data]; return nil unless email
         | 
| 111 | 
            -
                  args1 = { | 
| 111 | 
            +
                  args1 = {data: email, hook: argvs[:hook]}
         | 
| 112 112 | 
             
                  mesg1 = Sisimai::Message.rise(**args1)
         | 
| 113 113 | 
             
                  return nil unless mesg1
         | 
| 114 114 | 
             
                  return nil unless mesg1['ds']
         | 
| @@ -179,7 +179,7 @@ module Sisimai | |
| 179 179 | 
             
                    datevalues << mesg1['header']['date'] if datevalues.size < 2
         | 
| 180 180 | 
             
                    while v = datevalues.shift do
         | 
| 181 181 | 
             
                      # Parse each date value in the array
         | 
| 182 | 
            -
                      datestring = Sisimai::DateTime.parse(v)  | 
| 182 | 
            +
                      datestring = Sisimai::DateTime.parse(v); next if datestring.empty?
         | 
| 183 183 |  | 
| 184 184 | 
             
                      if cv = datestring.match(/\A(.+)[ ]+([-+]\d{4})\z/)
         | 
| 185 185 | 
             
                        # Get the value of timezone offset from datestring: Wed, 26 Feb 2014 06:05:48 -0500
         | 
| @@ -195,7 +195,7 @@ module Sisimai | |
| 195 195 | 
             
                      t = TimeModule.strptime(datestring, '%a, %d %b %Y %T')
         | 
| 196 196 | 
             
                      piece['timestamp'] = (t.to_time.to_i - zoneoffset) || nil
         | 
| 197 197 | 
             
                    rescue
         | 
| 198 | 
            -
                      warn  | 
| 198 | 
            +
                      warn " ***warning: Failed to strptime #{datestring.to_s}"
         | 
| 199 199 | 
             
                    end
         | 
| 200 200 | 
             
                    next unless piece['timestamp']
         | 
| 201 201 |  | 
| @@ -402,8 +402,7 @@ module Sisimai | |
| 402 402 | 
             
                        next unless er.include?(' for ')
         | 
| 403 403 |  | 
| 404 404 | 
             
                        af = Sisimai::RFC5322.received(er)
         | 
| 405 | 
            -
                        next if af.empty?
         | 
| 406 | 
            -
                        next if af[5].empty?
         | 
| 405 | 
            +
                        next if af.empty? || af[5].empty?
         | 
| 407 406 | 
             
                        next unless Sisimai::Address.is_emailaddress(af[5])
         | 
| 408 407 | 
             
                        next if thing['recipient'].address == af[5]
         | 
| 409 408 |  | 
| @@ -434,14 +433,14 @@ module Sisimai | |
| 434 433 | 
             
                      thing['replycode'] = '' unless thing['reason'] == 'delivered'
         | 
| 435 434 | 
             
                    else
         | 
| 436 435 | 
             
                      # The reason is not "delivered", or "feedback", or "vacation"
         | 
| 437 | 
            -
                      smtperrors = piece['deliverystatus']  | 
| 436 | 
            +
                      smtperrors = "#{piece['deliverystatus']} #{piece['diagnosticcode']}"
         | 
| 438 437 | 
             
                      smtperrors = '' if smtperrors.size < 4
         | 
| 439 438 | 
             
                      thing['hardbounce'] = Sisimai::SMTP::Failure.is_hardbounce(thing['reason'], smtperrors)
         | 
| 440 439 | 
             
                    end
         | 
| 441 440 |  | 
| 442 441 | 
             
                    # DELIVERYSTATUS: Set a pseudo status code if the value of "deliverystatus" is empty
         | 
| 443 442 | 
             
                    if thing['deliverystatus'].empty?
         | 
| 444 | 
            -
                      smtperrors = piece['replycode']  | 
| 443 | 
            +
                      smtperrors = "#{piece['replycode']} #{piece['diagnosticcode']}"
         | 
| 445 444 | 
             
                      smtperrors = '' if smtperrors.size < 4
         | 
| 446 445 | 
             
                      permanent0 = Sisimai::SMTP::Failure.is_permanent(smtperrors)
         | 
| 447 446 | 
             
                      temporary0 = Sisimai::SMTP::Failure.is_temporary(smtperrors)
         | 
| @@ -459,7 +458,7 @@ module Sisimai | |
| 459 458 |  | 
| 460 459 | 
             
                    unless ActionList.has_key?(thing['action'])
         | 
| 461 460 | 
             
                      # There is an action value which is not described at RFC1894
         | 
| 462 | 
            -
                      if ox = Sisimai::RFC1894.field( | 
| 461 | 
            +
                      if ox = Sisimai::RFC1894.field("Action: #{thing['action']}")
         | 
| 463 462 | 
             
                        # Rewrite the value of "Action:" field to the valid value
         | 
| 464 463 | 
             
                        #
         | 
| 465 464 | 
             
                        #    The syntax for the action-field is:
         | 
| @@ -509,7 +508,7 @@ module Sisimai | |
| 509 508 | 
             
                    v['recipient']  = self.recipient.address
         | 
| 510 509 | 
             
                    v['timestamp']  = self.timestamp.to_time.to_i
         | 
| 511 510 |  | 
| 512 | 
            -
                    # Backward compatibility until v5. | 
| 511 | 
            +
                    # Backward compatibility until v5.5.0
         | 
| 513 512 | 
             
                    v["smtpagent"] = self.decodedby
         | 
| 514 513 | 
             
                    v["smtpcommand"] = self.command
         | 
| 515 514 | 
             
                    data = v
         | 
| @@ -526,12 +525,12 @@ module Sisimai | |
| 526 525 | 
             
                #           [Nil]           The value of the first argument is neither "json" nor "yaml"
         | 
| 527 526 | 
             
                def dump(type = 'json')
         | 
| 528 527 | 
             
                  return nil unless %w[json yaml].include?(type)
         | 
| 529 | 
            -
                  referclass =  | 
| 528 | 
            +
                  referclass = "Sisimai::Fact::#{type.upcase}"
         | 
| 530 529 |  | 
| 531 530 | 
             
                  begin
         | 
| 532 531 | 
             
                    require referclass.downcase.gsub('::', '/')
         | 
| 533 532 | 
             
                  rescue
         | 
| 534 | 
            -
                    warn  | 
| 533 | 
            +
                    warn "***warning: Failed to load #{referclass}"
         | 
| 535 534 | 
             
                  end
         | 
| 536 535 |  | 
| 537 536 | 
             
                  dumpeddata = Module.const_get(referclass).dump(self)
         | 
    
        data/lib/sisimai/lda.rb
    CHANGED
    
    | @@ -68,9 +68,9 @@ module Sisimai | |
| 68 68 | 
             
                  # @param  [Sisimai::Fact] argvs Decoded email object
         | 
| 69 69 | 
             
                  # @return [String]        Bounce reason
         | 
| 70 70 | 
             
                  def find(argvs)
         | 
| 71 | 
            -
                    return  | 
| 72 | 
            -
                    return "" | 
| 73 | 
            -
                    return "" | 
| 71 | 
            +
                    return "" if argvs.nil?
         | 
| 72 | 
            +
                    return "" if argvs["diagnosticcode"].empty?
         | 
| 73 | 
            +
                    return "" if argvs["command"] != "" && argvs["command"] != "DATA"
         | 
| 74 74 |  | 
| 75 75 | 
             
                    deliversby = ""   # [String] Local Delivery Agent name
         | 
| 76 76 | 
             
                    reasontext = ""   # [String] Error reason
         | 
| @@ -8,7 +8,7 @@ module Sisimai::Lhost | |
| 8 8 |  | 
| 9 9 | 
             
                  Indicators = Sisimai::Lhost.INDICATORS
         | 
| 10 10 | 
             
                  Boundaries = ['Content-Type: message/rfc822'].freeze
         | 
| 11 | 
            -
                  StartingOf = { | 
| 11 | 
            +
                  StartingOf = {message: ['  ----- The following addresses had permanent fatal errors -----']}.freeze
         | 
| 12 12 |  | 
| 13 13 | 
             
                  # @abstract decodes the bounce message from QUALITIA Active!hunter
         | 
| 14 14 | 
             
                  # @param  [Hash] mhead    Message headers of a bounce email
         | 
| @@ -20,12 +20,11 @@ module Sisimai::Lhost | |
| 20 20 | 
             
                    # :subject => %r/FAILURE NOTICE :/,
         | 
| 21 21 | 
             
                    return nil unless mhead['x-ahmailid']
         | 
| 22 22 |  | 
| 23 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 23 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 24 24 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 25 25 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 26 26 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 27 27 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 28 | 
            -
                    v = nil
         | 
| 29 28 |  | 
| 30 29 | 
             
                    while e = bodyslices.shift do
         | 
| 31 30 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -35,8 +34,7 @@ module Sisimai::Lhost | |
| 35 34 | 
             
                        readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
         | 
| 36 35 | 
             
                        next
         | 
| 37 36 | 
             
                      end
         | 
| 38 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 39 | 
            -
                      next if e.empty?
         | 
| 37 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 40 38 |  | 
| 41 39 | 
             
                      #  ----- The following addresses had permanent fatal errors -----
         | 
| 42 40 | 
             
                      #
         | 
| @@ -68,7 +66,7 @@ module Sisimai::Lhost | |
| 68 66 | 
             
                    return nil unless recipients > 0
         | 
| 69 67 |  | 
| 70 68 | 
             
                    dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
         | 
| 71 | 
            -
                    return { | 
| 69 | 
            +
                    return {"ds" => dscontents, "rfc822" => emailparts[1]}
         | 
| 72 70 | 
             
                  end
         | 
| 73 71 | 
             
                  def description; return 'TransWARE Active!hunter'; end
         | 
| 74 72 | 
             
                end
         | 
| @@ -111,7 +111,7 @@ module Sisimai::Lhost | |
| 111 111 | 
             
                      end
         | 
| 112 112 | 
             
                    rescue StandardError => ce
         | 
| 113 113 | 
             
                      # Something wrong in decoding JSON
         | 
| 114 | 
            -
                      warn  | 
| 114 | 
            +
                      warn " ***warning: Failed to decode JSON: #{ce.to_s}"
         | 
| 115 115 | 
             
                      return nil
         | 
| 116 116 | 
             
                    end
         | 
| 117 117 | 
             
                    return nil if jsonobject.has_key?("notificationType") == false
         | 
| @@ -121,10 +121,9 @@ module Sisimai::Lhost | |
| 121 121 | 
             
                    require "sisimai/smtp/reply"
         | 
| 122 122 | 
             
                    require "sisimai/smtp/status"
         | 
| 123 123 | 
             
                    require "sisimai/smtp/command"
         | 
| 124 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 124 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = dscontents[-1]
         | 
| 125 125 | 
             
                    recipients = 0  # (Integer) The number of 'Final-Recipient' header
         | 
| 126 126 | 
             
                    whatnotify = jsonobject["notificationType"][0, 1] || ""
         | 
| 127 | 
            -
                    v          = dscontents[-1]
         | 
| 128 127 |  | 
| 129 128 | 
             
                    if whatnotify == "B"
         | 
| 130 129 | 
             
                      # "notificationType":"Bounce"
         | 
| @@ -207,13 +206,13 @@ module Sisimai::Lhost | |
| 207 206 |  | 
| 208 207 | 
             
                    cv = ""
         | 
| 209 208 | 
             
                    jsonobject["mail"]["headers"].each do |e|
         | 
| 210 | 
            -
                      cv  | 
| 209 | 
            +
                      cv += sprintf("%s: %s\n", e["name"], e["value"])
         | 
| 211 210 | 
             
                    end
         | 
| 212 211 | 
             
                    %w[date subject].each do |e|
         | 
| 213 212 | 
             
                      next if jsonobject["mail"]["commonHeaders"].has_key?(e) == false
         | 
| 214 | 
            -
                      cv  | 
| 213 | 
            +
                      cv += sprintf("%s: %s\n", e.capitalize, jsonobject["mail"]["commonHeaders"][e])
         | 
| 215 214 | 
             
                    end
         | 
| 216 | 
            -
                    return { | 
| 215 | 
            +
                    return {"ds" => dscontents, "rfc822" => cv}
         | 
| 217 216 | 
             
                  end
         | 
| 218 217 | 
             
                  def description; return 'Amazon SES(Sending): https://aws.amazon.com/ses/'; end
         | 
| 219 218 | 
             
                end
         | 
| @@ -26,13 +26,12 @@ module Sisimai::Lhost | |
| 26 26 | 
             
                    match += 1 if mhead["received"].any? { |a| a.include?("JAMES SMTP Server") }
         | 
| 27 27 | 
             
                    return nil unless match > 0
         | 
| 28 28 |  | 
| 29 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 29 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = dscontents[-1]
         | 
| 30 30 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 31 31 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 32 32 | 
             
                    readcursor = 0                # Points the current cursor position
         | 
| 33 33 | 
             
                    recipients = 0                # The number of 'Final-Recipient' header
         | 
| 34 34 | 
             
                    alternates = ["", "", "", ""] # [Envelope-From, Header-From, Date, Subject]
         | 
| 35 | 
            -
                    v          = dscontents[-1]
         | 
| 36 35 |  | 
| 37 36 | 
             
                    while e = bodyslices.shift do
         | 
| 38 37 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -45,11 +44,10 @@ module Sisimai::Lhost | |
| 45 44 | 
             
                          readcursor |= Indicators[:deliverystatus]
         | 
| 46 45 | 
             
                          next
         | 
| 47 46 | 
             
                        end
         | 
| 48 | 
            -
                        v["diagnosis"]  | 
| 47 | 
            +
                        v["diagnosis"] += "#{e }" if e != ""
         | 
| 49 48 | 
             
                        next
         | 
| 50 49 | 
             
                      end
         | 
| 51 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 52 | 
            -
                      next if e.empty?
         | 
| 50 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 53 51 |  | 
| 54 52 | 
             
                      # Message details:
         | 
| 55 53 | 
             
                      #   Subject: Nyaaan
         | 
| @@ -93,16 +91,16 @@ module Sisimai::Lhost | |
| 93 91 |  | 
| 94 92 | 
             
                    if emailparts[1].empty?
         | 
| 95 93 | 
             
                      # The original message is empty
         | 
| 96 | 
            -
                      emailparts[1]  | 
| 97 | 
            -
                      emailparts[1]  | 
| 94 | 
            +
                      emailparts[1] += sprintf("From: %s\n", alternates[1]) if alternates[1] != ""
         | 
| 95 | 
            +
                      emailparts[1] += sprintf("Date: %s\n", alternates[2]) if alternates[2] != ""
         | 
| 98 96 | 
             
                    end
         | 
| 99 97 | 
             
                    if emailparts[1].include?("Return-Path: ") == false
         | 
| 100 98 | 
             
                      # Set the envelope from address as a Return-Path: header
         | 
| 101 | 
            -
                      emailparts[1]  | 
| 99 | 
            +
                      emailparts[1] += sprintf("Return-Path: <%s>\n", alternates[0]) if alternates[0] != ""
         | 
| 102 100 | 
             
                    end
         | 
| 103 101 | 
             
                    if emailparts[1].include?("\nSubject: ") == false
         | 
| 104 102 | 
             
                      # Set the envelope from address as a Return-Path: header
         | 
| 105 | 
            -
                      emailparts[1]  | 
| 103 | 
            +
                      emailparts[1] += sprintf("Subject: %s\n", alternates[3]) if alternates[3] != ""
         | 
| 106 104 | 
             
                    end
         | 
| 107 105 |  | 
| 108 106 | 
             
                    dscontents.each { |e| e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"]) }
         | 
| @@ -26,12 +26,11 @@ module Sisimai::Lhost | |
| 26 26 | 
             
                    return nil unless %w[biglobe inacatv tmtv ttv].any? { |a| mhead['from'].include?('@' + a + '.ne.jp') }
         | 
| 27 27 | 
             
                    return nil unless mhead['subject'].start_with?('Returned mail:')
         | 
| 28 28 |  | 
| 29 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 29 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 30 30 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 31 31 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 32 32 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 33 33 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 34 | 
            -
                    v = nil
         | 
| 35 34 |  | 
| 36 35 | 
             
                    while e = bodyslices.shift do
         | 
| 37 36 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -41,8 +40,7 @@ module Sisimai::Lhost | |
| 41 40 | 
             
                        readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
         | 
| 42 41 | 
             
                        next
         | 
| 43 42 | 
             
                      end
         | 
| 44 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 45 | 
            -
                      next if e.empty?
         | 
| 43 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 46 44 |  | 
| 47 45 | 
             
                      # This is a MIME-encapsulated message.
         | 
| 48 46 | 
             
                      #
         | 
| @@ -74,7 +72,7 @@ module Sisimai::Lhost | |
| 74 72 | 
             
                        recipients += 1
         | 
| 75 73 | 
             
                      else
         | 
| 76 74 | 
             
                        next if e.include?('--')
         | 
| 77 | 
            -
                        v['diagnosis']  | 
| 75 | 
            +
                        v['diagnosis'] += "#{e }"
         | 
| 78 76 | 
             
                      end
         | 
| 79 77 | 
             
                    end
         | 
| 80 78 | 
             
                    return nil unless recipients > 0
         | 
| @@ -44,14 +44,13 @@ module Sisimai::Lhost | |
| 44 44 | 
             
                    fieldtable = Sisimai::RFC1894.FIELDTABLE
         | 
| 45 45 | 
             
                    permessage = {}     # (Hash) Store values of each Per-Message field
         | 
| 46 46 |  | 
| 47 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 47 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 48 48 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 49 49 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 50 50 | 
             
                    readslices = ['']
         | 
| 51 51 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 52 52 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 53 53 | 
             
                    thecommand = ''     # (String) SMTP Command name begin with the string '>>>'
         | 
| 54 | 
            -
                    v = nil
         | 
| 55 54 |  | 
| 56 55 | 
             
                    while e = bodyslices.shift do
         | 
| 57 56 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -65,8 +64,7 @@ module Sisimai::Lhost | |
| 65 64 | 
             
                          next
         | 
| 66 65 | 
             
                        end
         | 
| 67 66 | 
             
                      end
         | 
| 68 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 69 | 
            -
                      next if e.empty?
         | 
| 67 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 70 68 |  | 
| 71 69 | 
             
                      f = Sisimai::RFC1894.match(e)
         | 
| 72 70 | 
             
                      if f > 0
         | 
| @@ -118,8 +116,8 @@ module Sisimai::Lhost | |
| 118 116 | 
             
                          # Continued line of the value of Diagnostic-Code field
         | 
| 119 117 | 
             
                          next unless readslices[-2].start_with?('Diagnostic-Code:')
         | 
| 120 118 | 
             
                          next unless e.start_with?(' ')
         | 
| 121 | 
            -
                          v['diagnosis']  | 
| 122 | 
            -
                          readslices[-1] | 
| 119 | 
            +
                          v['diagnosis'] += " #{Sisimai::String.sweep(e)}"
         | 
| 120 | 
            +
                          readslices[-1]  = "Diagnostic-Code: #{e}"
         | 
| 123 121 | 
             
                        end
         | 
| 124 122 | 
             
                      end
         | 
| 125 123 | 
             
                    end
         | 
    
        data/lib/sisimai/lhost/domino.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ module Sisimai::Lhost | |
| 7 7 |  | 
| 8 8 | 
             
                  Indicators = Sisimai::Lhost.INDICATORS
         | 
| 9 9 | 
             
                  Boundaries = ['Content-Type: message/rfc822'].freeze
         | 
| 10 | 
            -
                  StartingOf = { | 
| 10 | 
            +
                  StartingOf = {message: ['Your message']}.freeze
         | 
| 11 11 | 
             
                  MessagesOf = {
         | 
| 12 12 | 
             
                    "filtered"    => ["Cannot route mail to user"],
         | 
| 13 13 | 
             
                    "systemerror" => ["Several matches found in Domino Directory"],
         | 
| @@ -33,13 +33,12 @@ module Sisimai::Lhost | |
| 33 33 | 
             
                    fieldtable = Sisimai::RFC1894.FIELDTABLE
         | 
| 34 34 | 
             
                    permessage = {}     # (Hash) Store values of each Per-Message field
         | 
| 35 35 |  | 
| 36 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 36 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 37 37 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 38 38 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 39 39 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 40 40 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 41 41 | 
             
                    subjecttxt = ''     # (String) The value of Subject:
         | 
| 42 | 
            -
                    v = nil
         | 
| 43 42 |  | 
| 44 43 | 
             
                    while e = bodyslices.shift do
         | 
| 45 44 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -135,9 +134,9 @@ module Sisimai::Lhost | |
| 135 134 | 
             
                    end
         | 
| 136 135 |  | 
| 137 136 | 
             
                    # Set the value of subjecttxt as a Subject if there is no original message in the bounce mail.
         | 
| 138 | 
            -
                    emailparts[1]  | 
| 137 | 
            +
                    emailparts[1] += "Subject: #{subjecttxt}\n" unless emailparts[1].include?("\nSubject:")
         | 
| 139 138 |  | 
| 140 | 
            -
                    return { | 
| 139 | 
            +
                    return {"ds" => dscontents, "rfc822" => emailparts[1]}
         | 
| 141 140 | 
             
                  end
         | 
| 142 141 | 
             
                  def description; return 'IBM Domino Server'; end
         | 
| 143 142 | 
             
                end
         | 
| @@ -41,12 +41,11 @@ module Sisimai::Lhost | |
| 41 41 | 
             
                    return nil unless mhead['subject'].start_with?('Mail delivery failed')
         | 
| 42 42 | 
             
                    return nil unless mhead['received'].any? { |a| a.include?(' (DragonFly Mail Agent') }
         | 
| 43 43 |  | 
| 44 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 44 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 45 45 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 46 46 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 47 47 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 48 48 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 49 | 
            -
                    v = nil
         | 
| 50 49 |  | 
| 51 50 | 
             
                    while e = bodyslices.shift do
         | 
| 52 51 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -56,8 +55,7 @@ module Sisimai::Lhost | |
| 56 55 | 
             
                        readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
         | 
| 57 56 | 
             
                        next
         | 
| 58 57 | 
             
                      end
         | 
| 59 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 60 | 
            -
                      next if e.empty?
         | 
| 58 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 61 59 |  | 
| 62 60 | 
             
                      # This is the DragonFly Mail Agent v0.13 at df.example.jp.
         | 
| 63 61 | 
             
                      #
         | 
| @@ -81,7 +79,7 @@ module Sisimai::Lhost | |
| 81 79 | 
             
                        recipients += 1
         | 
| 82 80 | 
             
                      else
         | 
| 83 81 | 
             
                        # Pick the error message
         | 
| 84 | 
            -
                        v['diagnosis']  | 
| 82 | 
            +
                        v['diagnosis'] += " #{e}"
         | 
| 85 83 |  | 
| 86 84 | 
             
                        # Pick the remote hostname, and the SMTP command
         | 
| 87 85 | 
             
                        # net.c:500| snprintf(errmsg, sizeof(errmsg), "%s [%s] did not like our %s:\n%s",
         | 
| @@ -11,7 +11,7 @@ module Sisimai::Lhost | |
| 11 11 | 
             
                    message: ['This message was created automatically by mail delivery software'],
         | 
| 12 12 | 
             
                    error:   ['For the following reason:'],
         | 
| 13 13 | 
             
                  }.freeze
         | 
| 14 | 
            -
                  MessagesOf = { | 
| 14 | 
            +
                  MessagesOf = {'mesgtoobig' => ['Mail size limit exceeded']}.freeze
         | 
| 15 15 |  | 
| 16 16 | 
             
                  # @abstract Decode the bounce message from 1&1
         | 
| 17 17 | 
             
                  # @param  [Hash] mhead    Message headers of a bounce email
         | 
| @@ -22,12 +22,11 @@ module Sisimai::Lhost | |
| 22 22 | 
             
                    return nil unless mhead['from'].start_with?('"Mail Delivery System"')
         | 
| 23 23 | 
             
                    return nil unless mhead['subject'] == 'Mail delivery failed: returning message to sender'
         | 
| 24 24 |  | 
| 25 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 25 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 26 26 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 27 27 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 28 28 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 29 29 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 30 | 
            -
                    v = nil
         | 
| 31 30 |  | 
| 32 31 | 
             
                    while e = bodyslices.shift do
         | 
| 33 32 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -38,8 +37,7 @@ module Sisimai::Lhost | |
| 38 37 | 
             
                        readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
         | 
| 39 38 | 
             
                        next
         | 
| 40 39 | 
             
                      end
         | 
| 41 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 42 | 
            -
                      next if e.empty?
         | 
| 40 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 43 41 |  | 
| 44 42 | 
             
                      # The following address failed:
         | 
| 45 43 | 
             
                      #
         | 
| @@ -68,13 +66,13 @@ module Sisimai::Lhost | |
| 68 66 | 
             
                      else
         | 
| 69 67 | 
             
                        if v['diagnosis']
         | 
| 70 68 | 
             
                          # Get error message and append error message strings
         | 
| 71 | 
            -
                          v['diagnosis']  | 
| 69 | 
            +
                          v['diagnosis'] += " #{e}"
         | 
| 72 70 | 
             
                        else
         | 
| 73 71 | 
             
                          # OR the following format:
         | 
| 74 72 | 
             
                          #   neko@example.fr:
         | 
| 75 73 | 
             
                          #   SMTP error from remote server for TEXT command, host: ...
         | 
| 76 74 | 
             
                          v['alterrors'] ||= ''
         | 
| 77 | 
            -
                          v['alterrors']  | 
| 75 | 
            +
                          v['alterrors']  += " #{e}"
         | 
| 78 76 | 
             
                        end
         | 
| 79 77 | 
             
                      end
         | 
| 80 78 | 
             
                    end
         | 
| @@ -110,7 +108,7 @@ module Sisimai::Lhost | |
| 110 108 | 
             
                      end
         | 
| 111 109 | 
             
                    end
         | 
| 112 110 |  | 
| 113 | 
            -
                    return { | 
| 111 | 
            +
                    return {"ds" => dscontents, "rfc822" => emailparts[1]}
         | 
| 114 112 | 
             
                  end
         | 
| 115 113 | 
             
                  def description; return '1&1: https://www.1und1.de'; end
         | 
| 116 114 | 
             
                end
         | 
| @@ -83,7 +83,7 @@ module Sisimai::Lhost | |
| 83 83 | 
             
                    end
         | 
| 84 84 | 
             
                    return nil unless match > 0
         | 
| 85 85 |  | 
| 86 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 86 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 87 87 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 88 88 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 89 89 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| @@ -95,7 +95,6 @@ module Sisimai::Lhost | |
| 95 95 | 
             
                      'date'    => '',  # The value of "Date"
         | 
| 96 96 | 
             
                      'subject' => '',  # The value of "Subject"
         | 
| 97 97 | 
             
                    }
         | 
| 98 | 
            -
                    v = nil
         | 
| 99 98 |  | 
| 100 99 | 
             
                    while e = bodyslices.shift do
         | 
| 101 100 | 
             
                      # Read error messages and delivery status lines from the head of the email to the previous
         | 
| @@ -105,8 +104,7 @@ module Sisimai::Lhost | |
| 105 104 | 
             
                        readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
         | 
| 106 105 | 
             
                        next
         | 
| 107 106 | 
             
                      end
         | 
| 108 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 109 | 
            -
                      next if statuspart
         | 
| 107 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || statuspart == true
         | 
| 110 108 |  | 
| 111 109 | 
             
                      if connvalues == connheader.keys.size
         | 
| 112 110 | 
             
                        # did not reach the following recipient(s):
         | 
| @@ -139,18 +137,18 @@ module Sisimai::Lhost | |
| 139 137 |  | 
| 140 138 | 
             
                        elsif e.start_with?(' ') && e.include?('MSEXCH:')
         | 
| 141 139 | 
             
                          #     MSEXCH:IMS:KIJITORA CAT:EXAMPLE:EXCHANGE 0 (000C05A6) Unknown Recipient
         | 
| 142 | 
            -
                          v['diagnosis']  | 
| 140 | 
            +
                          v['diagnosis'] += e[e.index('MSEXCH:'), e.size]
         | 
| 143 141 | 
             
                        else
         | 
| 144 142 | 
             
                          next if v['msexch']
         | 
| 145 143 | 
             
                          if v['diagnosis'].start_with?('MSEXCH:')
         | 
| 146 144 | 
             
                            # Continued from MEEXCH in the previous line
         | 
| 147 145 | 
             
                            v['msexch'] = true
         | 
| 148 | 
            -
                            v['diagnosis']  | 
| 146 | 
            +
                            v['diagnosis'] += " #{e}"
         | 
| 149 147 | 
             
                            statuspart = true
         | 
| 150 148 | 
             
                          else
         | 
| 151 149 | 
             
                            # Error message in the body part
         | 
| 152 150 | 
             
                            v['alterrors'] ||= ''
         | 
| 153 | 
            -
                            v['alterrors']  | 
| 151 | 
            +
                            v['alterrors'] += " #{e}"
         | 
| 154 152 | 
             
                          end
         | 
| 155 153 | 
             
                        end
         | 
| 156 154 | 
             
                      else
         | 
| @@ -197,7 +195,7 @@ module Sisimai::Lhost | |
| 197 195 | 
             
                          # Find captured code from the error code table
         | 
| 198 196 | 
             
                          next unless ErrorCodes[r].index(capturedcode)
         | 
| 199 197 | 
             
                          e['reason'] = r
         | 
| 200 | 
            -
                          e['status'] = Sisimai::SMTP::Status.code(r) | 
| 198 | 
            +
                          e['status'] = Sisimai::SMTP::Status.code(r)
         | 
| 201 199 | 
             
                          break
         | 
| 202 200 | 
             
                        end
         | 
| 203 201 | 
             
                        e['diagnosis'] = errormessage
         | 
| @@ -208,7 +206,7 @@ module Sisimai::Lhost | |
| 208 206 | 
             
                        next if e["alterrors"].empty?
         | 
| 209 207 |  | 
| 210 208 | 
             
                        # Copy alternative error message
         | 
| 211 | 
            -
                        e['diagnosis'] = e['alterrors']  | 
| 209 | 
            +
                        e['diagnosis'] = "#{e['alterrors']} #{e['diagnosis']}"
         | 
| 212 210 | 
             
                        e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
         | 
| 213 211 | 
             
                        e.delete('alterrors')
         | 
| 214 212 | 
             
                      end
         | 
| @@ -216,9 +214,9 @@ module Sisimai::Lhost | |
| 216 214 |  | 
| 217 215 | 
             
                    if emailparts[1].empty?
         | 
| 218 216 | 
             
                      # When original message does not included in the bounce message
         | 
| 219 | 
            -
                      emailparts[1]  | 
| 220 | 
            -
                      emailparts[1]  | 
| 221 | 
            -
                      emailparts[1]  | 
| 217 | 
            +
                      emailparts[1] += "From: #{connheader['to']}\n"
         | 
| 218 | 
            +
                      emailparts[1] += "Date: #{connheader['date']}\n"
         | 
| 219 | 
            +
                      emailparts[1] += "Subject: #{connheader['subject']}\n"
         | 
| 222 220 | 
             
                    end
         | 
| 223 221 |  | 
| 224 222 | 
             
                    return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
         | 
| @@ -85,8 +85,7 @@ module Sisimai::Lhost | |
| 85 85 | 
             
                        readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| e.start_with?(a) }
         | 
| 86 86 | 
             
                        next
         | 
| 87 87 | 
             
                      end
         | 
| 88 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 89 | 
            -
                      next if e == ""
         | 
| 88 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 90 89 |  | 
| 91 90 | 
             
                      # Diagnostic information for administrators:
         | 
| 92 91 | 
             
                      #
         | 
| @@ -124,9 +123,9 @@ module Sisimai::Lhost | |
| 124 123 | 
             
                          if cr != "" || cs != "" || e.include?("Remote Server ")
         | 
| 125 124 | 
             
                            # Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
         | 
| 126 125 | 
             
                            # 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
         | 
| 127 | 
            -
                            v["replycode"] | 
| 128 | 
            -
                            v["status"] | 
| 129 | 
            -
                            v["diagnosis"]  | 
| 126 | 
            +
                            v["replycode"]  = cr
         | 
| 127 | 
            +
                            v["status"]     = cs
         | 
| 128 | 
            +
                            v["diagnosis"] += "#{e }"
         | 
| 130 129 | 
             
                          end
         | 
| 131 130 | 
             
                        end
         | 
| 132 131 | 
             
                      end
         | 
    
        data/lib/sisimai/lhost/exim.rb
    CHANGED
    
    | @@ -168,14 +168,13 @@ module Sisimai::Lhost | |
| 168 168 | 
             
                    require "sisimai/rfc2045"
         | 
| 169 169 | 
             
                    require "sisimai/smtp/command"
         | 
| 170 170 |  | 
| 171 | 
            -
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
         | 
| 171 | 
            +
                    dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
         | 
| 172 172 | 
             
                    emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
         | 
| 173 173 | 
             
                    bodyslices = emailparts[0].split("\n")
         | 
| 174 174 | 
             
                    readcursor = 0      # (Integer) Points the current cursor position
         | 
| 175 175 | 
             
                    nextcursor = false
         | 
| 176 176 | 
             
                    recipients = 0      # (Integer) The number of 'Final-Recipient' header
         | 
| 177 177 | 
             
                    boundary00 = ""     # (String) Boundary string
         | 
| 178 | 
            -
                    v = nil
         | 
| 179 178 |  | 
| 180 179 | 
             
                    if mhead["content-type"]
         | 
| 181 180 | 
             
                      # Get the boundary string and set regular expression for matching with the boundary string.
         | 
| @@ -194,8 +193,7 @@ module Sisimai::Lhost | |
| 194 193 | 
             
                          next unless StartingOf["frozen"].any? { |a| e.include?(a) }
         | 
| 195 194 | 
             
                        end
         | 
| 196 195 | 
             
                      end
         | 
| 197 | 
            -
                      next if (readcursor & Indicators[:deliverystatus]) == 0
         | 
| 198 | 
            -
                      next if e.empty?
         | 
| 196 | 
            +
                      next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
         | 
| 199 197 |  | 
| 200 198 | 
             
                      # This message was created automatically by mail delivery software.
         | 
| 201 199 | 
             
                      #
         | 
| @@ -279,7 +277,7 @@ module Sisimai::Lhost | |
| 279 277 | 
             
                          # Message *** has been frozen by the system filter.
         | 
| 280 278 | 
             
                          # Message *** was frozen on arrival by ACL.
         | 
| 281 279 | 
             
                          v["alterrors"] ||= ""
         | 
| 282 | 
            -
                          v["alterrors"] | 
| 280 | 
            +
                          v["alterrors"]  += "#{e} "
         | 
| 283 281 | 
             
                        elsif boundary00 != ""
         | 
| 284 282 | 
             
                          # --NNNNNNNNNN-eximdsn-MMMMMMMMMM
         | 
| 285 283 | 
             
                          # Content-type: message/delivery-status
         | 
| @@ -313,19 +311,19 @@ module Sisimai::Lhost | |
| 313 311 | 
             
                            # Content-type: message/delivery-status
         | 
| 314 312 | 
             
                            nextcursor = true if e.start_with?(StartingOf["deliverystatus"][0])
         | 
| 315 313 | 
             
                            v["alterrors"] ||= ''
         | 
| 316 | 
            -
                            v["alterrors"]  | 
| 314 | 
            +
                            v["alterrors"]  += "#{e} " unless v["alterrors"].include?(e) if e.start_with?(" ")
         | 
| 317 315 | 
             
                          end
         | 
| 318 316 | 
             
                        else
         | 
| 319 317 | 
             
                          # There is no boundary string in $boundary00
         | 
| 320 318 | 
             
                          if dscontents.size == recipients
         | 
| 321 319 | 
             
                            # Error message
         | 
| 322 | 
            -
                            v["diagnosis"]  | 
| 320 | 
            +
                            v["diagnosis"] += "#{e} "
         | 
| 323 321 | 
             
                          else
         | 
| 324 322 | 
             
                            # Error message when email address above does not include '@' and domain part
         | 
| 325 323 | 
             
                            # pipe to |/path/to/prog ...
         | 
| 326 324 | 
             
                            #   generated by kijitora@example.com
         | 
| 327 325 | 
             
                            next unless e.start_with?("  ")
         | 
| 328 | 
            -
                            v["diagnosis"]  | 
| 326 | 
            +
                            v["diagnosis"] += "#{e} "
         | 
| 329 327 | 
             
                          end
         | 
| 330 328 | 
             
                        end
         | 
| 331 329 | 
             
                      end
         |