--- /dev/null
+# -*- coding: utf-8 -*-
+"""
+@summary: A handler module for parsing and analysing postfix logfiles.
+
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2024 by Frank Brehm, Berlin
+"""
+from __future__ import absolute_import
+
+# Standard modules
+import logging
+import re
+
+# Third party modules
+
+# from fb_tools.common import pp
+# from fb_tools.common import to_str
+from fb_tools.handling_obj import HandlingObject
+
+# Own modules
+# from ..postfix_chain import PostfixLogchainInfo
+from ..xlate import XLATOR
+
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+__version__ = '0.1.0'
+
+
+# =============================================================================
+class PostfixLogfileParser(HandlingObject):
+ """Handler class for parsing and analysing postfix logfiles."""
+
+ pattern_logentry = r'^(?P<timestamp>\S+)\s+\S+\s+'
+ pattern_logentry += r'(?P<command>[^\[\s]+)\[(?P<pid>\d+)\]:\s+'
+ pattern_logentry += r'(?P<msg>.*)\s*$'
+
+ re_logentry = re.compile(pattern_logentry)
+
+ re_postfix_id = re.compile(r'^(?P<id>[0-9a-f]+):\s+', re.IGNORECASE)
+ # 'connect\s+from\s+[^\[]+\[[0-9a-f\.:]+\]'
+ re_connect = re.compile(
+ r'connect\s+from\s+(?P<client>[^\[]+)\[(?P<addr>[0-9a-f\.:]+)\]', re.IGNORECASE)
+ re_disconnect = re.compile(r'disconnect\s+from\s+', re.IGNORECASE)
+
+ re_dis_ehlo = re.compile(r'\sehlo=(\d+)', re.IGNORECASE)
+ re_dis_starttls = re.compile(r'\sstarttls=(\d+)', re.IGNORECASE)
+ re_dis_quit = re.compile(r'\squit=(\d+)', re.IGNORECASE)
+ re_dis_auth = re.compile(r'\sauth=(\d+(?:/\d+))', re.IGNORECASE)
+ re_dis_commands = re.compile(r'\scommands=(\d+(?:/\d+))', re.IGNORECASE)
+ re_dis_rcpt = re.compile(r'\srcpt=(\d+)', re.IGNORECASE)
+ re_dis_data = re.compile(r'\sdata=(\d+)', re.IGNORECASE)
+ re_dis_mail = re.compile(r'\smail=(\d+)', re.IGNORECASE)
+
+ re_message_id = re.compile(r'message-id=(\S+)', re.IGNORECASE)
+
+ re_from_addr = re.compile(r'^\s*from=<([^>]*)>')
+
+ # -------------------------------------------------------------------------
+ def __init__(
+ self, appname=None, verbose=0, version=__version__, base_dir=None,
+ simulate=False, force=False, assumed_answer=None,
+ terminal_has_colors=False, initialized=False):
+ """Initialize the PostfixLogfileParser object."""
+ self.chains = {}
+ self.active_smtpd_pid = {}
+
+ super(PostfixLogfileParser, self).__init__(
+ appname=appname, verbose=verbose, version=version, base_dir=base_dir,
+ simulate=simulate, force=force, assumed_answer=assumed_answer,
+ terminal_has_colors=terminal_has_colors, initialized=False,
+ )
+
+ self.reset(no_warnings=True)
+
+ if initialized:
+ self.initialized = True
+
+ # -------------------------------------------------------------------------
+ def reset(self, no_warnings=False):
+ """Reset all resulting data structures."""
+ msg = _('Resetting all resulting data structures.')
+ if no_warnings:
+ LOG.debug(msg)
+ else:
+ LOG.warn(msg)
+
+ self.chains = {}
+ self.active_smtpd_pid = {}
+
+
+# =============================================================================
+if __name__ == '__main__':
+
+ pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list