[Mailman-Users] configuring mailman with courier
Mark McEahern
marklists at mceahern.com
Wed Mar 12 23:32:25 CET 2003
I just spent a considerable amount of time getting Mailman to work with
Courier as the MTA.
I'm sure there's probably more than one way to do it, but here's an outline
of what I did. I offer this here in the hopes that anyone trying to do this
in the future won't have to pursue all the deadends I did. ;-)
Courier setup
-------------
For starters, I'm using authpgsql as the authmodule for Courier. The domain
where I'm hosting Mailman is one of my hosteddomains.
Mailman
-------
I did NOT have to create any accounts for Mailman, local or virtual. I do
everything with aliases. That, to me, seems like A Good Thing (tm). I
would have liked to use a single dot-courier file for each alias instead of
using the intermediate dummy aliases as described below, but I was unable to
get the .courier-alias at domain:com stuff to work.
After running bin/newlist, I copy the alias information it spits out into a
file (e.g., mylistname-list.aliases). I then run a Python script on this
file that does this:
1. Creates a file in /path/to/courier/etc/aliases/ named after the list. I
name the alias file after the list just to keep each list's aliases separate
and easily identifiable. In this file, I create intermediate aliases.
Suppose my list is named mailman and the hosted domain is domain.com. Then
I'd have:
mailman at domain.com: mailman1
mailman-admin at domain.com: mailman2
...
The right-hand side is a dummy alias.
2. For each dummy alias, create a dot-courier file in
/path/to/courier/etc/aliasdir/. E.g.,
aliasdir/.courier-mailman1
aliasdir/.courier-mailman2
...
The contents of each dot-courier file look like this:
|/opt/mailman/mail/mailman post mailman
In other words, the contents of the dot-courier file are the same as the
right-hand side of what bin/newlist spits out for that alias, just without
the quotation marks.
I've attached the actual script below.
Cheers,
// mark
#!/usr/bin/env python
"""
Create the dot-courier files for the aliases listed in the specified file.
"""
import os
import sys
import pwd
class IncorrectUserError(Exception):pass
def require_user(username):
"""Exit if the current user is not username."""
current_username = pwd.getpwuid(os.getuid())[0]
if current_username != username:
template = 'Please run as %s (current user: %s).\n'
message = template % (username, current_username)
raise IncorrectUserError(message)
class Alias(object):
def __init__(self, alias, domain, command, counter):
self.alias = alias
self.domain = domain
self.command = command
self.counter = counter
def get_basename(self):
alias = self.alias
i = alias.find('-')
if i >= 0:
return alias[:i]
else:
return alias
def get_full_alias(self):
return '%s@%s' % (self.alias, self.domain)
def get_dummy_alias(self):
return '%s%d' % (self.get_basename(), self.counter)
def main():
program = os.path.basename(sys.argv[0])
usage = 'usage: %s listname filename etcdir [domain]\n' % (program,)
try:
listname = sys.argv[1]
filename = sys.argv[2]
etcdir = sys.argv[3]
except IndexError:
sys.stderr.write(usage)
sys.exit(1)
default_domain = 'yourlistdomain.com'
try:
domain = sys.argv[4]
except IndexError:
domain = default_domain
courier_username = 'courier'
try:
require_user(courier_username)
except IncorrectUserError, e:
message = str(e) + '\n'
sys.stderr.write(message)
sys.exit(2)
if not os.path.isdir(etcdir):
message = 'etcdir %s is not a directory.\n' % etcdir
sys.stderr.write(message)
sys.exit(2)
comment_char = '#'
separator = ':'
quote = '"'
aliases = []
counter = 0
for line in file(filename):
if line.startswith(comment_char):
continue
counter += 1
line = line.strip()
if not line:
continue
alias, command = line.split(separator)
alias = alias.strip()
command = command.strip()
if command.startswith(quote):
command = command[1:]
if command.endswith(quote):
command = command[:-1]
a = Alias(alias, domain, command, counter)
aliases.append(a)
# Write the intermediate aliases to $etcdir/aliases/.
filename = os.path.join(etcdir, 'aliases', listname)
f = file(filename, 'w')
for a in aliases:
f.write('%s: %s\n' % (a.get_full_alias(), a.get_dummy_alias()))
f.close()
# Write the dot-courier file to $etcdir/aliasdir/.
dirname = os.path.join(etcdir, 'aliasdir')
for a in aliases:
basename = '.courier-%s' % (a.get_dummy_alias(),)
filename = os.path.join(dirname, basename)
f = file(filename, 'w')
f.write(a.command + '\n')
f.close()
print 'You must run makealiases for these changes to take effect.'
if __name__ == '__main__':
main()
-
More information about the Mailman-Users
mailing list