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