aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Mailman/Handlers/AvoidDuplicates.py20
-rw-r--r--Mailman/Handlers/Decorate.py3
-rw-r--r--Mailman/ListAdmin.py22
-rw-r--r--Mailman/MTA/Postfix.py7
-rw-r--r--Mailman/SecurityManager.py5
-rw-r--r--NEWS31
-rw-r--r--bin/arch11
-rwxr-xr-xbin/check_perms3
-rwxr-xr-xcron/gate_news9
-rw-r--r--templates/ru/userpass.txt2
-rw-r--r--templates/zh_CN/postack.txt8
-rw-r--r--templates/zh_CN/postauth.txt14
-rw-r--r--templates/zh_CN/postheld.txt10
-rw-r--r--templates/zh_CN/unsub.txt20
14 files changed, 114 insertions, 51 deletions
diff --git a/Mailman/Handlers/AvoidDuplicates.py b/Mailman/Handlers/AvoidDuplicates.py
index fdcc49ca..038034c7 100644
--- a/Mailman/Handlers/AvoidDuplicates.py
+++ b/Mailman/Handlers/AvoidDuplicates.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2003 by the Free Software Foundation, Inc.
+# Copyright (C) 2002-2008 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
@@ -40,34 +40,38 @@ def process(mlist, msg, msgdata):
# Short circuit
if not recips:
return
+ # There is an issue with addresses in To: or Cc: that differ in
+ # case from the MemberCPAddresses in recips. We can't just
+ # lower-case everything because we still want CP addresses in
+ # the final recips list, so we lower case the keys.
# Seed this set with addresses we don't care about dup avoiding
explicit_recips = {}
listaddrs = [mlist.GetListEmail(), mlist.GetBouncesEmail(),
mlist.GetOwnerEmail(), mlist.GetRequestEmail()]
for addr in listaddrs:
- explicit_recips[addr] = True
+ explicit_recips[addr.lower()] = True
# Figure out the set of explicit recipients
ccaddrs = {}
for header in ('to', 'cc', 'resent-to', 'resent-cc'):
addrs = getaddresses(msg.get_all(header, []))
if header == 'cc':
for name, addr in addrs:
- ccaddrs[addr] = name, addr
+ ccaddrs[addr.lower()] = name, addr
for name, addr in addrs:
if not addr:
continue
# Ignore the list addresses for purposes of dup avoidance
- explicit_recips[addr] = True
+ explicit_recips[addr.lower()] = True
# Now strip out the list addresses
for addr in listaddrs:
- del explicit_recips[addr]
+ del explicit_recips[addr.lower()]
if not explicit_recips:
# No one was explicitly addressed, so we can't do any dup collapsing
return
newrecips = []
for r in recips:
# If this recipient is explicitly addressed...
- if explicit_recips.has_key(r):
+ if explicit_recips.has_key(r.lower()):
send_duplicate = True
# If the member wants to receive duplicates, or if the recipient
# is not a member at all, just flag the X-Mailman-Duplicate: yes
@@ -81,8 +85,8 @@ def process(mlist, msg, msgdata):
if send_duplicate:
msgdata.setdefault('add-dup-header', {})[r] = True
newrecips.append(r)
- elif ccaddrs.has_key(r):
- del ccaddrs[r]
+ elif ccaddrs.has_key(r.lower()):
+ del ccaddrs[r.lower()]
else:
# Otherwise, this is the first time they've been in the recips
# list. Add them to the newrecips list and flag them as having
diff --git a/Mailman/Handlers/Decorate.py b/Mailman/Handlers/Decorate.py
index 64d569db..81bf7d33 100644
--- a/Mailman/Handlers/Decorate.py
+++ b/Mailman/Handlers/Decorate.py
@@ -227,7 +227,8 @@ def decorate(mlist, template, what, extradict=None):
template = Utils.to_percent(template)
# Interpolate into the template
try:
- text = re.sub(r' *\r?\n', r'\n', template % d)
+ text = re.sub(r'(?m)(?<!^--) +(?=\n)', '',
+ re.sub(r'\r\n', r'\n', template % d))
except (ValueError, TypeError), e:
syslog('error', 'Exception while calculating %s:\n%s', what, e)
what = what.upper()
diff --git a/Mailman/ListAdmin.py b/Mailman/ListAdmin.py
index 191b76f8..ec1307ac 100644
--- a/Mailman/ListAdmin.py
+++ b/Mailman/ListAdmin.py
@@ -538,7 +538,21 @@ class ListAdmin:
except IOError, e:
if e.errno <> errno.ENOENT: raise
self.__db = {}
- for id, (op, info) in self.__db.items():
+ for id, x in self.__db.items():
+ # A bug in versions 2.1.1 through 2.1.11 could have resulted in
+ # just info being stored instead of (op, info)
+ if len(x) == 2:
+ op, info = x
+ elif len(x) == 6:
+ # This is the buggy info. Check for digest flag.
+ if x[4] in (0, 1):
+ op = SUBSCRIPTION
+ else:
+ op = HELDMSG
+ self.__db[id] = op, x
+ continue
+ else:
+ assert False, 'Unknown record format in %s' % self.__filename
if op == SUBSCRIPTION:
if len(info) == 4:
# pre-2.1a2 compatibility
@@ -553,7 +567,8 @@ class ListAdmin:
assert len(info) == 6, 'Unknown subscription record layout'
continue
# Here's the new layout
- self.__db[id] = when, addr, fullname, passwd, digest, lang
+ self.__db[id] = op, (when, addr, fullname, passwd,
+ digest, lang)
elif op == HELDMSG:
if len(info) == 5:
when, sender, subject, reason, text = info
@@ -562,7 +577,8 @@ class ListAdmin:
assert len(info) == 6, 'Unknown held msg record layout'
continue
# Here's the new layout
- self.__db[id] = when, sender, subject, reason, text, msgdata
+ self.__db[id] = op, (when, sender, subject, reason,
+ text, msgdata)
# All done
self.__closedb()
diff --git a/Mailman/MTA/Postfix.py b/Mailman/MTA/Postfix.py
index 33cb9a47..daa9692f 100644
--- a/Mailman/MTA/Postfix.py
+++ b/Mailman/MTA/Postfix.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2005 by the Free Software Foundation, Inc.
+# Copyright (C) 2001-2008 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
@@ -256,6 +256,7 @@ def _do_remove(mlist, textfile, virtualp):
filteroutp = False
start = '# STANZA START: ' + listname
end = '# STANZA END: ' + listname
+ oops = '# STANZA START: '
while 1:
line = infp.readline()
if not line:
@@ -270,6 +271,10 @@ def _do_remove(mlist, textfile, virtualp):
# Discard the trailing blank line, but don't worry if
# we're at the end of the file.
infp.readline()
+ elif line.startswith(oops):
+ # Stanza end must be missing - start writing from here.
+ filteroutp = False
+ outfp.write(line)
# Otherwise, ignore the line
else:
if line.strip() == start:
diff --git a/Mailman/SecurityManager.py b/Mailman/SecurityManager.py
index 01610b43..572018e2 100644
--- a/Mailman/SecurityManager.py
+++ b/Mailman/SecurityManager.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2008 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
@@ -299,7 +299,8 @@ class SecurityManager:
usernames.append(k[len(prefix):])
# If any check out, we're golden. Note: `@'s are no longer legal
# values in cookie keys.
- for user in [Utils.UnobscureEmail(u) for u in usernames]:
+ for user in [Utils.UnobscureEmail(urllib.unquote(u))
+ for u in usernames]:
ok = self.__checkone(c, authcontext, user)
if ok:
return True
diff --git a/NEWS b/NEWS
index ddc79973..91418076 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,37 @@ Copyright (C) 1998-2008 by the Free Software Foundation, Inc.
Here is a history of user visible changes to Mailman.
+2.1.12? (xx-xxx-xxxx)
+
+ Bug fixes and other patches
+
+ - Fixed a bug in admin.py which would result in chunked pages of the
+ membership list for members whose address begins with a non-alphanumeric
+ character to not be visible or retrievable.
+
+ - Changed ListAdmin.py to make rejected post messages From: the -owner
+ address instead of the -bounces address.
+
+ - With MTA = 'Postfix', if the STANZA END for a list being removed is
+ missing or munged, the remainder of the aliases and/or virtual-mailman
+ file is lost. Fixed.
+
+ - Since Mailman 2.1.1, 2.0.x outstanding subscription and held message
+ requests have not been migrated properly. This is fixed.
+ Bug #266106 (sf998384).
+
+ - Changed cron/gate_news to continue processing the remaining lists on
+ certain errors that can be caused by configuration of a particular list.
+ Bug #265941 (sf775100).
+
+ - Fixed a bug in AvoidDuplicates.py that caused it to fail if the address
+ in the To: or Cc: header differed in case from the case-preserved member
+ address. Bug #297795.
+
+ - Fixed a problem in SecurityManager that caused it to not find the
+ cookie when CheckCookie was not given a user and the user in the cookie
+ had a %xx encoded character. Bug # 299220.
+
2.1.11 (30-Jun-2008)
New Features
diff --git a/bin/arch b/bin/arch
index 40a75a0e..a98ae2af 100644
--- a/bin/arch
+++ b/bin/arch
@@ -1,6 +1,6 @@
#! @PYTHON@
#
-# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2008 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
@@ -161,6 +161,11 @@ def main():
# set the lock lifetime to 3 hours. XXX is this reasonable???
lock = LockFile(lockfile, lifetime=3*60*60)
lock.lock()
+ # Try to open mbox before wiping old archive.
+ try:
+ fp = open(mbox)
+ except IOError, msg:
+ usage(3, _('Cannot open mbox file %(mbox)s: %(msg)s'))
# Maybe wipe the old archives
if wipe:
if mlist.scrub_nondigest:
@@ -177,10 +182,6 @@ def main():
shutil.rmtree(mlist.archive_dir())
if mlist.scrub_nondigest and saved:
os.renames(savedir, atchdir)
- try:
- fp = open(mbox)
- except IOError, msg:
- usage(3, _('Cannot open mbox file %(mbox)s: %(msg)s'))
archiver = HyperArchive(mlist)
archiver.VERBOSE = verbose
diff --git a/bin/check_perms b/bin/check_perms
index 7bba0f74..3c8d3768 100755
--- a/bin/check_perms
+++ b/bin/check_perms
@@ -1,6 +1,6 @@
#! @PYTHON@
#
-# Copyright (C) 1998-2007 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2008 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
@@ -334,6 +334,7 @@ def checkdata():
checkfiles = ('config.pck', 'config.pck.last',
'config.db', 'config.db.last',
'next-digest', 'next-digest-topics',
+ 'digest.mbox', 'pending.pck',
'request.db', 'request.db.tmp')
if STATE.VERBOSE:
print _('checking permissions on list data')
diff --git a/cron/gate_news b/cron/gate_news
index a84731f3..a44257cd 100755
--- a/cron/gate_news
+++ b/cron/gate_news
@@ -1,6 +1,6 @@
#! @PYTHON@
#
-# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2008 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
@@ -206,8 +206,11 @@ def process_lists(glock):
# Open the newsgroup, but let most exceptions percolate up.
try:
conn, first, last = open_newsgroup(mlist)
- except (socket.error, nntplib.NNTPError):
- break
+ except (socket.error, nntplib.NNTPError), e:
+ syslog('fromusenet',
+ "%s: couldn't open newsgroup %s: skipping\n%s",
+ listname, mlist.linked_newsgroup, e)
+ continue
syslog('fromusenet', '%s: [%d..%d]' % (listname, first, last))
try:
try:
diff --git a/templates/ru/userpass.txt b/templates/ru/userpass.txt
index 7efb934f..fbc9e706 100644
--- a/templates/ru/userpass.txt
+++ b/templates/ru/userpass.txt
@@ -1,5 +1,5 @@
-
- $(fqdn_lname)s. ,
+ %(fqdn_lname)s. ,
, ,
.
diff --git a/templates/zh_CN/postack.txt b/templates/zh_CN/postack.txt
index 2fc80b71..df442f00 100644
--- a/templates/zh_CN/postack.txt
+++ b/templates/zh_CN/postack.txt
@@ -1,8 +1,8 @@
+您的名为
%(subject)s
-ʼѾ %(listname)s ʼбɹա
+的邮件已经被 %(listname)s 邮件列表成功接收。
-бϢҳΪ %(listinfo_url)s
-ƫΪ %(optionsurl)s
+列表信息页为: %(listinfo_url)s
+您的偏好设置为: %(optionsurl)s
diff --git a/templates/zh_CN/postauth.txt b/templates/zh_CN/postauth.txt
index 8dfce787..400a5afb 100644
--- a/templates/zh_CN/postauth.txt
+++ b/templates/zh_CN/postauth.txt
@@ -1,12 +1,12 @@
-ΪбԱʼбżҪȨ
+作为列表管理员,下面的邮件列表信件需要您的授权:
- б %(listname)s@%(hostname)s
- ߣ %(sender)s
- ⣺ %(subject)s
- ԭ %(reason)s
+ 列表: %(listname)s@%(hostname)s
+ 发送者: %(sender)s
+ 主题: %(subject)s
+ 原因: %(reason)s
-Ϊķ㣬ʣ
+为了您的方便,请访问:
%(admindb_url)s
-ܾͨ
+来通过或拒绝请求。
diff --git a/templates/zh_CN/postheld.txt b/templates/zh_CN/postheld.txt
index 32c02c80..ff05d9be 100644
--- a/templates/zh_CN/postheld.txt
+++ b/templates/zh_CN/postheld.txt
@@ -1,14 +1,14 @@
- %(listname)sΪ
+您发给 %(listname)s,主题为
%(subject)s
-ʼݴ棬ֱͨбˡ
+的邮件被暂存,直到通过列表主持者审核。
-ʼݴԭǣ
+邮件被暂存的原因是:
%(reason)s
-ʼ߽͸бյб߷֪ͨ
-ȡηͣURL
+您的邮件或者将被发送给列表,或者您将收到列表主持者发给您的通知。
+如果您想取消本次发送,请访问下面的URL:
%(confirmurl)s
diff --git a/templates/zh_CN/unsub.txt b/templates/zh_CN/unsub.txt
index 1b887275..cd4996e9 100644
--- a/templates/zh_CN/unsub.txt
+++ b/templates/zh_CN/unsub.txt
@@ -1,18 +1,18 @@
-˶ʼб %(listname)s ȷ֪ͨ
+退订邮件列表 %(listname)s 的确认通知
-ǽյһҪַ"%(email)s"ʼб %(listaddr)s Ƴ
- %(remote)s Ϊȷȷʵ˶бظżֻŵ
-ⲻ䡣߷ҳ
+我们接收到一个要把您的信箱地址,"%(email)s"从邮件列表 %(listaddr)s 移除
+的请求 %(remote)s 。为了确认您确实想退订此列表,请回复此信件,保持回信的
+主题不变。或者访问下面的网页:
%(confirmurl)s
- %(requestaddr)s һһϢż:
+或者向 %(requestaddr)s 发送一封仅包含下面一行信息的信件:
confirm %(cookie)s
-ע⣬ԴʼĶ˵򵥵ķһԴżĻظͿˣ
-ΪһᱣֻظżΪȷʽ(жı"Re:"û
-ϵ)
+注意,对大多数的邮件阅读器来说,简单的发送一封对此信件的回复就可以了,因
+为这样一般会保持回复信件的主题为正确的形式(主题中有多余的文本"Re:"是没关
+系的)。
-˶ʼб򵥵ĺԴżΪij˶Ҫ
-бƳκ⣬Ƿ͸ %(listadmin)s
+如果您并不想退订此邮件列表,请简单的忽略此信件。如果您认为是某人恶意的要
+将您从列表中移除,或者有其它的任何问题,请把他们发送给 %(listadmin)s 。