===========
LTMP server
===========

Mailman can accept messages via LMTP (RFC 2033).  Most modern mail servers
support LMTP local delivery, so this is a very portable way to connect Mailman
with your mail server.

Our LMTP server is fairly simple though; all it does is make sure that the
message is destined for a valid endpoint, e.g. mylist-join@example.com.

Let's start a testable LMTP queue runner.

    >>> from mailman.testing import helpers
    >>> master = helpers.TestableMaster()
    >>> master.start('lmtp')

It also helps to have a nice LMTP client.

    >>> lmtp = helpers.get_lmtp_client()
    (220, '... Python LMTP queue runner 1.0')
    >>> lmtp.lhlo('remote.example.org')
    (250, ...)


Posting address
===============

If the mail server tries to send a message to a nonexistent mailing list, it
will get a 550 error.

    >>> lmtp.sendmail(
    ...     'anne.person@example.com',
    ...     ['mylist@example.com'], """\
    ... From: anne.person@example.com
    ... To: mylist@example.com
    ... Subject: An interesting message
    ... Message-ID: <aardvark>
    ...
    ... This is an interesting message.
    ... """)
    Traceback (most recent call last):
    ...
    SMTPDataError: (550, 'Requested action not taken: mailbox unavailable')

Once the mailing list is created, the posting address is valid.

    >>> from mailman.app.lifecycle import create_list
    >>> create_list('mylist@example.com')
    <mailing list "mylist@example.com" at ...>

    >>> transaction.commit()
    >>> lmtp.sendmail(
    ...     'anne.person@example.com',
    ...     ['mylist@example.com'], """\
    ... From: anne.person@example.com
    ... To: mylist@example.com
    ... Subject: An interesting message
    ... Message-ID: <badger>
    ...
    ... This is an interesting message.
    ... """)
    {}


Sub-addresses
=============

The LMTP server understands each of the list's sub-addreses, such as -join,
-leave, -request and so on.  If the message is posted to an invalid
sub-address though, it is rejected.

    >>> lmtp.sendmail(
    ...     'anne.person@example.com',
    ...     ['mylist-bogus@example.com'], """\
    ... From: anne.person@example.com
    ... To: mylist-bogus@example.com
    ... Subject: Help
    ... Message-ID: <cow>
    ...
    ... Please help me.
    ... """)
    Traceback (most recent call last):
    ...
    SMTPDataError: (550, 'Requested action not taken: mailbox unavailable')

But the message is accepted if posted to a valid sub-address.

    >>> lmtp.sendmail(
    ...     'anne.person@example.com',
    ...     ['mylist-request@example.com'], """\
    ... From: anne.person@example.com
    ... To: mylist-request@example.com
    ... Subject: Help
    ... Message-ID: <dog>
    ...
    ... Please help me.
    ... """)
    {}


Clean up
========

    >>> master.stop()
