Next Previous Contents

4. Overview of ezmlm function

4.1 The basic setup.

In designing ezmlm, Dan J. Bernstein has used the unix philosophy of small component programs with limited and well defined functions. Requests for specific functions can then be met by the addition of new programs.

Thanks to the program execution mechanism Dan built into qmail, it is easy to execute several small programs per delivery in a defined sequence. It is also very easy to add shell scripts for further customization.

4.2 Inventions in ezmlm.

Dan J. Bernstein has written ezmlm in C. It is written for speed and reliability even in the face of power loss and NFS. These features are augmented to a large extent by the ruggedness of the qmail (also by Dan) delivery mechanism (see qmail-command(8)).

ezmlm uses some routines and techniques that still are not frequently seen in many mailing list managers. For example, subscriber E-mail addresses are stored in a hash so that searches require reading only, at most, 2% of the E-mail addresses. ezmlm has a optional message archive, where messages are stored 100 per directory, again to allow more efficient storage and retrieval. Important files are written under a new name and, only when safely written, moved in place, to assure that crashes do not leave the list in an undefined state.

In addition, ezmlm has a number of new inventions. One of these is bounce detection, which generates an automatic warning containing information identifying the messages which have bounced, followed by a probe message to the E-mail addresses for which mail has bounced. If the probe bounces, the address is unsubscribed. Thus, the system won't remove E-mail addresses due to temporary bounces: it takes 12 days after the first bounce before a warning is sent, and another 12 days of bounces after the warning bounce before the probe message is set.

Another Dan J. Bernstein invention is the use of cryptographic cookies based on a timestamp, address, and action. These are used to assure that the user sending a request to subscribe or unsubscribe really controls the target address. It is also used to prevent forgery of warning or probe messages to make it exceedingly difficult to subvert the bounce detection mechanism to unsubscribe another user.

4.3 The qmail delivery mechanism.

See qmail(7), qmail-local(8), qmail-command(8), envelopes(5), and dot-qmail(5). Briefly, qmail having resolved the delivery address delivers it via the .qmail file that most completely matches the address. This file may be a link to another file, as is the case in ezmlm lists. qmail then delivers the message according to successive lines in this file forwarding it to an address, storing it, or piping it to a program. In the latter case, the program is expected to exit 0 leading delivery to proceed to the next line in the .qmail file, or 99 leading to success without delivery to succeeding lines. An exit code of 100 is a permanent error leading to an error message to the SENDER. An exit code of 111 is used for temporary errors, leading to re-delivery until successful or until the queue lifetime of the message has been exceeded.

Delivery granularity is the .qmail file and re-deliveries start at the top. Thus, if the message fails temporarily at a later line, the delivery according to an earlier line will be repeated. Similarly, qmail may have made deliveries successfully according to most of the .qmail file and then fail permanently. The SENDER is informed that the delivery failed, but not about at which point.

ezmlm takes advantage of these basic mechanisms to build a fast, efficient, and very configurable mailing list manager from a set of small independent programs.

4.4 What the different programs do.

See ezmlm(5) and the man pages for the different programs (listed in ezmlm(5)).

4.5 What the different files in the list directory do.

See ezmlm(5).

4.6 The paper path for posts.

Messages to the list are delivered to a .qmail file, usually ~/.qmail-listname which is linked to DIR/editor. Here, the message is first delivered to ezmlm-reject(1) which can reject messages based on subject line contents, MIME content-type, and message body length. It also by default rejects all messages that do not have the list address in the ``To:'' or ``Cc:'' header. This eliminates most bulk spam. If the list is set up for restrictions based on envelope SENDER, the next delivery is to one or more instances of ezmlm-issubn(1). If the messages passed this check, it is usually delivered to ezmlm-send(1) for distribution. If the list is message moderated, it is instead delivered to ezmlm-store(1) which queues the message and sends out a moderation request. ezmlm-gate(1) is used by some other setups. It will for message moderated lists invoke ezmlm-send(1) directly if the message is from a specific set of SENDERs, and in other cases ezmlm-store(1) to send the message out for moderation.

If the list is configured for digests, DIR/editor also contains an ezmlm-tstdig(1) line followed by an ezmlm-get(1) line. If ezmlm-tstdig(1) determines that the criteria are met for digest generation, it exits with an exit code of 0, causing the ezmlm-get(1) line to be executed leading to a digest mailing. Otherwise, ezmlm-tstdig(1) exits 99, resulting in the remainder of the DIR/editor file to be ignored too long. The digest is not related to the message being delivered, but the delivery is used to trigger execution of the relevant programs.

In addition, DIR/editor contains a number of house-keeping functions. These are invocations of ezmlm-warn(1) to send out bounce warnings and and (if the list is moderated) ezmlm-clean(1) to clean the moderation queue of messages that have been ignored. Again, these functions are not related to the specific message delivered, but the delivery itself is used as a convenient ``trigger'' for processing.

4.7 The ezmlm path for moderation messages.

Replies to moderation requests are channeled to DIR/moderator. This file contains an invocation of ezmlm-moderate(1) which invokes ezmlm-send(1) for accepted messages and sends out a rejection notice for rejected messages. It also sends error messages if the message is not found or already accepted/rejected contrary to the moderation message. Thus, if you accept a message already accepted, no error message is sent. ezmlm-clean(1) is also invoked from DIR/moderator for house keeping.

4.8 The ezmlm path for administrative messages.

Administrative requests for both list and digest lists are captured by ~/.qmail-listname-default linked to DIR/manager. Here they are delivered first to ezmlm-get(1) which processed archive retrieval requests, exiting 99 after successful completion which causes the rest of the delivery lines to be ignored. If the request is not for ezmlm-get(1) it rapidly exits 0. This leads to invocation of ezmlm-manage(1) which handles subscriber database functions, help messages, and (if configured) editing of DIR/text/ files. Again, ezmlm-warn(1) lines are included for bounce directory processing.

If configured, an ezmlm-request(1) line is present. This program constructs valid ezmlm requests from command in the subject lines of messages sent to listname-request@host and exits 99. These requests are mailed and will then return to be processed by one of the other programs.

4.9 The ezmlm path for bounces.

Bounces to the list are handled by DIR/bouncer. For the digest list this is DIR/digest/bouncer. The two were combined in previous versions, which is still supported. As this leads to problems with list names ending in ``digest'', the functions are separate with lists set up or edited with ezmlm-idx>=0.32. The bounce is first delivery is to ezmlm-weed(1) which removes delivery delay notification and other junk. The second to ezmlm-return(1) which analyzes valid bounces storing the information in DIR/bounce/ for the list and DIR/digest/bounce/ for the digest. This is the information that ezmlm-warn(1) (invoked from DIR/editor and DIR/manager) uses and processes for automatic bounce handling. ezmlm-return(1) will also unsubscribe a subscriber from whom a probe message has bounced.

4.10 Messages to list-owner and list-digest-owner.

These are processed by DIR/owner and delivered to DIR/mailbox by default. It is better to put the real owner address in this location. This can be done manually, via editing of ezmlmrc(5), or via the ezmlm-make(1) -5 switch. Again, some house-keeping functions are also executed.

4.11 Structure of subscriber databases.

ezmlm subscriber E-mail addresses are stored within DIR/subscribers/ as a hashed set of 53 files. The hash calculated from the address determines which of the 53 files and address is stored in. Thus, to find out if an address is a subscriber, ezmlm has to read at most about 2% of the E-mail addresses. The hash function insures that E-mail addresses are reasonably evenly distributed among the 53 files.

Addresses in the files in DIR/subscribers/ are stored as strings starting with ``T'', followed by the address, followed by a zero byte. This is the same format as taken by qmail-queue(8) on file descriptor 1. Thus, subscriber lists can be directly copied to qmail without any further processing.

With ezmlm-idx>=0.32 you can use an SQL server for the subscriber databases. Please see the SQL section ( ezmlm support for SQL datbases).

4.12 Local case in E-mail addresses.

rfc822 states that the host part of an address is case insensitive, but that case of the local part should be respected and the interpretation of it is the prerogative of the machine where the mailbox exists. Thus, ezmlm preserves the case of the local part, but converts the host part to lower case. ezmlm proper also bases the hash on the case of the local part, so that USER@host and user@host are not (usually) stored in the same file.

Locally, deliveries are most often case insensitive, i.e. mail to USER@host and user@host are delivered to the same mail box. A consequence of this is that many users use E-mail addresses with different case interchangeably. The problem is that when USER@host is subscribed, ezmlm will not find that address in response to an unsubscribe request from user@host. This is even more problematic when E-mail addresses have been added by hand to e.g. moderator lists.

ezmlm-idx>=0.22 changes address storage to make comparisons case insensitive and store E-mail addresses based on the hash of the all lower case address. Case is maintained for the local part. Thus, if USER@host is subscribed, mail is set to USER@host, but user@host is recognized as a subscriber and an unsubscribe request from user@host will remove USER@host from the subscriber list.

To maintain backwards compatibility with old subscriber lists, a second lookup is made for partially upper case E-mail addresses in some cases. This will find USER@host subscribed with a case sensitive hash as well.

If may be useful to move all old mixed case E-mail addresses to the ``new'' positions. Without this, USER@host subscribed with the old system will be able to unsubscribe as USER@host, but not as user@host. After the repositioning, s/he will be successfully able to use any case in an unsubscribe request, e.g. UsEr@host. To do this:

% ezmlm-list DIR | grep -G '[A-Z]' > tmp.tmp
% xargs ezmlm-sub DIR < tmp.tmp

This works, because subscribing an address, even if it already exists, will assure that it is stored with a case insensitive hash. On some systems, the grep ``-G'' switch need/should not be used.

4.13 Testing SENDER to allow posts only from list subscribers.

This mode of operation is automatically set up if you specify the ezmlm-make(1) ``-u'' switch. Since there may be some addresses that should be allowed to post, but are not subscribers of list or list-digest, ezmlm-make(1) sets up an additional address database in DIR/allow/. Use ezmlm-sub(1), ezmlm-unsub(1), and ezmlm-list(1) to manipulate these addresses. If the list is configured for remote administration (see How remote administration works), you can add/remove addresses from the DIR/allow/ database by mailing list-allow-subscribe@listhost and list-allow-unsubscribe@listhost, respectively. Other commands that access subscriber databases work in the same manner.

To similarly restrict archive access, use the ezmlm-make(1) ``-g'' switch.

Since SENDER is under the control of a potential attacker, it is not secure to use tests of SENDER for anything important. However, when replies are always sent to SENDER (such as for archive access), a check of SENDER can prevent the sending of information to E-mail addresses not in the database.

To test sender, use the program ezmlm-issubn(1). It will return 0 (true for the shell, success for qmail deliveries) if SENDER is in at least one of a set of subscriber databases. If not, it will return 99 (false for the shell: success, but skip remainder of .qmail file for qmail deliveries). The basedirs of the subscriber lists (i.e. the directories in which the ``subscriber'' dirs are located) are given as arguments. ezmlm-issubn(1) can take any number of arguments.

Thus, to permit an action if SENDER is a subscriber to the list in any of DIR/, DIR/digest/, or DIR/allow/ and exit silently, put the following into the relevant .qmail file:

|/usr/local/bin/ezmlm/ezmlm-issubn DIR DIR/digest DIR/allow [...]

Restricting your list to posts from your subscribers is as easy as that. If your ezmlm binaries are in a different directory, you may have to modify the ezmlm-issubn(1) path.

ezmlm-issubn(1) has a ``-n'' switch which ``negates/reverses'' the exit code. To do an action if SENDER is NOT a subscriber of any of the lists:

|/usr/local/bin/ezmlm-ezmlm-issubn -n DIR/deny [dir2 ...]

To automatically configure the list with a blacklist address database in DIR/deny, use the ezmlm-make(1) ``-k'' switch. If the list is configured for remote administration (see How remote administration works) and if you are a remote administrator, you can manipulate the ``deny'' database remotely by sending mail to list-deny-subscribe-user=userhost@listhost, etc.

4.14 How cookies work.

Each ezmlm list has it's own ``key'' created by ezmlm-make at setup time. This key is stored in DIR/key, and you can improve it by adding garbage of your own to it. However, changing the key will make all outstanding cookies invalid, so this should be done when the list is established.

When ezmlm receives an action request, such as ``subscribe'', it constructs a cookie as a function of:

The cookie and these items are then assembled into a address that is sent out as the ``Reply-To:'' address in the confirmation request sent to the subscriber. When the subscriber replies, ezmlm first checks if the timestamp is more than 1,000,000 seconds old (approx 11.6 days) and rejects the request if it is. Next, ezmlm recalculates the cookie from the items. If the cookies match, the request is valid and will be completed. Depending on the circumstances, ezmlm generates an error message or a new cookie based on the current time and sends the target a new confirmation request.

Dan has based these cookies on cryptographic functions that make it very unlikely that a change in any part of the cookie or the items will result in a valid combination. Thus, it is virtually impossible to forge a request even for someone who has a number of valid requests to analyze. Since the algorithm ezmlm uses is available, the security rests on the key (and the correctness of the algorithm). Anyone who knows the key for your lists can easily construct valid requests.

As ezmlm-make(1) doesn't use a truly random process to generate the key, it is theoretically possible that someone with sufficient knowledge about your system can guess your key. In practice, this is very unlikely, and the safety of the system is orders of magnitude higher than that of other mechanisms that you may rely on in your list management and mail transport (exclusive of strong encryption, such as PGP).

4.15 How moderator E-mail addresses are stored.

Moderator E-mail addresses are stored just like ezmlm subscriber addresses, in a set of up to 53 files within the subscribers subdirectory of the list's basedir/. For subscribers, the basedir/ is the list directory itself, i.e. DIR/. For moderators, the default is DIR/mod/, which can be overridden by placing a basedir name (starting with a ``/'') in DIR/modsub, DIR/remote, or DIR/modpost for subscription moderation, remote administration, and message moderation, respectively. This permits the use of one moderator database for multiple lists. Note: Subscription moderators and remote administrators are always the same addresses. If both DIR/modsub and DIR/remote contain paths, only the DIR/modsub path is used.

4.16 How subscription moderation works.

Subscription moderation is a simple extension of the ezmlm subscribe mechanism. Once the user has confirmed the subscribe request, a new request is constructed with a different action code. This is sent out to the moderator(s). When a moderator replies with a valid request and cookie combination, the user is subscribed. The user is then also welcomed to the list. Other moderators won't know that the request has already been approved. If other moderators reply to the request, no notification of the duplicate action is sent to the subscriber of the duplicate action. Ezmlm knows that this is a repeat request since the target address is already a subscriber.

The moderators are not informed about the result, unless there was an error (subscribing a target that is already a subscriber is not considered an error). This cuts down the number of messages a moderator receives. Any list moderator knows (or should know) the qmail/ezmlm/unix paradigm: if you're not told otherwise, your command was carried out successfully. This may be counterintuitive to those used to some other operating systems, but in our experience it doesn't take long to get used to the reliability and efficiency of U*ix/qmail/ezmlm.

Subscription moderation is enabled by creating DIR/modsub and adding the subscription moderator to DIR/mod/:

% ezmlm-sub DIR/mod moderator@host
To use an alternative basedir for subscription moderators, place that directory name with a leading ``/'' in DIR/modsub.

4.17 How remote administration works.

The term ``remote administration'' is used to denote the ability of a list administrator by E-mail to add or remove any E-mail address from the subscriber list without the cooperation of the user. Normally, when user@userhost sends a message to list-subscribe-other=otherhost@listhost to subscribe other@otherhost, the confirmation request goes to other@otherhost. However, if remote administration is enabled and user@userhost is a moderator, a confirmation request (with a different action code) is sent back to user@userhost instead. The reply from the administrator is suppressed in the welcome message sent to the new subscriber (other@otherhost). This protects the identity of the remote administrator.

Remote administration is enabled by creating DIR/remote and adding the remote administrator E-mail address(es) to DIR/mod/:

% ezmlm-sub DIR/mod remoteadm@host
To use an alternative basedir for remote administrators, place that directory name with a leading ``/'' in DIR/modsub. Remote administrators and subscription moderators databases always consist of the same E-mail addresses. If both are enabled and one of DIR/modsub and DIR/remote contains an alternative basedir name, this basedir is used for both functions. If both DIR/modsub and DIR/remote contain directory names, the one in DIR/modsub is used for both functions.

Remote administrators can add and remove addresses to the digest list, the ``allow'' list (user aliases for lists using SENDER restrictions on posting and archive access), and if used the ``deny'' list containing addresses that are denied posting rights to the list. The latter is easy to circumvent and intended to block errant mail robots, rather than human users.

4.18 How message moderation works.

ezmlm-store(1), invoked in DIR/editor, receives messages for message moderated lists. If DIR/modpost does not exist, ezmlm-store(1) just calls ezmlm-send(1) and the message is posted to the list as if it were not moderated. If DIR/modpost exists, ezmlm-store(1) places the message in DIR/mod/pending/. It also sends a moderation request to all the moderators. Included with this request is a copy of the message. The ``From:'' and ``Reply-To:'' E-mail addresses contain codes for ``reject'' and ``accept'', together with a unique message name (derived from the message timestamp and process id) and a cookie based on these items. When a moderator replies, ezmlm-moderate(1) is invoked via DIR/moderator. ezmlm-moderate(1) validates the request, and if the request is valid and the message is found in DIR/mod/pending/, it carries out the requested action.

If the request is ``reject'' the post is returned to SENDER with an explanation and an optional moderator comment. If the request is ``accept'' the message is posted to the list via ezmlm-send(1). As the request is processed, a stub for the message is created in DIR/mod/rejected/ or DIR/mod/accepted/ for ``reject'' and ``accept'' requests, respectively.

If a valid reply is received but the message is no longer in DIR/mod/pending/, ezmlm-moderate(1) looks for the corresponding stub in DIR/mod/rejected/ and DIR/mod/accepted/. If the stub is found and the fate of the message was the one dictated by the new request, no further action is taken. If, however, no stub is found or the request and the actual message fate do not match, a notification is sent to the moderator. This scheme was chosen to impart a maximum of information with a minimum of messages. Also, it is the least demoralizing setup for multiple moderator lists, where it is important not to notify subsequent moderators that their work was in vain since the action of the first responding moderator has already resulted in processing of the message.

If a message is not ``rejected'' or ``accepted'' it remains in DIR/mod/pending/ until it times out. Cleanup of both messages and stubs is accomplished by ezmlm-clean(1) which is invoked through both DIR/editor and DIR/moderator for message moderated lists. ezmlm-clean(1) looks at the timestamp used to generate the message/stub name. If it is older than 120 hours (configurable in a range of 24-240 hours, by placing the value in DIR/modtime) it is removed. Unless suppressed with the ezmlm-clean(1) ``-R'' switch, the SENDER of the message is notified.

By default, the E-mail addresses of message moderators are stored as a subscriber list with a basedir of DIR/mod/. This can be changed to any other basedir by placing the name of that directory with a leading ``/'' in DIR/modpost. Although the default basedirs for message moderation and subscription moderation/remote administration are the same, both the functions and actors are entirely independent.

4.19 How messages are stored in the archive.

The structure of the ezmlm list archive is described in the ezmlm(5) manual page. Basically, the message is stored in DIR/archive/n/m, where ``n'' is the message number divided by 100 and ``m'' the remainder (2 digits). The first message is stored in DIR/archive/0/01.

4.20 How the message index works.

The ezmlm-idx(1) adds the option (default) of a message index to ezmlm. The ``From:'' line, the subject, the author's E-mail address and name and the time of receipt are logged for each message as it is received. The subject is ``normalized'' by concatenating split lines and removing reply-indicators such as ``Re:''. A hash of the normalized subject with all white space removed is also stored. The hash for any message within a thread is almost always the same and is used together with the order of receipt to connect a set of messages into a ``thread''. A hash is needed due to the inconsistent handling by MUAs of white space in rfc2047-encoded subject headers.

The message index is stored as DIR/archive/n/index, where ``n'' is the message number mod 100. Thus, the directory DIR/archive/52/ stores messages 5200 through 5299 and the file ``index'' which contains the index for those messages.

The message index can be retrieved with the -index command (see ezmlm-get(1)). You can also retrieve a range of messages, a specific thread, or generate a message digest (see ezmlm-get(1)). Each of these commands can be disabled or restricted as desired by the list owner.

The ezmlm-idx(1) can be used at any time to either reconstruct an existing index or create one an index for an existing message archive. without one.

4.21 How threading works.

A ezmlm thread is just a message number-ordered set of messages with identical ``normalized'' subject entries. This is a very reliable method for threading messages. It does not rely on any variably present ``In-Reply-To:'' or ``References:'' headers. If the subject changes, the continuation becomes a separate thread very close to the original thread in a digest. ezmlm uses this mechanism to return message sets threaded and with a thread and author index, unless specifically told not to do so with the ``n'' format specifier. Naturally, lists set up without a message index (using the ezmlm-make ``-I'' switch) do not maintain thread information.

4.22 How digests work.

A ``digest'' is just an ordered collection of messages from a list, usually sent out regularly depending on the time and traffic volume since the last digest. Digest subscribers thus can read messages as ``threads'' once daily, rather than receiving a constant trickle of messages.

As a major change in ezmlm-idx-0.30, the digest is no longer a totally separate ezmlm-list, but a part of the main list. This has security advantages, makes setup and administration easier, saves space, and allows a consistent way for subscribers of both ``list'' and ``list-digest'' to retrieve missed messages from a single archive.

The digest of the list ``list'' is always called ``list-digest''. To set up a list with a digest, simply use the ezmlm-make(1) ``-d'' switch. You subscribe to and unsubscribe from a digest the same way as for the main list, except that the request is sent to e.g. list-digest-subscribe@host rather than to list-subscribe@host.

Any option such as remote admin or subscription moderation that is active for the list applies also to the digest list. Any restrictions in posts or archive retrieval set up for the list, automatically accept both subscribers of the main list and of the digest list.

The changes in ezmlm-idx>=0.30 allow all programs to service both list and list-digest functions. All digest-specific files are stored in DIR/digest/. Digest list subscriber addresses in DIR/digest/subscribers/ and digest list bounce information in DIR/digest/bounce/. Text files are shared between list and digest. To get the local part of the list or list-digest name in a context sensitive manner, use ``<#l#>'' (lower case ``L'') in the text file.

In order to generate digest, the list needs to be archived and indexed (both default). You can retrieve sets of messages from the message archive. Such sets are always returned to the SENDER of the request. ``Digests'' are a special form of such a set/request. First, there are no restrictions on the number of messages that can be in a digest (which is balanced by the requirement for a ``digest code'' that needs to be specified in order to create a digest based on a mailed request). Second, special files (DIR/digissue and DIR/dignum) keep track of the digest issue and the message number, amount, and time when the last digest was created. Thus, the system is adapted to make it easy to create the regular collections of messages commonly referred to as ``digests''.

Digest can be generated in several different ways:

Command line

ezmlm-get can be invoked on the command line, or via a script from e.g. crond(8):

        % ezmlm-get DIR
If for some reason the digest should be disseminated via a separate list, the digest can be redirected to a ``target address'' with the ezmlm-get(1) ``-t'' switch. This may be useful if a non-standard digest list name is required. In this case, the list disseminating the digest must be set up as a sublist of the main list (see How sublists work).

from DIR/editor

This is the default and does not require and additional setup. It works well with most lists. The only possible advantage is for very low traffic lists and for lists where it is important that a digest be sent out at a specific time (as DIR/editor digests are triggered only when messages are received).

In DIR/editor, ezmlm-get(1) needs to be combined with ezmlm-tstdig(1) so that digests are generated only if certain criteria are met (in this case, more than 30 messages, 64 kbytes of message body or 48 hours since the latest digest). Add these lines after the ezmlm-send line in DIR/editor:

        |/usr/local/bin/ezmlm/ezmlm-tstdig -t48 -m30 -k64 DIR || exit 99
        |/usr/local/bin/ezmlm/ezmlm-get diglist@host DIR || exit 0
To set this up automatically when you create the list:
        % ezmlm-make -d DIR dot local host [code]
Again, the ezmlm-get(1) ``-t'' switch can be used for non-standard arrangements to redirect the digest. The ezmlm-make(1) ``-4'' switch can be used to specify alternative ezmlm-tstdig(1) parameters.
from DIR/manager

This is useful only if you want digests at specific times, and you do not have access to crond(8) on the list host. ezmlm-get(1) is in it's normal place in DIR/manager before ezmlm-manage(1), but a digest code is specified in the ezmlm-get(1) command line. To trigger digests requires a regular trigger messages generated from e.g. crond(8) (see below), but this can be done from _any_ host, not only the list host. ezmlm-make(1) sets up ezmlm-get(1) this way if a digest ``code'' is given as the 5th ezmlm-make(1) command line argument. However, you need to set up the trigger messages separately (see below):

        % ezmlm-make DIR dot local host code
To also test for message volume with this setup, generate trigger messages with the granularity you'd like, and add a ezmlm-tstdig(1) line to DIR/manager. E.g., use a trigger message every 3 hours and the following ezmlm-tstdig(1) line before ezmlm-get(1):
        |/usr/local/bin/ezmlm/ezmlm-tstdig -t24 -m30 -k64 DIR || exit 99
In general, a cron-triggered digest is preferred for very large lists and for lists with very low traffic. Again, the ezmlm-get(1) ``-t'' switch can be used for non-standard arrangements to redirect the digest. For most lists, the digesting from DIR/editor works very well, and does not require any extra setup work.
Combination setups

The default setup in the ezmlmrc(5) file included in the distribution is the DIR/editor triggered setup described above. If you in addition use ezmlm-cron(1) or crond(8) directly to generate trigger messages to list-dig.code@host, you can get regular digests (via the trigger messages and DIR/manager), with extra digest sent when traffic is unusually high (via the ezmlm-tstdig/ezmlm-get limits set in DIR/editor). This works best when the time argument on the ezmlm-tstdig(1) command line is the same as the trigger message interval, and the other ezmlm-tstdig(1) parameters are set so that they are only rarely exceeded within the normal digest interval.

4.23 How ezmlm-tstdig works.

ezmlm-tstdig(1) looks at DIR/num and DIR/dignum to determine how many messages and how much traffic (in terms of bytes of message body) has arrived to the list since the latest digest. It also determines how much time has passed since the last digest was generated. If any of the criteria specified by command line switches exists, ezmlm-tstdig(1) exits 0, causing the invocation of the next line in the .qmail file. If not, ezmlm-tstdig(1) exits 99 causing qmail to skip the rest of the .qmail file. ezmlm-tstdig(1) looks at LOCAL to determine if it is invoked in the command line, in DIR/editor, or in DIR/manager. In the latter two cases, ezmlm-tstdig(1) verifies that the list local address is correct. If invoked in DIR/manager, ezmlm-tstdig(1) exits 0 for all action requests except list-dig, so that is does not interfere with the normal functions of ezmlm-get(1) and ezmlm-manage(1). ezmlm-tstdig(1) uses DIR/tstdig as a flag to avoid problems caused by starting the program when another copy is already running.

ezmlm-make(1) automatically configures ezmlm-tstdig(1) with the parameters ``-t48 -m30 -k64'', which can be overridden with the ``-3'' switch.

4.24 How sublists work.

ezmlm uses the concept of sublists. Sublists are regular ezmlm lists, except that they only accept messages from their parent list, which is placed in the file DIR/sublist.

sublists are used to split the load of a large mailing list among several hosts. All you need to do to set up a local sublist of e.g. the list is to create a ezmlm list, and put ``'' into DIR/sublist of you list, and subscribe the sublist to the main qmail list. Now anyone can subscribe to your local list which handles its own bounces, subscribe requests, etc. The load on the main list is only the single message to your local list.

Sublists will not add their own mailing list header and they will not add a subject prefix. Normally, sublists will use their own message number, rather than that used by the main list. With ezmlm-idx>=0.23, sublists that are not archived and not indexed, will instead use the main list message number. This way, bounce messages from the sublist can refer the subscriber to the main list archive. This is not done for indexed/archived sublists for security reasons (an attacker could overwrite messages in the sublist archive).

With ezmlm-idx>=0.31, there is support for using ezmlm as a sublist of a mailing list run by another mailing list manager. To set this up, set up a normal ezmlm sublist, then edit DIR/editor so that the ezmlm-send line contains the command line option ``-h X-Listprocessor-Version:'' (before DIR). As the header text, you need to use a header that the main list manager adds to messages. Now your sublist will accept only messages from the main list requiring that they come from that list and contain the header specified.

ezmlm-idx>=0.313 also has added protection against the malicious subscription of the ezmlm list to mailing lists run by other list managers. If the ezmlm-reject(1) line in DIR/editor has ``-h'' and ``DIR'' on it, ezmlm-reject(1) will read DIR/headerreject and reject messages that have any header specified in that file. See the ezmlm-reject(1) man page for suitable headers.

4.25 How sublisting can be made transparent to the user.

Often you create a local sublist of a list that you do not control. Local users know to subscribe to your local list. However, occasionally, you want to run your own list as a main list and a series of sublists per geographic site, or split onto several hosts if the list is too large to be handled by a single computer. You may also want to split the load of a ``well known'' list host that is getting overwhelmed with traffic. ezmlm supports sublists, but here the fact that the user has to interact with the correct sublist is a problem. What if the user doesn't remember which sublist s/he is subscribed to? What if you change the name of a sublist host or move a sublist to a different host?

ezmlm-idx&-0.32 adds ezmlm-split(1), which allows sublisting transparent to the user. This program is invoked before ezmlm-manage(1) in DIR/manager. If it detects a subscribe or unsubscribe command, it will forward the command to the appropriate sublist based on a ``split file'' DIR/split. This file contains entries, one per line, of the format:

For each address, a hash in the range 0-52 is calculated. The ``domain'' is the last two parts of the host name, reversed. Thus, for it would be ``edu.wustl''. The domain is considered to match if the characters in the split file match. It is advisable to use only the last part of the domain for compatibility with the SQL version version (see section ezmlm support for SQL datbases).

Thus, any address *@*.domain with a hash between ``lo'' and ``hi'' inclusive would match the first line and be forwarded to sublistname@sublisthost. *@*.edu (independent of hash) would match the second line and be forwarded to othersub@otherhost. Of remaining requests, a request for any target address with a hash between 1 and 26 would be forwarded to the sublist third@thirdhost. Remaining requests would be passed on to the local list.

The domain is useful for ``geographic'' splitting, and the hash for load splitting (within a domain). The user interacts only with the main list, and does not need to know from which sublist s/he is serviced.

ezmlm-idx sublists use the message number of the main list message if they are not indexed. This allows sublists to in bounce messages refer the subscriber to the main list archive. Use ezmlm-make(1) in conjunction with ezmlmsubrc(5) to set up the sublists. See man pages for further details.

Since the addresses are stored locally, the system is very fast and robust, but it is difficult to add new sublists. ezmlm-split(1) -D supports parsing addresses on stdin and splitting them to stdout (see man page). Thus, if you divide the domain of some sublist(s) onto a net set of sublists, you can use ezmlm-list(1) to collect the addresses, ezmlm-split -D with the new split file to split them, then after clearing the local subscriber databases use ezmlm-sub(1) to add the correct addresses to each new sublist. The section on SQL support describes an alternative way of managing sublists (see section ezmlm support for SQL datbases).

4.26 How to service commands in the subject line.

Rfc2142 (standards track) says that for each mailing list list@host, there MUST be an administrative address list-request@host. This is not the default for ezmlm, but can be added with ezmlm-make(1) ``-q'', which adds a ezmlm-request(1) line before the ezmlm-manage(1) line in DIR/manager. This address is used to manage commands in the ``Subject:'' line, by translating them into appropriate ezmlm command messages.

When migrating from other mailing list managers which use this method to issue list commands, configuring ezmlm to respond to such commands may be useful. In addition, some software manufacturers sell MUAs and mail gateways that are unable to correctly transport rfc822-compliant Internet mail with certain characters in the local part of the address.

ezmlm-request(1) services the list-request@host address per rfc2142 (standards track). It is usually invoked in DIR/manager before ezmlm-get(1) and ezmlm-manage(1). It ignores all requests that are not for the list-request address. For requests to the list-request@host address, ezmlm-request(1) parses the ``Subject:'' line. If a ezmlm command address starting with the contents of DIR/outlocal (e.g. list-get45) is on the command line, ezmlm-request(1) generates the corresponding full ezmlm request message. If the subject does not start with the contents of DIR/outlocal, ezmlm-request(1) prefixes the line with the contents of DIR/outlocal, thereby building a complete ezmlm command. If a host name is specified, it must match the contents of DIR/outhost, i.e. ezmlm-request(1) in this function will only generate command messages for the local list.

Thus, a subject of ``subscribe'' to list-request@host will be auto-magically rewritten as a message to list-subscribe-userlocal=userhost@host. Similarly, any ezmlm command or ``Reply-To:'' address can be pasted into the subject field and sent to list-request@host. ezmlm-request(1) does not validate the command name, but invalid commands result in a ``help'' message in reply via ezmlm-manage(1). This allows ezmlm-request(1) to also service custom commands, like list-faq@host that you may have created for your list.

If the ``Subject:'' is empty or does not start with a letter, ezmlm-request(1) will attempt to interpret the first message body line that starts with a letter in the first position.

When ezmlm-request(1) has successfully processed a ''request'' command, it exits 99 to skip the rest of DIR/manager.

To set up a list to include ezmlm-request processing, use the ezmlm-make(1) ``-q'' switch. The default is to not do this.

4.27 How to support alternative command names.

ezmlm-idx>=0.23 allows alternate names for all user commands. This can be used to e.g. make a message to list-remove@host to result in an ``unsubscribe'' action. This may help migration from other mailing list managers and in non-English environments. The use of aliases allows ezmlm to respond to new command names, while always responding correctly to the standard commands. If ezmlm-request(1) is used it will automatically be able to deal with any commands you set up for the list, within ezmlm or as separate programs. See Multiple language support on how to set up command aliases.

4.28 How to add your own commands.

The qmail/ezmlm mechanism makes it very easy to add your own commands. You can add them to DIR/manager, but this requires great care in terms of ordering and exit codes. Easier is to set them up separately with a .qmail-list-command file.

Let's assume you want to allow anyone to determine how many subscribers are subscribed to your list with the command list-count@host. Just create a program to do the work:

        DTLINE='Delivered-To: list-count@host processor'
        grep "$DTLINE" > /dev/null &&
                { echo "This message is looping"; exit 100; }
          echo "$DTLINE"
          cat <<EOF
          From: list-help@host
          To: $SENDER
          Subject: list@host subscriber count

          Current number of subscribers:
          ezmlm-list ~/DIR | wc -l
        } | /var/qmail/qmail-inject -f list-return- "$SENDER"
        exit 0
Then, create DIR/count containing ``|/path/program'' and then do ``ln -sf DIR/count ~/.qmail-list-count''. Now, the command will pass the message to ``program''. The first thing ``program'' looks for is its delivered-to line to detect looping. If not found, it goes on to print this header, followed by some minimal text and the subscriber number. This can of course be made prettier with ezmlm-list error checking, and maybe in perl, but shows how easy it is to extend ezmlm. All thanks to the DJB/qmail delivery mechanism.

4.29 How remote administrators can retrieve a subscriber list

A user with shell access can always manipulate subscriber lists with ezmlm-sub(1), ezmlm-unsub(1), and ezmlm-list(1) for the lists s/he owns.

Sometimes a remote administrator requires a list of subscriber E-mail addresses. At the same time, the list should be kept out of the hands of spammers and all unauthorized entities. By default, ezmlm does not allow remote subscriber list retrieval. You can enable the ``-list'' command for remote retrieval of a subscriber list by using the ezmlm-make(1) ``-l'' switch or by adding the ``-l'' switch to the ezmlm-manage(1) line in DIR/manager. With this switch, ezmlm will permit retrieval of a subscriber list, but only to remote administrators. Subscribers cannot get the list membership, and any outsider would have to be able to read a remote administrator's mail to get the list. Note: This option is not functional unless the list is configured for remote administration, i.e. the ezmlm-make(1) ``-rl'' switches need to both be used.

The list returned is unsorted for efficiency reasons. You can easily sort it or use your mail reader to find a specific entry. The number of subscribers is shown at the bottom of the list. To get the number of subscribers from the command line, use:

        % ezmlm-list DIR | wc -l

4.30 How remote administrators can search the subscription log

The same conditions that enable remote administrators to retrieve a subscriber list (see subscriber_list ) also enable the remote admin to retrieve the subscription log, i.e. the log of changes made to the subscriber list. The command is list-log@host. The entries are of the form ``date timestamp dir event address comment''. ``dir'' is ``+'' for addition of an address, ``-'' for removal, ``event'' is empty for normal (un)subscribe ``manual'' for changes made with ezmlm-(un)sub, and ``probe'' for removals via bounce handling. ``address'' is the subscription address, and ``comment'' is empty or the subscribers ``From:'' line. The log can be used to look at recent additions/removals and to try to track down a subscriber address from e.g. the name on the ``From:'' line. The log is written on a best-effort basis. In contrast to the subscriber database, entries in the log may be lost at a system crash.

The remote administrator can do a case-insensitive search through the log with the command, where ``xxx'' is any sequence of letters/numbers that must occur on a line in order for that line to be included in the reply. A ``_'' is a wild card and should be used for special characters as well. Thus, to search for any entry with a host name of host* mail list-log._host and to find entries for ``Keith John...'' etc, use list-log.keith_john.

For SQL-enabled lists, this command searches the ``list_slog'' table.

4.31 How text file editing works.

If a list is set up with the ezmlm-make(1) ``-n'' switch, or if the ``-e'' switch is added to the ezmlm-manage(1) line in DIR/manager, ezmlm allows remote administrators to edit the text files that make up most of the ezmlm responses. Of course, this will work only if remote administration is enabled for the list. Replies are sent only if the target address is a remote administrator. Thus, ezmlm does not rely on SENDER (easily forged) but on the notion that only the recipient receives the message. This is a reasonable assumption for remote administrators that receive mail on the local system.

With this switch, ezmlm replies to the -edit command with a list of the files in DIR/text/. Only files where editing seems reasonable are included in the list. The remote administrator can edit any file in DIR/text/ by sending e-mail containing the new text to -edit.file where ``file'' is the name of the file replaced (edited). The file must exist and the name consist of only lower case letters and '-'. Any '-' (hyphen) must be substituted by a '_' (underscore). For remote administrator convenience, the substitution has been made in the list of files sent in reply to the -edit command.

In reply to this command, ezmlm sends a message with the file and editing instructions. A ``cookie'' based on the date, file name, and contents of the file is added to the ``Reply-To:'' address. The cookie becomes invalid as soon as the file has been changed, or after 27 hours, whichever is shorter. Also, the cookie cannot be used to edit any other file, even if the other file has exactly the same contents. If you sent an edit request, and decide not to edit the file, you can simply delete the message.

To apply standard changes to all your text files it is easier to edit ~/.ezmlmrc. To reset the list's text files back to their default contents (as specified by ezmlmrc(5)), use the ezmlm-make(1) ``-e'' switch together with any other switches used to set up the list.

4.32 How subject line prefixes work.

First of all, it is against a number of RFCs to modify the ``Subject:'' header of messages. However, it is frequently requested by users who have seen it on other list managers. Second, it is many times worse to have a prefix that changes from message to message, such as a prefix with the message number. However, a number of lists, especially in Japan, use this feature and in its absence these lists might be unable to take advantage of ezmlm. Thus, while we recommend against using a prefix, ezmlm-idx supports it.

To add a subject prefix, just put the text into DIR/prefix. The only format that makes any sense is ``list:'' or ``(list)'' or such.

The message number prefix is activated by putting e.g. ``(list-#)'' into DIR/prefix. ``#'' is replaced by the message number. ezmlm refuses to make more drastic changes in the subject of a message. As a consequence, the message number prefix is added only when the subject does not already contain a prefix. Thus, replies will have the message number of the original message. Doing anything else and still supporting rfc2047-encoded subjects in the archive threading (much more important) would require decoding the subject, removing/editing the prefix, and re-encoding the subject. This is far too invasive.

The entire thread can always be retrieved by sending a message to list-thread-x where ``x'' is the message number in the prefix of any message in the thread.

4.33 How bounces are handled.

Ezmlm messages are sent with an envelope sender (``Return-Path'') that directs bounces to DIR/bouncer and also via ``VERP'' contain information about the intended recipient. Thus, programs run from DIR/bouncer know the subscriber for whom the message bounced. ezmlm-weed(1) is used to weed out delivery delay notification and other junk. For others ezmlm-return(1) decides if the address is a subscriber. If so, it saves the first bounce message and a list of bounced-message numbers. ezmlm-warn(1) executed from e.g. DIR/editor goes through these bounce files. If it finds any that are older than 1,000,000 seconds (about 11.6 days) it sends a warning message to the subscriber. If this warning message bounces, ezmlm-return(1) sets up a "warning flag" for the subscriber. If ezmlm-warn(1) finds a warning flag older than 11.6 days, it sends a "probe" to the subscriber. If ezmlm-return(1) receives a bounced probe, the subscriber is automatically unsubscribed.

The ezmlm-warn(1) ``-t'' switch can be used to change the time-out (in days). The ezmlm-warn(1) ``-d'' switch causes processing of ``list-digest'' bounces rather than ``list'' bounces. ezmlm-weed(1) and ezmlm-return(1) can handle bounces for either list.

ezmlm-warn(1) also removes any files in the bounce directory that are older than 3 times the bounce time-out.

ezmlm-warn(1) is normally run from DIR/editor. This can take quite a lot of resources, if there are a large number of bouncing addresses (>>1000) on a busy list, since by default all bounces are stored in a single directory and ezmlm-warn(1) examines all of them with each invocation. ezmlm-idx->=0.32 changes bounce handling to improve performance for large lists. Bounces are stored in subdirectories of DIR/bounce/d/, one per 10,000 seconds. The corresponding address hashes are stored in 16 subdirectories of DIR/bounce/h/. Instead of looking at all bounces, ezmlm-warn(1) processes only the bounces in DIR/bounce/d/ subdirectories that are ``due''. In addition, ezmlm-warn(1) uses DIR/bounce/lastd as a simple lockout, to assure that it will do work only at most once every 5.5 hours. (Times are scaled to the ezmlm-warn(1) ``-t'' argument if used.) Together, these changes assure that bounce handling will scale well in the default configuration, even for very large lists.

4.34 How the info and faq commands work.

The -info and -faq commands simply reply with the contents of the DIR/text/info and DIR/text/faq files. Edit these files directly or remotely (see How to remotely edit dir/text files). The DIR/text/info file should start with a single line that is meaningful as is and describes the list. This will be used in later versions to allow automatic assembly of the global ``list-of-lists'' (see How to set up a global list address like majordomo@host or listserv@host).

4.35 How the global ezmlm list address works.

Sometimes, it is desirable to have a host- or user-wide address that can list available mailing lists.

ezmlm-request(1) can be used to set up a global address, such as ezmlm@host which allows the user to see and interact with a number of different mailing lists. This is especially useful when your users are used to other mailing list managers, such as ``majordomo'' or ``listproc''. ezmlm-request(1) is set up to answer requests to the address (see How to set up a global list address like majordomo@host or listserv@host). There, it interprets the first line of the message body as a command. It will reply directly to ``lists'' and ``which'' commands. All other commands will be used to construct messages to the respective lists. Where other mailing list managers use synonyms of ezmlm commands, ezmlm-request(1) recognizes these and translates them to the corresponding ezmlm commands. ezmlm-request(1) will build commands also of unrecognized commands. Thus, if you create new commands for a list, ezmlm-request(1) will automatically support them.

If the user does not specify the complete list address, ezmlm-request(1) will attempt to complete the name. See the ezmlm-reject(1) man page for more info.

4.36 How ezmlm-cron works.

If you are a user and have crond(8) access, if you do not need to get digests at specific times, or if you are a system administrator setting up lists, there is no reason for you to use ezmlm-cron(1). If you are a system administrator not allowing users crond(8) access or a user that needs digests at specific times, but without crond(8) access, read on.

ezmlm-cron(1) is a very restrictive interface to crond(8). ezmlm-cron(1) can be used to create digest trigger messages. If a list is set up with a digest code (see ezmlm-make(1) and ezmlm-get(1)) ezmlm will generate a digest from the list joe-sos@host sent to to subscribers of joe-sos-digest@dighost when receiving a message to joe-sos-dig-code@host where ``code'' is the digest code. ezmlm-cron(1) can be used to generate such messages at regular intervals. The file ezcronrc is set up by the sysadmin and controls what trigger messages specific users may set up via ezmlm-cron(1).

Usually, the ezcronrc of that use will have an entry like ``user:user-:host:10'' allowing ``user'' to create trigger messages for up to 10 lists with names starting with ``user-'' and on the host ``host''.

To list the ezcronrc line controlling your use of ezmlm-cron(1):

        % ezmlm-cron -c
To list all entries that you've created:
        % ezmlm-cron -l
To add an entry to trigger digests from list@host every morning at 0230:
        % ezmlm-cron -t 02:30 -i24 list@host code
A new entry for the same list overwrites an old entry.

To delete the entry above:

        % ezmlm-cron -d list@host
or use ezmlm-cron to trigger messages at a different time:
        % ezmlm-cron -t 16:16 -i24 list@host code

4.37 How ezmlm-make works.

ezmlm lists allow almost infinite customization. The component build, together with the qmail delivery mechanism makes it possible to create any variant of list function imaginable. However, this complexity makes it somewhat daunting to the average user wanting to set up a mailing list. ezmlm-make(1) allows automated list setup, while permitting a large amount of configurability.

At first glance, ezmlm-make(1) has many complicated options. However, these can be applied iteratively through the ezmlm-make(1) edit mechanism. Also, they are intended to be relatively complete so that execution of ezmlm-make(1) by e.g. a GUI can be used to safely set up and edit any list.

ezmlm-make(1) reads its command line arguments and switches, then creates the list directory. If the ``-e'' edit or ``-+'' sticky edit switches are not specified, ezmlm-make(1) will fail if the directory already exists. The directory argument must be an absolute path starting with a slash. The dot-qmail file argument, if specified, must also be absolute.

ezmlm-make(1) next reads ezmlmrc(5) located in the /etc/ directory with a default install. If not found, the file in the ezmlm binary directory will be used. The second ezmlm-make command line argument specify the root name of the .qmail files. If the ezmlm-make(1) ``-c'' switch is used, ezmlm-make(1) will look in that directory for a .ezmlmrc file and use it instead. If this file does not exist, ezmlm-make(1) will print a warning and use the previously discussed ezmlmrc(5) files in the same order. You can also use ``-C ezmlmrc.alt'' to use ezmlmrc.alt as the ezmlmrc(5) file. Again, ezmlm-make(1) will fall back to the others with a warning, if the specified ezmlmrc(5) file is not found.

When not run in ``-e edit'' or ``-+'' sticky edit modes, ezmlm-make(1) first creates the list directory. It also as the last step of its action creates DIR/key containing the key used for cookie generation.

The ezmlmrc(5) file consists of a number of file names relative to the list directory, followed by conditional flags (see ezmlm-make(1) and ezmlmrc(5) for details). If all the conditional flags (controlled by the corresponding command line switches) are true, the lines that follow are entered into the named file. There are also tags to erase files. Tags in the format <#X#> (where ``X'' is any number, except ``1'' and ``2'') are replaced by the corresponding ezmlm-make(1) switch argument. The ezmlm-make(1) command line arguments and the ezmlm binary path can be similarly substituted into the text. Thus, ezmlmrc(5) controls (within reason) the entire operation of ezmlm-make(1). ezmlmrc(5) is also set up so that no messages or file containing list state information are lost. Therefore, ezmlm-make(1) can be used to safely edit existing lists. The only caveat is that the list state is undefined while editing is in progress. Thus, it is advisable to prevent mail delivery by setting the ``sticky'' bit on the user's home directory while editing lists.

ezmlm-make(1) will create the file DIR/config. This files saves all the flags that were set at the last execution of ezmlm-make, as well as all the switch and command line arguments. When editing a list, only ``DIR'' and the non-default letter switches need to be specified. Other command line arguments and the ``digit switch'' arguments are read from DIR/config. To remove a digit switch, simply use it with two single quotes as the argument.

You can also easily determine how a list was set up by looking at DIR/config.

4.38 What names can I use for my lists?

Rather than restrict you to a single E-mail address (user@host), qmail in the default setup gives you control over an infinite number of addresses user-*@host. Of course, you (normally) have no way of controlling elsewhere@host since that could lead to overlap between users' ``e-mail address space''. As a consequence, all you mailing lists have to be named user-xx@host where ``user'' is your user name and ``xx'' is anything. You cannot create e.g. mylist@host, only user-mylist@host. To create the list user-list@host do:

        % ezmlm-make ~/list ~/.qmail-list user-list host
Notice that ``user'' is not part of the .qmail file name.

There are two way to create lists with names not starting with your user name: First, qmail can be set up so that you control a virtual domain (see below). Second, the system administrator can set up lists with arbitrary names within the ~alias/ directory.

4.39 Lists in virtual domains

If you use qmail>=1.02 and ezmlm-idx>=0.32, lists under virtual domains work just like other lists and require no adjustments. You can choose any local name for the list and the ezmlm-make(1) argument ``local'' is that name; ``host'' is the name of the virtual domain.

4.40 How do I make customization simple for me/my users?

All non-default switches, ezmlm-issubn(1) setups, etc, can be made standard for new lists by customizing the ezmlm-make(1) configuration file named ``ezmlmrc''. A default ezmlmrc(5) is installed in the ezmlm binary directory. If installed, a system-wide customized ezmlmrc file in /etc/ezmlmrc (or symlinked from there) overrides this. Installing a ~/.ezmlmrc file in a user dotdir and using the ezmlm-make(1) ``-c'' switch allows further per user customization (see Customizing ezmlm-make operation).

Next Previous Contents