fml 8 tutorial

Dr . Ken'ichi Fukamachi

FML.ORG

    < fukachan@fml.org >
        

Copyright (C) 2001-2018 Ken'ichi Fukamachi

All rights reserved. This program is free software; you can redistribute it and
/or modify it under the same terms as Perl itself.

The current status of fml8 is PRE ALPHA. The version is 7.98.x. We plan to
assign version 7.99.x to fml 8 ALPHA through fml 8 RC (release candidate).

The current TODO is seen at http://www.fml.org/software/fml-devel/fml/doc/ja/
todo/STATUS.html (Japanese only now, sorry). See  Chapter 8 on the changes
between fml 4 and fml8.

It is verified that fml8 works on the following environemnt now.

        perl 5.8.5   on NetBSD 2.0
        perl 5.8.5   on NetBSD 1.6
        perl 5.6.1   on NetBSD 1.5.x (1.5 stable)
        perl 5.6.1   on NetBSD 1.6
        perl 5.6.1   on FreeBSD 5.2.1
        perl 5.00503 on FreeBSD 4.3 STABLE
        perl ?       on FreeBSD 4.6 RELEASE
        perl 5.00503 on FreeBSD 4.7 RELEASE-p3
        perl 5.00503 on FreeBSD 4.6.2 RELEASE
        perl 5.6.1   on Turbolinux Server 8 (qmail)
        perl 5.6.1   on Redhat Linux 7.2 (postfix)
        perl 5.00503 on Redhat Linux 6.2 (sendmail8.11.6)
        postfix       + perl 5.6.1 on Solaris 7
        postfix 2.0.3 + perl 5.6.1 on Solaris 9

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Table of Contents
Preface

    fml8 Status
    The Road To The Next Generation Of Fml
    Relation Between fml4 And fml8 Development Branch.
    Mailing List
    Please Let Me Know Your Opinion ...
    On This Tutorial
    Technical terms in this tutorial

I. Fml Fundamental Usage

    1. What Is Mailing List ?

        Email
        Mailing List (Ml)

    2. fml8 Overview

        fml8 Features
        Installation Overview
        Create An ML
        Add A New User To ML
        Remove The User
        Customize
        Recipes

II. How To Set Up ML

    3. Download fml8 Source Code.

        Download Via FTP.
        Access To GitHUB.

    4. fml8 Installation On Unix

        Preparation Of Installation
        Run Configure
        Appendix: Directory Roles
        Fml Installation: make install
        Edit main.cf
        Edit site_default_config.cf (optional)
        Filter
        Virtual Domain
        MTA Configuration (postfix)
        MTA configuration (qmail)
        recipes

    5. Create ML On Unix

        Run "makefml newml" To Create An ML (In The Case Of Default Domain)
        Run "makefml newml" To Create An ML (In The Case Of Virtual Domain)
        MTA Configuration (postfix)
        MTA Configuration (qmail)
        Customize config.cf
        Recipes

    6. fml8 installation on Microsft 2000/NT
    7. Convert fml4 Style ML To fml8 Style ML

        Overview: fml4 To fml8 (1)
        Overview: Convert fml4 To fml8 (2)
        Overview: Difference Between fml4 and fml8
        Discussion

    8. Difference Between fml4 And fml8

        Difference Between fml4 And fml8: License.
        Difference Between fml4 And fml8: Command Mail And Error Messages.
        Difference Between fml4 And fml8: CUI
        Difference Between fml4 And fml8: GUI (CGI)
        File Naming Convention

    9. Upgrade And Downgrade Of fml8

        Upgrade
        downgrade.

    10. Configure CGI

        "makefml newml" Creates CGI Script Always
        Edit .htaccess
        Example: Master Cgi
        CGI Example: Create ML
        CGI Example: subscribe
        CGI Skin Selection

    11. Apache Configuration

        Use Suexec Of Apache

    12. Test

        Before Test
        Test Of MTA
        Send A Mail To ML
        Test Of fml8 Itself.
        Reset After Test.

III. How To Customise

    13. What A User Can

        Get ML Guide
        Subscribe
        Posting Article
        Help: When You Want To know The Usage
        Get Past Articles
        Unsubscribe
        Command Mail (Control fml By Sending Mail)

    14. What Can You Do On The Mailing List Server

        On The Host
        Policy Of Command Creation
        Common Command Line Options
        Create A New ML
        Remove An ML
        Subscribe and Unsubscribe
        Change the registered address
        Stop Realtime Delivery
        Start Realtime Delivery
        See Log
        See The Member List
        Modify Configuration
        Add or Remove A Remote Administrator.
        Add or Remove A Modrator
        "fml" And "makefml" Command
        Show Addresses (Users + Aliases)
        Show Alias
        Show Configuration
        Show Perl Module Document
        Convert Articles To HTML Form
        Recipes

    15. Modify Configuration Files

        Change Default For All ML's On Thie Host

    16. [Caution] File Names

        Filename Structure
        Case Study: Address List
        Case Study: List Of Remote Administrators
        Case Study: List Of Moderators
        Case Study: Remote Administrator Password Files

    17. Case Studies Of Customization

        Case Study: Auto File Responder
        Case Study: Anyonen Can Use Command Mail.
        Case Study: Disable Command Mail
        Case Study: Mail Magazine (1)
        Case Study: Mail Magazine (2)
        Case Study: Anyone Can Post.
        Case Study: Article Posting Allowd If It Is A Reply To The Former One.
        Case Study: PGP/PGP Based Authentication In Posting
        Case Study: Authenticate command mail by PGP/GPG
        case study: hierarchical ML
        I Want To Use ML By My Account.
        Case Study: Office (1)
        Case Study: Office (2)

    18. Header Rewriting

        Recipe's

    19. Extend Command

        Case Study: Create Your Own Help Command.
        Recipes

    20. Filtering
    21. Extend Message

        Case Study: Customize Message

    22. Be ML Articles public via WWW

        Recipes

IV. Operations

    23. Logging

        See Log
        Show Computer Oriented Log
        Recipes

    24. Back Up Of Configurations

        Back Up fml8 Configurations
        Back Up All Files Except For Some Large Directories.

V. Troubleshoot

    25. Troubleshoot

        When The File System Error Ocuurs

VI. fml8 Design

    26. [LOG] Original Idea Of fml8 Project

        The Original Idea Of fml8 (fml-devel) Project
        Details Of Idea
        Refactoring
        Architecture image
        release engineering

    27. Programming Style

        Variable Naming Convension
        A Few Topics On Design And Coding Style
        Programming Style Original Idea

VII. fml8 Internals

    28. fml8 Boot Loader To Resolve Version Dependence Dynamically

        Case: Distribution
        FML::Process:: Class Structure
        Modules In Process Execution
        Discussion: Where Function Should Resolve $ml_name And $ml_domain.

    29. Configuration File: config.cf

        ML Specific Configuration File: config.cf
        config.cf Format
        Extension To Postfix Style
        Overload Variables In config.cf
        Modifying/Adding Variables After All Configuration Files Have Been
            Loaded.
        Variable List (Alphabetical Order)
        Variable List (Class Based)
        Recipes

    30. Create A New Program

        Create A Program (CUI)
        Create A Program (CGI)

    31. fml8 Mail Delivery System

        The Difference Between fml4 And fml8
         Mail::Message Object
        Incoming Queuing
        fml Sends Back A Mail Message
        Mail Queue And Delivery System
        Mail Queue Directory
        Queue Management System
        Discussion: FML::Mailer Is Apropriate ?
        Delivery TIPS

    32. Digest Delivery

        Files Used For Digest Delivery Control
        Idea: Digest Related Commands
        recipes

    33. Language Preference In Processing

        Problems Of Language Preference
        Japanese Preferred ML
        English preferred ML

    34. Manipulate Message (Mail Message)

        Mail::Message Class
        Mail::Message::Parse Class
        Mail::Message::Compose Class
        Message Internationalization: The Usage Of reply_message_nl()
        Discussion: How To Send Back Language Dependent Error Mesages

    35. Filter

        Overview Of Filter System
        Configuration Variables
        Size Limit
        Limit For Command Mail
        Mime Component Filter Rules
        Discussion: Mime Component Filter Needs What Functions ?

    36. Subscribe / Unsubscribe

        Which Map Subscribe/Unsubscribe Is Operated To ?

    37. Command (Command Mail, CUI And GUI)

        Modules for commands
        Data Flow Of Command Request Processing
        Command Extension: Command Mail
        CUI Command Extension: makefml/fml
        GUI Command Extension: CGI
        How Differ Coding Style Among fml4 And fml8

    38. Internal Of CGI Process

        Method
        Screen Of CGI And The Method
        Screen And Trampolin Mechanism
        MISC: Hard Coding Is Mandatory ?
        CGI Implementation: Inheritance Among CGI Classes
        CGI Implementation: config.cgi

    39. Directory

        Q: How Recursively Sub Directory Can Be Created ?
        Recipes

    40. Restrict Input Data

        Overview: Checks Of Input Data
        FML::Restriction Class
        How CGI Restricts The Input
        Discussion: FML::Restriction Is Too Restrictive ?

    41. User Authentication

        Discussion: FML::Credential Implementation

    42. Hook

        Overview
        Hook Naming Convension
        Recipes

    43. Virtual Domain

        Overview: virtual domain handling in fml8
        Case study: movement ?

    44. Errormail Analyzer (libexec/error)

        Overview
        Algorithm Of Error Detection
        Cache Of Error Messages Data
        Forward Error Messages

    45. IO Interface And Operations

        Fundamentals Of IO::Adapter
        Methods / Operation Vector
        Discussion

    46. Lock

        Overview: Lock
        TODO

    47. Database Related Modules

        Overview
        Persistent Data Use
        Tie::JournaledFile Class
        FML::Cache::Ring Class

    48. Database Management System

        Overview

    49. Convert Another ML System To fml8

        Implementation: fml4 To fml8

VIII. Modules

    50. IO Abstraction Layer (IO::Adapter Class)

        IO::Adapter Overview
        IO::Adapter Methods
        Argument Type Of Methods
        File Map
        Unixgroup Map
        Nis Map
        MySQL Map

    51. Mail::Message Module

        Mail::Message Overview
        Mail::Message Module: Analyze
        Mail::Message Module: Create A New Object
        Mail::Message Module: Header Manipulations
        Mail::Message Module: Manipulate Messabe Body
        Mail::Message Module: Search
        Mail::Message Module: Print
        Mail::Message Module: Utility Functions
        References

    52. Language Dependent Functions

        Something::Language:: Class

    53. Mail::Message::Encode Class

        Mail::Message::Encode Specification
        run_in_chcode()

    54. Execise: Create A New Program

        Case Study: Create A fmlsch
        Case Study: fmlsch.cgi

IX. Apendixes

    Glossary (function and variable names convention)
    A. Struct curproc (Object In Fact)

        curproc Object
        PCB Category List

List of Tables
4-1. directory structure
8-1. Difference between fml4 and fml8: CUI
26-1. refactoring TODO
26-2. release interval
29-1. table description

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Preface

fml8 Status

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fml8 has already implemented fundamental functions. Several people uses fml8芍
芍as hobby and office mailing list system under normal operations.            芍
芍                                                                            芍
芍When you configure fml8, you need to edit configuration files since         芍
芍configuration helper tool has basic functions now. Except it, you can use   芍
芍fml8 as same as fml4.                                                       芍
芍                                                                            芍
芍See http://www.fml.org/software/fml-devel/fml/doc/ja/todo/STATUS.html for   芍
芍the current status of fml8.                                                 芍
芍                                                                            芍
芍See  Chapter 8 on the difference between fml4 and fml8.                     芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

The Road To The Next Generation Of Fml

fml8 is fully rewritten mailing list driver from scratch to re-implement fml4.
The main purpose of this project is re-implementation of fml mailing list
driver system with reflecting our 10 years experience on mailing list driver
developement.

Roughly speaking, the relation between fml4 and fml8 is similar to one between
sendmail and Postfix.

fml8 re-implements almost all features of fml4 functions. We re-design fml and
clean up the function and variable naming convenstion. Also, We reinforce guide
line to the coding style for clean source codes.

For example, when you use fml4, you'll find that fml assumes the list of
members is a text file on the host. fml4 inherits the assumption from version
1.0 through 4.0. It affetcts the core part of the design. Hence, it is
difficult to extend fml IO for the use of RDBMS, redundency et.al. In fact,
fml4 supports RDBMS but the code is ugly. We should need to fully rewrite fml
core parts.

Also, I want a lot of new features. fml8 should provide tiny bug tracking
system maintatined automatically. It is better to co-relate fml with cvs log.
These features help the support by mail and developer mailing list. I need it,
of course.

Firstly, we need to discuss what we should inherit from fml4 design and
features, and discard what in fml4.

 ’ What we should inherit into fml8 from fml4 ?

 ’ easily customizable ?

 ’ what obsolete features we should remove ?

Anyway, we should write codes for the further discussion! You can find it at
the following URL.

http://www.fml.org/software/fml8/

ftp://ftp.fml.org/pub/fml8/

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Relation Between fml4 And fml8 Development Branch.

We implement new features at fml8 branch. fml4 imports it if needed. We only
have to bug-fix at fml4 branch.

(further translation omited).

               fml-devel
             -----------------------------> 8.0
                       A  |
                       |  | (interaction)
                       |  V
1.2 ->  4.0 ------------------------------> 4.0-current
              |      |
            4.0.1   4.0.2 .... (release / 4.0-stable release)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mailing List

fml-users@ffs.fml.org is prepared. Use it for English discussion.

To subscribe it, send the mail with "subscribe YOUR NAME" in the body to
fml-users-ctl@ffs.fml.org. You will receive the reply for confirmation. Please
reply the confirmation and send back it to fml-users-ctl@ffs.fml.org again. For
example, a subscribe mail is as follows:

From: your-account@your-domain
To: fml-users-ctl@ffs.fml.org

subscribe Kinomoto Sakura

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Please Let Me Know Your Opinion ...

Please send me the idea on fml8 to the mail address: fml-request@fml.org or
myself fukachan@fml.org directly.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

On This Tutorial

For the fml4 user, the order of chapters and sections are almost same as the
book "fml bible" publishded by O'reilly Japan (rewritten in Japanese).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Technical terms in this tutorial

See  Glossary (function and variable names convention) also.

%

    user prompt on the shell

#

    root user prompt on the shell

~

    user's home directory

CUI

    command line tool such as makefml or fml.

fml

    fml software in general use.

fml (command)

    fml command included in fml8 software. fml is same as makefml command
    except for the argument order.

user fml

    a user called as fml. a user account for fml8 software.

fml4

    fml4 series.

fml8

    fml8 series.

GUI

    CGI interface.

makefml (command)

    configuration helper tool included in fml4 and fml8. You can use them when
    you login the mailing list server.

I. Fml Fundamental Usage

This part describes a brief guide for beginners.

See http://www.fml.org/software/fml/ and other sites for more details on
mechanism of the mailing list.

Table of Contents
1. What Is Mailing List ?
2. fml8 Overview

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 1. What Is Mailing List ?

Email

Email is an electirc version of mail.

One email has the following structure which consists of two parts. The former
is header, the latter is body. The separator between them is one null line
(empty line).

[Example]

From: rudo@nuinui.net
To: kenken@nuinui.net
Subject: asobo.

Hi, Kenken. I am Rudo.

// rudo

See RFC822 and RFC2822 for more details of definitions.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mailing List (Ml)

Mailing list (ML) is forwarding mechanism of email. The program for it is
called as ML driver. ML driver receives the email injected via MTA over the
network, copy and redistributes it to members subscribed to the ML.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Model Of An ML.

[ml]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 2. fml8 Overview

See  Chapter 8 on the detail of difference between fml4 and fml8.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

fml8 Features

 ’ fml8 configuration file format is changed to new Postfix style format
    configuration files (.cf files).

 ’ usage of CUI is almost same as fml4 (it is same as could as possible). You
    can use CUI (makefml and fml command)

            to create/remove an ML,
            to add/remove/change an addresse of ML members,
            to add/remove/change an address of remote administrators,
            to see log and member list,
            et.al.


    Makefml and fml are same programs except for argument order.

    See  the Section called Difference Between fml4 And fml8: CUI in Chapter 8
    on the CUI usage difference between fml4 and fml8.

 ’ GUI (CGI) interface. The functions are a subset of CUI ones.

            to create/remove an ML,
            to add/remove/change an address of ML members,
            to add/remove/change an address of remote administrators,
            to see log and member list,
            et.al.


    The configuration file editing is incomplete yet.

 ’ article delivery, header rewriting and several filters ( corresponding with
    fml4's envelope filter and content filter ).

 ’ command mail for users.

            to add/remove/change the address,
            get article summary,
            get old articles,
            et.al.


 ’ command mail (admin command mail) for remote administratoin by mail.

            to add/remove/change an addresse of ML members,
            to add/remove/change an address of remote administrators,
            to see log and member list,
            et.al.


 ’ automatic analyzer of error messages.

 ’ IPv6 ready.

 ’ tiny thread track system.

 ’ built-in module for HTML converter of articles. support automatic
    conversion by default.

    fmlhtmlify and makefml supports html conversion functions.

 ’ main programs (fml/libexec): distribute command error

 ’ utilities: fmladdr fmlailas fmlconf fmldoc makefml fml

 ’ fml4 emulation: if you replace fml.pl of fml4 and fml.pl of fml8, fml8 runs
    as fml4.

 ’ After 2004 summer, the queueing system is implemanted. Currently the
    delivery system is queuing based. So, fml8 is a MTA in fact.

 ’ Abstracted IO layer to get member list in unified way from a file, /etc/
    group, NIS, SQL.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Installation Overview

    Important: Run GNU autoconf firstly, and "make install". It is defact
    standard in the world of open sources. This procedure is different from
    fml4 installation steps. It may confuse you if you are customered with fml4
    But fml8 is more friendly for package systems of free unix like systems.

    The main differece between fml4 and fml8 in installation is "run programs
    as root", "use of configure", and editing of configuration files.

Suppose we create a new ML named elena ML (elena@fml.org). The brief flow of
installation is as follows:

 1. Download fml8 source and extract it on the disk.

 2. Install it by user root. Firstly, change user to "root" and create the user
    "fml" and the group "fml". Secondly, run configure and "make install".

    % su root
    # groupadd fml
    # useradd -m -g fml fml
    # ./configure
    # make install

    By default, 4.4 BSD style sub-directories are created. The path is
    configurable at configure options.

    For example, main programs called from MTA such as distribute, command,
    et.al. are installed into under /usr/local/libexec/fml/. Instead, utility
    programs are installed to /usr/local/bin. These are wrappers to call real
    programs at /usr/local/libexec/fml/.

    Perl modules are installed into /usr/local/lib/fml/$fml_version/ and
    message templates et.al. are installed into /usr/local/share/fml/
    $fml_version/.

 3. Change user to "fml" and create elena ML for test.

    % su fml
    % makefml newml elena

    You can use "fml" instead of makefml. Both are same except for the argument
    order.

    % su fml
    % fml elena newml

 4. Set up MTA which runs fml8 programs.

 5. Test.

 6. Customize your ML.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Please install by user root. It is different from fml4.                     芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Create An ML

Create an ML by CUI (makefml). To create elena@fml.org ML (fml.org is the
default domain), run

% su fml
% makefml newml elena

. See the section  Chapter 5 for more details.

In the virtual domain case, specify the whole address as an argument. For
example, to create an ML elena@nuinui.net, run the following command:

(At the first time)
% su root
% makefml newdomain nuinui.net /some/where/nuinui.net
% su fml
% makefml newml elena@nuinui.net

(After the 2nd time)
% su fml
% makefml newml elena@nuinui.net

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍See  Chapter 43 for the virtual domain case detail.                         芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Add A New User To ML

In the case of the default domain (fml.org)

% su fml
% makefml subscribe elena rudo@nuinui.net

in the case of virtual domain (nuinui.net), specify the whole adress of ML
name.

% su fml
% makefml subscribe elena@nuinui.net fukachan@sapporo.iij.ad.jp

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Remove The User

In the case of the default domain (fml.org),

% su fml
% makefml unsubscribe elena rudo@nuinui.net

in the case of virtual domain (nuinui.net), specify the whole adress of ML
name.

% su fml
% makefml unsubscribe elena@nuinui.net fukachan@sapporo.iij.ad.jp

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Customize

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍"makefml config" is a CUI to customize ML by menu form. BUT YET INCOMPLETE. 芍
芍                                                                            芍
芍Edit configuration files anyway now.                                        芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Common Configurations On This Host

/usr/local/etc/fml/site_default_config.cf affects all ML on this host
irrespective of the default domain or virtual domains. [1]

The format of site_default_config.cf is same as config.cf described below.

See list of all variables for the configurable variation.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

elena ML's Configuration

To customize elena ML, edit /var/spool/ml/elena/config.cf file. The format is a
little modified postfix style. It is different from both fml4's config.ph and
cf. Add hooks after =cut line if needed.

Add or modify the least variables. If unspecified, the default value is used.
The default value depends fml version and is defined at

/usr/local/etc/fml/defaults/${fml_version}/default_config.cf

The library path depends fml version. This technique ensures the easy upgrade/
downgrade procedure. This is a feature of fml8.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. Why fml8 is the next official release of fml4 series ?
2. What difference between fml4 and fml8 ?
3. Which of current, stable and release should we download ?

1. Why fml8 is the next official release of fml4 series ?

1 bit shift of version with greate internal change is traditional :-)

fml8 is build from scratch by discarding fml4 source codes. fml8 is not a
upgraded fml4 software. So we use 1 bit shifted version number for fml8.

2. What difference between fml4 and fml8 ?

See  Chapter 8 fore more details.

3. Which of current, stable and release should we download ?

fml8 does not provide such release line today. Please download the latest one
by comparing file name which has date in int.

See  Chapter 3 on download.

II. How To Set Up ML

Topics driven in this part.

Table of Contents
3. Download fml8 Source Code.
4. fml8 Installation On Unix
5. Create ML On Unix
6. fml8 installation on Microsft 2000/NT
7. Convert fml4 Style ML To fml8 Style ML
8. Difference Between fml4 And fml8
9. Upgrade And Downgrade Of fml8
10. Configure CGI
11. Apache Configuration
12. Test

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 3. Download fml8 Source Code.

Download Via FTP.

You can find fml8 source at ftp://ftp.fml.org/pub/fml8/ . You can get it by
ftp.

We build snapshot as a tarball in some interval. The file name contains date
such as YYYYMMDD form. Please get the latest one.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Access To GitHUB.

https://github.com/fmlorg/

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 4. fml8 Installation On Unix

Preparation Of Installation

Create the user "fml" and the group "fml" before running configure.

% su root
# groupadd fml
# useradd -g fml -m fml

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Run Configure

Run configure (GNU autoconf) and make.

% su root
# groupadd fml
# useradd -g fml -m fml
# ./configure
# make install

where configure replaces variables in scripts and .cf files.

After runnig configure, run "make install". The fml installer (perl scripts)
reads ./etc/fml/install.cf configure created and install fml8 to e.g. /usr/
local/.

You can specify the user name and fundamental directory names by configure
arguments. Customizable variables are follows: configure --help shows them.

variables       default value               example
--------------------------------------------------------
prefix          /usr/local                  /usr/local
exec_prefix     /usr/local
bindir          ${exec_prefix}/bin          /usr/local/bin
sbindir         ${exec_prefix}/sbin         /usr/local/sbin
libexecdir      ${exec_prefix}/libexec      /usr/local/libexec/fml
datadir         ${prefix}/share             /usr/local/share/fml
sysconfdir      ${prefix}/etc               /usr/local/etc/fml
sharedstatedir  ${prefix}/com
localstatedir   ${prefix}/var
libdir          ${exec_prefix}/lib          /usr/local/lib/fml
includedir      ${prefix}/include
oldincludedir   /usr/include
infodir         ${prefix}/info
mandir          ${prefix}/man

You can overwrite the following variables by configure arguments.

fmlconfdir      $sysconfidr/fml             /usr/local/etc/fml
mlspooldir      /var/spool/ml               /var/spool/ml
fml_owner       fml                         fml
fml_group       fml                         fml
default_domain  (spaculated by configure)   (spaculated by configure)

These options are shown by runnig

configure --help

.

  --without-warning       run perl as perl without -w
  --with-fmlconfdir=DIR   use DIR instead of SYSCONFDIR/fml
  --with-mlspooldir=DIR   use DIR instead of /var/spool/ml
  --with-fml-owner=USER   use USER instead of fml
  --with-fml-group=GROUP  use GROUP instead of fml
  --with-default-domain=DOMAIN  use DOMAIN as the ML domain

 

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example: Running Configure

Example: On NetBSD, you should install 3rd party programs into /usr/pkg.

% ./configure --prefix=/usr/pkg

Example: On FreeBSD, use /usr/local.

% ./configure

If you use /etc/fml as configuration directory on e.g. Debian,

# ./configure --with-fmlconfdir=/etc/fml
loading cache ./config.cache
checking for perl... (cached) perl
checking for perl... (cached) /usr/local/bin/perl
checking whether optional useful commands are available or not
checking for cksum... (cached) /usr/bin/cksum
checking for md5... (cached) /usr/bin/md5
checking for ls... (cached) /bin/ls
checking for tar... (cached) /usr/bin/tar
checking for gzip... (cached) /usr/bin/gzip
checking for zcat... (cached) /usr/bin/zcat
checking for gunzip... (cached) /usr/bin/gunzip
checking for lha... (cached) /usr/pkg/bin/lha
checking for ish... no
checking for bzip2... (cached) /usr/bin/bzip2
checking for bunzip2... (cached) /usr/bin/bunzip2
checking for uuencode... (cached) /usr/bin/uuencode
checking for compress... (cached) /usr/bin/compress
checking for sendmail... (cached) /usr/sbin/sendmail
checking for newaliases... (cached) /usr/bin/newaliases
checking for postfix... (cached) /usr/sbin/postfix
checking for postalias... (cached) /usr/sbin/postalias
checking for postconf... (cached) /usr/sbin/postconf
checking for postmap... (cached) /usr/sbin/postmap
checking for nkf... (cached) /usr/pkg/bin/nkf
checking for kakasi... no
checking for namazu... no
checking for pgp... (cached) /usr/pkg/bin/pgp
checking for pgp5... no
checking for pgpe... no
checking for pgpk... no
checking for pgps... no
checking for pgpv... no
checking for gpg... no
checking for less... (cached) /usr/bin/less
checking for more... (cached) /usr/bin/more
checking for w3m... (cached) /usr/pkg/bin/w3m
updating cache ./config.cache
creating ./config.status
creating config.sh
creating fml/etc/main.cf
creating fml/etc/default_config.cf.ja
creating fml/etc/site_default_config.cf
creating fml/libexec/loader
creating fml/bin/fmlalias
creating fml/bin/fmlconf
creating fml/bin/fmldoc
creating fml/bin/fmlhtmlify
creating fml/bin/fmlsch
creating fml/bin/fmlthread
creating fml/bin/fmlspool
creating fml/bin/makefml
enabled perl -w

fml has been configure with the following options:

                 prefix: /usr/local
            exec_prefix: ${prefix}
                 bindir: ${exec_prefix}/bin
                sbindir: ${exec_prefix}/sbin
                lib_dir: ${exec_prefix}/lib
            libexec_dir: ${exec_prefix}/libexec
                 mandir: ${prefix}/man
                datadir: ${prefix}/share

      fml process owner: fml
      fml process group: fml
             fmlconfdir: /etc/fml
             mlspooldir: /var/spool/ml
         default domain: home.fml.org

Now you must run "make install".

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Appendix: Directory Roles

fml8 installs files under /usr/local by default.

Table 4-1. directory structure

見芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍directory 芍                         description                          芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍/usr/local芍Configuration files. It corresponds with fml4's /usr/local/fml芍
芍/etc/fml  芍/.fml and default_config.ph. /usr/local/etc/fml/main.cf has   芍
芍          芍fml version and library paths et.al.                          芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍/usr/local芍                                                              芍
芍/libexec/ 芍Executables (corresponding with fml4's /usr/local/fml )       芍
芍fml       芍                                                              芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍/usr/local芍Perl module location ( fml4's /usr/local/fml )                芍
芍/lib/fml  芍                                                              芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍/usr/local芍Message templates ( fml4's /usr/local/fml/messages/). Template芍
芍/share/fml芍files are language dependendent.                              芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍The top directory for mailing lists of the default domain.    芍
芍          芍same as fml4. caution: the owner of /var/spool/ml can be      芍
芍          芍specified by configure arguments. Prepare different directory 芍
芍/var/spool芍for each domain. For example, /var/spool/ml for fml.org       芍
芍/ml       芍(default domain), whereas /var/spool/nuinui.net for nuinui.net芍
芍          芍domain (virtual domain). See ml_home_prefix_maps for the      芍
芍          芍relation between domain and directory. Also see  Chapter 43   芍
芍          芍for the virtual domain detail.                                芍
谷芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Fml Installation: make install

change user to "root" and run "make install" after configure runs.

% su root
# make install

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍You need not to run configure by the user root. But, you need to run "make  芍
芍install" by root. So, it may be better to run both by root.                 芍
芍                                                                            芍
芍% su root                                                                   芍
芍# ./configure                                                               芍
芍# make install                                                              芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Edit main.cf

Please edit /usr/local/etc/fml/main.cf if needed, though already configure
rewrites main.cf to fit your environment.

The file main.cf contains the most fundamental configuration variables to
control fml8 basic features: fml version control, library path, virtual domain
et.al.

Instead, the detail of each ML configuration depends on config.cf file of each
ML such as /var/spool/ml/elena/config.cf for elena ML. "config.cf" can override
all configuration variables: header customizations, filter rules, member file
locations et.al.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example: /usr/local/etc/fml/main.cf

/usr/local/etc/fml/main.cf is not ML specific. This is meta file to define
fundamental variables e.g. fml version, directory path et.al. fml8 loader reads
them.

The format of main.cf is same as other .cf files: [2]

variable = value

style.

#
# $FML: main.cf.sgml,v 1.1 2005/07/27 12:21:36 fukachan Exp $
#

# fml version
#   This is important
# Example: fml 8.0
#          fml-current YYYYMMDD
#          fml-devel YYYYMMDD
fml_version     =       current-20020701

fml_owner       =       fml

fml_group       =       fml


###
### DIRECTORIES
###

# Example: /usr/local
prefix                  =       /usr/local
exec_prefix             =       ${prefix}

# $config_dir holds the global main configuration and
# several version-dependent default configurations
# Example: /usr/local/etc/fml
config_dir              =       /usr/local/etc/fml

# Example: /usr/local/etc/fml/defaults/$fml_version
default_config_dir      =       $config_dir/defaults/$fml_version

# defined for convenience, for example, we need this variable
# at include, include-ctl, which needs expansion of ../libexec/fml/fml.pl
# Example: /usr/local/libexec/fml
executable_prefix       =       ${exec_prefix}/libexec/fml

# Example: /usr/local/libexec/fml/$fml_version
libexec_dir             =       ${exec_prefix}/libexec/fml/$fml_version

# Example: /usr/local/lib/fml/$fml_version
lib_dir                 =       ${exec_prefix}/lib/fml/$fml_version

# Example: /usr/local/share/fml/$fml_version
share_dir               =       ${prefix}/share/fml/$fml_version

# site local library location
# which is prepared but not used by fml itself
local_lib_dir           =       ${exec_prefix}/lib/fml/site_local


# ml's home directories
# $ml_home_dir (e.g. /var/spool/ml/elena ) is taken from loader's @ARGV.
# This is compatible with fml 4.0.
# Example: /var/spool/ml
default_ml_home_prefix  =       /var/spool/ml



###
### CONFIGURATION FILES AND DEFAULT PARAMETERS
###


# default domain
default_domain          =       fml.org


# version dependent default_config.cf location
# whic holds
# Example: /usr/local/etc/fml/defaults/8.0/default_config.cf
default_config_cf       =       $default_config_dir/default_config.cf


# domain specific configurations
# Example: /usr/local/etc/fml/domains/fml.org/default_config.cf
domain_default_config   =       $config_dir/domains/$default_domain/config.cf


# virtual format: domain directory
# for example,
#   fml.org     /var/spool/ml/fml.org
#   nuinui.net  /var/spool/ml/nuinui.net
virtual_maps            =       $config_dir/virtual

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Edit site_default_config.cf (optional)

/usr/local/etc/fml/site_default_config.cf is the configuration file common over
all mailing list on this host (site). [3]

site_default_config.cf overrides default_config.cf file. Each ML configuration
file (/var/spool/ml/elena/config.cf for elena ML) overrides
site_default_config.cf.

By default, some example configurations are added to this file.

#
#               site default_config.cf EXAMPLE
#
# fml-devel loads .cf files in this order for elena ML.
#      1. ${prefix}/etc/fml/defaults/$VERSION/default_config.cf
#      2. ${prefix}/etc/fml/site_default_config.cf
#      3. ${prefix}/etc/fml/domains/$DOMAIN/default_config.cf
#      4. /tmp/dir/elena/config.cf
#
# This file overrides the default "default_config.cf" configurations
# in the following way.
#

# We want to disable the subject tag in articles by default.
article_header_rewrite_rules    -=      rewrite_article_subject_tag

# mime based comonent filter
use_mime_component_filter       =       yes


# [site specific options]
#   Example:
#       key  = value
#       key += value
#       key -= value


=cut

#
# you can write hooks here after.
#   Example:
#       $distribute_run_start_hook = q{ ... };

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Filter

All filter are enabled by default.

"mime component filter" is important. By default mime component filter is
enabled, Only text/plain article can be passed through fml8.

To disable mime component filter on all ML's, set

use_mime_component_filter       =       no

at site_default_config.cf.

To customize mime component filter, set

use_mime_component_filter       =       yes

at site_default_config.cf, and edit rules in /usr/local/etc/fml/
mime_component_filter file.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Virtual Domain

You do not need edit /usr/local/etc/fml/main.cf but you need to edit
$ml_home_prefix_maps (/usr/local/etc/fml/ml_home_prefix file by default). You
can use "makefml newdomain" command to control $ml_home_prefix_maps. See "ML
creation" for newdomain command.

Suppose that fml.org is the default domain. In this case, /var/spool/ml/$ml is
used for $ml ML of fml.org. /var/spool/ml is used only for the domain fml.org.
If you want to set up elena@nuinui.net, you need to specify other directory.

Specify the relation between domain and directory, edit /usr/local/etc/fml/
ml_home_prefix and set the following:

nuinui.net      /var/spool/nuinui.net

Please use "makefml newdomain" command to change /usr/local/etc/fml/
ml_home_prefix file. It is recommended that you do not edit this file directly.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍site_default_config.cf is applied to all domains.                           芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

MTA Configuration (postfix)

Please set up postfix properly before "makefml newml" can set up a ml.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Default Domain (Example: fml.org)

Set up /etc/postfix/main.cf like this:

[/etc/postfix/main.cf]

allow_mail_to_commands = alias,forward,include

alias_maps      =       hash:/etc/mail/aliases
                        hash:/var/spool/ml/etc/mail/aliases

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Please check that $mydestination contains the default domain (may be        芍
芍$mydomain).                                                                 芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Virtual Domain (Example: nuinui.net)

You need to edit /etc/postfix/main.cf to set up $virtual_maps.

[/etc/postfix/main.cf]

allow_mail_to_commands = alias,forward,include

alias_maps      =       hash:/etc/mail/aliases
                        hash:/var/spool/ml/etc/mail/aliases
                        hash:/var/spool/nuinui.net/etc/mail/aliases

virtual_maps    =       hash:/var/spool/nuinui.net/etc/postfix/virtual

[/usr/local/etc/fml/ml_home_prefix]

nuinui.net /var/spool/nuinui.net

Both alias files and /var/spool/nuinui.net/etc/postfix/virtual are updated by
makefml automatically where we suppose ml_home_prefix_maps defines

nuinui.net /var/spool/nuinui.net

relation.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Postfix variable $mydestination should contain the default domain (may be   芍
芍$mydomain) but not virtual domain. Pay attention that we assume we use      芍
芍postfix style virtual domain. Please see postfix document for more details. 芍
芍                                                                            芍
芍When you begin to use a new virtual domain, you need to update both         芍
芍$alias_maps and $virtual_maps in /etc/postfix/main.cf. Also, you have to    芍
芍update /usr/local/etc/fml/ml_home_prefix by running "makefml newdomain".    芍
芍                                                                            芍
芍Recent postfix has $virtual_alias_maps and $virtual_maps variables. But     芍
芍$virtual_alias_maps = $virtual_maps by default. You can use either.         芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

MTA configuration (qmail)

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fml8 assumes that qmail configurations is always based on /var/qmail/control芍
芍/virtualdomains regardless of the default domain or not.                    芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

The template of /var/qmail/control/virtualdomains is created at /var/spool/ml/
etc/qmail by makefml.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

The default domain (example: fml.org)

It is good to prepare "ml.fml.org" domain for ml specific. At

/var/qmail/control/virtualdomains

specify the following rule

ml.fml.org:fml-fml.org

. "makefml newml" can set up ~/.qmail-* automatically.

See the section on "makefml newml and qmail" on how "makefml newml" creates ~
/.qmail-* files.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

virtual domain (example: nuinui.net)

For "nuinui.net" virtual domain, not the default one, specify

nuinui.net:fml-nuinui.net

at /var/qmail/control/virtualdomains. It is same as in default domain case.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

recipes

1. Can we use other user as fml process ?
2. When should we change use to fml in installation ?
3. Can we install fml8 without document.
4. Can we specify per path in installation ?
5. Can we use jperl ?
6. Can we overwrite elena ML ?
7. Can we edit alias files under /var/spool/ml/etc ?
8. Can we use fml8 on Windows 2000/NT4 but MTA on Unix server ?
9. Can we initialize ML ?

1. Can we use other user as fml process ?

Run configure with --with-fml-owner option.

configure --with-fml-owner=$USER

Do not use your own account but use fml specific user for all fml processes.

Please use procmail et.al. if fml processes are kicked off by .forward not
aliases. See /var/spool/ml/etc/procmail/procmailrc for more details on procmail
usage.

2. When should we change use to fml in installation ?

In installation.

You can download source code and run configure by not user root (e.g. user
fml), but run "make install" by user root. It may be better to run by user too
always.

3. Can we install fml8 without document.

Yes by default. fml8 does not install document. If you need documentation,
please install ./SOURCE/Documentation/ into /usr/local/share/doc/fml8/
$FML_VERSION/.

4. Can we specify per path in installation ?

No directly. Run configure with proper environment variable PATH.

% env PATH=/some/where/:$PATH sh configure

5. Can we use jperl ?

Unknown.

6. Can we overwrite elena ML ?

Run "makefml newml" with --force option.

% makefml --force newml elena

7. Can we edit alias files under /var/spool/ml/etc ?

Yes but please control them by yourself. These files are controlled by makefml/
fml scripts. These scripts edit them. If the ML is removed, the corresponding
entries are removed and cannot be back.

8. Can we use fml8 on Windows 2000/NT4 but MTA on Unix server ?

Caution: not tested.

It can be. Run fetchfml on Windows 2000 or NT4 and run MTA on Unix.

9. Can we initialize ML ?

It is easy to run rmml once and newml again.

% makefml rmml elena
% makefml newml elena

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 5. Create ML On Unix

Run "makefml newml" To Create An ML (In The Case Of Default Domain)

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The usage of fml8 makefml is same as fml4 in the case of default domain. But芍
芍differs in the virtual domain case. See  the Section called Run "makefml    芍
芍newml" To Create An ML (In The Case Of Virtual Domain) for the virtual      芍
芍domain case.                                                                芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

To create an ML, use "makefml" command (CUI) in the same way as fml4.

% su fml
% makefml newml elena
   ... snip ...

In the case of non default domain (virtual domain), run "makefml newdomain"
command before running "makefml newml".

% su root
# makefml newdomain fml.org /var/spool/virtual/fml.org
# exit
% su fml
% makefml newml elena
   ... snip ...

"makefml newml" processes the following steps.

 ’ Create files such as

            config.cf
            include
            include-ctl


    at /var/spool/ml/elena. The domain name et.al. in these files is replaced
    to proper value.

 ’ Add elena ML entry into /var/spool/ml/etc/mail/aliases. Run postalias to
    rebuild /var/spool/ml/etc/mail/aliases.db.

 ’ Create ~fml/.qmail-* files for qmail.

 ’ Update procmailrc as a sample.

 ’ Prepare the directory

            ~fml/public_html/fml/mlarchive/$domain/$ml/


    for html archive. For example, for elena@fml.org

            ~fml/public_html/fml/mlarchive/fml.org/elena/


    is creatd. HTML archive of ML articles is created by default.

 ’ Prepare CGI (GUI). Set up

            ~fml/public_html/cgi-bin/fml/$domain/admin/config.cgi


    for the master cgi, instead cgi to control one ML $ml@$domain is set up at

            ~fml/public_html/cgi-bin/fml/$domain/ml-admin/$ml/config.cgi


足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Run "makefml newml" To Create An ML (In The Case Of Virtual Domain)

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The usage of makefml differs from fml4. In the case of fml8 firstly use     芍
芍"makefml newdomain" command, in the next run "makefml newml" command. Also  芍
芍ml_name differs. For virtual domain, use ml_name@ml_domain form.            芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

In using "makefml newml", the usage is same as fml4 except for the ml_name.
ml_name part is ml_name@ml_domain in the case of fml8

At the first time to use a virtual domain, run "makefml newdomain" before
"makefml newml".

% su root
# makefml newdomain nuinui.net /var/spool/virtual/nuinui.net
# exit
% su fml
% makefml newml elena@nuinui.net

After the second time, just use "makefml newml".

% su fml
% makefml newml elena@nuinui.net

In running "makefml newdomain", specify a pair of domain and directory in
ml_home_prefix_maps. This command edits /usr/local/etc/fml/ml_home_prefix file
to add the following line.

nuinui.net /var/spool/virtual/nuinui.net

To remove this line, use "makefml rmdomain".

The usage of "makefml newml" command is same as in the case of default domain.

"makefml newml" creates an example of virtual domain configurations for several
MTA's such as

/var/spool/ml/etc/sendmail/virtusertable
/var/spool/ml/etc/postfix/virtual

. No example for qmail (not needed). No example for procmail since .procmailrc
contains domain.

See the chapter of virtual domain for more details.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

MTA Configuration (postfix)

    Important: If $alias_maps of Postfix is properly set up, "makefml newml"
    automatically prepares fml and postfix configuration for the new ML.

    See  the Section called MTA Configuration (postfix) in Chapter 4 for the
    detail of postfix configuration.

"makefml" does not update system aliases (e.g. /etc/mail/aliases), but updates
only alias file $ml_home_prefix/etc/mail/aliases file, which is used only for
fml. "makefml" rebuilds $ml_home_prefix/etc/mail/aliases.db automatically, too.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

NOTE: Format Of /var/spool/ml/etc/mail/aliases

$ml_home_prefix/etc/mail/aliases has the following entry for elena@home.fml.org
ML.

### <ALIASES elena@home.fml.org ML> ###

# address for post
elena: :include:/var/spool/ml/elena/include
owner-elena: fukachan

# address for command
elena-ctl: :include:/var/spool/ml/elena/include-ctl
owner-elena-ctl: fukachan

# maintainer
elena-request: elena-admin
elena-admin: fukachan, elena-error

# error analyzer
elena-error: :include:/var/spool/ml/elena/include-error
owner-elena-error: fukachan

### </ALIASES elena@home.fml.org ML> ###

In the case of virtual domain, $ml_home_prefix varies with $virtual_maps.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

MTA Configuration (qmail)

"makefml newml" creates the following files for qmail:

~fml/.qmail-fml:org-elena
~fml/.qmail-fml:org-elena-admin
~fml/.qmail-fml:org-elena-ctl
~fml/.qmail-fml:org-elena-default
~fml/.qmail-fml:org-elena-request

Hence, if /var/qmail/control/virtualdomains contains the following definition

fml.org:fml-fml.org

you have only to run "makefml newml" to create an ML in the case of qmail.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍This configuration assumuss ML's uses the whole one domain only for mailing 芍
芍list.                                                                       芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Virtual Domain

The logic is same as above. So you need to edit /var/qmail/control/
virtualdomains to make an ML effective automatically when you runs "makefml
newml". This edit needs root priviledge. Please contact the administrator on
it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Customize config.cf

In running "makefml newml", makefml sets up configuration files such as
config.cf, include files for sendmail and postfix and ~fml/.qmail-* files.

% su fml
% makefml newml elena
   ... snip ...
% ls /var/spool/ml/elena
config.cf include include-ctl include-error
        ... snip ...

To customize one ML configuraiton, edit config.cf.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍menu tool to edit config.cf is incomplete.                                  芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

config.cf contains little definition. For example, /var/spool/ml/elena/include
file follows:

"| /usr/local/libexec/fml/distribute elena@fml.org"

/var/spool/ml/elena/include-ctl file follows:

"| /usr/local/libexec/fml/commande elena@fml.org"

/usr/local/libexec/fml/PROGMAR resolves ml_name and ml_domain from the
arguments such as elena@fml.org. That is, elena@fml.org in this argument
determines values of $ml_domain and $ml_name. It is enough that ml_name and
ml_domain in config.cf is a comment.

The content of include, include-ctl and aliases are same as fml4 except for the
path.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. Specify administrator's mail address in alias file when "newml" command
    runs.
2. Not create a configuration file for a specific MTA not used.

1. Specify administrator's mail address in alias file when "newml" command
runs.

CUI (makefml/fml) creats an alias in "newml".

${ml_name}-admin: ADDRESS

where ADDRESS is defined by $newml_command_ml_admin_default_address. By
default, $newml_command_ml_admin_default_address == $fml_owner defined in /usr/
local/etc/fml/main.cf file. To change the value, specify
$newml_command_ml_admin_default_address in site_default_config.cf.

$newml_command_ml_admin_default_address = YOUR_ADDRESS

You can use $ml_name here.

$newml_command_ml_admin_default_address = $ml_name-owner@$ml_domain

2. Not create a configuration file for a specific MTA not used.

$newml_command_mta_config_list defines list of MTA. "makefml newml" command
creates examples of the specified MTA's. Remove the specific MTA from the list
to disable example creation.

For example, you do not need "qmail" configuration example

newml_command_mta_config_list -= qmail

fml8 does not generate ~/.qmail-* files.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 6. fml8 installation on Microsft 2000/NT

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍not yet implemented.                                                        芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 7. Convert fml4 Style ML To fml8 Style ML

2004/03: We have implemented a converter which converts ML HOME DIRECTORY
($DIR) such as /var/spool/ml/elena ($ml_home_dir in fml8) from fml4 style to
fml8 style. It is incomplete but is being developed.

2004/11: You can replace fml.pl of fml4 with fml.pl of fml8. now. It means that
fml8 directly emulates fml4. It enables easy upgrade from fml4 to fml8.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview: fml4 To fml8 (1)

It is a little wrong that fml8 works if fml8 overwrites fml4 programs.
Currently fml8 can work but it needs automatic conversion in the background.
Hence, fml8 modifies fml4 to emulate fml4.

Firstly there is a problem. You want to upgrade all ML's at the same time from
fml4 to fml8? It is better to upgrade from one to one ? When something fails,
you want to downgrade your system if could.

We want to support both types. So it is available that some ML's are fml8,
other ML's are fml4 in one domain simultaneously. Downgrading if needed are
supported.

One example of upgrade operation follows:

1. install fml8

2. (in the case of Postfix) add fml8 aliases to postfix's alias_maps.

   Example:
        alias_maps      =       hash:/etc/mail/aliases
                                hash:/var/spool/ml/etc/aliases (fml4)
                                hash:/var/spool/ml/etc/mail/aliases (fml8)


3. convert fml4 ML to fml8 one.

   fml $ml mergeml fml4's$DIR
for example,
   fml elena mergeml /var/spool/ml/elena

Apply 3. for ML's which would be converted to fml8.

You can use "makefml mergeml" command to convert aliases, include files, fml4
configuration files and member lists from fml4 to fml8.

It is not easy to convert difficult fml4's config.ph file. Now we can convert
simple config.ph to fml8 config.cf style file automatically. We suppose this
simple config.ph is generated by fml4's "makefml config" command.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview: Convert fml4 To fml8 (2)

2004/11: you can replace fml4's fml.pl with fml8's fml.pl.

Configure like this.

[1. Install fml8]

% su fml
% sh configure
% su root
# make install

[2. Emulate fml4]

# mv /usr/local/fml/fml.pl /usr/local/fml/fml.pl.orig
# ln -s /usr/local/libexec/fml/fml.pl   /usr/local/fml/fml.pl
# ln -s /usr/local/libexec/fml/msend.pl /usr/local/fml/msend.pl
# ln -s /usr/local/libexec/fml/mead.pl  /usr/local/fml/libexec/mead.pl

Precisely fml8 can not read fml4 configuration file. If fml8's fml.pl cannot
find config.cf, it tries to convert config.ph in ML's home directory to fml8
config.cf, read it and starts to run.

The conversion is incomplete but fml8 can convert simple configurations
manipulated by fml4 CUI or GUI.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview: Difference Between fml4 and fml8

There are several fml8 variables and functions not related with fml4 since fml8
is re-designed and re-coded from scratch.

Also not one to one even if the relation found.

Let's see a few examples below.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Anyone Can Post

Users registered as members can post ML by default. This default behaviour is
common between fml4 and fml8. To set "anyone can post", in the case of fml4,

$PERMIT_POST_FROM = "anyone";

in the case of fml8,

article_post_restrictions = reject_system_special_accounts
                            permit_anyone
                            reject

.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Subject Tag

No subject tag defined by default. This is common between fml4 and fml8 To set
the tag such as '[ML_NAME:00100]', in the case of fml4,

$SUBJECT_TAG_TYPE = '[:]';

This corresponds to the following fml8 configuration:

article_header_rewrite_rules = rewrite_article_subject_tag

article_subject_tag           = [$ml_name:%05d]

fml8 configuration concepts are more orthogonal.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Disable Specific Command In Command Mail

Commands such as "members" are prohibited in fml8 by default. fml4 needs the
following configurations to disable dangerous commands:

&DENY_PROCEDURE('member');
&DENY_PROCEDURE('active');
&DENY_PROCEDURE('members');
&DENY_PROCEDURE('actives');
&DENY_PROCEDURE('status');
&DENY_PROCEDURE('stat');

Old fml4 use no filter by default but fml8 uses filter by default.

fml8 applies confirmation for subscribe, chaddr, unsubscribe commands by
default. fml4 not. Currently fml8 always applies confirmation, which can not be
disabled by configuration.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion

"makefml mergeml" command processes the following steps automatically.

To clarify details more, explain conversion of aliases and include files below.

Our purpose is to run fml8 anyway. If fml8 runs, converter of config.ph runs
too. So, we need MTA runs fml4 and fml4 runs fml8.

Explain more details. Consider ML driver internal section.

For example, when you use Postfix, Postfix reads aliases and recognizes it
needs to read include file. By reading include file, Postfix knows how to call
fml8 process. Finally, postfix runs /usr/local/libexec/fml/distribute command.

Executed distribute command reads config.cf and knows the location of member
lists and processes et.al.

That is, when fml8 process starts, the following two phases

aliases (MTA configuration)
include

ends.

It is mandatory that no duplication in aliases files. For example, if /etc/
postfix/main.cf contains the following configuration:

alias_maps      =       hash:/etc/mail/aliases
                        hash:/var/spool/ml/etc/aliases (fml4)
                        hash:/var/spool/ml/etc/mail/aliases (fml8)

aliases of fml4 and fml8 should not have duplication.

In othe words, in the case of fml4 process,

MTA -> fml4's aliases -> fml4's include -> fml4 (fml.pl) runs

in the case of fml8 process,

MTA -> fml8's aliases -> fml8's include -> fml8 runs

So we need the following condition:

remove the ml from fml4's aliases file.
add the ml to fml8's aliases file.

If no duplication in aliases, both fml4 and fml8 runs on the same host.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 8. Difference Between fml4 And fml8

In this chapter, we describe the difference beetween fml4 and fml8

Intuitively fml4 vs fml8 is equal to sendmail vs Postfix. It is good image.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Difference Between fml4 And fml8: License.

Roughly speaking, fml8 license is composed of Artistic, BSD or GPL. A part of
fml8 is either of them.

In the case of fml4, almost all codes are written by fml project. The license
of such codes is GPL. jcode.pl and some perl modules are exceptions.

In the case of fml8, the source tree has sub tree which is divided according to
the license. For example, the license of fml/ sub tree is Artictic, cpan/ is
Artistic or GPL, gnu/ is GPL and img/ is BSD. See the license files under them
on the detail.

It is easy to remove some licensed files since the sub-tree is license based.

fml8 installs all modules of the tree into the proper path, so installed
modules are hybrid of licenses. You need to clarify the license before
installation.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Difference Between fml4 And fml8: Command Mail And Error Messages.

fml8 selects language of the return mail for command mail and error messages by
Accept-Language of the incoming message and other information. See  Chapter 33
for more details.

In sending back files or messages, fml8 uses MIME/Multipart. tar.gz and zip
formats are not supported..

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Difference Between fml4 And fml8: CUI

There are two CUI: makefml and fml. The syntax of the two is different.

makefml COMMAND ML OPTIONS
fml     ML COMMAND OPTIONS

The only difference is the order of command argument.

fml4 command shows processing information as could as possible. Instead fml8
command runs as could as silently since it is proper for automatic process. [4]
This behaviour is UNIX style.

Table 8-1. Difference between fml4 and fml8: CUI

見芋芋芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍   Content    芍          fml4          芍              fml8              芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml help ML".      芍                                芍
芍              芍"makefml info ML" is    芍                                芍
芍show help     芍same as "makefml help   芍not implemented.                芍
芍              芍ML". If the environment 芍                                芍
芍              芍variable PAGER, use it  芍                                芍
芍              芍as pager.               芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍run "make install" at   芍run "configure" and "make       芍
芍installation  芍the source top          芍install" at the source top      芍
芍of fml        芍directory. In fact "make芍directory. In fact "make        芍
芍              芍install" executes       芍install" executes install.pl    芍
芍              芍"makefml install".      芍script.                         芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍interactive by default. 芍not interactive. You can use    芍
芍Behaviour of  芍You can use interactive 芍configure for most important    芍
芍install script芍menu for most important 芍options.                        芍
芍              芍options.                芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍create ML     芍"makefml newml ML" or   芍makefml newml ML                芍
芍              芍"makefml new ML"        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍templates of  芍                        芍                                芍
芍alias files   芍only for sendmail (also 芍all for postfix, sendmail,      芍
芍"makefml      芍used as postfix for     芍qmail, procmail MTA's.          芍
芍newml"        芍compatibility).         芍                                芍
芍generates.    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍alias file    芍                        芍                                芍
芍path "makefml 芍/var/spool/ml/etc/      芍/var/spool/ml/etc/mail/aliases  芍
芍newml"        芍aliases                 芍                                芍
芍generates.    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍how to        芍                        芍                                芍
芍generate qmail芍makefml qmail-setup ML  芍"makefml newml" generates it.   芍
芍configuration 芍                        芍                                芍
芍files.        芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍re-generate   芍makefml                 芍not implemented.                芍
芍aliaes.       芍recollect-aliases ML    芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍remove ML     芍makefml destructml ML   芍makefml rmml ML                 芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍how to set up 芍run "makefml mead ML"   芍                                芍
芍error         芍and set up aliases      芍enabled by default.             芍
芍analyzer.     芍properly.               芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍test of fml   芍makefml test ML         芍not implemented                 芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍makefml fmlserv ML      芍                                芍
芍LISTSERV style芍listserv majordomo is   芍not implemented                 芍
芍server.       芍same as.                芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml add ML         芍"makefml subscribe ML ADDRESS". 芍
芍              芍ADDRESS". "makefml      芍Other 4 commands (add subscribe 芍
芍subscribe (add芍adduser ML ADDRESS" is  芍adduser useradd) are same as    芍
芍addess to     芍same. the changes is    芍subscribe. No message is shown  芍
芍member and    芍shown after the         芍unless error occurs. This       芍
芍recipient     芍operation. This         芍operation is applied to         芍
芍list)         芍operation is applied to 芍$primary_recipient_map and      芍
芍              芍both actives and members芍$primary_member_map (recipients 芍
芍              芍files.                  芍and members files actually).    芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍                        芍"makefml unsubscribe ML         芍
芍              芍"makefml bye ML         芍ADDRESS". Other 7 commands ( bye芍
芍              芍ADDRESS". byeuser is    芍unsubscribe deluser remove      芍
芍remove address芍same. the changes is    芍resign signoff userdel ) are    芍
芍from recipient芍shown after the         芍same as unsubscribe. No message 芍
芍and member    芍operation. This         芍is shown unless error occurs.   芍
芍list.         芍operation is applied to 芍This operation is applied to    芍
芍              芍both actives and members芍$primary_recipient_map and      芍
芍              芍files.                  芍$primary_member_map (recipients 芍
芍              芍                        芍and members files actually).    芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml chaddr ML      芍"makefml chaddr ML OLD_ADDRESS  芍
芍              芍OLD_ADDRESS             芍NEW_ADDRESS". No message is     芍
芍change address芍NEW_ADDRESS". the       芍shown unless error occurs. This 芍
芍(in recipient 芍changes is shown after  芍operation is applied to         芍
芍and member    芍the operation. This     芍$primary_recipient_map and      芍
芍list)         芍operation is applied to 芍$primary_member_map (recipients 芍
芍              芍both actives and members芍and members files actually).    芍
芍              芍files.                  芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml addactives ML  芍                                芍
芍              芍ADDRESS". Commands      芍"makefml addactives ML ADDRESS  芍
芍add address to芍(addactive add2active   芍". No message is shown unless   芍
芍only recipient芍add2actives) are same.  芍error occurs. This operation is 芍
芍list          芍the changes is shown    芍applied to                      芍
芍              芍after the operation.    芍$primary_recipient_map          芍
芍              芍This operation is       芍(recipients file actually).     芍
芍              芍applied to actives file.芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml addmembers ML  芍                                芍
芍              芍ADDRESS". Commands      芍"makefml addmembers ML ADDRESS".芍
芍add address to芍(addmember add2member   芍No message is shown unless error芍
芍only member   芍add2members) are same.  芍occurs. This operation is       芍
芍list.         芍the changes is shown    芍applied to $primary_member_map  芍
芍              芍after the operation.    芍(members file actually).        芍
芍              芍This operation is       芍                                芍
芍              芍applied to members file.芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml off ML         芍"makefml off ML ADDRESS". No    芍
芍              芍ADDRESS". skip is same  芍message is shown unless error   芍
芍disable real  芍as off. the changes is  芍occurs. This operation is       芍
芍time delivery 芍shown after the         芍applied to                      芍
芍              芍operation. This         芍$primary_recipient_map          芍
芍              芍operation is applied to 芍(recipients file actually).     芍
芍              芍actives file.           芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍                        芍"makefml digestoff ML ADDRESS"  芍
芍              芍"makefml on ML ADDRESS".芍or "makefml digest ML ADDRESS   芍
芍enable real   芍the changes is shown    芍off". No message is shown unless芍
芍time delivery.芍after the operation.    芍error occurs. This operation is 芍
芍              芍This operation is       芍applied to                      芍
芍              芍applied to actives file.芍$primary_recipient_map          芍
芍              芍                        芍(recipients file actually).     芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml matome ML      芍"makefml digeston ML ADDRESS" or芍
芍              芍ADDRESS". digest is     芍"makefml digest ML ADDRESS on". 芍
芍change real   芍same. the changes is    芍No message is shown unless error芍
芍time to digest芍shown after the         芍occurs. This operation is       芍
芍delivery.     芍operation. This         芍applied to                      芍
芍              芍operation is applied to 芍$primary_recipient_map          芍
芍              芍actives file.           芍(recipients file actually).     芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml addadmin ML    芍"makefml addadmin ML ADDRESS".  芍
芍add a remote  芍ADDRESS". the changes is芍No message is shown unless error芍
芍administrator 芍shown after the         芍occurs. This operation is       芍
芍address.      芍operation. This         芍applied to recipients-admin and 芍
芍              芍operation is applied to 芍members-admin.                  芍
芍              芍members-admin file.     芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍"makefml byeadmin ML    芍"makefml byeadmin ML ADDRESS".  芍
芍remove a      芍ADDRESS". the changes is芍No message is shown unless error芍
芍remote        芍shown after the         芍occurs. This operation is       芍
芍administrator 芍operation. This         芍applied to recipients-admin and 芍
芍address.      芍operation is applied to 芍members-admin.                  芍
芍              芍members-admin file.     芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍                                芍
芍password of   芍"makefml passwd ML".    芍"makefml passwd ML" (incomplete 芍
芍remote        芍interactive.            芍?)                              芍
芍administrator 芍                        芍                                芍
芍(1).          芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍                                芍
芍password of   芍"makefml passwd ML      芍"makefml passwd ML ADDRESS".    芍
芍remote        芍ADDRESS" interactive.   芍interactive.                    芍
芍administrator 芍                        芍                                芍
芍(2).          芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍"makefml passwd ML      芍"makefml passwd ML ADDRESS      芍
芍password of   芍ADDRESS PASSWORD". the  芍PASSWORD". No message is shown  芍
芍remote        芍changes is shown after  芍unless error occurs. This       芍
芍administrator 芍the operation. This     芍operation is applied to etc/    芍
芍(3).          芍operation is applied to 芍passwd-admin file.              芍
芍              芍etc/passwd file.        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍menu style    芍                        芍                                芍
芍configuration 芍makefml config ML       芍incomplete.                     芍
芍tool.         芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍edit          芍"makefml edit ML". Ask  芍"makefml edit ML". Not ask the  芍
芍configuration 芍the editor to use before芍editor to use before running.   芍
芍file.         芍running. "vi" by        芍use environment variable EDITOR 芍
芍              芍default.                芍if specified. "vi" by default.  芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fml4 specific 芍"makefml update-config  芍                                芍
芍configuration 芍ML". Commands (update   芍                                芍
芍file          芍config-update           芍no corresponding idea (one      芍
芍conversion    芍update-config.ph) are   芍configuration file).            芍
芍(generate cf  芍same. the operations is 芍                                芍
芍to config.ph) 芍shown.                  芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍edit cf       芍makefml config-template 芍                                芍
芍template by   芍ML                      芍not implemented                 芍
芍menu.         芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍edit template 芍makefml edit-template   芍                                芍
芍files "makefml芍FILE list up available  芍not implemented                 芍
芍newml" uses   芍file list unless FILE   芍                                芍
芍              芍specified.              芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍re-generate   芍                        芍                                芍
芍files e.g.    芍makefml                 芍                                芍
芍help at the ml芍create-doc-template ML  芍no corresponding idea.          芍
芍home          芍                        芍                                芍
芍directory.    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍convert SRC   芍                        芍                                芍
芍file to DST   芍                        芍                                芍
芍file with     芍makefml conv ML SRC DST 芍not implemented                 芍
芍variable      芍                        芍                                芍
芍conversion.   芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍see log (the  芍"makefml log ML [OPTION]芍"makefml log ML". options are   芍
芍last 100 lines芍". "makefml tail ML" is 芍not implemented.                芍
芍shown).       芍same.                   芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍                                芍
芍admin.cgi     芍                        芍                                芍
芍(scripts and  芍"makefml admin.cgi ML". 芍incomplete.                     芍
芍apache        芍interactive.            芍                                芍
芍configuration 芍                        芍                                芍
芍helper).      芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍                                芍
芍ml-admin.cgi  芍"makefml ml-admin.cgi   芍                                芍
芍(scripts and  芍ML". "makefml           芍incomplete.                     芍
芍apache        芍mladmin.cgi ML" is same.芍                                芍
芍configuration 芍interactive.            芍                                芍
芍helper).      芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍makefml                 芍                                芍
芍.htpasswd for 芍html_cgiadmin_passwd ML 芍not implemented                 芍
芍admin.cgi.    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍html_config   芍                        芍                                芍
芍(makefml      芍makefml html_config ML  芍not implemented                 芍
芍internal use  芍html_config_set is same.芍                                芍
芍command)      芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍                                芍
芍.htpasswd for 芍                        芍                                芍
芍ml-admin.cgi  芍                        芍                                芍
芍and the       芍makefml html_passwd ML  芍not implemented                 芍
芍password of   芍                        芍                                芍
芍admin command 芍                        芍                                芍
芍mail.         芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍                                芍
芍.htpasswd for 芍makefml htpasswd ML     芍not implemented                 芍
芍ml-admin.cgi. 芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍pgp command   芍makefml pgp ML          芍fmlpgp                          芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍pgp2 command  芍makefml pgp2 ML         芍fmppgp2                         芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍pgpe command  芍makefml pgpe ML         芍fmlpgpe                         芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍pgpk command  芍makefml pgpk ML         芍fmlpgk                          芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍pgps command  芍makefml pgps ML         芍fmlpgps                         芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍pgpv command  芍makefml pgpv ML         芍fmlpgpv                         芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍gpg command   芍makefml gpg ML          芍fmlgpg                          芍
芍wrapper       芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin-auth    芍                        芍                                芍
芍(PGP, GPG KEY 芍makefml admin-auth ML   芍fmlpgp* command                 芍
芍RING          芍                        芍--admin-command-mail-auth       芍
芍operation)    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin-encrypt 芍                        芍                                芍
芍(PGP, GPG KEY 芍makefml admin-encrypt ML芍not implemented                 芍
芍RING          芍                        芍                                芍
芍operation)    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍dist-auth     芍                        芍                                芍
芍(PGP, GPG KEY 芍makefml dist-auth ML    芍fmlpgp* command                 芍
芍RING          芍                        芍--article-post-auth             芍
芍operation)    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍dist-encrypt  芍                        芍                                芍
芍(PGP, GPG KEY 芍makefml dist-encrypt ML 芍fmlpgp* command                 芍
芍RING          芍                        芍--article-post-encrypt          芍
芍operation)    芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up popfml 芍                        芍                                芍
芍(emulate MTA  芍makefml popfml          芍fetchfml                        芍
芍and ML via    芍                        芍                                芍
芍POP).         芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍                        芍write password in configuration 芍
芍password for  芍makefml pop_passwd      芍file config.cf.                 芍
芍POP.          芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍              芍                        芍not implemented (no             芍
芍lock ML.      芍makefml lock ML         芍corresponding idea, no giant    芍
芍              芍                        芍lock).                          芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍create a      芍makefml                 芍                                芍
芍template of   芍bug-report-template ML  芍not implemented                 芍
芍bug report.   芍send-pr is same.        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍execute       芍makefml command ML      芍not implemented                 芍
芍command.      芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍set up        芍makefml delivery_mode ML芍not implemented                 芍
芍delivery mode.芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍change        芍                        芍                                芍
芍configuration 芍                        芍                                芍
芍variable in   芍makefml setq ML         芍-o options.                     芍
芍running       芍                        芍                                芍
芍makefml.      芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍show          芍                        芍                                芍
芍environment   芍makefml showconfig ML   芍not implemented / no plan       芍
芍summary where 芍showconf is same.       芍                                芍
芍fml runs.     芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍show OS       芍                        芍                                芍
芍information by芍"makefml show".         芍not implemented / no plan       芍
芍"show COMMAND"芍                        芍                                芍
芍style command.芍                        芍                                芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍send a file.  芍makefml resend ML       芍not implemented / no plan       芍
豆芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍upgrade       芍                        芍                                芍
芍command:      芍                        芍                                芍
芍convert fml   芍makefml upgrade ML      芍not needed                      芍
芍2.0 to fml    芍                        芍                                芍
芍3.0.          芍                        芍                                芍
谷芋芋芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Difference Between fml4 And fml8: GUI (CGI)

In the case of fml4, you need to set up .cgi scripts and apache configurations
after installation.

In the case of fml8, "makefml newml" generates GUI scripts except for the
apache configurations.

Interface differs a lot. The interface of fml4 GUI is classical. That of fml8
is table based by default.

It is a TODO to select GUI skin dynamically.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

File Naming Convention

See  Chapter 16 for the file naming convention. You need not to know the
detail, since the conversion tools convert files from fml4 style to fml8 one.
But it is useful to know it to see files.

The policy to handle member list and recipient list separately is same. But the
file name differs.

The file name is "filename-role" style. The role is abbreviated if the role is
default.

"actives" is renamed to "recipients". The meaning is clear. Instead "members"
is "members".

"members-admin" is same. "recipients-admin" exists virtually but is is not
used.

"etc/passwd" is renamed to "etc/passwd-admin". The format differs a little.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 9. Upgrade And Downgrade Of fml8

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍This chapter describes upgrade and downgrade of fml8.                       芍
芍                                                                            芍
芍See  Chapter 7 on the upgrade from fml4 to fml8.                            芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Upgrade

Install again.

After fml8 installation, rewrite fml_version line in /usr/local/etc/fml/main.cf
to switch fml to the version installed now. Just when the file is saved, fml is
changed to the new version.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

downgrade.

No need to install. Edit /usr/local/etc/fml/main.cf to back the fml_version to
the previous one.

Just when the file is saved, fml is changed to the new version.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 10. Configure CGI

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍See the section  the Section called Method in Chapter 38 for CGI Internal   芍
芍details.                                                                    芍
芍                                                                            芍
芍We assumes you use suexec under apache.                                     芍
芍                                                                            芍
芍Now fml8 provides both the master cgi to control all ML's in one domain and 芍
芍a cgi for each ML. You can add and remove a user, or view member list et.al.芍
芍by this interface. Editing of configuration on this cgi is incomplete.      芍
芍                                                                            芍
芍If you use postfix and qmail, you do not need to modify MTA configuration   芍
芍for cgi specific reason.                                                    芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

"makefml newml" Creates CGI Script Always

"makefml newml" sets up CGI scripts such as config.cgi under ~fml/public_html
/... directory. There are two types of cgi scripts. One is for the whole
domain, one for each ML.

In creating elena@fml.org ML, makefml creates the following cgi

http://lists.fml.org/~fml/cgi-bin/fml/$domain/admin/config.cgi

[Example]
http://lists.fml.org/~fml/cgi-bin/fml/fml.org/admin/config.cgi

for all ML's of fml.org.

To control only elena ML, please use

http://lists.fml.org/~fml/cgi-bin/fml/$domain/ml-admin/${ml_name}/config.cgi

[Example]
http://lists.fml.org/~fml/cgi-bin/fml/fml.org/ml-admin/elena/config.cgi

[cgi]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Edit .htaccess

.htaccess is created but it is configured to deny all.

http://lists.fml.org/~fml/cgi-bin/fml/$domain/.htaccess

[Example]
http://lists.fml.org/~fml/cgi-bin/fml/fml.org/.htaccess

The default .htaccess is a dummy like this:

AuthName ByPassword
AuthType Basic
require valid-user

Please edit .htaccess properly.

Apache does not support ~user style access by default. Please set up apache to
enable it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example: Master Cgi

The role of this cgi is same as limited makefml (CUI). Though this cgi permits
ML creation and destruction, all functions makefml has are not supported. The
function is limited.

Eample: TOP MENU

                     @home.fml.org CGI for configuration

fml admin menu             fml CGI interface for @home.fml.org ML's
mailing list:
[elena]
command:                .. help message ...
[subscribe  ]
[submit][reset]
                     subscribe
                     unsubscribe
                     addadmin
                     byeadmin
options Language:    list
[Japanese] [change]  log
                     newml
                     rmml

[cgi]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI Example: Create ML

Select newml and push "submit". No need to select ML name in this stage.

You find another menu at the center. Specify the ML name you create and push
"submit" at the center.

[cgi]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI Example: subscribe

Specify the ML name and select "subscribe", push "submit".

You find another menu at the center. Specify the address to subscribe and push
"submit" at the center.

[cgi]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI Skin Selection

config.cgi is TABLE and SELECT based. If you use old style menu, use menu.cgi.

for a whole domain
~fml/public_html/fml/DOMAIN/admin/menu.cgi

for a ml
~fml/public_html/fml/DOMAIN/ml-admin/menu.cgi

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 11. Apache Configuration

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍See  the Section called Method in Chapter 38 for the fml8 CGI internals.    芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Use Suexec Of Apache

Build apache enabled with suexec. Run configure by

(apache 1.x)
configure --enable-suexec --suexec-caller=www

In this case, the user "www" can call suexec. Please prepare a user specific
for suexec-ed environment.

After apache installation, change httpd.conf to allow ~user/cgi-bin/ form.

Example:

<Directory /home/*/*/public_html>
    AllowOverride FileInfo AuthConfig Limit
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec ExecCGI
    <Limit GET POST OPTIONS PROPFIND>
        Order allow,deny
        Allow from SPECIFIC_HOST
    </Limit>
</Directory>

<IfModule mod_mime.c>
        ... snip ...

   AddHandler cgi-script .cgi

        ... snip ...
</IfModule>

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 12. Test

Before Test

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Set up MTA properly before test of fml.                                     芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

In this chapter, fml8 and MTA works on ahodori.fml.org, which is called as the
mail server.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Test Of MTA

Firstly, check MTA without fml on ahodori.fml.org.

Prepare one personal user address such as rudo@fml.org. Usually, just create a
user named as "rudo".

# useradd rudo

Check you can send a mail to rudo@fml.org on ahodori.fml.org and rudo receives
the mail.

% echo test |Mail rudo@fml.org

If it not works, check MTA configuration. See /var/log/maillog et.al to track
errors.

Secondary, verify mail delivery over network. Send a mail to rudo@fml.org from
other host (not ahodori.fml.org). If rudo receives the mail, MTA is o.k.

If both work well, MTA configuration must be ok.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Send A Mail To ML

Create elena ML (elena@fml.org) and subscribe rudo@fml.org to elena ML.

% su fml
% makefml newml elena
% makefml add elena rudo@fml.org

Send a test mail to elena@fml.org from on the host and from other host (not
ahodori.fml.org). Verify the header of this test mail should be "From:
rudo@fml.org" since fml8 checks the From: header field.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Checkpoints

If something not work well, check the following points:

check the mail server log (e.g. /var/log/maillog)
check the fml log (e.g. /var/spool/m/elena/log)
fml can pass the message to MTA ? (e.g. /var/spool/m/elena/log)
MTA succeeds to deliver it? (e.g. /var/log/maillog)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Test Of fml8 Itself.

*** not yet implemented ***.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Reset After Test.

It is easy to re-create this mailing list (e.g. test ML).

% su fml
% makefml rmml test
% makefml newml test

The removed ML home is left as /var/spool/ml/@test.$DATE.$SEQUENCE. Please
remove it since this is a test to avoid the duplication in the future.

% rm -fr /var/spool/ml/@test.$DATE.*

III. How To Customise

Topics driven in this part.

Table of Contents
13. What A User Can
14. What Can You Do On The Mailing List Server
15. Modify Configuration Files
16. [Caution] File Names
17. Case Studies Of Customization
18. Header Rewriting
19. Extend Command
20. Filtering
21. Extend Message
22. Be ML Articles public via WWW

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 13. What A User Can

Get ML Guide

Send the mail with

guide

to elena-ctl@fml.org address. fml8 sends back the guide message to the sender.

If a file named "guide" is found at $ml_home_dir, it is used as a message
template.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Subscribe

Suppose elena@fml.org ML. Firstly, send the mail with

subscribe YOUR-NAME

to elena-ctl@fml.org address.

fml8 sends back the confirmation to both addresses. Please send back the reply
for the confirmation to elena-ctl@fml.org again. When your reply to the
confirmation is confirmed to be valid, fml8 add the address as a new ML member.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Posting Article

Send a mail to elena@fml.org. MTA running on the mailing list server host (on
e.g. ahodori.fml.org) receives the mail and finally kicks off /usr/local/
libexec/fml/distribute command.

"distribute" command recieves the message from STDIN, rewrites the header, save
it in the spool directory and pass it back to MTA for delivery.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Distribution Process

1) fml8 adds a tag to the subject, update the article sequence number.

Example:

Subject: [elena:00100] teddy bear is cute.

(no tag by default).

2) save article (as a text file).

3) create a HTML version of the article under ~fml/public_html/ directory.

4) update database (udb) on thread.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Variables

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍*** sorry, not yet written ***                                              芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example: Boot Sequence Of Distribute Process

fml boot loader boots off in the following way.

/usr/local/libexec/fml/distribute command is symlink-ed to /usr/local/libexec/
fml/loader. These files are same.

/usr/local/libexec/fml/loader reads /usr/local/etc/fml/main.cf firstly.
$fml_vesrion such as "current-20010501" is defined in the main.cf. fml8
resolves $fml_version from it and determines the library path as /usr/local/lib
/fml/current-20010501/. fml8 loads perl modules under it.

fml8 sets up @INC properly. fml loader loads FML::Process::Switch module and
check $0 (process name). fml knows the process role from $0. In this case of
distribute, fml loads FML::Process::Distribute module (defined as /usr/local/
etc/fml/$fml_version/modules), switch itself to it and processes distribution.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Help: When You Want To know The Usage

Send the mail with

help

to elena-ctl@fml.org address. It sends back the help message to the sender.

If a file named "help" is found at $ml_home_dir, it is used as a message
template.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Get Past Articles

Send the mail with

get NUMBER

to elena-ctl@fml.org address where NUMBER is the article number. fml8 sends
back articles by mime/multipart form to the sender.

You can use MH style arguments as NUMBER.

[Example]

get 100
get 1-100
get first:3
get last:3
get 1-100,first:3,last:3

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Unsubscribe

In the case of elena@fml.org ML, send the mail with

unsubscribe YOUR-NAME

to elena-ctl@fml.org (control address).

fml8 sends back the confirmation to the sender. Please send back the reply for
the confirmation to elena-ctl@fml.org again. When your reply to the
confirmation is confirmed to be valid, fml8 removes the address.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Command Mail (Control fml By Sending Mail)

fml8 accepts control commands which is sent as a mail. It is called "command
mail".

    Important: The use of CUI (makefml/fml) is basic in fml world. It is
    expected you should use CUI if you can login the mailing list server.

    The role of command mail is to delegate fml control priviledge to users who
    cannot login the mailing list server.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Flow

Consider elena ML. Send the command mail to elena-ctl@fml.org which is the
address for command mail. MTA receives the mail and finally kicks off /usr/
local/libexec/fml/command program. This program receives the mail (command
mail) from STDIN , processes the requests and sends back the result to the
sender. The mail to send back is passed to MTA for delivery via SMTP.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The result is aggreagated to one msssage as MIME/Multipart. This is         芍
芍different from fml4 behaviour.                                              芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Perl Modules For Command Mail

All modules which CUI, GUI and command mail uses are implented as
FML::Command:: class.

In fact, a sub set of FML::Command:: class is allowed as command mail.
$user_command_mail_allowed_commands, $anonymous_command_mail_allowed_commands
and $admin_command_mail_allowed_commands variables defines it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 14. What Can You Do On The Mailing List Server

On the host which serves ML driver, you can use CUI (makefml and fml) and edit
all configuration files as you like. It implies you are the greatest
administrator :)

"makefml" command of fml8 is same as fml4 as could as possible to preserve
compatibility.

See  the Section called Difference Between fml4 And fml8: CUI in Chapter 8 on
the detail of the difference.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

On The Host

You need no confirmation in using makefml.

Person who can login the host of mailing list server has priviledge for all
ML's on the host. So, He/She can edit all configuration files.

But He/She may do wrong operations.

To avoid careless wrong operations, in usual cases you should use CUI (makefml
or fml) to configure fml. Of course you can edit files directly if you can
understand fml structures. By default we recommend you should use CUI always on
the host.

"fml" command is same as "makefml" command except for the argument order.

makefml COMMAND ML OPTIONS
fml     ML COMMAND OPTIONS

Please either as you like.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Policy Of Command Creation

fml8 provides a different command for each function. Its policy makes the
number of commands infinite. So, except for some special cases, we should unify
all functions into makefml/fml command since such commands can be shared among
CUI, GUI and commmnd mail.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Operation May Modify The Specific ML (Read + Write)

We should implement sub-command of makefml/fml when some operation may modify
the specific ML.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Operation For Read Only Data Of The Specific ML (Read Only)

We should implement it as a makefml/fml command since it is related to the
specific ML.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Show The General Data (Read Only)

If the data is not related to the specific ML, for example, see the module
manual, aliases on the host, we implement specific commands other than makefml/
fml. This command name begins with "fml" prefix.

fmladdr  [-n]
fmlalias [-n]
fmldoc   MODULE
fmlconf  [-n] ML

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

ML Specific But A Command Wrapper

PGP / GPG related command (e.g. fmlpgp) is very command speicific. So, it looks
difficult to incorporate them into "makefml" and "fml" framework. So we
implement it as another command such as fmlpgp, fmlgpg, ...

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Misc

We implement specific commands other than makefml/fml. This command name begins
with fml prefix.

For example, "fmlhtmlify" is a conveter from text to html form. This command is
used to convert both fml spool and MH folders.

fmlhtmlify [-I DIR] $src_dir $dst_dir

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Common Command Line Options

Programs under libexec/ and bin/ supports the following common command line
options.

--debug
--help
-c file
-o key=value

Use -c to specify non default main.cf path. -o overwrites configuration
variables. Plural -o are acceptable.

-o key1=value1 -o key2=value2

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Create A New ML

% su fml
% makefml newml ML

If ML without @domain part is specified, the domain of the ML is treated as the
default domain. Both ML and ML@DOMAIN form is o.k. for the default domain.

Example: In the case of default domain:

% makefml newml elena
% makefml newml elena@fml.org

In the case of virtual domain, you should specify the address with the domain
such as user@domain form as ML string.

See the section  Chapter 5 for more details.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Remove An ML

Example:

% su fml
% makefml rmml ML

fml accepts ML string without @domain as the default domain. Both user and
user@domain syntax is acceptable.

Example: in the case of default domain:

% makefml rmml elena
% makefml rmml elena@fml.org

Please use user@domain syntax for virtual domains.

It reverts the action newml did. It removes ML home directory, alias entries
and ~fml/.qmail-*.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Subscribe and Unsubscribe

Use "useradd" commadn to subscribe the user, "userdel" to unsubscribe the user.

Example:

% su fml
% makefml useradd ML ADDRESS
% makefml userdel ML ADDRESS

fml treats ML without @domain part as one of the default domain.

Examle:

% su fml
% makefml useradd elena rudo@nuinui.net
% makefml userdel elena rudo@nuinui.net
% makefml useradd elena@fml.org rudo@nuinui.net
% makefml userdel elena@fml.org rudo@nuinui.net

For convenience, useradd is an acronym. The following commands,


useradd
adduser
subscribe
add

, are same as useradd. In the same way,

userdel
deluser
bye
remove
resign
signoff
unsubscribe

are same as userdel.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Change the registered address

Example:

% su fml
% makefml chaddr ML OLD-ADDRESS NEW-ADDRESS

fml treats ML without @domain part as one of the default domain. For example,

Example: in the case of a virtual domain

% su fml
% makefml chaddr elena rudo@nuinui.net teddy@nuinui.net
% makefml chaddr elena@fml.org rudo@nuinui.net teddy@nuinui.net

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Stop Realtime Delivery

% makefml off elena ADDRESS

Delivery to ADDRESS is switched to digest.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Start Realtime Delivery

% makefml on elena ADDRESS

Delivery to ADDRESS is switched from digest to real time.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

See Log

% makefml log elena
% makefml log elena@fml.org

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

See The Member List

% makefml list elena

It shows recipients of this ML. Also,

% makefml list elena recipient

lists up only recipients of this ML. Instead

% makefml list elena member

shows the list who can post this ML.

You can specify arbitrary MAP as an argument to show it.

% makefml list elena MAP

MAP can be an abbrebiation. For example, you can use "xxx" as MAP to imply
"primary_xxx_map" or "xxx_maps".

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Modify Configuration

Edit config.cf directly now.

Configuration helper tool is incompletely implemented.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Add or Remove A Remote Administrator.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍A remote administor is a person who cannot login to the mail server but     芍
芍control an ML by sending a command mail (which is called "admin command").  芍
芍                                                                            芍
芍Please use CUI to control remote administrators. If you use CUI, you can    芍
芍have priviledge to do since the use of CUI needs login to this host.        芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

[Example]

% su fml
% makefml addadmin ML ADDRESS
% makefml deladmin ML ADDRESS

fml treats ML without @domain part as one of the default domain.

[Example: in the case of a virtual domain]

% su fml
% makefml addadmin elena rudo@nuinui.net
% makefml deladmin elena rudo@nuinui.net
% makefml addadmin elena@fml.org rudo@nuinui.net
% makefml deladmin elena@fml.org rudo@nuinui.net

For convenience,


adminadd
addpriv

are same as addadmin.

byeadmin
byepriv

are same as deladmin.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Add or Remove A Modrator

[Example]

% su fml
% makefml addmoderator ML ADDRESS
% makefml delmoderator ML ADDRESS

fml treats ML without @domain part as one of the default domain.

[Example: in the case of a virtual domain]

% su fml
% makefml addmoderator elena rudo@nuinui.net
% makefml delmoderator elena rudo@nuinui.net
% makefml addmoderator elena@fml.org rudo@nuinui.net
% makefml delmoderator elena@fml.org rudo@nuinui.net

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

"fml" And "makefml" Command

"fml" (/usr/local/bin/fml) and "makefml" (/usr/local/bin/makefml) is same
except for argument order. Please use it as you like.

% fml ML COMMNAD [OPTIONS]

% makefml COMMAND ML [OPTIONS]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Show Addresses (Users + Aliases)

"fmladdr" (/usr/local/bin/fmladdr) lists up all users on this host. It shows
users defined in /etc/passwd and aliases defined in Postfix.

% fmladdr

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The difference between "fmladdr" and "fmlalias" is whether it contains users芍
芍defined at /etc/passwd or not. "fmladdr" contains it but "fmlalias" not.    芍
芍"fmlalias" lists up all users defined at aliases.                           芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Show Alias

fmlalias (/usr/local/bin/fmlalias) shows all aliases. Precisely speaking, it
shows all aliases defined as valid aliases of Postfix.

% fmlalias

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The difference between "fmladdr" and "fmlalias" is whether it contains users芍
芍defined at /etc/passwd or not. "fmladdr" contains it but "fmlalias" not.    芍
芍"fmlalias" lists up all users defined at aliases.                           芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Show Configuration

"fmlconf" (/usr/local/bin/fmlconf) takes ML name as an argument. It shows all
variables of the specified ML. If "-n" option specified, it shows variables
different from default ones.

To list up all variable list,

% fmlconf elena

To list up variables different from the default one,

% fmlconf -n elena

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Show Perl Module Document

The usage of fmldoc is same as perldoc. This is a wrapper for perldoc.

To see FML::Process::Kernel perl module document,

% fmldoc FML::Process::Kernel

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Convert Articles To HTML Form

By default, fml converts the article to HTML form. "fmlhtmlify" command is a
tool to convert all articles to initialize the html archive.

[Usage]

% fmlhtmlify SPOOL_DIRECTORY HTML_ARCHIVE_DIRECTORY

[Example]

% fmlhtmlify /var/spool/ml/elena/spool /some/where/mlarchive/elena

 

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. I've removed ML accidentally. Can I revive it ? (CUI,CGI,admin command)
2. Add an address who can post (CUI,CGI,admin command)
3. Add an address who receive articles but not post.
4. Change registered address.

1. I've removed ML accidentally. Can I revive it ? (CUI,CGI,admin command)

If you have removed ML by running "makefml rmml", please use

% makefml reviveml ML

Same as CGI.

When you use admin command (remote administration), you cannot use this
operation.

If you have removed ML by running "rm -fr /var/spool/ml/elena", you cannot
revive it. Please revive ML from back-up.

2. Add an address who can post (CUI,CGI,admin command)

Usually run

% makefml add ML ADDRESS

If you post from both office and home but want to receive article at office, it
is better to add an address who can post but not receive. It implies we should
add the address to only member_maps.

On the mailing list server host, use makefml.

% makefml addmember ML ADDRESS

The following 4 commands are same function: add2member add2members addmember
addmembers

When you use "admin command", as in same way.

To: elena-ctl@fml.org
Subject:

admin pass PASSWORD
admin addmember ML ADDRESS

CGI does not provide this function now.

3. Add an address who receive articles but not post.

The usage of address, who cannot post but can receive articles, is for such as
mail magazine case.

n the mailing list server host, use makefml.

% makefml addrecipient ML ADDRESS

This ADDRESS is added to only recipient_maps. The following 4 commands are same
function: add2recipient add2recipients addrecipient addrecipients 

The usage is same in "admin command".

To: elena-ctl@fml.org
Subject:

admin pass PASSWORD
admin addrecipient ML ADDRESS

CGI does not provide this function.

4. Change registered address.

On the mailing list server host, use makefml.

% makefml chaddr ML OLD-ADDRESS NEW-ADDRESS

The usage is same in "admin command".

To: elena-ctl@fml.org
Subject:

admin pass PASSWORD
admin chaddr ML OLD-ADDRESS NEW-ADDRESS

"chaddr" command is available in using CGI.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 15. Modify Configuration Files

Change Default For All ML's On Thie Host

Edit /usr/local/etc/fml/site_default_config.cf file. The format is same as
config.cf.

This file corresponds to site_force.ph of fml4.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 16. [Caution] File Names

References: fml-devel 205

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Filename Structure

The fundamental syntax is

FILENAME-ROLE

. For example, fml uses the following syntax for address lists.

recipients-ROLE
members-ROLE

Other than address lists, fml uses similar manner for other type of files. For
example,

passwd-admin
passwd-moderator
passwd-cgiadmin

for several password files.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Address List

primary_recipient_maps  =       recipients

# add actives for backward compatibility
recipient_maps  =       recipients
                        actives

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: List Of Remote Administrators

recipients-admin
members-admin

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: List Of Moderators

recipients-moderator
members-moderator

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Remote Administrator Password Files

etc/passwd-admin

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍etc/passwd, lack of role name, was used in the case of fml4.                芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 17. Case Studies Of Customization

Case Study: Auto File Responder

Modify delivery process ( libexec/distribute ) to send back /some/where/help
file. For example, when a user can send anything to help@fml.org, fml sends
back the help file to the sender.

In this case, set the following at config.cf

article_post_restrictions = permit_anyone

and define the following hook after =cut line.

$distribute_run_start_hook = q{

        $curproc->reply_message( {
                type        => "text/plain; charset=iso-2022-jp",
                path        => "/some/where/help",
                filename    => "help",
                disposition => "help example",
        });

        $curproc->stop_this_process();

};

The last

$curproc->stop_this_process();

method of fml8 corresponds to the statement

$DO_NOTHING = 1;

of fml4. After this statement, the normal processing stops.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Anyonen Can Use Command Mail.

$command_mail_restrictions defines who can use command mail. By default user
registerd as a poster can use command mail. To enable that anyone can use
command mail, set

command_mail_restrictions = permit_anyone

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. Anyone can use command mail.
2. Anyone except system accounts can use command mail.
3. nobody use command mail.

1. Anyone can use command mail.

command_mail_restrictions = permit_anyone

2. Anyone except system accounts can use command mail.

command_mail_restrictions = reject_system_accounts
                            permit_anyone

3. nobody use command mail.

command_mail_restrictions = reject

There are other methods to disable command mail. See  the Section called Case
Study: Disable Command Mail for more details.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Disable Command Mail

It is most safe to remove command mail entries from aliases.

Another 2nd best solution follows:

use_command_mail_function       =       no

In this case, /usr/local/libexec/fml/command runs once but does not work and
ends as soon as possible.

The following solution may be possible.

use_command_mail_function = yes

command_mail_restrictions = reject

When fml receives the incoming command mail, it inform the rejection to the
sender in all cases.

This configuration works but it evalutates each line. It is useless.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Mail Magazine (1)

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Please use PGP auth if could, though we describe header based auth here.    芍
芍Also please set up MTA properly e.g. to disable smtp interfaces as could as 芍
芍possible.                                                                   芍
芍                                                                            芍
芍It is a problem that PGP auth requires user's skill at some level.          芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

In the case of header based auth, you can create a mail magazine by using the
asymmetirc member list. Consider asymmetric case of member list (list of
persons who can post) and recipient list below.

Firstly, remove $primary_member_map from $member_maps. Instead, define
$ml_home_dir/members-mailmag who can post to $member_maps.

member_maps     =       $ml_home_dir/members-mailmag

The use of "subscribe" command is same as default one since "subscribe" command
changes $primary_member_map not $member_maps. It is a little tricky but crafty
use of $primary_XXX_map and $XX_maps enhances fml8 configuration.

In this case, when a new user is subscribed, the user address is added to both
$ml_home_dir/members ($primary_member_map) and $ml_home_dir/recipinets
($primary_recipient_map). But $member_maps is defined as $ml_home_dir/
members-mailmag. $ml_home_dir/members is not used. Hence, only the list of
recipients is updated but the list of posters is NOT changed.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Strictly speaking, this configuration is not enough safe. If somebody fakes 芍
芍From: address, he/she can post since fml checks only From: address.         芍
芍                                                                            芍
芍So, pgp auth is recommended.                                                芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

Another solution.

primary_member_map      =       $tmp_dir/members-dummy

and use $member_maps (member_maps = $ml_home_dir/members) for normal use. It
has only poster's addresses.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Mail Magazine (2)

After 2004/06, fml8 supports the queuing system. So the outgoing mail fails
once, after the confirmation of content, you flush again to deliver if the
content is ok.

The queuing system support enables "queue once, dequeue after content
confirmation". It avoids delivery of wrong content.

The configuration is as follows.

Specify irrelevant port at config.cf.

smtp_servers = IRRELEVANT_PORT

[Example]

smtp_servers = 127.0.0.1:2025

This makes the delivery fail. The message is queued.

Check the content. If the content is correct and delivery is ready, runs the
following command by specifying the correct transport.

% fml -o smtp_servers=TRANSPORT ML_NAME flushq

[Example]

% fml -o smtp_servers=127.0.0.1:25 ML_NAME flushq

"flush" and "flushq" command are same.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Anyone Can Post.

article_post_restrictions = permit_anyone

$article_post_restrictions parameter controls who can post to this ML. To set
this as "permit_anyone", anybody (including system special account e.g. root,
postmaster) can post.

By default, $article_post_restrictions is defined as follows for fml4
compatibility,

article_post_restrictions       =       reject_system_special_accounts
                                        permit_member_maps
                                        reject

"reject_system_special_accounts" denies post if From: looks like system
accounts e.g. root, postmaster.

This configuration means that system special accounts cannot post and only user
contained in $member_maps can post article.

Attention that reject_XXX and permit_XXX statement is first match.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

recipes

1. Any persons in a domain can post always.

1. Any persons in a domain can post always.

It is not easy to handle global variables in the case of fml4 .

By using the following restriction, you can ermit only sender of example.co.jp
domain and reject other domain.

[/var/spool/ml/elena/config.cf]

article_post_restrictions       =       reject_system_special_accounts
                                        permit_member_maps
                                        reject

member_maps                     =       pcre:$ml_home_dir/sender.pcre

[$ml_home_dir/domains]
        \S+\@example.co.jp

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Article Posting Allowd If It Is A Reply To The Former One.

From time to time we can find that a posted article is denied due to posting
from not a member.

One reason is that the member who replied some article forgot to notify changes
of his/her mail address to the mailing list administrator. Another reason that
his/her mail address is changed from @DOMAIN to @SUB.DOMAIN vice versa. Yet
another reason is that he/she replied it from other location which recieved the
article via mail forwarding at some other host.

After 2004/10/28 fml8 current, fml8 supports "allow article post irrespective
of the From: address if some condition satisfied" at article_post_restrictions.

The current implementation suppors the condition that "if the reply refers a
known message-id within some time limit". Precisely speaking, "known
message-id" implies the id is found at the message-id database which holds
In-Reply-To: and References: of old articles within some time limit (e.g. one
week).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. Article Posting Allowd If It Is A Reply To The Former One.

1. Article Posting Allowd If It Is A Reply To The Former One.

"check_article_thread" is the keyword to enable this check.

article_post_restrictions       =       reject_system_special_accounts
                                        check_article_thread
                                        permit_member_maps
                                        reject

Not used by default. To use it, specify it at article_post_restrictions.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion

Hmm, this is similar to a cookie. There are some problems.

1) What is proper time scale ? $article_post_article_thread_lifetime controlls
it. One day by default.

article_post_article_thread_lifetime = 86400

Also, boundary of the time scale ? When starts the allowd window ? It starts
from the first article of the specific thread ? Or from the last article ?

2) More restricted condition support required ? If so, we should check the
corelation between subject: and the thread?

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. Only A Few Persons Can Starts Article Thread.

1. Only A Few Persons Can Starts Article Thread.

member_maps                     =       $tmp_dir/members-thread-init

article_post_restrictions       =       reject_system_special_accounts
                                        check_article_thread
                                        permit_member_maps
                                        reject


Only persons registered at members-thread-init file can post article always.
Other persons can post the article if the article is a reply to some other
article.

Hmm, it looks a variation of moderator system ?

Better that they use PGP auth if could.

member_maps                     =       $tmp_dir/members-thread-init

article_post_restrictions       =       reject_system_special_accounts
                                        check_article_thread
                                        check_pgp_signature
                                        reject

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: PGP/PGP Based Authentication In Posting

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Please install Crypt::OpenPGP perl module firstly. It is better to use OS   芍
芍dependent pacakge system since Crypt::OpenPGP depends a lot of other        芍
芍packages.                                                                   芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. PGP/PGP Based Authentication In Posting

1. PGP/PGP Based Authentication In Posting

check_pgp_signature options enables PGP/GPG based auth. If the degital
signature is confirmed, the user can post articles.

article_post_restrictions       =       reject_system_special_accounts
                                        check_pgp_signature
                                        reject

This function is disabled by default. Change article_post_restrictions if use.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Key Operations

PGP KEY RING directories are separeted for each purpose. For example, the
keyring dir for article pgp auth is $ml_home_dir/etc/pgp-article-post-auth/
directory, the keyring dir for remote administration by command mail is
$ml_home_dir/etc/pgp-admin-command-mail-auth/ directory.

Use pgp2, pgp5 and gpg commands to edit keys under them It is useful to use the
following fmlpgp wrapper command. The wrapper sets up proper environment
variables.

[Example] operations for elena ML

fmlpgp elena --article-post-auth -kg

the command line options available:

--article-post-auth       (auth for post article)
--command-mail-auth       (auth for command mail)
--admin-command-mail-auth (auth for admin command mail)
--article-post-encrypt    (article encryption)

Available wrappers follow:

pgp2: fmlpgp

pgp5: fmlpgp5 fmlpgpe fmlpgpk fmlpgps fmlpgpv

gpg: fmlgpg fmlgpgv

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Authenticate command mail by PGP/GPG

1. Authenticate user mode command mail by PGP/GPG.
2. Authenticate admin command mail by PGP/GPG.

1. Authenticate user mode command mail by PGP/GPG.

command_mail_restrictions       =       check_pgp_signature
                                        reject

Use CLI ( fmlgpg fmlgpgv fmlpgp fmlpgp5 fmlpgpe fmlpgpk fmlpgps fmlpgpv ) to
manipulate PGP/GPG keys.

Example: generate key for mailing list "ML_NAME".

% fmlpgp --command-mail-auth ML_NAME -kg

See  the Section called Case Study: PGP/PGP Based Authentication In Posting for
more details.

2. Authenticate admin command mail by PGP/GPG.

admin_command_mail_restrictions =       check_pgp_signature
                                        reject

Use CLI ( fmlgpg fmlgpgv fmlpgp fmlpgp5 fmlpgpe fmlpgpk fmlpgps fmlpgpv ) to
manipulate PGP/GPG keys.

Example: generate key for mailing list "ML_NAME".

% fmlpgp --admin-command-mail-auth ML_NAME -kg

See  the Section called Case Study: PGP/PGP Based Authentication In Posting for
more details.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

case study: hierarchical ML

Consider usual ML's which allows post from registered members. For example,
sales 1, 2 and 3 division.

Create sales-1, sales-2 and sales-3 ML. Each division manages each member list.
Also, create sales ML other than that to inform the whole sales members. If you
send a mail to sales ML, the mail is sent to all members of sales-1, sales-2
and sales-3 ML.

Define the following $recipient_maps in the config.cf of sales ML.

recipient_maps  +=      $ml_home_dir/../sales-1/recipients
recipient_maps  +=      $ml_home_dir/../sales-2/recipients
recipient_maps  +=      $ml_home_dir/../sales-3/recipients

Define $member_maps in the same way to allow post from all sales members:

member_maps     +=      $ml_home_dir/../sales-1/members
member_maps     +=      $ml_home_dir/../sales-2/members
member_maps     +=      $ml_home_dir/../sales-3/members

Instead of $member_maps change, it is simple that you allow post from anybody.
If so set

article_post_restrictions       =       permit_anyone

This example is simplest. It is easy to use this style.

If you need to use SQL e.g. MySQL, it is modern. It needs a lot of preparions
and operation know-how.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

I Want To Use ML By My Account.

When you set up an ML within your account, for example when you are using
virtual domain service of ISP, you need to use a mail processor such as
procmail.

To catch up messages to ML's, you need to filter messages according to To: or
Cc: in the mail header.

fml8 expects the user uses a filter tool such as procmail in such a situation.
fml8 distribution itself does not provide such a tool.

When running "makefml newml", "makefml" creates/updates ~/.procmailrc sample at
/var/spool/ml/etc/procmail/procmailrc. Please use it as a sample.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

~/.procmailrc Example

PATH=$HOME/bin:/usr/bin:/usr/ucb:/bin:/usr/local/bin:/usr/pkg/bin
MAILDIR=$HOME/Mail      # You'd better make sure it exists
DEFAULT=$HOME/Mail/mbox
LOGFILE=$MAILDIR/procmail.log
LOCKFILE=$HOME/.lockmail
VERBOSE=on

:0
* To.*elena@fml.org
| /usr/local/libexec/fml/fml.pl /var/spool/ml/elena

:0
* To.*elena-ctl@fml.org
| /usr/local/libexec/fml/fml.pl /var/spool/ml/elena --ctladdr

# last resort, mail for me et. al.
:0
inbox/.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Virtual Domain Case

The procmail rules above contains ml_name and ml_domain within it. So it does
not need special handling for virtual domain. It is same for both default
domain and virtual domain.

MTA configuration is another issue. Please contact administrator on it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Office (1)

Edit /usr/local/etc/fml/site_default_config.cf to apply the effect to all ML's.

No tag of subject. [5]

article_header_rewrite_rules    -=      rewrite_article_subject_tag

This means header rewrite rules minus "adding subject tag" operation.

Prepend office# at X-ML-Name:. That is, mlname is changed to office#mlname.

# office#$mlname
outgoing_mail_header_x_ml_name          =       office#$ml_name

Anybody can post to this ML since customers send mails to this address.

article_post_restrictions               =       permit_anyone

In this case, anybody including system special accounts e.g. root, postmaster
can post.

Disable almost all filters since a lot of customer messages looks something
wrong.

use_article_filter              =       no

Change spool type as subdir since the number of articles may become over
million.

spool_type                      =       subdir

Disable command mail.

use_command_mail_function       =       no

If someboby want to use command mail (e.g. by CGI), we use this variable. It is
recommended to remove proper alias entries if could to ensure the command mail
is prohibited.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Office (2)

Edit /usr/local/etc/fml/site_default_config.cf to apply the effect to all ML's.

Add uppercase-ed ML name to the article subject tag.

article_subject_tag = (\U$ml_name\E %05d)

For example, an article of support@example.co.jp has the tag

Subject: (SUPPORT 10000)

.

Allow the use of command mail, which comes only from the specific domain (my
domain e.g. example.co.jp). This hook enables it.

$command_verify_request_end_hook = q{
        my $cred = $curproc->credential();
        my $from = $cred->sender();

        unless ($from =~ /\@example\.co\.jp/i) {
                $curproc->stop_this_process();
                $curproc->logerror("deny command request from $from");
        }
};

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 18. Header Rewriting

Header information is stored at FML::Header class object. FML::Header class
inherits Mail::Header. See Mail::Header for method details.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipe's

1. Uppercase the tag in article Subject:
2. Lowercase the tag in article Subject:

1. Uppercase the tag in article Subject:

article_subject_tag = [\U$ml_name\E:%05d]

(available after 2002/10/29 snapshot)

2. Lowercase the tag in article Subject:

article_subject_tag = [\L$ml_name\E:%05d]

(available after 2002/10/29 snapshot)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 19. Extend Command

Case Study: Create Your Own Help Command.

To extend help command of elena ML, create help.pm perl module at

/var/spool/ml/elena/local/lib/FML/Command/User/help.pm

In loading module, libraries under local/ path is preferred. So, this help
command is loaded for help command (FML::Command::User::help).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. initialize ML by admin command.
2. add or remove a log of user by admin command.
3. send welcome message when "admin add" runs.
4. restrict subscribers.
5. I forget how to use admin command ?

1. initialize ML by admin command.

now allowd. Please use CUI on the mail server host.

2. add or remove a log of user by admin command.

Specific command not yet supported. Use ordinary admin commands.

admin add ..
admin add ..
admin add ..

 

3. send welcome message when "admin add" runs.

not implemented.

 

4. restrict subscribers.

not implemented.

5. I forget how to use admin command ?

See fml8 document ;-)

http://www.fml.org/software/fml8/

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 20. Filtering

1. Where the mail is sent back to when filter system rejects ?
2. Reject SPAM messages by using spamassassin.
3. Add X-Spam-Status: Yes header field if spamassassin determines the message
    as a spam.
4. How to write a hook to reject a message with danger attachment(s).

1. Where the mail is sent back to when filter system rejects ?

By default, It is defined as

use_article_filter_reject_notice        =       yes
article_filter_reject_notice_recipient  =       maintainer sender

When the filter system rejects the request, fml sends back it to both the ML
maintainer and the sender.

To change the recipient to the sender (From: address) only, set

article_filter_reject_notice_recipient  =       sender

To notify the rejection to both ML maintainer and the sender, set

article_filter_reject_notice_recipient  =       maintainer sender

To disable notification of rejection, set

use_article_filter_reject_notice        =       no

2. Reject SPAM messages by using spamassassin.

Case 1: use internal filter.

use_article_spam_filter         =       yes
article_spam_filter_drivers     =       spamassassin

Case 2: In this case, fml8 use not spamassassin internal filter but use a hook.

$distribute_verify_request_end_hook = q{
        my $spamassassin = '/usr/pkg/bin/spamc -c';

        use FileHandle;
        my $wh  = new FileHandle "| $spamassassin";

        if (defined $wh) {
                $wh->autoflush(1);
                my $msg = $curproc->incoming_message();
                $msg->print($wh);
                $wh->close();
                if ($?) {
                        $curproc->log("spam: (code = $?)");
                        $curproc->stop_this_process();
                }
        }
};

3. Add X-Spam-Status: Yes header field if spamassassin determines the message
as a spam.

$distribute_verify_request_end_hook = q{
        my $spamassassin = '/usr/pkg/bin/spamc -c';

        use FileHandle;
        my $wh  = new FileHandle "| $spamassassin";

        if (defined $wh) {
                $wh->autoflush(1);
                my $msg = $curproc->incoming_message();
                $msg->print($wh);
                $wh->close();
                if ($?) {
                        $curproc->log("spam: (code = $?)");
                        my $hdr = $curproc->incoming_message_header();
                        $hdr->add('X-Spam-Status', 'Yes');
                }
        }
};

This is a little tricky but it works well.

4. How to write a hook to reject a message with danger attachment(s).

fml8 analyzed the incoming message firstly and creates a chain of Mail::Message
objects on memory. It is easy for fml8 to analyze the chain to check the
message content.

The following examples uses hooks. In all cases, if matched, call
stop_this_process() to stop further processing. Pay attension that these
examples do not try to return error messsages.

If you need to return error messages, use reply_message(). It is better not to
return it since this message must be a virus or a spam.

Here is an example to check attachment keywords e.g. .exe in mesages. Before
fml8 2004/12/08 current, it follows:

$distribute_verify_request_start_hook = q{
    my $msg = $curproc->incoming_message() || undef;
    for (my $m = $msg; $m ; $m = $m->{ next } ) {
        my $hs = $m->message_fields() || '';
        if ($hs =~ /filename=.*\.(com|vbs|vbe|wsh|wse|js|exe|doc|rtf)/o) {
            $curproc->log("attachment \.$1 found");
            $curproc->stop_this_process();
        }
    }
};

After fml8 2004/12/08 current, it follows:

$distribute_verify_request_start_hook = q{
    my $msg  = $curproc->incoming_message() || undef;
    my $list = $msg->message_chain_as_array_ref();
    for my $m (@$list) {
        my $hs = $m->message_fields() || '';
        if ($hs =~ /filename=.*\.(com|vbs|vbe|wsh|wse|js|exe|doc|rtf)/o) {
            $curproc->log("[new] attachment \.$1 found");
            $curproc->stop_this_process();
        }
    }
};

Another solution is to trap

Content-Disposition: attachment;

to detect the existence of attachments. Before fml8 2004/12/08 current, it
follows:

$distribute_verify_request_start_hook = q{
    my $msg = $curproc->incoming_message() || undef;
    for (my $m = $msg; $m ; $m = $m->{ next } ) {
        my $hs = $m->message_fields() || '';
        if ($hs =~ /Content-Disposition:.*attachment;/o) {
            $curproc->log("attachment \.$1 found");
            $curproc->stop_this_process();
        }
    }
};

After fml8 2004/12/08 current, it follows:

$distribute_verify_request_start_hook = q{
    my $msg  = $curproc->incoming_message() || undef;
    my $list = $msg->message_chain_as_array_ref();
    for my $m (@$list) {
        my $hs = $m->message_fields() || '';
        if ($hs =~ /Content-Disposition:.*attachment;/o) {
            $curproc->log("[new] attachment \.$1 found");
            $curproc->stop_this_process();
        }
    }
};

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 21. Extend Message

Case Study: Customize Message

Create file at

/var/spool/ml/elena/local/share/message/$language/class

See /usr/local/share/fml/$version/message/$language/class as samples. Copy, cut
and paste one of them :)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 22. Be ML Articles public via WWW

Recipes

1. convert articles to html form after ML runs without html conversion.
2. convert articles to html form for resetting.
3. How to create html archive on a different machine?

1. convert articles to html form after ML runs without html conversion.

use fmlhtmlify command.

Example

% fmlhtmlify /var/spool/ml/elena/spool ~fml/public/fml/mlarchive/DOMAIN/ML

 

2. convert articles to html form for resetting.

use fmlhtmlify command.

Example

% fmlhtmlify /var/spool/ml/elena/spool ~fml/public/fml/mlarchive/DOMAIN/ML

 

3. How to create html archive on a different machine?

1. syncrhnize archive by e.g. rsync.

2. set up html converter such as mhonarch on the machine.

3. NFS but pay attension network structure in using NFS seen from Internet.

IV. Operations

This part describes operations.

Table of Contents
23. Logging
24. Back Up Of Configurations

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 23. Logging

See Log

% makefml log ML_NAME
% fml     ML_NAME log

shows the latest 30 lines of log.

GUI uses log command.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Show Computer Oriented Log

When not fml program or CGI calls fml8 CUI and such program wants to analyze
the output, you can use use the following option.

% makefml --log-computer-output COMMAND ML_NAME
% fml --log-computer-output     ML_NAME COMMAND

It shows the computer oriented log into STDERR channel.

For example

% fml --log-computer-output elena@fml.org list
rudo@nuinui.net
1070109341  info lock channel=recipient_map_modify
1070109342  info unlock channel=recipient_map_modify

This example shows "TIME LOG_LEVEL MESSAGE" style log. It is suitable for
computer proceessing.

The command line option --log-computer-output is same effect as

use_log_computer_output = yes

in config.cf file.

When "use_log_computer_output = yes" specified in config.cf, all programs are
affected. All programs shows the computer oriented log to STDERR. So use of
command line option is recommended.

We should use perl module which holds a set of functions. In this case, the
print out engine is the class called as FML::Log::Print::Simple. The output
style is contolled by $log_computer_output_engine in config.cf file.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. show fml error log of yesterday.
2. See old logs.
3. Centralize log messages.
4. extract specific log messages in monitoring.
5. extrace the specific log messages with coping it.
6. Expire old log files.

1. show fml error log of yesterday.

daily.pl of fml4 is not implemented yet.

Currently use grep to parse the log file.

2. See old logs.

fml8 appends log messages continuously into the log file at $ml_home_directory
by default. All log messages exist in it.

On the other hand, Unix log expires. So you cannot trace too lod messages.

Please tune parameters of expiration tools e.g. newsyslog which program differs
from unix variants to variants to save log messages in at least 3 months.

3. Centralize log messages.

Unix uses syslog mechanism. To redirect all messages to /var/log/messages, set
the following:

[/etc/syslog.conf]

*.*             /var/log/messages

Also, fml8 can use syslog mechanism.

[/var/spool/ml/elena/config.cf]

log_type        =       syslog

To use these configuration, all messages are centralized to /var/log/messages
file.

4. extract specific log messages in monitoring.

% tail -F /var/spool/ml/elena/log | grep 'PATTERN'

 

5. extrace the specific log messages with coping it.

% tail -F /var/spool/ml/elena/log | grep 'PATTERN' | tee FILE

 

6. Expire old log files.

Newsyslog mechanism provided by fml4 is not implemented.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 24. Back Up Of Configurations

To preserve fml8 configurations, back up the following two directories:

/usr/local/etc/fml/
$ml_home_prefix (e.g. /var/spool/ml/, domain specific)

Attention: These directories holds all articles, log files and others et.al.

It is better to back up MTA configurations, too. For example, /etc/postfix in
the case of Postfix.

In summary, the following three (generally speaking 2 + number of domains fml8
operatates) are targets.

/etc/postfix/
/usr/local/etc/fml/
$ml_home_prefix (e.g. /var/spool/ml/)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Back Up fml8 Configurations

To back up fml8 configurations, it is enough to back up the following two
directories. But it is too large since they contains articles, log files and
all contents.

/usr/local/etc/fml/
$ml_home_prefix (e.g. /var/spool/ml/, domain specific)

The hard disk is cheap. So it is safe to preserve all contents as could as
possible.

If you preserve only configuratoins, it is enough to back up the following
files.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Configuration Files To Back Up

It is useful to make a list of targets based on the file naming convension.

In the case of fml8, a file with .cf extension is a configuration file. The
format of .cf file is


key = value

style. This style configuration files follow

/usr/local/etc/fml/main.cf
/usr/local/etc/fml/site_default_config.cf
/EACH_ML_HOME_DIRECTORY/config.cf

et.al.

Configuration files with other syntax are

/usr/local/etc/fml/mime_component_filter
/usr/local/etc/fml/ml_home_prefix

This type of files are space separeted.

/usr/local/etc/fml/ contains only configuration files. So back up all under
them.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Address List To Back Up

Lists of mail addresses are

/ML_HOME_DIRECTORY/members*
/ML_HOME_DIRECTORY/recipients*

Article delivery uses both recipients and members. For other roles, fml8 uses
members-$role and recipients-$role. So, back up all members* and recipients*
files.

Remote administration by command mail (admin command mail) uses the following
password files

/ML_HOME_DIRECTORY/etc/passwd-$role

. Back up /ML_HOME_DIRECTORY/etc/ too.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Back Up All Files Except For Some Large Directories.

It is easy to back up all files except for the following large directories.
They contains large data or temporary files.

spool   articles
tmp     temporary files
var     useful data

If you use rsync, rsync --exclude is useful.

V. Troubleshoot

This part describes how to shoot troubles.

Table of Contents
25. Troubleshoot

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 25. Troubleshoot

1. I want to know fml version.
2. Check Postfix version.
3. Check Sendmail version.
4. List up pre-defined addresses on this host.
5. List up defined aliases on this host
6. List up all ML addresses containing the specific member address.

1. I want to know fml version.

[Example: in the case of "test" ML]
% fmlconf test fml_version
fml_version                          = fml-devel current-20021029

2. Check Postfix version.

% postconf mail_version

3. Check Sendmail version.

% echo '$v' | sendmail -bt

4. List up pre-defined addresses on this host.

"fmladdr" command lists up users defined at both /etc/passwd and aliases.

% fmladdr

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The difference between "fmladdr" and "fmlalias" is whether it contains users芍
芍defined at /etc/passwd or not. "fmladdr" contains it but fmlalias not.      芍
芍"fmlalias" lists up only users defined at aliases.                          芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

5. List up defined aliases on this host

Run "fmlalias". It shows all addresses defined in aliases files.

% fmlalias

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The difference between "fmladdr" and "fmlalias" is whether it contains users芍
芍defined at /etc/passwd or not. "fmladdr" contains it but fmlalias not.      芍
芍"fmlalias" lists up only users defined at aliases.                          芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

6. List up all ML addresses containing the specific member address.

For each ML, run the following command:

% fml ML list |grep ADDRESS

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

When The File System Error Ocuurs

When the file system error occurs, fml8 exit abnormally to make MTA re-deliver
the message again to fml8 or fml8 re-delivers it by itself without saving the
article on the file system. So fml8 do not lost received messages whereas both
log or summary file lack something.

Describe below what happans when the file system error occurs in the delivery
process.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

When Passed From MTA MTA To fml8

fml8 reads a message and writes it into the disk once. If succeeded, it
processes more. If failed, fml8 exits abnormally as exit(EX_TEMPFAIL) for MTA
to re-deliver it. See  the Section called Incoming Queuing in Chapter 31 for
more details.

In this case, incoming message queue may have a incomplete message. fml8 tries
to remove it in abnormal exit. Even if failed, the queue management system
removes it later.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

If Updating Of The Article Sequence Number Failed

In normal case, fml8 updates the article sequence number and re-reads it and
compares it again. If the check fails, fml8 exit(EX_TEMPFAIL) for MTA to
re-deliver it.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The article sequence number updated. After that, fml8 does not do exit      芍
芍(EX_TEMPFAIL) to deliver the message on memory as could as possible.        芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

When Saving Of Article Failed

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍In this stage, the article sequence has been updated.                       芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

In this case, fml8 does not create a new article file but the original message
is already on the disk. The header of the article differs from the original one
but the body content is same. So fml8 tries to link(2) the original mail in the
incoming queue to the article file to save the content. [6]

fml8 tries to deliver the message on memory.

If the delivery process exits abnormally, distribution of article ends
incompletely since fml8 can not use outgoing queue due to file system error.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Delivery Process

fml8 saves the message into the outgoing queue, after succeeded, the delivery
process runs.

When fml8 fails to write the outgoing queue, fml8 exits incompletely.

See  the Section called fml Sends Back A Mail Message in Chapter 31 for more
details.

VI. fml8 Design

This part describes the design policy of fml.

Table of Contents
26. [LOG] Original Idea Of fml8 Project
27. Programming Style

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 26. [LOG] Original Idea Of fml8 Project

The Original Idea Of fml8 (fml-devel) Project

fml8 project called as fml-devel also is refactoring of fml4 mailing list
driver.

See http://www.fml.org/software/fml8/ for more details on the furure plan,
design and implementation of fml-current.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Details Of Idea

 ’ simple implementation of configuration files and menu.

 ’ perl module (> perl 5.00504 )

 ’ support more integrated CUI (makefml) and GUI.

 ’ Separation

     ╰ easy upgrade

     ╰ use CPAN modules as could as possible.

     ╰ 3rd party directory

 ’ abstracted IO layer

     ╰ file (implemented)

     ╰ /etc/group (implemented)

     ╰ NIS (implemented)

     ╰ SQL (MySQL implemetned)

     ╰ LDAP

 ’ IPv4/IPv6 ready (implemented)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Refactoring

Table 26-1. refactoring TODO

見芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍  status  芍              entry               芍          detail          芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍done.     芍license                           芍perl conformance          芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍                                  芍fml4 to fml8 is similar to芍
芍underway. 芍image                             芍sendmail to postfix.      芍
芍          芍                                  芍support configuration     芍
芍          芍                                  芍converter.                芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍done.     芍wrapper (separation layer).       芍separation layer for      芍
芍          芍                                  芍upgrade/downgrade, debug. 芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍                                  芍use CPAN modules as could 芍
芍          芍adapter                           芍as possible. prepare      芍
芍          芍                                  芍adapter layer in using    芍
芍          芍                                  芍CPAM module.              芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍new single configuration file     芍                          芍
芍          芍format.                           芍                          芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍rule of variable naming convension芍use_XXX, XXX_TYPet ...    芍
芍          芍                                  芍prohibit NOT_USE style.   芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍function name convension use X11  芍use Perl Cookbook style ? 芍
芍          芍style for main:: space. use method芍e.g. "MemberP() ->        芍
芍          芍style for method. not use Lisp    芍IsMember()"               芍
芍          芍like style (-p).                  芍                          芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍done.     芍queue manager                     芍re-delivery by itself     芍
豆芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍          芍tools                             芍not use BSD make.         芍
谷芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Architecture image

[architectu]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

release engineering

Not be an architect nor developer. Not too abstractive and not too object
oriented. Be between them. Feedback in one month to manage project and code
review.

Table 26-2. release interval

見芋芋芋芋芋芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍 days in one month  芍                      content                       芍
豆芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍the first 4 - 5 days芍manage project. apply at least 20 % of the project  芍
芍                    芍to this stage.                                      芍
豆芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍2 - 3 weeks         芍coding.                                             芍
豆芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍the last week       芍code review, document review                        芍
豆芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍at the last of the  芍release a snapshot. alpha-0, alpha-1, alpha-2, ...  芍
芍month               芍                                                    芍
谷芋芋芋芋芋芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 27. Programming Style

This chapter describes a few topics on programming technique.

See FNF on FML.ORG programming style.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Variable Naming Convension

It is ambiguous where "default" word in the variable name is proper. The left
side of the naming string is expected to show large scale such as CLASS.

Let us consider article related variables. We expect $article_* variables for
them.

It seems better to use CLASS_default_XXX syntax not default_XXX.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Structure Of Variable Naming

It seems proper to use systematic naming convension. For it, we define base
class or inheritence of naming syntax.

Consider class names. For example, "mail" implies messsage/rfc822 format text.
The input into fml system is a mail, outgoing one is a mail. The variable are
sub class of "mail" object, so the name is unified as PREFIX_mail_ATTRIBUTE
style.

mail_XXX
mail_default_XXX

use_incoming_mail_XXX
incoming_mail_XXX

use_outgoing_mail_XXX
outgoing_mail_XXX

use_report_mail_XXX
report_mail_XXX

Other example (header):

header_XXX
header_default_XXX

article_header_XXX
use_article_header_XXX

command_mail_header_XXX
use_command_mail_header_XXX

We can describe structure of class as follows:

command {
        SOMETHING_command
        admin_command
}

directory {
        XXX_directory
}

file {
        template_file
}

mail {
        incoming_mail
        outgoing_mail
        report_mail
}

message {
        reply_message
}

article {
        article_digest (not use digest to show digest of article)
        article_spool  (not use spool to show  spool of article)
}

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example: Standard Pattern (e.g. log.cf lock.cf)

use_VARIABLE            =       yes or no

# append _dir for directory.
VARIABLE_dir            =       STRING

# append _file for file.
VARIABLE_file           =       STRING

VARIABLE_type           =       STRING

VARIABLE_format         =       STRING

VARIABLE_format_type    =       STRING

VARIABLE_limit          =       STRING (NUMBER but STRING)

VARIABLE_upper_limit    =       STRING (NUMBER but STRING)

VARIABLE_lower_limit    =       STRING (NUMBER but STRING)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example 2: (e.g. acl.cf)

VARIABLE_restrictions   =       reject_ATTRIBUTE1
                                check_ATTRIBUTE2
                                permit_XXX

ATTRIBUTE1                      =       PATTERN1
                                        PATTERN2
                                        ...

ATTRIBUTE2                      =       var1
                                        var2

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Example 3: (program name prefix)

PROGRAM_VARIABLE_ATTRIBUTE

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

A Few Topics On Design And Coding Style

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍See also FNF on style.                                                      芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

A Few Cautions

Apply quotemeta() for search key.

Use access method for object not handle directly within objects. Example: To
access to main.cf object, not use

$curproc->{ ... }->{ main_cf }

instead use

$curproc->main_cf();

style.

It is better not to use @EXPORT and @EXPORT_OK.

How depth of classes is allowed ? two such as String::is_japanese_string() ? At
least 3, I think.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Programming Style Original Idea

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Here is the original idea log.                                              芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

 ’ We can use polymorphism in perl. Use it and object composition instaed of
    multiple inheritence.

 ’ Perl 5's OOP is not OOP. Do not depent on it. It just provides simple use
    of variable since variable itself knows the home (object / package).

 ’ Interface for re-use and abstraction should be OOP style.

 ’ We want to use OOP style in using Perl 5 but take care for OOP-ism. Balance
    is important.

 ’ not use deep inheritence.

Programs in libexec/ describes the basic flow of processes. They may be allowd
to be structured not object oriented programming

Polymorphism and re-use is important especially in sub-classes.

VII. fml8 Internals

This part describles the fml internals for developers.

Table of Contents
28. fml8 Boot Loader To Resolve Version Dependence Dynamically
29. Configuration File: config.cf
30. Create A New Program
31. fml8 Mail Delivery System
32. Digest Delivery
33. Language Preference In Processing
34. Manipulate Message (Mail Message)
35. Filter
36. Subscribe / Unsubscribe
37. Command (Command Mail, CUI And GUI)
38. Internal Of CGI Process
39. Directory
40. Restrict Input Data
41. User Authentication
42. Hook
43. Virtual Domain
44. Errormail Analyzer (libexec/error)
45. IO Interface And Operations
46. Lock
47. Database Related Modules
48. Database Management System
49. Convert Another ML System To fml8

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 28. fml8 Boot Loader To Resolve Version Dependence Dynamically

fml8 provides a boot loader to resolve version dependence dynamically. For
example, the loader boot straps fml8 as follows:

fml (libexec/distribute) boots like this ...

       functions                class
       ----------------------------------------

       main::Bootstrap()        libexec/loader
            |
            V
       main::Bootstrap2()       FML::Process::Switch
            |
            V
       ProcessSwitch()          FML::Process::Switch
            |
            |
            | switch to ($obj = FML::Process:Distribute)
            |
            V
       ProcessStart($obj,$args) FML::Process::Flow

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case: Distribution

fml8 loader boot straps like this in the case of distribution.

/usr/local/libexec/fml/distributre (is same as /usr/local/libexec/fml/loader in
fact) reads /usr/local/etc/fml/main.cf and resolvers the version it should use
from $fml_version variable. Let $fml_version current-20010501. The loader uses
library perl modules under /usr/local/lib/fml/current-20010501/.

The loader resets @INC (perl include path). It loads FML::Process::Switch and
checks $0 (program name in process table). The loader resolves from the name
that the role is distribution. It loads FML::Process::Distribute and switches
to the class.

The relation between program name and class (perl module) is defined at /usr/
local/etc/fml/defaults/$fml_version/modules file.

FML::Process::Flow::ProcessStart() function drives these sequential steps.
ProcessStart() takes FML::Process::Distribute object as an argument and drives
the object.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

FML::Process:: Class Structure

FML::Process::Distribute >-|
FML::Process::Command    >-|-- FML::Process::Kernel
FML::Process::Mead       >-|    |
                                |-use-a FML::Parse
                                |-use-a FML::Config
                                |-use-a FML::Log
                                |-use-a  ... SOMETHING ...

 

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Modules In Process Execution

 ’ libexec/loader (wrapper): executes Bootstrap() runction. libexec/distribute
    et.al. is a symlink(2) to this loader. See under /usr/local/libexec/fml/
    path.

 ’ 
     ╰ reads /usr/local/etc/fml/main.cf and resolves $fml_version. reset @INC
        by main.cf value. Since default_config.cf is version dependent, the
        loader should evaluate the file before it reads ML specific
        configuration files.

     ╰ Evaluate @ARGV and resolves which ML specific configuration files we
        need to load.

     ╰ load FML::Process::Switch class which is also version dependent.

         ↗ The loader executes Bootstrap2() and ProcessSwitch() to switch the
            context to each one such as distribution, command mail et.al. In
            this time, the loader knows the role from $0 process name.

         ↗ Exapmle of Polymorphyism: dynamic binding of module and creation of
            process object in starting the process. FML::Process::Flow
            describes the flow of process like this:

            $process = new FML::Process::SOMETHING;
            $process->prepare($args);
            $process->verify_request($args);
            $process->run($args);
            $process->finish($args);

            Each process should probide proper methods under FML::Process::
            class.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: Where Function Should Resolve $ml_name And $ml_domain.

Currently fml8 resolves them in prepare() under FML::Process:: classes.

Here is a part of background idea.

main::Bootstrap()

        resoles $fml_version based on main.cf information.

        pass hints to some processes e.g. CGI.
                CGI only
                it should ignore invalid input.
                $ml_name $and ml_domain is hard-coded in cgi scripts.


main::Bootstrap2()
ProcessSwitch()

        resolves the module, configuration files, library path and @INC.

        pass hints to some processes e.g. CGI.
                CGI only

ProcessStart($obj, $args)

   main process starts

        new

        prepare
                resoles $ml_name and $ml_domain.
                parse input from CGI using hints.
                determine ml specific configuration files.
                parse incoming message.
                parse command line arguments.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 29. Configuration File: config.cf

ML Specific Configuration File: config.cf

You can customize each ML differently. fml4 and fml8 are same in this point.

In the case of fml4, there is a config.ph in ML home directory, $DIR (e.g. /var
/spool/ml). This "config.ph" file is a perl script.

There is one configuration file (config.cf) in fml8, too. But the format is
different. The format is like this:

variable = value

. It is similar to postfix or .ini files.

It is similar to a perl module. You can write perl codes after =cut line.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Problems in fml4

The configuration file of fml4, config.ph, is a perl script. Perl script is
good for human editing but it is not suitable for configuration tools. It
implies it is difficult to prepare configuration tools for config.ph. So, in
fml4 two files, cf and config.ph are used. [7]

The use of cf is suitable for configuration tools but introduces another
difficulty such as inconsistency between cf and config.ph since human may edit
config.ph but forgets editing cf. So, fml8 introduces only one configuration
file. It is a new format which is similar to Postfix main.cf.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

config.cf Format

The format of "config.cf" is "variable = value syntax". If plural values are
required, space or "\n\s" is a separator.

variable = value

valiable = value1 value2 value3

variable = value1
           value2
           value3

The syntax of files with the suffix .cf e.g. /etc/fml/main.cf ,
default_config.cf, is same.

$variable at the right hand is expanded. For example,

a = value1
b = $a/value2

is expanded to

a = value1
b = value1/value2

.

The variable expansion is done at the last. So, the following definitions

a = value1
b = $a/value2/$c
c = value3
a = value4

are expaned to

b = valu4/value2/value3

since the last $a overwrites the previous one.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Extension To Postfix Style

variable += value
variable -= value

is used for adding or removing the specific value.

x  = a b c d
x -= b

becoms

x = a c d

.

Another case,

x  = a b c d
x += e

becomes

x = a b c d e

.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overload Variables In config.cf

Overloading of .cf files is possible. It overwrites variables.

It enables separation of configuration files e.g. the default file, the host
specific file, the domain specific file, and ML specific file.

fml8 reads these files sequentially. At the last, fml8 expands variables when
variable reading is requested.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Modifying/Adding Variables After All Configuration Files Have Been Loaded.

The variable expansion is always done. If some value with $ is added to some
variable, the next reading operation [8] causes variable expansion.

For example, set

$config->{ key } = '$ml_home_dir/value';

here. The next read operation e.g.

$config->{ another_key }

(where the key is any) evaluates the variable expansion.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Internal Of Variable Expansion

%_fml_config hash holds pairs of key and value. The format is $dir/$file in
this hash, it is not expanded. get() returns the value of %_fml_config_result.
The value in this hash is after the variable expansion. The variable is
expanded in calling get() method.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Variable List (Alphabetical Order)

Table 29-1. table description

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋豕芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                  variable name                   芍       descrition       芍           default value(s)           芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍address_compare_function_domain_matching_level    芍domain matching level in芍3                                     芍
芍                                                  芍comparing mail addresses芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍case insensitive        芍                                      芍
芍address_compare_function_type                     芍comparison of user part 芍user_part_case_insensitive            芍
芍                                                  芍of mail address.        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍base directory which    芍                                      芍
芍admin_cgi_base_dir                                芍locates .cgi for this   芍$cgi_base_dir/admin                   芍
芍                                                  芍domain.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍gpg configurations for  芍                                      芍
芍admin_command_mail_auth_gpg_config_dir            芍admin commnad mail      芍$etc_dir/gpg-admin-command-mail-auth  芍
芍                                                  芍authentication.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin_command_mail_auth_gpg_config_dir_alias      芍conventional naming     芍$etc_dir/gpg-admin                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍pgp configurations for  芍                                      芍
芍admin_command_mail_auth_pgp_config_dir            芍admin commnad mail      芍$etc_dir/pgp-admin-command-mail-auth  芍
芍                                                  芍authentication.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin_command_mail_auth_pgp_config_dir_alias      芍conventional naming     芍$etc_dir/pgp-admin                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin_command_mail_restrictions                   芍restrictions for admin  芍reject_system_special_accounts        芍
芍                                                  芍command mail            芍check_admin_member_password reject    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin_member_maps                                 芍all remote administrator芍$primary_admin_member_map             芍
芍                                                  芍lists                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin_member_password_maps                        芍all password files.     芍$primary_admin_member_password_map    芍
芍                                                  芍                        芍file:$etc_dir/passwd                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍admin_recipient_maps                              芍dummy                   芍$primary_admin_recipient_map          芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍anonymous_cgi_base_dir                            芍top level directory for 芍$fml_owner_home_dir/public_html/      芍
芍                                                  芍anonymous cgi scripts.  芍cgi-bin/anonymous                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍expire limit of         芍                                      芍
芍anonymous_cgi_expire_limit                        芍anonymous CGI session   芍15m                                   芍
芍                                                  芍ID.                     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_delivery_transport                        芍specify transport for   芍smtp                                  芍
芍                                                  芍article delivery.       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_expire_limit                              芍how old article to be   芍90d                                   芍
芍                                                  芍removed                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_filter_reject_notice_data_type            芍how fml refer the       芍string                                芍
芍                                                  芍rejeced message.        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_filter_reject_notice_recipients           芍recipients to inform    芍maintainer sender                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_filter_rules                       芍header filter rules.    芍check_message_id check_date permit    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_help                          芍list-help of article    芍$mail_header_default_list_help        芍
芍                                                  芍header.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_id                            芍list-id of article      芍$mail_header_default_list_id          芍
芍                                                  芍header.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_owner                         芍list-owner of article   芍$mail_header_default_list_owner       芍
芍                                                  芍header.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_post                          芍list-post of article    芍$mail_header_default_list_post        芍
芍                                                  芍header.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_software                      芍default list-software   芍$mail_header_default_list_software    芍
芍                                                  芍header field.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_subscribe                     芍list-subscribe of       芍$mail_header_default_list_subscribe   芍
芍                                                  芍article header.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_header_list_unsubscribe                   芍list-unsubscribe of     芍$mail_header_default_list_unsubscribe 芍
芍                                                  芍article header.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍delete_unsafe_header_fields           芍
芍                                                  芍                        芍rewrite_article_subject_tag           芍
芍                                                  芍                        芍rewrite_reply_to rewrite_errors_to    芍
芍                                                  芍                        芍rewrite_stardate rewrite_precedence   芍
芍article_header_rewrite_rules                      芍header rewriting rules  芍rewrite_message_id add_software_info  芍
芍                                                  芍                        芍add_fml_ml_name                       芍
芍                                                  芍                        芍add_fml_traditional_article_id        芍
芍                                                  芍                        芍add_fml_article_id add_x_sequence     芍
芍                                                  芍                        芍add_rfc2369                           芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_message_id_cache_dir                      芍article Message-ID cache芍$db_dir/article_message_id            芍
芍                                                  芍directory               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_mime_component_filter_rules               芍file of filter rules    芍$fml_config_dir/mime_component_filter 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_non_mime_filter_rules                     芍dummy                   芍permit                                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍permit post from anyone 芍                                      芍
芍article_post_article_thread_lifetime              芍if the posted message   芍86400                                 芍
芍                                                  芍follows                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_post_auth_gpg_config_dir                  芍gpg configurations for  芍$etc_dir/gpg-article-post-auth        芍
芍                                                  芍article authentication. 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_post_auth_pgp_config_dir                  芍pgp configurations for  芍$etc_dir/pgp-article-post-auth        芍
芍                                                  芍article authentication. 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_post_encrypt_gpg_config_dir               芍gpg configurations for  芍$etc_dir/gpg-article-post-encrypt     芍
芍                                                  芍article encryption.     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_post_encrypt_pgp_config_dir               芍pgp configurations for  芍$etc_dir/pgp-article-post-encrypt     芍
芍                                                  芍article encryption.     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_post_restrictions                         芍restrictions for post   芍isolate_system_special_accounts       芍
芍                                                  芍                        芍permit_member_maps isolate            芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_post_restrictions_reject_notice_data_type 芍how to inform the       芍string                                芍
芍                                                  芍rejected message        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_sequence_file                             芍file to store sequence  芍$sequence_file                        芍
芍                                                  芍number                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_size_filter_rules                         芍size based filter rules.芍check_header_size check_body_size     芍
芍                                                  芍                        芍permit                                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_spam_filter_bogofilter_options            芍"-e" implies embedded   芍-e                                    芍
芍                                                  芍mode.                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_spam_filter_drivers                       芍external spam checker.  芍bogofilter                            芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_spam_filter_functions                     芍list up driver names    芍bogofilter                            芍
芍                                                  芍used as spam checker.   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_spam_filter_rules                         芍action if the message   芍header_rewrite                        芍
芍                                                  芍looks a spam.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍exit non-zero status    芍                                      芍
芍article_spam_filter_spamassassin_options          芍code when spam caught if芍-e                                    芍
芍                                                  芍"-e" specified.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_spam_filter_spamc_options                 芍spamc optoins. "-c"     芍-c                                    芍
芍                                                  芍means check only.       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_subject_tag                               芍Subject: tag.           芍[$ml_name:%05d]                       芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_summary_file                              芍article summary file.   芍$ml_home_dir/summary                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍save the first N bytes  芍                                      芍
芍article_summary_file_format_address_length        芍of the address in       芍15                                    芍
芍                                                  芍summary.                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_summary_file_format_style                 芍format style.           芍fml4_compatible                       芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍reject_not_iso2022jp_japanese_string  芍
芍                                                  芍                        芍reject_null_mail_body                 芍
芍                                                  芍filter rules of text/   芍reject_one_line_message               芍
芍article_text_plain_filter_rules                   芍plain filter.           芍reject_old_fml_command_syntax         芍
芍                                                  芍                        芍reject_invalid_fml_command_syntax     芍
芍                                                  芍                        芍reject_japanese_command_syntax        芍
芍                                                  芍                        芍reject_ms_guid permit                 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_thread_outline_greeting_en                芍greeting prepended to   芍[outline of this thread]              芍
芍                                                  芍thread outline          芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_thread_outline_greeting_ja                芍旦伊永玉及陬邰互銨引月朿芍[呿旦伊永玉及丐日允元]                芍
芍                                                  芍坌卞勾仃月飢誥          芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_thread_outline_rules                      芍where should we add     芍add_outline_to_header                 芍
芍                                                  芍thread outline ?        芍append_outline_to_body                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_virus_filter_clamav_options               芍--mbox needed for mail  芍--quiet --mbox                        芍
芍                                                  芍files.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_virus_filter_drivers                      芍external virus checker. 芍clamscan                              芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_virus_filter_functions                    芍list up driver names    芍clamav                                芍
芍                                                  芍used as virus checker.  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍article_virus_filter_rules                        芍action if virus found.  芍reject                                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍base directory which    芍$fml_owner_home_dir/public_html/      芍
芍cgi_base_dir                                      芍locates .cgi for this   芍cgi-bin/fml/$ml_domain                芍
芍                                                  芍domain.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_charset_en                                    芍cgi charset in English  芍us-ascii                              芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_charset_ja                                    芍cgi charset in Japanese 芍euc-jp                                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_default_charset                               芍default charset         芍us-ascii                              芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_default_language                              芍language mode of CGI (!=芍english                               芍
芍                                                  芍charset)                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_language_select_list                          芍available language mode 芍english japanese                      芍
芍                                                  芍in CGI                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_main_menu_color                               芍default bgcolor         芍#FFFFFF                               芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_menu_address_map_select_list                  芍choise of address list  芍member recipient admin_member         芍
芍                                                  芍types in CGI operations.芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_menu_default_address_map                      芍default value of list   芍recipient                             芍
芍                                                  芍types in CGI operations.芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍cgi_navigation_bar_color                          芍default bgcolor in      芍#FFFFFF                               芍
芍                                                  芍navigation menu         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍chaddr_command_auth_type                          芍use comnfirmation in    芍confirmation                          芍
芍                                                  芍chaddr command ?        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍operate action          芍                                      芍
芍chaddr_command_operation_mode                     芍automatically or        芍automatic                             芍
芍                                                  芍manually by maintainer ?芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍gpg configurations for  芍                                      芍
芍command_mail_auth_gpg_config_dir                  芍(user) commnad mail     芍$etc_dir/gpg-command-mail-auth        芍
芍                                                  芍authentication.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍pgp configurations for  芍                                      芍
芍command_mail_auth_pgp_config_dir                  芍(user) commnad mail     芍$etc_dir/pgp-command-mail-auth        芍
芍                                                  芍authentication.         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍command_mail_filter_reject_notice_data_type       芍how fml refer the       芍string                                芍
芍                                                  芍rejeced message.        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍command_mail_filter_reject_notice_recipients      芍recipients to inform    芍maintainer sender                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍the numfer of           芍                                      芍
芍command_mail_invalid_command_limit                芍ineffective commands in 芍100                                   芍
芍                                                  芍one command mail.       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍command_mail_line_length_limit                    芍maximum length of one   芍128                                   芍
芍                                                  芍command line.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍command_mail_reply_prompt                         芍command prompt in       芍>>>                                   芍
芍                                                  芍message reply           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍restrictions for command芍isolate_system_special_accounts       芍
芍command_mail_restrictions                         芍mail                    芍permit_anonymous_command              芍
芍                                                  芍                        芍permit_user_command isolate           芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍check_header_size check_body_size     芍
芍command_mail_size_filter_rules                    芍size based filter rules.芍check_command_limit                   芍
芍                                                  芍                        芍check_line_length_limit permit        芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍the numfer of effective 芍                                      芍
芍command_mail_valid_command_limit                  芍commands in one command 芍100                                   芍
芍                                                  芍mail.                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍confirm_command_expire_limit                      芍how long confirmation is芍14d                                   芍
芍                                                  芍effective ?             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍confirm_command_prefix                            芍special command name    芍confirm                               芍
芍                                                  芍used as confirmation    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍restrict "who can create芍                                      芍
芍createonpost_newml_maps                           芍a new ML". PCRE is      芍pcre:$ml_home_dir/newml.allow.pcre    芍
芍                                                  芍available.              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍reject_system_special_accounts        芍
芍                                                  芍                        芍reject_errormail                      芍
芍createonpost_newml_restrictions                   芍Who can create a new    芍reject_fml8_managed_address           芍
芍                                                  芍CREATE-ON-POST ML ?     芍reject_createonpost_domain            芍
芍                                                  芍                        芍permit_createonpost_maintainer_maps   芍
芍                                                  芍                        芍permit_ml_domain                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍createonpost_sender_maps                          芍restrict "who can post".芍pcre:$ml_home_dir/sender.allow.pcre   芍
芍                                                  芍PCRE is available.      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍reject_system_special_accounts        芍
芍                                                  芍                        芍reject_errormail                      芍
芍createonpost_sender_restrictions                  芍who can post for        芍reject_list_header_field              芍
芍                                                  芍CREATE-ON-POST ML ?     芍reject_fml8_managed_address           芍
芍                                                  芍                        芍reject_createonpost_domain            芍
芍                                                  芍                        芍permit_anyone                         芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍restrict "who can       芍                                      芍
芍createonpost_subscribe_maps                       芍subscribe". PCRE is     芍pcre:$ml_home_dir/subscribe.allow.pcre芍
芍                                                  芍available.              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍reject_system_special_accounts        芍
芍                                                  芍                        芍reject_errormail                      芍
芍createonpost_subscribe_restrictions               芍who can subscribe ?     芍reject_fml8_managed_address           芍
芍                                                  芍                        芍reject_createonpost_domain            芍
芍                                                  芍                        芍permit_anyone                         芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍db_dir                                            芍directoy to hold several芍$var_dir/db                           芍
芍                                                  芍data files              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍default_mail_body_size_limit                      芍body size limit         芍10240000                              芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍default_mail_header_size_limit                    芍header size limit       芍102400                                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍deny_file                                         芍deny file               芍$ml_home_dir/deny                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍digest_header_rewrite_rules                       芍digest article header   芍add_software_info add_rfc2369         芍
芍                                                  芍rewrite rules           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍digest_member_maps                                芍dummy                   芍$primary_member_maps                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍digest_recipient_maps                             芍all maps of digest      芍$primary_digest_recipient_map         芍
芍                                                  芍recipients.             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍digest_sequence_file                              芍file to store the last  芍$ml_home_dir/seq-digest               芍
芍                                                  芍sequence to deliver     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍directory_default_mode                            芍default mode in creating芍0755                                  芍
芍                                                  芍directory.              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_config_base_dir                            芍system data directory   芍$ml_home_prefix/etc                   芍
芍                                                  芍provided by fml         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_exim_config_dir                            芍directory to hold exim  芍$domain_config_base_dir/exim          芍
芍                                                  芍specific config files.  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_local_dir                                  芍domian local directory. 芍$ml_home_prefix                       芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_local_log_file                             芍domin local log file.   芍$domain_local_dir/@log@               芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_local_tmp_dir                              芍domian local temporary  芍$ml_home_prefix/@tmp@                 芍
芍                                                  芍directory.              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_mail_config_dir                            芍directory to hold config芍$domain_config_base_dir/mail          芍
芍                                                  芍files for MTA           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍directory to hold       芍                                      芍
芍domain_postfix_config_dir                         芍postfix specific config 芍$domain_config_base_dir/postfix       芍
芍                                                  芍files.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍directory to hold       芍                                      芍
芍domain_procmail_config_dir                        芍procmail specific config芍$domain_config_base_dir/procmail      芍
芍                                                  芍files.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍domain_qmail_config_dir                           芍directory to hold qmail 芍$domain_config_base_dir/qmail         芍
芍                                                  芍specific config files.  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍directory to hold       芍                                      芍
芍domain_sendmail_config_dir                        芍sendmail specific config芍$domain_config_base_dir/sendmail      芍
芍                                                  芍files.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍error_mail_analyzer_cache_dir                     芍directory to cache error芍$db_dir/error                         芍
芍                                                  芍messages.               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍error_mail_analyzer_cache_mode                    芍mode of cache expiration芍temporal                              芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍error_mail_analyzer_cache_size                    芍cache size.             芍14                                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍error_mail_analyzer_cache_type                    芍module as cache engine  芍File::CacheDir                        芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍function in             芍                                      芍
芍error_mail_analyzer_function                      芍FML::Error::Analyze to  芍histgram                              芍
芍                                                  芍analyze.                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍error_mail_analyzer_function_select_list          芍functions defined in    芍simple_count histgram                 芍
芍                                                  芍FML::Error::Analyze     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍error limit in using    芍                                      芍
芍error_mail_analyzer_simple_count_limit            芍simple_count as anlyzer 芍5                                     芍
芍                                                  芍function.               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍etc_dir                                           芍etc directory           芍$ml_home_dir/etc                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍event_queue_dir                                   芍event queue directory   芍$var_dir/event/queue                  芍
芍                                                  芍for scheduler           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍password to fetch       芍                                      芍
芍fetchfml_article_post_password                    芍article messages for    芍********                              芍
芍                                                  芍$ml_name ML             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍username to fetch       芍                                      芍
芍fetchfml_article_post_user                        芍article messages for    芍$ml_name                              芍
芍                                                  芍$ml_name ML             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍password to fetch       芍                                      芍
芍fetchfml_command_mail_password                    芍command messages for    芍********                              芍
芍                                                  芍$ml_name ML             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍username to fetch       芍                                      芍
芍fetchfml_command_mail_user                        芍command messages for    芍$ml_name-ctl                          芍
芍                                                  芍$ml_name ML             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fetchfml_error_mail_analyzer_password             芍password to fetch error 芍********                              芍
芍                                                  芍messages for $ml_name ML芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fetchfml_error_mail_analyzer_user                 芍username to fetch error 芍$ml_name-admin                        芍
芍                                                  芍messages for $ml_name ML芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fetchfml_fetch_protocol                           芍protocol to fetch       芍pop3                                  芍
芍                                                  芍messages.               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fetchfml_imap_servers                             芍imap servers fetchfml   芍localhost                             芍
芍                                                  芍process uses.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍fetchfml_pop_servers                              芍pop servers fetchfml    芍localhost                             芍
芍                                                  芍process uses.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍queue_dir fetchfml uses 芍                                      芍
芍fetchfml_queue_dir                                芍as temporary incoming   芍$var_dir/mail/queue-fetchfml          芍
芍                                                  芍queue                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍file_default_mode                                 芍default mode in creating芍0600                                  芍
芍                                                  芍file                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍maximu number of request芍                                      芍
芍get_command_request_limit                         芍in get command(s) in one芍100                                   芍
芍                                                  芍mail.                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍guide_file                                        芍guide file              芍$ml_home_dir/guide                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍help_file                                         芍help file               芍$ml_home_dir/help                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍html_archive_dir                                  芍html archive directory  芍$fml_owner_home_dir/public_html/fml/  芍
芍                                                  芍of the specific ML.     芍mlarchive/$ml_domain/$ml_name         芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍html_tmp_base_url                                 芍temporary url base for  芍/~$fml_owner/fml/tmp                  芍
芍                                                  芍CGI                     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍html_tmp_dir                                      芍temporary directory for 芍$fml_owner_home_dir/public_html/fml/  芍
芍                                                  芍CGI                     芍tmp                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍maximum size limit of   芍                                      芍
芍incoming_article_body_size_limit                  芍article body passed from芍$default_mail_body_size_limit         芍
芍                                                  芍MTA.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍maximum size limit of   芍                                      芍
芍incoming_article_header_size_limit                芍article header passed   芍$default_mail_header_size_limit       芍
芍                                                  芍from MTA.               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍maximum size limit of   芍                                      芍
芍incoming_command_mail_body_size_limit             芍article body passed from芍$default_mail_body_size_limit         芍
芍                                                  芍MTA.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍maximum size limit of   芍                                      芍
芍incoming_command_mail_header_size_limit           芍article header passed   芍$default_mail_header_size_limit       芍
芍                                                  芍from MTA.               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍incoming_mail_body_checksum_cache_dir             芍Message-ID cache        芍$db_dir/body_checksum                 芍
芍                                                  芍directory               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍incoming_mail_body_loop_check_rules               芍body loop check rules   芍check_body_checksum                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍incoming_mail_cache_dir                           芍incoming mail queue     芍$var_dir/mail/incoming                芍
芍                                                  芍directory               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍incoming_mail_cache_size                          芍the maximum number of   芍128                                   芍
芍                                                  芍cached incoming mails   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍incoming_mail_envelope_loop_check_rules           芍envelope based loop     芍check_envelope_sender                 芍
芍                                                  芍check rules             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍incoming_mail_header_loop_check_rules             芍loop check rules        芍check_message_id check_x_ml_info      芍
芍                                                  芍                        芍check_list_post                       芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍isolated_queue_dir                                芍top level directory to  芍$var_dir/mail/queue-isolated          芍
芍                                                  芍hold isolated messages  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍isolated_queue_expire_limit                       芍expire messages in the  芍14d                                   芍
芍                                                  芍queue after this limit. 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ldap_base_dn                                      芍base DN to contact in   芍dc=$ml_name, dc=fml, dc=org           芍
芍                                                  芍modify, search et.al.   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ldap_bind_dn                                      芍DN to bind.             芍dc=fml, dc=org                        芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ldap_query_add_as_ldif                            芍attributes to add into  芍fmlrecipient:&address fmlmember:&     芍
芍                                                  芍$ldap_base_dn entry.    芍address                               芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍attributes to remove    芍fmlrecipient:&address fmlmember:&     芍
芍ldap_query_delete_as_ldif                         芍from $ldap_base_dn      芍address                               芍
芍                                                  芍entry.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ldap_user                                         芍dummy                   芍fml                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍list_addresses                                    芍addresses fml uses: e.g.芍$maintainer $article_post_address     芍
芍                                                  芍elena, elena-ctl        芍$command_mail_address                 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍list_command_default_maps                         芍default map to show by  芍$recipient_maps                       芍
芍                                                  芍list command.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍listinfo_base_dir                                 芍base directory for ML   芍$fml_owner_home_dir/public_html/fml/  芍
芍                                                  芍information             芍listinfo                              芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍listinfo_dir                                      芍directory for ML        芍$listinfo_base_dir/$ml_domain/$ml_name芍
芍                                                  芍information             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍listinfo_template_base_dir                        芍listinfo template       芍$fml_share_dir/listinfo               芍
芍                                                  芍template dir            芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍listinfo_template_dir                             芍listinfo template       芍$fml_share_dir/listinfo/              芍
芍                                                  芍                        芍$template_file_charset                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍lock_dir                                          芍directory where lock    芍$var_dir/lock                         芍
芍                                                  芍files are created.      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍lock_file                                         芍giant lock file name    芍$lock_dir/giantlock                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍lock_type                                         芍lock algorithm type     芍flock                                 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_command_tail_starting_location                芍show the last N lines of芍100                                   芍
芍                                                  芍log file where N == 100.芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_computer_output_engine                        芍specify perl module for 芍FML::Log::Print::Simple               芍
芍                                                  芍output engine.          芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_dir                                           芍log dir                 芍$var_dir/log                          芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_file                                          芍log file.               芍$ml_home_dir/log                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_format_type                                   芍log message format      芍process[pid]                          芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍number of archive files 芍                                      芍
芍log_rotate_archive_file_total                     芍to be kept besides the  芍7                                     芍
芍                                                  芍log                     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍The interval field      芍                                      芍
芍log_rotate_interval                               芍specifies the time      芍86400                                 芍
芍                                                  芍separation              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_rotate_policy                                 芍log rotation policy.    芍size                                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_rotate_size_limit                             芍rotate log if the size  芍300000                                芍
芍                                                  芍is over this size.      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_syslog_facility                               芍see syslog(3)           芍mail                                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_syslog_ident                                  芍string prepended to     芍fml/$program_name                     芍
芍                                                  芍every message.          芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_syslog_options                                芍see syslog(3)           芍pid                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_syslog_priority                               芍see syslog(3)           芍info                                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍log_type                                          芍logging type            芍file                                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_aliases_file                                 芍aliases                 芍$domain_mail_config_dir/aliases       芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_errors_to                     芍default Errors-To:      芍$maintainer                           芍
芍                                                  芍field.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_help                     芍default list-help header芍<mailto:${command_mail_address}?body= 芍
芍                                                  芍field.                  芍help>                                 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_id                       芍default list-id header  芍$ml_name ML <$ml_name.$ml_domain>     芍
芍                                                  芍field.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_owner                    芍default list-owner      芍<mailto:${maintainer}>                芍
芍                                                  芍header field.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_post                     芍default list-post header芍<mailto:${article_post_address}>      芍
芍                                                  芍field.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_software                 芍default list-software   芍$fml_version                          芍
芍                                                  芍header field.           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_subscribe                芍default list-subscribe  芍<mailto:${command_mail_address}?body= 芍
芍                                                  芍header field.           芍subscribe>                            芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_list_unsubscribe              芍default list-unsubscribe芍<mailto:${command_mail_address}?body= 芍
芍                                                  芍header field.           芍unsubscribe>                          芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_precedence                    芍default Precedence:     芍bulk                                  芍
芍                                                  芍field.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_header_default_x_ml_name                     芍default X-ML-Name:      芍$ml_name                              芍
芍                                                  芍field.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍mail_queue_dir                                    芍mail queue directory    芍$var_dir/mail/queue                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍member_maps                                       芍all maps used to check  芍$primary_member_map $admin_member_maps芍
芍                                                  芍member list.            芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍member_total_limit                                芍upper limit of posters. 芍3000                                  芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍message_id_cache_dir                              芍Message-ID cache        芍$db_dir/message_id                    芍
芍                                                  芍directory               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍message_template_dir                              芍directory to hold       芍$fml_share_dir/message                芍
芍                                                  芍message template files  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍base directory which    芍                                      芍
芍ml_admin_cgi_base_dir                             芍locates .cgi for this   芍$cgi_base_dir/ml-admin/$ml_name       芍
芍                                                  芍ML.                     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ml_anonymous_cgi_allowed_commands                 芍                        芍subscribe unsubscribe                 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍ml specific directory   芍$anonymous_cgi_base_dir/$ml_domain/   芍
芍ml_anonymous_cgi_base_dir                         芍for anonymous cgi       芍$ml_name                              芍
芍                                                  芍scripts.                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ml_anonymous_cgi_base_url                         芍ml specific url base for芍/~$fml_owner/cgi-bin/anonymous/       芍
芍                                                  芍anonymous cgi scripts.  芍$ml_domain/$ml_name                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ml_local_dir                                      芍ML local directory      芍$ml_home_dir/local                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ml_local_lib_dir                                  芍ML local library path   芍$ml_local_dir/lib                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍directory to hold ml    芍                                      芍
芍ml_local_message_template_dir                     芍specific message        芍$ml_local_share_dir/message           芍
芍                                                  芍template files          芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍ml_local_share_dir                                芍ML local share/         芍$ml_local_dir/share                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍queue_dir moderate uses 芍                                      芍
芍moderate_queue_dir                                芍as temporary incoming   芍$var_dir/mail/queue-moderate          芍
芍                                                  芍queue                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍expire submitted queue  芍                                      芍
芍moderate_queue_expire_limit                       芍after                   芍14d                                   芍
芍                                                  芍$moderate_expire_limit. 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍moderator_member_maps                             芍all list of moderator   芍$primary_moderator_member_map         芍
芍                                                  芍lists.                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍moderator_recipient_maps                          芍dummy                   芍$primary_moderator_recipient_map      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍newml_command_ml_admin_default_address            芍fml_owner value used by 芍$fml_owner                            芍
芍                                                  芍newml command.          芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍newml_command_postfix_template_files              芍templates of include    芍include include-ctl include-error     芍
芍                                                  芍files                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍templates files of ~fml 芍dot-qmail dot-qmail-ctl               芍
芍newml_command_qmail_template_files                芍/.qmail-*               芍dot-qmail-admin dot-qmail-request     芍
芍                                                  芍                        芍dot-qmail-default                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍newml_command_template_files                      芍template files used in  芍config.cf                             芍
芍                                                  芍running "makefml newml" 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍objective_file                                    芍objective file          芍$ml_home_dir/objective                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_article_body_size_limit                  芍maximum size limit of   芍$default_mail_body_size_limit         芍
芍                                                  芍deliverd article body.  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_article_header_size_limit                芍maximum size limit of   芍$default_mail_header_size_limit       芍
芍                                                  芍deliverd article header.芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_command_mail_body_size_limit             芍maximum size limit of   芍$default_mail_body_size_limit         芍
芍                                                  芍deliverd article body.  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_command_mail_header_size_limit           芍maximum size limit of   芍$default_mail_header_size_limit       芍
芍                                                  芍deliverd article header.芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_mail_cache_dir                           芍outgoing mail cache     芍$var_dir/mail/outgoing                芍
芍                                                  芍directory               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_mail_cache_size                          芍the maximum number of   芍128                                   芍
芍                                                  芍cached outgoing mails   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_mail_header_errors_to                    芍Errors-To: field        芍${mail_header_default_errors_to}      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍outgoing_mail_header_precedence                   芍Precedence: field       芍${mail_header_default_precedence}     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍ml name in both         芍                                      芍
芍outgoing_mail_header_x_ml_name                    芍X-ML-Name: and          芍${mail_header_default_x_ml_name}      芍
芍                                                  芍X-Sequence header       芍                                      芍
芍                                                  芍fields.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍postfix_verp_delimiters                           芍verps delimieters used  芍+=                                    芍
芍                                                  芍in postfix              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍postfix_virtual_map_file                          芍virtual map file        芍$domain_postfix_config_dir/virtual    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍list of remote          芍                                      芍
芍primary_admin_member_map                          芍administrators who has  芍file:$ml_home_dir/members-admin       芍
芍                                                  芍priviledge              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍primary password file to芍                                      芍
芍primary_admin_member_password_map                 芍authenticate remote     芍file:$etc_dir/passwd-admin            芍
芍                                                  芍administrator           芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_admin_recipient_map                       芍dummy                   芍file:$ml_home_dir/recipients-admin    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_digest_member_map                         芍dummy                   芍$primary_member_map                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_digest_recipient_map                      芍primary list of digest  芍file:$ml_home_dir/recipients-digest   芍
芍                                                  芍recipients.             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍member list == primary  芍                                      芍
芍primary_member_map                                芍address list who can    芍file:$ml_home_dir/members             芍
芍                                                  芍post.                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_moderator_member_map                      芍primary list of         芍file:$ml_home_dir/members-moderator   芍
芍                                                  芍moderators.             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_moderator_recipient_map                   芍dummy                   芍file:$ml_home_dir/recipients-moderator芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_recipient_map                             芍primary recipients list.芍file:$ml_home_dir/recipients          芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍primary_user_db_gecos_map                         芍primary { address =>    芍$user_db_dir/gecos                    芍
芍                                                  芍gecos_field } map.      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍primary { address =>    芍                                      芍
芍primary_user_db_subscribe_date_map                芍unix time when          芍$user_db_dir/subscribe_date           芍
芍                                                  芍subscribed } map.       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍special command name    芍                                      芍
芍privileged_command_prefix                         芍used as admin command   芍admin                                 芍
芍                                                  芍mail                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍procmail_aliases_file                             芍sample of ~fml          芍$domain_procmail_config_dir/procmailrc芍
芍                                                  芍/.procmailrc            芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍qmail_verp_delimiters                             芍verps delimieters used  芍-=                                    芍
芍                                                  芍in qmail                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍qmail_virtual_map_file                            芍template of /var/qmail/ 芍$domain_qmail_config_dir/             芍
芍                                                  芍control/virtualdomains  芍virtualdomains                        芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍qmail_virtualdomains_file                         芍virtual domain          芍/var/qmail/control/virtualdomains     芍
芍                                                  芍configurations for qmail芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍recipient_maps                                    芍all maps used as        芍$primary_recipient_map                芍
芍                                                  芍recipient list.         芍file:$ml_home_dir/actives             芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍recipient_total_limit                             芍upper limit of          芍3000                                  芍
芍                                                  芍recipients.             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍sendmail_virtual_map_file                         芍sample of /etc/mail/    芍$domain_sendmail_config_dir/          芍
芍                                                  芍virtusertable           芍virtusertable                         芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍sequence_file                                     芍file to store article   芍$ml_home_dir/seq                      芍
芍                                                  芍sequence.               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍shared_db_dir                                     芍database directory      芍$ml_home_prefix/@db@                  芍
芍                                                  芍shared among ML's       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍smtp_recipient_limit                              芍recipient limits over   芍1000                                  芍
芍                                                  芍one smtp transaction.   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍smtp_sender                                       芍MAIL FROM:<$smtp_sender>芍$maintainer                           芍
芍                                                  芍in SMTP                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍smtp_servers                                      芍smtp servers.           芍[::1]:25 127.0.0.1:25                 芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍spammer_maps                                      芍list of spammers or     芍$primary_spammer_map                  芍
芍                                                  芍addresses to reject.    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍spool_dir                                         芍spool directory         芍$ml_home_dir/spool                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍spool_type                                        芍use subdir in spool     芍plane                                 芍
芍                                                  芍directory ?             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍subscribe_command_auth_type                       芍use comnfirmation in    芍confirmation                          芍
芍                                                  芍subscribe command ?     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍operate action          芍                                      芍
芍subscribe_command_operation_mode                  芍automatically or        芍automatic                             芍
芍                                                  芍manually by maintainer ?芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍system_has_alarm                                  芍has alarm(2) ?          芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍system_has_fork                                   芍has fork(2) ?           芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍system_has_getpwgid                               芍has getpwgid(2) ?       芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍system_has_getpwuid                               芍has getpwuid(2) ?       芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍system_has_select                                 芍has select(2) ?         芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍                        芍root postmaster MAILER-DAEMON msgs    芍
芍system_special_accounts                           芍list of system accounts.芍nobody news majordomo listserv        芍
芍                                                  芍                        芍listproc \S+\-help \S+\-subscribe \S+\芍
芍                                                  芍                        芍-unsubscribe                          芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_cgi_base_url                               芍CGI relative path       芍/cgi-bin/fmlthread.cgi                芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_cgi_bgcolor                                芍CGI color               芍#E6E6FA                               芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_cgi_title                                  芍CGI title               芍thread tracking system interface      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_db_dir                                     芍directory to hold ticket芍$shared_db_dir/thread                 芍
芍                                                  芍data                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_id_syntax                                  芍ticket number           芍$ml_name/%d                           芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_sequence_file                              芍file to store ticket    芍$ml_home_dir/thread.seq               芍
芍                                                  芍sequence                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_subject_tag                                芍syntax added to Subject:芍[$thread_id_syntax]                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_subject_tag_location                       芍location of insertion of芍appended                              芍
芍                                                  芍tag                     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍thread_subject_tag_name                           芍ml name assigned to     芍$ml_name                              芍
芍                                                  芍ticket                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍tmp_dir                                           芍directory to hold       芍$ml_home_dir/tmp                      芍
芍                                                  芍temporary files         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍udb_base_dir                                      芍database directory      芍$ml_home_prefix/@udb@                 芍
芍                                                  芍shared among ML's.      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍unsafe_header_fields                              芍remove unsafe header    芍Return-Receipt-To                     芍
芍                                                  芍fields                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍unsubscribe_command_auth_type                     芍use comnfirmation in    芍confirmation                          芍
芍                                                  芍unsubscribe command ?   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍operate action          芍                                      芍
芍unsubscribe_command_operation_mode                芍automatically or        芍automatic                             芍
芍                                                  芍manually by maintainer ?芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_address_compare_function                      芍FML::Credential checks  芍yes                                   芍
芍                                                  芍address comparison      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_admin_command_mail_function                   芍use admin command mail ?芍no                                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍allow a request e.g.    芍                                      芍
芍use_anonymous_cgi_function                        芍subscribe and           芍yes                                   芍
芍                                                  芍unsubscribe from www.   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_delivery                              芍user article delivery   芍yes                                   芍
芍                                                  芍function ?              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_expire                                芍expire too old article  芍no                                    芍
芍                                                  芍or not ?                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_filter_reject_notice                  芍infor the filter        芍yes                                   芍
芍                                                  芍rejection ?             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_header_filter                         芍use header based filter 芍yes                                   芍
芍                                                  芍?                       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_header_rewrite                        芍use article header      芍yes                                   芍
芍                                                  芍rewrite function ?      芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_mime_component_filter                 芍MIME structure based    芍yes                                   芍
芍                                                  芍filter                  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_non_mime_filter                       芍dummy                   芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_post_function                         芍use function of article 芍${use_distribute_program:-yes}        芍
芍                                                  芍delivery                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_size_filter                           芍use size based filter.  芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_spam_filter                           芍use external spam       芍no                                    芍
芍                                                  芍checker.                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_spool                                 芍store article into spool芍${ues_spool:-yes}                     芍
芍                                                  芍directory ?             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍remove content          芍                                      芍
芍use_article_summary_file_expire                   芍correspoding with       芍no                                    芍
芍                                                  芍article expiration.     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍use text/plain filter,  芍                                      芍
芍use_article_text_plain_filter                     芍which is a simple syntax芍yes                                   芍
芍                                                  芍checker.                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_thread_outline                        芍add thread outline      芍no                                    芍
芍                                                  芍automatically ?         芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_article_virus_filter                          芍external virus checker. 芍no                                    芍
芍                                                  芍disabled by default.    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_command_mail_filter_reject_notice             芍inform filter rejection 芍yes                                   芍
芍                                                  芍?                       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_command_mail_function                         芍use commnd mail ?       芍${use_command_mail_program:-yes}      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍add self introduction   芍                                      芍
芍use_command_mail_reply_preamble                   芍into the preamble of    芍yes                                   芍
芍                                                  芍command mail reply.     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍add processing summary  芍                                      芍
芍use_command_mail_reply_trailor                    芍into the trailor of     芍yes                                   芍
芍                                                  芍command mail reply.     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_command_mail_size_filter                      芍use size based filter   芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_createonpost_function                         芍use CREATE-ON-POST or   芍yes                                   芍
芍                                                  芍not ?                   芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_debug                                         芍debug on or off (off by 芍no                                    芍
芍                                                  芍default).               芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍use digest article      芍                                      芍
芍use_digest_header_rewrite                         芍header rewrite function 芍yes                                   芍
芍                                                  芍?                       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_error_mail_analyzer_function                  芍use error message       芍${use_error_analyzer_program:-yes}    芍
芍                                                  芍analyzer ?              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍use fetchfml            芍                                      芍
芍use_fetchfml_article_post_function                芍article_post function or芍yes                                   芍
芍                                                  芍not.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍use fetchfml            芍                                      芍
芍use_fetchfml_command_mail_function                芍command_mail function or芍yes                                   芍
芍                                                  芍not.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍use fetchfml            芍                                      芍
芍use_fetchfml_error_mail_analyzer_function         芍error_mail_analyzer     芍yes                                   芍
芍                                                  芍function or not.        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_fetchfml_function                             芍use fetchfml function or芍no                                    芍
芍                                                  芍not.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_html_archive                                  芍use html converter      芍yes                                   芍
芍                                                  芍function ?              芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_incoming_mail_body_loop_check                 芍use loop check based on 芍yes                                   芍
芍                                                  芍body information        芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_incoming_mail_cache                           芍cache incoing mail ?    芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_incoming_mail_envelope_loop_check             芍enable envelope based   芍yes                                   芍
芍                                                  芍loop check or not ?     芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_incoming_mail_header_loop_check               芍use loop check based on 芍yes                                   芍
芍                                                  芍header information ?    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_lock                                          芍use lock system ?       芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_log                                           芍user logging function   芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍if yes, makefml/fml     芍                                      芍
芍use_log_computer_output                           芍outputs machine friendly芍no                                    芍
芍                                                  芍log.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_log_rotate                                    芍rotate log files or not.芍no                                    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍upper limit of posters. 芍                                      芍
芍use_member_total_limit                            芍no limitation by        芍no                                    芍
芍                                                  芍default.                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_moderate_function                             芍use moderate function or芍yes                                   芍
芍                                                  芍not.                    芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_outgoing_mail_cache                           芍cache outgoing mail     芍yes                                   芍
芍                                                  芍cache ?                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍upper limit of          芍                                      芍
芍use_recipient_total_limit                         芍recipients. no          芍no                                    芍
芍                                                  芍limitation by default.  芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_smtp_log                                      芍log smtp transaction ?  芍yes                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_spool                                         芍store article into spool芍yes                                   芍
芍                                                  芍directory ?             芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_thread_subject_tag                            芍use special subject tag 芍no                                    芍
芍                                                  芍?                       芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍use_thread_track                                  芍user thread tracking    芍yes                                   芍
芍                                                  芍system ?                芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍                                                  芍effective command in    芍help get mget get mget send subscribe 芍
芍user_command_mail_allowed_commands                芍normal commnd mail (for 芍add unsubscribe bye on off digest     芍
芍                                                  芍usual users)            芍remove resign signoff chaddr confirm  芍
芍                                                  芍                        芍guide info admin objective summary    芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍user_db_dir                                       芍user database directory.芍$db_dir/user_info                     芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍user_db_gecos_maps                                芍{ address => gecos_field芍$primary_user_db_gecos_map            芍
芍                                                  芍} maps.                 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍user_db_subscribe_date_maps                       芍{ address => unix time  芍$primary_user_db_subscribe_date_map   芍
芍                                                  芍when subscribed } maps. 芍                                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍var_dir                                           芍directory hoding        芍$ml_home_dir/var                      芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋走芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍welcome_file                                      芍welcome file            芍$ml_home_dir/welcome                  芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋赤芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Variable List (Class Based)

__exceptional__ {
    ?     $timezone
}

address {

   address_compare {
    ?     $address_compare_function_domain_matching_level
          $address_compare_function_type
          $use_address_compare_function
   }
}

admin {

   admin_command {
   }

   admin_command_mail {
    ?     $admin_command_mail_allowed_commands
          $admin_command_mail_auth_gpg_config_dir
    ?     $admin_command_mail_auth_gpg_config_dir_alias
          $admin_command_mail_auth_pgp_config_dir
    ?     $admin_command_mail_auth_pgp_config_dir_alias
          $admin_command_mail_restrictions
          $use_admin_command_mail_function
   }

   admin_member {
          $admin_member_maps
          $primary_admin_member_map
   }

   admin_member_password {
          $admin_member_password_maps
          $primary_admin_member_password_map
   }

   admin_recipient {
          $admin_recipient_maps
          $primary_admin_recipient_map
   }

   admin_* {
    ?     $admin_cgi_allowed_commands
          $admin_cgi_base_dir
   }
}

anonymous {

   anonymous_cgi {
          $anonymous_cgi_base_dir
          $anonymous_cgi_expire_limit
    ?     $ml_anonymous_cgi_allowed_commands
          $ml_anonymous_cgi_base_dir
    ?     $ml_anonymous_cgi_base_url
          $use_anonymous_cgi_function
   }

   anonymous_command {
    ?     $anonymous_command_mail_allowed_commands
   }
}

article {

   article_delivery {
    ?     $article_delivery_transport
          $use_article_delivery
   }

   article_digest {
          $use_article_digest_function
   }

   article_expire {
          $article_expire_limit
          $use_article_expire
   }

   article_filter {
          $article_filter_functions
          $use_article_filter
   }

   article_filter_reject_notice {
          $article_filter_reject_notice_data_type
    ?     $article_filter_reject_notice_recipients
          $use_article_filter_reject_notice
   }

   article_header_filter {
          $article_header_filter_rules
          $use_article_header_filter
   }

   article_header_rewrite {
          $article_header_rewrite_rules
          $use_article_header_rewrite
   }

   article_mime_component_filter {
          $article_mime_component_filter_rules
          $use_article_mime_component_filter
   }

   article_non_mime_filter {
          $article_non_mime_filter_rules
          $use_article_non_mime_filter
   }

   article_post {
    ?     $article_post_address
    ?     $article_post_article_thread_lifetime
          $article_post_auth_gpg_config_dir
          $article_post_auth_pgp_config_dir
          $article_post_encrypt_gpg_config_dir
          $article_post_encrypt_pgp_config_dir
          $article_post_restrictions
          $article_post_restrictions_reject_notice_data_type
          $use_article_post_function
   }

   article_size_filter {
          $article_size_filter_rules
          $use_article_size_filter
   }

   article_spam_filter {
    ?     $article_spam_filter_bogofilter_options
    ?     $article_spam_filter_drivers
          $article_spam_filter_functions
          $article_spam_filter_rules
    ?     $article_spam_filter_spamassassin_options
    ?     $article_spam_filter_spamc_options
          $use_article_spam_filter
   }

   article_spool {
          $use_article_spool
   }

   article_summary_file_expire {
          $use_article_summary_file_expire
   }

   article_text_plain_filter {
          $article_text_plain_filter_rules
          $use_article_text_plain_filter
   }

   article_thread_outline {
    ?     $article_thread_outline_greeting_en
    ?     $article_thread_outline_greeting_ja
          $article_thread_outline_rules
          $use_article_thread_outline
   }

   article_virus_filter {
    ?     $article_virus_filter_clamav_options
    ?     $article_virus_filter_drivers
          $article_virus_filter_functions
          $article_virus_filter_rules
          $use_article_virus_filter
   }

   article_* {
    ?     $article_header_list_help
    ?     $article_header_list_id
    ?     $article_header_list_owner
    ?     $article_header_list_post
    ?     $article_header_list_software
    ?     $article_header_list_subscribe
    ?     $article_header_list_unsubscribe
          $article_message_id_cache_dir
          $article_sequence_file
    ?     $article_subject_tag
          $article_summary_file
    ?     $article_summary_file_format_address_length
    ?     $article_summary_file_format_style
   }
}

cgi {

   cgi_* {
          $cgi_base_dir
    ?     $cgi_charset_en
    ?     $cgi_charset_ja
    ?     $cgi_default_charset
    ?     $cgi_default_language
    ?     $cgi_language_select_list
    ?     $cgi_main_menu_color
    ?     $cgi_menu_address_map_select_list
          $cgi_menu_default_address_map
    ?     $cgi_navigation_bar_color
   }
}

command {

   command_mail {
    ?     $command_mail_address
          $command_mail_auth_gpg_config_dir
          $command_mail_auth_pgp_config_dir
          $command_mail_line_length_limit
    ?     $command_mail_reply_prompt
          $command_mail_restrictions
          $use_command_mail_function
   }

   command_mail_filter {
          $command_mail_filter_functions
          $use_command_mail_filter
   }

   command_mail_filter_reject_notice {
          $command_mail_filter_reject_notice_data_type
    ?     $command_mail_filter_reject_notice_recipients
          $use_command_mail_filter_reject_notice
   }

   command_mail_invalid_command {
          $command_mail_invalid_command_limit
   }

   command_mail_reply_preamble {
          $use_command_mail_reply_preamble
   }

   command_mail_reply_trailor {
          $use_command_mail_reply_trailor
   }

   command_mail_size_filter {
          $command_mail_size_filter_rules
          $use_command_mail_size_filter
   }

   command_mail_valid_command {
          $command_mail_valid_command_limit
   }
}

admin_command {

   admin_command {
   }

   admin_command_mail {
   }
}

anonymous_command {

   anonymous_command {
   }
}

chaddr_command {

   chaddr_command {
          $chaddr_command_auth_type
    ?     $chaddr_command_operation_mode
   }
}

confirm_command {

   confirm_command {
          $confirm_command_expire_limit
    ?     $confirm_command_prefix
   }
}

get_command {

   get_command {
          $get_command_request_limit
   }
}

list_command {

   list_command {
   }

   list_command_default {
          $list_command_default_maps
   }
}

log_command {

   log_command {
    ?     $log_command_tail_starting_location
   }
}

newml_command {

   newml_command {
    ?     $newml_command_init_private_directories
    ?     $newml_command_init_public_directories
    ?     $newml_command_ml_admin_default_address
    ?     $newml_command_mta_config_list
          $newml_command_postfix_template_files
          $newml_command_qmail_template_files
          $newml_command_template_files
   }
}

privileged_command {

   privileged_command {
    ?     $privileged_command_prefix
   }
}

rmml_command {

   rmml_command {
    ?     $rmml_command_mta_config_list
   }
}

subscribe_command {

   subscribe_command {
          $subscribe_command_auth_type
    ?     $subscribe_command_operation_mode
   }
}

unsubscribe_command {

   unsubscribe_command {
          $unsubscribe_command_auth_type
    ?     $unsubscribe_command_operation_mode
   }
}

user_command {

   user_command {
    ?     $user_command_mail_allowed_commands
   }
}

createonpost {

   createonpost {
          $use_createonpost_function
   }

   createonpost_newml {
          $createonpost_newml_maps
          $createonpost_newml_restrictions
   }

   createonpost_sender {
          $createonpost_sender_maps
          $createonpost_sender_restrictions
   }

   createonpost_subscribe {
          $createonpost_subscribe_maps
          $createonpost_subscribe_restrictions
   }
}

debug {

   debug {
          $use_debug
   }
}

default {

   default_* {
          $default_mail_body_size_limit
          $default_mail_header_size_limit
   }
}

digest {

   digest_header_rewrite {
          $digest_header_rewrite_rules
          $use_digest_header_rewrite
   }

   digest_member {
          $digest_member_maps
          $primary_digest_member_map
   }

   digest_recipient {
          $digest_recipient_maps
          $primary_digest_recipient_map
   }

   digest_* {
          $digest_sequence_file
   }
}

directory {

   directory_* {
    ?     $directory_default_mode
    ?     $directory_private_mode
    ?     $directory_public_mode
   }
}

domain {

   domain_* {
          $domain_config_base_dir
          $domain_exim_config_dir
          $domain_local_dir
          $domain_local_tmp_dir
          $domain_mail_config_dir
          $domain_postfix_config_dir
          $domain_procmail_config_dir
          $domain_qmail_config_dir
          $domain_sendmail_config_dir
   }
}

error {

   error_mail_analyzer {
          $error_mail_analyzer_cache_dir
    ?     $error_mail_analyzer_cache_mode
    ?     $error_mail_analyzer_cache_size
          $error_mail_analyzer_cache_type
    ?     $error_mail_analyzer_function
    ?     $error_mail_analyzer_function_select_list
          $error_mail_analyzer_simple_count_limit
          $use_error_mail_analyzer_function
   }
}

fetchfml {

   fetchfml {
    ?     $fetchfml_fetch_protocol
    ?     $fetchfml_imap_servers
    ?     $fetchfml_pop_servers
          $fetchfml_queue_dir
          $use_fetchfml_function
   }

   fetchfml_article_post {
    ?     $fetchfml_article_post_password
    ?     $fetchfml_article_post_user
          $use_fetchfml_article_post_function
   }

   fetchfml_command_mail {
    ?     $fetchfml_command_mail_password
    ?     $fetchfml_command_mail_user
          $use_fetchfml_command_mail_function
   }

   fetchfml_error_mail_analyzer {
    ?     $fetchfml_error_mail_analyzer_password
    ?     $fetchfml_error_mail_analyzer_user
          $use_fetchfml_error_mail_analyzer_function
   }
}

html {

   html_archive {
    ?     $html_archive_charset_en
    ?     $html_archive_charset_ja
    ?     $html_archive_default_charset
          $html_archive_dir
          $html_archive_index_order_type
          $use_html_archive
   }

   html_archive_address_mask {
          $html_archive_address_mask_type
          $use_html_archive_address_mask
   }

   html_* {
    ?     $html_tmp_base_url
          $html_tmp_dir
   }
}

incoming {

   incoming_article {
          $incoming_article_body_size_limit
          $incoming_article_header_size_limit
   }

   incoming_command_mail {
          $incoming_command_mail_body_size_limit
          $incoming_command_mail_header_size_limit
   }

   incoming_mail_body_loop_check {
          $incoming_mail_body_loop_check_rules
          $use_incoming_mail_body_loop_check
   }

   incoming_mail_cache {
          $incoming_mail_cache_dir
    ?     $incoming_mail_cache_size
          $use_incoming_mail_cache
   }

   incoming_mail_envelope_loop_check {
          $incoming_mail_envelope_loop_check_rules
          $use_incoming_mail_envelope_loop_check
   }

   incoming_mail_header_loop_check {
          $incoming_mail_header_loop_check_rules
          $use_incoming_mail_header_loop_check
   }

   incoming_* {
          $incoming_mail_body_checksum_cache_dir
   }
}

ldap {

   ldap_* {
    ?     $ldap_base_dn
    ?     $ldap_bind_dn
    ?     $ldap_password
    ?     $ldap_query_add_as_ldif
    ?     $ldap_query_delete_as_ldif
    ?     $ldap_query_find_result_attribute
    ?     $ldap_query_find_search_filter
    ?     $ldap_query_get_next_key_result_attribute
    ?     $ldap_query_get_next_key_search_filter
    ?     $ldap_query_getline_result_attribute
    ?     $ldap_query_getline_search_filter
    ?     $ldap_servers
    ?     $ldap_user
   }
}

list {

   list_command {
   }

   list_command_default {
   }

   list_* {
    ?     $list_addresses
   }
}

lock {

   lock {
          $lock_dir
          $lock_file
          $lock_type
          $use_lock
   }
}

log {

   log {
          $domain_local_log_file
          $log_dir
          $log_file
    ?     $log_file_charset_en
    ?     $log_file_charset_ja
    ?     $log_file_default_charset
          $log_format_type
    ?     $log_syslog_facility
    ?     $log_syslog_ident
    ?     $log_syslog_options
    ?     $log_syslog_priority
    ?     $log_syslog_servers
          $log_type
          $use_log
   }

   log_command {
   }

   log_computer_output {
    ?     $log_computer_output_engine
          $use_log_computer_output
   }

   log_rotate {
    ?     $log_rotate_archive_file_total
    ?     $log_rotate_interval
    ?     $log_rotate_policy
          $log_rotate_size_limit
          $use_log_rotate
   }
}

mail {

   mail_* {
          $mail_aliases_file
    ?     $mail_header_default_errors_to
    ?     $mail_header_default_list_help
    ?     $mail_header_default_list_id
    ?     $mail_header_default_list_owner
    ?     $mail_header_default_list_post
    ?     $mail_header_default_list_software
    ?     $mail_header_default_list_subscribe
    ?     $mail_header_default_list_unsubscribe
    ?     $mail_header_default_precedence
    ?     $mail_header_default_x_ml_name
          $mail_queue_dir
   }
}

maintainer {

   maintainer_recipient {
          $maintainer_recipient_maps
   }

   maintainer_* {
    ?     $maintainer
    ?     $maintainer_signature
   }
}

member {

   member {
          $member_maps
          $primary_member_map
   }

   member_total_limit {
          $member_total_limit
          $use_member_total_limit
   }
}

message {

   message_* {
    ?     $message_default_subject
          $message_id_cache_dir
          $message_template_dir
   }
}

ml_local {

   ml_local_* {
          $ml_local_dir
          $ml_local_lib_dir
          $ml_local_message_template_dir
          $ml_local_share_dir
   }
}

moderate {

   moderate {
          $moderate_queue_dir
          $moderate_queue_expire_limit
          $use_moderate_function
   }
}

moderator {

   moderator_member {
          $moderator_member_maps
          $primary_moderator_member_map
   }

   moderator_recipient {
          $moderator_recipient_maps
          $primary_moderator_recipient_map
   }
}

outgoing {

   outgoing_article {
          $outgoing_article_body_size_limit
          $outgoing_article_header_size_limit
   }

   outgoing_command_mail {
          $outgoing_command_mail_body_size_limit
          $outgoing_command_mail_header_size_limit
   }

   outgoing_mail_cache {
          $outgoing_mail_cache_dir
    ?     $outgoing_mail_cache_size
          $use_outgoing_mail_cache
   }

   outgoing_* {
    ?     $outgoing_mail_header_errors_to
    ?     $outgoing_mail_header_precedence
    ?     $outgoing_mail_header_x_ml_name
   }
}

path {

   path_* {
          $path_bogofilter
          $path_bunzip2
          $path_bzip2
          $path_cksum
          $path_clamscan
          $path_compress
          $path_emacs
          $path_gpg
          $path_gpgsplit
          $path_gpgv
          $path_gunzip
          $path_gzcat
          $path_gzip
          $path_ish
          $path_kakasi
          $path_less
          $path_lha
          $path_ls
          $path_makemap
          $path_md5
          $path_more
          $path_mule
          $path_namazu
          $path_newaliases
          $path_ng
          $path_nkf
          $path_perl
          $path_pgp
          $path_pgp5
          $path_pgpe
          $path_pgpk
          $path_pgps
          $path_pgpv
          $path_postalias
          $path_postconf
          $path_postfix
          $path_postmap
          $path_sendmail
          $path_spamassassin
          $path_spamc
          $path_spamd
          $path_sum
          $path_tar
          $path_uuencode
          $path_vi
          $path_w3m
          $path_xemacs
          $path_zcat
   }
}

post {
}

postfix {

   postfix_* {
    ?     $postfix_verp_delimiters
          $postfix_virtual_map_file
   }
}

procmail {

   procmail_* {
          $procmail_aliases_file
   }
}

qmail {

   qmail_* {
    ?     $qmail_verp_delimiters
          $qmail_virtual_map_file
          $qmail_virtualdomains_file
   }
}

recipient {

   recipient {
          $primary_recipient_map
          $recipient_maps
          $smtp_recipient_limit
   }

   recipient_total_limit {
          $recipient_total_limit
          $use_recipient_total_limit
   }
}

reply_message {
}

report_mail {

   report_mail_* {
    ?     $report_mail_charset_en
    ?     $report_mail_charset_ja
    ?     $report_mail_default_charset
    ?     $report_mail_subject
   }
}

sendmail {

   sendmail_* {
          $sendmail_virtual_map_file
   }
}

smtp {

   smtp_log {
          $use_smtp_log
   }

   smtp_* {
    ?     $smtp_sender
    ?     $smtp_servers
   }
}

spammer {

   spammer {
          $primary_spammer_map
          $spammer_maps
   }
}

spool {

   spool {
          $spool_dir
    ?     $spool_subdir_unit
          $spool_type
          $use_spool
   }
}

sql {

   sql_* {
    ?     $sql_database
    ?     $sql_password
    ?     $sql_query_add
    ?     $sql_query_delete
    ?     $sql_query_find
    ?     $sql_query_get_next_key
    ?     $sql_query_getline
    ?     $sql_servers
    ?     $sql_table
    ?     $sql_user
   }
}

system {

   system_* {
    ?     $system_default_umask
    ?     $system_has_alarm
    ?     $system_has_fork
    ?     $system_has_getpwgid
    ?     $system_has_getpwuid
    ?     $system_has_select
    ?     $system_special_accounts
    ?     $system_timezone
   }
}

template_file {

   template_file_* {
    ?     $template_file_charset_en
    ?     $template_file_charset_ja
    ?     $template_file_charset_select_list
    ?     $template_file_default_charset
   }
}

thread {

   thread_subject_tag {
    ?     $thread_subject_tag
    ?     $thread_subject_tag_location
    ?     $thread_subject_tag_name
          $use_thread_subject_tag
   }

   thread_track {
          $use_thread_track
   }

   thread_* {
    ?     $thread_cgi_base_url
    ?     $thread_cgi_bgcolor
    ?     $thread_cgi_title
          $thread_db_dir
    ?     $thread_id_syntax
          $thread_sequence_file
   }
}

user {

   user_command {
   }

   user_db_gecos {
          $primary_user_db_gecos_map
          $user_db_gecos_maps
   }

   user_db_subscribe_date {
          $primary_user_db_subscribe_date_map
          $user_db_subscribe_date_maps
   }

   user_* {
          $user_db_dir
   }
}

x {
}


_file$ {
          $compat_old_fml_default_config_ph_file
          $deny_file
          $guide_file
          $help_file
          $objective_file
          $sequence_file
          $welcome_file
}

_dir$ {
          $compat_config_base_dir
          $compat_old_fml_config_dir
          $db_dir
          $etc_dir
          $event_queue_dir
          $isolated_queue_dir
          $listinfo_base_dir
          $listinfo_dir
          $listinfo_template_base_dir
          $listinfo_template_dir
          $ml_admin_cgi_base_dir
          $shared_db_dir
          $tmp_dir
          $udb_base_dir
          $var_dir
}


*** unclassified ***
    ?     $file_default_mode
          $isolated_queue_expire_limit
    ?     $language_preference_order
    ?     $ml_admin_cgi_allowed_commands
    ?     $unsafe_header_fields

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. What functions are proper used in config.cf file ?

1. What functions are proper used in config.cf file ?

Use methods of $curproc (in hooks).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 30. Create A New Program

Create A Program (CUI)

Firstly, prepare a new module in FML::Process class. See FML::Process::Calendar
as the least functional model and see FML::Process::Distribute for the most
complicated class.

See FML::Process::Flow::ProcessStart() for mandatory methods to implement.
FML::Process::Flow::ProcessStart() kicks off several methods sequentially. At
2002/07, these methods are mandatory.

new()
prepare()
verify_request()
run()
finish()

        FML::Process::Kernel
                |       uses-a FML::Process::{Flow,Utils} FML::Parse ...
                |
                A
        FML::Process::MODULE
                        uses-a FML::Something
                        uses-a CPAN module
                        uses-a ...

If you have prepared FML::Process::MODULE, define relation between the program
name and the module at fml/etc/modules. Also, define available command line
options at fml/etc/command_line_options if needed.

After it is prepared, symlink the loader and the new program name. For example,

% ls -l /usr/local/libexec/fml
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 command@ -> loader
drwxr-xr-x  2 root  wheel   512 Apr 14 18:25 current-20030414/
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 digest@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 distribute@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 error@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fml@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fml.pl@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmladdr@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmlalias@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmlconf@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmldoc@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmlhtmlify@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmlsch@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 fmlserv@ -> loader
-rwxr-xr-x  1 root  wheel  6863 Apr 14 18:24 loader*
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 makefml@ -> loader
lrwxr-xr-x  1 root  wheel     6 Apr 14 18:25 mead@ -> loader

As a test, you symlink it explicitly. For the canonical programs, fml installer
symlinks them according to fml/etc/install.cf. You need to define the program
as $bin_programs or $exec_programs in install.cf.in (configure generates
install.cf).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Create A Program (CGI)

The main part of CGI program is implemented as an FML::CGI::XXX class. These
modules have the following relation.

        FML::Process::Kernel
                |
                A
        FML::Process::CGI::Kernel   uses-a CGI
                |
                A
        FML::Process::CGI
                |
                A
        FML::CGI::XXX

How to write CGI programs is same as one of CUI. GUI modules locate under
FML::CGI to clarify the difference between CUI and GUI.

In the case of CGI, prepare the following methods for screen control in
FML::CGI::MODULE.

html_start()
html_end()

and

run_cgi_main()
run_cgi_title()
run_cgi_navigator()
run_cgi_menu()
run_cgi_command_help()
run_cgi_options()

These methods are called from verify_request() and run() in FML::Process::CGI.

CGI process is driven by FML::Process::CGI. run() method calls

$curproc->html_start($args);

call a set of run_cgi_xxx() methods

$curproc->html_end($args);

to control screen.

At 2001/11, FML::Process::CGI::Kernel consists of the following methods: [9]

new()
prepare()
verify_request()
run()
finish()

You do not need edit these files. FML::CGI:: is called at run() method.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 31. fml8 Mail Delivery System

The Difference Between fml4 And fml8

One of purposes of fml8 is unification and abstraction of member list
operations. Mail distribution is based on the following module Mail::Delivery.

Mail::Delivery class provides SMTP, ESMTP and LMTP delivery library interface.
Mail::Delivery is an adapter layer for Mail::Delivery subclass ( SMTP ESMTP
LMTP ).

For example,

    use Mail::Delivery::SMTP;
    my $service = new Mail::Delivery::SMTP;
    if ($service->error) { Log($service->error); return;}

    $service->deliver(
                      {
                          mta             => '127.0.0.1:25',

                          smtp_sender     => 'rudo@nuinui.net',
                          recipient_maps  => $recipient_maps,
                          recipient_limit => 1000,

                          mesage          => $message
                      });

where $message is a Mail::Message object.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Object

This object provies message analyzer. It analyzes a message and build the
following object chains on memory.

header -> body
header -> preamble -> part1 -> part2 -> trailor (multipart)

Mail::Message class provides such data structure described above.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Incoming Queuing

MTA kicks off a fml process. It reads a message from STDIN.

The fml process reads a message once and write it onto the hard disk (write it
into the incoming queue). After the queuing succeeded, the process starts to
analyze a message. For this logic, the original mail is saved before main
processing starts.

If the queuing fails, fml calls exit(EX_TEMPFAIL). In almost cases, exit(75).
If MTA receives this exit code, MTA tries to deliver again later.

Mail::Delivery::Queue class processes the incoming queue. The queus is removed
when the process ends.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

fml Sends Back A Mail Message

Mail::Delivery::Queue class inserts a message to send back into the mail queue.
Later FML::Process::QueueManager handles the real delivery process.

Article delivery processing is a little diffferent but based on queueing by
Mail::Delivery::Queue. If someting error occurs in delivery, another fml
process tries to deliver it later.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Coding In fml8 Sources.

Code is like this to send back a message:

$curproc->reply_message( "you are not a ML member." );

If no recipient specified, the recipient is the sender of the message (From:
address).

To send a file, like this:

$curproc->reply_message( {
        type        => "text/plain; charset=iso-2022-jp",
        path        => "/etc/fml/main.cf",
        filename    => "main.cf",
        disposition => "main.cf example",
    });

$curproc->reply_message( {
        type        => "image/gif",
        path        => "/some/where/logo001.gif",
        filename    => "logo.gif",
        disposition => "attachment",
    });

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail Queue And Delivery System

FML::Process::QueueManager picks up one queue from the queue directory.
Mail::Message parses it. Mail::Delivery processes the real delivery via
FML::Mailer.

Mail::Delivery::Queue
   |
   | ---> queue directory
   V
FML::Process::QueueManager
   |
   | <--- queue directory
   V
FML::Mailer
   |
   V
Mail::Delivery

In manipulating queue, we should lock the target queue by flock(2).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail Queue Directory

The queue directory consists of the following plural directories:

new/
active/
incoming/
deferred/
info/sender/
info/recipients/
info/transport/

info/ stores envelope information. incoming/ holds incoming queue, others hold
outgoing information.

In creating a new outgoing queue file, make a temporary file in new/ once. When
the delivery preparation is ended, move the queue from new/ to active/. Hence
files under active/ is delivery ready.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Lock The Queue

When we need to handle the specific queue file, use lock()/unlock() method for
each $queue_id object. The lock algorithm is based on flock(2) for the file.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Queue Management System

Since 2004 summer, delivery system of fml8 is under queue management system
like MTA. Now fml8 can deliver again messages by itself.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: FML::Mailer Is Apropriate ?

Only FML::Process::QueueManager uses FML::Mailer. So, independent FML::Mailer
class is needed ?

In usual codes, reply_message() handles all message operations. FML::Mailer is
always behind it. But modules other than reply_message() is created in the
future ? Hmm, ...

FML::Mailer should be merged into FML::Process::QueueManager class?

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Delivery TIPS

1. Wwitch forwarding address regarding the mail content.

1. Wwitch forwarding address regarding the mail content.

It is simple if you can prepare different files as necessary. For example,
prepare

recipients.A
recipients.B
recipients.C

for the corresponding conditions A B C. Set up the following hook:

if (condition A matched) {
   $config->set('recipient_maps', "recipients.A");
}
elsif (condition B matched) {
   $config->set('recipient_maps', "recipients.B");
}
elsif (condition C matched) {
   $config->set('recipient_maps', "recipients.C");
}

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 32. Digest Delivery

Run

/usr/local/libexec/fml/digest $ml_name

periodically for digest delivery. It aggregates articles into one MIME/
multipart message and send it to members defined by $digest_recipient_maps.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Digest delivery program is a simple version yet now.                        芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Files Used For Digest Delivery Control

This program uses the following files under $ml_home_dir.

seq-digest
members-digest
recipients-digest

seq-digest holds the last sequence delivered as digest.

members-digest is dummy. recipients-digest is a recipient list.
$digest_recipient_maps is this recipients-digest file only by default.

The argument of $digest_recipient_maps is IO::Adapter, so you can use mysql
here.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Idea: Digest Related Commands

Idea on digest commands (references: fml-devel:313).

Hmm, how about the further extension?

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

makefml command

makefml digest    $ml $address on
makefml digeston  $ml $address

makefml digest    $ml $address off
makefml digestoff $ml $address

(These commands are implemented already).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

admin command mail

admin digest $address on
admin digest $address off

(These commands are implemented already).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

user level command mail ?

digest on
digest off

The confirmation is needed ? Yes, we should need it to unify the fml
fundamental design. We should restrict address manipulation functions as could
as possible.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI

digeston
digestoff

ok?

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

recipes

1. When digest program should run ?
2. Can we change default compression style in digest delivery ?
3. Can we specify parameters in running "makefml add" ?
4. Can we log digest log mesages in the file other than the default log file ?

1. When digest program should run ?

Anytime OK. Please edit crontab.

2. Can we change default compression style in digest delivery ?

No since fml8 supports only MIME/Multipart now.

3. Can we specify parameters in running "makefml add" ?

No since fml8 supports only MIME/Multipart now.

4. Can we log digest log mesages in the file other than the default log file ?

Not configurable. But you can if you us HOOK.

[Example]

$article_digest_prepare_start_hook = q{
        $config->{ log_file } = "/some/where/log.digest";
};

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 33. Language Preference In Processing

Problems Of Language Preference

The simplest model is that we suppose we should return the japanese message
when the ML is configured as for Japanese. This model needs that the language
of a ML is fixed. This ML always returns the error message in Japanese.

However, it is not proper to ignore Accept-Language: header field since some
Japanese people cannot read Japanese on the screen. There may be invalid
Accept-Language: field. There are several problems.

For example, if "Accept-Language: ja" is given, we can recognize the language
is "ja". However, how about the case Japanese send a mail with the body content
"help" (English) ? In that case we cannot determine we should return the reply
in us-ascii or iso-2022-jp. For example, how about the following example ?

[Example]

From: rudo@example.co.jp
Subject: help
mime-version: 1.0
content-type: text/plain; charset=us-ascii

help

We should return the English reply message based on charset information since
this message contains English only, so charset is us-ascii. But in this case we
should return Japanese message since the sender is a Japanese. So we should
return the help message in both English and Japanese if the ML is configured as
Japanese preferrable. If English is preferrable, the reply is English only.

If Accept-Lanaguage: is specified, we prefer it. Even if the ML is English
preferrable (config: language_preference_order = en) and the message with
"Accept-Lanaguage: ja" is given, the ML returns the Japanese help message. fml8
behaves like it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Japanese Preferred ML

language_preference_order variable controls the behaviour. By default, an ML
for Japanese is configured as

language_preference_order       =       ja en

fml8 uses this hint.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Accept-Language: ja, en

fml8 returns the message only in Japanese.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Accept-Language: en

fml8 returns the message only in English.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

no Accept-Language:, Content-Type: charset=iso-2022-jp

fml8 returns the message only in Japanese.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

no Accept-Language:, Content-Type: charset=us-ascii

We cannot determine the language. We should return the message in both English
and Japanese.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

no Accept-Language:, no Content-Type:

We cannot determine the language. We should return the message in both English
and Japanese.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

English preferred ML

By default, a ML for English people is configured as

language_preference_order       =       en

fml8 uses this hints.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Accept-Language: ja, en

fml8 returns the message only in Japanese.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Accept-Language: en

fml8 returns the message only in English.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

no Accept-Language:, Content-Type: charset=iso-2022-jp

fml8 returns the message only in Japanese.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

no Accept-Language:, Content-Type: charset=us-ascii

fml8 returns the message only in English.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

no Accept-Language:, no Content-Type:

fml8 returns the message only in English.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 34. Manipulate Message (Mail Message)

See Mail::Message class for the mail message object handling. Mail::Message
class provides fundamental methods. Several message handling modules e.g.
Mail::Bounce, Mail::Delivery depend on this class.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Class

A mail consists of one header and one body. A multipart mail body consists of
several parts.

The mail delivery module needs not to know the detail of a message. But the
filter system needs to know the structure of the message.

These modules depend Mail::Message class to know the message structure. For
example, Mail::Bounce, Mail::Delivery et.al. use this class.

The usage is as follows:

    my $fh  = new FileHandle $file;
    my $msg = Mail::Message->parse( { fd => $fh } );

    use FML::Mailer;
    my $obj = new FML::Mailer;
    $obj->send( {
        sender    => $sender,
        recipient => $rcpt,
        message   => $msg,
    });

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message::Parse Class

dummy.

The real functions are within Mail::Message class.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message::Compose Class

dummy. This is an adapter for MIME::Lite class. All requests are forwarded to
MIME::Lite class.

See MIME::Lite class for the usage details.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Message Internationalization: The Usage Of reply_message_nl()

For the message internationalization, use reply_message_nl() [10] like this:

$curproc->reply_message_nl('error.already_member',
                           'already member',
                           { _arg_address => $address });

This function uses the message template at /usr/local/share/fml/$fml_version/
message/$language/error/already_member .

$_arg_VARNAME in the message template such as

$_args_address

is expanded by using the value specified as the argument of reply_mesage_nl().

Usual $VARIABLE is also expaned by replacing it with value of config name
space. For example, $ml_name is expanded to ML name defined in config.cf. In
fact $_arg_ prefix is used for lexical scope variables to avoid conflicts
against variables in config.cf.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: How To Send Back Language Dependent Error Mesages

fml needs to send back language dependent error messages. How we should
implement it ?

(Below, just a discussion not implemation in fact.)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

fml4 Case

In the case of fml4, fml4 calls language dependent message converter like this:

   Mesg(*e, KEYWORD, DEFAULT MESSAGE, ARGUMENT);

Mesg() searches the specified keyword in files under /usr/local/fml/messages/
Japanese/ directory. Each file contains messages with keywords to be
substituted properly.

For example, the keyword not_found matches not_found entry in /usr/local/fml/
messages/Japanese/kern file.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

What fml8 Should Do ?

"One file has one keyword" and "one file for one category, so one file contains
plural entries". Hmm, which is better? I don't determine it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

X/Open Portability Guide Issue 4 Version 2 (``XPG4.2'')

If you use XPG (X/Open standard),

catgets(catd, set_id, msg_id, char *s);

function converts the message specified by LOCALE_XXX. [11] For example, the
usage is as follows:

printf(catgets(catd, 30,  4,  "%s: Internal match error.\n"), progname);

This function uses set 30 and entry 4 in the local definition file such as /usr
/pkg/share/nls/ja_JP.EUC/PROGNAME.cat.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

fml8: Design (Temporary ?)

One problem is whether we should use locale or not ? In considering CUI e.g.
makefml, it is better to use locale. For example, prepare

/usr/local/lib/fml/$fml_version/messages/ja_JP.EUC/kern

1: %s not found
2: %s (error number = %d)

.

Instead, one file for one message may be useful. Especially it is easy we can
customize only one message.

To try the latter case, we can prepare a lot of classes such as

FML::Message::ja::KEYWORD

For example, there are 200 or 300 files such as

FML::Message::ja::not_found

.

This methods has the following problems:

 ’ separete files but in contrast more customizable.

 ’ locale friendly? may be no.

Consider an example. In the latter case, the message module will be like this?

sub not_found
{
   my ..  = @_;

   return <<"_EOF_"
$sender is ... something ...
_EOF_
}

Hmm, is it good ???

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 35. Filter

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Filter described here is filter system for articles posted to ML. This      芍
芍filter is implemented as FML::Filter class.                                 芍
芍                                                                            芍
芍Other than article filter, there may be command mail filter. FML::Filter    芍
芍does not provide such function. Instead, FML::Command::Filter class provides芍
芍command mail specific filter e.g. line length limit of one line.            芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview Of Filter System

There are three types of filter system for content check such as for header,
body and mime structure based. Other than the tree cases, we should consider
text/plain and non mime text (text/?) filter. So there may be four types of
filter.

  header

  body
        non-mime
                permit / reject (!MIME of 4.0's content filter)

        mime component filter
                4.0's content filter

        text/plain filter
                        ja, en, ... (language dependent)
                        language independent (e.g. M$ GUID scanner)
                check of the first text/plain part
                syntax check

        external filter (call external virus/spam checker)
                clamav
                spamassassin
                bogofilter

Other than these filters, content_filter using SMTP/LMTP can be needed but not
implemented. If you need content_filter, please use the function of Postfix.

Traffic based filter is also needed but not implemented yet.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Configuration Variables

Each sub filter system is enabled/disabled independently.

use_SERVICE_filter       = yes
SERVICE_filter_functions = function_A function_B

use_function_A           = yes
function_A_rules         = rule_01 urle_02

# Descriptions: how to inform the rejected message
#               when the filter system rejects.
#               We prefer string not mime/multipart to avoid parsing by MUA.
#      History: string in 4.0.
#        Value: SELECT ( multipart string )
#     Examples: string
article_post_restrictions_reject_notice_data_type       =       string


=head2  filter


# Descriptions:
#      History: fml8 rearragena fml4 filter functions and integrates them
#               into one.
#               Roughly speaking, fml8 filter is composed of the following
#                       $USE_DISTRIBUTE_FILTER
#                       $INCOMING_MAIL_SIZE_LIMIT
#                       ADD_CONTENT_HANDLER()
#               functions.
#        Value: YES_OR_NO
#     Examples: yes
use_article_filter      =       yes


# Descriptions:
#      History:
#        Value: MIX (
#                       article_size_filter
#                       article_header_filter
#                       article_non_mime_filter
#                       article_mime_component_filter
#                       article_text_plain_filter
#                       article_spam_filter
#                       article_virus_filter
#               )
#     Examples:
article_filter_functions        =       article_size_filter
                                        article_header_filter
                                        article_non_mime_filter
                                        article_mime_component_filter
                                        article_text_plain_filter
                                        article_spam_filter
                                        article_virus_filter


=head2  size based filter


# Descriptions: use size based filter.
#      History: no
#        Value: YES_OR_NO
#     Examples:
use_article_size_filter =       yes


# Descriptions: size based filter rules.
#               first match.
#               permit post if no rule matched.
#      History:
#        Value: MIX (   check_header_size
#                       check_body_size
#                       permit
#               )
#     Examples:
article_size_filter_rules       =       check_header_size
                                        check_body_size
                                        permit


=head2  header base filter


# Descriptions: use header based filter ?
#      History: disabled by default.
#               "yes" always if $USE_DISTRIBUTE_FILTER is yes.
#        Value: YES_OR_NO
#     Examples:
use_article_header_filter               =       yes


# Descriptions: header filter rules.
#               first match.
#               permit post if no rule matched.
#      History: fml4 has no check_date rule.
#        Value: MIX (
#                       check_message_id
#                       check_date
#                       permit
#               )
#     Examples:
article_header_filter_rules             =       check_message_id
                                                check_date
                                                permit


=head2  filter for non MIME structure


# Descriptions: dummy
#      History: disabled by default.
#               !MIME of 4.0 content filter.
#        Value: YES_OR_NO
#     Examples:
use_article_non_mime_filter             =       yes


# Descriptions: dummy
#      History:
#        Value: MIX ( permit reject_empty_content_type )
#     Examples: permit
article_non_mime_filter_rules           =       permit


# Descriptions: MIME structure based filter
#      History: 4.0 content filter. disabled by default.
#        Value: YES_OR_NO
#     Examples:
use_article_mime_component_filter       =       yes


# Descriptions: file of filter rules
#      History: @CONTENT_HANDLER
#        Value: FILE
#     Examples:
article_mime_component_filter_rules     = $fml_config_dir/mime_component_filter

=head2  filter for text/plain


# Descriptions: use text/plain filter, which is a simple syntax checker.
#      History: 4.0's EnvelopeFilter.
#               half of the following rules applied when
#               $USE_DISTRIBUTE_FILTER is enabled.
#        Value: YES_OR_NO
#     Examples:
use_article_text_plain_filter           =       yes


# Descriptions: filter rules of text/plain filter.
#               first match.
#               permit post if no rule matched.
#      History: See kern/libenvf.pl for more detail.
#               [DISABLED BY DEFAULT]
#
#                       reject_not_iso2022jp_japanese_string
#                               <=> FILTER_ATTR_REJECT_INVALID_JAPANESE
#                       reject_old_fml_command_syntax
#                               <=> FILTER_ATTR_REJECT_COMMAND
#                       reject_japanese_command_syntax
#                               <=> FILTER_ATTR_REJECT_2BYTES_COMMAND
#
#               [ENABLED BY DEFAULT]
#
#                       reject_null_mail_body
#                               <=> FILTER_ATTR_REJECT_NULL_BODY
#                       reject_invalid_fml_command_syntax
#                               <=> FILTER_ATTR_REJECT_INVALID_COMMAND
#                       reject_one_line_message
#                               <=> FILTER_ATTR_REJECT_ONE_LINE_BODY
#                       reject_ms_guid
#                               <=> FILTER_ATTR_REJECT_MS_GUID
#
#         Note: permit by default
#        Value: MIX (
#                       reject_not_iso2022jp_japanese_string
#                       reject_null_mail_body
#                       reject_one_line_message
#                       reject_old_fml_command_syntax
#                       reject_invalid_fml_command_syntax
#                       reject_japanese_command_syntax
#                       reject_ms_guid
#                       permit
#               )
#     Examples:
article_text_plain_filter_rules =       reject_not_iso2022jp_japanese_string
                                        reject_null_mail_body
                                        reject_one_line_message
                                        reject_old_fml_command_syntax
                                        reject_invalid_fml_command_syntax
                                        reject_japanese_command_syntax
                                        reject_ms_guid
                                        permit


=head2  external SPAM filter


# Descriptions: use external spam checker.
#               disabled by default.
#               add flag to header and go through if the message looks a spam.
#      History: none
#        Value: YES_OR_NO
#     Examples: no
use_article_spam_filter         =       no


# Descriptions: action if the message looks a spam.
#      History: none
#        Value: MIX ( reject ignore header_rewrite )
#     Examples: header_rewrite
article_spam_filter_rules       =       header_rewrite


# Descriptions: external spam checker.
#               if plural drivers specified, try them sequentially.
#      History: none
#        Value: MIX ( spamassasin spamc bogofilter )
#     Examples: bogofilter
article_spam_filter_drivers     =       bogofilter


# Descriptions: external virus checker. disabled by default.
#      History: none
#        Value: YES_OR_NO
#     Examples: no
use_article_virus_filter        =       no


# Descriptions: action if virus found.
#      History: none
#        Value: MIX ( reject ignore header_rewrite )
#     Examples: reject
article_virus_filter_rules      =       reject


# Descriptions: external virus checker.
#               if plural drivers specified, try them sequentially.
#      History: none
#        Value: MIX ( clamscan )
#     Examples: clamscan
article_virus_filter_drivers    =       clamscan

=head2  inform the filter rejection


# Descriptions: infor the filter rejection ?
#      History: halfly hard-coded in fml 4.0.
#               notice is always sent to maintainer,
#               but not to sender by default.
#               $FILTER_NOTIFY_REJECTION controlls notice to sender.
#        Value: YES_OR_NO
#     Examples: yes
use_article_filter_reject_notice        =       yes


# Descriptions: recipients to inform
#      History: halfly hard-coded in fml 4.0.
#               notice is always sent to maintainer,
#               but not to sender by default.
#               $FILTER_NOTIFY_REJECTION controlls notice to sender.
#        Value: MIX ( maintainer sender )
#     Examples: maintainer sender
article_filter_reject_notice_recipients =       maintainer
                                                sender


# Descriptions: how fml refer the rejeced message.
#               We prefer string not multipart to avoid parsing of MUA.
#      History: string in fml 4.0.
#        Value: SELECT ( multipart string )
#     Examples: string
article_filter_reject_notice_data_type  =       string


# Descriptions:
#      History:
#        Value: YES_OR_NO
#     Examples:
use_article_spam_filter         =       no


# Descriptions: list up driver names used as spam checker.
#      History: none
#        Value: MIX ( spamassassin spamc bogofilter )
#     Examples: bogofilter
article_spam_filter_functions   =       bogofilter


# Descriptions: exit non-zero status code when spam caught if "-e" specified.
#      History: none
#        Value: COMMAND_LINE_OPTIONS
#     Examples: -e
article_spam_filter_spamassassin_options        =       -e


# Descriptions: spamc optoins. "-c" means check only.
#      History: none
#        Value: COMMAND_LINE_OPTIONS
#     Examples: -c
article_spam_filter_spamc_options               =       -c


# Descriptions: "-e" implies embedded mode.
#      History: none
#        Value: COMMAND_LINE_OPTIONS
#     Examples: -e
article_spam_filter_bogofilter_options          =       -e


# Descriptions:
#      History:
#        Value: YES_OR_NO
#     Examples:
use_article_virus_filter        =       no


# Descriptions: list up driver names used as virus checker.
#      History: none
#        Value: MIX ( virusassassin virusc bogofilter )
#     Examples: bogofilter
article_virus_filter_functions  =       clamav


# Descriptions: --mbox needed for mail files.
#      History: none
#        Value: COMMAND_LINE_OPTIONS
#     Examples: --quiet --mbox
article_virus_filter_clamav_options             =       --quiet --mbox


=head2  filter


# Descriptions:
#      History:
#        Value: YES_OR_NO
#     Examples:
use_command_mail_filter =       yes


# Descriptions:
#      History:
#        Value: MIX ( command_mail_size_filter )
#     Examples:
command_mail_filter_functions   =       command_mail_size_filter


=head2  size based filter


# Descriptions: use size based filter
#      History:
#        Value: YES_OR_NO
#     Examples:
use_command_mail_size_filter    =       yes


# Descriptions: size based filter rules.
#               first match.
#               permit if no rule matched.
#      History:
#        Value: MIX (
#                       check_header_size
#                       check_body_size
#                       check_command_limit
#                       check_line_length_limit
#                       permit
#               )
#     Examples:
command_mail_size_filter_rules  =       check_header_size
                                        check_body_size
                                        check_command_limit
                                        check_line_length_limit
                                        permit


=head2  inform filter rejection


# Descriptions: inform filter rejection ?
#      History: hard-coded.
#        Value: YES_OR_NO
#     Examples: yes
use_command_mail_filter_reject_notice   =       yes


# Descriptions: recipients to inform
#      History: hard-coded.
#        Value: MIX ( maintainer sender )
#     Examples: maintainer sender
command_mail_filter_reject_notice_recipients    =       maintainer
                                                        sender


# Descriptions: how fml refer the rejeced message.
#               We prefer string not multipart to avoid parsing of MUA.
#      History: string in fml 4.0.
#        Value: SELECT ( multipart string )
#     Examples: string
command_mail_filter_reject_notice_data_type     =       string

# Descriptions:
#      History:
#        Value: FILE
#     Examples:
path_bogofilter           = @BOGOFILTER@

# $article_digest_finish_end_hook = q{ 1;};
# $article_digest_finish_start_hook = q{ 1;};
# $article_digest_prepare_end_hook = q{ 1;};
# $article_digest_prepare_start_hook = q{ 1;};
# $article_digest_run_end_hook = q{ 1;};
# $article_digest_run_start_hook = q{ 1;};
# $article_digest_verify_request_end_hook = q{ 1;};
# $article_digest_verify_request_start_hook = q{ 1;};
# $article_filter_end_hook = q{ 1;};
# $article_filter_start_hook = q{ 1;};
# $article_header_rewrite_end_hook = q{ 1;};
# $article_header_rewrite_start_hook = q{ 1;};
# $article_post_finish_end_hook = q{ 1;};
# $article_post_finish_start_hook = q{ 1;};
# $article_post_prepare_end_hook = q{ 1;};
# $article_post_prepare_start_hook = q{ 1;};
# $article_post_run_end_hook = q{ 1;};
# $article_post_run_start_hook = q{ 1;};
# $article_post_verify_request_end_hook = q{ 1;};
# $article_post_verify_request_start_hook = q{ 1;};
# $command_mail_filter_end_hook = q{ 1;};
# $command_mail_filter_start_hook = q{ 1;};
# $command_mail_finish_end_hook = q{ 1;};
# $command_mail_finish_start_hook = q{ 1;};
# $command_mail_prepare_end_hook = q{ 1;};
# $command_mail_prepare_start_hook = q{ 1;};
# $command_mail_run_end_hook = q{ 1;};
# $command_mail_run_start_hook = q{ 1;};
# $command_mail_verify_request_end_hook = q{ 1;};
# $command_mail_verify_request_start_hook = q{ 1;};
# $createonpost_finish_end_hook = q{ 1;};
# $createonpost_finish_start_hook = q{ 1;};
# $createonpost_prepare_end_hook = q{ 1;};
# $createonpost_prepare_start_hook = q{ 1;};
# $createonpost_run_end_hook = q{ 1;};
# $createonpost_run_start_hook = q{ 1;};
# $createonpost_verify_request_end_hook = q{ 1;};
# $createonpost_verify_request_start_hook = q{ 1;};
# $distribute_finish_end_hook = q{ 1;};
# $distribute_finish_start_hook = q{ 1;};
# $distribute_prepare_end_hook = q{ 1;};
# $distribute_prepare_start_hook = q{ 1;};
# $distribute_run_end_hook = q{ 1;};
# $distribute_run_start_hook = q{ 1;};
# $distribute_verify_request_end_hook = q{ 1;};
# $distribute_verify_request_start_hook = q{ 1;};
# $error_mail_analyzer_finish_end_hook = q{ 1;};
# $error_mail_analyzer_finish_start_hook = q{ 1;};
# $error_mail_analyzer_prepare_end_hook = q{ 1;};
# $error_mail_analyzer_prepare_start_hook = q{ 1;};
# $error_mail_analyzer_run_end_hook = q{ 1;};
# $error_mail_analyzer_run_start_hook = q{ 1;};
# $error_mail_analyzer_verify_request_end_hook = q{ 1;};
# $error_mail_analyzer_verify_request_start_hook = q{ 1;};
# $faker_finish_end_hook = q{ 1;};
# $faker_finish_start_hook = q{ 1;};
# $faker_prepare_end_hook = q{ 1;};
# $faker_prepare_start_hook = q{ 1;};
# $faker_run_end_hook = q{ 1;};
# $faker_run_start_hook = q{ 1;};
# $faker_verify_request_end_hook = q{ 1;};
# $faker_verify_request_start_hook = q{ 1;};
# $fetchfml_finish_end_hook = q{ 1;};
# $fetchfml_finish_start_hook = q{ 1;};
# $fetchfml_prepare_end_hook = q{ 1;};
# $fetchfml_prepare_start_hook = q{ 1;};
# $fetchfml_run_end_hook = q{ 1;};
# $fetchfml_run_start_hook = q{ 1;};
# $fetchfml_verify_request_end_hook = q{ 1;};
# $fetchfml_verify_request_start_hook = q{ 1;};
# $fmladdr_finish_end_hook = q{ 1;};
# $fmladdr_finish_start_hook = q{ 1;};
# $fmladdr_prepare_end_hook = q{ 1;};
# $fmladdr_prepare_start_hook = q{ 1;};
# $fmladdr_run_end_hook = q{ 1;};
# $fmladdr_run_start_hook = q{ 1;};
# $fmladdr_verify_request_end_hook = q{ 1;};
# $fmladdr_verify_request_start_hook = q{ 1;};
# $fmlalias_finish_end_hook = q{ 1;};
# $fmlalias_finish_start_hook = q{ 1;};
# $fmlalias_prepare_end_hook = q{ 1;};
# $fmlalias_prepare_start_hook = q{ 1;};
# $fmlalias_run_end_hook = q{ 1;};
# $fmlalias_run_start_hook = q{ 1;};
# $fmlalias_verify_request_end_hook = q{ 1;};
# $fmlalias_verify_request_start_hook = q{ 1;};
# $fmlconf_finish_end_hook = q{ 1;};
# $fmlconf_finish_start_hook = q{ 1;};
# $fmlconf_prepare_end_hook = q{ 1;};
# $fmlconf_prepare_start_hook = q{ 1;};
# $fmlconf_run_end_hook = q{ 1;};
# $fmlconf_run_start_hook = q{ 1;};
# $fmlconf_verify_request_end_hook = q{ 1;};
# $fmlconf_verify_request_start_hook = q{ 1;};
# $fmldoc_finish_end_hook = q{ 1;};
# $fmldoc_finish_start_hook = q{ 1;};
# $fmldoc_prepare_end_hook = q{ 1;};
# $fmldoc_prepare_start_hook = q{ 1;};
# $fmldoc_run_end_hook = q{ 1;};
# $fmldoc_run_start_hook = q{ 1;};
# $fmldoc_verify_request_end_hook = q{ 1;};
# $fmldoc_verify_request_start_hook = q{ 1;};
# $fmlhtmlify_finish_end_hook = q{ 1;};
# $fmlhtmlify_finish_start_hook = q{ 1;};
# $fmlhtmlify_prepare_end_hook = q{ 1;};
# $fmlhtmlify_prepare_start_hook = q{ 1;};
# $fmlhtmlify_run_end_hook = q{ 1;};
# $fmlhtmlify_run_start_hook = q{ 1;};
# $fmlhtmlify_verify_request_end_hook = q{ 1;};
# $fmlhtmlify_verify_request_start_hook = q{ 1;};
# $fmlpgp_finish_end_hook = q{ 1;};
# $fmlpgp_finish_start_hook = q{ 1;};
# $fmlpgp_prepare_end_hook = q{ 1;};
# $fmlpgp_prepare_start_hook = q{ 1;};
# $fmlpgp_run_end_hook = q{ 1;};
# $fmlpgp_run_start_hook = q{ 1;};
# $fmlpgp_verify_request_end_hook = q{ 1;};
# $fmlpgp_verify_request_start_hook = q{ 1;};
# $makefml_finish_end_hook = q{ 1;};
# $makefml_finish_start_hook = q{ 1;};
# $makefml_prepare_end_hook = q{ 1;};
# $makefml_prepare_start_hook = q{ 1;};
# $makefml_run_end_hook = q{ 1;};
# $makefml_run_start_hook = q{ 1;};
# $makefml_verify_request_end_hook = q{ 1;};
# $makefml_verify_request_start_hook = q{ 1;};

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Size Limit

fml8 provides size limit for header and body. Also you can use different size
limit of article or command mail.

Implementation of this filter is easy since the input message is analyzed
already.

=head1  size limit

=head2  default size limit


# Descriptions: header size limit
#      History:
#        Value: NUM
#     Examples: 102400
default_mail_header_size_limit  =       102400


# Descriptions: body size limit
#      History:
#        Value: NUM
#     Examples: 10240000
default_mail_body_size_limit    =       10240000


# Descriptions: the maximum number of cached incoming mails
#      History: $NUM_LOG_MAIL
#        Value: NUM
#     Examples: 128
incoming_mail_cache_size        =       128


# Descriptions: the maximum number of cached outgoing mails
#      History: $NUM_LOG_MAIL
#        Value: NUM
#     Examples: 128
outgoing_mail_cache_size        =       128


# Descriptions: log rotation policy.
#      History: none
#        Value: SELECT ( size interval )
#     Examples: size
log_rotate_policy       =       size


# Descriptions: rotate log if the size is over this size.
#      History: $LOGFILE_NEWSYSLOG_LIMIT value.
#        Value: NUM
#     Examples: 300000 (300K bytes)
log_rotate_size_limit   =       300000


=head2  size limit


# Descriptions: maximum size limit of article header passed from MTA.
#      History:
#        Value: NUM
#     Examples: 102400
incoming_article_header_size_limit      = $default_mail_header_size_limit


# Descriptions: maximum size limit of article body passed from MTA.
#      History:
#        Value: NUM
#     Examples: 10240000
incoming_article_body_size_limit        = $default_mail_body_size_limit


# Descriptions: maximum size limit of deliverd article header.
#               (not yet implemented ;-)
#      History:
#        Value: NUM
#     Examples: 102400
outgoing_article_header_size_limit      = $default_mail_header_size_limit


# Descriptions: maximum size limit of deliverd article body.
#               (not yet implemented ;-)
#        Value: NUM
#     Examples: 10240000
outgoing_article_body_size_limit        = $default_mail_body_size_limit

# Descriptions:
#      History:
#        Value: MIX (
#                       article_size_filter
#                       article_header_filter
#                       article_non_mime_filter
#                       article_mime_component_filter
#                       article_text_plain_filter
#                       article_spam_filter
#                       article_virus_filter
#               )
#     Examples:
article_filter_functions        =       article_size_filter
                                        article_header_filter
                                        article_non_mime_filter
                                        article_mime_component_filter
                                        article_text_plain_filter
                                        article_spam_filter
                                        article_virus_filter


=head2  size based filter


# Descriptions: use size based filter.
#      History: no
#        Value: YES_OR_NO
#     Examples:
use_article_size_filter =       yes


# Descriptions: size based filter rules.
#               first match.
#               permit post if no rule matched.
#      History:
#        Value: MIX (   check_header_size
#                       check_body_size
#                       permit
#               )
#     Examples:
article_size_filter_rules       =       check_header_size
                                        check_body_size
                                        permit


=head2  size limit


# Descriptions: maximum size limit of article header passed from MTA.
#      History:
#        Value: NUM
#     Examples: 102400
incoming_command_mail_header_size_limit = $default_mail_header_size_limit


# Descriptions: maximum size limit of article body passed from MTA.
#      History:
#        Value: NUM
#     Examples: 10240000
incoming_command_mail_body_size_limit   = $default_mail_body_size_limit


# Descriptions: maximum size limit of deliverd article header.
#               (not yet implemented ;-)
#      History:
#        Value: NUM
#     Examples: 102400
outgoing_command_mail_header_size_limit = $default_mail_header_size_limit


# Descriptions: maximum size limit of deliverd article body.
#               (not yet implemented ;-)
#      History:
#        Value: NUM
#     Examples: 10240000
outgoing_command_mail_body_size_limit   = $default_mail_body_size_limit

# Descriptions:
#      History:
#        Value: MIX ( command_mail_size_filter )
#     Examples:
command_mail_filter_functions   =       command_mail_size_filter


=head2  size based filter


# Descriptions: use size based filter
#      History:
#        Value: YES_OR_NO
#     Examples:
use_command_mail_size_filter    =       yes


# Descriptions: size based filter rules.
#               first match.
#               permit if no rule matched.
#      History:
#        Value: MIX (
#                       check_header_size
#                       check_body_size
#                       check_command_limit
#                       check_line_length_limit
#                       permit
#               )
#     Examples:
command_mail_size_filter_rules  =       check_header_size
                                        check_body_size
                                        check_command_limit
                                        check_line_length_limit
                                        permit


# Descriptions: cache size.
#               it implies days if the cache mode is temporal.
#      History: none
#        Value: NUM
#     Examples:
error_mail_analyzer_cache_size          =       14

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Limit For Command Mail

fml8 provides restrictions such as "the number of commands in one command mail
message", "the number of articles in one command mail message", et.al.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mime Component Filter Rules

The format of fml8 mime component filter is space separeted. It is not fml4's
content filter rules.

text/plain      permit
text/html       reject
*               permit

This filter supporse MIME, not including non mime operations. To identify the
whole type (e.g. text/plain) and the part type (e.g. text/plain in multipart/
mixed), we use the following format.

Whole message type      part type      action
----------------------------------------------
text/plain              *               permit
multipart/mixed         text/plain      permit
multipart/mixed         text/html       reject
multipart/mixed         image/*         cutoff
*                       *               permit

the following operations are not implemented but needed ?

text/plain              :uuencoded:     cutoff
text/plain              :size>500k      cutoff

But there are several problems of rule construction.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

First Match Vs Last Match ?

This is a filter but not a router filter. Router filter is first match in
almost cases. But both first match and last match are not suitable for mime
component filter when we consider the meaning of "cutoff" operation.

( NOT TRANSLATED AFTER THIS )

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: Mime Component Filter Needs What Functions ?

( NOT TRANSLATED AFTER THIS )

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 36. Subscribe / Unsubscribe

Which Map Subscribe/Unsubscribe Is Operated To ?

Subscribe/unsubscribe is operated to $primary_*_map.

For example, subscription of remote administrators is operated into both
$primary_admin_member_map and $primary_admin_recipient_map. Unsubscription of
remote administrators is operated into both $primary_admin_member_map and
$primary_admin_recipient_map.

Why use primary_*_map ? If we use admin_member_maps and admin_recipient_maps,
it causes a problem.

Subscription should be operated into one map. So we should operate it into
primary_*_map.

Unsubscription must be same since xxx_maps is composed of different privileged
maps.

For example, $member_maps is as follows. It contais a list of member and a list
of remote administrators.

member_maps             =       $primary_member_map
                                $admin_member_maps

So unsubscription operated for $member_maps may cause unsubscription of remote
administrators. It is wrong logic.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 37. Command (Command Mail, CUI And GUI)

Modules for commands

In fml8, all command modules are shared among command mail, CUI (makefml, fml)
and GUI (CGI). Commands are caregorized into user and administrative ones by
the priviledge.

FML::Command class consists of the following classes:

FML::Command            entrance into FML::Command. command dispatcher.
FML::Command::User      command for general ML users.
FML::Command::Admin     command for remote administrators.

For example, a user command in a command mail kicks off FML::Command firstly,
after some steps, calls FML::Command::User::$command where $command is the
specified command name.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

User Command In Command Mail

FML::Process::Command call FML::Command::User::$command for $command via
FML::Command.

FYI: some module calls FML::Command::Admin::$command for real work even if it
is a user command. For example, FML::Command::Admin::subscribe works for
subscription. In this case, FML::Command::User::subscribe module is a wrapper/
entrance for confirmation before the real subscription process runs.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Admin Command (Administrative Command In Command Mail)

It calles FML::Command::Admin::$command for $command via FML::Command via
FML::Process::Command.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CUI (makefml/fml)

FML::Process::Configure calls FML::Command::Admin::$command via FML::Command.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

GUI (CGI)

FML::Process::CGI calls FML::Command::Admin::$command via FML::Command.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Data Flow Of Command Request Processing

All command processing calls FML::Command::MODE::COMMAND class via FML::Command
class. GUI, CUI and command mail has different pre processing stage.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Command Mail Procssing

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Caution                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍We adopt new frame work after 2004/03/05.                                   芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

Firstly, parse and analyze each line in one message.

An empty line is ignored. The buffer is clean up. After them, check if the
command line is allowed in our context.

For example,

1) if this command matches anonymous command such as "guide" or "subscribe",
call command processor. Allowd list of commands are defined in
$anonymous_command_mail_allowed_commands.

2) if this command matches a normal command which are allowd for a member,
check other conditions based on rules of $command_mail_restrictions. Allowd
list of commands are defined in $user_command_mail_allowed_commands.

Command dispatcher checks the return path dependent on the command and the
syntax, finally executes the command via FML::Command class. This process runs
as normal user priviledge.

"admin" command needs administrator priviledge. So an exception. If "admin"
command is given, process user priviledged "admin" command and execute
FML::Command::User::admin class. [12] In this user command class, checks the
context by $admin_command_mail_restrictions to see that the current context has
remote administrator priveledge. If enough priviledge is satisfied, execute
FML::Command::Admin::COMMAND class via FML::Command again.
FML::Command::Admin::COMMAND needs admin priviledge.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CUI (makefml/fml)

If you use this program, you can have priveledge to login the mailing list
server host and switch user to the user "fml". So please use CUI as you like.
In this case, CUI calls FML::Command::Admin::COMMAND directly.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Command Extension: Command Mail

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍To make a new local command usable for all ML's on this host, you need to   芍
芍put the module you wrote at                                                 芍
芍                                                                            芍
芍/usr/local/lib/fml/site_local/                                              芍
芍                                                                            芍
芍. If the command is allowed only for the specifiec ML (e.g. elena ML), put  芍
芍it at the ML local library path                                             芍
芍                                                                            芍
芍/var/spool/ml/elena/local/lib/                                              芍
芍                                                                            芍
芍where $ml_home_dir = /var/spool/ml/elena.                                   芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Create A New User Command

Consider to make a new local user command "uja". Pick up a command at
FML::Command::User, cut and paste it. Please put it at

/usr/local/lib/fml/site_local/FML/Command/User/uja.pm

To permit the use of it for all ML's, edit site_default_config.cf to add it
into $commands_for_user to permit the user of "uja" command.

user_command_mail_allowed_commands += uja

It you allow the command only for the specific elena ML, edit /var/spool/ml/
elena/config.cf in the same way.

user_command_mail_allowed_commands += uja

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Create A New Admin Command Such As "admin uja"

In the same way described above, hack the module!:) but the module path
differs. Put it at the FML::Command::Admin:: class. For example

/usr/local/lib/fml/site_local/FML/Command/Admin/uja.pm

Edit site_default_config.cf to add it into $user_command_mail_allowed_commands
to permit the use of "admin uja" command.

admin_command_mail_allowed_commands += uja

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CUI Command Extension: makefml/fml

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍To make a new local command usable for all ML's on this host, put the module芍
芍you wrote at                                                                芍
芍                                                                            芍
芍/usr/local/lib/fml/site_local/                                              芍
芍                                                                            芍
芍If you permit the command is used only for the specifiec ML (e.g. elena ML),芍
芍put it at the ML local library path                                         芍
芍                                                                            芍
芍/var/spool/ml/elena/local/lib/                                              芍
芍                                                                            芍
芍.                                                                           芍
芍                                                                            芍
芍In this section, we consider the former case. In both cases, the module     芍
芍codes are same.                                                             芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

Create a module "uja" and put it at

/usr/local/lib/fml/site_local/FML/Command/Admin/uja.pm

You do not need to edit .cf files. The existence of module file enables the
command automatically in the CUI case since the usability of CUI implies
administrator use.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

GUI Command Extension: CGI

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍You need another work to create a menu screen.                              芍
芍                                                                            芍
芍To make a new local command usable for all ML's on this host, put the module芍
芍you wrote at                                                                芍
芍                                                                            芍
芍/usr/local/lib/fml/site_local/                                              芍
芍                                                                            芍
芍If you permit the command is used only for the specifiec ML (e.g. elena ML),芍
芍put it at the ML local library path                                         芍
芍                                                                            芍
芍/var/spool/ml/elena/local/lib/                                              芍
芍                                                                            芍
芍.                                                                           芍
芍                                                                            芍
芍In this section, we consider the former case. In both cases, the module     芍
芍codes are same.                                                             芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

Craete a module "uja" and put it at

/usr/local/lib/fml/site_local/FML/Command/Admin/uja.pm

Edit site_default_config.cf to add it into $admin_cgi_allowed_commands to
permit the use of "uja" command.

admin_cgi_allowed_commands += uja

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

How Differ Coding Style Among fml4 And fml8

Consider localization of "help" command as an example of an fml command, which
sends back help message to the sender.

In the case of fml4, prepare myProcHelpFileSendBack() function and register it
at %LocalProcedure hash to enable it.

%LocalProcedure = (
                    'help',     'myProcHelpFileSendBack',
                );

myProcHelpFileSendBack as follows:

sub myProcHelpFileSendBack
{
    local($proc, *Fld, *e, *misc) = @_;
    my $UJA_FILE = "/some/where/help";
    &SendFile($Envelope{'Addr2Reply:'}, "UJA $ML_FN", $UJA_FILE);
}

In the case of fml8, the main code of help command locates at
FML::Command::User::help class. This class is called by FML::Process::Command
via AUTOLOAD of FML::Command.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍All fml8 commands are implemented at either of FML::Command::User or        芍
芍FML::Command::Admin classes. Both CUI (makefml, fml) and GUI (CGI) uses     芍
芍FML::Command::Admin class. Instead command mail users both classes according芍
芍to the context.                                                             芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言

The real content of help command is process() method in
FML::Command::User::help class.

sub process
{
    my ($self, $curproc, $optargs) = @_;
    my $config    = $curproc->{ config };
    my $charset   = $config->{ report_mail_charset_ja };
    my $help_file = $config->{ help_file };

    # template substitution: kanji code, $varname expansion et. al.
    my $params = {
        src         => $help_file,
        charset_out => $charset,
    };
    my $help_template = $curproc->reply_message_prepare_template( $params );

    if (-f $help_template) {
        $curproc->reply_message( {
            type        => "text/plain; charset=$charset",
            path        => $help_template,
            filename    => "help",
            disposition => "help",
        });
    }
    else {
        croak("no help file ($help_template)\n");
    }
}

where $curproc is an object, which type is hash reference. It corresponds to
%Envelope of fml4. It contains several references to objects for this process.
For exmple, variable $config is an object holding configuration variables.

All variables of fml4 are global. Instead variables of fml8 locates within
configuration space accessed via $config object.

reply_message_prepare_template() converts the message language and expands the
arguments in the message templates.

$curproc->reply_message() inserts the specified mesage string into the message
queue of this process on memory.

The error/log messages queued in on memory are aggergated to one message at the
last of the current process. Mail::Delivery class handles the aggregation and
send it. If needed, the aggregator handles text strings or multipart properly
to build one message.

This mechanism is same as Notify() of fml4 but the last aggregator which
handles all at the last is different.

FYI: commands such as "get" for the file manipulation uses the same message
queuing mechanism. fml4's Notify() sends back immediately. Instead fml8's
mechanism is queuing based always. This fml8 mechanism is different from fml4's
Notify() fundamentally.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 38. Internal Of CGI Process

Method

FML::CGI class should implement the following methods:

html_start()
run_cgi_main()
run_cgi_title()
run_cgi_navigator()
run_cgi_menu()
run_cgi_command_help()
run_cgi_options()
html_end()

where html_start() prints out the header of HTML such as DOCTYPE ... BODY,
html_end() prints /BODY and /HTML. run_XXX methons prints the main content.

run() of $curproc method drives

html_start()
run_cgi_XXX()
html_end()

sequentially. That is, the flow of CGI process is as follows:

new()
prepare()
verify_request()
run()
   html_start()
   run_cgi_XXX()
   html_end()
finish()

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Screen Of CGI And The Method

fml8 CGI script creates the screen:

          header
space     menu        space
bar 1     main        bar 2
space     menu        space
          footer

The bar 1 and 2 are called as navigation bar.

html_start() generates header part(DOCTYPE ... BODY of HTML, NOT HTTP HEADER).
html_end() generates footer part.

Instead, BODY content generates 3 x 3 tables by using methods drived by run_cgi
().

9 sub methods called by run_cgi() generetes the following 9 pieces on the
screen.

nw   north  ne
west center east
sw   south  se

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Screen Of The Current CGI

CGI screen generates 3 x 3 table structure. The following methods generates the
corresponding part of the screen.

run_cgi_main
                        run_cgi_title
run_cgi_navigator       run_cgi_menu    run_cgi_command_help
run_cgi_options

These methods use TABLE to create 3 x 3 matrix. These methods are defined in
hash table. run_cgi() executes them sequentially.

run_cgi_main() print nothing if nothing to do. In almost cases, print just "OK
..." message. If needed, it shows error messages. run_cgi_main() runs before
all other methonds to print out the latest information.

run_cgi_main() is adapter layer defined at FML::CGI::Menu::Admin. Each command
is executed via this layer.

In a few cases such as showing log, listing up addresses, run_cgi_menu() print
out the data.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Screen And Trampolin Mechanism

CGI print engine is moved to FML::Command:: class. However FML::Command:: does
not contains all content of print engine. By object composition, some modules
use methods FML::CGI:: provides. For example, subscribe command internal is as
follows.

FML::CGI::Admin::Main ->
FML::Command::Admin::subscribe ->
FML::CGI::Admin::User ->
SCREEN

The flow goes and back again like trampolin mechanism.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

MISC: Hard Coding Is Mandatory ?

FML::CGI::Admin::User contains the relation between $comname and maps. It is
hard-coded. But it cannnot be avoided.

If we move the relation to configuration space, we need a lot of variables in
it. It is better to use configuration variables for cusotomization, but ...

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI Implementation: Inheritance Among CGI Classes

@ISA of config.cgi follows:

FML::CGI::Menu   FML::Process::CGI::Kernel FML::Process::CGI::Param

In the case of thread.cgi, @ISA is

FML::CGI::Thread FML::Process::CGI::Kernel FML::Process::CGI::Param

.cgi specific codes locate at FML::CGI:: class layer.

FML::Process::CGI::Kernel provides the main part of CGI process and CGI
specific function run_cgi_XXX(). If needed, FML::CGI:: class overloads this
layer. Currently, the following methods in FML::Process::CGI::Kernel are not
used.

run_cgi_log
run_cgi_dummy
run_cgi_date

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI Implementation: config.cgi

@ISA of config.cgi is as follows:

FML::CGI::Menu FML::Process::CGI::Kernel FML::Process::CGI::Param

Let see processing of config.cgi below.

config.cgi process object $curproc is a FML::Process::CGI::Kernel class.

        new()
        prepare()
        verify_request()
        run()
        finish()

is sequentially called from FML::Process::CGI::Kernel class.

run() is important. run() executes the following methods sequentially.

    $curproc->html_start();          (FML::CGI::Menu)
    $curproc->_drive_cgi_by_table(); (FML::Process::CGI::Kernel)
    $curproc->html_end();            (FML::CGI::Menu)

_drive_cgi_by_table() prepares the screen. This function calls the main part of
CGI.

$curproc->_drive_cgi_by_table() calles the following run_XXX() methods.

run_cgi_main              (FML::CGI::Menu)

calls cgi_execute_command (FML::Process::CGI::Kernel) to execute
FML::Command::Admin::$COMMAND via FML::Command class. This is the main part of
command execution via CGI but the screen creation is a role of another part.

For example, consider subscribe an address via CGI. run_cgi_main() executes the
real process of subscription. Instead run_cgi_menu() creates input menu. Former
calls FML::Command::Admin::subscribe::process() method, latter calls
FML::Command::Admin::subscribe::cgi_menu() method.

There are several other run_cgi_XXX() methods. They are optional for screen
creation.

The following run_cgi_XXX() uses the default method.

run_cgi_title             FML::Process::CGI::Kernel (show title)
run_cgi_options           FML::Process::CGI::Kernel (show language selection)

.cgi specific methods are as follows:

run_cgi_navigator         FML::CGI::Menu
run_cgi_help              FML::CGI::Menu
run_cgi_command_help      FML::CGI::Menu
run_cgi_menu              FML::CGI::Menu

run_cgi_menu() executes FML::Command::Admin::COMMAND::cgi_menu() via
cgi_execute_cgi_menu() method.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 39. Directory

Q: How Recursively Sub Directory Can Be Created ?

The structore holding the html-ized article is as follows:

200201/msg\d+.html

One sub-directory by default.

Consider directory listing. "ls" returns 1000 files soon, but 10000 files a
little slowly.

To accelerate listing, we should use sub-directory structure. For example, each
sub-directory holds 1000 files. The structure such as "spool/sub/file" holds 10
^6 ( million ) files and listing of it is fast.

It must be enough to assume that 1 million articles for one ML.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

1. Where directory names are defined ?

1. Where directory names are defined ?

There are default definitiions at /usr/local/etc/fml/defaults/$VERSION/
default_config.cf file. Each config.cf of each ML overloads them. Use fmlconf
command to show the current value.

% fmlconf $ml_name | grep _dir

You can extract values from config object in a hook.

$_xxx_hook = q{
        my $config = $curproc->config();
        my $xxxdir = $config->{ some_where_dir };

        ... snip ...
}

 

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 40. Restrict Input Data

fml8 checks the input by regular expression FML::Restriction class provides.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview: Checks Of Input Data

Restriction For Article Posting

Restrictions for article are ambiguous or too restrictive. In fact
FML::Restriction class does not provide restriction rules for article posting.

Instead FML::Filter filter system checks each line of content.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Restrictions For Command Mail

FML::Process::Command class parses each line of the command mail and checks the
input by regular expressions FML::Restriction::Command provides. If the check
is passed, fml8 calls FML::Command::{User,Admin}::COMMAND at the next step.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

CGI

CGI programs can receive the input from HTTP via only safe_param_XXX() method.

It is expected that safe_param_*() and try_cgi_*() returns the safe value.

These safe_param_XXX() functions checks the input by regular expressions
FML::Restriction::CGI provides (FML::Restriction::CGI inherits
FML::Restriction::Base).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

makefml / fml

CUI runs on the shell. It means he/she who runs CUI has priviledge to log in
the mailing list server. So it does not check the input.

Each module checks the input independetly in that case though no checks by
FML::Restriction at the entrance. For example, "adduser" module checks whether
the input address is valid or not even in the case of CUI. These restrictions
are dependent command specific modules. These are applied even in the case of
CUI.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

FML::Restriction Class

ACLs for the input data and commands are found at FML::Restriction class.

For example, CGI modules use FML::Restriction::CGI class to check if the input
data matches the proper regular expression.

Though FML::Restriction inherits FML::Restriction::Base class, fundamentally
each module should use FML::Restriction as object composition. For example, use
in the following way:

use FML::Restriction::CGI;
$safe = new FML::Restriction::CGI;
my $allowed_regexp = $safe->param_regexp();

if ($value =~ /^$allowed_regexp{$key}$) { ... ok, do something ... ;}

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

How CGI Restricts The Input

CGI checks the input data by using FML::Restriction::CGI class.

The input should be restricted by FML::Restriction class. We should not use
param() method provided by perl's CGI class. Instead use safe_param_xxx()
method always to get value.

The following use may be allowed

for my $dirty_buf (param()) {
   ... check ...
}

but we should not use raw param() call.

param($dirtty_buf)

Instead, use safe_param_key().

for my $key (param()) {
   ... check ...

   if (key eq $key) {
       value = safe_param_key()
   }
}

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: FML::Restriction Is Too Restrictive ?

FML::Restriction class allows a subset of RFC defined expression.

RRC definition is too large. It is too difficult to implement it ;-) We
restrict the expression a little.

FML::Restriction::Command may be more granular but more granular version is not
implemented.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 41. User Authentication

User authentication is provided by methods of FML::Credential class.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: FML::Credential Implementation

Case Sensitive / Case Insensitive

For the user@domain address, we handle user part as case sensitively and domain
as case insensitively. Is it better to prepare the option that handling of user
part is insensitive? (Yes, I think so.)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 42. Hook

Overview

Hooks are required to resolve complicated problems or for compilcated
customization. But there are several problems in implemantation.

One problem is naming convension. $START_HOOK of fml4 is ambiguous. It means
the location in process but not clarify where in which process. So, fml8 hook
naming convension has role and function in it.

$ROLE_FUNCTION_start_hook
$ROLE_FUNCTION_end_hook

There is no common hook among processes. Each process has each hook. In other
words, there is no common hook. You need to define plural hooks for different
processes even if the hook is same content.

$distribute_XXX_start_hook = q{ ... };
$YYY_XXX_start_hook = $distribute_XXX_start_hook;

Coding style of hooks are expected not too restrictive since perl beginners may
code it. fml8 modules have

use strict;

definition but not effective in evalauating hooks. In evaluating a hook, fml8
evaluate it as

no strict;
HOOK CONTENT

to disable the strict check.

Function scope differs among fml4 and fml8. In fml4 all functions are global.
Instead in fml8 functions are methods, which is not called anytime anywhere. We
should provide hooks when we can see $curproc.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Hook Naming Convension

Hook standard form is

ROLE_METHOD_start_hook
ROLE_METHOD_end_hook

The role is "ROLE" part of $use_ROLE_function (e.g. $use_article_post_function)
in configuration variables. This hook directory corresponds to some variables
in configuration. More granular hooks do not match this rule.

For example, the main part of fmlconf command, run() method, provide the
following hooks:

fmlconf_run_start_hook
fmlconf_run_end_hook

The actual code calling hooks as follows:

sub run
{
    my ($curproc, $args) = @_;
    my $config  = $curproc->{ config };

    my $eval = $config->get_hook( 'fmlconf_run_start_hook' );
    if ($eval) {
        eval qq{ $eval; };
        print STDERR $@ if $@;
    }

    $curproc->_fmlconf($args);

    $eval = $config->get_hook( 'fmlconf_run_end_hook' );
    if ($eval) {
        eval qq{ $eval; };
        print STDERR $@ if $@;
    }
}

This case is fundamental. More granular hooks must be needed. The naming
convension may differ from this convension.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Recipes

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 43. Virtual Domain

2003/10: We enhanced fml8 to handle virtual domains as same way as default
domain.

It is difficult to handle virtual domains and the default domain in the same
way.

One proper enhancement is using "user@domain" form for the ML name as an
argument of commands. For example, for a virtual domain, use makefml like this

% makefml newml mlname@virtualdomain

The following two syntaxes are acceptable for the default domain.

% makefml newml mlname@defaultdomain
% makefml newml mlname

Fml treats these properly as could as possible. But fml needs some hints such
as ml home directory information for each domain. You need to prepare /usr/
local/etc/fml/ml_home_prefix file for a hint on mappping between domain and
directory.

This file name is defined as $ml_home_prefix_maps (formerly $virtual_maps) in
main.cf. $virtual_maps is obsolete but effective now for compatibility.

To handle $ml_home_prefix_maps, you can use "makefml newdomain" and "makefml
rmdomain".

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview: virtual domain handling in fml8

It is easy in use. For the first time to use a virtual domain, run "newdomain"
command to add {domain => directory} relation to ml_home_prefix_maps (precisely
primary_ml_home_prefix_map).

After that, you can use "user@domain" form in makefml arguments in handling
virtual domains.

makefml newml   ML@virtualdomain
makefml add     ML@virtualdomain        address
makefml bye     ML@virtualdomain        address

Instead, for the default domain, definitions in ml_home_prefix_maps is not
needed and either of user and user@domain is accpetable.

When you use CGI, you need not to use user@domain syntax since config.cgi knows
the domain name the cgi handles.

http://lists/~fml/cgi-bin/fml/$domain/admin/config.cgi

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍The domain name is hard-coded within config.cgi since makefml injects the   芍
芍domain name in creating config.cgi when "makefml newml" runs. That is,      芍
芍"config.cgi" does not resolve its domain by the URL.                        芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case study: movement ?

*** SORRY, NOT YET WRITTEN ***.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 44. Errormail Analyzer (libexec/error)

fml8 error (/usr/local/libexec/fml/error) program corresponds to mead (/usr/
local/fml/libexec/mead) of fml4

Set "$use_error_mail_analyzer_function = yes" to enable error mail analyzer
function. By default, $use_error_mail_analyzer_function is "yes". That is, fml8
error analyzer is enabled by default but fml4 not. This default behaviour
differs from fml4.

In fact, typical functions of fml8 are enabled by default.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview

In creating a ML, fml8 sets up that $ml-admin address (address error messages
returned to) calls /usr/local/libexec/fml/error.

/usr/local/libexec/fml/error reads a message, analyzes it and creates a chain
of Mail::Message objects on memory. Mail::Bounce class analyzes the detail of
error based on the objects.

Mail::Bounce analylzes which MTA generates the error, which address generates
the error, and the error reason.

The result is cached at $error_mail_analyzer_cache_dir directory.

After some time interval, $error_mail_analyzer_function analyzes the cache data
to determine if an address is effective or not. If some address is determined
to be removed, fml8 removes it from member/recipient list.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Algorithm Of Error Detection

Functions of $error_mail_analyzer_function_select_list are available to
determine error or not. Currently "simple_count histgram" and "histgram"
algorithm are supported. "histgram" is used by default.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Algorithm: simple_count

Count up the number of error messages from an address and determine whether the
address is effective or not.

This logic depends on just the total number of errors. If the traffic of ML is
high, even a little configuration error of recipients caueses removal of the
address soon. This is the main problem of this logic.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Algorithm: histgram

Count up the number of continuous days that error messages returned. If the
number oversomes the threshold, fml8 removes the corresponding address. The
threshold is 14 days by default. That implies continuous errors in 14 days.

This logic assumes that the traffic of an ML is at least one message per day.
In other words, this logic requires the continuous error. So, little
configuration error in the side of recipient has no effect.

fml8 uses this algorithm by default.

Caution: If the traffic of the ML is too little under at least one message per
day, this algorithm does not work.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Cache Of Error Messages Data

Error messages data is cached at $error_mail_analyzer_cache_dir directory.

IO to cache uses Tie::JournaledDir class via FML::Error::Cache.

FML::Error::Cache is a front end (adapter layer) for Tie::JournaledDir class.
All IO should be done via methods provided by FML::Error::Cache.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Forward Error Messages

You can specify the location the error message is forwarded to as
$maintainer_recipient_maps variable.

Undefined by default. Error messages are logged at a log file but not
forwarded.

If enabled, this function forwards the error messages. Just forward it as mime/
multipart which contains one messages/rfc822 part.

FUTURE PLAN: we forward error messages with the analyzed data.

REFERENCE: fml-devel ML 451 around

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 45. IO Interface And Operations

We need IO abstraction layer for porting and extension. See Vnode/VFS interface
(vnode(9)) on IO abstraction.

struct vnode {
                ...
        voff_t          v_size;                 /* size of file */
        int             v_numoutput;            /* num pending writes */
        long            v_writecount;           /* ref count of writers */
                ...
        int             (**v_op)(void *);       /* vnode ops vector */
                ...
        void            *v_data;                /* private data for fs */
};

vop_open(), vop_read(), vop_getattr(), ... are defined over v_op.

**v_op (vnode operation vector) corresponds to a method of object oriented
programming. fml8 provides IO::Adapter class as IO abstraction layer.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Fundamentals Of IO::Adapter

IO::Adapter is most fundamental in fml8 architecture. It is well considered and
implemented. It provides enough primitive methods.

IO::Adapter class abstracts

KEY => VALUE

or

KEY => [ VALUE, VALUE2, VALUE3 ]

type data structure. It is similar to RDBMS theory like this.

KEY1 VALUE1-1 ""     ""
KEY2 VALUE2-1 VALUE2-2 VALUE2-3
KEY3 VALUE3-1 VALUE3-2 VALUE3-3
KEY4 VALUE4-1 VALUE4-2 VALUE4-3

To maintain address list, least fundamental methods of IO::Adapter are

open()
close()

and IO operations to the object

add(KEY, ARGV) (ARGV is class dependent)
delete(KEY)
find(KEY or REGEXP)
get_next_key()

methods. At least, enough to write user management codes.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Methods / Operation Vector

Mentioned above, the fundamental methods of IO::Adapter are as follows:

open()
close()
add(KEY, ARGV) (ARGV = class dependent)
delete(KEY)
find(KEY or REGEXP)
get_next_key()

Other than these methods, new() as a constructor and destructor() are needed.

The constructor is new() methond. For example, use like this;

$obj = new IO::Adapter MAP;

The argument is a map which calls map dependent constructor.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

open()

For a file, call open(2), for RDBMS, connect to the specified SQL server.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

close()

Reverse of open().

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

add(KEY, ARGV)

add KEY (primary key) or KEY and the associated VALUE into the object. ARGV is
class dependent.

We assume an object is composed of a form. It is similar to RDBMS.

The primary key is a mail address. This assumption is correct in the case of
mailing list driver. This is basic data structure.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

delete(KEY)

Delete KEY and the associated VALUE.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

find(KEY) / find(REGEXP)

Search data corresponding with the primary key within an object.

The target is specified as regular expression. Regular expression search is
useful.

The return value is STR of ARRAY_REF (KEY => [ VALUE, VALUE2, VALUE3 ]).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

get_next_key()

Return the list of primary keys like this:

while ($obj->get_next_key()) { ... }

This operation corresponds to FIRST_KEY() and NEXT_KEY() of perl hash.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion

What ARRAY_REF return ?

What expected in using ARRAY_REF as the return value ? A list of PRIMARY KEY ?

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

How To Get All Primary Keys ?

We need to call get_next_keys() again and again to retrieve all keys. It may be
useful to implement special method to return a list of keys but it is not
implemented.

get_primary_keys() ? find('*', { all => 1 }) is used for this purpose. It is of
no use to implement specific method for this.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

HASH_REF As Return Value ?

What expected ?

RETURN VALUE = {
        KEY_1 => VALUE_1,
        KEY_2 => VALUE_2,
}

If a mail address has several attributes, this method is useful. For example,
consider digest delivery:

ADDRESS => {
        internal        =>      3 hours,
        compression     =>      no,
        format          =>      mime/multipart,
};

Abstracted Cache IO layer is this type such as:

FML::Error -> FML::Error::Cache -> Tie::JournaledDir

But ... dependent on Tie::* hmm ..

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 46. Lock

Synchronization among processes uses lock. fml8 provides flock(2) or lockf(2)
based lock mechanism.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview: Lock

After 2003/03, fml8 provides more granular not giant lock.

Each resource defines each lock channel name.

For example, Mail::Delivery related class accesses the member list. It needs
several locks.

Mail::Delivery::SMTP needs lock of member list. FML::Send and
FML::Process::Delivery locks member list access in callling
Mail::Delivery::SMTP.

Instead Mail::Delivery::Queue just sees the mail queue. The function can access
the queue concurrently, also. So this module does not need lock.

Generally speaking, modules using maps require lock. For example, FML/Command/
UserControl.pm and FML/Command/Auth.pm needs write lock, but FML/Credential.pm
needs only read lock.

It is useful if fml8 provides reader writer lock. But it is not implemented.
Currently we attension we use short critical region.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

TODO

Mutex lock in calling *_maps.

READER WRITER LOCK in calling IO::Adapter.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 47. Database Related Modules

Overview

ML driver needs to hold some data on mail. Some data exixsts persistently but
some data with expiration (data is discarded after some interval).

An example of permisistent data is thread database. The latter case, an exapmle
of non persistent data, is message-id cache. The thread database also has
message-id cache in it, which is a sub-set of all message-id set of incoming
messages. We handle these two data separately.

We should handle these data in integrated way.

module A ---| A  |--- persistent database
module B ---| da |
module C ---| pt |
modlue D ---| er |--- cache with expiration

An example of this persistent DB, thread DB, is Mail::Message::DB class.
Examples of cache database are Tie::JournaledDir and FML::Cache::Ring classes.

It is better to use RDBMS for important persistent data such as address list.
This chapter describes persistent data handling only for fml8 internal use.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Persistent Data Use

Handling of persistent data is important. We should consider use of DBMS [13]
for important data.

This chapter describes only fml8 internal use.

fml8 provides two type of cache databases. The type is time saving or space
saving.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Tie::JournaledFile Class

This class appends data into a file. Tie::JournaledFile class provides this
function.

This class is append only. It is similar to LFS (Log Structured File System).

Operation to extract a value is to get the latest (last appended) value. That
is, the last match.

In other words, data cache logs all data to enable back track.

We cannot restrict the maximum size of this cache. This class holds data within
some period without size limitation. We control cache expiration by time.

To get the following structure as a result, you can use
get_all_values_as_hash_ref() method.

key => [
        log1    (line A of file 1),
        log2    (line B of file 2),
        log2    (line C of file 3),
]

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍Search algorithm is either of first match or last match. The last match by  芍
芍default since the last appended data is latest.                             芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

FML::Cache::Ring Class

FML::Cache::Ring holds data with size limit but without time limitation.

It is suitable for debug since the debug data is expected not to eat disk.

This class holds data in files in a directory such as $ml_home_dir/var/db/. For
example, files named as db/1 .. db/100 are created. These files are used
repeatedly.

見芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋角
芍                                  Warning                                   芍
豆芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋貝
芍RingBuffer class is integrated into FML::Cache::Ring class. FML::Cache::Ring芍
芍is derived from File::CacheDir class.                                       芍
谷芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋芋言
足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 48. Database Management System

This chapter describes how to handle persistent data. You should use DBMS
(DataBase Management System) for that data. See  Chapter 47 on the internal use
database.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Overview

Communication with DBMS (database management system) via IO::Adapter class.

This class provides fundamental functions such as insersion and deletion of
data. If more complex operation is needed, the preprocessing module calling
IO::Adapter should handle it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 49. Convert Another ML System To fml8

Implementation: fml4 To fml8

Case 1: /var/spool/ml/elena/ From fml4 To fml8

This conversion does the following steps in fact.

1) install fml8 firstly. In this case, add /var/spool/ml/etc/mail/aliases into
$alias_maps of postfix main.cf. /var/spool/ml/etc/mail/aliases may be empty.

2) run "makefml --force newml elena" to create several files fml8 needs.

3) convert address lists in /var/spool/ml/elena to fml8 style.

3-1) IO::Adapter ignores a line beginning with '^#' as a comment. We should
handle carefully it since "actives" file contains ^# lines as "off" address.

3-2) s=skip (off) options is ignored. It handles as "on".

3-3) m=... (digest) options is ignored. Also, "# address" is "off" in the case
of fml4 but ignored in the case of fml8. We should warn it ?

4) remove the corresponding entry of alias file (/var/spool/ml/etc/fml/aliases)
of fml4 and rebuild .db.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case 2: Convert The Whole /var/spool/ml/ From fml4 To fml8

Apply case 1 for all ML's.

If we can stop all ML's, it is easy to remove /var/spool/ml/etc/fml/aliases of
fml4 firstly and apply case 1 steps. Please stop MTA in migration.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: Use Half And Half Of fml4 And fml8 Softwares.

(X-Sequence: fml-devel 389)

How in half and half case.

For example, site_init.ph or config.ph of fml4 follows

[fml4]

push(@ACTIVE_LIST,"$DIR/recipients") if( -f "$DIR/recipients" ) ;

instead in the case of fml8 site_default_config.cf or config.cf follows:

[fml8]

html_archive_dir = $ml_home_dir/htdocs

VIII. Modules

This part descripbes how to use most important modules.

Table of Contents
50. IO Abstraction Layer (IO::Adapter Class)
51. Mail::Message Module
52. Language Dependent Functions
53. Mail::Message::Encode Class
54. Execise: Create A New Program

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 50. IO Abstraction Layer (IO::Adapter Class)

IO::Adapter Overview

All IO of fml8 should use IO::Adapter class like vfs/vnode framework. For
example, read/write member list, add/remove a user. The usage is like this:

use IO::Adapter;
$obj = new IO::Adapter $map, $map_params;
$obj->open || croak("cannot open $map");
while ($x = $obj->get_next_key()) { ... }
$obj->close;

$map is map:identifier. file: can be omitted. Currently available maps follow:

file:/var/spool/ml/elena/recipients
unix.group:root
nis.group:root
mysql:id
postgresql:id
ldap:id

"file:" map is a normal file (text file). "unix.group:root" map is to read root
entry in /etc/group file. "nis.group:root" map is to read root entry in NIS
(YP). "mysql:id" map implies the use of MySQL. Parameters for MySQL access is
defined in "mysql:id" entry. These paraemeters should be specified before
calling "new IO::Adapter".

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

IO::Adapter Methods

Official methods IO::Adapter provides currently follow:

new()
open()
close()

get_next_key()

add(KEY)
delete(KEY)

getpos()
setpos(NUM)
eof()

touch()

find(REGEXP, $args)

KEY is a primary key to handle database access. In almost cases, the primary
key is a mail address. REGEXP is a regular expression (regexp), this is usually
also a mail address.

Unification of all types of IO needs that we should implement least methods.

The currently implemented methods are selected by test and our operations. If
could, we refer SQL IO more than file IO as an abstraction base model of
IO::Adapter. It introduces difference between fml4 and fml8 but it is mandatory
for further abstraction.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Argument Type Of Methods

The argument needs nothing, STR or ARRAY_REF as the argument and the return
value is STR. get_next_key() is typical as the no argument case. This method is
used to list up the content of files or retrieve the specific address in the
file.

In other case, the return value may be a pair of strings.

KEY_STR => [
     VALUE_STR_1
     VALUE_STR_2
     VALUE_STR_3
]

This is used as the return value to represent ARRAY_REF. For example, "actives"
file of fml4 consists of lines which have plural space separeted entries. So it
can be representated as a type of array.

rudo@nuinui.net s=skip m=xxx.yyy.z # commnet

rudo@nuinui.net => [
        s=skip
        m=xxx.yyy.z
        # comment
]

If retrieval value could be represented as ARRAY_REF, argument of store
operations alsot needs ARRAY_REF.

It is summarized as follows. The argument is one of "nothing", "STR" or
ARRAY_REF. The return value is either of STR of ARRAY_REF (array reference).

argument     return value
---------------------------------------
none      => STR

STR       => STR

none      => [STR, STR, ... ]

STR       => [STR, STR, ... ]

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

File Map

"file:/some/where/file/name" or file name "/some/where/file/name" map is
abstraction of IO to/from a text file. The format of text file is space
separated.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Unixgroup Map

Abstraction of /etc/group. IO is read only.

For example, the access to

wheel:*:0:root,rudo,kenken

in /etc/group is "unixgroup:wheel" map in IO::Adapter.

$obj = new IO::Adapter "unixgroup:wheel";

If you call get_next_key() method for this object, you will get the member of
wheel group sequentially. In other words the wheel group is regarded as the
following file by IO::Adapter.

root
rudo
kenken

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Nis Map

It is same as one of /etc/group but the data is retrieved from NIS/YP.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

MySQL Map

For easy maintenance, it is better to write all mysql configurations in one
file. For example, it is good that we have only to write SQL configurations in
config.cf.

But we identify plural mysql conditions. So, we use the tag [mysql:members] to
declare one region between a tag to the next tag or =cut. It is similar to .ini
file format used on Microsoft OS. We use the tags like this:

config.cf example

member_maps     =       mysql:members

recipient_maps  =       mysql:recipients

[mysql:members]

sql_server      =       localhost
sql_user        =       fml
sql_password    =       uja
sql_database    =       fml
sql_table       =       ml

sql_find        =       select * from ...

                ...

In calling IO::Adapter, use

new IO::Adapter "mysql:members", $config;

where $config is a hash reference holding some paremeters like this:

$config => {
        [mysql:members] => {
                sql_sever => localhost
                        ...
        }
}

FML::Config prepares this $config by reading .cf files. Hence, we usually use
FML::Config object as an argument of IO::Adapter::new() method.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Discussion: How To Write SQL Statements In config.cf ? (fml-devel 204)

How about lexical scope ? The .cf files cannot contain all variables since
lexical scope variables exist. We use &varname syntax for such lexical scope
variables.

For example, use different member and recipient maps. In SQL statements, the
difference is a flag (fml_recipient) in a table. For example, consider the case
that "where" statement has different value but it is determined lexically in
calling MySQL.

member_maps     =       mysql:members

recipient_maps  =       mysql:recipients


[mysql:members]

sql_server      =       localhost
sql_user        =       fml
sql_password    =       uja
sql_database    =       fml
sql_table       =       ml

sql_get_next_key =      select fml_address from $sql_table
                        where fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'

sql_getline     =       select * from $sql_table
                        where fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'

sql_add         =       insert into $sql_table
                        values ('$ml_name', '$ml_domain', '&address', 1, 1)

sql_delete      =       delete from $sql_table
                        where   fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_address = '&address'

sql_find        =       select * from $sql_table
                        where   fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_address like '&regexp'



[mysql:recipients]

sql_server      =       localhost
sql_user        =       fml
sql_password    =       uja
sql_database    =       fml
sql_table       =       ml

sql_get_next_key =      select fml_address from $sql_table
                        where fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_recipient = '1'

sql_getline     =       select * from $sql_table
                        where fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_recipient = '1'

sql_add         =       update ml
                        set recipient = 1
                        where fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_address = '&address'

sql_delete      =       update ml
                        set recipient = 0
                        where fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_address = '&address'


sql_find        =       select * from $sql_table
                        where   fml_ml = '$ml_name'
                                        and
                                fml_domain = '$ml_domain'
                                        and
                                fml_recipient = '1'
                                        and
                                fml_address like '&regexp'

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 51. Mail::Message Module

Mail::Message Overview

Mail::Message object provides several methods to analyze a message and
manipulate messages or parts of a message.

Precisely speaking, this module analyzes the specified mail message and build a
chain of Mail::Message objects.

If not multipart

   header -> body

else if multipart

   header -> preamble -> part1 -> part2 -> ... -> trailor

The link between objects is double link list. Mail::Message class provides
several methods to manipulate these structures.

Each part of this chain is a Mail::Message object. In other words, one mail
message consits of a chain of plural Mail::Message objects in fml8 internal.

For example, "header" is a Mail::Message, which type is text/rfc822-headers and
the data is stored as Mail::Header object. Instead "part1" is a Mail::Message
object, which type is text/plain and the data is reference to the message
string.

References: Mail::Message module manual.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Analyze

parse() analyzes the file. The argument is the file name or the file handle for
the file which should be specified at the argument.

data_type_list() returns information of the chain. The return value is array
reference. For example, MIME/multipart consists of the following objects.

  type[ 1]: text/rfc822-headers       | multipart/mixed
  type[ 2]: multipart/mixed           | multipart/mixed
  type[ 3]: multipart.preamble        | multipart/mixed
  type[ 4]: multipart.delimiter       | multipart/mixed
  type[ 5]: text/plain                | multipart/mixed
  type[ 6]: multipart.delimiter       | multipart/mixed
  type[ 7]: image/gif                 | multipart/mixed
  type[ 8]: multipart.close-delimiter | multipart/mixed
  type[ 9]: text/plain                | multipart/mixed

The center row is the object type, the right one is the mime type of the whole
message (content-type in the mail header).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Create A New Object

new() method is used to create a new object chain.

The following MIME/multipart specific methdos exist.

build_mime_multipart_chain($args)
parse_and_build_mime_multipart_chain($args)
build_mime_header($args)

These methods are used internally now. So these will become private methods in
the furure. Please do not use these methods.

To create a new MIME/mulitpart message, use Mail::Message::Compose. It is
MIME::Lite class in fact :-)

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Header Manipulations

dup_header() method duplicates only header part of a chain and left the body
part as it is. The new chain has different head (header object) but others
begining from the second part is same as the original chain.

              |<--------------- mail body ------------->
header0 ----> part1 -> part2 -> ...
               A
               |
dup_header0 ---

whole_message_header() returns the header object of the chain. The return value
is a Mail::Message object not string.

header_data_type() returns the type of the whole message as string. It tells
whether this message is text or multipart.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Manipulate Messabe Body

Consider the following object chain.

If not multipart

header -> body

else if multipart

header -> preamble -> part1 -> part2 -> ... -> trailor

header_data_type() return the type of the whole type. It is known from
Content-Type: in the whole message header.

whole_message_body() returns body or part1 if multipart.
whole_message_body_head() is same.

find_first_plaintext_message($args) return the first text/plain type object in
the chain. This is useful in filter codes since filter system checks the first
text field in a lot of cases.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Search

find() searches the specified type of Mail::Message in the object chain and
returns the first matched object.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Print

print() method is usual print() function. Usually specify the file descriptor
as an argument.

print() has the concept "mode" to specify CRLF or LF. use set_print_mode(mode)
and reset_print_mode() to set the mode. By default, mode is raw. Specify smtp
mode in using print() within SMTP codes.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Module: Utility Functions

Size

size() returns the size of the object not the whole message size.

is_empty() tells the object data is empty or not.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

General Information

envelope_sender() returns the envelope sender as string.

data_type() returns the type of the object (a part of an object chain) not the
whole message type (Content-Type: in the whole message header).

encoding_mechanism() returns the encoding mechanism of the object (a part of an
object chain) as string. This is not of the whole message encoding mechanism.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message Internals

num_paragraph() returns the number of paragraphs in the data of the object.

nth_paragraph(N) returns N-th paragrah as the string. Caution that N starts
from 1 not 0.

header() returns the header part of a multipart block (header part of an
object). data() returns the data part (data part of an object). Respectively,
alias of message_fields($size) and message_text($size).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

References

 Mail::Message manual

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 52. Language Dependent Functions

fml8 needs language dependent functions internally. Especially, JIS to/from
EUC-JP Janapese code conversion is used anywhere since Japanese mail messages
are written in JIS code but programs are easy to use strings in EUC-JP.

See message internationalization for the language dependence handling in
messages.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Something::Language:: Class

Language dependent module locates at Something::Language.

For example, there are

FML::Language::Japanese::String
Mail::Bounce::Language::Japanese

, The former provides Japanese dependent string functions. The latter provides
Japanese dependent error mail analyzer functions.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 53. Mail::Message::Encode Class

[References] fml-help ML's Count: 02012, 02013, 02016.

[Usage]

        use Mail::Message::Encode;
        my $encode  = new Mail::Message::Encode;
        my $str_euc = $encode->convert( $s, 'euc-jp' );
        my $str_euc = $encode->convert( $s, 'euc-jp', 'iso-2022-jp' );

        my $encode  = new Mail::Message::Encode;
        my $status  = $encode->convert_str_ref( \$s, 'euc-jp' );
        my $status  = $encode->convert_str_ref( \$s, 'euc-jp', 'jis' );

        my $fp = sub { ... };
        $encode->run_in_chcode( $fp, $oout, $in );

  * If you want to use 4.0 compatible functions,
        ues Mail::Message::Encode qw(STR2EUC);
        my $euc_s = STR2EUC( $s );

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Mail::Message::Encode Specification

The main code is within _convert_str_ref() method.

   sub convert # if the argument is STR.
   {
        my ($self, $str, $out_code, $in_code) = @_;
        _convert_str_ref(\$str, $out, $in);

        return $str;
   }


   sub convert_str_ref # if the argument is STR_REF.
   {
        my ($self, $str, $out, $in) = @_;
        _convert_str_ref($str, $out, $in);
   }


   sub _convert_str_ref # if the argument is STR_REF.
   {
        my ($str, $out, $in) = @_;

        # 1. speculate charset
        if $in unspecified -> speculat -> fail -> return 0

        # 2. try conversion
        if ($in resolved or or $in specified in @_) {
                converted to $out charset
                (use jcode, Jcode, use Encode if perl version > 5.8).
                conversion
                return 1 ; # success
        }
        else { # principle of least surprise ?
                nothing todo ;
                return $str;
        }

        return 0 ; # failed
   }

sub base64 {}
sub quoted_printable {}

is implemented for convenience.

$x = $encode->base64($s);

For backward compatibility, STR2XXX() functoins are prepared, too.

   STR2EUC(  $str, [$icode] )
   STR2JIS(  $str, [$icode] )
   STR2SJIS( $str, [$icode] )

These wraps convert_str_ref().

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

run_in_chcode()

In language dependent processes, convert the charset to machine friendly one,
process something and back it to the original chaset each time. This step is
widely used. So it is convenient to prepare a function to pack these steps into
one function.

run_in_chcode example:

sub run_in_chcode
{
   my ($self, $proc, $s, $out_code, $in_code) = @_;

   my $conv_status = convert_str_ref($s, $EUC_JP, $in_code);
   my $proc_status = &$proc($s, @_);
   convert_str_ref($s, $out_code, $EUC_JP) if $conv_status && $out_code;
   return wantarray ? ($conv_status, $proc_status): $conv_status;
}

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Chapter 54. Execise: Create A New Program

Consider creation of a simple scheduler listing tool in the fml8 framework.
Here the program name is "fmlsch" and the cgi is "fmlsch.cgi".

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: Create A fmlsch

Step 1: Add fmlsch Into Installer Configuration

Prepare fml/bin/fmlsch.in, add fmlsch into $bin_programs in fml/etc/
install.cf.in. Run configure to re-create fml/etc/install.cf.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Step 2: Build A Module

Write fml/lib/FML/Demo/Calendar.pm as the main library of fmlsch.

Import other libraries if needed. For fmlsch we import
HTML-CalendarMonthSimple-1.02.tar.gz from CPAN. See cpan/ directory.

Also, install Date-Calc if your system has not it.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Step 3: Modify FML::Process:: Class

FML::Demo::Calendar works mainly. We need to prepare FML::Process class for
fml8 bootloader to call FML::Demo::Calendar.

Firstly, write mandatory methods for fmlsch process in fml/lib/FML/Process/
Calender.pm. You need to create this file.

Secondly, set up boot loader configuration. In the case of fmlsch, the
bootloader loads FML::Process::Calender. Define it in fml/etc/modules. Set up
fml/etc/command_line_options properly. This "command_line_options" file has a
map between a command and the command line options parsed by Getopt::Long().

Create FML::Process::Calender module by copy-and-pasting other FML::Process::
modules :-) Though fmlsch has only to contain least functions, you need to
write FML::Process::Calender::run() method. For undefined methods, fml loads
FML::Process::Kernel functions (inheritence).

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Case Study: fmlsch.cgi

The way of hacking is similar to fmlsch. The differnce is the target to modify,
which is FML::CGI:: class. FML::CGI::Calender is a sub-class of
FML::Process::CGI.

If undefined method is called, fml loads it from FML::Process::CGI or
FML::Process::Kernel. FML::Process::CGI uses CGI.pm to create a http header
et.al. If FML::Process::CGI functions are not enough, FML::CGI class module
should support the lack.

IX. Apendixes

Table of Contents
Glossary (function and variable names convention)
A. Struct curproc (Object In Fact)

Glossary (function and variable names convention)

fml4

    fml4 series

fml8

    fml8 series

fml-devel

    current development version on the way to fml8 in the future.

    same as fml8 now.

curproc

    abbrebiation of "current process".

    Typical abbrebiation form used in UNIX kernel.

PCB

    Process Control Block.

    Typical abbrebiation form used in UNIX kernel.

config

    configuration.

conf

    configuration.

arg / args

    argument / arguments.

fh

    file handle.

dh

    directory handle.

fp

    function pointer == code reference of perl 5.

_foobar

    keyword begining with _ is used for internal function or variable.

    private in other words.

rfoobar

    The first "r" implies "reference". This called hangalian form but we use it
    very little in fml8.

STR

    string.

Japanese character set name

    JIS, SJIS, EUC ...

2

    the same pronounciation as "to".

    STR2EUC (== STRing to EUC)

    use String qw(STR2EUC);
    $euc_string = STR2EUC($string);

4

    the same pronounciation as "for".

command mail

    a mail which message body includes commands for fml.

    By sending the command mail to some address, a user can make fml8 action
    something, such as subscribe, file retrieve, unsubscribe et.al, The address
    is typically $ml-ctl@$domain for $ml@$domain ML.

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

Appendix A. Struct curproc (Object In Fact)

curproc Object

Example of FML::Process::Distribute object.

__parent_args        => HASH {
                        ARGV                 => ARRAY
                        ___shared_memory___  => HASH
                        argv                 => ARRAY
                        cf_list              => ARRAY
                        curproc              => FML::Process::Distribute
                        fml_version
                        main_cf              => HASH
                        module_info          => HASH
                        myname
                        need_ml_name
                        options              => HASH
                        program_fullname
                        program_name
                     }

__print_style        => SCALAR

__start_time         => SCALAR

article              => HASH {
                        body                 => Mail::Message
                        header               => FML::Header
                        message              => Mail::Message
                     }

config               => FML::Config

credential           => FML::Credential

incoming_message     => HASH {
                        body                 => Mail::Message
                        header               => FML::Header
                        message              => Mail::Message
                     }

log_message_queue    => FML::Log::Print::Simple

main_cf              => HASH {
                        _hints               => HASH
                        config_dir
                        debug
                        default_command_line_option_config
                        default_config_cf
                        default_config_dir
                        default_cui_menu
                        default_domain
                        default_gui_menu
                        default_ml_home_prefix
                        default_module_config
                        default_paths_cf
                        domain_default_config
                        domain_default_config_cf
                        exec_prefix
                        executable_prefix
                        fml_group
                        fml_owner
                        fml_version
                        group_writable_config_dir
                        lib_dir
                        libexec_dir
                        local_lib_dir
                        ml_home_prefix_maps
                        prefix
                        prefix_dir
                        primary_ml_home_prefix_map
                        share_dir
                        site_default_config_cf
                        virtual_maps
                     }

pcb                  => FML::PCB

scheduler            => FML::Process::Scheduler

足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足足

PCB Category List

PCB category list, which contains module and function relation.

module     function                                     category
                                                    <-- (get value)
                                                    --> (set value)
--------------------------------------------------------------------------------
State      command_context_get_ml_name              <-- process_command
State      command_context_get_admin_auth           <-- process_command
State      command_context_get_normal_stop          <-- process_command
State      command_context_get_need_confirm         <-- process_command
State      command_context_get_stop_process         <-- process_command
State      command_context_get_admin_password       <-- process_command
State      command_context_get_try_admin_auth_request <-- process_command
State      command_context_set_ml_name              --> process_command
State      command_context_set_admin_auth           --> process_command
State      command_context_set_normal_stop          --> process_command
State      command_context_set_need_confirm         --> process_command
State      command_context_set_stop_process         --> process_command
State      command_context_set_admin_password       --> process_command
State      command_context_set_try_admin_auth_request --> process_command
State      command_context_reset_try_admin_auth_request --> process_command
State      article_get_id                           <-- article_message
State      article_set_id                           --> article_message
Utils      incoming_message_get_cache_file_path     <-- incoming_message
Utils      incoming_message_set_cache_file_path     --> incoming_message
State      filter_state_get_error                   <-- filter_state
State      filter_state_get_tempfail_request        <-- filter_state
State      filter_state_spam_checker_get_error      <-- filter_state
State      filter_state_virus_checker_get_error     <-- filter_state
State      filter_state_set_error                   --> filter_state
State      filter_state_set_tempfail_request        --> filter_state
State      filter_state_spam_checker_set_error      --> filter_state
State      filter_state_virus_checker_set_error     --> filter_state
State      smtp_server_state_get_error              <-- smtp_transaction
State      smtp_server_state_set_error              --> smtp_transaction
Utils      incoming_message_get_current_queue       <-- incoming_smtp_transaction
Utils      incoming_message_set_current_queue       --> incoming_smtp_transaction
Fake       _get_emul_domain                         <-- faker
Fake       _get_emul_ml_list                        <-- faker
Fake       _get_emul_user_list                      <-- faker
Fake       _set_emul_domain                         --> faker
Fake       _set_emul_ml_list                        --> faker
Fake       _set_emul_user_list                      --> faker
Error      finish                                   <-- error
Error      run                                      --> error
Kernel     sysflow_finalize_stderr_channel          <-- stderr
Kernel     sysflow_finalize_stderr_channel          <-- stderr
Kernel     sysflow_reopen_stderr_channel            --> stderr
Kernel     sysflow_reopen_stderr_channel            --> stderr
Kernel     sysflow_finalize_stderr_channel          --> stderr
State      restriction_state_get_deny_reason        <-- check_restrictions
State      restriction_state_set_deny_reason        --> check_restrictions
State      current_process_get_ml_name              <-- current_process
State      current_process_set_ml_name              <-- current_process
Utils      langinfo_get_charset                     <-- charset
Utils      langinfo_get_charset                     <-- charset
Utils      langinfo_set_charset                     --> charset
Utils      langinfo_get_language_hint               <-- language_hint
Utils      langinfo_set_language_hint               --> language_hint
State      error_message_get_count                  <-- reply_message_count
State      error_message_set_count                  <-- reply_message_count
State      error_message_set_count                  --> reply_message_count

Notes

[1]  This corresponds to site_force.ph of fml4.

[2]  file extension corresponds to the format.

[3]  This file corresponds to fml4's site_force.ph.

[4]  This silent behaviour is proper for automatic work. If needed, makefml/fml
     shows log output for computer processing.

[5]  This is default in fml8 (default site_default_config.cf includes this
     configuration).

[6]  If it could be, it is useful to implement another command which fixes the
     article header later. It is not implemented.

[7]  It is similar to the conversion from .mc to .cf in sendmail.

[8]  tie() operation of perl

[9]  Almost cases, FML::Process::Kernel method is overloaded by other modules.
     So, not called directly.

[10] See FML::Process::Kernel module.

[11] "s" is the default message.

[12] admin command is defined in $user_command_mail_allowed_commands as a
     normal user command.

[13] DBMS = DataBase Management System

