Index: Mailman/Archiver/pipermail.py --- Mailman/Archiver/pipermail.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/Archiver/pipermail.py 2009-03-27 11:55:18 +0100 @@ -122,9 +122,9 @@ parentID = article.parentID if parentID is not None and self.articleIndex.has_key(parentID): parent = self.getArticle(archive, parentID) - myThreadKey = parent.threadKey + article.date + '-' + myThreadKey = parent.threadKey + article.date + '/' + article.msgid + '-' else: - myThreadKey = article.date + '-' + myThreadKey = article.date + '/' + article.msgid + '-' article.threadKey = myThreadKey key = myThreadKey, article.msgid self.setThreadKey(archive, key, article.msgid) @@ -418,7 +418,7 @@ else: parent = self.database.getArticle(self.archive, article.parentID) - article.threadKey = parent.threadKey+article.date+'-' + article.threadKey = parent.threadKey + article.date + '/' + article.msgid + '-' self.database.setThreadKey(self.archive, (article.threadKey, article.msgid), msgid) @@ -632,9 +632,9 @@ article.parentID = parentID = self.get_parent_info(arch, article) if parentID: parent = self.database.getArticle(arch, parentID) - article.threadKey = parent.threadKey + article.date + '-' + article.threadKey = parent.threadKey + article.date + '/' + article.msgid + '-' else: - article.threadKey = article.date + '-' + article.threadKey = article.date + '/' + article.msgid + '-' key = article.threadKey, article.msgid self.database.setThreadKey(arch, key, article.msgid) Index: Mailman/Commands/cmd_subscribe.py --- Mailman/Commands/cmd_subscribe.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/Commands/cmd_subscribe.py 2009-03-27 11:55:18 +0100 @@ -84,6 +84,7 @@ if password is None: password = Utils.MakeRandomPassword() if address is None: + h = None realname, address = parseaddr(res.msg['from']) if not address: # Fall back to the sender address Index: Mailman/HTMLFormatter.py --- Mailman/HTMLFormatter.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/HTMLFormatter.py 2009-03-27 11:55:18 +0100 @@ -44,7 +44,7 @@ realname = self.real_name hostname = self.host_name listinfo_link = Link(self.GetScriptURL('listinfo'), realname).Format() - owner_link = Link('mailto:' + self.GetOwnerEmail(), ownertext).Format() + owner_link = Link('mailto:' + self.GetOwnerEmail(), realname + '-owner').Format() innertext = _('%(listinfo_link)s list run by %(owner_link)s') return Container( '
', Index: Mailman/Handlers/Decorate.py --- Mailman/Handlers/Decorate.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/Handlers/Decorate.py 2009-03-27 11:55:18 +0100 @@ -205,6 +205,7 @@ del msg['content-transfer-encoding'] del msg['content-disposition'] msg['Content-Type'] = 'multipart/mixed' + msg['Mime-version'] = '1.0' Index: Mailman/Handlers/Scrubber.py --- Mailman/Handlers/Scrubber.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/Handlers/Scrubber.py 2009-03-27 11:55:18 +0100 @@ -388,6 +388,8 @@ t = unicode(t, 'ascii', 'replace') try: # Should use HTML-Escape, or try generalizing to UTF-8 + if len(charset) == 0: + charset = 'us-ascii' t = t.encode(charset, 'replace') except (UnicodeError, LookupError, ValueError, AssertionError): Index: Mailman/Queue/OutgoingRunner.py --- Mailman/Queue/OutgoingRunner.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/Queue/OutgoingRunner.py 2009-03-27 11:55:18 +0100 @@ -89,6 +89,7 @@ syslog('error', 'Cannot connect to SMTP server %s on port %s', mm_cfg.SMTPHOST, port) self.__logged = True + self._snooze(0) return True except Errors.SomeRecipientsFailed, e: # Handle local rejects of probe messages differently. Index: Mailman/htmlformat.py --- Mailman/htmlformat.py.orig 2009-02-23 22:23:35 +0100 +++ Mailman/htmlformat.py 2009-03-27 11:55:18 +0100 @@ -300,7 +300,8 @@ charset = 'us-ascii' if self.language: charset = Utils.GetCharSet(self.language) - output = ['Content-Type: text/html; charset=%s\n' % charset] + output = ['Content-Type: text/html; charset=%s' % charset] + output.append('Cache-control: no-cache\n') if not self.suppress_head: kws.setdefault('bgcolor', self.bgcolor) tab = ' ' * indent Index: bin/check_perms --- bin/check_perms.orig 2009-02-23 22:23:35 +0100 +++ bin/check_perms 2009-03-27 11:55:18 +0100 @@ -82,7 +82,7 @@ return os.stat(path)[ST_MODE] def statgidmode(path): - stat = os.stat(path) + stat = os.lstat(path) return stat[ST_MODE], stat[ST_GID] seen = {} Index: bin/config_list --- bin/config_list.orig 2009-02-23 22:23:35 +0100 +++ bin/config_list 2009-03-27 11:55:18 +0100 @@ -307,6 +307,11 @@ in mm_cfg.OPTINFO.items() if validval & bitval] gui._setValue(mlist, k, validval, fakedoc) + # Ugly hack, but seems to be needed since + # new_member_options isn't really a number in gui. + # -- tfheen, 2003-12-06 + if k == "new_member_options": + mlist.new_member_options = validval # BAW: when to do gui._postValidate()??? finally: if savelist and not checkonly: Index: bin/mailmanctl --- bin/mailmanctl.orig 2009-02-23 22:23:35 +0100 +++ bin/mailmanctl 2009-03-27 11:55:18 +0100 @@ -417,6 +417,13 @@ # won't be opening any terminal devices, don't do the ultra-paranoid # suggestion of doing a second fork after the setsid() call. os.setsid() + + # Be sure to close any open std{in,out,err} + devnull = os.open('/dev/null', 0) + os.dup2(devnull, 0) + os.dup2(devnull, 1) + os.dup2(devnull, 2) + # Instead of cd'ing to root, cd to the Mailman installation home os.chdir(mm_cfg.PREFIX) # Set our file mode creation umask Index: bin/newlist --- bin/newlist.orig 2009-02-23 22:23:35 +0100 +++ bin/newlist 2009-03-27 11:58:07 +0100 @@ -88,12 +88,16 @@ defined in your Defaults.py file or overridden by settings in mm_cfg.py). Note that listnames are forced to lowercase. + +The list admin address need to be a fully-qualified address, like +owner@example.com, not just owner. """ import sys import os import getpass import getopt +import grp import paths from Mailman import mm_cfg @@ -122,6 +126,9 @@ def main(): + gid = grp.getgrnam(mm_cfg.MAILMAN_GROUP)[2] + if os.getgid() != mm_cfg.MAILMAN_GROUP: + os.setgid(gid) try: opts, args = getopt.getopt(sys.argv[1:], 'hql:u:e:', ['help', 'quiet', 'language=', @@ -203,7 +210,7 @@ except Errors.BadListNameError, s: usage(1, _('Illegal list name: %(s)s')) except Errors.EmailAddressError, s: - usage(1, _('Bad owner email address: %(s)s')) + usage(1, _('Bad owner email address: %(s)s. Owner addresses need to be fully-qualified names, like "owner@example.com", not just "owner".')) except Errors.MMListAlreadyExistsError: usage(1, _('List already exists: %(listname)s')) Index: bin/update --- bin/update.orig 2009-02-23 22:23:35 +0100 +++ bin/update 2009-03-27 11:55:18 +0100 @@ -551,9 +551,11 @@ file20 = os.path.join(mm_cfg.DATA_DIR, 'pending_subscriptions.db') file214 = os.path.join(mm_cfg.DATA_DIR, 'pending.pck') db = None + ver = None # Try to load the Mailman 2.0 file try: fp = open(file20) + ver = "20" except IOError, e: if e.errno <> errno.ENOENT: raise else: @@ -565,6 +567,7 @@ # Try to load the Mailman 2.1.x where x < 5, file try: fp = open(file214) + ver = "214" except IOError, e: if e.errno <> errno.ENOENT: raise else: @@ -598,8 +601,12 @@ # data[0] is the address being unsubscribed addrops_by_address.setdefault(data[0], []).append((key, val)) elif op == Pending.SUBSCRIPTION: - # data[0] is a UserDesc object - addr = data[0].address + if ver == "20": + # data is tuple (emailaddr, password, digest) + addr = data[0] + else: + # data[0] is a UserDesc object + addr = data[0].address subs_by_address.setdefault(addr, []).append((key, val)) elif op == Pending.RE_ENABLE: # data[0] is the mailing list's internal name Index: scripts/driver --- scripts/driver.orig 2009-02-23 22:23:35 +0100 +++ scripts/driver 2009-03-27 11:55:18 +0100 @@ -98,6 +98,15 @@ module = getattr(pkg, scriptname) main = getattr(module, 'main') try: + import os + request_method = os.environ.get('REQUEST_METHOD') + if not request_method in ['GET', 'POST', 'HEAD']: + print "Status: 405 Method not allowed" + print "Content-type: text/plain" + print + print "The method is not allowed" + sys.exit() + try: sys.stderr = logger sys.stdout = tempstdout