diff -Nru mailman-2.1.5/bin/change_maxmembers mailman-2.1.5/bin/change_maxmembers --- mailman-2.1.5/bin/change_maxmembers 1969-12-31 21:00:00.000000000 -0300 +++ mailman-2.1.5/bin/change_maxmembers 2004-09-16 11:26:28.000000000 -0300 @@ -0,0 +1,163 @@ +#! /usr/bin/python +# +# Copyright (C) 2004 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# 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. + +"""Change a list's maximum number of members. + +Usage: change_maxmembers [options] + +Options: + + --all / -a + Change the member limit for all lists. + + --domain=domain + -d domain + Change the member limit for all lists in the virtual domain `domain'. It + is okay to give multiple -d options. + + --listname=listname + -l listname + Change/Print (see below) the member limit only for the named list. It is + okay to give multiple -l options. + + --max_members=max_members + -m max_members + Use the supplied `max_members` as the maximum number of members + than can be subscribed on the list(s). + + --show_limit + -s + Print the maximum number of members for the named list(s). + + --help / -h + Print this help message and exit. + +The options -m and -s are mutually exclusive. +""" + +import sys +import getopt + +import paths +from Mailman import mm_cfg +from Mailman import Utils +from Mailman import MailList +from Mailman import Errors +from Mailman import i18n + +_ = i18n._ + +SPACE = ' ' + + + +def usage(code, msg=''): + if code: + fd = sys.stderr + else: + fd = sys.stdout + print >> fd, _(__doc__) + if msg: + print >> fd, msg + sys.exit(code) + + + +_listcache = {} + +def openlist(listname): + missing = [] + mlist = _listcache.get(listname, missing) + if mlist is missing: + try: + mlist = MailList.MailList(listname, lock=0) + except Errors.MMListError, e: + usage(1, _('No such list "%(listname)s"\n%(e)s')) + _listcache[listname] = mlist + return mlist + + + +def main(): + # Parse options + try: + opts, args = getopt.getopt( + sys.argv[1:], 'ad:l:m:sh', + ['all', 'domain=', 'listname=', 'max_members=', 'show_limit', 'help']) + except getopt.error, msg: + usage(1, msg) + + # defaults + listnames = {} + domains = {} + max_members = 0 + show_limit = 0 + + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-a', '--all'): + for name in Utils.list_names(): + listnames[name] = 1 + elif opt in ('-d', '--domain'): + domains[arg] = 1 + elif opt in ('-l', '--listname'): + listnames[arg] = 1 + elif opt in ('-m', '--max_members'): + try: + max_members = int(arg) + except ValueError: + usage(1) + elif opt in ('-s', '--show_limit'): + show_limit = 1 + + if max_members is not 0 and show_limit is not 0: + usage(1) + + if args: + strargs = SPACE.join(args) + usage(1, _('Bad arguments: %(strargs)s')) + + if domains: + for name in Utils.list_names(): + mlist = openlist(name) + if domains.has_key(mlist.host_name): + listnames[name] = 1 + + if not listnames: + print >> sys.stderr, _('Nothing to do.') + sys.exit(0) + + for listname in listnames.keys(): + mlist = openlist(listname) + mlist.Lock() + try: + if show_limit is not 0: + max_members = mlist.max_members + print _('%(listname)s limit of members: %(max_members)d') + else: + mlist.max_members = max_members + mlist.Save() + print _('New %(listname)s limit of members: %(max_members)d') + finally: + mlist.Unlock() + + + +if __name__ == '__main__': + main() diff -Nru mailman-2.1.5/bin/Makefile.in mailman-2.1.5/bin/Makefile.in --- mailman-2.1.5/bin/Makefile.in 2003-12-24 15:03:15.000000000 -0200 +++ mailman-2.1.5/bin/Makefile.in 2004-09-16 11:50:52.000000000 -0300 @@ -48,7 +48,8 @@ version config_list list_lists dumpdb cleanarch \ list_admins genaliases change_pw mailmanctl qrunner inject \ unshunt fix_url.py convert.py transcheck b4b5-archfix \ - list_owners msgfmt.py show_qfiles discard rb-archfix + list_owners msgfmt.py show_qfiles discard rb-archfix \ + change_maxmembers BUILDDIR= ../build/bin diff -Nru mailman-2.1.5/Mailman/Cgi/admin.py mailman-2.1.5/Mailman/Cgi/admin.py --- mailman-2.1.5/Mailman/Cgi/admin.py 2003-12-24 15:27:45.000000000 -0200 +++ mailman-2.1.5/Mailman/Cgi/admin.py 2004-09-14 16:02:19.000000000 -0300 @@ -1344,6 +1344,8 @@ else: subscribe_errors.append((entry, _('Bad/Invalid email address'))) + except Errors.MMMembersLimit: + subscribe_errors.append((entry, _('This list have reached its members limit'))) except Errors.MMHostileAddress: subscribe_errors.append( (entry, _('Hostile address (illegal characters)'))) diff -Nru mailman-2.1.5/Mailman/Cgi/subscribe.py mailman-2.1.5/Mailman/Cgi/subscribe.py --- mailman-2.1.5/Mailman/Cgi/subscribe.py 2003-04-07 19:51:15.000000000 -0300 +++ mailman-2.1.5/Mailman/Cgi/subscribe.py 2004-09-14 16:02:29.000000000 -0300 @@ -185,6 +185,9 @@ results = _("""\ The email address you supplied is not valid. (E.g. it must contain an `@'.)""") + except Errors.MMMembersLimit: + results = _("""\ +This list have reached its members limit.""") except Errors.MMHostileAddress: results = _("""\ Your subscription is not allowed because the email address you gave is diff -Nru mailman-2.1.5/Mailman/Commands/cmd_subscribe.py mailman-2.1.5/Mailman/Commands/cmd_subscribe.py --- mailman-2.1.5/Mailman/Commands/cmd_subscribe.py 2002-11-21 03:37:25.000000000 -0200 +++ mailman-2.1.5/Mailman/Commands/cmd_subscribe.py 2004-09-14 16:02:45.000000000 -0300 @@ -109,6 +109,10 @@ Mailman won't accept the given email address as a valid address. (E.g. it must have an @ in it.)""")) return STOP + except Errors.MMMembersLimit: + res.results.append = _("""\ +This list have reached its members limit.""") + return STOP except Errors.MMHostileAddress: res.results.append(_("""\ Your subscription is not allowed because diff -Nru mailman-2.1.5/Mailman/Errors.py mailman-2.1.5/Mailman/Errors.py --- mailman-2.1.5/Mailman/Errors.py 2003-11-30 22:35:32.000000000 -0200 +++ mailman-2.1.5/Mailman/Errors.py 2004-09-14 16:02:53.000000000 -0300 @@ -30,6 +30,7 @@ class MMMemberError(Exception): pass class MMBadUserError(MMMemberError): pass class MMAlreadyAMember(MMMemberError): pass +class MMMembersLimit(Exception): pass # "New" style membership exceptions (new w/ MM2.1) class MemberError(Exception): pass diff -Nru mailman-2.1.5/Mailman/ListAdmin.py mailman-2.1.5/Mailman/ListAdmin.py --- mailman-2.1.5/Mailman/ListAdmin.py 2004-02-29 00:55:27.000000000 -0300 +++ mailman-2.1.5/Mailman/ListAdmin.py 2004-09-14 16:03:02.000000000 -0300 @@ -414,6 +414,10 @@ except Errors.MMAlreadyAMember: # User has already been subscribed, after sending the request pass + except Errors.MMMembersLimit: + self.__refuse(_('Subscription request'), addr, + _('[This list have reached its members limit]'), + lang=lang) # TBD: disgusting hack: ApprovedAddMember() can end up closing # the request database. self.__opendb() diff -Nru mailman-2.1.5/Mailman/Cgi/create.py mailman-2.1.5/Mailman/Cgi/create.py --- mailman-2.1.5/Mailman/Cgi/create.py 2004-02-29 14:07:51.000000000 -0300 +++ mailman-2.1.5/Mailman/Cgi/create.py 2004-09-29 14:27:01.000000000 -0300 @@ -92,6 +92,12 @@ confirm = cgidata.getvalue('confirm', '').strip() auth = cgidata.getvalue('auth', '').strip() langs = cgidata.getvalue('langs', [mm_cfg.DEFAULT_SERVER_LANGUAGE]) + + try: + max_members = int(cgidata.getvalue('max_members', '0')) + except ValueError: + max_members = 0 + if not isinstance(langs, ListType): langs = [langs] @@ -184,7 +190,7 @@ oldmask = os.umask(002) try: try: - mlist.Create(listname, owner, pw, langs, emailhost) + mlist.Create(listname, owner, pw, langs, emailhost, max_members) finally: os.umask(oldmask) except Errors.EmailAddressError, s: @@ -408,6 +414,13 @@ values=(0, 1))]) ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY) ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY) + + safemax_members = Utils.websafe(cgidata.getvalue('max_members', '')) + ftable.AddRow([Label(_( + 'Maximum number of members (leave it blank for unlimited):')), + TextBox('max_members', safemax_members)]) + ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY) + ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY) ftable.AddRow(['
']) ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, colspan=2) diff -Nru mailman-2.1.5/Mailman/MailList.py mailman-2.1.5/Mailman/MailList.py --- mailman-2.1.5/Mailman/MailList.py 2004-03-04 11:10:28.000000000 -0300 +++ mailman-2.1.5/Mailman/MailList.py 2004-09-29 14:26:07.000000000 -0300 @@ -263,7 +263,7 @@ continue self._gui.append(getattr(Gui, component)()) - def InitVars(self, name=None, admin='', crypted_password=''): + def InitVars(self, name=None, admin='', crypted_password='', max_members=0): """Assign default values - some will be overriden by stored state.""" # Non-configurable list info if name: @@ -275,6 +275,7 @@ # Must save this state, even though it isn't configurable self.volume = 1 self.members = {} # self.digest_members is initted in mm_digest + self.max_members = max_members self.data_version = mm_cfg.DATA_FILE_VERSION self.last_post_time = 0 @@ -433,7 +434,7 @@ # List creation # def Create(self, name, admin, crypted_password, - langs=None, emailhost=None): + langs=None, emailhost=None, max_members=0): if Utils.list_exists(name): raise Errors.MMListAlreadyExistsError, name # Validate what will be the list's posting address. If that's @@ -454,7 +455,7 @@ self._full_path = Site.get_listpath(name, create=1) # Don't use Lock() since that tries to load the non-existant config.pck self.__lock.lock() - self.InitVars(name, admin, crypted_password) + self.InitVars(name, admin, crypted_password, max_members) self.CheckValues() if langs is None: self.available_languages = [self.preferred_language] @@ -808,7 +809,13 @@ if email.lower() == self.GetListEmail().lower(): # Trying to subscribe the list to itself! raise Errors.MMBadEmailError - + + # Check if there is a members limit on this list. 0 = unlimited. + if self.max_members == 0: + pass + elif len(self.members) >= self.max_members: + raise Errors.MMMembersLimit + # Is the subscribing address banned from this list? ban = 0 for pattern in self.ban_list: @@ -932,6 +939,13 @@ Utils.ValidateEmail(email) if self.isMember(email): raise Errors.MMAlreadyAMember, email + + # Check if there is a members limit on this list. 0 = unlimited. + if self.max_members == 0: + pass + elif len(self.members) >= self.max_members: + raise Errors.MMMembersLimit + # Do the actual addition self.addNewMember(email, realname=name, digest=digest, password=password, language=lang) diff -Nru mailman-2.1.5/configure.in mailman-2.1.5/configure.in --- mailman-2.1.5/configure.in 2003-12-24 15:11:48.000000000 -0200 +++ mailman-2.1.5/configure.in 2004-09-16 12:18:19.000000000 -0300 @@ -545,6 +545,7 @@ bin/add_members \ bin/arch \ bin/change_pw \ +bin/change_maxmembers \ bin/check_db \ bin/check_perms \ bin/cleanarch \