[Mailman-Users] newlist patch for beta 5

Derek Simkowiak dereks at kd-dev.com
Sun Oct 1 02:12:11 CEST 2000

	Newlist has a problem.

	When run in interactive mode, it will output the necessary entries
for the Sendmail 'aliases' file.  That is very nice.

	However, I am not usually in an X-Window session, so I can't use a
mouse to cut'n'paste those entries into my /etc/aliases.  It's very

	The attached version will print all *informational* messages to
stderr, not stdout.  Only the 'aliases' entries are printed to
stdout.  So now, all I need to do is

./newlist >> /etc/aliases 

	(or ./newlist > tempfile.txt ; cat tempfile >> /etc/aliases.  You
get the idea.)  I will still get prompted (if in interactive mode), but
the prompts will be printed to stderr, and all the aliases will go to
stdout (and hence redirect into my file).

	If I run in non-interactive mode, and put all the necessary
variables on the command line, then the only output (to stdout) is the
aliases.  All other behaviour is unchanged.

	This also makes it much easier to write automated shell scripts
and CGI programs to create new lists, because there's no messy sed to
parse out the informational messages.

	The attached file is the new version of newlist, created off
2.0beta5.  Feel free to create a diff of it if that is your preferred

	Note that I presented this same patch for beta2 but it was never
incorporated, so I assume the maintainers aren't interested in this
feature.  In short: You have to grab this and keep updating it yourself if
you want to use it in future versions of MailMan.

Derek Simkowiak
dereks at kd-dev.com
-------------- next part --------------
#! /usr/bin/env python
# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

"""Create a new, unpopulated mailing list.

  newlist <list-name> <list-admin's-address> <admin-password> <immediate>

You can specify as many of the arguments as you want on the command line. 
The optional <immediate> argument, if present, means to send out the notice 
immediately.  Otherwise, the script hangs pending input, to give time for
the person creating the list to customize it before sending the admin an
email notice about the existence of the new list.

Note that list-names are forced to lowercase.

import sys
import os
import string
import time

import paths
from Mailman import mm_cfg
from Mailman import MailList
from Mailman import Utils
from Mailman import Errors
from Mailman import Message
from Mailman.Handlers import HandlerAPI
from Mailman.Crypt import crypt
from Mailman.pythonlib import getpass

## %(listname)s mailing list
## created: %(date)s %(user)s
%(list)s "|%(wrapper)s post %(listname)s"
%(admin)s "|%(wrapper)s mailowner %(listname)s"
%(request)s "|%(wrapper)s mailcmd %(listname)s"
%(owner2)s %(listname)s-admin

def getusername():
    username = os.environ.get('USER') or os.environ.get('LOGNAME')
    if not username:
        import pwd
        username = pwd.getpwuid(os.getuid())[0]
    if not username:
        username = '<unknown>'
    return username

def usage(code, msg=''):
    print __doc__
    if msg:
        print msg

def raw_input(prompt=''):

		# A raw_input() replacement that doesn't save the string in the
		# GNU readline history, and prints the prompt to stderr
		import sys
		prompt = str(prompt)
		if prompt:
		line = sys.stdin.readline()
		if not line:
				raise EOFError
		if line[-1] == '\n':
				line = line[:-1]
		return line

def main(argv):
    if len(argv) > 1:
	listname = argv[1]
	listname = raw_input("Enter the name of the list: ")
    listname = string.lower(listname)

    if '@' in listname:
        usage(1, 'List name must not include "@": ' + listname)

    if Utils.list_exists(listname):
        usage(1, 'List already exists: ' + listname)

    if len(argv) > 2:
	owner_mail = argv[2]
	owner_mail = raw_input(
	    "Enter the email of the person running the list: ")
    if len(argv) > 3:
	list_pw = argv[3]
        # A simple hack to have getpass() print to stderr, not stdout
        temp = sys.stdout
        sys.stdout = sys.stderr
        list_pw = getpass.getpass("Initial %s password: " % listname)
        sys.stdout = temp

    mlist = MailList.MailList()
        pw = crypt(list_pw , Utils.GetRandomSeed())
        # guarantee that all newly created files have the proper permission.
        # proper group ownership should be assured by the autoconf script
        # enforcing that all directories have the group sticky bit set
        oldmask = os.umask(002)
                mlist.Create(listname, owner_mail, pw)
        except Errors.MMBadEmailError:
            usage(1, 'Bad owner email address: ' + owner_mail)
        except Errors.MMListAlreadyExistsError:
            usage(1, 'List already exists: ' + listname)

        if len(argv) < 4:
            sys.stderr.write ("\nEntry for aliases file:\n");

        print ALIASTEMPLATE % {
            'listname': listname,
            'list'    : "%-24s" % (listname + ":"),
            'wrapper' : '%s/wrapper' % mm_cfg.WRAPPER_DIR,
            'admin'   : "%-24s" % ("%s-admin:" % listname),
            'request' : "%-24s" % ("%s-request:" % listname),
            'owner2'  : "%-24s" % ("%s-owner:" % listname),
            'date'    : time.strftime('%d-%b-%Y', time.localtime(time.time())),
            'user'    : getusername(),

        if len(argv) < 5:
            sys.stderr.write ("Hit enter to continue with %s owner notification..."
                   % listname),
        # send the notice to the list owner
        text = Utils.maketext(
            {'listname'    : listname,
             'password'    : list_pw, 
             'admin_url'   : mlist.GetScriptURL('admin', absolute=1), 
             'listinfo_url': mlist.GetScriptURL('listinfo', absolute=1),
             'requestaddr' : "%s-request@%s" % (listname, mlist.host_name),
             'hostname'    : mlist.host_name,
        msg = Message.UserNotification(owner_mail,
                                       'mailman-owner@' + mlist.host_name,
                                       'Your new mailing list: ' + listname,
        HandlerAPI.DeliverToUser(mlist, msg)

if __name__ == '__main__':

More information about the Mailman-Users mailing list