Module: Sisimai::Lhost::FML

Defined in:
lib/sisimai/lhost/fml.rb

Overview

Sisimai::Lhost::FML decodes a bounce email which created by fml mailing list server/manager www.fml.org/. Methods in the module are called from only Sisimai::Message.

Constant Summary collapse

Indicators =
Sisimai::Lhost.INDICATORS
Boundaries =
['Original mail as follows:'].freeze
ErrorTitle =
{
  'rejected' => [
    ' are not member',
    'NOT MEMBER article from ',
    'reject mail ',
    'Spam mail from a spammer is rejected',
  ],
  'systemerror' => [
    'fml system error message',
    'Loop Alert: ',
    'Loop Back Warning: ',
    'WARNING: UNIX FROM Loop',
  ],
  'securityerror' => ['Security Alert'],
}.freeze

Class Method Summary collapse

Class Method Details

.descriptionObject



83
# File 'lib/sisimai/lhost/fml.rb', line 83

def description; return 'fml mailing list server/manager'; end

.inquire(mhead, mbody) ⇒ Hash, Nil

This method is abstract.

Decodes the bounce message from fml mailling list server/manager

Parameters:

  • mhead (Hash)

    Message headers of a bounce email

  • mbody (String)

    Message body of a bounce email

Returns:

  • (Hash)

    Bounce data list and message/rfc822 part

  • (Nil)

    it failed to decode or the arguments are missing

Since:

  • v4.22.3



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/sisimai/lhost/fml.rb', line 32

def inquire(mhead, mbody)
  return nil if mhead['x-mlserver'].nil?
  return nil if mhead['from'].include?('-admin@') == false
  return nil if mhead['message-id'].index('.FML') < 2

  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
  emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
  bodyslices = emailparts[0].split("\n")
  recipients = 0      # (Integer) The number of 'Final-Recipient' header

  while e = bodyslices.shift do
    # Read error messages and delivery status lines from the head of the email to the previous
    # line of the beginning of the original message.
    next if e.empty?

    # Duplicated Message-ID in <2ndml@example.com>.
    # Original mail as follows:
    v = dscontents[-1]

    p1 = e.index('<')  || -1
    p2 = e.rindex('>') || -1
    if p1 > 0 && p2 > 0
      # You are not a member of this mailing list <neko-nyaan@example.org>.
      if v["recipient"] != ""
        # There are multiple recipient addresses in the message body.
        dscontents << Sisimai::Lhost.DELIVERYSTATUS
        v = dscontents[-1]
      end
      v['recipient'] = e[p1 + 1, p2 - p1 - 1]
      v['diagnosis'] = e
      recipients += 1
    else
      # If you know the general guide of this list, please send mail with
      # the mail body
      v['diagnosis'] += e
    end
  end
  return nil if recipients == 0

  dscontents.each do |e|
    # Error messages in the message body did not matched
    ErrorTitle.each_key do |f|
      # Try to match with the Subject string
      next if ErrorTitle[f].none? { |a| mhead["subject"].include?(a) }
      e['reason'] = f
      break
    end
  end

  return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
end