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