diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..935691ca
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,84 @@
+mailman.po~
+Mailman/Archiver/Makefile
+Mailman/Bouncers/Makefile
+Mailman/Cgi/Makefile
+Mailman/Commands/Makefile
+Mailman/Defaults.py
+Mailman/Gui/Makefile
+Mailman/Handlers/Makefile
+Mailman/Logging/Makefile
+Mailman/MTA/Makefile
+Mailman/Makefile
+Mailman/Queue/Makefile
+Mailman/__pycache__/
+Mailman/mm_cfg.py.dist
+Makefile
+bin/Makefile
+build/
+config.log
+config.status
+cron/Makefile
+cron/crontab.in
+messages/Makefile
+messages/ar/LC_MESSAGES/mailman.mo
+messages/ast/LC_MESSAGES/mailman.mo
+messages/ca/LC_MESSAGES/mailman.mo
+messages/cs/LC_MESSAGES/mailman.mo
+messages/da/LC_MESSAGES/mailman.mo
+messages/de/LC_MESSAGES/mailman.mo
+messages/el/LC_MESSAGES/mailman.mo
+messages/eo/LC_MESSAGES/mailman.mo
+messages/es/LC_MESSAGES/mailman.mo
+messages/et/LC_MESSAGES/mailman.mo
+messages/eu/LC_MESSAGES/mailman.mo
+messages/fa/LC_MESSAGES/mailman.mo
+messages/fi/LC_MESSAGES/mailman.mo
+messages/fr/LC_MESSAGES/mailman.mo
+messages/gl/LC_MESSAGES/mailman.mo
+messages/he/LC_MESSAGES/mailman.mo
+messages/hr/LC_MESSAGES/mailman.mo
+messages/hu/LC_MESSAGES/mailman.mo
+messages/ia/LC_MESSAGES/mailman.mo
+messages/it/LC_MESSAGES/mailman.mo
+messages/ja/LC_MESSAGES/mailman.mo
+messages/ko/LC_MESSAGES/mailman.mo
+messages/lt/LC_MESSAGES/mailman.mo
+messages/nl/LC_MESSAGES/mailman.mo
+messages/no/LC_MESSAGES/mailman.mo
+messages/pl/LC_MESSAGES/mailman.mo
+messages/pt/LC_MESSAGES/mailman.mo
+messages/pt_BR/LC_MESSAGES/mailman.mo
+messages/ro/LC_MESSAGES/mailman.mo
+messages/ru/LC_MESSAGES/mailman.mo
+messages/sk/LC_MESSAGES/mailman.mo
+messages/sl/LC_MESSAGES/mailman.mo
+messages/sr/LC_MESSAGES/mailman.mo
+messages/sv/LC_MESSAGES/mailman.mo
+messages/tr/LC_MESSAGES/mailman.mo
+messages/uk/LC_MESSAGES/mailman.mo
+messages/vi/LC_MESSAGES/mailman.mo
+messages/zh_CN/LC_MESSAGES/mailman.mo
+messages/zh_TW/LC_MESSAGES/mailman.mo
+misc/Makefile
+misc/mailman
+misc/paths.py
+scripts/Makefile
+src/Makefile
+src/admin
+src/admindb
+src/common.o
+src/confirm
+src/create
+src/edithtml
+src/listinfo
+src/mailman
+src/options
+src/private
+src/rmlist
+src/roster
+src/subscribe
+src/vsnprintf.o
+templates/Makefile
+tests/Makefile
+tests/bounces/Makefile
+tests/msgs/Makefile
diff --git a/Mailman/Archiver/Archiver.py b/Mailman/Archiver/Archiver.py
index a94246c2..471b551e 100644
--- a/Mailman/Archiver/Archiver.py
+++ b/Mailman/Archiver/Archiver.py
@@ -29,7 +29,7 @@
import errno
import traceback
import re
-from io import StringIO
+import tempfile
from Mailman import mm_cfg
from Mailman import Mailbox
@@ -150,7 +150,7 @@ def __archive_file(self, afn):
"""Open (creating, if necessary) the named archive file."""
omask = os.umask(0o002)
try:
- return Mailbox.Mailbox(open(afn, 'a+'))
+ return Mailbox.Mailbox(open(afn, 'a+b'))
finally:
os.umask(omask)
@@ -162,9 +162,11 @@ def __archive_to_mbox(self, post):
"""Retain a text copy of the message in an mbox file."""
try:
afn = self.ArchiveFileName()
+ syslog('debug', 'Archiver: Writing to mbox file: %s', afn)
mbox = self.__archive_file(afn)
mbox.AppendMessage(post)
- mbox.fp.close()
+ mbox.close()
+ syslog('debug', 'Archiver: Successfully wrote message to mbox file: %s', afn)
except IOError as msg:
syslog('error', 'Archive file access failure:\n\t%s %s', afn, msg)
raise
@@ -186,32 +188,56 @@ def ExternalArchive(self, ar, txt):
#
def ArchiveMail(self, msg):
"""Store postings in mbox and/or pipermail archive, depending."""
+ from Mailman.Logging.Syslog import syslog
+ syslog('debug', 'Archiver: Starting ArchiveMail for list %s', self.internal_name())
+
# Fork so archival errors won't disrupt normal list delivery
if mm_cfg.ARCHIVE_TO_MBOX == -1:
+ syslog('debug', 'Archiver: ARCHIVE_TO_MBOX is -1, archiving disabled')
return
+
+ syslog('debug', 'Archiver: ARCHIVE_TO_MBOX = %s', mm_cfg.ARCHIVE_TO_MBOX)
#
# We don't need an extra archiver lock here because we know the list
# itself must be locked.
if mm_cfg.ARCHIVE_TO_MBOX in (1, 2):
+ syslog('debug', 'Archiver: Writing to mbox archive')
self.__archive_to_mbox(msg)
if mm_cfg.ARCHIVE_TO_MBOX == 1:
# Archive to mbox only.
+ syslog('debug', 'Archiver: ARCHIVE_TO_MBOX = 1, mbox only, returning')
return
- txt = str(msg)
+
+ txt = msg.as_string()
+ unixfrom = msg.get_unixfrom()
+ # Handle case where unixfrom is None (Python 3 compatibility)
+ if unixfrom and not txt.startswith(unixfrom):
+ txt = unixfrom + '\n' + txt
+
# should we use the internal or external archiver?
private_p = self.archive_private
+ syslog('debug', 'Archiver: archive_private = %s', private_p)
+
if mm_cfg.PUBLIC_EXTERNAL_ARCHIVER and not private_p:
+ syslog('debug', 'Archiver: Using public external archiver')
self.ExternalArchive(mm_cfg.PUBLIC_EXTERNAL_ARCHIVER, txt)
elif mm_cfg.PRIVATE_EXTERNAL_ARCHIVER and private_p:
+ syslog('debug', 'Archiver: Using private external archiver')
self.ExternalArchive(mm_cfg.PRIVATE_EXTERNAL_ARCHIVER, txt)
else:
# use the internal archiver
- f = StringIO(txt)
+ syslog('debug', 'Archiver: Using internal HyperArch archiver')
+ f = tempfile.NamedTemporaryFile()
+ if isinstance(txt, str):
+ txt = txt.encode('utf-8')
+ f.write(txt)
+ f.flush()
from . import HyperArch
h = HyperArch.HyperArchive(self)
h.processUnixMailbox(f)
h.close()
f.close()
+ syslog('debug', 'Archiver: Completed internal archiving')
#
# called from MailList.MailList.Save()
diff --git a/Mailman/Archiver/HyperArch.py b/Mailman/Archiver/HyperArch.py
index b5459dbf..f88432b6 100644
--- a/Mailman/Archiver/HyperArch.py
+++ b/Mailman/Archiver/HyperArch.py
@@ -41,6 +41,7 @@
from email.header import decode_header, make_header
from email.errors import HeaderParseError
from email.charset import Charset
+from functools import cmp_to_key
from Mailman import mm_cfg
from Mailman import Utils
@@ -94,7 +95,7 @@ def html_quote(s, lang=None):
('"', '"'))
for thing, repl in repls:
s = s.replace(thing, repl)
- return Utils.uncanonstr(s, lang)
+ return s
def url_quote(s):
@@ -136,7 +137,7 @@ def CGIescape(arg, lang=None):
s = Utils.websafe(arg)
else:
s = Utils.websafe(str(arg))
- return Utils.uncanonstr(s.replace('"', '"'), lang)
+ return s.replace('"', '"')
# Parenthesized human name
paren_name_pat = re.compile(r'([(].*[)])')
@@ -223,7 +224,7 @@ def quick_maketext(templatefile, dict=None, lang=None, mlist=None):
syslog('error', 'broken template: %s\n%s', filepath, e)
# Make sure the text is in the given character set, or html-ify any bogus
# characters.
- return Utils.uncanonstr(text, lang)
+ return text
@@ -298,7 +299,7 @@ def __init__(self, message=None, sequence=0, keepHeaders=[],
cset_out = Charset(cset).output_charset or cset
if isinstance(cset_out, str):
# email 3.0.1 (python 2.4) doesn't like unicode
- cset_out = cset_out.encode('us-ascii')
+ cset_out = cset_out.encode('us-ascii', 'replace')
charset = message.get_content_charset(cset_out)
if charset:
charset = charset.lower().strip()
@@ -311,12 +312,17 @@ def __init__(self, message=None, sequence=0, keepHeaders=[],
except binascii.Error:
body = None
if body and charset != Utils.GetCharSet(self._lang):
+ if isinstance(charset, bytes):
+ charset = charset.decode('utf-8', 'replace')
# decode body
try:
- body = str(body, charset)
+ body = body.decode(charset)
except (UnicodeError, LookupError):
body = None
if body:
+ # Handle both bytes and strings properly
+ if isinstance(body, bytes):
+ body = body.decode('utf-8', 'replace')
self.body = [l + "\n" for l in body.splitlines()]
self.decode_headers()
@@ -414,9 +420,9 @@ def decode_headers(self):
otrans = i18n.get_translation()
try:
i18n.set_language(self._lang)
- atmark = str(_(' at '), Utils.GetCharSet(self._lang))
+ atmark = _(' at ')
subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
- '\g<1>' + atmark + '\g<2>', subject)
+ r'\g<1>' + atmark + r'\g<2>', subject)
finally:
i18n.set_translation(otrans)
self.decoded['subject'] = subject
@@ -429,14 +435,14 @@ def strip_subject(self, subject):
if prefix:
prefix_pat = re.escape(prefix)
prefix_pat = '%'.join(prefix_pat.split(r'\%'))
- prefix_pat = re.sub(r'%\d*d', r'\s*\d+\s*', prefix_pat)
+ prefix_pat = re.sub(r'%\d*d', r'\\\\s*\\\\d+\\\\s*', prefix_pat)
subject = re.sub(prefix_pat, '', subject)
subject = subject.lstrip()
# MAS Should we strip FW and FWD too?
- strip_pat = re.compile('^((RE|AW|SV|VS)(\[\d+\])?:\s*)+', re.I)
+ strip_pat = re.compile(r'^((RE|AW|SV|VS)(\[\d+\])?:\s*)+', re.I)
stripped = strip_pat.sub('', subject)
# Also remove whitespace to avoid folding/unfolding differences
- stripped = re.sub('\s', '', stripped)
+ stripped = re.sub(r'\s', '', stripped)
return stripped
def decode_charset(self, field):
@@ -444,7 +450,7 @@ def decode_charset(self, field):
# Convert 'field' into Unicode one line string.
try:
pairs = decode_header(field)
- ustr = make_header(pairs).__unicode__()
+ ustr = make_header(pairs).__str__()
except (LookupError, UnicodeError, ValueError, HeaderParseError):
# assume list's language
cset = Utils.GetCharSet(self._mlist.preferred_language)
@@ -519,8 +525,8 @@ def _get_subject_enc(self, art):
def _get_next(self):
"""Return the href and subject for the previous message"""
- if self.__next__:
- subject = self._get_subject_enc(self.__next__)
+ if hasattr( self, 'next' ) and self.next is not None:
+ subject = self._get_subject_enc(self.next)
next = (''
% (url_quote(self.next.filename)))
next_wsubj = ('
' + _('Next message (by thread):') +
@@ -540,6 +546,7 @@ def _get_body(self):
body = self.html_body
except AttributeError:
body = self.body
+
return null_to_space(EMPTYSTRING.join(body))
def _add_decoded(self, d):
@@ -581,13 +588,14 @@ def as_text(self):
otrans = i18n.get_translation()
try:
i18n.set_language(self._lang)
- atmark = str(_(' at '), cset)
+ atmark = _(' at ')
+ if isinstance(atmark, bytes):
+ atmark = str(atmark, cset)
body = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
- '\g<1>' + atmark + '\g<2>', body)
+ r'\g<1>' + atmark + r'\g<2>', body)
finally:
i18n.set_translation(otrans)
- # Return body to character set of article.
- body = body.encode(cset, 'replace')
+
return NL.join(headers) % d + '\n\n' + body + '\n'
def _set_date(self, message):
@@ -870,7 +878,7 @@ def processListArch(self):
#if the working file is still here, the archiver may have
# crashed during archiving. Save it, log an error, and move on.
try:
- wf = open(wname)
+ wf = open(wname, 'r')
syslog('error',
'Archive working file %s present. '
'Check %s for possibly unarchived msgs',
@@ -890,7 +898,7 @@ def processListArch(self):
except IOError:
pass
os.rename(name,wname)
- archfile = open(wname)
+ archfile = open(wname, 'r')
self.processUnixMailbox(archfile)
archfile.close()
os.unlink(wname)
@@ -1017,7 +1025,7 @@ def sf(a, b):
else:
return 0
if self.ARCHIVE_PERIOD in ('month','year','quarter'):
- self.archives.sort(sf)
+ self.archives.sort(key = cmp_to_key(sf))
else:
self.archives.sort()
self.archives.reverse()
@@ -1034,7 +1042,7 @@ def open_new_archive(self, archive, archivedir):
index_html = os.path.join(archivedir, 'index.html')
try:
os.unlink(index_html)
- except:
+ except (OSError, IOError):
pass
os.symlink(self.DEFAULTINDEX+'.html',index_html)
@@ -1139,7 +1147,7 @@ def update_archive(self, archive):
oldgzip = os.path.join(self.basedir, '%s.old.txt.gz' % archive)
try:
# open the plain text file
- archt = open(txtfile)
+ archt = open(txtfile, 'r')
except IOError:
return
try:
@@ -1185,8 +1193,6 @@ def __processbody_URLquote(self, lines):
# 3. make it faster
# TK: Prepare for unicode obscure.
atmark = _(' at ')
- if lines and isinstance(lines[0], str):
- atmark = str(atmark, Utils.GetCharSet(self.lang), 'replace')
source = lines[:]
dest = lines
last_line_was_quoted = 0
@@ -1250,6 +1256,8 @@ def __processbody_URLquote(self, lines):
kr = urlpat.search(L)
if jr is None and kr is None:
L = CGIescape(L, self.lang)
+ if isinstance(L, bytes):
+ L = L.decode('utf-8')
L = prefix + L2 + L + suffix
source[i] = None
dest[i] = L
diff --git a/Mailman/Archiver/HyperDatabase.py b/Mailman/Archiver/HyperDatabase.py
index ddf4d62f..b46eb362 100644
--- a/Mailman/Archiver/HyperDatabase.py
+++ b/Mailman/Archiver/HyperDatabase.py
@@ -30,6 +30,7 @@
#
from . import pipermail
from Mailman import LockFile
+from Mailman import Utils
CACHESIZE = pipermail.CACHESIZE
@@ -68,10 +69,21 @@ def __repr__(self):
def __sort(self, dirty=None):
if self.__dirty == 1 or dirty:
- self.sorted = list(self.dict.keys())
- self.sorted.sort()
+ self.sorted = self.__fix_for_sort(list(self.dict.keys()))
+ if hasattr(self.sorted, 'sort'):
+ self.sorted.sort()
self.__dirty = 0
+ def __fix_for_sort(self, items):
+ if isinstance(items, bytes):
+ return items.decode()
+ elif isinstance(items, list):
+ return [ self.__fix_for_sort(item) for item in items ]
+ elif isinstance(items, tuple):
+ return tuple( self.__fix_for_sort(item) for item in items )
+ else:
+ return items
+
def lock(self):
self.lockfile.lock()
@@ -169,7 +181,7 @@ def __len__(self):
def load(self):
try:
- fp = open(self.path)
+ fp = open(self.path, mode='rb')
try:
self.dict = marshal.load(fp)
finally:
@@ -185,7 +197,7 @@ def load(self):
def close(self):
omask = os.umask(0o007)
try:
- fp = open(self.path, 'w')
+ fp = open(self.path, 'wb')
finally:
os.umask(omask)
fp.write(marshal.dumps(self.dict))
@@ -275,7 +287,7 @@ def close(self):
def hasArticle(self, archive, msgid):
self.__openIndices(archive)
- return msgid in self.articleIndex
+ return self.articleIndex.has_key(msgid)
def setThreadKey(self, archive, key, msgid):
self.__openIndices(archive)
@@ -286,7 +298,7 @@ def getArticle(self, archive, msgid):
if msgid not in self.__cache:
# get the pickled object out of the DumbBTree
buf = self.articleIndex[msgid]
- article = self.__cache[msgid] = pickle.loads(buf, fix_imports=True, encoding='latin1')
+ article = self.__cache[msgid] = Utils.load_pickle(buf)
# For upgrading older archives
article.setListIfUnset(self._mlist)
else:
diff --git a/Mailman/Archiver/pipermail.py b/Mailman/Archiver/pipermail.py
index 2dfd7fd3..bd1e8df9 100644
--- a/Mailman/Archiver/pipermail.py
+++ b/Mailman/Archiver/pipermail.py
@@ -1,5 +1,6 @@
-#! /usr/bin/env python
+#! /usr/bin/python3
+import errno
import mailbox
import os
import re
@@ -8,10 +9,7 @@
from email.utils import parseaddr, parsedate_tz, mktime_tz, formatdate
import pickle
from io import StringIO
-
-# Work around for some misguided Python packages that add iso-8859-1
-# accented characters to string.lowercase.
-lowercase = lowercase[:26]
+from string import ascii_lowercase as lowercase
__version__ = '0.09 (Mailman edition)'
VERSION = __version__
@@ -19,6 +17,7 @@
from Mailman import mm_cfg
from Mailman import Errors
+from Mailman import Utils
from Mailman.Mailbox import ArchiverMailbox
from Mailman.Logging.Syslog import syslog
from Mailman.i18n import _, C_
@@ -220,8 +219,9 @@ def __init__(self, message = None, sequence = 0, keepHeaders = []):
self.headers[i] = message[i]
# Read the message body
- s = StringIO(message.get_payload(decode=True)\
- or message.as_string().split('\n\n',1)[1])
+ msg = message.get_payload()\
+ or message.as_string().split('\n\n',1)[1]
+ s = StringIO(msg)
self.body = s.readlines()
def _set_date(self, message):
@@ -284,10 +284,9 @@ def __init__(self, basedir = None, reload = 1, database = None):
# message in the HTML archive now -- Marc
try:
os.stat(self.basedir)
- except os.error as errdata:
- errno, errmsg = errdata
- if errno != 2:
- raise os.error(errdata)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
else:
self.message(C_('Creating archive directory ') + self.basedir)
omask = os.umask(0)
@@ -300,10 +299,10 @@ def __init__(self, basedir = None, reload = 1, database = None):
try:
if not reload:
raise IOError
- f = open(os.path.join(self.basedir, 'pipermail.pck'), 'r')
+ d = Utils.load_pickle(os.path.join(self.basedir, 'pipermail.pck'))
+ if not d:
+ raise IOError("Pickled data is empty or None")
self.message(C_('Reloading pickled archive state'))
- d = pickle.load(f, fix_imports=True, encoding='latin1')
- f.close()
for key, value in list(d.items()):
setattr(self, key, value)
except (IOError, EOFError):
@@ -335,7 +334,7 @@ def close(self):
omask = os.umask(0o007)
try:
- f = open(os.path.join(self.basedir, 'pipermail.pck'), 'w')
+ f = open(os.path.join(self.basedir, 'pipermail.pck'), 'wb')
finally:
os.umask(omask)
pickle.dump(self.getstate(), f)
@@ -377,7 +376,7 @@ def __findParent(self, article, children = []):
parentID = article.in_reply_to
elif article.references:
# Remove article IDs that aren't in the archive
- refs = list(filter(self.articleIndex.has_key, article.references))
+ refs = list(filter(lambda x: x in self.articleIndex, article.references))
if not refs:
return None
maxdate = self.database.getArticle(self.archive,
@@ -526,7 +525,7 @@ def _open_index_file_as_stdout(self, arcdir, index_name):
path = os.path.join(arcdir, index_name + self.INDEX_EXT)
omask = os.umask(0o002)
try:
- self.__f = open(path, 'w')
+ self.__f = open(path, 'w', encoding='utf-8')
finally:
os.umask(omask)
self.__stdout = sys.stdout
@@ -552,7 +551,8 @@ def _makeArticle(self, msg, sequence):
return Article(msg, sequence)
def processUnixMailbox(self, input, start=None, end=None):
- mbox = ArchiverMailbox(input, self.maillist)
+ mbox = ArchiverMailbox(input.name, self.maillist)
+ mbox_iterator = iter(mbox.values())
if start is None:
start = 0
counter = 0
@@ -560,7 +560,7 @@ def processUnixMailbox(self, input, start=None, end=None):
mbox.skipping(True)
while counter < start:
try:
- m = next(mbox)
+ m = next(mbox_iterator, None)
except Errors.DiscardMessage:
continue
if m is None:
@@ -571,7 +571,7 @@ def processUnixMailbox(self, input, start=None, end=None):
while 1:
try:
pos = input.tell()
- m = next(mbox)
+ m = next(mbox_iterator, None)
except Errors.DiscardMessage:
continue
except Exception:
@@ -599,16 +599,15 @@ def new_archive(self, archive, archivedir):
# If the archive directory doesn't exist, create it
try:
os.stat(archivedir)
- except os.error as errdata:
- errno, errmsg = errdata
- if errno == 2:
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ else:
omask = os.umask(0)
try:
os.mkdir(archivedir, self.DIRMODE)
finally:
os.umask(omask)
- else:
- raise os.error(errdata)
self.open_new_archive(archive, archivedir)
def add_article(self, article):
@@ -688,7 +687,7 @@ def get_parent_info(self, archive, article):
def write_article(self, index, article, path):
omask = os.umask(0o002)
try:
- f = open(path, 'w')
+ f = open(path, 'w', encoding='utf-8')
finally:
os.umask(omask)
temp_stdout, sys.stdout = sys.stdout, f
diff --git a/Mailman/Bouncers/Caiwireless.py b/Mailman/Bouncers/Caiwireless.py
index 0d436507..4eb55509 100644
--- a/Mailman/Bouncers/Caiwireless.py
+++ b/Mailman/Bouncers/Caiwireless.py
@@ -18,6 +18,7 @@
import re
import email
+import email.iterators
from io import StringIO
tcre = re.compile(r'the following recipients did not receive this message:',
@@ -34,7 +35,7 @@ def process(msg):
# 1 == tag line seen
state = 0
# This format thinks it's a MIME, but it really isn't
- for line in email.Iterators.body_line_iterator(msg):
+ for line in email.iterators.body_line_iterator(msg):
line = line.strip()
if state == 0 and tcre.match(line):
state = 1
diff --git a/Mailman/Bouncers/Compuserve.py b/Mailman/Bouncers/Compuserve.py
index 0a94b00c..be83bddc 100644
--- a/Mailman/Bouncers/Compuserve.py
+++ b/Mailman/Bouncers/Compuserve.py
@@ -18,6 +18,7 @@
import re
import email
+import email.iterators
dcre = re.compile(r'your message could not be delivered', re.IGNORECASE)
acre = re.compile(r'Invalid receiver address: (?P.*)')
@@ -30,7 +31,7 @@ def process(msg):
# 1 = intro line seen
state = 0
addrs = []
- for line in email.Iterators.body_line_iterator(msg):
+ for line in email.iterators.body_line_iterator(msg):
if state == 0:
mo = dcre.search(line)
if mo:
diff --git a/Mailman/Bouncers/Exchange.py b/Mailman/Bouncers/Exchange.py
index 917c5146..273c8947 100644
--- a/Mailman/Bouncers/Exchange.py
+++ b/Mailman/Bouncers/Exchange.py
@@ -17,7 +17,7 @@
"""Recognizes (some) Microsoft Exchange formats."""
import re
-import email.Iterators
+import email.iterators
scre = re.compile('did not reach the following recipient')
ecre = re.compile('MSEXCH:')
@@ -28,7 +28,7 @@
def process(msg):
addrs = {}
- it = email.Iterators.body_line_iterator(msg)
+ it = email.iterators.body_line_iterator(msg)
# Find the start line
for line in it:
if scre.search(line):
diff --git a/Mailman/Bouncers/GroupWise.py b/Mailman/Bouncers/GroupWise.py
index fe02bfdd..91521869 100644
--- a/Mailman/Bouncers/GroupWise.py
+++ b/Mailman/Bouncers/GroupWise.py
@@ -22,7 +22,7 @@
"""
import re
-from email.Message import Message
+from email.message import Message
from io import StringIO
acre = re.compile(r'<(?P[^>]*)>')
diff --git a/Mailman/Bouncers/LLNL.py b/Mailman/Bouncers/LLNL.py
index 1e038182..3da78159 100644
--- a/Mailman/Bouncers/LLNL.py
+++ b/Mailman/Bouncers/LLNL.py
@@ -18,13 +18,14 @@
import re
import email
+import email.iterators
acre = re.compile(r',\s*(?P\S+@[^,]+),', re.IGNORECASE)
def process(msg):
- for line in email.Iterators.body_line_iterator(msg):
+ for line in email.iterators.body_line_iterator(msg):
mo = acre.search(line)
if mo:
return [mo.group('addr')]
diff --git a/Mailman/Bouncers/Microsoft.py b/Mailman/Bouncers/Microsoft.py
index 4b047886..09ec9384 100644
--- a/Mailman/Bouncers/Microsoft.py
+++ b/Mailman/Bouncers/Microsoft.py
@@ -33,7 +33,7 @@ def process(msg):
# The message *looked* like a multipart but wasn't
return None
data = subpart.get_payload()
- if isinstance(data, ListType):
+ if isinstance(data, list):
# The message is a multi-multipart, so not a matching bounce
return None
body = StringIO(data)
diff --git a/Mailman/Bouncers/Qmail.py b/Mailman/Bouncers/Qmail.py
index a22771b5..5d4f2157 100644
--- a/Mailman/Bouncers/Qmail.py
+++ b/Mailman/Bouncers/Qmail.py
@@ -27,7 +27,7 @@
"""
import re
-import email.Iterators
+import email.iterators
# Other (non-standard?) intros have been observed in the wild.
introtags = [
@@ -50,7 +50,7 @@ def process(msg):
# 1 = intro paragraph seen
# 2 = recip paragraphs seen
state = 0
- for line in email.Iterators.body_line_iterator(msg):
+ for line in email.iterators.body_line_iterator(msg):
line = line.strip()
if state == 0:
for introtag in introtags:
diff --git a/Mailman/Bouncers/SMTP32.py b/Mailman/Bouncers/SMTP32.py
index c91b294e..b21a90ee 100644
--- a/Mailman/Bouncers/SMTP32.py
+++ b/Mailman/Bouncers/SMTP32.py
@@ -30,6 +30,7 @@
import re
import email
+import email.iterators
ecre = re.compile('original message follows', re.IGNORECASE)
acre = re.compile(r'''
@@ -51,7 +52,7 @@ def process(msg):
if not mailer.startswith('[^>]*)>')),
+ _c(r'rcpt to:\s*<(?P[^>]*)>')),
# s1.com (InterScan E-Mail VirusWall NT ???)
(_c('message from interscan e-mail viruswall nt'),
_c('end of message'),
- _c('rcpt to:\s*<(?P[^>]*)>')),
+ _c(r'rcpt to:\s*<(?P[^>]*)>')),
# Smail
(_c('failed addresses follow:'),
_c('message text follows:'),
@@ -65,15 +65,15 @@ def _c(pattern):
# turbosport.com runs something called `MDaemon 3.5.2' ???
(_c('The following addresses did NOT receive a copy of your message:'),
_c('--- Session Transcript ---'),
- _c('[>]\s*(?P.*)$')),
+ _c(r'[>]\s*(?P.*)$')),
# usa.net
- (_c('Intended recipient:\s*(?P.*)$'),
+ (_c(r'Intended recipient:\s*(?P.*)$'),
_c('--------RETURNED MAIL FOLLOWS--------'),
- _c('Intended recipient:\s*(?P.*)$')),
+ _c(r'Intended recipient:\s*(?P.*)$')),
# hotpop.com
- (_c('Undeliverable Address:\s*(?P.*)$'),
+ (_c(r'Undeliverable Address:\s*(?P.*)$'),
_c('Original message attached'),
- _c('Undeliverable Address:\s*(?P.*)$')),
+ _c(r'Undeliverable Address:\s*(?P.*)$')),
# Another demon.co.uk format
(_c('This message was created automatically by mail delivery'),
_c('^---- START OF RETURNED MESSAGE ----'),
@@ -81,19 +81,19 @@ def _c(pattern):
# Prodigy.net full mailbox
(_c("User's mailbox is full:"),
_c('Unable to deliver mail.'),
- _c("User's mailbox is full:\s*<(?P[^>]*)>")),
+ _c(r"User's mailbox is full:\s*<(?P[^>]*)>")),
# Microsoft SMTPSVC
(_c('The email below could not be delivered to the following user:'),
_c('Old message:'),
_c('<(?P[^>]*)>')),
# Yahoo on behalf of other domains like sbcglobal.net
- (_c('Unable to deliver message to the following address\(es\)\.'),
- _c('--- Original message follows\.'),
+ (_c(r'Unable to deliver message to the following address\(es\)\.'),
+ _c(r'--- Original message follows\.'),
_c('<(?P[^>]*)>:')),
# googlemail.com
(_c('Delivery to the following recipient(s)? failed'),
_c('----- Original message -----'),
- _c('^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
# kundenserver.de, mxlogic.net
(_c('A message that you( have)? sent could not be delivered'),
_c('^---'),
@@ -101,18 +101,18 @@ def _c(pattern):
# another kundenserver.de
(_c('A message that you( have)? sent could not be delivered'),
_c('^---'),
- _c('^(?P[^\s@]+@[^\s@:]+):')),
+ _c(r'^(?P[^\s@]+@[^\s@:]+):')),
# thehartford.com and amenworld.com
(_c('Del(i|e)very to the following recipient(s)? (failed|was aborted)'),
# this one may or may not have the original message, but there's nothing
# unique to stop on, so stop on the first line of at least 3 characters
# that doesn't start with 'D' (to not stop immediately) and has no '@'.
_c('^[^D][^@]{2,}$'),
- _c('^\s*(. )?(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^\s*(. )?(?P[^\s@]+@[^\s@]+)\s*$')),
# and another thehartfod.com/hartfordlife.com
- (_c('^Your message\s*$'),
+ (_c(r'^Your message\s*$'),
_c('^because:'),
- _c('^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
# kviv.be (InterScan NT)
(_c('^Unable to deliver message to'),
_c(r'\*+\s+End of message\s+\*+'),
@@ -120,15 +120,15 @@ def _c(pattern):
# earthlink.net supported domains
(_c('^Sorry, unable to deliver your message to'),
_c('^A copy of the original message'),
- _c('\s*(?P[^\s@]+@[^\s@]+)\s+')),
+ _c(r'\s*(?P[^\s@]+@[^\s@]+)\s+')),
# ademe.fr
(_c('^A message could not be delivered to:'),
_c('^Subject:'),
- _c('^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
# andrew.ac.jp
(_c('^Invalid final delivery userid:'),
_c('^Original message follows.'),
- _c('\s*(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'\s*(?P[^\s@]+@[^\s@]+)\s*$')),
# E500_SMTP_Mail_Service@lerctr.org and similar
(_c('---- Failed Recipients ----'),
_c(' Mail ----'),
@@ -136,65 +136,65 @@ def _c(pattern):
# cynergycom.net
(_c('A message that you sent could not be delivered'),
_c('^---'),
- _c('(?P[^\s@]+@[^\s@)]+)')),
+ _c(r'(?P[^\s@]+@[^\s@)]+)')),
# LSMTP for Windows
- (_c('^--> Error description:\s*$'),
+ (_c(r'^--> Error description:\s*$'),
_c('^Error-End:'),
- _c('^Error-for:\s+(?P[^\s@]+@[^\s@]+)')),
+ _c(r'^Error-for:\s+(?P[^\s@]+@[^\s@]+)')),
# Qmail with a tri-language intro beginning in spanish
(_c('Your message could not be delivered'),
_c('^-'),
_c('<(?P[^>]*)>:')),
# socgen.com
(_c('Your message could not be delivered to'),
- _c('^\s*$'),
- _c('(?P[^\s@]+@[^\s@]+)')),
+ _c(r'^\s*$'),
+ _c(r'(?P[^\s@]+@[^\s@]+)')),
# dadoservice.it
(_c('Your message has encountered delivery problems'),
_c('Your message reads'),
- _c('addressed to\s*(?P[^\s@]+@[^\s@)]+)')),
+ _c(r'addressed to\s*(?P[^\s@]+@[^\s@)]+)')),
# gomaps.com
(_c('Did not reach the following recipient'),
- _c('^\s*$'),
- _c('\s(?P[^\s@]+@[^\s@]+)')),
+ _c(r'^\s*$'),
+ _c(r'\s(?P[^\s@]+@[^\s@]+)')),
# EYOU MTA SYSTEM
(_c('This is the deliver program at'),
_c('^-'),
- _c('^(?P[^\s@]+@[^\s@<>]+)')),
+ _c(r'^(?P[^\s@]+@[^\s@<>]+)')),
# A non-standard qmail at ieo.it
(_c('this is the email server at'),
_c('^-'),
- _c('\s(?P[^\s@]+@[^\s@]+)[\s,]')),
+ _c(r'\s(?P[^\s@]+@[^\s@]+)[\s,]')),
# pla.net.py (MDaemon.PRO ?)
(_c('- no such user here'),
_c('There is no user'),
- _c('^(?P[^\s@]+@[^\s@]+)\s')),
+ _c(r'^(?P[^\s@]+@[^\s@]+)\s')),
# fastdnsservers.com
(_c('The following recipient.*could not be reached'),
_c('bogus stop pattern'),
- _c('^(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^(?P[^\s@]+@[^\s@]+)\s*$')),
# lttf.com
(_c('Could not deliver message to'),
- _c('^\s*--'),
- _c('^Failed Recipient:\s*(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^\s*--'),
+ _c(r'^Failed Recipient:\s*(?P[^\s@]+@[^\s@]+)\s*$')),
# uci.edu
(_c('--------Message not delivered'),
_c('--------Error Detail'),
- _c('^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
+ _c(r'^\s*(?P[^\s@]+@[^\s@]+)\s*$')),
# Dovecot LDA Over quota MDN (bogus - should be DSN).
(_c('^Your message'),
_c('^Reporting'),
_c(
- 'Your message to (?P[^\s@]+@[^\s@]+) was automatically rejected'
+ r'Your message to (?P[^\s@]+@[^\s@]+) was automatically rejected'
)),
# mail.ru
(_c('A message that you sent was rejected'),
_c('This is a copy of your message'),
- _c('\s(?P[^\s@]+@[^\s@]+)')),
+ _c(r'\s(?P[^\s@]+@[^\s@]+)')),
# MailEnable
(_c('Message could not be delivered to some recipients.'),
_c('Message headers follow'),
- _c('Recipient: \[SMTP:(?P[^\s@]+@[^\s@]+)\]')),
+ _c(r'Recipient: \[SMTP:(?P[^\s@]+@[^\s@]+)\]')),
# This one is from Yahoo but dosen't fit the yahoo recognizer format
(_c(r'wasn\'t able to deliver the following message'),
_c(r'---Below this line is a copy of the message.'),
@@ -224,7 +224,7 @@ def process(msg, patterns=None):
# we process the message multiple times anyway.
for scre, ecre, acre in patterns:
state = 0
- for line in email.Iterators.body_line_iterator(msg, decode=True):
+ for line in email.iterators.body_line_iterator(msg, decode=True):
if state == 0:
if scre.search(line):
state = 1
diff --git a/Mailman/Bouncers/SimpleWarning.py b/Mailman/Bouncers/SimpleWarning.py
index e51e5931..27970640 100644
--- a/Mailman/Bouncers/SimpleWarning.py
+++ b/Mailman/Bouncers/SimpleWarning.py
@@ -18,6 +18,7 @@
"""Recognizes simple heuristically delimited warnings."""
import email
+import email.iterators
from Mailman.Bouncers.BouncerAPI import Stop
from Mailman.Bouncers.SimpleMatch import _c
@@ -74,7 +75,7 @@ def process(msg):
addrs = {}
for scre, ecre, acre in patterns:
state = 0
- for line in email.Iterators.body_line_iterator(msg, decode=True):
+ for line in email.iterators.body_line_iterator(msg, decode=True):
if state == 0:
if scre.search(line):
state = 1
diff --git a/Mailman/Bouncers/Sina.py b/Mailman/Bouncers/Sina.py
index ced78e9e..223bcdb7 100644
--- a/Mailman/Bouncers/Sina.py
+++ b/Mailman/Bouncers/Sina.py
@@ -18,7 +18,7 @@
from __future__ import print_function
import re
-from email import Iterators
+from email import iterators
acre = re.compile(r'<(?P[^>]*)>')
@@ -41,7 +41,7 @@ def process(msg):
print('out 3')
return []
addrs = {}
- for line in Iterators.body_line_iterator(part):
+ for line in iterators.body_line_iterator(part):
mo = acre.match(line)
if mo:
addrs[mo.group('addr')] = 1
diff --git a/Mailman/Bouncers/Yahoo.py b/Mailman/Bouncers/Yahoo.py
index 3154c331..68e016e7 100644
--- a/Mailman/Bouncers/Yahoo.py
+++ b/Mailman/Bouncers/Yahoo.py
@@ -19,6 +19,7 @@
import re
import email
+import email.iterators
from email.utils import parseaddr
tcre = (re.compile(r'message\s+from\s+yahoo\.\S+', re.IGNORECASE),
@@ -45,7 +46,7 @@ def process(msg):
# 1 == tag line seen
# 2 == end line seen
state = 0
- for line in email.Iterators.body_line_iterator(msg):
+ for line in email.iterators.body_line_iterator(msg):
line = line.strip()
if state == 0:
for cre in tcre:
diff --git a/Mailman/CSRFcheck.py b/Mailman/CSRFcheck.py
index 5b19cadc..23494b50 100644
--- a/Mailman/CSRFcheck.py
+++ b/Mailman/CSRFcheck.py
@@ -41,7 +41,7 @@ def csrf_token(mlist, contexts, user=None):
if user:
# Unmunge a munged email address.
- user = UnobscureEmail(urllib.unquote(user))
+ user = UnobscureEmail(urllib.parse.unquote(user))
for context in contexts:
key, secret = mlist.AuthContextInfo(context, user)
@@ -53,7 +53,8 @@ def csrf_token(mlist, contexts, user=None):
needs_hash = (secret + repr(issued)).encode('utf-8')
mac = sha_new(needs_hash).hexdigest()
keymac = '%s:%s' % (key, mac)
- token = binascii.hexlify(marshal.dumps((issued, keymac)))
+ token = marshal.dumps((issued, keymac)).hex()
+
return token
def csrf_check(mlist, token, cgi_user=None):
@@ -85,7 +86,7 @@ def csrf_check(mlist, token, cgi_user=None):
# This is for CVE-2021-42097. The token is a user token because
# of the fix for CVE-2021-42096 but it must match the user for
# whom the options page is requested.
- raw_user = UnobscureEmail(urllib.unquote(user))
+ raw_user = UnobscureEmail(urllib.parse.unquote(user))
if cgi_user and cgi_user.lower() != raw_user.lower():
syslog('mischief',
'Form for user %s submitted with CSRF token '
@@ -95,7 +96,8 @@ def csrf_check(mlist, token, cgi_user=None):
context = keydict.get(key)
key, secret = mlist.AuthContextInfo(context, user)
assert key
- mac = sha_new(secret + repr(issued)).hexdigest()
+ secret = secret + repr(issued)
+ mac = sha_new(secret.encode()).hexdigest()
if (mac == received_mac
and 0 < time.time() - issued < mm_cfg.FORM_LIFETIME):
return True
diff --git a/Mailman/Cgi/admin.py b/Mailman/Cgi/admin.py
index 9b4cab84..328c4162 100644
--- a/Mailman/Cgi/admin.py
+++ b/Mailman/Cgi/admin.py
@@ -17,15 +17,14 @@
"""Process and produce the list-administration options forms."""
-# For Python 2.1.x compatibility
-from __future__ import nested_scopes
-from __future__ import print_function
+def cmp(a, b):
+ return (a > b) - (a < b)
-from past.builtins import cmp
+#from future.builtins import cmp
import sys
import os
import re
-import cgi
+from Mailman.Utils import FieldStorage
import urllib.request, urllib.parse, urllib.error
import signal
@@ -74,7 +73,7 @@ def main():
safelistname = Utils.websafe(listname)
# Send this with a 404 status.
print('Status: 404 Not Found')
- admin_overview(_('No such list %(safelistname)s'))
+ admin_overview(_(f'No such list {safelistname}'))
syslog('error', 'admin: No such list "%s": %s\n',
listname, e)
return
@@ -82,7 +81,7 @@ def main():
# pages are shown in that list's preferred language.
i18n.set_language(mlist.preferred_language)
# If the user is not authenticated, we're done.
- cgidata = cgi.FieldStorage(keep_blank_values=1)
+ cgidata = FieldStorage(keep_blank_values=1)
try:
cgidata.getfirst('csrf_token', '')
except TypeError:
@@ -158,7 +157,7 @@ def main():
qsenviron = os.environ.get('QUERY_STRING')
parsedqs = None
if qsenviron:
- parsedqs = cgi.parse_qs(qsenviron)
+ parsedqs = urllib.parse.parse_qs(qsenviron)
if 'VARHELP' in cgidata:
varhelp = cgidata.getfirst('VARHELP')
elif parsedqs:
@@ -220,7 +219,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
# Additional sanity checks
if not mlist.digestable and not mlist.nondigestable:
doc.addError(
- _('''You have turned off delivery of both digest and
+ _(f'''You have turned off delivery of both digest and
non-digest messages. This is an incompatible state of
affairs. You must turn on either digest delivery or
non-digest delivery or your mailing list will basically be
@@ -229,14 +228,14 @@ def sigterm_handler(signum, frame, mlist=mlist):
dm = mlist.getDigestMemberKeys()
if not mlist.digestable and dm:
doc.addError(
- _('''You have digest members, but digests are turned
+ _(f'''You have digest members, but digests are turned
off. Those people will not receive mail.
Affected member(s) %(dm)r.'''),
tag=_('Warning: '))
rm = mlist.getRegularMemberKeys()
if not mlist.nondigestable and rm:
doc.addError(
- _('''You have regular list members but non-digestified mail is
+ _(f'''You have regular list members but non-digestified mail is
turned off. They will receive non-digestified mail until you
fix this problem. Affected member(s) %(rm)r.'''),
tag=_('Warning: '))
@@ -261,7 +260,7 @@ def admin_overview(msg=''):
# This page should be displayed in the server's default language, which
# should have already been set.
hostname = Utils.get_domain()
- legend = _('%(hostname)s mailing lists - Admin Links')
+ legend = _(f'{hostname} mailing lists - Admin Links')
# The html `document'
doc = Document()
doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
@@ -303,14 +302,14 @@ def admin_overview(msg=''):
if not advertised:
welcome.extend([
greeting,
- _('''
There currently are no publicly-advertised %(mailmanlink)s
- mailing lists on %(hostname)s.'''),
+ _(f'''
There currently are no publicly-advertised {mailmanlink}
+ mailing lists on {hostname}.'''),
])
else:
welcome.extend([
greeting,
- _('''
Below is the collection of publicly-advertised
- %(mailmanlink)s mailing lists on %(hostname)s. Click on a list
+ _(f'''
Below is the collection of publicly-advertised
+ {mailmanlink} mailing lists on {hostname}. Click on a list
name to visit the configuration pages for that list.'''),
])
@@ -318,10 +317,10 @@ def admin_overview(msg=''):
mailman_owner = Utils.get_site_email()
extra = msg and _('right ') or ''
welcome.extend([
- _('''To visit the administrators configuration page for an
+ _(f'''To visit the administrators configuration page for an
unadvertised list, open a URL similar to this one, but with a '/' and
- the %(extra)slist name appended. If you have the proper authority,
- you can also create a new mailing list.
+ the {extra}list name appended. If you have the proper authority,
+ you can also create a new mailing list.
General list information can be found at '''),
Link(Utils.ScriptURL('listinfo'),
@@ -388,14 +387,14 @@ def option_help(mlist, varhelp):
get_item_characteristics(item)
# Set up the document
realname = mlist.real_name
- legend = _("""%(realname)s Mailing list Configuration Help
- %(varname)s Option""")
+ legend = _(f"""{realname} Mailing list Configuration Help
+ {varname} Option""")
header = Table(width='100%')
header.AddRow([Center(Header(3, legend))])
header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
- doc.SetTitle(_("Mailman %(varname)s List Option Help"))
+ doc.SetTitle(_("Mailman {varname} List Option Help"))
doc.AddItem(header)
doc.AddItem("%s (%s): %s
" % (varname, category, description))
if elaboration:
@@ -413,7 +412,7 @@ def option_help(mlist, varhelp):
form.AddItem(Center(submit_button()))
doc.AddItem(Center(form))
- doc.AddItem(_("""Warning: changing this option here
+ doc.AddItem(_(f"""Warning: changing this option here
could cause other screens to be out-of-sync. Be sure to reload any other
pages that are displaying this option for this mailing list. You can also
"""))
@@ -424,7 +423,7 @@ def option_help(mlist, varhelp):
else:
url = '%s/%s' % (adminurl, category)
categoryname = mlist.GetConfigCategories()[category][0]
- doc.AddItem(Link(url, _('return to the %(categoryname)s options page.')))
+ doc.AddItem(Link(url, _(f'return to the {categoryname} options page.')))
doc.AddItem('')
doc.AddItem(mlist.GetMailmanFooter())
print(doc.Format())
@@ -439,9 +438,9 @@ def show_results(mlist, doc, category, subcat, cgidata):
# Set up the document's headers
realname = mlist.real_name
- doc.SetTitle(_('%(realname)s Administration (%(label)s)'))
+ doc.SetTitle(_(f'{realname} Administration ({label})'))
doc.AddItem(Center(Header(2, _(
- '%(realname)s mailing list administration %(label)s Section'))))
+ f'{realname} mailing list administration {label} Section'))))
doc.AddItem('')
# Now we need to craft the form that will be submitted, which will contain
# all the variable settings, etc. This is a bit of a kludge because we
@@ -536,7 +535,7 @@ def show_results(mlist, doc, category, subcat, cgidata):
form.AddItem(linktable)
form.AddItem('')
form.AddItem(
- _('''Make your changes in the following section, then submit them
+ _(f'''Make your changes in the following section, then submit them
using the Submit Your Changes button below.''')
+ '
')
@@ -560,7 +559,7 @@ def show_results(mlist, doc, category, subcat, cgidata):
# Add a blank separator row
table.AddRow([' ', ' '])
# Add a section to set the moderation bit for all members
- table.AddRow([_("""
Set everyone's moderation bit, including
+ table.AddRow([_(f"""
Set everyone's moderation bit, including
those members not currently visible""")])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
table.AddRow([RadioButtonArray('allmodbit_val',
@@ -661,7 +660,7 @@ def get_item_characteristics(record):
elif len(record) == 6:
varname, kind, params, dependancies, descr, elaboration = record
else:
- raise ValueError('Badly formed options entry:\n %(record)s')
+ raise ValueError(f'Badly formed options entry:\n {record}')
return varname, kind, params, dependancies, descr, elaboration
@@ -863,16 +862,16 @@ def get_item_gui_description(mlist, category, subcat,
else:
varhelp = '/?VARHELP=%s/%s' % (category, varname)
if descr == elaboration:
- linktext = _(' (Edit %(varname)s)')
+ linktext = _(f' (Edit {varname})')
else:
- linktext = _(' (Details for %(varname)s)')
+ linktext = _(f' (Details for {varname})')
link = Link(mlist.GetScriptURL('admin') + varhelp,
linktext).Format()
text = Label('%s %s' % (descr, link)).Format()
else:
text = Label(descr).Format()
if varname[0] == '_':
- text += Label(_(''' Note:
+ text += Label(_(f''' Note:
setting this value performs an immediate action but does not modify
permanent state.''')).Format()
return text
@@ -923,7 +922,7 @@ def membership_options(mlist, subcat, cgidata, doc, form):
link = Link('https://docs.python.org/2/library/re.html'
'#regular-expression-syntax',
_('(help)')).Format()
- table.AddRow([Label(_('Find member %(link)s:')),
+ table.AddRow([Label(_(f'Find member {link}:')),
TextBox('findmember',
value=cgidata.getfirst('findmember', '')),
SubmitButton('findmember_btn', _('Search...'))])
@@ -935,11 +934,12 @@ def membership_options(mlist, subcat, cgidata, doc, form):
chunksz = mlist.admin_member_chunksize
# The email addresses had /better/ be ASCII, but might be encoded in the
# database as Unicodes.
- all = [_m.encode() for _m in mlist.getMembers()]
- all.sort(lambda x, y: cmp(x.lower(), y.lower()))
+ all = mlist.getMembers()
+ all.sort()
# See if the query has a regular expression
regexp = cgidata.getfirst('findmember', '').strip()
try:
+ regexp = regexp.encode()
regexp = regexp.decode(Utils.GetCharSet(mlist.preferred_language))
except UnicodeDecodeError:
# This is probably a non-ascii character and an English language
@@ -977,7 +977,7 @@ def membership_options(mlist, subcat, cgidata, doc, form):
# put into FieldStorage's keys :-(
qsenviron = os.environ.get('QUERY_STRING')
if qsenviron:
- qs = cgi.parse_qs(qsenviron)
+ qs = urllib.parse.parse_qs(qsenviron)
bucket = qs.get('letter', '0')[0].lower()
keys = list(buckets.keys())
keys.sort()
@@ -1007,9 +1007,9 @@ def membership_options(mlist, subcat, cgidata, doc, form):
if bucket:
membercnt = len(members)
usertable.AddRow([Center(Italic(_(
- '%(allcnt)s members total, %(membercnt)s shown')))])
+ f'{allcnt} members total, {membercnt} shown')))])
else:
- usertable.AddRow([Center(Italic(_('%(allcnt)s members total')))])
+ usertable.AddRow([Center(Italic(_(f'{allcnt} members total')))])
usertable.AddCellInfo(usertable.GetCurrentRowIndex(),
usertable.GetCurrentCellIndex(),
colspan=OPTCOLUMNS,
@@ -1022,9 +1022,6 @@ def membership_options(mlist, subcat, cgidata, doc, form):
if regexp:
findfrag = '&findmember=' + urllib.parse.quote(regexp)
url = adminurl + '/members?letter=' + letter + findfrag
- if type(url) is str:
- url = url.encode(Utils.GetCharSet(mlist.preferred_language),
- errors='ignore')
if letter == bucket:
show = Bold('[%s]' % letter.upper()).Format()
else:
@@ -1140,11 +1137,11 @@ def membership_options(mlist, subcat, cgidata, doc, form):
legend.AddItem(
_('unsub -- Click on this to unsubscribe the member.'))
legend.AddItem(
- _("""mod -- The user's personal moderation flag. If this is
+ _(f"""mod -- The user's personal moderation flag. If this is
set, postings from them will be moderated, otherwise they will be
approved."""))
legend.AddItem(
- _("""hide -- Is the member's address concealed on
+ _(f"""hide -- Is the member's address concealed on
the list of subscribers?"""))
legend.AddItem(_(
"""nomail -- Is delivery to the member disabled? If so, an
@@ -1161,26 +1158,26 @@ def membership_options(mlist, subcat, cgidata, doc, form):
in older versions of Mailman.
"""))
legend.AddItem(
- _('''ack -- Does the member get acknowledgements of their
+ _(f'''ack -- Does the member get acknowledgements of their
posts?'''))
legend.AddItem(
- _('''not metoo -- Does the member want to avoid copies of their
+ _(f'''not metoo -- Does the member want to avoid copies of their
own postings?'''))
legend.AddItem(
- _('''nodupes -- Does the member want to avoid duplicates of the
+ _(f'''nodupes -- Does the member want to avoid duplicates of the
same message?'''))
legend.AddItem(
- _('''digest -- Does the member get messages in digests?
+ _(f'''digest -- Does the member get messages in digests?
(otherwise, individual messages)'''))
legend.AddItem(
- _('''plain -- If getting digests, does the member get plain
+ _(f'''plain -- If getting digests, does the member get plain
text digests? (otherwise, MIME)'''))
legend.AddItem(_("language -- Language preferred by the user"))
addlegend = ''
parsedqs = 0
qsenviron = os.environ.get('QUERY_STRING')
if qsenviron:
- qs = cgi.parse_qs(qsenviron).get('legend')
+ qs = urllib.parse.parse_qs(qsenviron).get('legend')
if qs and type(qs) is list:
qs = qs[0]
if qs == 'yes':
@@ -1200,7 +1197,7 @@ def membership_options(mlist, subcat, cgidata, doc, form):
if chunkindex is not None:
buttons = []
url = adminurl + '/members?%sletter=%s&' % (addlegend, bucket)
- footer = _('''
To view more members, click on the appropriate
+ footer = _(f'''
To view more members, click on the appropriate
range listed below:''')
chunkmembers = buckets[bucket]
last = len(chunkmembers)
@@ -1210,11 +1207,7 @@ def membership_options(mlist, subcat, cgidata, doc, form):
start = chunkmembers[i*chunksz]
end = chunkmembers[min((i+1)*chunksz, last)-1]
thisurl = url + 'chunk=%d' % i + findfrag
- if type(thisurl) is str:
- thisurl = thisurl.encode(
- Utils.GetCharSet(mlist.preferred_language),
- errors='ignore')
- link = Link(thisurl, _('from %(start)s to %(end)s'))
+ link = Link(thisurl, _(f'from {start} to {end}'))
buttons.append(link)
buttons = UnorderedList(*buttons)
container.AddItem(footer + buttons.Format() + '
')
@@ -1263,7 +1256,7 @@ def mass_subscribe(mlist, container):
container.AddItem(Center(table))
# Invitation text
table.AddRow([' ', ' '])
- table.AddRow([Italic(_("""Below, enter additional text to be added to the
+ table.AddRow([Italic(_(f"""Below, enter additional text to be added to the
top of your invitation or the subscription notification. Include at least
one blank line at the end..."""))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
@@ -1309,7 +1302,7 @@ def address_change(mlist, container):
# ADDRESS CHANGE
GREY = mm_cfg.WEB_ADMINITEM_COLOR
table = Table(width='90%')
- table.AddRow([Italic(_("""To change a list member's address, enter the
+ table.AddRow([Italic(_(f"""To change a list member's address, enter the
member's current and new addresses below. Use the check boxes to send
notice of the change to the old and/or new address(es)."""))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=3)
@@ -1357,7 +1350,7 @@ def password_inputs(mlist):
table.AddRow([Center(Header(2, _('Change list ownership passwords')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
- table.AddRow([_("""\
+ table.AddRow([_(f"""\
The list administrators are the people who have ultimate control over
all parameters of this mailing list. They are able to change any list
configuration variable available through these administration web pages.
@@ -1371,7 +1364,7 @@ def password_inputs(mlist):
In order to split the list ownership duties into administrators and
moderators, you must set a separate moderator password in the fields below,
and also provide the email addresses of the list moderators in the
-general options section.""")])
+general options section.""")])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
# Set up the admin password table on the left
atable = Table(border=0, cellspacing=3, cellpadding=4,
@@ -1389,7 +1382,7 @@ def password_inputs(mlist):
PasswordBox('confirmmodpw', size=20)])
# Add these tables to the overall password table
table.AddRow([atable, mtable])
- table.AddRow([_("""\
+ table.AddRow([_(f"""\
In addition to the above passwords you may specify a password for
pre-approving posts to the list. Either of the above two passwords can
be used in an Approved: header or first body line pseudo-header to
@@ -1431,7 +1424,7 @@ def safeint(formvar, defaultval=None):
confirm = cgidata.getfirst('confirmmodpw', '').strip()
if new or confirm:
if new == confirm:
- mlist.mod_password = sha_new(new).hexdigest()
+ mlist.mod_password = sha_new(new.encode()).hexdigest()
# No re-authentication necessary because the moderator's
# password doesn't get you into these pages.
else:
@@ -1442,7 +1435,7 @@ def safeint(formvar, defaultval=None):
confirm = cgidata.getfirst('confirmpostpw', '').strip()
if new or confirm:
if new == confirm:
- mlist.post_password = sha_new(new).hexdigest()
+ mlist.post_password = sha_new(new.encode()).hexdigest()
# No re-authentication necessary because the poster's
# password doesn't get you into these pages.
else:
@@ -1452,7 +1445,7 @@ def safeint(formvar, defaultval=None):
confirm = cgidata.getfirst('confirmpw', '').strip()
if new or confirm:
if new == confirm:
- mlist.password = sha_new(new).hexdigest()
+ mlist.password = sha_new(new.encode()).hexdigest()
# Set new cookie
print(mlist.MakeCookie(mm_cfg.AuthListAdmin))
else:
@@ -1465,8 +1458,11 @@ def safeint(formvar, defaultval=None):
gui.handleForm(mlist, category, subcat, cgidata, doc)
# mass subscription, removal processing for members category
subscribers = ''
- subscribers += cgidata.getfirst('subscribees', '')
- subscribers += cgidata.getfirst('subscribees_upload', '')
+ subscribers += str(cgidata.getfirst('subscribees', ''))
+ sub_uploads = cgidata.getfirst('subscribees_upload', '')
+ if isinstance(sub_uploads, bytes):
+ sub_uploads = sub_uploads.decode()
+ subscribers += sub_uploads
if subscribers:
entries = [_f for _f in [n.strip() for n in subscribers.splitlines()] if _f]
send_welcome_msg = safeint('send_welcome_msg_to_this_batch',
@@ -1522,7 +1518,7 @@ def safeint(formvar, defaultval=None):
(safeentry, _('Hostile address (illegal characters)')))
except Errors.MembershipIsBanned as pattern:
subscribe_errors.append(
- (safeentry, _('Banned address (matched %(pattern)s)')))
+ (safeentry, _(f'Banned address (matched {pattern})')))
else:
member = Utils.uncanonstr(formataddr((fullname, address)))
subscribe_success.append(Utils.websafe(member))
@@ -1547,7 +1543,10 @@ def safeint(formvar, defaultval=None):
removals += cgidata['unsubscribees'].value
if 'unsubscribees_upload' in cgidata and \
cgidata['unsubscribees_upload'].value:
- removals += cgidata['unsubscribees_upload'].value
+ unsub_upload = cgidata['unsubscribees_upload'].value
+ if isinstance(unsub_upload, bytes):
+ unsub_upload = unsub_upload.decode()
+ removals += unsub_upload
if removals:
names = [_f for _f in [n.strip() for n in removals.splitlines()] if _f]
send_unsub_notifications = safeint(
@@ -1595,12 +1594,12 @@ def safeint(formvar, defaultval=None):
elif mlist.isMember(change_to):
# ApprovedChangeMemberAddress will just delete the old address
# and we don't want that here.
- msg = _('%(schange_to)s is already a list member.')
+ msg = _(f'{schange_to} is already a list member.')
else:
try:
Utils.ValidateEmail(change_to)
except (Errors.MMBadEmailError, Errors.MMHostileAddress):
- msg = _('%(schange_to)s is not a valid email address.')
+ msg = _(f'{schange_to} is not a valid email address.')
if msg:
doc.AddItem(Header(3, msg))
doc.AddItem('
')
@@ -1608,24 +1607,24 @@ def safeint(formvar, defaultval=None):
try:
mlist.ApprovedChangeMemberAddress(change_from, change_to, False)
except Errors.NotAMemberError:
- msg = _('%(schange_from)s is not a member')
+ msg = _(f'{schange_from} is not a member')
except Errors.MMAlreadyAMember:
- msg = _('%(schange_to)s is already a member')
+ msg = _(f'{schange_to} is already a member')
except Errors.MembershipIsBanned as pat:
spat = Utils.websafe(str(pat))
- msg = _('%(schange_to)s matches banned pattern %(spat)s')
+ msg = _(f'{schange_to} matches banned pattern {spat}')
else:
- msg = _('Address %(schange_from)s changed to %(schange_to)s')
+ msg = _(f'Address {schange_from} changed to {schange_to}')
success = True
doc.AddItem(Header(3, msg))
lang = mlist.getMemberLanguage(change_to)
otrans = i18n.get_translation()
i18n.set_language(lang)
list_name = mlist.getListAddress()
- text = Utils.wrap(_("""The member address %(change_from)s on the
-%(list_name)s list has been changed to %(change_to)s.
+ text = Utils.wrap(_(f"""The member address {change_from} on the
+{list_name} list has been changed to {change_to}.
"""))
- subject = _('%(list_name)s address change notice.')
+ subject = _(f'{list_name} address change notice.')
i18n.set_translation(otrans)
if success and cgidata.getfirst('notice_old', '') == 'yes':
# Send notice to old address.
@@ -1636,7 +1635,7 @@ def safeint(formvar, defaultval=None):
lang=lang
)
msg.send(mlist)
- doc.AddItem(Header(3, _('Notification sent to %(schange_from)s.')))
+ doc.AddItem(Header(3, _(f'Notification sent to {schange_from}.')))
if success and cgidata.getfirst('notice_new', '') == 'yes':
# Send notice to new address.
msg = Message.UserNotification(change_to,
@@ -1646,13 +1645,16 @@ def safeint(formvar, defaultval=None):
lang=lang
)
msg.send(mlist)
- doc.AddItem(Header(3, _('Notification sent to %(schange_to)s.')))
+ doc.AddItem(Header(3, _(f'Notification sent to {schange_to}.')))
doc.AddItem('
')
# sync operation
memberlist = ''
memberlist += cgidata.getvalue('memberlist', '')
- memberlist += cgidata.getvalue('memberlist_upload', '')
+ upload = cgidata.getvalue('memberlist_upload', '')
+ if isinstance(upload, bytes):
+ upload = upload.decode()
+ memberlist += upload
if memberlist:
# Browsers will convert special characters in the text box to HTML
# entities. We need to fix those.
@@ -1695,7 +1697,7 @@ def clean_input(x):
(safeentry, _('Hostile address (illegal characters)')))
except Errors.MembershipIsBanned as pattern:
subscribe_errors.append(
- (safeentry, _('Banned address (matched %(pattern)s)')))
+ (safeentry, _(f'Banned address (matched {pattern})')))
else:
member = Utils.uncanonstr(formataddr((fullname, address)))
subscribe_success.append(Utils.websafe(member))
@@ -1744,7 +1746,7 @@ def clean_input(x):
# do the user options for members category
if 'setmemberopts_btn' in cgidata and 'user' in cgidata:
user = cgidata['user']
- if type(user) is ListType:
+ if type(user) is list:
users = []
for ui in range(len(user)):
users.append(urllib.parse.unquote(user[ui].value))
@@ -1765,7 +1767,7 @@ def clean_input(x):
errors.append((user, _('Not subscribed')))
continue
if not mlist.isMember(user):
- doc.addError(_('Ignoring changes to deleted member: %(user)s'),
+ doc.addError(_(f'Ignoring changes to deleted member: {user}'),
tag=_('Warning: '))
continue
value = '%s_digest' % quser in cgidata
diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py
index c0083696..730fc90f 100644
--- a/Mailman/Cgi/admindb.py
+++ b/Mailman/Cgi/admindb.py
@@ -22,13 +22,14 @@
from builtins import str
import sys
import os
-import cgi
+from Mailman.Utils import FieldStorage
+import codecs
import errno
import signal
import email
import email.errors
import time
-from urllib.parse import quote_plus, unquote_plus
+from urllib.parse import quote_plus, unquote_plus, parse_qs
from Mailman import mm_cfg
from Mailman import Utils
@@ -121,7 +122,7 @@ def main():
safelistname = Utils.websafe(listname)
# Send this with a 404 status.
print('Status: 404 Not Found')
- handle_no_list(_('No such list %(safelistname)s'))
+ handle_no_list(_(f'No such list {safelistname}'))
syslog('error', 'admindb: No such list "%s": %s\n', listname, e)
return
@@ -129,7 +130,7 @@ def main():
i18n.set_language(mlist.preferred_language)
# Make sure the user is authorized to see this page.
- cgidata = cgi.FieldStorage(keep_blank_values=1)
+ cgidata = FieldStorage(keep_blank_values=1)
try:
cgidata.getfirst('adminpw', '')
except TypeError:
@@ -201,14 +202,14 @@ def main():
if envar:
# POST methods, even if their actions have a query string, don't get
# put into FieldStorage's keys :-(
- qs = cgi.parse_qs(envar).get('sender')
- if qs and type(qs) == ListType:
+ qs = parse_qs(envar).get('sender')
+ if qs and type(qs) == list:
sender = qs[0]
- qs = cgi.parse_qs(envar).get('msgid')
- if qs and type(qs) == ListType:
+ qs = parse_qs(envar).get('msgid')
+ if qs and type(qs) == list:
msgid = qs[0]
- qs = cgi.parse_qs(envar).get('details')
- if qs and type(qs) == ListType:
+ qs = parse_qs(envar).get('details')
+ if qs and type(qs) == list:
details = qs[0]
# We need a signal handler to catch the SIGTERM that can come from Apache
@@ -236,10 +237,10 @@ def sigterm_handler(signum, frame, mlist=mlist):
if not list(cgidata.keys()) or 'admlogin' in cgidata:
# If this is not a form submission (i.e. there are no keys in the
# form) or it's a login, then we don't need to do much special.
- doc.SetTitle(_('%(realname)s Administrative Database'))
+ doc.SetTitle(_(f'{realname} Administrative Database'))
elif not details:
# This is a form submission
- doc.SetTitle(_('%(realname)s Administrative Database Results'))
+ doc.SetTitle(_(f'{realname} Administrative Database Results'))
if csrf_checked:
process_form(mlist, doc, cgidata)
else:
@@ -249,7 +250,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
# are no pending requests, but be sure to save the results!
admindburl = mlist.GetScriptURL('admindb', absolute=1)
if not mlist.NumRequestsPending():
- title = _('%(realname)s Administrative Database')
+ title = _(f'{realname} Administrative Database')
doc.SetTitle(title)
doc.AddItem(Header(2, title))
doc.AddItem(_('There are no pending requests.'))
@@ -299,7 +300,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
addform = 1
if sender:
esender = Utils.websafe(sender)
- d['description'] = _("all of %(esender)s's held messages.")
+ d['description'] = _("all of {esender}'s held messages.")
doc.AddItem(Utils.maketext('admindbpreamble.html', d,
raw=1, mlist=mlist))
show_sender_requests(mlist, form, sender)
@@ -363,7 +364,7 @@ def handle_no_list(msg=''):
doc.AddItem(msg)
url = Utils.ScriptURL('admin', absolute=1)
link = Link(url, _('list of available mailing lists.')).Format()
- doc.AddItem(_('You must specify a list name. Here is the %(link)s'))
+ doc.AddItem(_(f'You must specify a list name. Here is the {link}'))
doc.AddItem('
')
doc.AddItem(MailmanLogo())
print(doc.Format())
@@ -410,7 +411,7 @@ def show_pending_subs(mlist, form):
checked=0).Format()
if addr not in mlist.ban_list:
radio += (' ' + '')
# While the address may be a unicode, it must be ascii
@@ -419,7 +420,7 @@ def show_pending_subs(mlist, form):
Utils.websafe(fullname),
displaytime),
radio,
- TextBox('comment-%d' % id, size=40)
+ TextBox(f'comment-%d' % id, size=40)
])
num += 1
if num > 0:
@@ -472,7 +473,7 @@ def show_pending_unsubs(mlist, form):
mm_cfg.REJECT,
mm_cfg.DISCARD),
checked=0),
- TextBox('comment-%d' % id, size=45)
+ TextBox(f'comment-%d' % id, size=45)
])
if num > 0:
form.AddItem('')
@@ -569,7 +570,7 @@ def show_helds_overview(mlist, form, ssort=SSENDER):
''
])
left.AddCellInfo(left.GetCurrentRowIndex(), 0, colspan=2)
@@ -585,14 +586,14 @@ def show_helds_overview(mlist, form, ssort=SSENDER):
''])
left.AddCellInfo(left.GetCurrentRowIndex(), 0, colspan=2)
right = Table(border=0)
right.AddRow([
- _("""Click on the message number to view the individual
+ _(f"""Click on the message number to view the individual
message, or you can """) +
- Link(senderurl, _('view all messages from %(esender)s')).Format()
+ Link(senderurl, _(f'view all messages from {esender}')).Format()
])
right.AddCellInfo(right.GetCurrentRowIndex(), 0, colspan=2)
right.AddRow([' ', ' '])
@@ -684,7 +685,7 @@ def show_post_requests(mlist, id, info, total, count, form):
# Header shown on each held posting (including count of total)
msg = _('Posting Held for Approval')
if total != 1:
- msg += _(' (%(count)d of %(total)d)')
+ msg += _(f' (%(count)d of %(total)d)')
form.AddItem(Center(Header(2, msg)))
# We need to get the headers and part of the textual body of the message
# being held. The best way to do this is to use the email Parser to get
@@ -692,10 +693,11 @@ def show_post_requests(mlist, id, info, total, count, form):
# just do raw reads on the file.
try:
msg = readMessage(os.path.join(mm_cfg.DATA_DIR, filename))
+ Utils.set_cte_if_missing(msg)
except IOError as e:
if e.errno != errno.ENOENT:
raise
- form.AddItem(_('Message with id #%(id)d was lost.'))
+ form.AddItem(_(f'Message with id #%(id)d was lost.'))
form.AddItem('
')
# BAW: kludge to remove id from requests.db.
try:
@@ -704,7 +706,7 @@ def show_post_requests(mlist, id, info, total, count, form):
pass
return
except email.errors.MessageParseError:
- form.AddItem(_('Message with id #%(id)d is corrupted.'))
+ form.AddItem(_(f'Message with id #%(id)d is corrupted.'))
# BAW: Should we really delete this, or shuttle it off for site admin
# to look more closely at?
form.AddItem('
')
@@ -719,14 +721,32 @@ def show_post_requests(mlist, id, info, total, count, form):
chars = 0
# A negative value means, include the entire message regardless of size
limit = mm_cfg.ADMINDB_PAGE_TEXT_LIMIT
- for line in email.Iterators.body_line_iterator(msg, decode=True):
- lines.append(line)
- chars += len(line)
- if chars >= limit > 0:
- break
- # We may have gone over the limit on the last line, but keep the full line
- # anyway to avoid losing part of a multibyte character.
- body = EMPTYSTRING.join(lines)
+
+ if msg.is_multipart():
+ for part in msg.walk():
+ if not hasattr(part, 'policy'):
+ part.policy = email._policybase.compat32
+ if part.get_content_type() == 'text/plain':
+ payload = part.get_payload(decode=True)
+ if payload:
+ decoded_payload = codecs.decode(payload, 'unicode_escape')
+ for line in decoded_payload.splitlines():
+ lines.append(line)
+ chars += len(line)
+ if chars >= limit > 0:
+ break
+ break
+ else:
+ payload = msg.get_payload(decode=True)
+ if payload:
+ decoded_payload = codecs.decode(payload, 'unicode_escape')
+ for line in decoded_payload.splitlines():
+ lines.append(line)
+ chars += len(line)
+ if chars >= limit > 0:
+ break
+ # Ensure the full last line is included to avoid splitting multibyte characters
+ body = ''.join(lines)
# Get message charset and try encode in list charset
# We get it from the first text part.
# We need to replace invalid characters here or we can throw an uncaught
@@ -739,11 +759,19 @@ def show_post_requests(mlist, id, info, total, count, form):
else:
mcset = 'us-ascii'
lcset = Utils.GetCharSet(mlist.preferred_language)
+ # Note that this following block breaks a lot of messages. Removing it allows them to stay in their native character sets.
+ # Leaving in as it seems like behavior people would have grown to expect.
if mcset != lcset:
+ # Ensure the body is in the list's preferred charset
try:
- body = str(body, mcset, 'replace').encode(lcset, 'replace')
- except (LookupError, UnicodeError, ValueError):
- pass
+ # If body is a str, encode to bytes using the source charset (mcset)
+ body_bytes = body.encode(mcset, 'replace') if isinstance(body, str) else body
+ # Then decode bytes to str using the list's charset (lcset)
+ body = body_bytes.decode(lcset, 'replace')
+ except (UnicodeEncodeError, UnicodeDecodeError):
+ # Fallback in case of encoding/decoding issues
+ body = body.encode('ascii', 'replace').decode('ascii', 'replace')
+ #
hdrtxt = NL.join(['%s: %s' % (k, v) for k, v in list(msg.items())])
hdrtxt = Utils.websafe(hdrtxt)
# Okay, we've reconstituted the message just fine. Now for the fun part!
@@ -769,16 +797,16 @@ def show_post_requests(mlist, id, info, total, count, form):
t.AddCellInfo(t.GetCurrentRowIndex(), col-1, align='right')
t.AddRow([' ',
''
])
t.AddRow([' ',
'' +
- TextBox('forward-addr-%d' % id, size=47,
+ TextBox(f'forward-addr-%d' % id, size=47,
value=mlist.GetOwnerEmail()).Format()
])
notice = msgdata.get('rejection_notice', _('[No explanation given]'))
@@ -905,7 +933,7 @@ def process_form(mlist, doc, cgidata):
erroraddrs = []
for k in list(cgidata.keys()):
formv = cgidata[k]
- if type(formv) == ListType:
+ if type(formv) == list:
continue
try:
v = int(formv.value)
@@ -974,7 +1002,7 @@ def process_form(mlist, doc, cgidata):
if banaddrs:
for addr, patt in banaddrs:
addr = Utils.websafe(addr)
- doc.AddItem(_('%(addr)s is banned (matched: %(patt)s)') + ' ')
+ doc.AddItem(_(f'{addr} is banned (matched: {patt})') + ' ')
if badaddrs:
for addr in badaddrs:
addr = Utils.websafe(addr)
diff --git a/Mailman/Cgi/confirm.py b/Mailman/Cgi/confirm.py
index 0be9542b..f0a13843 100644
--- a/Mailman/Cgi/confirm.py
+++ b/Mailman/Cgi/confirm.py
@@ -20,7 +20,7 @@
from __future__ import print_function
import signal
-import cgi
+from Mailman.Utils import FieldStorage
import time
from Mailman import mm_cfg
@@ -54,7 +54,7 @@ def main():
except Errors.MMListError as e:
# Avoid cross-site scripting attacks
safelistname = Utils.websafe(listname)
- bad_confirmation(doc, _('No such list %(safelistname)s'))
+ bad_confirmation(doc, _(f'No such list {safelistname}'))
doc.AddItem(MailmanLogo())
# Send this with a 404 status.
print('Status: 404 Not Found')
@@ -67,7 +67,7 @@ def main():
doc.set_language(mlist.preferred_language)
# Get the form data to see if this is a second-step confirmation
- cgidata = cgi.FieldStorage(keep_blank_values=1)
+ cgidata = FieldStorage(keep_blank_values=1)
try:
cookie = cgidata.getfirst('cookie')
except TypeError:
@@ -100,14 +100,14 @@ def main():
confirmurl = mlist.GetScriptURL('confirm', absolute=1)
# Avoid cross-site scripting attacks
safecookie = Utils.websafe(cookie)
- badconfirmstr = _('''Invalid confirmation string:
- %(safecookie)s.
+ badconfirmstr = _(f'''Invalid confirmation string:
+ {safecookie}.
Note that confirmation strings expire approximately
- %(days)s days after the initial request. They also expire if the
+ {days} days after the initial request. They also expire if the
request has already been handled in some way. If your confirmation
has expired, please try to re-submit your request.
- Otherwise, re-enter your confirmation
+ Otherwise, re-enter your confirmation
string.''')
content = mlist.pend_confirm(cookie, expunge=False)
@@ -134,7 +134,7 @@ def main():
else:
unsubscription_prompt(mlist, doc, cookie, *content[1:])
except Errors.NotAMemberError:
- doc.addError(_("""The address requesting unsubscription is not
+ doc.addError(_(f"""The address requesting unsubscription is not
a member of the mailing list. Perhaps you have already been
unsubscribed, e.g. by the list administrator?"""))
# Expunge this record from the pending database.
@@ -150,7 +150,7 @@ def main():
try:
addrchange_prompt(mlist, doc, cookie, *content[1:])
except Errors.NotAMemberError:
- doc.addError(_("""The address requesting to be changed has
+ doc.addError(_(f"""The address requesting to be changed has
been subsequently unsubscribed. This request has been
cancelled."""))
# Expunge this record from the pending database.
@@ -170,7 +170,7 @@ def main():
else:
reenable_prompt(mlist, doc, cookie, *content[1:])
else:
- bad_confirmation(doc, _('System error, bad content: %(content)s'))
+ bad_confirmation(doc, _(f'System error, bad content: {content}'))
except Errors.MMBadConfirmation:
bad_confirmation(doc, badconfirmstr)
@@ -212,7 +212,7 @@ def ask_for_cookie(mlist, doc, extra=''):
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
# Add cookie entry box
- table.AddRow([_("""Please enter the confirmation string
+ table.AddRow([_(f"""Please enter the confirmation string
(i.e. cookie) that you received in your email message, in the box
below. Then hit the Submit button to proceed to the next
confirmation step.""")])
@@ -251,8 +251,8 @@ def subscription_prompt(mlist, doc, cookie, userdesc):
# We do things this way so we don't have to reformat this paragraph, which
# would mess up translations. If you modify this text for other reasons,
# please refill the paragraph, and clean up the logic.
- result = _("""Your confirmation is required in order to complete the
- subscription request to the mailing list %(listname)s. Your
+ result = _(f"""Your confirmation is required in order to complete the
+ subscription request to the mailing list {listname}. Your
subscription settings are shown below; make any necessary changes and hit
Subscribe to complete the confirmation process. Once you've
confirmed your subscription request, you will be shown your account
@@ -267,8 +267,8 @@ def subscription_prompt(mlist, doc, cookie, userdesc):
if (mlist.subscribe_policy in (2, 3) and
not getattr(userdesc, 'invitation', False)):
# Confirmation is required
- result = _("""Your confirmation is required in order to continue with
- the subscription request to the mailing list %(listname)s.
+ result = _(f"""Your confirmation is required in order to continue with
+ the subscription request to the mailing list {listname}.
Your subscription settings are shown below; make any necessary changes
and hit Subscribe to list ... to complete the confirmation
process. Once you've confirmed your subscription request, the
@@ -309,7 +309,7 @@ def subscription_prompt(mlist, doc, cookie, userdesc):
table.AddRow([Hidden('cookie', cookie)])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
table.AddRow([
- Label(SubmitButton('submit', _('Subscribe to list %(listname)s'))),
+ Label(SubmitButton('submit', _(f'Subscribe to list {listname}'))),
SubmitButton('cancel', _('Cancel my subscription request'))
])
form.AddItem(table)
@@ -378,25 +378,25 @@ def sigterm_handler(signum, frame, mlist=mlist):
title = _('Awaiting moderator approval')
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
- doc.AddItem(_("""\
+ doc.AddItem(_(f"""\
You have successfully confirmed your subscription request to the
- mailing list %(listname)s, however final approval is required from
+ mailing list {listname}, however final approval is required from
the list moderator before you will be subscribed. Your request
has been forwarded to the list moderator, and you will be notified
of the moderator's decision."""))
except (Errors.NotAMemberError, TypeError):
- bad_confirmation(doc, _('''Invalid confirmation string. It is
+ bad_confirmation(doc, _(f'''Invalid confirmation string. It is
possible that you are attempting to confirm a request for an
address that has already been unsubscribed.'''))
except Errors.MMAlreadyAMember:
doc.addError(_("You are already a member of this mailing list!"))
except Errors.MembershipIsBanned:
owneraddr = mlist.GetOwnerEmail()
- doc.addError(_("""You are currently banned from subscribing to
+ doc.addError(_(f"""You are currently banned from subscribing to
this list. If you think this restriction is erroneous, please
- contact the list owners at %(owneraddr)s."""))
+ contact the list owners at {owneraddr}."""))
except Errors.HostileSubscriptionError:
- doc.addError(_("""\
+ doc.addError(_(f"""\
You were not invited to this mailing list. The invitation has
been discarded, and both list administrators have been
alerted."""))
@@ -410,14 +410,14 @@ def sigterm_handler(signum, frame, mlist=mlist):
optionsurl = mlist.GetOptionsURL(addr, absolute=1)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
- doc.AddItem(_('''\
+ doc.AddItem(_(f'''\
You have successfully confirmed your subscription request for
- "%(addr)s" to the %(listname)s mailing list. A separate
+ "{addr}" to the {listname} mailing list. A separate
confirmation message will be sent to your email address, along
with your password, and other useful information and links.
You can now
- proceed to your membership login
+ proceed to your membership login
page.'''))
mlist.Save()
finally:
@@ -451,7 +451,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
op, addr = mlist.ProcessConfirmation(cookie)
# See comment about TypeError in subscription_confirm.
except (Errors.NotAMemberError, TypeError):
- bad_confirmation(doc, _('''Invalid confirmation string. It is
+ bad_confirmation(doc, _(f'''Invalid confirmation string. It is
possible that you are attempting to confirm a request for an
address that has already been unsubscribed.'''))
else:
@@ -461,9 +461,9 @@ def sigterm_handler(signum, frame, mlist=mlist):
listinfourl = mlist.GetScriptURL('listinfo', absolute=1)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
- doc.AddItem(_("""\
- You have successfully unsubscribed from the %(listname)s mailing
- list. You can now visit the list's main
+ doc.AddItem(_(f"""\
+ You have successfully unsubscribed from the {listname} mailing
+ list. You can now visit the list's main
information page."""))
mlist.Save()
finally:
@@ -490,12 +490,12 @@ def unsubscription_prompt(mlist, doc, cookie, addr):
fullname = _('Not available')
else:
fullname = Utils.websafe(Utils.uncanonstr(fullname, lang))
- table.AddRow([_("""Your confirmation is required in order to complete the
- unsubscription request from the mailing list %(listname)s. You
+ table.AddRow([_(f"""Your confirmation is required in order to complete the
+ unsubscription request from the mailing list {listname}. You
are currently subscribed with
-
Real name: %(fullname)s
-
Email address: %(addr)s
+
Real name: {fullname}
+
Email address: {addr}
Hit the Unsubscribe button below to complete the confirmation
@@ -541,19 +541,19 @@ def sigterm_handler(signum, frame, mlist=mlist):
op, oldaddr, newaddr = mlist.ProcessConfirmation(cookie)
# See comment about TypeError in subscription_confirm.
except (Errors.NotAMemberError, TypeError):
- bad_confirmation(doc, _('''Invalid confirmation string. It is
+ bad_confirmation(doc, _(f'''Invalid confirmation string. It is
possible that you are attempting to confirm a request for an
address that has already been unsubscribed.'''))
except Errors.MembershipIsBanned:
owneraddr = mlist.GetOwnerEmail()
realname = mlist.real_name
- doc.addError(_("""%(newaddr)s is banned from subscribing to the
- %(realname)s list. If you think this restriction is erroneous,
- please contact the list owners at %(owneraddr)s."""))
+ doc.addError(_(f"""{newaddr} is banned from subscribing to the
+ {realname} list. If you think this restriction is erroneous,
+ please contact the list owners at {owneraddr}."""))
except Errors.MMAlreadyAMember:
realname = mlist.real_name
- bad_confirmation(doc, _("""%(newaddr)s is already a member of
- the %(realname)s list. It is possible that you are attempting
+ bad_confirmation(doc, _(f"""{newaddr} is already a member of
+ the {realname} list. It is possible that you are attempting
to confirm a request for an address that has already been
subscribed."""))
else:
@@ -563,10 +563,10 @@ def sigterm_handler(signum, frame, mlist=mlist):
optionsurl = mlist.GetOptionsURL(newaddr, absolute=1)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
- doc.AddItem(_("""\
- You have successfully changed your address on the %(listname)s
- mailing list from %(oldaddr)s to %(newaddr)s. You
- can now proceed to your membership
+ doc.AddItem(_(f"""\
+ You have successfully changed your address on the {listname}
+ mailing list from {oldaddr} to {newaddr}. You
+ can now proceed to your membership
login page."""))
mlist.Save()
finally:
@@ -597,17 +597,17 @@ def addrchange_prompt(mlist, doc, cookie, oldaddr, newaddr, globally):
globallys = _('globally')
else:
globallys = ''
- table.AddRow([_("""Your confirmation is required in order to complete the
- change of address request for the mailing list %(listname)s. You
+ table.AddRow([_(f"""Your confirmation is required in order to complete the
+ change of address request for the mailing list {listname}. You
are currently subscribed with
-
Real name: %(fullname)s
-
Old email address: %(oldaddr)s
+
Real name: {fullname}
+
Old email address: {oldaddr}
- and you have requested to %(globallys)s change your email address to
+ and you have requested to {globallys} change your email address to
-
New email address: %(newaddr)s
+
New email address: {newaddr}
Hit the Change address button below to complete the confirmation
@@ -635,7 +635,7 @@ def heldmsg_cancel(mlist, doc, cookie):
bgcolor=mm_cfg.WEB_HEADER_COLOR)
# Expunge this record from the pending database.
expunge(mlist, cookie)
- table.AddRow([_('''Okay, the list moderator will still have the
+ table.AddRow([_(f'''Okay, the list moderator will still have the
opportunity to approve or reject this message.''')])
doc.AddItem(table)
@@ -666,8 +666,8 @@ def sigterm_handler(signum, frame, mlist=mlist):
_('Sender discarded message via web.'))
# See comment about TypeError in subscription_confirm.
except (Errors.LostHeldMessage, KeyError, TypeError):
- bad_confirmation(doc, _('''The held message with the Subject:
- header %(subject)s could not be found. The most likely
+ bad_confirmation(doc, _(f'''The held message with the Subject:
+ header {subject} could not be found. The most likely
reason for this is that the list moderator has already approved or
rejected the message. You were not able to cancel it in
time.'''))
@@ -677,10 +677,10 @@ def sigterm_handler(signum, frame, mlist=mlist):
title = _('Posted message canceled')
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
- doc.AddItem(_('''\
+ doc.AddItem(_(f'''\
You have successfully canceled the posting of your message with
- the Subject: header %(subject)s to the mailing list
- %(listname)s.'''))
+ the Subject: header {subject} to the mailing list
+ {listname}.'''))
mlist.Save()
finally:
mlist.Unlock()
@@ -713,7 +713,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
mlist.Unlock()
if data is None:
- bad_confirmation(doc, _("""The held message you were referred to has
+ bad_confirmation(doc, _(f"""The held message you were referred to has
already been handled by the list administrator."""))
return
@@ -727,12 +727,12 @@ def sigterm_handler(signum, frame, mlist=mlist):
subject = Utils.websafe(Utils.oneline(msgsubject, Utils.GetCharSet(lang)))
reason = Utils.websafe(_(givenreason))
listname = mlist.real_name
- table.AddRow([_('''Your confirmation is required in order to cancel the
- posting of your message to the mailing list %(listname)s:
+ table.AddRow([_(f'''Your confirmation is required in order to cancel the
+ posting of your message to the mailing list {listname}:
-
Sender: %(sender)s
-
Subject: %(subject)s
-
Reason: %(reason)s
+
Sender: {sender}
+
Subject: {subject}
+
Reason: {reason}
Hit the Cancel posting button to discard the posting.
@@ -755,7 +755,7 @@ def reenable_cancel(mlist, doc, cookie):
# Don't actually discard this cookie, since the user may decide to
# re-enable their membership at a future time, and we may be sending out
# future notifications with this cookie value.
- doc.AddItem(_("""You have canceled the re-enabling of your membership. If
+ doc.AddItem(_(f"""You have canceled the re-enabling of your membership. If
we continue to receive bounces from your address, it could be deleted from
this mailing list."""))
@@ -780,7 +780,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
op, addr = mlist.ProcessConfirmation(cookie)
# See comment about TypeError in subscription_confirm.
except (Errors.NotAMemberError, TypeError):
- bad_confirmation(doc, _('''Invalid confirmation string. It is
+ bad_confirmation(doc, _(f'''Invalid confirmation string. It is
possible that you are attempting to confirm a request for an
address that has already been unsubscribed.'''))
else:
@@ -790,10 +790,10 @@ def sigterm_handler(signum, frame, mlist=mlist):
optionsurl = mlist.GetOptionsURL(addr, absolute=1)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
- doc.AddItem(_("""\
+ doc.AddItem(_(f"""\
You have successfully re-enabled your membership in the
- %(listname)s mailing list. You can now visit your member options page.
+ {listname} mailing list. You can now visit your member options page.
"""))
mlist.Save()
finally:
@@ -819,9 +819,9 @@ def reenable_prompt(mlist, doc, cookie, list, member):
if not info:
listinfourl = mlist.GetScriptURL('listinfo', absolute=1)
# They've already be unsubscribed
- table.AddRow([_("""We're sorry, but you have already been unsubscribed
+ table.AddRow([_(f"""We're sorry, but you have already been unsubscribed
from this mailing list. To re-subscribe, please visit the
- list information page.""")])
+ list information page.""")])
return
date = time.strftime('%A, %B %d, %Y',
@@ -838,16 +838,16 @@ def reenable_prompt(mlist, doc, cookie, list, member):
else:
username = Utils.websafe(Utils.uncanonstr(username, lang))
- table.AddRow([_("""Your membership in the %(realname)s mailing list is
+ table.AddRow([_(f"""Your membership in the {realname} mailing list is
currently disabled due to excessive bounces. Your confirmation is
required in order to re-enable delivery to your address. We have the
following information on file:
-
Member address: %(member)s
-
Member name: %(username)s
-
Last bounce received on: %(date)s
+
Member address: {member}
+
Member name: {username}
+
Last bounce received on: {date}
Approximate number of days before you are permanently removed
- from this list: %(daysleft)s
+ from this list: {daysleft}
Hit the Re-enable membership button to resume receiving postings
diff --git a/Mailman/Cgi/create.py b/Mailman/Cgi/create.py
index 6aea412b..691cfd88 100644
--- a/Mailman/Cgi/create.py
+++ b/Mailman/Cgi/create.py
@@ -22,7 +22,7 @@
import sys
import os
import signal
-import cgi
+from Mailman.Utils import FieldStorage
from Mailman import mm_cfg
from Mailman import MailList
@@ -43,7 +43,7 @@ def main():
doc = Document()
doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
try:
cgidata.getfirst('doit', '')
except TypeError:
@@ -107,20 +107,20 @@ def process_request(doc, cgidata):
auth = cgidata.getfirst('auth', '').strip()
langs = cgidata.getvalue('langs', [mm_cfg.DEFAULT_SERVER_LANGUAGE])
- if not isinstance(langs, ListType):
+ if not isinstance(langs, list):
langs = [langs]
# Sanity check
safelistname = Utils.websafe(listname)
if '@' in listname:
request_creation(doc, cgidata,
- _('List name must not include "@": %(safelistname)s'))
+ _(f'List name must not include "@": {safelistname}'))
return
if Utils.list_exists(listname):
# BAW: should we tell them the list already exists? This could be
# used to mine/guess the existance of non-advertised lists. Then
# again, that can be done in other ways already, so oh well.
request_creation(doc, cgidata,
- _('List already exists: %(safelistname)s'))
+ _(f'List already exists: {safelistname}'))
return
if not listname:
request_creation(doc, cgidata,
@@ -135,7 +135,7 @@ def process_request(doc, cgidata):
if password or confirm:
request_creation(
doc, cgidata,
- _('''Leave the initial password (and confirmation) fields
+ _(f'''Leave the initial password (and confirmation) fields
blank if you want Mailman to autogenerate the list
passwords.'''))
return
@@ -180,7 +180,7 @@ def process_request(doc, cgidata):
hostname not in mm_cfg.VIRTUAL_HOSTS:
safehostname = Utils.websafe(hostname)
request_creation(doc, cgidata,
- _('Unknown virtual host: %(safehostname)s'))
+ _(f'Unknown virtual host: {safehostname}'))
return
emailhost = mm_cfg.VIRTUAL_HOSTS.get(hostname, mm_cfg.DEFAULT_EMAIL_HOST)
# We've got all the data we need, so go ahead and try to create the list
@@ -216,12 +216,12 @@ def sigterm_handler(signum, frame, mlist=mlist):
else:
s = Utils.websafe(owner)
request_creation(doc, cgidata,
- _('Bad owner email address: %(s)s'))
+ _(f'Bad owner email address: {s}'))
return
except Errors.MMListAlreadyExistsError:
# MAS: List already exists so we don't need to websafe it.
request_creation(doc, cgidata,
- _('List already exists: %(listname)s'))
+ _(f'List already exists: {listname}'))
return
except Errors.BadListNameError as e:
if e.args:
@@ -229,12 +229,12 @@ def sigterm_handler(signum, frame, mlist=mlist):
else:
s = Utils.websafe(listname)
request_creation(doc, cgidata,
- _('Illegal list name: %(s)s'))
+ _(f'Illegal list name: {s}'))
return
except Errors.MMListError:
request_creation(
doc, cgidata,
- _('''Some unknown error occurred while creating the list.
+ _(f'''Some unknown error occurred while creating the list.
Please contact the site administrator for assistance.'''))
return
@@ -271,7 +271,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
}, mlist=mlist)
msg = Message.UserNotification(
owner, siteowner,
- _('Your new mailing list: %(listname)s'),
+ _(f'Your new mailing list: {listname}'),
text, mlist.preferred_language)
msg.send(mlist)
@@ -286,9 +286,9 @@ def sigterm_handler(signum, frame, mlist=mlist):
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
- table.AddRow([_('''You have successfully created the mailing list
- %(listname)s and notification has been sent to the list owner
- %(owner)s. You can now:''')])
+ table.AddRow([_(f'''You have successfully created the mailing list
+ {listname} and notification has been sent to the list owner
+ {owner}. You can now:''')])
ullist = UnorderedList()
ullist.AddItem(Link(listinfo_url, _("Visit the list's info page")))
ullist.AddItem(Link(admin_url, _("Visit the list's admin page")))
@@ -310,7 +310,7 @@ def request_creation(doc, cgidata=dummy, errmsg=None):
# What virtual domain are we using?
hostname = Utils.get_domain()
# Set up the document
- title = _('Create a %(hostname)s Mailing List')
+ title = _(f'Create a {hostname} Mailing List')
doc.SetTitle(title)
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
@@ -321,7 +321,7 @@ def request_creation(doc, cgidata=dummy, errmsg=None):
table.AddRow([Header(3, Bold(
FontAttr(_('Error: '), color='#ff0000', size='+2').Format() +
Italic(errmsg).Format()))])
- table.AddRow([_("""You can create a new mailing list by entering the
+ table.AddRow([_(f"""You can create a new mailing list by entering the
relevant information into the form below. The name of the mailing list
will be used as the primary address for posting messages to the list, so
it should be lowercased. You will not be able to change this once the
@@ -401,7 +401,7 @@ def request_creation(doc, cgidata=dummy, errmsg=None):
ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, colspan=2)
ftable.AddRow([
- Label(_("""Should new members be quarantined before they
+ Label(_(f"""Should new members be quarantined before they
are allowed to post unmoderated to this list? Answer Yes to hold
new member postings for moderator approval by default.""")),
RadioButtonArray('moderate', (_('No'), _('Yes')),
@@ -431,9 +431,9 @@ def request_creation(doc, cgidata=dummy, errmsg=None):
checked[langi] = 1
deflang = _(Utils.GetLanguageDescr(mm_cfg.DEFAULT_SERVER_LANGUAGE))
ftable.AddRow([Label(_(
- '''Initial list of supported languages.
Note that if you do not
+ f'''Initial list of supported languages.
Note that if you do not
select at least one initial language, the list will use the server
- default language of %(deflang)s''')),
+ default language of {deflang}''')),
CheckBoxArray('langs',
[_(Utils.GetLanguageDescr(L)) for L in langs],
checked=checked,
diff --git a/Mailman/Cgi/edithtml.py b/Mailman/Cgi/edithtml.py
index 18a9634e..6fdf7814 100644
--- a/Mailman/Cgi/edithtml.py
+++ b/Mailman/Cgi/edithtml.py
@@ -19,7 +19,7 @@
from __future__ import print_function
import os
-import cgi
+from Mailman.Utils import FieldStorage
import errno
import re
@@ -84,7 +84,7 @@ def _(s):
except Errors.MMListError as e:
# Avoid cross-site scripting attacks
safelistname = Utils.websafe(listname)
- doc.AddItem(Header(2, _('No such list %(safelistname)s')))
+ doc.AddItem(Header(2, _(f'No such list {safelistname}')))
# Send this with a 404 status.
print('Status: 404 Not Found')
print(doc.Format())
@@ -96,7 +96,7 @@ def _(s):
doc.set_language(mlist.preferred_language)
# Must be authenticated to get any farther
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
try:
cgidata.getfirst('adminpw', '')
except TypeError:
@@ -154,19 +154,19 @@ def _(s):
if template == template_name:
template_info = _(info)
doc.SetTitle(_(
- '%(realname)s -- Edit html for %(template_info)s'))
+ f'{realname} -- Edit html for {template_info}'))
break
else:
# Avoid cross-site scripting attacks
safetemplatename = Utils.websafe(template_name)
doc.SetTitle(_('Edit HTML : Error'))
- doc.AddItem(Header(2, _("%(safetemplatename)s: Invalid template")))
+ doc.AddItem(Header(2, _(f"{safetemplatename}: Invalid template")))
doc.AddItem(mlist.GetMailmanFooter())
print(doc.Format())
return
else:
- doc.SetTitle(_('%(realname)s -- HTML Page Editing'))
- doc.AddItem(Header(1, _('%(realname)s -- HTML Page Editing')))
+ doc.SetTitle(_(f'{realname} -- HTML Page Editing'))
+ doc.AddItem(Header(1, _(f'{realname} -- HTML Page Editing')))
doc.AddItem(Header(2, _('Select page to edit:')))
template_list = UnorderedList()
for (template, info) in template_data:
@@ -243,7 +243,7 @@ def ChangeHTML(mlist, cgi_info, template_name, doc, lang=None):
code = cgi_info['html_code'].value
if Utils.suspiciousHTML(code):
doc.AddItem(Header(3,
- _("""The page you saved contains suspicious HTML that could
+ _(f"""The page you saved contains suspicious HTML that could
potentially expose your users to cross-site scripting attacks. This change
has therefore been rejected. If you still want to make these changes, you
must have shell access to your Mailman server.
diff --git a/Mailman/Cgi/listinfo.py b/Mailman/Cgi/listinfo.py
index dc878d66..62daf739 100644
--- a/Mailman/Cgi/listinfo.py
+++ b/Mailman/Cgi/listinfo.py
@@ -23,7 +23,7 @@
from builtins import str
import os
-import cgi
+from Mailman.Utils import FieldStorage
import time
from Mailman import mm_cfg
@@ -54,12 +54,12 @@ def main():
safelistname = Utils.websafe(listname)
# Send this with a 404 status.
print('Status: 404 Not Found')
- listinfo_overview(_('No such list %(safelistname)s'))
+ listinfo_overview(_(f'No such list {safelistname}'))
syslog('error', 'listinfo: No such list "%s": %s', listname, e)
return
# See if the user want to see this page in other language
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
try:
language = cgidata.getfirst('language')
except TypeError:
@@ -88,7 +88,7 @@ def listinfo_overview(msg=''):
doc = Document()
doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
- legend = (hostname + "s Mailing Lists")
+ legend = (hostname + "'s Mailing Lists")
doc.SetTitle(legend)
table = Table(border=0, width="100%")
@@ -126,12 +126,12 @@ def listinfo_overview(msg=''):
mailmanlink = Link(mm_cfg.MAILMAN_URL, _('Mailman')).Format()
if not advertised:
welcome.extend(
- _('''
There currently are no publicly-advertised
- %(mailmanlink)s mailing lists on %(hostname)s.'''))
+ _(f'''
There currently are no publicly-advertised
+ {mailmanlink} mailing lists on {hostname}.'''))
else:
welcome.append(
- _('''
Below is a listing of all the public mailing lists on
- %(hostname)s. Click on a list name to get more information about
+ _(f'''
Below is a listing of all the public mailing lists on
+ {hostname}. Click on a list name to get more information about
the list, or to subscribe, unsubscribe, and change the preferences
on your subscription.'''))
@@ -139,13 +139,13 @@ def listinfo_overview(msg=''):
adj = msg and _('right') or ''
siteowner = Utils.get_site_email()
welcome.extend(
- (_(''' To visit the general information page for an unadvertised list,
- open a URL similar to this one, but with a '/' and the %(adj)s
+ (_(f''' To visit the general information page for an unadvertised list,
+ open a URL similar to this one, but with a '/' and the {adj}
list name appended.
List administrators, you can visit '''),
Link(Utils.ScriptURL('admin'),
_('the list admin overview page')),
- _(''' to find the management interface for your list.
+ _(f''' to find the management interface for your list.
If you are having trouble using the lists, please contact '''),
Link('mailto:' + siteowner, siteowner),
'.
'))
@@ -232,19 +232,13 @@ def list_listinfo(mlist, lang):
else:
# just to have something to include in the hash below
captcha_idx = ''
+ secret = mm_cfg.SUBSCRIBE_FORM_SECRET + ":" + now + ":" + captcha_idx + ":" + mlist.internal_name() + ":" + remote
+ hash_secret = Utils.sha_new(secret.encode('utf-8')).hexdigest()
# fill form
replacements[''] += (
'\n'
- % (now, captcha_idx,
- Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + ":" +
- now + ":" +
- captcha_idx + ":" +
- mlist.internal_name() + ":" +
- remote
- ).encode('utf-8').hexdigest()
- )
- )
+ % (now, captcha_idx, hash_secret ))
# Roster form substitutions
replacements[''] = mlist.FormatFormStart('roster')
replacements[''] = mlist.FormatRosterOptionForUser(lang)
diff --git a/Mailman/Cgi/options.py b/Mailman/Cgi/options.py
index 85ce4178..c8e1ced6 100644
--- a/Mailman/Cgi/options.py
+++ b/Mailman/Cgi/options.py
@@ -24,7 +24,7 @@
import re
import sys
import os
-import cgi
+from Mailman.Utils import FieldStorage
import signal
import urllib.request, urllib.parse, urllib.error
@@ -62,7 +62,7 @@ def main():
title = _('CGI script error')
doc.SetTitle(title)
doc.AddItem(Header(2, title))
- doc.addError(_('Invalid request method: %(method)s'))
+ doc.addError(_(f'Invalid request method: {method}'))
doc.AddItem('')
doc.AddItem(MailmanLogo())
print('Status: 405 Method Not Allowed')
@@ -92,7 +92,7 @@ def main():
title = _('CGI script error')
doc.SetTitle(title)
doc.AddItem(Header(2, title))
- doc.addError(_('No such list %(safelistname)s'))
+ doc.addError(_(f'No such list {safelistname}'))
doc.AddItem('')
doc.AddItem(MailmanLogo())
# Send this with a 404 status.
@@ -102,7 +102,7 @@ def main():
return
# The total contents of the user's response
- cgidata = cgi.FieldStorage(keep_blank_values=1)
+ cgidata = FieldStorage(keep_blank_values=1)
# CSRF check
safe_params = ['displang-button', 'language', 'email', 'password', 'login',
@@ -165,10 +165,10 @@ def main():
# using public rosters, otherwise, we'll leak membership information.
if not mlist.isMember(user):
if mlist.private_roster == 0:
- doc.addError(_('No such member: %(safeuser)s.'))
+ doc.addError(_(f'No such member: {safeuser}.'))
loginpage(mlist, doc, None, language)
print(doc.Format())
- return
+ return
# Avoid cross-site scripting attacks
if set(params) - set(safe_params):
@@ -203,7 +203,7 @@ def main():
# Are we processing an unsubscription request from the login screen?
msgc = _('If you are a list member, a confirmation email has been sent.')
msgb = _('You already have a subscription pending confirmation')
- msga = _("""If you are a list member, your unsubscription request has been
+ msga = _(f"""If you are a list member, your unsubscription request has been
forwarded to the list administrator for approval.""")
if 'login-unsub' in cgidata:
# Because they can't supply a password for unsubscribing, we'll need
@@ -233,7 +233,7 @@ def main():
# Not a member
if mlist.private_roster == 0:
# Public rosters
- doc.addError(_('No such member: %(safeuser)s.'))
+ doc.addError(_(f'No such member: {safeuser}.'))
else:
syslog('mischief',
'Unsub attempt of non-member w/ private rosters: %s',
@@ -247,7 +247,7 @@ def main():
return
# Are we processing a password reminder from the login screen?
- msg = _("""If you are a list member,
+ msg = _(f"""If you are a list member,
your password has been emailed to you.""")
if 'login-remind' in cgidata:
if mlist.isMember(user):
@@ -257,7 +257,7 @@ def main():
# Not a member
if mlist.private_roster == 0:
# Public rosters
- doc.addError(_('No such member: %(safeuser)s.'))
+ doc.addError(_(f'No such member: {safeuser}.'))
else:
syslog('mischief',
'Reminder attempt of non-member w/ private rosters: %s',
@@ -339,7 +339,7 @@ def main():
elif os.environ.get('QUERY_STRING'):
# POST methods, even if their actions have a query string, don't get
# put into FieldStorage's keys :-(
- qs = cgi.parse_qs(os.environ['QUERY_STRING']).get('VARHELP')
+ qs = urllib.parse.parse_qs(os.environ['QUERY_STRING']).get('VARHELP')
if qs and type(qs) == list:
varhelp = qs[0]
if varhelp:
@@ -367,16 +367,16 @@ def main():
if 'othersubs' in cgidata:
# Only the user or site administrator can view all subscriptions.
if not is_user_or_siteadmin:
- doc.addError(_("""The list administrator may not view the other
+ doc.addError(_(f"""The list administrator may not view the other
subscriptions for this user."""), _('Note: '))
options_page(mlist, doc, user, cpuser, userlang)
print(doc.Format())
return
hostname = mlist.host_name
- title = _('List subscriptions for %(safeuser)s on %(hostname)s')
+ title = _(f'List subscriptions for {safeuser} on {hostname}')
doc.SetTitle(title)
doc.AddItem(Header(2, title))
- doc.AddItem(_('''Click on a link to visit your options page for the
+ doc.AddItem(_(f'''Click on a link to visit your options page for the
requested mailing list.'''))
# Troll through all the mailing lists that match host_name and see if
@@ -414,7 +414,7 @@ def main():
# list admin is /not/ allowed to make global changes.
globally = cgidata.getfirst('changeaddr-globally')
if globally and not is_user_or_siteadmin:
- doc.addError(_("""The list administrator may not change the names
+ doc.addError(_(f"""The list administrator may not change the names
or addresses for this user's other subscriptions. However, the
subscription for this mailing list has been changed."""),
_('Note: '))
@@ -454,16 +454,16 @@ def main():
safenewaddr = Utils.websafe(newaddr)
if globally:
listname = mlist.real_name
- msg += _("""\
-The new address you requested %(newaddr)s is already a member of the
-%(listname)s mailing list, however you have also requested a global change of
+ msg += _(f"""\
+The new address you requested {newaddr} is already a member of the
+{listname} mailing list, however you have also requested a global change of
address. Upon confirmation, any other mailing list containing the address
-%(safeuser)s will be changed. """)
+{safeuser} will be changed. """)
# Don't return
else:
options_page(
mlist, doc, user, cpuser, userlang,
- _('The new address is already a member: %(newaddr)s'))
+ _(f'The new address is already a member: {newaddr}'))
print(doc.Format())
return
set_address = 1
@@ -483,7 +483,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
if cpuser is None:
cpuser = user
# Register the pending change after the list is locked
- msg += _('A confirmation message has been sent to %(newaddr)s. ')
+ msg += _(f'A confirmation message has been sent to {newaddr}. ')
mlist.Lock()
try:
try:
@@ -496,12 +496,12 @@ def sigterm_handler(signum, frame, mlist=mlist):
except Errors.MMHostileAddress:
msg = _('Illegal email address provided')
except Errors.MMAlreadyAMember:
- msg = _('%(newaddr)s is already a member of the list.')
+ msg = _(f'{newaddr} is already a member of the list.')
except Errors.MembershipIsBanned:
owneraddr = mlist.GetOwnerEmail()
- msg = _("""%(newaddr)s is banned from this list. If you
+ msg = _(f"""{newaddr} is banned from this list. If you
think this restriction is erroneous, please contact
- the list owners at %(owneraddr)s.""")
+ the list owners at {owneraddr}.""")
if set_membername:
mlist.Lock()
@@ -520,7 +520,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
# Is this list admin and is list admin allowed to change passwords.
if not (is_user_or_siteadmin
or mm_cfg.OWNERS_CAN_CHANGE_MEMBER_PASSWORDS):
- doc.addError(_("""The list administrator may not change the
+ doc.addError(_(f"""The list administrator may not change the
password for a user."""))
options_page(mlist, doc, user, cpuser, userlang)
print(doc.Format())
@@ -542,7 +542,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
# the list admin is /not/ allowed to change passwords globally.
pw_globally = cgidata.getfirst('pw-globally')
if pw_globally and not is_user_or_siteadmin:
- doc.addError(_("""The list administrator may not change the
+ doc.addError(_(f"""The list administrator may not change the
password for this user's other subscriptions. However, the
password for this mailing list has been changed."""),
_('Note: '))
@@ -568,7 +568,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
if not cgidata.getfirst('unsubconfirm'):
options_page(
mlist, doc, user, cpuser, userlang,
- _('''You must confirm your unsubscription request by turning
+ _(f'''You must confirm your unsubscription request by turning
on the checkbox below the Unsubscribe button. You
have not been unsubscribed!'''))
print(doc.Format())
@@ -613,16 +613,16 @@ def sigterm_handler(signum, frame, mlist=mlist):
doc.SetTitle(title)
doc.AddItem(Header(2, title))
if needapproval:
- doc.AddItem(_("""Your unsubscription request has been received and
+ doc.AddItem(_(f"""Your unsubscription request has been received and
forwarded on to the list moderators for approval. You will
receive notification once the list moderators have made their
decision."""))
else:
- doc.AddItem(_("""You have been successfully unsubscribed from the
- mailing list %(fqdn_listname)s. If you were receiving digest
+ doc.AddItem(_(f"""You have been successfully unsubscribed from the
+ mailing list {fqdn_listname}. If you were receiving digest
deliveries you may get one more digest. If you have any questions
about your unsubscription, please contact the list owners at
- %(owneraddr)s."""))
+ {owneraddr}."""))
doc.AddItem(mlist.GetMailmanFooter())
print(doc.Format())
return
@@ -688,7 +688,7 @@ def sigterm_handler(signum, frame, mlist=mlist):
# Some topics were selected. topicnames can actually be a string
# or a list of strings depending on whether more than one topic
# was selected or not.
- if not isinstance(topicnames, ListType):
+ if not isinstance(topicnames, list):
# Assume it was a bare string, so listify it
topicnames = [topicnames]
# unquote the topic names
@@ -767,7 +767,7 @@ def __bool__(self):
# /not/ if this is the list admin.
if globalopts:
if not is_user_or_siteadmin:
- doc.addError(_("""The list administrator may not change the
+ doc.addError(_(f"""The list administrator may not change the
options for this user's other subscriptions. However the
options for this mailing list subscription has been
changed."""), _('Note: '))
@@ -777,11 +777,11 @@ def __bool__(self):
# Now print the results
if cantdigest:
- msg = _('''The list administrator has disabled digest delivery for
+ msg = _(f'''The list administrator has disabled digest delivery for
this list, so your delivery option has not been set. However your
other options have been set successfully.''')
elif mustdigest:
- msg = _('''The list administrator has disabled non-digest delivery
+ msg = _(f'''The list administrator has disabled non-digest delivery
for this list, so your delivery option has not been set. However
your other options have been set successfully.''')
else:
@@ -896,7 +896,7 @@ def options_page(mlist, doc, user, cpuser, userlang, message=''):
units = _('days')
else:
units = _('day')
- replacements[''] = _('%(days)d %(units)s')
+ replacements[''] = _(f'%(days)d {units}')
replacements[''] = mlist.FormatBox('new-address')
replacements[''] = mlist.FormatBox(
@@ -936,9 +936,9 @@ def options_page(mlist, doc, user, cpuser, userlang, message=''):
mlist.FormatOptionButton(mm_cfg.ReceiveNonmatchingTopics, 1, user))
if cpuser is not None:
- replacements[''] = _('''
+ replacements[''] = _(f'''
You are subscribed to this list with the case-preserved address
-%(cpuser)s.''')
+{cpuser}.''')
else:
replacements[''] = ''
@@ -952,11 +952,11 @@ def loginpage(mlist, doc, user, lang):
realname = mlist.real_name
actionurl = mlist.GetScriptURL('options')
if user is None:
- title = _('%(realname)s list: member options login page')
+ title = _(f'{realname} list: member options login page')
extra = _('email address and ')
else:
safeuser = Utils.websafe(user)
- title = _('%(realname)s list: member options for user %(safeuser)s')
+ title = _(f'{realname} list: member options for user {safeuser}')
obuser = Utils.ObscureEmail(user)
extra = ''
# Set up the title
@@ -982,8 +982,8 @@ def loginpage(mlist, doc, user, lang):
form = Form(actionurl)
form.AddItem(Hidden('language', lang))
table = Table(width='100%', border=0, cellspacing=4, cellpadding=5)
- table.AddRow([_("""In order to change your membership option, you must
- first log in by giving your %(extra)smembership password in the section
+ table.AddRow([_(f"""In order to change your membership option, you must
+ first log in by giving your {extra}membership password in the section
below. If you don't remember your membership password, you can have it
emailed to you by clicking on the button below. If you just want to
unsubscribe from this list, click on the Unsubscribe button and a
@@ -1010,7 +1010,7 @@ def loginpage(mlist, doc, user, lang):
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
- table.AddRow([_("""By clicking on the Unsubscribe button, a
+ table.AddRow([_(f"""By clicking on the Unsubscribe button, a
confirmation message will be emailed to you. This message will have a
link that you should click on to complete the removal process (you can
also confirm by email; see the instructions in the confirmation
@@ -1022,7 +1022,7 @@ def loginpage(mlist, doc, user, lang):
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
- table.AddRow([_("""By clicking on the Remind button, your
+ table.AddRow([_(f"""By clicking on the Remind button, your
password will be emailed to you.""")])
table.AddRow([Center(SubmitButton('login-remind', _('Remind')))])
@@ -1136,7 +1136,7 @@ def topic_details(mlist, doc, user, cpuser, userlang, varhelp):
if not name:
options_page(mlist, doc, user, cpuser, userlang,
- _('Requested topic is not valid: %(topicname)s'))
+ _(f'Requested topic is not valid: {topicname}'))
print(doc.Format())
return
diff --git a/Mailman/Cgi/private.py b/Mailman/Cgi/private.py
index f193e357..034ed6f4 100644
--- a/Mailman/Cgi/private.py
+++ b/Mailman/Cgi/private.py
@@ -20,7 +20,7 @@
import os
import sys
-import cgi
+from Mailman.Utils import FieldStorage
import mimetypes
from Mailman import mm_cfg
@@ -106,8 +106,8 @@ def main():
except Errors.MMListError as e:
# Avoid cross-site scripting attacks
safelistname = Utils.websafe(listname)
- msg = _('No such list %(safelistname)s')
- doc.SetTitle(_("Private Archive Error - %(msg)s"))
+ msg = _(f'No such list {safelistname}')
+ doc.SetTitle(_(f"Private Archive Error - {msg}"))
doc.AddItem(Header(2, msg))
# Send this with a 404 status.
print('Status: 404 Not Found')
@@ -118,7 +118,7 @@ def main():
i18n.set_language(mlist.preferred_language)
doc.set_language(mlist.preferred_language)
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
try:
username = cgidata.getfirst('username', '').strip()
except TypeError:
@@ -155,7 +155,7 @@ def main():
# Are we processing a password reminder from the login screen?
if 'login-remind' in cgidata:
if username:
- message = Bold(FontSize('+1', _("""If you are a list member,
+ message = Bold(FontSize('+1', _(f"""If you are a list member,
your password has been emailed to you."""))).Format()
else:
message = Bold(FontSize('+1',
@@ -214,7 +214,7 @@ def main():
import gzip
f = gzip.open(true_filename, 'r')
else:
- f = open(true_filename, 'r')
+ f = open(true_filename, 'rb')
except IOError:
msg = _('Private archive file not found')
doc.SetTitle(msg)
@@ -223,6 +223,16 @@ def main():
print(doc.Format())
syslog('error', 'Private archive file not found: %s', true_filename)
else:
- print('Content-type: %s\n' % ctype)
- sys.stdout.write(f.read())
+ content = f.read()
f.close()
+ buffered = sys.stdout.getvalue()
+ sys.stdout.truncate(0)
+ sys.stdout.seek(0)
+ orig_stdout = sys.stdout
+ sys.stdout = sys.__stdout__
+ sys.stdout.write(buffered)
+ print('Content-type: %s\n' % ctype)
+ sys.stdout.flush()
+ sys.stdout.buffer.write(content)
+ sys.stdout.flush()
+ sys.stdout = orig_stdout
diff --git a/Mailman/Cgi/rmlist.py b/Mailman/Cgi/rmlist.py
index a30a2939..103cc4f7 100644
--- a/Mailman/Cgi/rmlist.py
+++ b/Mailman/Cgi/rmlist.py
@@ -18,7 +18,7 @@
from __future__ import print_function
import os
-import cgi
+from Mailman.Utils import FieldStorage
import sys
import errno
import shutil
@@ -41,7 +41,7 @@ def main():
doc = Document()
doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
try:
cgidata.getfirst('password', '')
except TypeError:
@@ -73,8 +73,8 @@ def main():
except Errors.MMListError as e:
# Avoid cross-site scripting attacks
safelistname = Utils.websafe(listname)
- title = _('No such list %(safelistname)s')
- doc.SetTitle(_('No such list %(safelistname)s'))
+ title = _(f'No such list {safelistname}')
+ doc.SetTitle(_(f'No such list {safelistname}'))
doc.AddItem(
Header(3,
Bold(FontAttr(title, color='#ff0000', size='+2'))))
@@ -185,12 +185,12 @@ def process_request(doc, cgidata, mlist):
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
if not problems:
- table.AddRow([_('''You have successfully deleted the mailing list
- %(listname)s.''')])
+ table.AddRow([_(f'''You have successfully deleted the mailing list
+ {listname}.''')])
else:
sitelist = Utils.get_site_email(mlist.host_name)
- table.AddRow([_('''There were some problems deleting the mailing list
- %(listname)s. Contact your site administrator at %(sitelist)s
+ table.AddRow([_(f'''There were some problems deleting the mailing list
+ {listname}. Contact your site administrator at {sitelist}
for details.''')])
doc.AddItem(table)
doc.AddItem('')
@@ -206,8 +206,8 @@ def process_request(doc, cgidata, mlist):
def request_deletion(doc, mlist, errmsg=None):
realname = mlist.real_name
- title = _('Permanently remove mailing list %(realname)s')
- doc.SetTitle(_('Permanently remove mailing list %(realname)s'))
+ title = _(f'Permanently remove mailing list {realname}')
+ doc.SetTitle(_(f'Permanently remove mailing list {realname}'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
@@ -220,7 +220,7 @@ def request_deletion(doc, mlist, errmsg=None):
FontAttr(_('Error: '), color='#ff0000', size='+2').Format() +
Italic(errmsg).Format()))])
- table.AddRow([_("""This page allows you as the list owner, to permanently
+ table.AddRow([_(f"""This page allows you as the list owner, to permanently
remove this mailing list from the system. This action is not
undoable so you should undertake it only if you are absolutely
sure this mailing list has served its purpose and is no longer necessary.
diff --git a/Mailman/Cgi/roster.py b/Mailman/Cgi/roster.py
index 33afdf11..d90e4de6 100644
--- a/Mailman/Cgi/roster.py
+++ b/Mailman/Cgi/roster.py
@@ -26,7 +26,7 @@
import sys
import os
-import cgi
+from Mailman.Utils import FieldStorage
import urllib.request, urllib.parse, urllib.error
from Mailman import mm_cfg
@@ -57,11 +57,11 @@ def main():
safelistname = Utils.websafe(listname)
# Send this with a 404 status.
print('Status: 404 Not Found')
- error_page(_('No such list %(safelistname)s'))
+ error_page(_(f'No such list {safelistname}'))
syslog('error', 'roster: No such list "%s": %s', listname, e)
return
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
# messages in form should go in selected language (if any...)
try:
@@ -116,7 +116,7 @@ def main():
doc.set_language(lang)
# Send this with a 401 status.
print('Status: 401 Unauthorized')
- error_page_doc(doc, _('%(realname)s roster authentication failed.'))
+ error_page_doc(doc, _(f'{realname} roster authentication failed.'))
doc.AddItem(mlist.GetMailmanFooter())
print(doc.Format())
remote = os.environ.get('HTTP_FORWARDED_FOR',
diff --git a/Mailman/Cgi/subscribe.py b/Mailman/Cgi/subscribe.py
index 0ea11d5e..1aff1ef8 100644
--- a/Mailman/Cgi/subscribe.py
+++ b/Mailman/Cgi/subscribe.py
@@ -20,7 +20,7 @@
import sys
import os
-import cgi
+from Mailman.Utils import FieldStorage
import time
import signal
import urllib.request, urllib.parse, urllib.error
@@ -65,7 +65,7 @@ def main():
# Avoid cross-site scripting attacks
safelistname = Utils.websafe(listname)
doc.AddItem(Header(2, _("Error")))
- doc.AddItem(Bold(_('No such list %(safelistname)s')))
+ doc.AddItem(Bold(_(f'No such list {safelistname}')))
# Send this with a 404 status.
print('Status: 404 Not Found')
print(doc.Format())
@@ -74,7 +74,7 @@ def main():
# See if the form data has a preferred language set, in which case, use it
# for the results. If not, use the list's preferred language.
- cgidata = cgi.FieldStorage()
+ cgidata = FieldStorage()
try:
language = cgidata.getfirst('language', '')
except TypeError:
@@ -153,10 +153,10 @@ def process_form(mlist, doc, cgidata, lang):
httpresp.close()
if not captcha_response['success']:
e_codes = COMMASPACE.join(captcha_response['error-codes'])
- results.append(_('reCAPTCHA validation failed: %(e_codes)s'))
+ results.append(_(f'reCAPTCHA validation failed: {e_codes}'))
except urllib.error.URLError as e:
e_reason = e.reason
- results.append(_('reCAPTCHA could not be validated: %(e_reason)s'))
+ results.append(_(f'reCAPTCHA could not be validated: {e_reason}'))
# Are we checking the hidden data?
if mm_cfg.SUBSCRIBE_FORM_SECRET:
@@ -245,7 +245,7 @@ def process_form(mlist, doc, cgidata, lang):
# Public rosters
privacy_results = ''
else:
- privacy_results = _("""\
+ privacy_results = _(f"""\
Your subscription request has been received, and will soon be acted upon.
Depending on the configuration of this mailing list, your subscription request
may have to be first confirmed by you via email, or approved by the list
@@ -259,15 +259,15 @@ def process_form(mlist, doc, cgidata, lang):
# Check for all the errors that mlist.AddMember can throw options on the
# web page for this cgi
except Errors.MembershipIsBanned:
- results = _("""The email address you supplied is banned from this
+ results = _(f"""The email address you supplied is banned from this
mailing list. If you think this restriction is erroneous, please
- contact the list owners at %(listowner)s.""")
+ contact the list owners at {listowner}.""")
except Errors.MMBadEmailError:
- results = _("""\
+ results = _(f"""\
The email address you supplied is not valid. (E.g. it must contain an
`@'.)""")
except Errors.MMHostileAddress:
- results = _("""\
+ results = _(f"""\
Your subscription is not allowed because the email address you gave is
insecure.""")
except Errors.MMSubscribeNeedsConfirmation:
@@ -275,10 +275,10 @@ def process_form(mlist, doc, cgidata, lang):
if privacy_results:
results = privacy_results
else:
- results = _("""\
+ results = _(f"""\
Confirmation from your email address is required, to prevent anyone from
subscribing you without permission. Instructions are being sent to you at
-%(email)s. Please note your subscription will not start until you confirm
+{email}. Please note your subscription will not start until you confirm
your subscription.""")
except Errors.MMNeedApproval as x:
# Results string depends on whether we have private rosters or not
@@ -287,8 +287,8 @@ def process_form(mlist, doc, cgidata, lang):
else:
# We need to interpolate into x.__str__()
x = _(str(x))
- results = _("""\
-Your subscription request was deferred because %(x)s. Your request has been
+ results = _(f"""\
+Your subscription request was deferred because {x}. Your request has been
forwarded to the list moderator. You will receive email informing you of the
moderator's decision when they get to your request.""")
except Errors.MMAlreadyPending:
@@ -313,9 +313,9 @@ def process_form(mlist, doc, cgidata, lang):
mlist.getMemberCPAddress(email),
mlist.GetBouncesEmail(),
_('Mailman privacy alert'),
- _("""\
+ _(f"""\
An attempt was made to subscribe your address to the mailing list
-%(listaddr)s. You are already subscribed to this mailing list.
+{listaddr}. You are already subscribed to this mailing list.
Note that the list membership is not public, so it is possible that a bad
person was trying to probe the list for its membership. This would be a
@@ -325,7 +325,7 @@ def process_form(mlist, doc, cgidata, lang):
subscribed to the list, then you can ignore this message. If you suspect that
an attempt is being made to covertly discover whether you are a member of this
list, and you are worried about your privacy, then feel free to send a message
-to the list administrator at %(listowner)s.
+to the list administrator at {listowner}.
"""), lang=mlang)
finally:
i18n.set_translation(otrans)
@@ -341,8 +341,8 @@ def process_form(mlist, doc, cgidata, lang):
if privacy_results:
results = privacy_results
else:
- results = _("""\
-You have been successfully subscribed to the %(realname)s mailing list.""")
+ results = _(f"""\
+You have been successfully subscribed to the {realname} mailing list.""")
# Show the results
print_results(mlist, results, doc, lang)
diff --git a/Mailman/Commands/cmd_confirm.py b/Mailman/Commands/cmd_confirm.py
index 1ef3e4b3..c7d3aeb3 100644
--- a/Mailman/Commands/cmd_confirm.py
+++ b/Mailman/Commands/cmd_confirm.py
@@ -43,6 +43,8 @@ def process(res, args):
res.results.append(gethelp(mlist))
return STOP
cookie = args[0]
+ if isinstance(cookie, bytes):
+ cookie = cookie.decode()
try:
results = mlist.ProcessConfirmation(cookie, res.msg)
except Errors.MMBadConfirmation as e:
@@ -53,29 +55,29 @@ def process(res, args):
approximately %(days)s days after the initial request. They also expire if
the request has already been handled in some way. If your confirmation has
expired, please try to re-submit your original request or message."""))
- except Errors.MMNeedApproval:
+ except Errors.MMNeedApproval as e:
res.results.append(_("""\
Your request has been forwarded to the list moderator for approval."""))
- except Errors.MMAlreadyAMember:
+ except Errors.MMAlreadyAMember as e:
# Some other subscription request for this address has
# already succeeded.
res.results.append(_('You are already subscribed.'))
- except Errors.NotAMemberError:
+ except Errors.NotAMemberError as e:
# They've already been unsubscribed
res.results.append(_("""\
You are not currently a member. Have you already unsubscribed or changed
your email address?"""))
- except Errors.MembershipIsBanned:
+ except Errors.MembershipIsBanned as e:
owneraddr = mlist.GetOwnerEmail()
res.results.append(_("""\
You are currently banned from subscribing to this list. If you think this
restriction is erroneous, please contact the list owners at
%(owneraddr)s."""))
- except Errors.HostileSubscriptionError:
+ except Errors.HostileSubscriptionError as e:
res.results.append(_("""\
You were not invited to this mailing list. The invitation has been discarded,
and both list administrators have been alerted."""))
- except Errors.MMBadPasswordError:
+ except Errors.MMBadPasswordError as e:
res.results.append(_("""\
Bad approval password given. Held message is still being held."""))
else:
diff --git a/Mailman/Commands/cmd_set.py b/Mailman/Commands/cmd_set.py
index 66d2e978..91bad858 100644
--- a/Mailman/Commands/cmd_set.py
+++ b/Mailman/Commands/cmd_set.py
@@ -117,7 +117,7 @@ def process(self, res, args):
res.results.append(_(DETAILS))
return STOP
subcmd = args.pop(0)
- methname = 'set_' + subcmd
+ methname = 'set_' + subcmd.decode('utf-8') if isinstance(subcmd, bytes) else 'set_' + subcmd
method = getattr(self, methname, None)
if method is None:
res.results.append(_('Bad set command: %(subcmd)s'))
diff --git a/Mailman/Commands/cmd_subscribe.py b/Mailman/Commands/cmd_subscribe.py
index 6cb61eaf..8a2404af 100644
--- a/Mailman/Commands/cmd_subscribe.py
+++ b/Mailman/Commands/cmd_subscribe.py
@@ -52,7 +52,8 @@ def process(res, args):
realname = None
# Parse the args
argnum = 0
- for arg in args:
+ for arg_bytes in args:
+ arg = arg_bytes.decode('utf-8')
if arg.lower().startswith('address='):
address = arg[8:]
elif argnum == 0:
@@ -94,8 +95,7 @@ def process(res, args):
# Watch for encoded names
try:
h = make_header(decode_header(realname))
- # BAW: in Python 2.2, use just unicode(h)
- realname = h.__unicode__()
+ realname = h.__str__()
except UnicodeError:
realname = u''
# Coerce to byte string if uh contains only ascii
diff --git a/Mailman/Commands/cmd_unsubscribe.py b/Mailman/Commands/cmd_unsubscribe.py
index 686b274a..38d5ec2c 100644
--- a/Mailman/Commands/cmd_unsubscribe.py
+++ b/Mailman/Commands/cmd_unsubscribe.py
@@ -43,7 +43,8 @@ def process(res, args):
password = None
address = None
argnum = 0
- for arg in args:
+ for arg_bytes in args:
+ arg = arg_bytes.decode('utf-8')
if arg.startswith('address='):
address = arg[8:]
elif argnum == 0:
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index daa9e672..697af315 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -933,6 +933,11 @@ DEFAULT_RESPOND_TO_POST_REQUESTS = Yes
# BAW: Eventually we may support weighted hash spaces.
# BAW: Although not enforced, the # of slices must be a power of 2
+# Distribution method for queue runners: 'hash' (default) or 'round_robin'
+# Hash-based distribution ensures same message always goes to same runner
+# Round-robin distribution provides more even load distribution
+QUEUE_DISTRIBUTION_METHOD = 'hash'
+
QRUNNERS = [
('ArchRunner', 1), # messages for the archiver
('BounceRunner', 2), # for processing the qfile/bounces directory
@@ -1781,7 +1786,7 @@ SITE_PW_FILE = os.path.join(DATA_DIR, 'adm.pw')
LISTCREATOR_PW_FILE = os.path.join(DATA_DIR, 'creator.pw')
# Import a bunch of version numbers
-from Version import *
+from .Version import *
# Vgg: Language descriptions and charsets dictionary, any new supported
# language must have a corresponding entry here. Key is the name of the
@@ -1798,41 +1803,41 @@ def add_language(code, description, charset, direction='ltr'):
LC_DESCRIPTIONS[code] = (description, charset, direction)
add_language('ar', _('Arabic'), 'utf-8', 'rtl')
-add_language('ast', _('Asturian'), 'iso-8859-1', 'ltr')
+add_language('ast', _('Asturian'), 'utf-8', 'ltr')
add_language('ca', _('Catalan'), 'utf-8', 'ltr')
-add_language('cs', _('Czech'), 'iso-8859-2', 'ltr')
-add_language('da', _('Danish'), 'iso-8859-1', 'ltr')
-add_language('de', _('German'), 'iso-8859-1', 'ltr')
-add_language('en', _('English (USA)'), 'us-ascii', 'ltr')
+add_language('cs', _('Czech'), 'utf-8', 'ltr')
+add_language('da', _('Danish'), 'utf-8', 'ltr')
+add_language('de', _('German'), 'utf-8', 'ltr')
+add_language('en', _('English (USA)'), 'utf-8', 'ltr')
add_language('eo', _('Esperanto'), 'utf-8', 'ltr')
-add_language('es', _('Spanish (Spain)'), 'iso-8859-1', 'ltr')
-add_language('et', _('Estonian'), 'iso-8859-15', 'ltr')
-add_language('eu', _('Euskara'), 'iso-8859-15', 'ltr') # Basque
+add_language('es', _('Spanish (Spain)'), 'utf-8', 'ltr')
+add_language('et', _('Estonian'), 'utf-8', 'ltr')
+add_language('eu', _('Euskara'), 'utf-8', 'ltr') # Basque
add_language('fa', _('Persian'), 'utf-8', 'rtl')
-add_language('fi', _('Finnish'), 'iso-8859-1', 'ltr')
-add_language('fr', _('French'), 'iso-8859-1', 'ltr')
+add_language('fi', _('Finnish'), 'utf-8', 'ltr')
+add_language('fr', _('French'), 'utf-8', 'ltr')
add_language('gl', _('Galician'), 'utf-8', 'ltr')
-add_language('el', _('Greek'), 'iso-8859-7', 'ltr')
+add_language('el', _('Greek'), 'utf-8', 'ltr')
add_language('he', _('Hebrew'), 'utf-8', 'rtl')
-add_language('hr', _('Croatian'), 'iso-8859-2', 'ltr')
-add_language('hu', _('Hungarian'), 'iso-8859-2', 'ltr')
-add_language('ia', _('Interlingua'), 'iso-8859-15', 'ltr')
-add_language('it', _('Italian'), 'iso-8859-1', 'ltr')
-add_language('ja', _('Japanese'), 'euc-jp', 'ltr')
-add_language('ko', _('Korean'), 'euc-kr', 'ltr')
-add_language('lt', _('Lithuanian'), 'iso-8859-13', 'ltr')
-add_language('nl', _('Dutch'), 'iso-8859-1', 'ltr')
-add_language('no', _('Norwegian'), 'iso-8859-1', 'ltr')
-add_language('pl', _('Polish'), 'iso-8859-2', 'ltr')
-add_language('pt', _('Portuguese'), 'iso-8859-1', 'ltr')
-add_language('pt_BR', _('Portuguese (Brazil)'), 'iso-8859-1', 'ltr')
+add_language('hr', _('Croatian'), 'utf-8', 'ltr')
+add_language('hu', _('Hungarian'), 'utf-8', 'ltr')
+add_language('ia', _('Interlingua'), 'utf-8', 'ltr')
+add_language('it', _('Italian'), 'utf-8', 'ltr')
+add_language('ja', _('Japanese'), 'utf-8', 'ltr')
+add_language('ko', _('Korean'), 'utf-8', 'ltr')
+add_language('lt', _('Lithuanian'), 'utf-8', 'ltr')
+add_language('nl', _('Dutch'), 'utf-8', 'ltr')
+add_language('no', _('Norwegian'), 'utf-8', 'ltr')
+add_language('pl', _('Polish'), 'utf-8', 'ltr')
+add_language('pt', _('Portuguese'), 'utf-8', 'ltr')
+add_language('pt_BR', _('Portuguese (Brazil)'), 'utf-8', 'ltr')
add_language('ro', _('Romanian'), 'utf-8', 'ltr')
add_language('ru', _('Russian'), 'utf-8', 'ltr')
add_language('sk', _('Slovak'), 'utf-8', 'ltr')
-add_language('sl', _('Slovenian'), 'iso-8859-2', 'ltr')
+add_language('sl', _('Slovenian'), 'utf-8', 'ltr')
add_language('sr', _('Serbian'), 'utf-8', 'ltr')
-add_language('sv', _('Swedish'), 'iso-8859-1', 'ltr')
-add_language('tr', _('Turkish'), 'iso-8859-9', 'ltr')
+add_language('sv', _('Swedish'), 'utf-8', 'ltr')
+add_language('tr', _('Turkish'), 'utf-8', 'ltr')
add_language('uk', _('Ukrainian'), 'utf-8', 'ltr')
add_language('vi', _('Vietnamese'), 'utf-8', 'ltr')
add_language('zh_CN', _('Chinese (China)'), 'utf-8', 'ltr')
diff --git a/Mailman/Deliverer.py b/Mailman/Deliverer.py
index 61f63e84..a4790c1f 100644
--- a/Mailman/Deliverer.py
+++ b/Mailman/Deliverer.py
@@ -71,7 +71,7 @@ def SendSubscribeAck(self, name, password, digest, text=''):
realname = self.real_name
msg = Message.UserNotification(
self.GetMemberAdminEmail(name), self.GetRequestEmail(),
- _('Welcome to the "%(realname)s" mailing list%(digmode)s'),
+ _(f'Welcome to the "{realname}" mailing list{digmode}'),
text, pluser)
msg['X-No-Archive'] = 'yes'
msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
@@ -81,7 +81,7 @@ def SendUnsubscribeAck(self, addr, lang):
i18n.set_language(lang)
msg = Message.UserNotification(
self.GetMemberAdminEmail(addr), self.GetBouncesEmail(),
- _('You have been unsubscribed from the %(realname)s mailing list'),
+ _(f'You have been unsubscribed from the {realname} mailing list'),
Utils.wrap(self.goodbye_msg), lang)
msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
@@ -108,7 +108,7 @@ def MailUserPassword(self, user):
# Now send the user his password
cpuser = self.getMemberCPAddress(user)
recipient = self.GetMemberAdminEmail(cpuser)
- subject = _('%(listfullname)s mailing list reminder')
+ subject = _(f'{listfullname} mailing list reminder')
# Get user's language and charset
lang = self.getMemberLanguage(user)
cset = Utils.GetCharSet(lang)
@@ -116,7 +116,7 @@ def MailUserPassword(self, user):
# TK: Make unprintables to ?
# The list owner should allow users to set language options if they
# want to use non-us-ascii characters in password and send it back.
- password = str(password, cset, 'replace').encode(cset, 'replace')
+ #password = str(password, cset, 'replace').encode(cset, 'replace')
# get the text from the template
text = Utils.maketext(
'userpass.txt',
@@ -161,7 +161,7 @@ def SendHostileSubscriptionNotice(self, listname, address):
msg = Message.OwnerNotification(
self,
_('Hostile subscription attempt detected'),
- Utils.wrap(_("""%(address)s was invited to a different mailing
+ Utils.wrap(_(f"""{address} was invited to a different mailing
list, but in a deliberate malicious attempt they tried to confirm the
invitation to your list. We just thought you'd like to know. No further
action by you is required.""")))
@@ -180,7 +180,7 @@ def SendHostileSubscriptionNotice(self, listname, address):
msg = Message.OwnerNotification(
mlist,
_('Hostile subscription attempt detected'),
- Utils.wrap(_("""You invited %(address)s to your list, but in a
+ Utils.wrap(_(f"""You invited {address} to your list, but in a
deliberate malicious attempt, they tried to confirm the invitation to a
different list. We just thought you'd like to know. No further action by you
is required.""")))
@@ -213,7 +213,7 @@ def sendProbe(self, member, msg):
otrans = i18n.get_translation()
i18n.set_language(ulang)
try:
- subject = _('%(listname)s mailing list probe message')
+ subject = _(f'{listname} mailing list probe message')
finally:
i18n.set_translation(otrans)
outer = Message.UserNotification(member, probeaddr, subject,
diff --git a/Mailman/Errors.py b/Mailman/Errors.py
index a836979f..3410e1f4 100644
--- a/Mailman/Errors.py
+++ b/Mailman/Errors.py
@@ -52,21 +52,21 @@ class MMCookieError(MMAuthenticationError): pass
class MMExpiredCookieError(MMCookieError): pass
class MMInvalidCookieError(MMCookieError): pass
-class MMMustDigestError(object): pass
-class MMCantDigestError(object): pass
-class MMNeedApproval(object):
+class MMMustDigestError(Exception): pass
+class MMCantDigestError(Exception): pass
+class MMNeedApproval(Exception):
def __init__(self, message=None):
self.message = message
def __str__(self):
return self.message or ''
-class MMSubscribeNeedsConfirmation(object): pass
-class MMBadConfirmation(object):
+class MMSubscribeNeedsConfirmation(Exception): pass
+class MMBadConfirmation(Exception):
def __init__(self, message=None):
self.message = message
def __str__(self):
return self.message or ''
-class MMAlreadyDigested(object): pass
-class MMAlreadyUndigested(object): pass
+class MMAlreadyDigested(Exception): pass
+class MMAlreadyUndigested(Exception): pass
MODERATED_LIST_MSG = "Moderated list"
IMPLICIT_DEST_MSG = "Implicit destination"
diff --git a/Mailman/Gui/GUIBase.py b/Mailman/Gui/GUIBase.py
index 2f1b4d29..52f2f753 100644
--- a/Mailman/Gui/GUIBase.py
+++ b/Mailman/Gui/GUIBase.py
@@ -61,7 +61,7 @@ def _getValidValue(self, mlist, property, wtype, val):
if wtype in (mm_cfg.EmailList, mm_cfg.EmailListEx):
# BAW: value might already be a list, if this is coming from
# config_list input. Sigh.
- if isinstance(val, ListType):
+ if isinstance(val, list):
return val
addrs = []
bad_addrs = []
@@ -124,7 +124,7 @@ def _getValidValue(self, mlist, property, wtype, val):
# Checkboxes return a list of the selected items, even if only one is
# selected.
if wtype == mm_cfg.Checkbox:
- if isinstance(val, ListType):
+ if isinstance(val, list):
return val
return [val]
if wtype == mm_cfg.FileUpload:
@@ -162,10 +162,14 @@ def handleForm(self, mlist, category, subcat, cgidata, doc):
val = cgidata[uploadprop].value
elif property not in cgidata:
continue
- elif isinstance(cgidata[property], ListType):
+ elif isinstance(cgidata[property], list):
val = [x.value for x in cgidata[property]]
else:
- val = cgidata[property].value
+ field = cgidata[property]
+ if hasattr(field, "value"):
+ val = field.value
+ else:
+ val = field
# Coerce the value to the expected type, raising exceptions if the
# value is invalid.
try:
diff --git a/Mailman/Gui/General.py b/Mailman/Gui/General.py
index ecfa8eff..89319449 100644
--- a/Mailman/Gui/General.py
+++ b/Mailman/Gui/General.py
@@ -567,7 +567,7 @@ def _setValue(self, mlist, property, val, doc):
else:
mlist.info = val
elif property == 'admin_member_chunksize' and (val < 1
- or not isinstance(val, IntType)):
+ or not isinstance(val, int)):
doc.addError(_("""admin_member_chunksize attribute not
changed! It must be an integer > 0."""))
elif property == 'host_name':
@@ -595,4 +595,4 @@ def getValue(self, mlist, kind, varname, params):
if varname != 'subject_prefix':
return None
# The subject_prefix may be Unicode
- return Utils.uncanonstr(mlist.subject_prefix, mlist.preferred_language)
+ return Utils.uncanonstr(mlist.subject_prefix, mlist.preferred_language).decode() # Does this break encodings?
diff --git a/Mailman/HTMLFormatter.py b/Mailman/HTMLFormatter.py
index 677b7f62..d86a13ce 100644
--- a/Mailman/HTMLFormatter.py
+++ b/Mailman/HTMLFormatter.py
@@ -48,7 +48,7 @@ def GetMailmanFooter(self):
hostname = self.host_name
listinfo_link = Link(self.GetScriptURL('listinfo'), realname).Format()
owner_link = Link('mailto:' + self.GetOwnerEmail(), ownertext).Format()
- innertext = _('%(listinfo_link)s list run by %(owner_link)s')
+ innertext = _(f'{listinfo_link} list run by {owner_link}')
return Container(
'',
Address(
@@ -56,11 +56,11 @@ def GetMailmanFooter(self):
innertext,
' ',
Link(self.GetScriptURL('admin'),
- _('%(realname)s administrative interface')),
+ _(f'{realname} administrative interface')),
_(' (requires authorization)'),
' ',
Link(Utils.ScriptURL('listinfo'),
- _('Overview of all %(hostname)s mailing lists')),
+ _(f'Overview of all {hostname} mailing lists')),
'
', MailmanLogo()))).Format()
def FormatUsers(self, digest, lang=None, list_hidden=False):
@@ -207,13 +207,13 @@ def FormatSubscriptionMsg(self):
if msg:
msg += ' '
if self.private_roster == 1:
- msg += _('''This is %(also)sa private list, which means that the
+ msg += _(f'''This is {also}a private list, which means that the
list of members is not available to non-members.''')
elif self.private_roster:
- msg += _('''This is %(also)sa hidden list, which means that the
+ msg += _(f'''This is {also}a hidden list, which means that the
list of members is available only to the list administrator.''')
else:
- msg += _('''This is %(also)sa public list, which means that the
+ msg += _(f'''This is {also}a public list, which means that the
list of members list is available to everyone.''')
if self.obscure_addresses:
msg += _(''' (but we obscure the addresses so they are not
@@ -221,10 +221,10 @@ def FormatSubscriptionMsg(self):
if self.umbrella_list:
sfx = self.umbrella_member_suffix
- msg += _("""
(Note that this is an umbrella list, intended to
+ msg += _(f"""
(Note that this is an umbrella list, intended to
have only other mailing lists as members. Among other things,
this means that your confirmation request will be sent to the
- `%(sfx)s' account for your address.)""")
+ `{sfx}' account for your address.)""")
return msg
def FormatUndigestButton(self):
@@ -255,8 +255,8 @@ def FormatEditingOption(self, lang):
either = ''
realname = self.real_name
- text = (_('''To unsubscribe from %(realname)s, get a password reminder,
- or change your subscription options %(either)senter your subscription
+ text = (_(f'''To unsubscribe from {realname}, get a password reminder,
+ or change your subscription options {either}enter your subscription
email address:
''')
+ TextBox('email', size=30).Format()
@@ -277,10 +277,10 @@ def RestrictedListMessage(self, which, restriction):
return ''
elif restriction == 1:
return _(
- '''(%(which)s is only available to the list
+ f'''({which} is only available to the list
members.)''')
else:
- return _('''(%(which)s is only available to the list
+ return _(f'''({which} is only available to the list
administrator.)''')
def FormatRosterOptionForUser(self, lang):
@@ -341,10 +341,9 @@ def FormatFormEnd(self):
return ''
def FormatBox(self, name, size=20, value=''):
- if isinstance(value, str):
- safevalue = Utils.websafe(value)
- else:
- safevalue = value
+ if isinstance(value, bytes):
+ value = value.decode('utf-8')
+ safevalue = Utils.websafe(value)
return '' % (
name, size, safevalue)
diff --git a/Mailman/Handlers/Approve.py b/Mailman/Handlers/Approve.py
index 4e6e57c6..4dad429d 100644
--- a/Mailman/Handlers/Approve.py
+++ b/Mailman/Handlers/Approve.py
@@ -84,7 +84,8 @@ def process(mlist, msg, msgdata):
for lineno, line in zip(list(range(len(lines))), lines):
if line.strip():
break
- i = line.find(':')
+
+ i = line.find(b':')
if i >= 0:
name = line[:i]
value = line[i+1:]
@@ -121,7 +122,7 @@ def process(mlist, msg, msgdata):
# If we don't find the pattern in the decoded part, but we do
# find it after stripping HTML tags, we don't know how to remove
# it, so we just reject the post.
- pattern = name + ':(\xA0|\s| )*' + re.escape(passwd)
+ pattern = name + r':(\xA0|\s| )*' + re.escape(passwd)
for part in typed_subpart_iterator(msg, 'text'):
if part is not None and part.get_payload() is not None:
lines = part.get_payload(decode=True)
diff --git a/Mailman/Handlers/Cleanse.py b/Mailman/Handlers/Cleanse.py
index 850875ad..2cf4acec 100644
--- a/Mailman/Handlers/Cleanse.py
+++ b/Mailman/Handlers/Cleanse.py
@@ -97,3 +97,8 @@ def process(mlist, msg, msgdata):
del msg['x-confirm-reading-to']
# Pegasus mail uses this one... sigh
del msg['x-pmrqc']
+
+ # Remove any header whose value is not a string.
+ for h, v in list(msg.items()):
+ if not isinstance(v, str):
+ del msg[h]
diff --git a/Mailman/Handlers/CookHeaders.py b/Mailman/Handlers/CookHeaders.py
index 04fb810f..40ce483f 100644
--- a/Mailman/Handlers/CookHeaders.py
+++ b/Mailman/Handlers/CookHeaders.py
@@ -38,11 +38,7 @@
COMMASPACE = ', '
MAXLINELEN = 78
-
-def _isunicode(s):
- return isinstance(s, UnicodeType)
-
-nonascii = re.compile('[^\s!-~]')
+nonascii = re.compile(r'[^\s!-~]')
def uheader(mlist, s, header_name=None, continuation_ws=' ', maxlinelen=None):
# Get the charset to encode the string in. Then search if there is any
@@ -50,7 +46,12 @@ def uheader(mlist, s, header_name=None, continuation_ws=' ', maxlinelen=None):
# us-ascii then we use iso-8859-1 instead. If the string is ascii only
# we use 'us-ascii' if another charset is specified.
charset = Utils.GetCharSet(mlist.preferred_language)
- if nonascii.search(s):
+ if isinstance(s, bytes):
+ search_string = s.decode()
+ else:
+ search_string = s
+
+ if nonascii.search(search_string):
# use list charset but ...
if charset == 'us-ascii':
charset = 'iso-8859-1'
@@ -160,7 +161,12 @@ def process(mlist, msg, msgdata):
# likewise, the list's real_name which should be ascii, but use the
# charset of the list's preferred_language which should be a superset.
lcs = Utils.GetCharSet(mlist.preferred_language)
- ulrn = str(mlist.real_name, lcs, errors='replace')
+
+ if isinstance(mlist.real_name, str):
+ ulrn = mlist.real_name
+ else:
+ ulrn = str(mlist.real_name, lcs, errors='replace')
+
# get translated 'via' with dummy replacements
realname = '%(realname)s'
lrn = '%(lrn)s'
@@ -170,9 +176,14 @@ def process(mlist, msg, msgdata):
i18n.set_language(mlist.preferred_language)
via = _('%(realname)s via %(lrn)s')
i18n.set_translation(otrans)
- uvia = str(via, lcs, errors='replace')
+
+ if isinstance(via, str):
+ uvia = via
+ else:
+ uvia = str(via, lcs, errors='replace')
+
# Replace the dummy replacements.
- uvia = re.sub(u'%\(lrn\)s', ulrn, re.sub(u'%\(realname\)s', urn, uvia))
+ uvia = re.sub(u'%\\(lrn\\)s', ulrn, re.sub(u'%\\(realname\\)s', urn, uvia))
# And get an RFC 2047 encoded header string.
dn = str(Header(uvia, lcs))
change_header('From',
@@ -392,18 +403,18 @@ def prefix_subject(mlist, msg, msgdata):
# range. It is safe to use unicode string when manupilating header
# contents with re module. It would be best to return unicode in
# ch_oneline() but here is temporary solution.
- subject = str(subject, cset)
+ subject = subject.__str__() #TODO will this break some encodings?
# If the subject_prefix contains '%d', it is replaced with the
# mailing list sequential number. Sequential number format allows
# '%d' or '%05d' like pattern.
prefix_pattern = re.escape(prefix)
# unescape '%' :-<
- prefix_pattern = '%'.join(prefix_pattern.split(r'\%'))
- p = re.compile('%\d*d')
+ prefix_pattern = prefix_pattern.replace(r'\%', '%')
+ p = re.compile(r'%\d*d')
if p.search(prefix, 1):
# prefix have number, so we should search prefix w/number in subject.
# Also, force new style.
- prefix_pattern = p.sub(r'\s*\d+\s*', prefix_pattern)
+ prefix_pattern = p.sub(r'\\s*\\d+\\s*', prefix_pattern)
old_style = False
else:
old_style = mm_cfg.OLD_STYLE_PREFIXING
@@ -413,7 +424,7 @@ def prefix_subject(mlist, msg, msgdata):
# leading space after stripping the prefix. It is not known what MUA would
# create such a Subject:, but the issue was reported.
rematch = re.match(
- '(\s*(RE|AW|SV|VS)\s*(\[\d+\])?\s*:\s*)+',
+ r'(\s*(RE|AW|SV|VS)\s*(\[\d+\])?\s*:\s*)+',
subject, re.I)
if rematch:
subject = subject[rematch.end():]
@@ -432,6 +443,8 @@ def prefix_subject(mlist, msg, msgdata):
subject = _('(no subject)')
i18n.set_translation(otrans)
cset = Utils.GetCharSet(mlist.preferred_language)
+ if isinstance(subject, str):
+ subject = subject.encode()
subject = str(subject, cset)
# and substitute %d in prefix with post_id
try:
@@ -498,9 +511,8 @@ def ch_oneline(headerstr):
cset = x[1]
break
h = make_header(d)
- ustr = h.__unicode__()
- oneline = u''.join(ustr.splitlines())
- return oneline.encode(cset, 'replace'), cset
+ ustr = h
+ return ustr, cset
except (LookupError, UnicodeError, ValueError, HeaderParseError):
# possibly charset problem. return with undecoded string in one line.
return ''.join(headerstr.splitlines()), 'us-ascii'
diff --git a/Mailman/Handlers/Decorate.py b/Mailman/Handlers/Decorate.py
index f54ddf8d..43338768 100644
--- a/Mailman/Handlers/Decorate.py
+++ b/Mailman/Handlers/Decorate.py
@@ -18,6 +18,7 @@
"""Decorate a message by sticking the header and footer around it."""
from builtins import str
+import codecs
import re
from email.mime.text import MIMEText
@@ -40,7 +41,7 @@ def process(mlist, msg, msgdata):
# Calculate the extra personalization dictionary. Note that the
# length of the recips list better be exactly 1.
recips = msgdata.get('recips')
- assert type(recips) == ListType and len(recips) == 1
+ assert type(recips) == list and len(recips) == 1
member = recips[0].lower()
d['user_address'] = member
try:
@@ -102,7 +103,11 @@ def process(mlist, msg, msgdata):
else:
ufooter = str(footer, lcset, 'ignore')
try:
- oldpayload = str(msg.get_payload(decode=True), mcset)
+ oldpayload = msg.get_payload(decode=True)
+ if isinstance(oldpayload, bytes):
+ oldpayload = oldpayload.decode(encoding=mcset)
+ if Utils.needs_unicode_escape_decode(oldpayload):
+ oldpayload = codecs.decode(oldpayload, 'unicode_escape')
frontsep = endsep = u''
if header and not header.endswith('\n'):
frontsep = u'\n'
@@ -135,7 +140,7 @@ def process(mlist, msg, msgdata):
# The next easiest thing to do is just prepend the header and append
# the footer as additional subparts
payload = msg.get_payload()
- if not isinstance(payload, ListType):
+ if not isinstance(payload, list):
payload = [payload]
if footer:
mimeftr = MIMEText(footer, 'plain', lcset)
@@ -205,7 +210,7 @@ def decorate(mlist, template, what, extradict=None):
# `what' is just a descriptive phrase used in the log message
# If template is only whitespace, ignore it.
- if len(re.sub('\s', '', template)) == 0:
+ if len(re.sub(r'\s', '', template)) == 0:
return ''
# BAW: We've found too many situations where Python can be fooled into
diff --git a/Mailman/Handlers/Hold.py b/Mailman/Handlers/Hold.py
index f7c7d1a0..09bec6b4 100644
--- a/Mailman/Handlers/Hold.py
+++ b/Mailman/Handlers/Hold.py
@@ -29,6 +29,7 @@
"""
import email
+from email.parser import Parser
from email.mime.text import MIMEText
from email.mime.message import MIMEMessage
import email.utils
@@ -173,7 +174,7 @@ def process(mlist, msg, msgdata):
# Is the message too big?
if mlist.max_message_size > 0:
bodylen = 0
- for line in email.Iterators.body_line_iterator(msg):
+ for line in email.iterators.body_line_iterator(msg):
bodylen += len(line)
for part in msg.walk():
if part.preamble:
@@ -197,11 +198,7 @@ def hold_for_approval(mlist, msg, msgdata, exc):
# that the message can be approved or denied via email as well as the
# web.
#
- # XXX We use the weird type(type) construct below because in Python 2.1,
- # type is a function not a type and so can't be used as the second
- # argument in isinstance(). However, in Python 2.5, exceptions are
- # new-style classes and so are not of ClassType.
- if isinstance(exc, ClassType) or isinstance(exc, type(type)):
+ if isinstance(exc, type):
# Go ahead and instantiate it now.
exc = exc()
listname = mlist.real_name
diff --git a/Mailman/Handlers/MimeDel.py b/Mailman/Handlers/MimeDel.py
index fc6628a0..f583368f 100644
--- a/Mailman/Handlers/MimeDel.py
+++ b/Mailman/Handlers/MimeDel.py
@@ -27,6 +27,7 @@
import os
import errno
import tempfile
+import html2text
from os.path import splitext
from email.iterators import typed_subpart_iterator
@@ -35,7 +36,6 @@
from Mailman import Errors
from Mailman.Message import UserNotification
from Mailman.Queue.sbcache import get_switchboard
-from Mailman.Logging.Syslog import syslog
from Mailman.Version import VERSION
from Mailman.i18n import _
from Mailman.Utils import oneline
@@ -230,28 +230,27 @@ def recast_multipart(msg):
def to_plaintext(msg):
changedp = 0
- for subpart in typed_subpart_iterator(msg, 'text', 'html'):
- filename = tempfile.mktemp('.html')
- fp = open(filename, 'w')
- try:
- fp.write(subpart.get_payload(decode=1))
- fp.close()
- cmd = os.popen(mm_cfg.HTML_TO_PLAIN_TEXT_COMMAND %
- {'filename': filename})
- plaintext = cmd.read()
- rtn = cmd.close()
- if rtn:
- syslog('error', 'HTML->text/plain error: %s', rtn)
- finally:
- try:
- os.unlink(filename)
- except OSError as e:
- if e.errno != errno.ENOENT: raise
+ # Get the subparts (ensure you're iterating through them)
+ subparts = list(typed_subpart_iterator(msg, 'text', 'html'))
+
+ # Iterate through the subparts
+ for subpart in subparts:
+
+ # Get the HTML content (ensure it's decoded if it's in bytes)
+ html_content = subpart.get_payload(decode=1) # Get the payload as bytes
+
+ if isinstance(html_content, bytes):
+ html_content = html_content.decode('utf-8') # Decode bytes to string
+
+ # Now convert HTML to plain text
+ plaintext = html2text.html2text(html_content)
+
# Now replace the payload of the subpart and twiddle the Content-Type:
- del subpart['content-transfer-encoding']
- subpart.set_payload(plaintext)
- subpart.set_type('text/plain')
+ del subpart['content-transfer-encoding'] # Remove encoding if necessary
+ subpart.set_payload(plaintext) # Set the new plaintext payload
+ subpart.set_type('text/plain') # Change the content type to 'text/plain'
changedp = 1
+
return changedp
diff --git a/Mailman/Handlers/SMTPDirect.py b/Mailman/Handlers/SMTPDirect.py
index 9d716d0e..aa98357e 100644
--- a/Mailman/Handlers/SMTPDirect.py
+++ b/Mailman/Handlers/SMTPDirect.py
@@ -31,6 +31,7 @@
import time
import socket
import smtplib
+from smtplib import SMTPException
from base64 import b64encode
from Mailman import mm_cfg
@@ -56,17 +57,37 @@ def __init__(self):
def __connect(self):
self.__conn = smtplib.SMTP()
self.__conn.set_debuglevel(mm_cfg.SMTPLIB_DEBUG_LEVEL)
- self.__conn.connect(mm_cfg.SMTPHOST, mm_cfg.SMTPPORT)
+
+ # Ensure we have a valid hostname for the connection
+ smtp_host = mm_cfg.SMTPHOST
+ if not smtp_host or smtp_host.startswith('.') or smtp_host == '@URLHOST@':
+ smtp_host = 'localhost'
+
+ # Log the hostname being used for debugging
+ syslog('smtp-failure', 'SMTP connection hostname: %s (original: %s)',
+ smtp_host, mm_cfg.SMTPHOST)
+
+ self.__conn.connect(smtp_host, mm_cfg.SMTPPORT)
if mm_cfg.SMTP_AUTH:
if mm_cfg.SMTP_USE_TLS:
+ # Log the hostname being used for TLS
+ syslog('smtp-failure', 'TLS connection hostname: %s', self.__conn._host)
try:
+ # Ensure the hostname is set for TLS
+ if not self.__conn._host:
+ self.__conn._host = smtp_host
+ syslog('smtp-failure', 'Set TLS hostname to: %s', smtp_host)
self.__conn.starttls()
except SMTPException as e:
syslog('smtp-failure', 'SMTP TLS error: %s', e)
self.quit()
raise
try:
- self.__conn.ehlo(mm_cfg.SMTP_HELO_HOST)
+ # Use a valid hostname for EHLO, fallback to localhost if SMTP_HELO_HOST is empty or invalid
+ helo_host = mm_cfg.SMTP_HELO_HOST
+ if not helo_host or helo_host.startswith('.') or helo_host == '@URLHOST@':
+ helo_host = 'localhost'
+ self.__conn.ehlo(helo_host)
except SMTPException as e:
syslog('smtp-failure', 'SMTP EHLO error: %s', e)
self.quit()
@@ -93,6 +114,8 @@ def sendmail(self, envsender, recips, msgtext):
if self.__conn is None:
self.__connect()
try:
+ if isinstance( msgtext, str ):
+ msgtext = msgtext.encode('utf-8', errors='ignore')
results = self.__conn.sendmail(envsender, recips, msgtext)
except smtplib.SMTPException:
# For safety, close this connection. The next send attempt will
@@ -359,7 +382,7 @@ def verpdeliver(mlist, msg, msgdata, envsender, failures, conn):
charset = 'iso-8859-1'
charset = Charset(charset)
codec = charset.input_codec or 'ascii'
- if not isinstance(name, UnicodeType):
+ if not isinstance(name, str):
name = str(name, codec, 'replace')
name = Header(name, charset).encode()
msgcopy['To'] = formataddr((name, recip))
diff --git a/Mailman/Handlers/Scrubber.py b/Mailman/Handlers/Scrubber.py
index 6708c3e0..07eda63a 100644
--- a/Mailman/Handlers/Scrubber.py
+++ b/Mailman/Handlers/Scrubber.py
@@ -111,7 +111,12 @@ def calculate_attachments_dir(mlist, msg, msgdata):
datedir = safe_strftime(fmt, datestr)
if not datedir:
# What next? Unixfrom, I guess.
- parts = msg.get_unixfrom().split()
+ unixfrom = msg.get_unixfrom()
+ if unixfrom:
+ parts = unixfrom.split()
+ else:
+ # Fallback if no unixfrom
+ parts = []
try:
month = {'Jan':1, 'Feb':2, 'Mar':3, 'Apr':4, 'May':5, 'Jun':6,
'Jul':7, 'Aug':8, 'Sep':9, 'Oct':10, 'Nov':11, 'Dec':12,
@@ -132,6 +137,8 @@ def calculate_attachments_dir(mlist, msg, msgdata):
msgid = msg['message-id']
if msgid is None:
msgid = msg['Message-ID'] = Utils.unique_message_id(mlist)
+
+ msgid = msgid.encode()
# We assume that the message id actually /is/ unique!
digest = sha_new(msgid).hexdigest()
return os.path.join('attachments', datedir, digest[:4] + digest[-4:])
@@ -206,7 +213,7 @@ def process(mlist, msg, msgdata=None):
Name: %(filename)s
URL: %(url)s
"""), lcset)
- elif ctype == 'text/html' and isinstance(sanitize, IntType):
+ elif ctype == 'text/html' and isinstance(sanitize, int):
if sanitize == 0:
if outer:
raise DiscardMessage
@@ -379,16 +386,26 @@ def doreplace(s):
if isinstance(t, str):
if not t.endswith('\n'):
t += '\n'
- text.append(t)
+ elif isinstance(t, bytes):
+ if not t.endswith(b'\n'):
+ t += b'\n'
+ text.append(t)
# Now join the text and set the payload
sep = _('-------------- next part --------------\n')
# The i18n separator is in the list's charset. Coerce it to the
# message charset.
try:
- s = str(sep, lcset, 'replace')
- sep = s.encode(charset, 'replace')
- except (UnicodeError, LookupError, ValueError,
- AssertionError):
+ if isinstance(sep, bytes):
+ # Only decode if it's a bytes object
+ s = sep.decode(lcset, 'replace')
+ sep = s.encode(charset, 'replace')
+ else:
+ # If it's already a str, no need to decode
+ sep = sep.encode(charset, 'replace')
+ except (UnicodeError, LookupError, ValueError, AssertionError) as e:
+ # If something failed and we are still a string, fall back to UTF-8
+ if isinstance(sep, str):
+ sep = sep.encode('utf-8', 'replace')
pass
replace_payload_by_text(msg, sep.join(text), charset)
if format:
@@ -397,7 +414,6 @@ def doreplace(s):
msg.set_param('DelSp', delsp)
return msg
-
def makedirs(dir):
# Create all the directories to store this attachment in
@@ -405,12 +421,17 @@ def makedirs(dir):
os.makedirs(dir, 0o02775)
# Unfortunately, FreeBSD seems to be broken in that it doesn't honor
# the mode arg of mkdir().
- def twiddle(arg, dirname, names):
- os.chmod(dirname, 0o02775)
- os.path.walk(dir, twiddle, None)
- except OSError as e:
- if e.errno != errno.EEXIST: raise
+ def twiddle(arg, dirpath, dirnames):
+ for dirname in dirnames:
+ # Construct the full path for each directory
+ full_path = os.path.join(dirpath, dirname)
+ os.chmod(full_path, 0o02775)
+ for dirpath, dirnames, filenames in os.walk(dir):
+ twiddle(None, dirpath, dirnames)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
def save_attachment(mlist, msg, dir, filter_html=True):
@@ -518,9 +539,25 @@ def save_attachment(mlist, msg, dir, filter_html=True):
# Is it a message/rfc822 attachment?
elif ctype == 'message/rfc822':
submsg = msg.get_payload()
+
+ # submsg is usually a list containing a single Message object.
+ # We need to extract that Message object. (taken from Utils.websafe())
+ if isinstance(submsg, list) or isinstance(submsg, tuple):
+ if len(submsg) == 0:
+ submsg = ''
+ else:
+ submsg = submsg[-1]
+
# BAW: I'm sure we can eventually do better than this. :(
decodedpayload = Utils.websafe(str(submsg))
- fp = open(path, 'w')
+
+ # encode the message back into the charset of the original message.
+ mcset = submsg.get_content_charset('')
+ if mcset == None or mcset == "":
+ mcset = 'utf-8'
+ decodedpayload = decodedpayload.encode(mcset)
+
+ fp = open(path, 'wb')
fp.write(decodedpayload)
fp.close()
# Now calculate the url
diff --git a/Mailman/Handlers/SpamDetect.py b/Mailman/Handlers/SpamDetect.py
index d7ab361a..a9e872fe 100644
--- a/Mailman/Handlers/SpamDetect.py
+++ b/Mailman/Handlers/SpamDetect.py
@@ -73,14 +73,20 @@ def getDecodedHeaders(msg, cset='utf-8'):
for h, v in list(msg.items()):
uvalue = u''
try:
- v = decode_header(re.sub('\n\s', ' ', v))
+ if isinstance(v, str):
+ v = decode_header(re.sub(r'\n\s', ' ', v))
+ else:
+ continue
except HeaderParseError:
v = [(v, 'us-ascii')]
for frag, cs in v:
if not cs:
cs = 'us-ascii'
try:
- uvalue += str(frag, cs, 'replace')
+ if isinstance(frag, bytes):
+ uvalue += str(frag, cs, 'replace')
+ else:
+ uvalue += frag
except LookupError:
# The encoding charset is unknown. At this point, frag
# has been QP or base64 decoded into a byte string whose
@@ -88,7 +94,6 @@ def getDecodedHeaders(msg, cset='utf-8'):
# unicode it as iso-8859-1 which may result in a garbled
# mess, but we have to do something.
uvalue += str(frag, 'iso-8859-1', 'replace')
- uhdr = h.decode('us-ascii', 'replace')
headers += u'%s: %s\n' % (h, normalize(mm_cfg.NORMALIZE_FORM, uvalue))
return headers
diff --git a/Mailman/Handlers/Tagger.py b/Mailman/Handlers/Tagger.py
index 0cc4a085..e3681a0e 100644
--- a/Mailman/Handlers/Tagger.py
+++ b/Mailman/Handlers/Tagger.py
@@ -97,7 +97,7 @@ def scanbody(msg, numlines=None):
# the first numlines of body text.
lines = []
lineno = 0
- reader = list(email.Iterators.body_line_iterator(msg, decode=True))
+ reader = list(email.iterators.body_line_iterator(msg, decode=True))
while numlines is None or lineno < numlines:
try:
line = reader.pop(0)
diff --git a/Mailman/Handlers/ToArchive.py b/Mailman/Handlers/ToArchive.py
index dab6b0a1..940c1ba7 100644
--- a/Mailman/Handlers/ToArchive.py
+++ b/Mailman/Handlers/ToArchive.py
@@ -26,15 +26,31 @@
def process(mlist, msg, msgdata):
+ # DEBUG: Log archiver processing start
+ from Mailman.Logging.Syslog import syslog
+ syslog('debug', 'ToArchive: Starting archive processing for list %s', mlist.internal_name())
+
# short circuits
- if msgdata.get('isdigest') or not mlist.archive:
+ if msgdata.get('isdigest'):
+ syslog('debug', 'ToArchive: Skipping digest message for list %s', mlist.internal_name())
return
+ if not mlist.archive:
+ syslog('debug', 'ToArchive: Archiving disabled for list %s', mlist.internal_name())
+ return
+
# Common practice seems to favor "X-No-Archive: yes". No other value for
# this header seems to make sense, so we'll just test for it's presence.
# I'm keeping "X-Archive: no" for backwards compatibility.
- if 'x-no-archive' in msg or msg.get('x-archive', '').lower() == 'no':
+ if 'x-no-archive' in msg:
+ syslog('debug', 'ToArchive: Skipping message with X-No-Archive header for list %s', mlist.internal_name())
+ return
+ if msg.get('x-archive', '').lower() == 'no':
+ syslog('debug', 'ToArchive: Skipping message with X-Archive: no for list %s', mlist.internal_name())
return
+
# Send the message to the archiver queue
archq = get_switchboard(mm_cfg.ARCHQUEUE_DIR)
+ syslog('debug', 'ToArchive: Enqueuing message to archive queue for list %s', mlist.internal_name())
# Send the message to the queue
archq.enqueue(msg, msgdata)
+ syslog('debug', 'ToArchive: Successfully enqueued message to archive queue for list %s', mlist.internal_name())
diff --git a/Mailman/Handlers/ToDigest.py b/Mailman/Handlers/ToDigest.py
index 7abea5b8..8ae5fa17 100644
--- a/Mailman/Handlers/ToDigest.py
+++ b/Mailman/Handlers/ToDigest.py
@@ -79,37 +79,36 @@ def process(mlist, msg, msgdata):
mboxfile = os.path.join(mlist.fullpath(), 'digest.mbox')
omask = os.umask(0o007)
try:
- mboxfp = open(mboxfile, 'a+')
+ with open(mboxfile, 'a+b') as mboxfp:
+ mbox = Mailbox(mboxfp.name)
+ mbox.AppendMessage(msg)
+ # Calculate the current size of the accumulation file. This will not tell
+ # us exactly how big the MIME, rfc1153, or any other generated digest
+ # message will be, but it's the most easily available metric to decide
+ # whether the size threshold has been reached.
+ mboxfp.flush()
+ size = os.path.getsize(mboxfile)
+ if (mlist.digest_size_threshhold > 0 and
+ size / 1024.0 >= mlist.digest_size_threshhold):
+ # This is a bit of a kludge to get the mbox file moved to the digest
+ # queue directory.
+ try:
+ # Enclose in try/except here because a error in send_digest() can
+ # silently stop regular delivery. Unsuccessful digest delivery
+ # should be tried again by cron and the site administrator will be
+ # notified of any error explicitly by the cron error message.
+ mboxfp.seek(0)
+ send_digests(mlist, mboxfp)
+ os.unlink(mboxfile)
+ except Exception as errmsg:
+ # Bare except is generally prohibited in Mailman, but we can't
+ # forecast what exceptions can occur here.
+ syslog('error', 'send_digests() failed: %s', errmsg)
+ s = StringIO()
+ traceback.print_exc(file=s)
+ syslog('error', s.getvalue())
finally:
os.umask(omask)
- mbox = Mailbox(mboxfp)
- mbox.AppendMessage(msg)
- # Calculate the current size of the accumulation file. This will not tell
- # us exactly how big the MIME, rfc1153, or any other generated digest
- # message will be, but it's the most easily available metric to decide
- # whether the size threshold has been reached.
- mboxfp.flush()
- size = os.path.getsize(mboxfile)
- if (mlist.digest_size_threshhold > 0 and
- size / 1024.0 >= mlist.digest_size_threshhold):
- # This is a bit of a kludge to get the mbox file moved to the digest
- # queue directory.
- try:
- # Enclose in try/except here because a error in send_digest() can
- # silently stop regular delivery. Unsuccessful digest delivery
- # should be tried again by cron and the site administrator will be
- # notified of any error explicitly by the cron error message.
- mboxfp.seek(0)
- send_digests(mlist, mboxfp)
- os.unlink(mboxfile)
- except Exception as errmsg:
- # Bare except is generally prohibited in Mailman, but we can't
- # forecast what exceptions can occur here.
- syslog('error', 'send_digests() failed: %s', errmsg)
- s = StringIO()
- traceback.print_exc(file=s)
- syslog('error', s.getvalue())
- mboxfp.close()
@@ -209,8 +208,11 @@ def send_i18n_digests(mlist, mboxfp):
print(mastheadtxt, file=plainmsg)
print(file=plainmsg)
# Now add the optional digest header but only if more than whitespace.
- if re.sub('\s', '', mlist.digest_header):
- headertxt = decorate(mlist, mlist.digest_header, _('digest header'))
+ if re.sub(r'\s', '', mlist.digest_header):
+ lc_digest_header_msg = _('digest header')
+ if isinstance(lc_digest_header_msg, bytes):
+ lc_digest_header_msg = str(lc_digest_header_msg)
+ headertxt = decorate(mlist, mlist.digest_header, lc_digest_header_msg)
# MIME
header = MIMEText(headertxt, _charset=lcset)
header['Content-Description'] = _('Digest Header')
@@ -226,22 +228,29 @@ def send_i18n_digests(mlist, mboxfp):
#
# Meanwhile prepare things for the table of contents
toc = StringIO()
- print(_("Today's Topics:\n"), file=toc)
+ start_toc = _("Today's Topics:\n")
+ if isinstance(start_toc, bytes):
+ start_toc = str(start_toc)
+ print(start_toc, file=toc)
# Now cruise through all the messages in the mailbox of digest messages,
# building the MIME payload and core of the RFC 1153 digest. We'll also
# accumulate Subject: headers and authors for the table-of-contents.
messages = []
msgcount = 0
- msg = next(mbox)
+ mbox = mbox.itervalues()
+ msg = next(mbox, None)
while msg is not None:
if msg == '':
# It was an unparseable message
- msg = next(mbox)
+ msg = next(mbox, None)
continue
msgcount += 1
messages.append(msg)
# Get the Subject header
- msgsubj = msg.get('subject', _('(no subject)'))
+ no_subject_locale = _('(no subject)')
+ if isinstance(no_subject_locale, bytes):
+ no_subject_locale = str(no_subject_locale)
+ msgsubj = msg.get('subject', no_subject_locale)
subject = Utils.oneline(msgsubj, lcset)
# Don't include the redundant subject prefix in the toc
mo = re.match('(re:? *)?(%s)' % re.escape(mlist.subject_prefix),
@@ -251,13 +260,15 @@ def send_i18n_digests(mlist, mboxfp):
username = ''
addresses = getaddresses([Utils.oneline(msg.get('from', ''), lcset)])
# Take only the first author we find
- if isinstance(addresses, ListType) and addresses:
+ if isinstance(addresses, list) and addresses:
username = addresses[0][0]
if not username:
username = addresses[0][1]
if username:
username = ' (%s)' % username
# Put count and Wrap the toc subject line
+ if isinstance(subject, bytes):
+ subject = str(subject)
wrapped = Utils.wrap('%2d. %s' % (msgcount, subject), 65)
slines = wrapped.split('\n')
# See if the user's name can fit on the last line
@@ -297,13 +308,14 @@ def send_i18n_digests(mlist, mboxfp):
# And a bit of extra stuff
msg['Message'] = repr(msgcount)
# Get the next message in the digest mailbox
- msg = next(mbox)
+ msg = next(mbox, None)
# Now we're finished with all the messages in the digest. First do some
# sanity checking and then on to adding the toc.
if msgcount == 0:
# Why did we even get here?
return
- toctext = to_cset_out(toc.getvalue(), lcset)
+ toctext = toc.getvalue()
+ toctext_encoded = to_cset_out(toctext, lcset)
# MIME
tocpart = MIMEText(toctext, _charset=lcset)
tocpart['Content-Description']= _("Today's Topics (%(msgcount)d messages)")
@@ -332,7 +344,10 @@ def send_i18n_digests(mlist, mboxfp):
try:
msg = scrubber(mlist, msg)
except Errors.DiscardMessage:
- print(_('[Message discarded by content filter]'), file=plainmsg)
+ discard_msg = _('[Message discarded by content filter]')
+ if isinstance(discard_msg, bytes):
+ discard_msg = str(discard_msg)
+ print(discard_msg, file=plainmsg)
continue
# Honor the default setting
for h in mm_cfg.PLAIN_DIGEST_KEEP_HEADERS:
@@ -343,24 +358,24 @@ def send_i18n_digests(mlist, mboxfp):
print(file=plainmsg)
# If decoded payload is empty, this may be multipart message.
# -- just stringfy it.
- payload = msg.get_payload(decode=True) \
- or msg.as_string().split('\n\n',1)[1]
+ payload = msg.get_payload(decode=True)
+ if payload == None:
+ payload = msg.as_string().split('\n\n',1)[1]
mcset = msg.get_content_charset('')
- if mcset and mcset != lcset and mcset != lcset_out:
- try:
- payload = str(payload, mcset, 'replace'
- ).encode(lcset, 'replace')
- except (UnicodeError, LookupError):
- # TK: Message has something unknown charset.
- # _out means charset in 'outer world'.
- payload = str(payload, lcset_out, 'replace'
- ).encode(lcset, 'replace')
+ if mcset == None or mcset == "":
+ mcset = 'utf-8'
+ if isinstance(payload, bytes):
+ payload = payload.decode(mcset, 'replace')
print(payload, file=plainmsg)
if not payload.endswith('\n'):
print(file=plainmsg)
+
# Now add the footer but only if more than whitespace.
- if re.sub('\s', '', mlist.digest_footer):
- footertxt = decorate(mlist, mlist.digest_footer, _('digest footer'))
+ if re.sub(r'\s', '', mlist.digest_footer):
+ lc_digest_footer_msg = _('digest footer')
+ if isinstance(lc_digest_footer_msg, bytes):
+ lc_digest_footer_msg = str(lc_digest_footer_msg)
+ footertxt = decorate(mlist, mlist.digest_footer, lc_digest_footer_msg)
# MIME
footer = MIMEText(footertxt, _charset=lcset)
footer['Content-Description'] = _('Digest Footer')
@@ -371,7 +386,11 @@ def send_i18n_digests(mlist, mboxfp):
# Subject: Digest Footer
print(separator30, file=plainmsg)
print(file=plainmsg)
- print('Subject: ' + _('Digest Footer'), file=plainmsg)
+
+ digest_footer_msg = _('Digest Footer')
+ if isinstance(digest_footer_msg, bytes):
+ digest_footer_msg = str(digest_footer_msg)
+ print('Subject: ' + digest_footer_msg, file=plainmsg)
print(file=plainmsg)
print(footertxt, file=plainmsg)
print(file=plainmsg)
@@ -416,7 +435,7 @@ def send_i18n_digests(mlist, mboxfp):
listname=mlist.internal_name(),
isdigest=True)
# RFC 1153
- rfc1153msg.set_payload(to_cset_out(plainmsg.getvalue(), lcset), lcset)
+ rfc1153msg.set_payload(plainmsg.getvalue(), 'utf-8')
virginq.enqueue(rfc1153msg,
recips=plainrecips,
listname=mlist.internal_name(),
diff --git a/Mailman/ListAdmin.py b/Mailman/ListAdmin.py
index f1dc5ddc..f8fad6d2 100644
--- a/Mailman/ListAdmin.py
+++ b/Mailman/ListAdmin.py
@@ -34,8 +34,12 @@
import email
from email.mime.message import MIMEMessage
+from email.generator import BytesGenerator
from email.generator import Generator
from email.utils import getaddresses
+from email.message import EmailMessage
+from email.parser import Parser
+from email import policy
from Mailman import mm_cfg
from Mailman import Utils
@@ -80,7 +84,9 @@ def __opendb(self):
try:
fp = open(self.__filename, 'rb')
try:
- self.__db = pickle.load(fp, fix_imports=True, encoding='latin1')
+ self.__db = Utils.load_pickle(fp)
+ if not self.__db:
+ raise IOError("Pickled data is empty or None")
finally:
fp.close()
except IOError as e:
@@ -133,7 +139,7 @@ def NumRequestsPending(self):
def __getmsgids(self, rtype):
self.__opendb()
ids = [k for k, (op, data) in list(self.__db.items()) if op == rtype]
- ids.sort()
+ ids.sort(key=int)
return ids
def GetHeldMessageIds(self):
@@ -241,25 +247,37 @@ def __handlepost(self, record, value, comment, preserve, forward, addr):
return LOST
try:
if path.endswith('.pck'):
- msg = pickle.load(fp, fix_imports=True, encoding='latin1')
+ msg = Utils.load_pickle(path)
else:
assert path.endswith('.txt'), '%s not .pck or .txt' % path
msg = fp.read()
finally:
fp.close()
+
+ # If msg is still a Message from Python 2 pickle, convert it
+ if isinstance(msg, email.message.Message):
+ if not hasattr(msg, 'policy'):
+ msg.policy = email._policybase.compat32
+ if not hasattr(msg, 'mangle_from_'):
+ msg.mangle_from_ = True
+ if not hasattr(msg, 'linesep'):
+ msg.linesep = email.policy.default.linesep
+
# Save the plain text to a .msg file, not a .pck file
outpath = os.path.join(mm_cfg.SPAM_DIR, spamfile)
head, ext = os.path.splitext(outpath)
outpath = head + '.msg'
- outfp = open(outpath, 'wb')
- try:
- if path.endswith('.pck'):
- g = Generator(outfp)
- g.flatten(msg, 1)
- else:
- outfp.write(msg)
- finally:
- outfp.close()
+
+ with open(outpath, 'w', encoding='utf-8') as outfp:
+ try:
+ if path.endswith('.pck'):
+ g = Generator(outfp, policy=msg.policy)
+ g.flatten(msg, 1)
+ else:
+ outfp.write(msg.get_payload(decode=True).decode() if isinstance(msg.get_payload(decode=True), bytes) else msg.get_payload())
+ except Exception as e:
+ raise Errors.LostHeldMessage(path)
+
# Now handle updates to the database
rejection = None
fp = None
@@ -301,7 +319,7 @@ def __handlepost(self, record, value, comment, preserve, forward, addr):
rejection = 'Refused'
lang = self.getMemberLanguage(sender)
subject = Utils.oneline(subject, Utils.GetCharSet(lang))
- self.__refuse(_('Posting of your message titled "%(subject)s"'),
+ self.__refuse(_(f'Posting of your message titled "{subject}"'),
sender, comment or _('[No reason given]'),
lang=lang)
else:
@@ -349,14 +367,11 @@ def __handlepost(self, record, value, comment, preserve, forward, addr):
fmsg.send(self)
# Log the rejection
if rejection:
- note = '''%(listname)s: %(rejection)s posting:
-\tFrom: %(sender)s
-\tSubject: %(subject)s''' % {
- 'listname' : self.internal_name(),
- 'rejection': rejection,
- 'sender' : str(sender).replace('%', '%%'),
- 'subject' : str(subject).replace('%', '%%'),
- }
+ if isinstance(subject, bytes):
+ subject = subject.decode()
+ note = '''{}: {} posting:
+\tFrom: {}
+\tSubject: {}'''.format(self.real_name, rejection, sender.replace('%', '%%'), subject.replace('%', '%%'))
if comment:
note += '\n\tReason: ' + comment.replace('%', '%%')
syslog('vette', note)
@@ -551,15 +566,10 @@ def _UpdateRecords(self):
except IOError as e:
if e.errno != errno.ENOENT: raise
filename = os.path.join(self.fullpath(), 'request.pck')
- try:
- fp = open(filename, 'rb')
- try:
- self.__db = pickle.load(fp, fix_imports=True, encoding='latin1')
- finally:
- fp.close()
- except IOError as e:
- if e.errno != errno.ENOENT: raise
+ self.__db = Utils.load_pickle(filename)
+ if self.__db is None:
self.__db = {}
+
for id, x in list(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)
@@ -610,13 +620,17 @@ def readMessage(path):
# For backwards compatibility, we must be able to read either a flat text
# file or a pickle.
ext = os.path.splitext(path)[1]
- fp = open(path, 'rb')
try:
if ext == '.txt':
+ fp = open(path, 'rb')
msg = email.message_from_file(fp, Message.Message)
+ fp.close()
else:
assert ext == '.pck'
- msg = pickle.load(fp, fix_imports=True, encoding='latin1')
- finally:
- fp.close()
- return msg
+ msg = Utils.load_pickle(path)
+ if not hasattr(msg, 'policy'):
+ msg.policy = email._policybase.compat32
+
+ return msg
+ except Exception as e:
+ return None
diff --git a/Mailman/Logging/Logger.py b/Mailman/Logging/Logger.py
index 556e4292..c3f644f4 100644
--- a/Mailman/Logging/Logger.py
+++ b/Mailman/Logging/Logger.py
@@ -69,8 +69,7 @@ def __get_f(self):
try:
try:
f = codecs.open(
- self.__filename, 'a+', self.__encoding, 'replace',
- 1)
+ self.__filename, 'a+', self.__encoding, 'replace')
except LookupError:
f = open(self.__filename, 'a+', 1)
self.__fp = f
@@ -95,6 +94,7 @@ def write(self, msg):
f = self.__get_f()
try:
f.write(msg)
+ f.flush()
except IOError as msg:
_logexc(self, msg)
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index 08b1c49e..50a7d260 100644
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -130,16 +130,88 @@ def __getattr__(self, name):
# access to a delegated member function gets passed to the
# sub-objects. This of course imposes a specific name resolution
# order.
- try:
- return getattr(self._memberadaptor, name)
- except AttributeError:
- for guicomponent in self._gui:
- try:
- return getattr(guicomponent, name)
- except AttributeError:
- pass
- else:
- raise AttributeError(name)
+ # Some attributes should not be delegated to the member adaptor
+ # because they belong to the main list object or other mixins
+ non_delegated_attrs = {
+ 'topics', 'delivery_status', 'bounce_info', 'bounce_info_stale_after',
+ 'archive_private', 'usenet_watermark', 'digest_members', 'members',
+ 'passwords', 'user_options', 'language', 'usernames', 'topics_userinterest',
+ 'new_member_options', 'digestable', 'nondigestable', 'one_last_digest',
+ 'archive', 'archive_volume_frequency'
+ }
+ if name not in non_delegated_attrs:
+ try:
+ return getattr(self._memberadaptor, name)
+ except AttributeError:
+ pass
+ for guicomponent in self._gui:
+ try:
+ return getattr(guicomponent, name)
+ except AttributeError:
+ pass
+ # For certain attributes that should exist but might not be initialized yet,
+ # return a default value instead of raising an AttributeError
+ if name in non_delegated_attrs:
+ if name == 'topics':
+ return []
+ elif name == 'delivery_status':
+ return {}
+ elif name == 'bounce_info':
+ return {}
+ elif name == 'bounce_info_stale_after':
+ return mm_cfg.DEFAULT_BOUNCE_INFO_STALE_AFTER
+ elif name == 'archive_private':
+ return mm_cfg.DEFAULT_ARCHIVE_PRIVATE
+ elif name == 'usenet_watermark':
+ return None
+ elif name == 'digest_members':
+ return {}
+ elif name == 'members':
+ return {}
+ elif name == 'passwords':
+ return {}
+ elif name == 'user_options':
+ return {}
+ elif name == 'language':
+ return {}
+ elif name == 'usernames':
+ return {}
+ elif name == 'topics_userinterest':
+ return {}
+ elif name == 'new_member_options':
+ return 0
+ elif name == 'digestable':
+ return 0
+ elif name == 'nondigestable':
+ return 0
+ elif name == 'one_last_digest':
+ return {}
+ elif name == 'archive':
+ return 0
+ elif name == 'archive_volume_frequency':
+ return 0
+ # For any other attribute not explicitly handled, return a sensible default
+ # based on the attribute name pattern
+ if name.startswith('_'):
+ return 0 # Private attributes default to 0
+ elif name.endswith('_msg') or name.endswith('_text'):
+ return '' # Message/text attributes default to empty string
+ elif name.endswith('_list') or name.endswith('_lists'):
+ return [] # List attributes default to empty list
+ elif name.endswith('_dict') or name.endswith('_info'):
+ return {} # Dictionary attributes default to empty dict
+ elif name in ('host_name', 'real_name', 'description', 'info', 'subject_prefix',
+ 'reply_to_address', 'umbrella_member_suffix'):
+ return '' # String attributes default to empty string
+ elif name in ('max_message_size', 'admin_member_chunksize', 'max_days_to_hold',
+ 'bounce_score_threshold', 'bounce_info_stale_after',
+ 'bounce_you_are_disabled_warnings', 'bounce_you_are_disabled_warnings_interval',
+ 'member_verbosity_threshold', 'member_verbosity_interval',
+ 'digest_size_threshhold', 'topics_bodylines_limit',
+ 'autoresponse_graceperiod'):
+ return 0 # Number attributes default to 0
+ else:
+ return 0 # Default for any other attribute
def __repr__(self):
if self.Locked():
@@ -658,9 +730,7 @@ def __load(self, dbfile):
if dbfile.endswith('.db') or dbfile.endswith('.db.last'):
dict_retval = marshal.load(fp)
elif dbfile.endswith('.pck') or dbfile.endswith('.pck.last'):
- dict_retval = pickle.load(fp, fix_imports=True, encoding='latin1')
-# dict_retval = loadfunc(fp)
-
+ dict_retval = Utils.load_pickle(dbfile)
if not isinstance(dict_retval, dict):
return None, 'Load() expected to return a dictionary'
except (EOFError, ValueError, TypeError, MemoryError,
@@ -809,23 +879,25 @@ def CheckValues(self):
# Legacy topics may have bad regular expressions in their patterns
# Also, someone may have broken topics with, e.g., config_list.
goodtopics = []
- for value in self.topics:
- try:
- name, pattern, desc, emptyflag = value
- except ValueError:
- # This value is not a 4-tuple. Just log and drop it.
- syslog('error', 'Bad topic "%s" for list: %s',
- value, self.internal_name())
- continue
- try:
- orpattern = OR.join(pattern.splitlines())
- re.compile(orpattern)
- except (re.error, TypeError):
- syslog('error', 'Bad topic pattern "%s" for list: %s',
- orpattern, self.internal_name())
- else:
- goodtopics.append((name, pattern, desc, emptyflag))
- self.topics = goodtopics
+ # Check if topics attribute exists before trying to access it
+ if hasattr(self, 'topics'):
+ for value in self.topics:
+ try:
+ name, pattern, desc, emptyflag = value
+ except ValueError:
+ # This value is not a 4-tuple. Just log and drop it.
+ syslog('error', 'Bad topic "%s" for list: %s',
+ value, self.internal_name())
+ continue
+ try:
+ orpattern = OR.join(pattern.splitlines())
+ re.compile(orpattern)
+ except (re.error, TypeError):
+ syslog('error', 'Bad topic pattern "%s" for list: %s',
+ orpattern, self.internal_name())
+ else:
+ goodtopics.append((name, pattern, desc, emptyflag))
+ self.topics = goodtopics
#
@@ -1026,6 +1098,11 @@ def AddMember(self, userdesc, remote=None):
del msg['auto-submitted']
msg['Auto-Submitted'] = autosub
msg.send(self)
+
+ # formataddr() expects a str and does its own encoding
+ if isinstance(name, bytes):
+ name = name.decode(Utils.GetCharSet(lang))
+
who = formataddr((name, email))
syslog('subscribe', '%s: pending %s %s',
self.internal_name(), who, by)
@@ -1102,6 +1179,12 @@ def ApprovedAddMember(self, userdesc, ack=None, admin_notif=None, text='',
kind = ' (digest)'
else:
kind = ''
+
+ # The formataddr() function, used in two places below, takes a str and performs
+ # its own encoding, so we should not allow the name to be pre-encoded.
+ if isinstance(name, bytes):
+ name = name.decode(Utils.GetCharSet(lang))
+
syslog('subscribe', '%s: new%s %s, %s', self.internal_name(),
kind, formataddr((name, email)), whence)
if ack:
@@ -1123,8 +1206,7 @@ def ApprovedAddMember(self, userdesc, ack=None, admin_notif=None, text='',
subject = _('%(realname)s subscription notification')
finally:
i18n.set_translation(otrans)
- if isinstance(name, UnicodeType):
- name = name.encode(Utils.GetCharSet(lang), 'replace')
+
text = Utils.maketext(
"adminsubscribeack.txt",
{"listname" : realname,
@@ -1328,7 +1410,7 @@ def log_and_notify_admin(self, oldaddr, newaddr):
name = self.getMemberName(newaddr)
if name is None:
name = ''
- if isinstance(name, UnicodeType):
+ if isinstance(name, str):
name = name.encode(Utils.GetCharSet(lang), 'replace')
text = Utils.maketext(
'adminaddrchgack.txt',
@@ -1427,7 +1509,7 @@ def ProcessConfirmation(self, cookie, context=None):
approved = context.get('Approved', context.get('Approve'))
if not approved:
try:
- subpart = list(email.Iterators.typed_subpart_iterator(
+ subpart = list(email.iterators.typed_subpart_iterator(
context, 'text', 'plain'))[0]
except IndexError:
subpart = None
diff --git a/Mailman/Mailbox.py b/Mailman/Mailbox.py
index ed04b83a..782bb84d 100644
--- a/Mailman/Mailbox.py
+++ b/Mailman/Mailbox.py
@@ -24,15 +24,16 @@
import email
from email.parser import Parser
from email.errors import MessageParseError
+from email.generator import Generator
from Mailman import mm_cfg
-from Mailman.Message import Generator
from Mailman.Message import Message
+from Mailman import Utils
def _safeparser(fp):
try:
- return email.message_from_file(fp, Message)
+ return email.message_from_binary_file(fp, Message)
except MessageParseError:
# Don't return None since that will stop a mailbox iterator
return ''
@@ -41,30 +42,34 @@ def _safeparser(fp):
class Mailbox(mailbox.mbox):
def __init__(self, fp):
+ if not isinstance( fp, str ):
+ fp = fp.name
+ self.filepath = fp
mailbox.mbox.__init__(self, fp, _safeparser)
# msg should be an rfc822 message or a subclass.
def AppendMessage(self, msg):
# Check the last character of the file and write a newline if it isn't
# a newline (but not at the beginning of an empty file).
- try:
- self.fp.seek(-1, 2)
- except IOError as e:
- # Assume the file is empty. We can't portably test the error code
- # returned, since it differs per platform.
- pass
- else:
- if self.fp.read(1) != '\n':
- self.fp.write('\n')
- # Seek to the last char of the mailbox
- self.fp.seek(0, 2)
- # Create a Generator instance to write the message to the file
- g = Generator(self.fp)
- g.flatten(msg, unixfrom=True)
- # Add one more trailing newline for separation with the next message
- # to be appended to the mbox.
- print(file=self.fp)
-
+ with open(self.filepath, 'r+') as fileh:
+ try:
+ fileh.seek(-1, 2)
+ except IOError as e:
+ # Assume the file is empty. We can't portably test the error code
+ # returned, since it differs per platform.
+ pass
+ else:
+ if fileh.read(1) != '\n':
+ fileh.write('\n')
+ # Seek to the last char of the mailbox
+ fileh.seek(0, 2)
+ # Create a Generator instance to write the message to the file
+ g = Generator(fileh)
+ Utils.set_cte_if_missing(msg)
+ g.flatten(msg, unixfrom=True)
+ # Add one more trailing newline for separation with the next message
+ # to be appended to the mbox.
+ print('\n', fileh)
# This stuff is used by pipermail.py:processUnixMailbox(). It provides an
@@ -96,7 +101,9 @@ def __init__(self, fp, mlist):
else:
self._scrubber = None
self._mlist = mlist
- mailbox.PortableUnixMailbox.__init__(self, fp, _archfactory(self))
+ if not isinstance(fp, str):
+ fp = fp.name
+ mailbox.mbox.__init__(self, fp, _archfactory(self))
def scrub(self, msg):
if self._scrubber:
diff --git a/Mailman/Message.py b/Mailman/Message.py
index ceff3031..d75e5a52 100644
--- a/Mailman/Message.py
+++ b/Mailman/Message.py
@@ -38,7 +38,7 @@
if hasattr(email, '__version__'):
mo = re.match(r'([\d.]+)', email.__version__)
else:
- mo = re.match(r'([\d.]+)', '2.1.39') # XXX should use @@MM_VERSION@@ perhaps?
+ mo = re.match(r'([\d.]+)', '2.2.0') # XXX should use @@MM_VERSION@@ perhaps?
VERSION = tuple([int(s) for s in mo.group().split('.')])
@@ -69,6 +69,8 @@ def __init__(self):
# BAW: For debugging w/ bin/dumpdb. Apparently pprint uses repr.
def __repr__(self):
+ if not hasattr(self, 'policy'):
+ self.policy = email._policybase.compat32
return self.__str__()
def __setstate__(self, d):
@@ -241,10 +243,10 @@ def as_string(self, unixfrom=False, mangle_from_=True):
"""
fp = StringIO()
g = Generator(fp, mangle_from_=mangle_from_)
+ Utils.set_cte_if_missing(self)
g.flatten(self, unixfrom=unixfrom)
return fp.getvalue()
-
class UserNotification(Message):
"""Class for internally crafted messages."""
@@ -261,7 +263,7 @@ def __init__(self, recip, sender, subject=None, text=None, lang=None):
self['Subject'] = Header(subject, charset, header_name='Subject',
errors='replace')
self['From'] = sender
- if isinstance(recip, ListType):
+ if isinstance(recip, list):
self['To'] = COMMASPACE.join(recip)
self.recips = recip
else:
diff --git a/Mailman/OldStyleMemberships.py b/Mailman/OldStyleMemberships.py
index 15a5214b..f406e65b 100644
--- a/Mailman/OldStyleMemberships.py
+++ b/Mailman/OldStyleMemberships.py
@@ -84,13 +84,13 @@ def isMember(self, member):
def getMemberKey(self, member):
cpaddr, where = self.__get_cp_member(member)
if cpaddr is None:
- raise Exception(Errors.NotAMemberError, member)
+ raise Errors.NotAMemberError(member)
return member.lower()
def getMemberCPAddress(self, member):
cpaddr, where = self.__get_cp_member(member)
if cpaddr is None:
- raise Exception(Errors.NotAMemberError, member)
+ raise Errors.NotAMemberError(member)
return cpaddr
def getMemberCPAddresses(self, members):
@@ -99,18 +99,20 @@ def getMemberCPAddresses(self, members):
def getMemberPassword(self, member):
secret = self.__mlist.passwords.get(member.lower())
if secret is None:
- raise Exception(Errors.NotAMemberError, member)
+ raise Errors.NotAMemberError(member)
return secret
def authenticateMember(self, member, response):
secret = self.getMemberPassword(member)
+ if isinstance(response, bytes):
+ response = response.decode('utf-8')
if secret == response:
return secret
return 0
def __assertIsMember(self, member):
if not self.isMember(member):
- raise Exception(Errors.NotAMemberError, member)
+ raise Errors.NotAMemberError(member)
def getMemberLanguage(self, member):
lang = self.__mlist.language.get(
@@ -172,7 +174,7 @@ def addNewMember(self, member, **kws):
assert self.__mlist.Locked()
# Make sure this address isn't already a member
if self.isMember(member):
- raise Exception(Errors.MMAlreadyAMember, member)
+ raise Errors.MMAlreadyAMember(member)
# Parse the keywords
digest = 0
password = Utils.MakeRandomPassword()
diff --git a/Mailman/Pending.py b/Mailman/Pending.py
index aaa4d373..06f777d2 100644
--- a/Mailman/Pending.py
+++ b/Mailman/Pending.py
@@ -27,7 +27,7 @@
from Mailman import mm_cfg
from Mailman import UserDesc
-from Mailman.Utils import sha_new
+from Mailman.Utils import sha_new, load_pickle
# Types of pending records
SUBSCRIPTION = 'S'
@@ -68,8 +68,8 @@ def pend_new(self, op, *content, **kws):
# are discarded because they're the most predictable bits.
while True:
now = time.time()
- x = random.random() + now % 1.0 + time.clock() % 1.0
- cookie = sha_new(repr(x)).hexdigest()
+ x = random.random() + now % 1.0 + time.time() % 1.0
+ cookie = sha_new(repr(x).encode()).hexdigest()
# We'll never get a duplicate, but we'll be anal about checking
# anyway.
if cookie not in db:
@@ -84,14 +84,13 @@ def pend_new(self, op, *content, **kws):
def __load(self):
try:
- fp = open(self.__pendfile)
- except IOError as e:
- if e.errno != errno.ENOENT: raise
+ obj = load_pickle(self.__pendfile)
+ if obj == None:
+ return {'evictions': {}}
+ else:
+ return obj
+ except Exception as e:
return {'evictions': {}}
- try:
- return pickle.load(fp, fix_imports=True, encoding='latin1')
- finally:
- fp.close()
def __save(self, db):
evictions = db['evictions']
@@ -112,7 +111,7 @@ def __save(self, db):
tmpfile = '%s.tmp.%d.%d' % (self.__pendfile, os.getpid(), now)
omask = os.umask(0o007)
try:
- fp = open(tmpfile, 'w')
+ fp = open(tmpfile, 'wb')
try:
pickle.dump(db, fp)
fp.flush()
diff --git a/Mailman/Queue/ArchRunner.py b/Mailman/Queue/ArchRunner.py
index 7e3cd17a..fb5265bb 100644
--- a/Mailman/Queue/ArchRunner.py
+++ b/Mailman/Queue/ArchRunner.py
@@ -30,51 +30,87 @@ class ArchRunner(Runner):
QDIR = mm_cfg.ARCHQUEUE_DIR
def _dispose(self, mlist, msg, msgdata):
+ from Mailman.Logging.Syslog import syslog
+ syslog('debug', 'ArchRunner: Starting archive processing for list %s', mlist.internal_name())
+
# Support clobber_date, i.e. setting the date in the archive to the
# received date, not the (potentially bogus) Date: header of the
# original message.
clobber = 0
originaldate = msg.get('date')
+
+ # Handle potential bytes/string issues with header values
+ if isinstance(originaldate, bytes):
+ try:
+ originaldate = originaldate.decode('utf-8', 'replace')
+ except (UnicodeDecodeError, AttributeError):
+ originaldate = None
+
receivedtime = formatdate(msgdata['received_time'])
+ syslog('debug', 'ArchRunner: Original date: %s, Received time: %s', originaldate, receivedtime)
+
if not originaldate:
clobber = 1
+ syslog('debug', 'ArchRunner: No original date, will clobber')
elif mm_cfg.ARCHIVER_CLOBBER_DATE_POLICY == 1:
clobber = 1
+ syslog('debug', 'ArchRunner: ARCHIVER_CLOBBER_DATE_POLICY = 1, will clobber')
elif mm_cfg.ARCHIVER_CLOBBER_DATE_POLICY == 2:
# what's the timestamp on the original message?
- tup = parsedate_tz(originaldate)
- now = time.time()
try:
+ tup = parsedate_tz(originaldate)
+ now = time.time()
if not tup:
clobber = 1
+ syslog('debug', 'ArchRunner: Could not parse original date, will clobber')
elif abs(now - mktime_tz(tup)) > \
mm_cfg.ARCHIVER_ALLOWABLE_SANE_DATE_SKEW:
clobber = 1
- except (ValueError, OverflowError):
+ syslog('debug', 'ArchRunner: Date skew too large, will clobber')
+ except (ValueError, OverflowError, TypeError):
# The likely cause of this is that the year in the Date: field
# is horribly incorrect, e.g. (from SF bug # 571634):
# Date: Tue, 18 Jun 0102 05:12:09 +0500
# Obviously clobber such dates.
clobber = 1
+ syslog('debug', 'ArchRunner: Date parsing exception, will clobber')
+
if clobber:
- del msg['date']
- del msg['x-original-date']
+ # Use proper header manipulation methods
+ if 'date' in msg:
+ del msg['date']
+ if 'x-original-date' in msg:
+ del msg['x-original-date']
msg['Date'] = receivedtime
if originaldate:
msg['X-Original-Date'] = originaldate
+ syslog('debug', 'ArchRunner: Clobbered date headers')
+
# Always put an indication of when we received the message.
msg['X-List-Received-Date'] = receivedtime
+
# Now try to get the list lock
+ syslog('debug', 'ArchRunner: Attempting to lock list %s', mlist.internal_name())
try:
mlist.Lock(timeout=mm_cfg.LIST_LOCK_TIMEOUT)
+ syslog('debug', 'ArchRunner: Successfully locked list %s', mlist.internal_name())
except LockFile.TimeOutError:
# oh well, try again later
+ syslog('debug', 'ArchRunner: Failed to lock list %s, will retry later', mlist.internal_name())
return 1
+
try:
# Archiving should be done in the list's preferred language, not
# the sender's language.
i18n.set_language(mlist.preferred_language)
+ syslog('debug', 'ArchRunner: Calling ArchiveMail for list %s', mlist.internal_name())
mlist.ArchiveMail(msg)
+ syslog('debug', 'ArchRunner: ArchiveMail completed, saving list %s', mlist.internal_name())
mlist.Save()
+ syslog('debug', 'ArchRunner: Successfully completed archive processing for list %s', mlist.internal_name())
+ except Exception as e:
+ syslog('error', 'ArchRunner: Exception during archive processing for list %s: %s', mlist.internal_name(), e)
+ raise
finally:
mlist.Unlock()
+ syslog('debug', 'ArchRunner: Unlocked list %s', mlist.internal_name())
diff --git a/Mailman/Queue/CommandRunner.py b/Mailman/Queue/CommandRunner.py
index ff7003d3..6272dfdc 100644
--- a/Mailman/Queue/CommandRunner.py
+++ b/Mailman/Queue/CommandRunner.py
@@ -70,7 +70,7 @@ def __init__(self, mlist, msg, msgdata):
# Python 2.1's unicode() builtin doesn't call obj.__unicode__().
subj = msg.get('subject', '')
try:
- subj = make_header(decode_header(subj)).__unicode__()
+ subj = make_header(decode_header(subj)).__str__()
# TK: Currently we don't allow 8bit or multibyte in mail command.
# MAS: However, an l10n 'Re:' may contain non-ascii so ignore it.
subj = subj.encode('us-ascii', 'ignore')
@@ -124,6 +124,8 @@ def do_command(self, cmd, args=None):
if args is None:
args = ()
# Try to import a command handler module for this command
+ if isinstance(cmd, bytes):
+ cmd = cmd.decode()
modname = 'Mailman.Commands.cmd_' + cmd
try:
__import__(modname)
@@ -131,7 +133,7 @@ def do_command(self, cmd, args=None):
# ValueError can be raised if cmd has dots in it.
# and KeyError if cmd is otherwise good but ends with a dot.
# and TypeError if cmd has a null byte.
- except (ImportError, ValueError, KeyError, TypeError):
+ except (ImportError, ValueError, KeyError, TypeError) as e:
# If we're on line zero, it was the Subject: header that didn't
# contain a command. It's possible there's a Re: prefix (or
# localized version thereof) on the Subject: line that's messing
@@ -166,7 +168,8 @@ def do_command(self, cmd, args=None):
def send_response(self):
# Helper
def indent(lines):
- return [' ' + line for line in lines]
+ normalized = [line.decode() if isinstance(line, bytes) else line for line in lines]
+ return [' ' + line for line in normalized]
# Quick exit for some commands which don't need a response
if not self.respond:
return
@@ -198,8 +201,8 @@ def indent(lines):
charset = Utils.GetCharSet(self.msgdata['lang'])
encoded_resp = []
for item in resp:
- if isinstance(item, UnicodeType):
- item = item.encode(charset, 'replace')
+ if isinstance(item, bytes):
+ item = item.decode()
encoded_resp.append(item)
results = MIMEText(NL.join(encoded_resp), _charset=charset)
# Safety valve for mail loops with misconfigured email 'bots. We
diff --git a/Mailman/Queue/IncomingRunner.py b/Mailman/Queue/IncomingRunner.py
index 60550f27..e14d5316 100644
--- a/Mailman/Queue/IncomingRunner.py
+++ b/Mailman/Queue/IncomingRunner.py
@@ -139,9 +139,21 @@ def _dispose(self, mlist, msg, msgdata):
def _get_pipeline(self, mlist, msg, msgdata):
# We must return a copy of the list, otherwise, the first message that
# flows through the pipeline will empty it out!
- return msgdata.get('pipeline',
- getattr(mlist, 'pipeline',
- mm_cfg.GLOBAL_PIPELINE))[:]
+ pipeline = msgdata.get('pipeline')
+ if pipeline is None:
+ pipeline = getattr(mlist, 'pipeline', None)
+ else:
+ # Use the already-imported mm_cfg directly
+ pipeline = mm_cfg.GLOBAL_PIPELINE
+
+ # Ensure pipeline is a list that can be sliced
+ if not isinstance(pipeline, list):
+ syslog('error', 'pipeline is not a list: %s (type: %s)',
+ pipeline, type(pipeline).__name__)
+ # Fallback to a basic pipeline
+ pipeline = mm_cfg.GLOBAL_PIPELINE
+
+ return pipeline[:]
def _dopipeline(self, mlist, msg, msgdata, pipeline):
while pipeline:
diff --git a/Mailman/Queue/NewsRunner.py b/Mailman/Queue/NewsRunner.py
index 9a402436..4a6c92d4 100644
--- a/Mailman/Queue/NewsRunner.py
+++ b/Mailman/Queue/NewsRunner.py
@@ -20,10 +20,15 @@
from builtins import str
import re
import socket
-import nntplib
+try:
+ import nntplib
+ NNTPLIB_AVAILABLE = True
+except ImportError:
+ NNTPLIB_AVAILABLE = False
from io import StringIO
import email
+import email.iterators
from email.utils import getaddresses
COMMASPACE = ', '
@@ -56,6 +61,14 @@ def _dispose(self, mlist, msg, msgdata):
mlist.Load()
if not msgdata.get('prepped'):
prepare_message(mlist, msg, msgdata)
+
+ # Check if nntplib is available
+ if not NNTPLIB_AVAILABLE:
+ syslog('error',
+ '(NewsRunner) nntplib not available, cannot post to newsgroup for list "%s"',
+ mlist.internal_name())
+ return False # Don't requeue, just drop the message
+
try:
# Flatten the message object, sticking it in a StringIO object
fp = StringIO(msg.as_string())
@@ -154,7 +167,7 @@ def prepare_message(mlist, msg, msgdata):
# Lines: is useful
if msg['Lines'] is None:
# BAW: is there a better way?
- count = len(list(email.Iterators.body_line_iterator(msg)))
+ count = len(list(email.iterators.body_line_iterator(msg)))
msg['Lines'] = str(count)
# Massage the message headers by remove some and rewriting others. This
# woon't completely sanitize the message, but it will eliminate the bulk
diff --git a/Mailman/Queue/RetryRunner.py b/Mailman/Queue/RetryRunner.py
index dd0ac34c..4ed129b7 100644
--- a/Mailman/Queue/RetryRunner.py
+++ b/Mailman/Queue/RetryRunner.py
@@ -38,5 +38,8 @@ def _dispose(self, mlist, msg, msgdata):
return False
def _snooze(self, filecnt):
- # We always want to snooze
- time.sleep(self.SLEEPTIME)
+ # We always want to snooze. Sleep in 1 second iterations to ensure that the sigterm handler can respond promptly and set _stop.
+ for sec in range(1, self.SLEEPTIME):
+ if self._stop:
+ break
+ time.sleep(1)
diff --git a/Mailman/Queue/Runner.py b/Mailman/Queue/Runner.py
index 8a68e5da..9c35f939 100644
--- a/Mailman/Queue/Runner.py
+++ b/Mailman/Queue/Runner.py
@@ -24,6 +24,10 @@
from io import StringIO
from Mailman import mm_cfg
+# Debug: Log when mm_cfg is imported
+from Mailman.Logging.Syslog import syslog
+syslog('debug', 'Runner.py: mm_cfg imported from %s', mm_cfg.__file__)
+syslog('debug', 'Runner.py: mm_cfg.GLOBAL_PIPELINE type: %s', type(mm_cfg.GLOBAL_PIPELINE).__name__ if hasattr(mm_cfg, 'GLOBAL_PIPELINE') else 'NOT FOUND')
from Mailman import Utils
from Mailman import Errors
from Mailman import MailList
@@ -43,7 +47,8 @@ def __init__(self, slice=None, numslices=1):
self._kids = {}
# Create our own switchboard. Don't use the switchboard cache because
# we want to provide slice and numslice arguments.
- self._switchboard = Switchboard(self.QDIR, slice, numslices, True)
+ distribution = getattr(mm_cfg, 'QUEUE_DISTRIBUTION_METHOD', 'hash')
+ self._switchboard = Switchboard(self.QDIR, slice, numslices, True, distribution)
# Create the shunt switchboard
self._shunt = Switchboard(mm_cfg.SHUNTQUEUE_DIR)
self._stop = False
diff --git a/Mailman/Queue/Switchboard.py b/Mailman/Queue/Switchboard.py
index df6729e4..8353ad94 100644
--- a/Mailman/Queue/Switchboard.py
+++ b/Mailman/Queue/Switchboard.py
@@ -65,8 +65,9 @@
class Switchboard:
- def __init__(self, whichq, slice=None, numslices=1, recover=False):
+ def __init__(self, whichq, slice=None, numslices=1, recover=False, distribution='hash'):
self.__whichq = whichq
+ self.__distribution = distribution
# Create the directory if it doesn't yet exist.
# FIXME
omask = os.umask(0) # rwxrws---
@@ -80,10 +81,18 @@ def __init__(self, whichq, slice=None, numslices=1, recover=False):
# Fast track for no slices
self.__lower = None
self.__upper = None
+ # Always set slice and numslices for compatibility
+ self.__slice = slice
+ self.__numslices = numslices
# BAW: test performance and end-cases of this algorithm
if numslices != 1:
- self.__lower = (((shamax+1) * slice) / numslices)
- self.__upper = ((((shamax+1) * (slice+1)) / numslices)) - 1
+ if distribution == 'hash':
+ self.__lower = (((shamax+1) * slice) / numslices)
+ self.__upper = ((((shamax+1) * (slice+1)) / numslices)) - 1
+ elif distribution == 'round_robin':
+ # __slice and __numslices already set above
+ pass
+ # Add more distribution methods here as needed
if recover:
self.recover_backup_files()
@@ -91,12 +100,18 @@ def whichq(self):
return self.__whichq
def enqueue(self, _msg, _metadata={}, **_kws):
+ from Mailman.Logging.Syslog import syslog
# Calculate the SHA hexdigest of the message to get a unique base
# filename. We're also going to use the digest as a hash into the set
# of parallel qrunner processes.
data = _metadata.copy()
data.update(_kws)
listname = data.get('listname', '--nolist--')
+
+ # DEBUG: Log archive queue enqueue
+ if self.__whichq == mm_cfg.ARCHQUEUE_DIR:
+ syslog('debug', 'Switchboard: Enqueuing message to archive queue for list %s', listname)
+
# Get some data for the input to the sha hash
now = time.time()
if SAVE_MSGS_AS_PICKLES and not data.get('_plaintext'):
@@ -105,7 +120,23 @@ def enqueue(self, _msg, _metadata={}, **_kws):
else:
protocol = 0
msgsave = pickle.dumps(str(_msg), protocol, fix_imports=True)
- hashfood = msgsave + listname.encode() + repr(now).encode()
+
+ # Choose distribution method
+ if self.__distribution == 'round_robin':
+ # Use a simple counter for round-robin distribution
+ import threading
+ if not hasattr(self, '_counter'):
+ self._counter = 0
+ self._counter_lock = threading.Lock()
+
+ with self._counter_lock:
+ self._counter = (self._counter + 1) % self.__numslices
+ current_slice = self._counter
+ hashfood = msgsave + listname.encode() + repr(now).encode() + str(current_slice).encode()
+ else:
+ # Default hash-based distribution
+ hashfood = msgsave + listname.encode() + repr(now).encode()
+
# Encode the current time into the file name for FIFO sorting in
# files(). The file name consists of two parts separated by a `+':
# the received time for this message (i.e. when it first showed up on
@@ -138,6 +169,11 @@ def enqueue(self, _msg, _metadata={}, **_kws):
finally:
os.umask(omask)
os.rename(tmpfile, filename)
+
+ # DEBUG: Log successful enqueue
+ if self.__whichq == mm_cfg.ARCHQUEUE_DIR:
+ syslog('debug', 'Switchboard: Successfully enqueued message to archive queue: %s', filebase)
+
return filebase
def dequeue(self, filebase):
@@ -192,14 +228,26 @@ def files(self, extension='.pck'):
if ext != extension:
continue
when, digest = filebase.split('+')
- # Throw out any files which don't match our bitrange. BAW: test
- # performance and end-cases of this algorithm. MAS: both
- # comparisons need to be <= to get complete range.
- if lower is None or (lower <= int(digest, 16) <= upper):
- key = float(when)
- while key in times:
- key += DELTA
- times[key] = filebase
+
+ # Choose distribution method for file filtering
+ if self.__distribution == 'round_robin':
+ # For round-robin, use modulo of digest to determine slice
+ slice_num = int(digest, 16) % self.__numslices
+ if slice_num == self.__slice:
+ key = float(when)
+ while key in times:
+ key += DELTA
+ times[key] = filebase
+ else:
+ # Default hash-based distribution
+ # Throw out any files which don't match our bitrange. BAW: test
+ # performance and end-cases of this algorithm. MAS: both
+ # comparisons need to be <= to get complete range.
+ if lower is None or (lower <= int(digest, 16) <= upper):
+ key = float(when)
+ while key in times:
+ key += DELTA
+ times[key] = filebase
# FIFO sort
keys = list(times.keys())
keys.sort()
diff --git a/Mailman/SecurityManager.py b/Mailman/SecurityManager.py
index 9d927ffb..492cd930 100644
--- a/Mailman/SecurityManager.py
+++ b/Mailman/SecurityManager.py
@@ -97,7 +97,7 @@ def AuthContextInfo(self, authcontext, user=None):
if authcontext == mm_cfg.AuthUser:
if user is None:
# A bad system error
- raise Exception(TypeError, 'No user supplied for AuthUser context')
+ raise TypeError('No user supplied for AuthUser context')
user = Utils.UnobscureEmail(urllib.parse.unquote(user))
secret = self.getMemberPassword(user)
userdata = urllib.parse.quote(Utils.ObscureEmail(user), safe='')
@@ -139,8 +139,7 @@ def Authenticate(self, authcontexts, response, user=None):
if not response:
# Don't authenticate null passwords
return mm_cfg.UnAuthorized
- # python3
- response = response.encode('UTF-8')
+
for ac in authcontexts:
if ac == mm_cfg.AuthCreator:
ok = Utils.check_global_password(response, siteadmin=0)
@@ -174,6 +173,9 @@ def cryptmatchp(response, secret):
key, secret = self.AuthContextInfo(ac)
if secret is None:
continue
+ if isinstance(response, str):
+ response = response.encode('utf-8')
+
sharesponse = sha_new(response).hexdigest()
upgrade = ok = False
if sharesponse == secret:
@@ -249,7 +251,7 @@ def MakeCookie(self, authcontext, user=None):
mac = sha_new(needs_hashing).hexdigest()
# Create the cookie object.
c = http.cookies.SimpleCookie()
- c[key] = binascii.hexlify(marshal.dumps((issued, mac)))
+ c[key] = binascii.hexlify(marshal.dumps((issued, mac))).decode()
# The path to all Mailman stuff, minus the scheme and host,
# i.e. usually the string `/mailman'
parsed = urlparse(self.web_page_url)
@@ -365,7 +367,7 @@ def __checkone(self, c, authcontext, user):
-splitter = re.compile(';\s*')
+splitter = re.compile(r';\s*')
def parsecookie(s):
c = {}
diff --git a/Mailman/UserDesc.py b/Mailman/UserDesc.py
index 39b45087..575749f5 100644
--- a/Mailman/UserDesc.py
+++ b/Mailman/UserDesc.py
@@ -57,9 +57,9 @@ def __repr__(self):
digest = 'yes'
language = getattr(self, 'language', 'n/a')
# Make sure fullname and password are encoded if they're strings
- if isinstance(fullname, UnicodeType):
+ if isinstance(fullname, str):
fullname = fullname.encode('ascii', 'replace')
- if isinstance(password, UnicodeType):
+ if isinstance(password, str):
password = password.encode('ascii', 'replace')
return '' % (
address, fullname, password, digest, language)
diff --git a/Mailman/Utils.py b/Mailman/Utils.py
index deec92d1..e67a877e 100644
--- a/Mailman/Utils.py
+++ b/Mailman/Utils.py
@@ -27,7 +27,6 @@
import os
import sys
import re
-import cgi
import time
import errno
import base64
@@ -40,7 +39,12 @@
import email.iterators
from email.errors import HeaderParseError
from string import whitespace, digits
-from urllib.parse import urlparse
+from urllib.parse import urlparse, parse_qs
+import tempfile
+import io
+from email.parser import BytesParser
+from email.policy import HTTP
+
try:
# Python 2.2
from string import ascii_letters
@@ -49,6 +53,218 @@
_lower = 'abcdefghijklmnopqrstuvwxyz'
ascii_letters = _lower + _lower.upper()
+
+class FieldStorage:
+ """
+ A modern replacement for cgi.FieldStorage using urllib.parse and email libraries.
+
+ This class provides the same interface as cgi.FieldStorage but uses
+ modern Python libraries instead of the deprecated cgi module.
+ """
+
+ def __init__(self, fp=None, headers=None, environ=None,
+ keep_blank_values=False, strict_parsing=False,
+ encoding='utf-8', errors='replace'):
+ self.keep_blank_values = keep_blank_values
+ self.strict_parsing = strict_parsing
+ self.encoding = encoding
+ self.errors = errors
+ self._data = {}
+ self._files = {}
+
+ if environ is None:
+ environ = os.environ
+
+ self.environ = environ
+
+ # Get the request method
+ self.method = environ.get('REQUEST_METHOD', 'GET').upper()
+
+ if self.method == 'GET':
+ self._parse_query_string()
+ elif self.method == 'POST':
+ self._parse_post_data()
+ else:
+ # For other methods, try to parse query string
+ self._parse_query_string()
+
+ def _parse_query_string(self):
+ """Parse query string from GET requests or other methods."""
+ query_string = self.environ.get('QUERY_STRING', '')
+ if query_string:
+ parsed = parse_qs(query_string,
+ keep_blank_values=self.keep_blank_values,
+ strict_parsing=self.strict_parsing,
+ encoding=self.encoding,
+ errors=self.errors)
+ self._data.update(parsed)
+
+ def _parse_post_data(self):
+ """Parse POST data."""
+ content_type = self.environ.get('CONTENT_TYPE', '')
+
+ if content_type.startswith('application/x-www-form-urlencoded'):
+ self._parse_urlencoded_post()
+ elif content_type.startswith('multipart/form-data'):
+ self._parse_multipart_post()
+ else:
+ # Fallback to query string parsing
+ self._parse_query_string()
+
+ def _parse_urlencoded_post(self):
+ """Parse application/x-www-form-urlencoded POST data."""
+ content_length = int(self.environ.get('CONTENT_LENGTH', 0))
+ if content_length > 0:
+ post_data = sys.stdin.buffer.read(content_length)
+ try:
+ decoded = post_data.decode(self.encoding, self.errors)
+ parsed = parse_qs(decoded,
+ keep_blank_values=self.keep_blank_values,
+ strict_parsing=self.strict_parsing,
+ encoding=self.encoding,
+ errors=self.errors)
+ self._data.update(parsed)
+ except (UnicodeDecodeError, ValueError):
+ # If decoding fails, try with different encoding
+ try:
+ decoded = post_data.decode('latin-1')
+ parsed = parse_qs(decoded,
+ keep_blank_values=self.keep_blank_values,
+ strict_parsing=self.strict_parsing,
+ encoding=self.encoding,
+ errors=self.errors)
+ self._data.update(parsed)
+ except (UnicodeDecodeError, ValueError):
+ pass
+
+ def _parse_multipart_post(self):
+ """Parse multipart/form-data POST data."""
+ content_length = int(self.environ.get('CONTENT_LENGTH', 0))
+ if content_length > 0:
+ post_data = sys.stdin.buffer.read(content_length)
+
+ # Parse the multipart message
+ parser = BytesParser(policy=HTTP)
+ msg = parser.parsebytes(post_data)
+
+ for part in msg.walk():
+ if part.get_content_maintype() == 'multipart':
+ continue
+
+ # Get the field name from Content-Disposition
+ content_disp = part.get('Content-Disposition', '')
+ if not content_disp:
+ continue
+
+ # Parse Content-Disposition header
+ disp_parts = content_disp.split(';')
+ field_name = None
+ filename = None
+
+ for part_item in disp_parts:
+ part_item = part_item.strip()
+ if part_item.startswith('name='):
+ field_name = part_item[5:].strip('"')
+ elif part_item.startswith('filename='):
+ filename = part_item[9:].strip('"')
+
+ if not field_name:
+ continue
+
+ # Get the field value
+ field_value = part.get_payload(decode=True)
+ if field_value is None:
+ field_value = b''
+
+ if filename:
+ # This is a file upload
+ self._files[field_name] = {
+ 'filename': filename,
+ 'data': field_value,
+ 'content_type': part.get_content_type()
+ }
+ else:
+ # This is a regular field
+ try:
+ decoded_value = field_value.decode(self.encoding, self.errors)
+ except UnicodeDecodeError:
+ decoded_value = field_value.decode('latin-1')
+
+ if field_name in self._data:
+ if isinstance(self._data[field_name], list):
+ self._data[field_name].append(decoded_value)
+ else:
+ self._data[field_name] = [self._data[field_name], decoded_value]
+ else:
+ self._data[field_name] = [decoded_value]
+
+ def getfirst(self, key, default=None):
+ """Get the first value for the given key."""
+ if key in self._data:
+ values = self._data[key]
+ if isinstance(values, list):
+ return values[0] if values else default
+ else:
+ return values
+ return default
+
+ def getvalue(self, key, default=None):
+ """Get the value for the given key."""
+ if key in self._data:
+ values = self._data[key]
+ if isinstance(values, list):
+ return values[0] if values else default
+ else:
+ return values
+ return default
+
+ def getlist(self, key):
+ """Get all values for the given key as a list."""
+ if key in self._data:
+ values = self._data[key]
+ if isinstance(values, list):
+ return values
+ else:
+ return [values]
+ return []
+
+ def keys(self):
+ """Get all field names."""
+ return list(self._data.keys())
+
+ def has_key(self, key):
+ """Check if the key exists."""
+ return key in self._data
+
+ def __contains__(self, key):
+ """Check if the key exists."""
+ return key in self._data
+
+ def __getitem__(self, key):
+ """Get the value for the given key."""
+ return self.getvalue(key)
+
+ def __iter__(self):
+ """Iterate over field names."""
+ return iter(self._data.keys())
+
+ def file(self, key):
+ """Get file data for the given key."""
+ if key in self._files:
+ file_info = self._files[key]
+ # Create a file-like object
+ temp_file = tempfile.NamedTemporaryFile(delete=False)
+ temp_file.write(file_info['data'])
+ temp_file.flush()
+ return temp_file
+ return None
+
+ def filename(self, key):
+ """Get the filename for the given key."""
+ if key in self._files:
+ return self._files[key]['filename']
+ return None
+
from Mailman import mm_cfg
from Mailman import Errors
from Mailman import Site
@@ -125,6 +341,12 @@ def list_names():
return Site.get_listnames()
+def needs_unicode_escape_decode(s):
+ # Check for Unicode escape patterns (\uXXXX or \UXXXXXXXX)
+ unicode_escape_pattern = re.compile(r'\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}')
+ return bool(unicode_escape_pattern.search(s))
+
+
# a much more naive implementation than say, Emacs's fill-paragraph!
def wrap(text, column=70, honor_leading_ws=True):
@@ -249,20 +471,20 @@ def ValidateEmail(s):
s = s[-1]
# Pretty minimal, cheesy check. We could do better...
if not s or s.count(' ') > 0:
- raise Exception(Errors.MMBadEmailError)
+ raise Errors.MMBadEmailError
if _badchars.search(s):
- raise Exception(Errors.MMHostileAddress, s)
+ raise Errors.MMHostileAddress(s)
user, domain_parts = ParseEmail(s)
# This means local, unqualified addresses, are not allowed
if not domain_parts:
- raise Exception(Errors.MMBadEmailError, s)
+ raise Errors.MMBadEmailError(s)
if len(domain_parts) < 2:
- raise Exception(Errors.MMBadEmailError, s)
+ raise Errors.MMBadEmailError(s)
# domain parts may only contain ascii letters, digits and hyphen
# and must not begin with hyphen.
for p in domain_parts:
if len(p) == 0 or p[0] == '-' or len(_valid_domain.sub('', p)) > 0:
- raise Exception(Errors.MMHostileAddress, s)
+ raise Errors.MMHostileAddress(s)
@@ -451,7 +673,10 @@ def set_global_password(pw, siteadmin=True):
omask = os.umask(0o026)
try:
fp = open(filename, 'w')
- fp.write(sha_new(pw).hexdigest() + '\n')
+ if isinstance(pw, bytes):
+ fp.write(sha_new(pw).hexdigest() + '\n')
+ else:
+ fp.write(sha_new(pw.encode()).hexdigest() + '\n')
fp.close()
finally:
os.umask(omask)
@@ -477,7 +702,10 @@ def check_global_password(response, siteadmin=True):
challenge = get_global_password(siteadmin)
if challenge is None:
return None
- return challenge == sha_new(response).hexdigest()
+ if isinstance(response, bytes):
+ return challenge == sha_new(response).hexdigest()
+ else:
+ return challenge == sha_new(response.encode()).hexdigest()
@@ -632,9 +860,32 @@ def findtext(templatefile, dict=None, raw=False, lang=None, mlist=None):
except IOError as e:
if e.errno != errno.ENOENT: raise
# We never found the template. BAD!
- raise Exception(IOError(errno.ENOENT, 'No template file found', templatefile))
- template = fp.read()
- fp.close()
+ raise IOError(errno.ENOENT, 'No template file found', templatefile)
+ try:
+ template = fp.read()
+ except UnicodeDecodeError as e:
+ # failed to read the template as utf-8, so lets determine the current encoding
+ # then save the file back to disk as utf-8.
+ filename = fp.name
+ fp.close()
+
+ current_encoding = get_current_encoding(filename)
+
+ with open(filename, 'rb') as f:
+ raw = f.read()
+
+ decoded_template = raw.decode(current_encoding)
+
+ with open(filename, 'w', encoding='utf-8') as f:
+ f.write(decoded_template)
+
+ template = decoded_template
+ except Exception as e:
+ # catch any other non-unicode exceptions...
+ syslog('error', 'Failed to read template %s: %s', fp.name, e)
+ finally:
+ fp.close()
+
text = template
if dict is not None:
try:
@@ -841,6 +1092,8 @@ def midnight(date=None):
def to_dollar(s):
"""Convert from %-strings to $-strings."""
+ if isinstance(s, bytes):
+ s = s.decode()
s = s.replace('$', '$$').replace('%%', '%')
parts = cre.split(s)
for i in range(1, len(parts), 2):
@@ -876,6 +1129,8 @@ def dollar_identifiers(s):
def percent_identifiers(s):
"""Return the set (dictionary) of identifiers found in a %-string."""
d = {}
+ if isinstance(s, bytes):
+ s = s.decode()
for name in cre.findall(s):
d[name] = True
return d
@@ -968,9 +1223,8 @@ def oneline(s, cset):
# Decode header string in one line and convert into specified charset
try:
h = email.header.make_header(email.header.decode_header(s))
- ustr = h.__unicode__()
- line = UEMPTYSTRING.join(ustr.splitlines())
- return line.encode(cset, 'replace')
+ ustr = h.__str__()
+ return UEMPTYSTRING.join(ustr.splitlines())
except (LookupError, UnicodeError, ValueError, HeaderParseError):
# possibly charset problem. return with undecoded string in one line.
return EMPTYSTRING.join(s.splitlines())
@@ -1009,7 +1263,7 @@ def strip_verbose_pattern(pattern):
elif c == ']' and inclass:
inclass = False
newpattern += c
- elif re.search('\s', c):
+ elif re.search(r'\s', c):
if inclass:
if c == NL:
newpattern += '\\n'
@@ -1231,6 +1485,10 @@ def get_suffixes(url):
url, e)
return
for line in d.readlines():
+ if not line:
+ continue
+ if isinstance(line, bytes):
+ line = line.decode()
if not line.strip() or line.startswith(' ') or line.startswith('//'):
continue
line = re.sub(' .*', '', line.strip())
@@ -1341,6 +1599,10 @@ def _DMARCProhibited(mlist, email, dmarc_domain, org=False):
cnames = {}
want_names = set([dmarc_domain + '.'])
for txt_rec in txt_recs.response.answer:
+ if not isinstance(txt_rec.items, list):
+ continue
+ if not txt_rec.items[0]:
+ continue
# Don't be fooled by an answer with uppercase in the name.
name = txt_rec.name.to_text().lower()
if txt_rec.rdtype == dns.rdatatype.CNAME:
@@ -1349,7 +1611,7 @@ def _DMARCProhibited(mlist, email, dmarc_domain, org=False):
if txt_rec.rdtype != dns.rdatatype.TXT:
continue
results_by_name.setdefault(name, []).append(
- "".join(txt_rec.items[0].strings))
+ "".join( [ record.decode() if isinstance(record, bytes) else record for record in txt_rec.items[0].strings ] ))
expands = list(want_names)
seen = set(expands)
while expands:
@@ -1484,7 +1746,7 @@ def check_eq_domains(email, domains_list):
except ValueError:
return []
domain = domain.lower()
- domains_list = re.sub('\s', '', domains_list).lower()
+ domains_list = re.sub(r'\s', '', domains_list).lower()
domains = domains_list.split(';')
domains_list = []
for d in domains:
@@ -1517,7 +1779,7 @@ def xml_to_unicode(s, cset):
similar to canonstr above except for replacing invalid refs with the
unicode replace character and recognizing \\u escapes.
"""
- if isinstance(s, str):
+ if isinstance(s, bytes):
us = s.decode(cset, 'replace')
us = re.sub(u'&(#[0-9]+);', _invert_xml, us)
us = re.sub(u'(?i)\\\\(u[a-f0-9]{4})', _invert_xml, us)
@@ -1606,3 +1868,72 @@ def captcha_verify(idx, given_answer, captchas):
# We append a `$` to emulate `re.fullmatch`.
correct_answer_pattern = captchas[idx][1] + "$"
return re.match(correct_answer_pattern, given_answer)
+
+def get_current_encoding(filename):
+ encodings = [ 'utf-8', 'iso-8859-1', 'iso-8859-2', 'iso-8859-15', 'iso-8859-7', 'iso-8859-13', 'euc-jp', 'euc-kr', 'iso-8859-9', 'us-ascii' ]
+ for encoding in encodings:
+ try:
+ with open(filename, 'r', encoding=encoding) as f:
+ f.read()
+ return encoding
+ except UnicodeDecodeError as e:
+ continue
+ # if everything fails, send utf-8 and hope for the best...
+ return 'utf-8'
+
+def set_cte_if_missing(msg):
+ if not hasattr(msg, 'policy'):
+ msg.policy = email._policybase.compat32
+ if 'content-transfer-encoding' not in msg:
+ msg['Content-Transfer-Encoding'] = '7bit'
+ if msg.is_multipart():
+ for part in msg.get_payload():
+ if not hasattr(part, 'policy'):
+ part.policy = email._policybase.compat32
+ set_cte_if_missing(part)
+
+# Attempt to load a pickle file as utf-8 first, falling back to others. If they all fail, there was probably no hope. Note that get_current_encoding above is useless in testing pickles.
+def load_pickle(path):
+ import pickle
+
+ encodings = [ 'utf-8', 'iso-8859-1', 'iso-8859-2', 'iso-8859-15', 'iso-8859-7', 'iso-8859-13', 'euc-jp', 'euc-kr', 'iso-8859-9', 'us-ascii', 'latin1' ]
+
+ if isinstance(path, str):
+ for encoding in encodings:
+ try:
+ try:
+ fp = open(path, 'rb')
+ except IOError as e:
+ if e.errno != errno.ENOENT: raise
+
+ msg = pickle.load(fp, fix_imports=True, encoding=encoding)
+ fp.close()
+ return msg
+ except UnicodeDecodeError as e:
+ continue
+ except Exception as e:
+ return None
+ elif isinstance(path, bytes):
+ for encoding in encodings:
+ try:
+ msg = pickle.loads(path, fix_imports=True, encoding=encoding)
+ return msg
+ except UnicodeDecodeError:
+ continue
+ except Exception as e:
+ return None
+ # Check if it's a file-like object, such as using BufferedReader
+ elif hasattr(path, 'read') and callable(getattr(path, 'read')):
+ for encoding in encodings:
+ try:
+ msg = pickle.load(path, fix_imports=True, encoding=encoding)
+ return msg
+ except UnicodeDecodeError:
+ continue
+ except EOFError as e:
+ return None
+ except Exception as e:
+ return None
+
+ else:
+ return None
diff --git a/Mailman/Version.py b/Mailman/Version.py
index a5a806c3..4293e275 100644
--- a/Mailman/Version.py
+++ b/Mailman/Version.py
@@ -16,7 +16,7 @@
# USA.
# Mailman version
-VERSION = '2.1.39'
+VERSION = '2.2.1'
# And as a hex number in the manner of PY_VERSION_HEX
ALPHA = 0xa
@@ -27,8 +27,8 @@
FINAL = 0xf
MAJOR_REV = 2
-MINOR_REV = 1
-MICRO_REV = 39
+MINOR_REV = 2
+MICRO_REV = 1
REL_LEVEL = FINAL
# at most 15 beta releases!
REL_SERIAL = 0
diff --git a/Mailman/__init__.py b/Mailman/__init__.py.in
similarity index 93%
rename from Mailman/__init__.py
rename to Mailman/__init__.py.in
index b271f895..21ebf673 100644
--- a/Mailman/__init__.py
+++ b/Mailman/__init__.py.in
@@ -13,3 +13,6 @@
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+import sys
+sys.path.append('@VAR_PREFIX@/Mailman')
diff --git a/Mailman/htmlformat.py b/Mailman/htmlformat.py
index bcfb974e..ad9bb08a 100644
--- a/Mailman/htmlformat.py
+++ b/Mailman/htmlformat.py
@@ -444,8 +444,7 @@ def Format(self, indent=0):
spaces, self.action, self.method, encoding)
if self.mlist:
output = output + \
- '\n' \
- % csrf_token(self.mlist, self.contexts, self.user)
+ '\n'.format( csrf_token(self.mlist, self.contexts, self.user))
output = output + Container.Format(self, indent+2)
output = '%s\n%s\n' % (output, spaces)
return output
@@ -461,8 +460,7 @@ def __init__(self, name, ty, value, checked, **kws):
def Format(self, indent=0):
charset = get_translation().charset() or 'us-ascii'
- output = ['%s' % self.text
if isinstance(output, str):
output = output.encode(charset, 'xmlcharrefreplace')
+ output = output.decode() # Does this break the charset?
return output
class FileUpload(InputObj):
@@ -648,7 +650,8 @@ def Format(self, indent=0):
# These are the URLs which the image logos link to. The Mailman home page now
# points at the gnu.org site instead of the www.list.org mirror.
#
-from mm_cfg import MAILMAN_URL
+MAILMAN_URL = mm_cfg.MAILMAN_URL
+# from Mailman.mm_cfg import MAILMAN_URL
PYTHON_URL = 'http://www.python.org/'
GNU_URL = 'http://www.gnu.org/'
diff --git a/Mailman/i18n.py b/Mailman/i18n.py
index 59de262b..ff8a08ca 100644
--- a/Mailman/i18n.py
+++ b/Mailman/i18n.py
@@ -100,8 +100,8 @@ def _(s, frame=1):
if not charset:
charset = 'us-ascii'
for k, v in list(dict.items()):
- if isinstance(v, str):
- dict[k] = v.encode(charset, 'replace')
+ if isinstance(v, bytes):
+ dict[k] = v.decode('utf-8', 'replace')
try:
return tns % dict
except (ValueError, TypeError):
diff --git a/Mailman/mm_cfg.py.dist.in b/Mailman/mm_cfg.py.dist.in
index df809426..3d278b7c 100644
--- a/Mailman/mm_cfg.py.dist.in
+++ b/Mailman/mm_cfg.py.dist.in
@@ -43,12 +43,10 @@ affect lists created after the change. For existing lists, see the FAQ at
"""
-import sys
###############################################
# Here's where we get the distributed defaults.
-sys.path.append('@VAR_PREFIX@/Mailman')
-from Defaults import *
+from Mailman.Defaults import *
##################################################
# Put YOUR site-specific settings below this line.
diff --git a/Mailman/versions.py b/Mailman/versions.py
index b540f3e1..42aff37a 100644
--- a/Mailman/versions.py
+++ b/Mailman/versions.py
@@ -349,12 +349,12 @@ def convert(s, f, t):
# transfer the list data type for holding members and digest members
# to the dict data type starting file format version 11
#
- if type(l.members) is ListType:
+ if type(l.members) is list:
members = {}
for m in l.members:
members[m] = 1
l.members = members
- if type(l.digest_members) is ListType:
+ if type(l.digest_members) is list:
dmembers = {}
for dm in l.digest_members:
dmembers[dm] = 1
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 00000000..5786eb4c
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,64 @@
+# generated automatically by aclocal 1.17 -*- Autoconf -*-
+
+# Copyright (C) 1996-2024 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2024 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 2006-2024 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
diff --git a/bin/change_pw b/bin/change_pw
index c0c7c8e1..28df1aa1 100644
--- a/bin/change_pw
+++ b/bin/change_pw
@@ -147,12 +147,12 @@ def main():
if password is not None:
if not password:
usage(1, C_('Empty list passwords are not allowed'))
- shapassword = Utils.sha_new(password).hexdigest()
+ shapassword = Utils.sha_new(password.encode()).hexdigest()
if domains:
for name in Utils.list_names():
mlist = openlist(name)
- if domains.has_key(mlist.host_name):
+ if mlist.host_name in domains:
listnames[name] = 1
if not listnames:
@@ -167,7 +167,7 @@ def main():
if password is None:
randompw = Utils.MakeRandomPassword(
mm_cfg.ADMIN_PASSWORD_LENGTH)
- shapassword = Utils.sha_new(randompw).hexdigest()
+ shapassword = Utils.sha_new(randompw.encode('utf-8')).hexdigest()
notifypassword = randompw
else:
notifypassword = password
diff --git a/bin/check_db b/bin/check_db
index b874c227..d44e18fd 100755
--- a/bin/check_db
+++ b/bin/check_db
@@ -84,7 +84,7 @@ def testfile(dbfile):
loadfunc = pickle.load
else:
assert 0
- fp = open(dbfile)
+ fp = open(dbfile,'rb')
try:
loadfunc(fp)
finally:
diff --git a/bin/cleanarch b/bin/cleanarch
index 2d6b0023..089d72dd 100644
--- a/bin/cleanarch
+++ b/bin/cleanarch
@@ -56,7 +56,13 @@ import mailbox
import paths
from Mailman.i18n import C_
-cre = re.compile(mailbox.UnixMailbox._fromlinepattern)
+# Taken from legacy module
+og_fromlinepattern = (r"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+"
+ r"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*"
+ r"[^\s]*\s*"
+ "$")
+
+cre = re.compile(og_fromlinepattern)
# From RFC 2822, a header field name must contain only characters from 33-126
# inclusive, excluding colon. I.e. from oct 41 to oct 176 less oct 072. Must
diff --git a/bin/clone_member b/bin/clone_member
index cfe40921..6b015335 100755
--- a/bin/clone_member
+++ b/bin/clone_member
@@ -110,6 +110,7 @@ def dolist(mlist, options):
if foundp:
newowners[options.toaddr] = 1
newowners = newowners.keys()
+ newowners = list(newowners)
newowners.sort()
if options.modify:
mlist.owner = newowners
diff --git a/bin/config_list b/bin/config_list
index f08d05f5..65daca30 100644
--- a/bin/config_list
+++ b/bin/config_list
@@ -262,7 +262,7 @@ def do_input(listname, infile, checkonly, verbose):
globals = {'mlist': mlist}
# Any exception that occurs in execfile() will cause the list to not
# be saved, but any other problems are not save-fatal.
- execfile(infile, globals)
+ exec(open(infile).read(), globals)
savelist = 1
for k, v in list(globals.items()):
if k in ('mlist', '__builtins__'):
diff --git a/bin/dumpdb b/bin/dumpdb
index 2800dd26..7d8ac590 100644
--- a/bin/dumpdb
+++ b/bin/dumpdb
@@ -54,6 +54,7 @@ import marshal
import paths
# Import this /after/ paths so that the sys.path is properly hacked
from Mailman.i18n import C_
+from Mailman import Utils
PROGRAM = sys.argv[0]
COMMASPACE = ', '
@@ -125,7 +126,14 @@ def main():
print(C_('[----- start %(typename)s file -----]'))
while True:
try:
- obj = load(fp)
+ if typename == 'pickle':
+ obj = Utils.load_pickle(fp)
+ if obj is None:
+ if doprint:
+ print(C_('[----- end %(typename)s file -----]'))
+ break
+ else:
+ obj = load(fp, encoding='utf-8')
except EOFError:
if doprint:
print(C_('[----- end %(typename)s file -----]'))
diff --git a/bin/export.py b/bin/export.py
index 5c88c1b8..f9ff5f0e 100644
--- a/bin/export.py
+++ b/bin/export.py
@@ -146,7 +146,7 @@ def _element(self, _name, _value=None, **_attributes):
if _value is None:
print('<%s%s/>' % (_name, attrs), file=self._fp)
else:
- value = escape(unicode(_value))
+ value = escape(str(_value))
print('<%s%s>%s%s>' % (_name, attrs, value, _name), file=self._fp)
def _do_list_categories(self, mlist, k, subcat=None):
@@ -289,15 +289,19 @@ def plaintext_password(password):
def sha_password(password):
+ if isinstance(password, str):
+ password = password.encode()
h = Utils.sha_new(password)
- return '{SHA}' + base64.b64encode(h.digest())
+ return '{SHA}' + base64.b64encode(h.digest()).decode('utf-8')
def ssha_password(password):
+ if isinstance(password, str):
+ password = password.encode()
salt = os.urandom(SALT_LENGTH)
h = Utils.sha_new(password)
h.update(salt)
- return '{SSHA}' + base64.b64encode(h.digest() + salt)
+ return '{SSHA}' + base64.b64encode(h.digest() + salt).decode('utf-8')
SCHEMES = {
diff --git a/bin/list_members b/bin/list_members
index a26b1977..a1f148a8 100755
--- a/bin/list_members
+++ b/bin/list_members
@@ -115,10 +115,11 @@ def usage(code, msg=''):
def safe(s):
if not s:
return ''
- if isinstance(s, UnicodeType):
- return s.encode(ENC, 'replace')
- return str(s, ENC, 'replace').encode(ENC, 'replace')
-
+ if isinstance(s, str):
+ return s
+ elif isinstance(s, bytes):
+ return s.decode(ENC, 'replace')
+ return str(s)
def isinvalid(addr):
try:
@@ -128,7 +129,7 @@ def isinvalid(addr):
return True
def isunicode(addr):
- return isinstance(addr, UnicodeType)
+ return isinstance(addr, str)
diff --git a/bin/mmsitepass b/bin/mmsitepass
index 86d9f403..8247f2a0 100755
--- a/bin/mmsitepass
+++ b/bin/mmsitepass
@@ -22,7 +22,7 @@ The site password can be used in most if not all places that the list
administrator's password can be used, which in turn can be used in most places
that a list users password can be used.
-Usage: %(PROGRAM)s [options] [password]
+Usage: mmsitepass [options] [password]
Options:
@@ -83,7 +83,7 @@ def main():
pw1 = args[0]
else:
try:
- pw1 = getpass.getpass('New %(pwdesc)s password: ')
+ pw1 = getpass.getpass(f'New {pwdesc} password: ')
pw2 = getpass.getpass('Again to confirm password: ')
if pw1 != pw2:
print('Passwords do not match; no changes made.')
diff --git a/bin/msgfmt.py b/bin/msgfmt.py
index 4ae4e8e5..78b4ef6a 100644
--- a/bin/msgfmt.py
+++ b/bin/msgfmt.py
@@ -39,9 +39,9 @@
def usage(code, msg=''):
- print >> sys.stderr, __doc__
+ sys.stderr.write(str(__doc__) + "\n")
if msg:
- print >> sys.stderr, msg
+ sys.stderr.write(str(msg) + "\n")
sys.exit(code)
diff --git a/bin/newlist b/bin/newlist
index a4ed575c..eeab3eb3 100755
--- a/bin/newlist
+++ b/bin/newlist
@@ -164,7 +164,7 @@ def main():
if len(args) > 0:
listname = args[0]
else:
- listname = raw_input('Enter the name of the list: ')
+ listname = input('Enter the name of the list: ')
listname = listname.lower()
if '@' in listname:
@@ -184,7 +184,7 @@ def main():
if len(args) > 1:
owner_mail = args[1]
else:
- owner_mail = raw_input(
+ owner_mail = input(
C_('Enter the email of the person running the list: '))
if len(args) > 2:
@@ -198,7 +198,7 @@ def main():
mlist = MailList.MailList()
try:
- pw = Utils.sha_new(listpasswd).hexdigest()
+ pw = Utils.sha_new(listpasswd.encode()).hexdigest()
# Guarantee that all newly created files have the proper permission.
# proper group ownership should be assured by the autoconf script
# enforcing that all directories have the group sticky bit set
diff --git a/bin/qrunner b/bin/qrunner
index bd2f263c..7b7b515e 100644
--- a/bin/qrunner
+++ b/bin/qrunner
@@ -79,6 +79,10 @@ import time
import paths
from Mailman import mm_cfg
+# Debug: Log when mm_cfg is imported in qrunner
+from Mailman.Logging.Syslog import syslog
+syslog('debug', 'qrunner: mm_cfg imported from %s', mm_cfg.__file__)
+syslog('debug', 'qrunner: mm_cfg.GLOBAL_PIPELINE type: %s', type(mm_cfg.GLOBAL_PIPELINE).__name__ if hasattr(mm_cfg, 'GLOBAL_PIPELINE') else 'NOT FOUND')
from Mailman.i18n import C_
from Mailman.Logging.Syslog import syslog
from Mailman.Logging.Utils import LogStdErr
@@ -164,6 +168,12 @@ def main():
except getopt.error as msg:
usage(1, msg)
+ def silent_unraisable_hook(unraisable):
+ pass
+
+ if hasattr(sys, 'unraisablehook'):
+ sys.unraisablehook = silent_unraisable_hook
+
once = 0
runners = []
verbose = 0
diff --git a/bin/show_qfiles b/bin/show_qfiles
index 10f9e131..8125d7c2 100644
--- a/bin/show_qfiles
+++ b/bin/show_qfiles
@@ -72,7 +72,7 @@ def main():
for filename in args:
if not quiet:
print(('====================>', filename))
- fp = open(filename)
+ fp = open(filename,'rb')
if filename.endswith(".pck"):
msg = load(fp)
data = load(fp)
diff --git a/bin/sync_members b/bin/sync_members
index 26801415..71a69638 100755
--- a/bin/sync_members
+++ b/bin/sync_members
@@ -80,7 +80,7 @@ import sys
import paths
# Import this /after/ paths so that the sys.path is properly hacked
-import email.Utils
+import email.utils
from Mailman import MailList
from Mailman import Errors
@@ -203,7 +203,7 @@ def main():
print(C_('Ignore : %(addr)30s'))
# first filter out any invalid addresses
- filemembers = email.Utils.getaddresses(filemembers)
+ filemembers = email.utils.getaddresses(filemembers)
invalid = 0
for name, addr in filemembers:
try:
@@ -234,7 +234,7 @@ def main():
# Any address found in the file that is also in the list can be
# ignored. If not found in the list, it must be added later.
laddr = addr.lower()
- if addrs.has_key(laddr):
+ if laddr in addrs:
del addrs[laddr]
matches[laddr] = 1
elif not matches.has_key(laddr):
@@ -256,11 +256,8 @@ def main():
try:
if not dryrun:
mlist.ApprovedAddMember(userdesc, welcome, notifyadmin)
- # Avoid UnicodeError if name can't be decoded
- if isinstance(name, str):
- name = unicode(name, errors='replace')
name = name.encode(enc, 'replace')
- s = email.Utils.formataddr((name, addr)).encode(enc, 'replace')
+ s = email.utils.formataddr((name, addr)).encode(enc, 'replace')
print(C_('Added : %(s)s'))
except Errors.MMAlreadyAMember:
pass
@@ -277,15 +274,12 @@ def main():
userack=goodbye)
except Errors.NotAMemberError:
# This can happen if the address is illegal (i.e. can't be
- # parsed by email.Utils.parseaddr()) but for legacy
+ # parsed by email.utils.parseaddr()) but for legacy
# reasons is in the database. Use a lower level remove to
# get rid of this member's entry
mlist.removeMember(addr)
- # Avoid UnicodeError if name can't be decoded
- if isinstance(name, str):
- name = unicode(name, errors='replace')
name = name.encode(enc, 'replace')
- s = email.Utils.formataddr((name, addr)).encode(enc, 'replace')
+ s = email.utils.formataddr((name, addr)).encode(enc, 'replace')
print(C_('Removed: %(s)s'))
mlist.Save()
diff --git a/bin/unshunt b/bin/unshunt
index c2ab7687..5ceb1197 100644
--- a/bin/unshunt
+++ b/bin/unshunt
@@ -40,6 +40,7 @@ from Mailman import mm_cfg
from Mailman.Queue.sbcache import get_switchboard
from Mailman.i18n import C_
+PROGRAM = sys.argv[0]
def usage(code, msg=''):
@@ -47,7 +48,7 @@ def usage(code, msg=''):
fd = sys.stderr
else:
fd = sys.stdout
- print(fd, C_(__doc__, file=fd))
+ print(C_(__doc__), file=fd)
if msg:
print(msg, file=fd)
sys.exit(code)
@@ -82,8 +83,7 @@ def main():
except Exception as e:
# If there are any unshunting errors, log them and continue trying
# other shunted messages.
- print(C_(
- 'Cannot unshunt message %(filebase)s, skipping:\n%(e)s'), file=sys.stderr)
+ print(C_('Cannot unshunt message %(filebase)s, skipping:\n%(e)s'), file=sys.stderr)
else:
# Unlink the .bak file left by dequeue()
sb.finish(filebase)
diff --git a/configure b/configure
index c5b79d6c..e82fb66f 100755
--- a/configure
+++ b/configure
@@ -1,11 +1,10 @@
#! /bin/sh
# From configure.in Revision: 8122 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71.
+# Generated by GNU Autoconf 2.69.
#
#
-# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
-# Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -16,16 +15,14 @@
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
-as_nop=:
-if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
-then :
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
-else $as_nop
+else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
@@ -35,46 +32,46 @@ esac
fi
-
-# Reset variables that may have inherited troublesome values from
-# the environment.
-
-# IFS needs to be set, to space, tab, and newline, in precisely that order.
-# (If _AS_PATH_WALK were called with IFS unset, it would have the
-# side effect of setting IFS to empty, thus disabling word splitting.)
-# Quoting is to prevent editors from complaining about space-tab.
as_nl='
'
export as_nl
-IFS=" "" $as_nl"
-
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# Ensure predictable behavior from utilities with locale-dependent output.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# We cannot yet rely on "unset" to work, but we need these variables
-# to be unset--not just set to an empty or harmless value--now, to
-# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
-# also avoids known problems related to "unset" and subshell syntax
-# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
-for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
-do eval test \${$as_var+y} \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-
-# Ensure that fds 0, 1, and 2 are open.
-if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
-if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
# The user is always right.
-if ${PATH_SEPARATOR+false} :; then
+if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -83,6 +80,13 @@ if ${PATH_SEPARATOR+false} :; then
fi
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
@@ -91,12 +95,8 @@ case $0 in #((
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
@@ -108,10 +108,30 @@ if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
- printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# Use a proper internal environment variable to ensure we don't fall
# into an infinite loop, continuously re-executing ourselves.
@@ -133,22 +153,20 @@ esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
-printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
fi
# We don't want this to propagate to other subprocesses.
{ _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="as_nop=:
-if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
-then :
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
# is contrary to our usage. Disable this feature.
alias -g '\${1+\"\$@\"}'='\"\$@\"'
setopt NO_GLOB_SUBST
-else \$as_nop
+else
case \`(set -o) 2>/dev/null\` in #(
*posix*) :
set -o posix ;; #(
@@ -168,53 +186,42 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" )
-then :
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-else \$as_nop
+else
exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
-blah=\$(echo \$(echo blah))
-test x\"\$blah\" = xblah || exit 1
test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
test \$(( 1 + 1 )) = 2 || exit 1"
- if (eval "$as_required") 2>/dev/null
-then :
+ if (eval "$as_required") 2>/dev/null; then :
as_have_required=yes
-else $as_nop
+else
as_have_required=no
fi
- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
-then :
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-else $as_nop
+else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
as_found=:
case $as_dir in #(
/*)
for as_base in sh bash ksh sh5; do
# Try only shells that exist, to save several forks.
- as_shell=$as_dir$as_base
+ as_shell=$as_dir/$as_base
if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
-then :
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
CONFIG_SHELL=$as_shell as_have_required=yes
- if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
-then :
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
break 2
fi
fi
@@ -222,21 +229,14 @@ fi
esac
as_found=false
done
-IFS=$as_save_IFS
-if $as_found
-then :
-
-else $as_nop
- if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
- as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
-then :
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
CONFIG_SHELL=$SHELL as_have_required=yes
-fi
-fi
+fi; }
+IFS=$as_save_IFS
- if test "x$CONFIG_SHELL" != x
-then :
+ if test "x$CONFIG_SHELL" != x; then :
export CONFIG_SHELL
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
@@ -254,19 +254,18 @@ esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
-printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi
- if test x$as_have_required = xno
-then :
- printf "%s\n" "$0: This script requires a shell more modern than all"
- printf "%s\n" "$0: the shells that I found on your system."
- if test ${ZSH_VERSION+y} ; then
- printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
- printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
- printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system,
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
$0: including any error possibly output before this
$0: message. Then install a modern shell, or manually run
$0: the script under such a shell if you do have one."
@@ -293,7 +292,6 @@ as_fn_unset ()
}
as_unset=as_fn_unset
-
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
@@ -311,14 +309,6 @@ as_fn_exit ()
as_fn_set_status $1
exit $1
} # as_fn_exit
-# as_fn_nop
-# ---------
-# Do nothing but, unlike ":", preserve the value of $?.
-as_fn_nop ()
-{
- return $?
-}
-as_nop=as_fn_nop
# as_fn_mkdir_p
# -------------
@@ -333,7 +323,7 @@ as_fn_mkdir_p ()
as_dirs=
while :; do
case $as_dir in #(
- *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
@@ -342,7 +332,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-printf "%s\n" X"$as_dir" |
+$as_echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -381,13 +371,12 @@ as_fn_executable_p ()
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
-then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
-else $as_nop
+else
as_fn_append ()
{
eval $1=\$$1\$2
@@ -399,27 +388,18 @@ fi # as_fn_append
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
-then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
-else $as_nop
+else
as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
}
fi # as_fn_arith
-# as_fn_nop
-# ---------
-# Do nothing but, unlike ":", preserve the value of $?.
-as_fn_nop ()
-{
- return $?
-}
-as_nop=as_fn_nop
# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
@@ -431,9 +411,9 @@ as_fn_error ()
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
- printf "%s\n" "$as_me: error: $2" >&2
+ $as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -460,7 +440,7 @@ as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-printf "%s\n" X/"$0" |
+$as_echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
@@ -504,7 +484,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
s/-\n.*//
' >$as_me.lineno &&
chmod +x "$as_me.lineno" ||
- { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
# If we had to re-execute with $CONFIG_SHELL, we're ensured to have
# already done that, so ensure we don't try to do so again and fall
@@ -518,10 +498,6 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
exit
}
-
-# Determine whether it's possible to make 'echo' print without a newline.
-# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
-# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
@@ -535,13 +511,6 @@ case `echo -n x` in #(((((
ECHO_N='-n';;
esac
-# For backward compatibility with old third-party macros, we provide
-# the shell variables $as_echo and $as_echo_n. New code should use
-# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
-as_echo='printf %s\n'
-as_echo_n='printf %s'
-
-
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
@@ -607,53 +576,57 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME=''
-PACKAGE_TARNAME=''
-PACKAGE_VERSION=''
-PACKAGE_STRING=''
-PACKAGE_BUGREPORT=''
-PACKAGE_URL=''
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
ac_unique_file="src/common.h"
ac_default_prefix=/usr/local/mailman
# Factoring default headers for most tests.
ac_includes_default="\
-#include
-#ifdef HAVE_STDIO_H
-# include
+#include
+#ifdef HAVE_SYS_TYPES_H
+# include
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include
#endif
-#ifdef HAVE_STDLIB_H
+#ifdef STDC_HEADERS
# include
+# include
+#else
+# ifdef HAVE_STDLIB_H
+# include
+# endif
#endif
#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include
+# endif
# include
#endif
+#ifdef HAVE_STRINGS_H
+# include
+#endif
#ifdef HAVE_INTTYPES_H
# include
#endif
#ifdef HAVE_STDINT_H
# include
#endif
-#ifdef HAVE_STRINGS_H
-# include
-#endif
-#ifdef HAVE_SYS_TYPES_H
-# include
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include
-#endif
#ifdef HAVE_UNISTD_H
# include
#endif"
-ac_header_c_list=
ac_subst_vars='LTLIBOBJS
LIBOBJS
SCRIPTS
-CPP
EGREP
GREP
+CPP
URLHOST
MAILHOST
CGIEXT
@@ -814,6 +787,8 @@ do
*) ac_optarg=yes ;;
esac
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
case $ac_dashdash$ac_option in
--)
ac_dashdash=yes ;;
@@ -854,9 +829,9 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: \`$ac_useropt'"
+ as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
- ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"enable_$ac_useropt"
@@ -880,9 +855,9 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: \`$ac_useropt'"
+ as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
- ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"enable_$ac_useropt"
@@ -1093,9 +1068,9 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: \`$ac_useropt'"
+ as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
- ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"with_$ac_useropt"
@@ -1109,9 +1084,9 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: \`$ac_useropt'"
+ as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
- ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"with_$ac_useropt"
@@ -1155,9 +1130,9 @@ Try \`$0 --help' for more information"
*)
# FIXME: should be removed in autoconf 3.0.
- printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
: "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
@@ -1173,7 +1148,7 @@ if test -n "$ac_unrecognized_opts"; then
case $enable_option_checking in
no) ;;
fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
- *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
fi
@@ -1237,7 +1212,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_myself" : 'X\(//\)[^/]' \| \
X"$as_myself" : 'X\(//\)$' \| \
X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-printf "%s\n" X"$as_myself" |
+$as_echo X"$as_myself" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -1402,9 +1377,9 @@ if test "$ac_init_help" = "recursive"; then
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
- ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1432,8 +1407,7 @@ esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for configure.gnu first; this name is used for a wrapper for
- # Metaconfig's "Configure" on case-insensitive file systems.
+ # Check for guested configure.
if test -f "$ac_srcdir/configure.gnu"; then
echo &&
$SHELL "$ac_srcdir/configure.gnu" --help=recursive
@@ -1441,7 +1415,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
echo &&
$SHELL "$ac_srcdir/configure" --help=recursive
else
- printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi || ac_status=$?
cd "$ac_pwd" || { ac_status=$?; break; }
done
@@ -1451,9 +1425,9 @@ test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
configure
-generated by GNU Autoconf 2.71
+generated by GNU Autoconf 2.69
-Copyright (C) 2021 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1470,14 +1444,14 @@ fi
ac_fn_c_try_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest.beam
+ rm -f conftest.$ac_objext
if { { ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
@@ -1485,15 +1459,14 @@ printf "%s\n" "$ac_try_echo"; } >&5
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
- } && test -s conftest.$ac_objext
-then :
+ } && test -s conftest.$ac_objext; then :
ac_retval=0
-else $as_nop
- printf "%s\n" "$as_me: failed program was:" >&5
+else
+ $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
@@ -1509,14 +1482,14 @@ fi
ac_fn_c_try_link ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+ rm -f conftest.$ac_objext conftest$ac_exeext
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
@@ -1524,18 +1497,17 @@ printf "%s\n" "$ac_try_echo"; } >&5
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
test -x conftest$ac_exeext
- }
-then :
+ }; then :
ac_retval=0
-else $as_nop
- printf "%s\n" "$as_me: failed program was:" >&5
+else
+ $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
@@ -1556,12 +1528,11 @@ fi
ac_fn_c_check_func ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-printf %s "checking for $2... " >&6; }
-if eval test \${$3+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Define $2 to an innocuous variant, in case declares $2.
@@ -1569,9 +1540,16 @@ else $as_nop
#define $2 innocuous_$2
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below. */
+ which can conflict with char $2 (); below.
+ Prefer to if __STDC__ is defined, since
+ exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include
+#else
+# include
+#endif
-#include
#undef $2
/* Override any GCC internal prototype to avoid an error.
@@ -1589,62 +1567,28 @@ choke me
#endif
int
-main (void)
+main ()
{
return $2 ();
;
return 0;
}
_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
+if ac_fn_c_try_link "$LINENO"; then :
eval "$3=yes"
-else $as_nop
+else
eval "$3=no"
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
+rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
eval ac_res=\$$3
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-printf "%s\n" "$ac_res" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_func
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-printf %s "checking for $2... " >&6; }
-if eval test \${$3+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"
-then :
- eval "$3=yes"
-else $as_nop
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-printf "%s\n" "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-
# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1657,7 +1601,7 @@ case "(($ac_try" in
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
@@ -1665,15 +1609,14 @@ printf "%s\n" "$ac_try_echo"; } >&5
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } > conftest.i && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
- }
-then :
+ }; then :
ac_retval=0
-else $as_nop
- printf "%s\n" "$as_me: failed program was:" >&5
+else
+ $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
@@ -1683,10 +1626,97 @@ fi
} # ac_fn_c_try_cpp
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
# ac_fn_c_try_run LINENO
# ----------------------
-# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
-# executables *can* be run.
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
ac_fn_c_try_run ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
@@ -1696,26 +1726,25 @@ case "(($ac_try" in
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
{ { case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_try") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
-then :
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
ac_retval=0
-else $as_nop
- printf "%s\n" "$as_me: program exited with status $ac_status" >&5
- printf "%s\n" "$as_me: failed program was:" >&5
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=$ac_status
@@ -1725,34 +1754,45 @@ fi
as_fn_set_status $ac_retval
} # ac_fn_c_try_run
-ac_configure_args_raw=
-for ac_arg
-do
- case $ac_arg in
- *\'*)
- ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append ac_configure_args_raw " '$ac_arg'"
-done
-case $ac_configure_args_raw in
- *$as_nl*)
- ac_safe_unquote= ;;
- *)
- ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab.
- ac_unsafe_a="$ac_unsafe_z#~"
- ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
- ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
-esac
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+} # ac_fn_c_check_header_compile
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by $as_me, which was
-generated by GNU Autoconf 2.71. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
- $ $0$ac_configure_args_raw
+ $ $0 $@
_ACEOF
exec 5>>config.log
@@ -1785,12 +1825,8 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- printf "%s\n" "PATH: $as_dir"
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
done
IFS=$as_save_IFS
@@ -1825,7 +1861,7 @@ do
| -silent | --silent | --silen | --sile | --sil)
continue ;;
*\'*)
- ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
case $ac_pass in
1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
@@ -1860,13 +1896,11 @@ done
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
- # Sanitize IFS.
- IFS=" "" $as_nl"
# Save into config.log some information that might help in debugging.
{
echo
- printf "%s\n" "## ---------------- ##
+ $as_echo "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
echo
@@ -1877,8 +1911,8 @@ trap 'exit_status=$?
case $ac_val in #(
*${as_nl}*)
case $ac_var in #(
- *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
esac
case $ac_var in #(
_ | IFS | as_nl) ;; #(
@@ -1902,7 +1936,7 @@ printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;}
)
echo
- printf "%s\n" "## ----------------- ##
+ $as_echo "## ----------------- ##
## Output variables. ##
## ----------------- ##"
echo
@@ -1910,14 +1944,14 @@ printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;}
do
eval ac_val=\$$ac_var
case $ac_val in
- *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
esac
- printf "%s\n" "$ac_var='\''$ac_val'\''"
+ $as_echo "$ac_var='\''$ac_val'\''"
done | sort
echo
if test -n "$ac_subst_files"; then
- printf "%s\n" "## ------------------- ##
+ $as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
echo
@@ -1925,15 +1959,15 @@ printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;}
do
eval ac_val=\$$ac_var
case $ac_val in
- *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
esac
- printf "%s\n" "$ac_var='\''$ac_val'\''"
+ $as_echo "$ac_var='\''$ac_val'\''"
done | sort
echo
fi
if test -s confdefs.h; then
- printf "%s\n" "## ----------- ##
+ $as_echo "## ----------- ##
## confdefs.h. ##
## ----------- ##"
echo
@@ -1941,8 +1975,8 @@ printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;}
echo
fi
test "$ac_signal" != 0 &&
- printf "%s\n" "$as_me: caught signal $ac_signal"
- printf "%s\n" "$as_me: exit $exit_status"
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
} >&5
rm -f core *.core core.conftest.* &&
rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
@@ -1956,48 +1990,63 @@ ac_signal=0
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h
-printf "%s\n" "/* confdefs.h */" > confdefs.h
+$as_echo "/* confdefs.h */" > confdefs.h
# Predefined preprocessor variables.
-printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
-printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
-printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
-printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
-printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
-printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
- ac_site_files="$CONFIG_SITE"
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
elif test "x$prefix" != xNONE; then
- ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
else
- ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
fi
-
-for ac_site_file in $ac_site_files
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
- case $ac_site_file in #(
- */*) :
- ;; #(
- *) :
- ac_site_file=./$ac_site_file ;;
-esac
- if test -f "$ac_site_file" && test -r "$ac_site_file"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file" \
- || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5; }
fi
@@ -2007,507 +2056,91 @@ if test -r "$cache_file"; then
# Some versions of bash will fail to source /dev/null (special files
# actually), so we avoid doing that. DJGPP emulates it as a regular file.
if test /dev/null != "$cache_file" && test -f "$cache_file"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
[\\/]* | ?:[\\/]* ) . "$cache_file";;
*) . "./$cache_file";;
esac
fi
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
>$cache_file
fi
-# Test code for whether the C compiler supports C89 (global declarations)
-ac_c_conftest_c89_globals='
-/* Does the compiler advertise C89 conformance?
- Do not test the value of __STDC__, because some compilers set it to 0
- while being otherwise adequately conformant. */
-#if !defined __STDC__
-# error "Compiler does not advertise C89 conformance"
-#endif
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
-#include
-#include
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */
-struct buf { int x; };
-struct buf * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not \xHH hex character constants.
- These do not provoke an error unfortunately, instead are silently treated
- as an "x". The following induces an error, until -std is added to get
- proper ANSI mode. Curiously \x00 != x always comes out true, for an
- array size at least. It is necessary to write \x00 == 0 to get something
- that is true only with -std. */
-int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) '\''x'\''
-int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
- int, int);'
-# Test code for whether the C compiler supports C89 (body of main).
-ac_c_conftest_c89_main='
-ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
-'
-# Test code for whether the C compiler supports C99 (global declarations)
-ac_c_conftest_c99_globals='
-// Does the compiler advertise C99 conformance?
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
-# error "Compiler does not advertise C99 conformance"
-#endif
-
-#include
-extern int puts (const char *);
-extern int printf (const char *, ...);
-extern int dprintf (int, const char *, ...);
-extern void *malloc (size_t);
-
-// Check varargs macros. These examples are taken from C99 6.10.3.5.
-// dprintf is used instead of fprintf to avoid needing to declare
-// FILE and stderr.
-#define debug(...) dprintf (2, __VA_ARGS__)
-#define showlist(...) puts (#__VA_ARGS__)
-#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
-static void
-test_varargs_macros (void)
-{
- int x = 1234;
- int y = 5678;
- debug ("Flag");
- debug ("X = %d\n", x);
- showlist (The first, second, and third items.);
- report (x>y, "x is %d but y is %d", x, y);
-}
-
-// Check long long types.
-#define BIG64 18446744073709551615ull
-#define BIG32 4294967295ul
-#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
-#if !BIG_OK
- #error "your preprocessor is broken"
-#endif
-#if BIG_OK
-#else
- #error "your preprocessor is broken"
-#endif
-static long long int bignum = -9223372036854775807LL;
-static unsigned long long int ubignum = BIG64;
-
-struct incomplete_array
-{
- int datasize;
- double data[];
-};
-
-struct named_init {
- int number;
- const wchar_t *name;
- double average;
-};
-
-typedef const char *ccp;
-
-static inline int
-test_restrict (ccp restrict text)
-{
- // See if C++-style comments work.
- // Iterate through items via the restricted pointer.
- // Also check for declarations in for loops.
- for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
- continue;
- return 0;
-}
-
-// Check varargs and va_copy.
-static bool
-test_varargs (const char *format, ...)
-{
- va_list args;
- va_start (args, format);
- va_list args_copy;
- va_copy (args_copy, args);
-
- const char *str = "";
- int number = 0;
- float fnumber = 0;
-
- while (*format)
- {
- switch (*format++)
- {
- case '\''s'\'': // string
- str = va_arg (args_copy, const char *);
- break;
- case '\''d'\'': // int
- number = va_arg (args_copy, int);
- break;
- case '\''f'\'': // float
- fnumber = va_arg (args_copy, double);
- break;
- default:
- break;
- }
- }
- va_end (args_copy);
- va_end (args);
-
- return *str && number && fnumber;
-}
-'
-
-# Test code for whether the C compiler supports C99 (body of main).
-ac_c_conftest_c99_main='
- // Check bool.
- _Bool success = false;
- success |= (argc != 0);
-
- // Check restrict.
- if (test_restrict ("String literal") == 0)
- success = true;
- char *restrict newvar = "Another string";
-
- // Check varargs.
- success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
- test_varargs_macros ();
-
- // Check flexible array members.
- struct incomplete_array *ia =
- malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
- ia->datasize = 10;
- for (int i = 0; i < ia->datasize; ++i)
- ia->data[i] = i * 1.234;
-
- // Check named initializers.
- struct named_init ni = {
- .number = 34,
- .name = L"Test wide string",
- .average = 543.34343,
- };
-
- ni.number = 58;
-
- int dynamic_array[ni.number];
- dynamic_array[0] = argv[0][0];
- dynamic_array[ni.number - 1] = 543;
-
- // work around unused variable warnings
- ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
- || dynamic_array[ni.number - 1] != 543);
-'
-
-# Test code for whether the C compiler supports C11 (global declarations)
-ac_c_conftest_c11_globals='
-// Does the compiler advertise C11 conformance?
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
-# error "Compiler does not advertise C11 conformance"
-#endif
-
-// Check _Alignas.
-char _Alignas (double) aligned_as_double;
-char _Alignas (0) no_special_alignment;
-extern char aligned_as_int;
-char _Alignas (0) _Alignas (int) aligned_as_int;
-
-// Check _Alignof.
-enum
-{
- int_alignment = _Alignof (int),
- int_array_alignment = _Alignof (int[100]),
- char_alignment = _Alignof (char)
-};
-_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
-
-// Check _Noreturn.
-int _Noreturn does_not_return (void) { for (;;) continue; }
-
-// Check _Static_assert.
-struct test_static_assert
-{
- int x;
- _Static_assert (sizeof (int) <= sizeof (long int),
- "_Static_assert does not work in struct");
- long int y;
-};
-
-// Check UTF-8 literals.
-#define u8 syntax error!
-char const utf8_literal[] = u8"happens to be ASCII" "another string";
-
-// Check duplicate typedefs.
-typedef long *long_ptr;
-typedef long int *long_ptr;
-typedef long_ptr long_ptr;
-
-// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
-struct anonymous
-{
- union {
- struct { int i; int j; };
- struct { int k; long int l; } w;
- };
- int m;
-} v1;
-'
-
-# Test code for whether the C compiler supports C11 (body of main).
-ac_c_conftest_c11_main='
- _Static_assert ((offsetof (struct anonymous, i)
- == offsetof (struct anonymous, w.k)),
- "Anonymous union alignment botch");
- v1.i = 2;
- v1.w.k = 5;
- ok |= v1.i != 5;
-'
-
-# Test code for whether the C compiler supports C11 (complete).
-ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
-${ac_c_conftest_c99_globals}
-${ac_c_conftest_c11_globals}
-
-int
-main (int argc, char **argv)
-{
- int ok = 0;
- ${ac_c_conftest_c89_main}
- ${ac_c_conftest_c99_main}
- ${ac_c_conftest_c11_main}
- return ok;
-}
-"
-
-# Test code for whether the C compiler supports C99 (complete).
-ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
-${ac_c_conftest_c99_globals}
-
-int
-main (int argc, char **argv)
-{
- int ok = 0;
- ${ac_c_conftest_c89_main}
- ${ac_c_conftest_c99_main}
- return ok;
-}
-"
-
-# Test code for whether the C compiler supports C89 (complete).
-ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
-
-int
-main (int argc, char **argv)
-{
- int ok = 0;
- ${ac_c_conftest_c89_main}
- return ok;
-}
-"
-
-as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
-as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
-as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
-as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
-as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
-as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
-as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
-as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
-as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
-
-# Auxiliary files required by this configure script.
-ac_aux_files="install-sh"
-
-# Locations in which to look for auxiliary files.
-ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.."
-
-# Search for a directory containing all of the required auxiliary files,
-# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.
-# If we don't find one directory that contains all the files we need,
-# we report the set of missing files from the *first* directory in
-# $ac_aux_dir_candidates and give up.
-ac_missing_aux_files=""
-ac_first_candidate=:
-printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in $ac_aux_dir_candidates
-do
- IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- as_found=:
-
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5
- ac_aux_dir_found=yes
- ac_install_sh=
- for ac_aux in $ac_aux_files
- do
- # As a special case, if "install-sh" is required, that requirement
- # can be satisfied by any of "install-sh", "install.sh", or "shtool",
- # and $ac_install_sh is set appropriately for whichever one is found.
- if test x"$ac_aux" = x"install-sh"
- then
- if test -f "${as_dir}install-sh"; then
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5
- ac_install_sh="${as_dir}install-sh -c"
- elif test -f "${as_dir}install.sh"; then
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5
- ac_install_sh="${as_dir}install.sh -c"
- elif test -f "${as_dir}shtool"; then
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5
- ac_install_sh="${as_dir}shtool install -c"
- else
- ac_aux_dir_found=no
- if $ac_first_candidate; then
- ac_missing_aux_files="${ac_missing_aux_files} install-sh"
- else
- break
- fi
- fi
- else
- if test -f "${as_dir}${ac_aux}"; then
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5
- else
- ac_aux_dir_found=no
- if $ac_first_candidate; then
- ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"
- else
- break
- fi
- fi
- fi
- done
- if test "$ac_aux_dir_found" = yes; then
- ac_aux_dir="$as_dir"
- break
- fi
- ac_first_candidate=false
-
- as_found=false
-done
-IFS=$as_save_IFS
-if $as_found
-then :
-
-else $as_nop
- as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
-fi
-
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-if test -f "${ac_aux_dir}config.guess"; then
- ac_config_guess="$SHELL ${ac_aux_dir}config.guess"
-fi
-if test -f "${ac_aux_dir}config.sub"; then
- ac_config_sub="$SHELL ${ac_aux_dir}config.sub"
-fi
-if test -f "$ac_aux_dir/configure"; then
- ac_configure="$SHELL ${ac_aux_dir}configure"
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- # differences in whitespace do not lead to failure.
- ac_old_val_w=`echo x $ac_old_val`
- ac_new_val_w=`echo x $ac_new_val`
- if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- ac_cache_corrupted=:
- else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
- eval $ac_var=\$ac_old_val
- fi
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
-printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;}
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
-printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;}
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) as_fn_append ac_configure_args " '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
- and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-# /usr/local/mailman is the default installation directory
+# /usr/local/mailman is the default installation directory
CONFIGURE_OPTS=`echo $@`
@@ -2516,12 +2149,11 @@ BUILD_DATE=`date`
# Check for Python! Better be found on $PATH
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-python" >&5
-printf %s "checking for --with-python... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-python" >&5
+$as_echo_n "checking for --with-python... " >&6; }
# Check whether --with-python was given.
-if test ${with_python+y}
-then :
+if test "${with_python+set}" = set; then :
withval=$with_python;
fi
@@ -2529,19 +2161,18 @@ case "$with_python" in
"") ans="no";;
*) ans="$with_python"
esac
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ans" >&5
-printf "%s\n" "$ans" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ans" >&5
+$as_echo "$ans" >&6; }
if test -z "$with_python"
then
# Extract the first word of "python3", so it can be a program name with args.
set dummy python3; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_path_with_python+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_with_python+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
case $with_python in
[\\/]* | ?:[\\/]*)
ac_cv_path_with_python="$with_python" # Let the user override the test with a path.
@@ -2551,15 +2182,11 @@ else $as_nop
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
- ac_cv_path_with_python="$as_dir$ac_word$ac_exec_ext"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_with_python="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -2572,18 +2199,18 @@ esac
fi
with_python=$ac_cv_path_with_python
if test -n "$with_python"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_python" >&5
-printf "%s\n" "$with_python" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_python" >&5
+$as_echo "$with_python" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Python interpreter" >&5
-printf %s "checking Python interpreter... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Python interpreter" >&5
+$as_echo_n "checking Python interpreter... " >&6; }
if test ! -x $with_python
then
as_fn_error $? "
@@ -2594,12 +2221,12 @@ then
fi
PYTHON=$with_python
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
-printf "%s\n" "$PYTHON" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
# See if Python is new enough.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Python version" >&5
-printf %s "checking Python version... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Python version" >&5
+$as_echo_n "checking Python version... " >&6; }
cat > conftest.py <&5
-printf "%s\n" "$version" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $version" >&5
+$as_echo "$version" >&6; }
# See if dnspython is installed.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dnspython" >&5
-printf %s "checking dnspython... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dnspython" >&5
+$as_echo_n "checking dnspython... " >&6; }
cat > conftest.py <
***** You must get a version < 2.0" "$LINENO" 5
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $havednspython" >&5
-printf "%s\n" "$havednspython" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $havednspython" >&5
+$as_echo "$havednspython" >&6; }
# Check the email package version.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Python's email package" >&5
-printf %s "checking Python's email package... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Python's email package" >&5
+$as_echo_n "checking Python's email package... " >&6; }
cat > conftest.py <&5
-printf "%s\n" "$needemailpkg" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $needemailpkg" >&5
+$as_echo "$needemailpkg" >&6; }
# Check Japanese codecs.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Japanese codecs" >&5
-printf %s "checking Japanese codecs... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Japanese codecs" >&5
+$as_echo_n "checking Japanese codecs... " >&6; }
cat > conftest.py <&5
-printf "%s\n" "$needjacodecs" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $needjacodecs" >&5
+$as_echo "$needjacodecs" >&6; }
# Check Korean codecs.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Korean codecs" >&5
-printf %s "checking Korean codecs... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Korean codecs" >&5
+$as_echo_n "checking Korean codecs... " >&6; }
cat > conftest.py <&5
-printf "%s\n" "$needkocodecs" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $needkocodecs" >&5
+$as_echo "$needkocodecs" >&6; }
# Make sure distutils is available. Some Linux Python packages split
# distutils into the "-devel" package, so they need both.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that Python has a working distutils" >&5
-printf %s "checking that Python has a working distutils... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that Python has a working distutils" >&5
+$as_echo_n "checking that Python has a working distutils... " >&6; }
cat > conftest.py <&5
-printf "%s\n" "$havedistutils" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $havedistutils" >&5
+$as_echo "$havedistutils" >&6; }
# Checks for programs.
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
- # Find a good install program. We prefer a C program (faster),
+# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
@@ -2828,25 +2482,20 @@ printf "%s\n" "$havedistutils" >&6; }
# OS/2's system install, which has a completely different semantic
# ./install, which can be erroneously created by make from ./install.sh.
# Reject install programs that cannot install multiple files.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-printf %s "checking for a BSD-compatible install... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
if test -z "$INSTALL"; then
-if test ${ac_cv_path_install+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- # Account for fact that we put trailing slashes in our PATH walk.
-case $as_dir in #((
- ./ | /[cC]/* | \
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
/etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
/usr/ucb/* ) ;;
@@ -2856,13 +2505,13 @@ case $as_dir in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
- grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
elif test $ac_prog = install &&
- grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# program-specific install script used by HP pwplus--don't use.
:
else
@@ -2870,12 +2519,12 @@ case $as_dir in #((
echo one > conftest.one
echo two > conftest.two
mkdir conftest.dir
- if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" &&
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
test -s conftest.one && test -s conftest.two &&
test -s conftest.dir/conftest.one &&
test -s conftest.dir/conftest.two
then
- ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c"
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
break 3
fi
fi
@@ -2891,7 +2540,7 @@ IFS=$as_save_IFS
rm -rf conftest.one conftest.two conftest.dir
fi
- if test ${ac_cv_path_install+y}; then
+ if test "${ac_cv_path_install+set}" = set; then
INSTALL=$ac_cv_path_install
else
# As a last resort, use the slow shell script. Don't cache a
@@ -2901,8 +2550,8 @@ fi
INSTALL=$ac_install_sh
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-printf "%s\n" "$INSTALL" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
@@ -2912,14 +2561,13 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
-ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval test \${ac_cv_prog_make_${ac_make}_set+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
cat >conftest.make <<\_ACEOF
SHELL = /bin/sh
all:
@@ -2935,23 +2583,22 @@ esac
rm -f conftest.make
fi
if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
SET_MAKE=
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
SET_MAKE="MAKE=${MAKE-make}"
fi
# Extract the first word of "true", so it can be a program name with args.
set dummy true; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_path_TRUE+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_TRUE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
case $TRUE in
[\\/]* | ?:[\\/]*)
ac_cv_path_TRUE="$TRUE" # Let the user override the test with a path.
@@ -2962,15 +2609,11 @@ as_dummy="$PATH:/bin:/usr/bin"
for as_dir in $as_dummy
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
- ac_cv_path_TRUE="$as_dir$ac_word$ac_exec_ext"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_TRUE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -2983,22 +2626,21 @@ esac
fi
TRUE=$ac_cv_path_TRUE
if test -n "$TRUE"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TRUE" >&5
-printf "%s\n" "$TRUE" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TRUE" >&5
+$as_echo "$TRUE" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
# Find compiler, allow alternatives to gcc
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --without-gcc" >&5
-printf %s "checking for --without-gcc... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --without-gcc" >&5
+$as_echo_n "checking for --without-gcc... " >&6; }
# Check whether --with-gcc was given.
-if test ${with_gcc+y}
-then :
+if test "${with_gcc+set}" = set; then :
withval=$with_gcc;
case $withval in
no) CC=cc
@@ -3008,12 +2650,12 @@ then :
*) CC=$withval
without_gcc=$withval;;
esac
-else $as_nop
+else
without_gcc=no;
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $without_gcc" >&5
-printf "%s\n" "$without_gcc" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $without_gcc" >&5
+$as_echo "$without_gcc" >&6; }
# If the user switches compilers, we can't believe the cache
if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
@@ -3022,15 +2664,6 @@ then
(it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5
fi
-
-
-
-
-
-
-
-
-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3039,12 +2672,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
@@ -3052,15 +2684,11 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -3071,11 +2699,11 @@ fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-printf "%s\n" "$CC" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
@@ -3084,12 +2712,11 @@ if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_ac_ct_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
@@ -3097,15 +2724,11 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -3116,11 +2739,11 @@ fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-printf "%s\n" "$ac_ct_CC" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
if test "x$ac_ct_CC" = x; then
@@ -3128,8 +2751,8 @@ fi
else
case $cross_compiling:$ac_tool_warned in
yes:)
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
CC=$ac_ct_CC
@@ -3142,12 +2765,11 @@ if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
@@ -3155,15 +2777,11 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -3174,11 +2792,11 @@ fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-printf "%s\n" "$CC" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
@@ -3187,12 +2805,11 @@ fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
@@ -3201,19 +2818,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
- if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -3229,18 +2842,18 @@ if test $ac_prog_rejected = yes; then
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
- ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-printf "%s\n" "$CC" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
@@ -3251,12 +2864,11 @@ if test -z "$CC"; then
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
@@ -3264,15 +2876,11 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -3283,11 +2891,11 @@ fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-printf "%s\n" "$CC" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
@@ -3300,12 +2908,11 @@ if test -z "$CC"; then
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_ac_ct_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
@@ -3313,15 +2920,11 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
+ test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
@@ -3332,11 +2935,11 @@ fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-printf "%s\n" "$ac_ct_CC" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
@@ -3348,138 +2951,34 @@ done
else
case $cross_compiling:$ac_tool_warned in
yes:)
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
-set dummy ${ac_tool_prefix}clang; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}clang"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-printf "%s\n" "$CC" >&6; }
-else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "clang", so it can be a program name with args.
-set dummy clang; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_ac_ct_CC+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="clang"
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-printf "%s\n" "$ac_ct_CC" >&6; }
-else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
CC=$ac_ct_CC
fi
-else
- CC="$ac_cv_prog_CC"
fi
fi
-test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
-printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
-for ac_option in --version -v -V -qversion -version; do
+for ac_option in --version -v -V -qversion; do
{ { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compiler $ac_option >&5") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
@@ -3489,7 +2988,7 @@ printf "%s\n" "$ac_try_echo"; } >&5
cat conftest.er1 >&5
fi
rm -f conftest.er1 conftest.err
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
done
@@ -3497,7 +2996,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main (void)
+main ()
{
;
@@ -3509,9 +3008,9 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-printf %s "checking whether the C compiler works... " >&6; }
-ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
@@ -3532,12 +3031,11 @@ case "(($ac_try" in
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link_default") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-then :
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
# Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile. We should not override ac_cv_exeext if it was cached,
@@ -3554,7 +3052,7 @@ do
# certainly right.
break;;
*.* )
- if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
then :; else
ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
fi
@@ -3570,46 +3068,44 @@ do
done
test "$ac_cv_exeext" = no && ac_cv_exeext=
-else $as_nop
+else
ac_file=''
fi
-if test -z "$ac_file"
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-printf "%s\n" "$as_me: failed program was:" >&5
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
See \`config.log' for more details" "$LINENO" 5; }
-else $as_nop
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; }
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-printf %s "checking for C compiler default output file name... " >&6; }
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-printf "%s\n" "$ac_file" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext
rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-printf %s "checking for suffix of executables... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-then :
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
# If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -3623,15 +3119,15 @@ for ac_file in conftest.exe conftest conftest.*; do
* ) break;;
esac
done
-else $as_nop
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-printf "%s\n" "$ac_cv_exeext" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
@@ -3640,7 +3136,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
int
-main (void)
+main ()
{
FILE *f = fopen ("conftest.out", "w");
return ferror (f) || fclose (f) != 0;
@@ -3652,8 +3148,8 @@ _ACEOF
ac_clean_files="$ac_clean_files conftest.out"
# Check that the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-printf %s "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
if test "$cross_compiling" != yes; then
{ { ac_try="$ac_link"
case "(($ac_try" in
@@ -3661,10 +3157,10 @@ case "(($ac_try" in
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
if { ac_try='./conftest$ac_cv_exeext'
{ { case "(($ac_try" in
@@ -3672,40 +3168,39 @@ printf "%s\n" "$ac_try_echo"; } >&5
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_try") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then
cross_compiling=no
else
if test "$cross_compiling" = maybe; then
cross_compiling=yes
else
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot run C compiled programs.
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-printf "%s\n" "$cross_compiling" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-printf %s "checking for suffix of object files... " >&6; }
-if test ${ac_cv_objext+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main (void)
+main ()
{
;
@@ -3719,12 +3214,11 @@ case "(($ac_try" in
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-printf "%s\n" "$ac_try_echo"; } >&5
+$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>&5
ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-then :
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
for ac_file in conftest.o conftest.obj conftest.*; do
test -f "$ac_file" || continue;
case $ac_file in
@@ -3733,32 +3227,31 @@ then :
break;;
esac
done
-else $as_nop
- printf "%s\n" "$as_me: failed program was:" >&5
+else
+ $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-printf "%s\n" "$ac_cv_objext" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
-printf %s "checking whether the compiler supports GNU C... " >&6; }
-if test ${ac_cv_c_compiler_gnu+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main (void)
+main ()
{
#ifndef __GNUC__
choke me
@@ -3768,33 +3261,29 @@ main (void)
return 0;
}
_ACEOF
-if ac_fn_c_try_compile "$LINENO"
-then :
+if ac_fn_c_try_compile "$LINENO"; then :
ac_compiler_gnu=yes
-else $as_nop
+else
ac_compiler_gnu=no
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
if test $ac_compiler_gnu = yes; then
GCC=yes
else
GCC=
fi
-ac_test_CFLAGS=${CFLAGS+y}
+ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-printf %s "checking whether $CC accepts -g... " >&6; }
-if test ${ac_cv_prog_cc_g+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
ac_save_c_werror_flag=$ac_c_werror_flag
ac_c_werror_flag=yes
ac_cv_prog_cc_g=no
@@ -3803,60 +3292,57 @@ else $as_nop
/* end confdefs.h. */
int
-main (void)
+main ()
{
;
return 0;
}
_ACEOF
-if ac_fn_c_try_compile "$LINENO"
-then :
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_g=yes
-else $as_nop
+else
CFLAGS=""
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main (void)
+main ()
{
;
return 0;
}
_ACEOF
-if ac_fn_c_try_compile "$LINENO"
-then :
+if ac_fn_c_try_compile "$LINENO"; then :
-else $as_nop
+else
ac_c_werror_flag=$ac_save_c_werror_flag
CFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
-main (void)
+main ()
{
;
return 0;
}
_ACEOF
-if ac_fn_c_try_compile "$LINENO"
-then :
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_g=yes
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_c_werror_flag=$ac_save_c_werror_flag
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
-if test $ac_test_CFLAGS; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
@@ -3871,144 +3357,94 @@ else
CFLAGS=
fi
fi
-ac_prog_cc_stdc=no
-if test x$ac_prog_cc_stdc = xno
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
-printf %s "checking for $CC option to enable C11 features... " >&6; }
-if test ${ac_cv_prog_cc_c11+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_cv_prog_cc_c11=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$ac_c_conftest_c11_program
-_ACEOF
-for ac_arg in '' -std=gnu11
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"
-then :
- ac_cv_prog_cc_c11=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam
- test "x$ac_cv_prog_cc_c11" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-fi
+#include
+#include
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
-if test "x$ac_cv_prog_cc_c11" = xno
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-printf "%s\n" "unsupported" >&6; }
-else $as_nop
- if test "x$ac_cv_prog_cc_c11" = x
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-printf "%s\n" "none needed" >&6; }
-else $as_nop
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
-printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
- CC="$CC $ac_cv_prog_cc_c11"
-fi
- ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
- ac_prog_cc_stdc=c11
-fi
-fi
-if test x$ac_prog_cc_stdc = xno
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
-printf %s "checking for $CC option to enable C99 features... " >&6; }
-if test ${ac_cv_prog_cc_c99+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_cv_prog_cc_c99=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_c_conftest_c99_program
-_ACEOF
-for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"
-then :
- ac_cv_prog_cc_c99=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam
- test "x$ac_cv_prog_cc_c99" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-fi
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-if test "x$ac_cv_prog_cc_c99" = xno
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-printf "%s\n" "unsupported" >&6; }
-else $as_nop
- if test "x$ac_cv_prog_cc_c99" = x
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-printf "%s\n" "none needed" >&6; }
-else $as_nop
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
-printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
- CC="$CC $ac_cv_prog_cc_c99"
-fi
- ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
- ac_prog_cc_stdc=c99
-fi
-fi
-if test x$ac_prog_cc_stdc = xno
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
-printf %s "checking for $CC option to enable C89 features... " >&6; }
-if test ${ac_cv_prog_cc_c89+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_c_conftest_c89_program
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"
-then :
+ if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_c89=$ac_arg
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam
+rm -f core conftest.err conftest.$ac_objext
test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC
-fi
-if test "x$ac_cv_prog_cc_c89" = xno
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-printf "%s\n" "unsupported" >&6; }
-else $as_nop
- if test "x$ac_cv_prog_cc_c89" = x
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-printf "%s\n" "none needed" >&6; }
-else $as_nop
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
- CC="$CC $ac_cv_prog_cc_c89"
-fi
- ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
- ac_prog_cc_stdc=c89
fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
fi
ac_ext=c
@@ -4035,12 +3471,11 @@ then
fi
# We better be able to execute interpreters
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether #! works in shell scripts" >&5
-printf %s "checking whether #! works in shell scripts... " >&6; }
-if test ${ac_cv_sys_interpreter+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether #! works in shell scripts" >&5
+$as_echo_n "checking whether #! works in shell scripts... " >&6; }
+if ${ac_cv_sys_interpreter+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
echo '#! /bin/cat
exit 69
' >conftest
@@ -4053,8 +3488,8 @@ else
fi
rm -f conftest
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_interpreter" >&5
-printf "%s\n" "$ac_cv_sys_interpreter" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_interpreter" >&5
+$as_echo "$ac_cv_sys_interpreter" >&6; }
interpval=$ac_cv_sys_interpreter
if test "$ac_cv_sys_interpreter" != "yes"
@@ -4069,12 +3504,11 @@ fi
# Check for an alternate data directory, separate from installation dir.
default_var_prefix="/var/mailman"
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-var-prefix" >&5
-printf %s "checking for --with-var-prefix... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-var-prefix" >&5
+$as_echo_n "checking for --with-var-prefix... " >&6; }
# Check whether --with-var-prefix was given.
-if test ${with_var_prefix+y}
-then :
+if test "${with_var_prefix+set}" = set; then :
withval=$with_var_prefix;
fi
@@ -4083,15 +3517,14 @@ case "$with_var_prefix" in
""|no) VAR_PREFIX="$prefix"; ans="no";;
*) VAR_PREFIX="$with_var_prefix"; ans=$VAR_PREFIX;
esac
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ans" >&5
-printf "%s\n" "$ans" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ans" >&5
+$as_echo "$ans" >&6; }
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-permcheck" >&5
-printf %s "checking for --with-permcheck... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-permcheck" >&5
+$as_echo_n "checking for --with-permcheck... " >&6; }
# Check whether --with-permcheck was given.
-if test ${with_permcheck+y}
-then :
+if test "${with_permcheck+set}" = set; then :
withval=$with_permcheck;
fi
@@ -4099,8 +3532,8 @@ if test -z "$with_permcheck"
then
with_permcheck="yes"
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_permcheck" >&5
-printf "%s\n" "$with_permcheck" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_permcheck" >&5
+$as_echo "$with_permcheck" >&6; }
# Now make sure that $prefix is set up correctly. It must be group
# owned by the target group, it must have the group sticky bit set, and
# it must be a+rx
@@ -4120,12 +3553,11 @@ fi
# Check for some other uid to use than `mailman'
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-username" >&5
-printf %s "checking for --with-username... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-username" >&5
+$as_echo_n "checking for --with-username... " >&6; }
# Check whether --with-username was given.
-if test ${with_username+y}
-then :
+if test "${with_username+set}" = set; then :
withval=$with_username;
fi
@@ -4135,13 +3567,13 @@ then
with_username="mailman"
fi
USERNAME=$with_username
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USERNAME" >&5
-printf "%s\n" "$USERNAME" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $USERNAME" >&5
+$as_echo "$USERNAME" >&6; }
# User `mailman' must exist
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for user name \"$USERNAME\"" >&5
-printf %s "checking for user name \"$USERNAME\"... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for user name \"$USERNAME\"" >&5
+$as_echo_n "checking for user name \"$USERNAME\"... " >&6; }
# MAILMAN_USER == variable name
# $USERNAME == user id to check for
@@ -4182,17 +3614,16 @@ then
***** file for details." "$LINENO" 5
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: okay" >&5
-printf "%s\n" "okay" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5
+$as_echo "okay" >&6; }
# Check for some other gid to use than `mailman'
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-groupname" >&5
-printf %s "checking for --with-groupname... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-groupname" >&5
+$as_echo_n "checking for --with-groupname... " >&6; }
# Check whether --with-groupname was given.
-if test ${with_groupname+y}
-then :
+if test "${with_groupname+set}" = set; then :
withval=$with_groupname;
fi
@@ -4202,14 +3633,14 @@ then
with_groupname="mailman"
fi
GROUPNAME=$with_groupname
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GROUPNAME" >&5
-printf "%s\n" "$GROUPNAME" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $GROUPNAME" >&5
+$as_echo "$GROUPNAME" >&6; }
# Target group must exist
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for group name \"$GROUPNAME\"" >&5
-printf %s "checking for group name \"$GROUPNAME\"... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for group name \"$GROUPNAME\"" >&5
+$as_echo_n "checking for group name \"$GROUPNAME\"... " >&6; }
# MAILMAN_GROUP == variable name
# $GROUPNAME == user id to check for
@@ -4250,12 +3681,12 @@ then
***** file for details." "$LINENO" 5
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: okay" >&5
-printf "%s\n" "okay" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5
+$as_echo "okay" >&6; }
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking permissions on $prefixcheck" >&5
-printf %s "checking permissions on $prefixcheck... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking permissions on $prefixcheck" >&5
+$as_echo_n "checking permissions on $prefixcheck... " >&6; }
cat > conftest.py <&5
-printf "%s\n" "$status" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $status" >&5
+$as_echo "$status" >&6; }
# Now find the UIDs and GIDs
# Support --with-mail-gid and --with-cgi-gid
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mail wrapper group; i.e. --with-mail-gid" >&5
-printf %s "checking for mail wrapper group; i.e. --with-mail-gid... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mail wrapper group; i.e. --with-mail-gid" >&5
+$as_echo_n "checking for mail wrapper group; i.e. --with-mail-gid... " >&6; }
# Check whether --with-mail-gid was given.
-if test ${with_mail_gid+y}
-then :
+if test "${with_mail_gid+set}" = set; then :
withval=$with_mail_gid;
fi
@@ -4368,16 +3798,15 @@ then
MAIL_GROUP=$with_mail_gid
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAIL_GROUP" >&5
-printf "%s\n" "$MAIL_GROUP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAIL_GROUP" >&5
+$as_echo "$MAIL_GROUP" >&6; }
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CGI wrapper group; i.e. --with-cgi-gid" >&5
-printf %s "checking for CGI wrapper group; i.e. --with-cgi-gid... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CGI wrapper group; i.e. --with-cgi-gid" >&5
+$as_echo_n "checking for CGI wrapper group; i.e. --with-cgi-gid... " >&6; }
# Check whether --with-cgi-gid was given.
-if test ${with_cgi_gid+y}
-then :
+if test "${with_cgi_gid+set}" = set; then :
withval=$with_cgi_gid;
fi
@@ -4430,18 +3859,17 @@ then
CGI_GROUP=$with_cgi_gid
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CGI_GROUP" >&5
-printf "%s\n" "$CGI_GROUP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CGI_GROUP" >&5
+$as_echo "$CGI_GROUP" >&6; }
# Check for CGI extensions, required by some Web servers
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CGI extensions" >&5
-printf %s "checking for CGI extensions... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CGI extensions" >&5
+$as_echo_n "checking for CGI extensions... " >&6; }
# Check whether --with-cgi-ext was given.
-if test ${with_cgi_ext+y}
-then :
+if test "${with_cgi_ext+set}" = set; then :
withval=$with_cgi_ext;
fi
@@ -4452,18 +3880,17 @@ then
else
CGIEXT=$with_cgi_ext
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_cgi_ext" >&5
-printf "%s\n" "$with_cgi_ext" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_cgi_ext" >&5
+$as_echo "$with_cgi_ext" >&6; }
# figure out the default mail hostname and url host component
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-mailhost" >&5
-printf %s "checking for --with-mailhost... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-mailhost" >&5
+$as_echo_n "checking for --with-mailhost... " >&6; }
# Check whether --with-mailhost was given.
-if test ${with_mailhost+y}
-then :
+if test "${with_mailhost+set}" = set; then :
withval=$with_mailhost;
fi
@@ -4474,16 +3901,15 @@ then
else
MAILHOST=$with_mailhost
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_mailhost" >&5
-printf "%s\n" "$with_mailhost" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_mailhost" >&5
+$as_echo "$with_mailhost" >&6; }
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-urlhost" >&5
-printf %s "checking for --with-urlhost... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-urlhost" >&5
+$as_echo_n "checking for --with-urlhost... " >&6; }
# Check whether --with-urlhost was given.
-if test ${with_urlhost+y}
-then :
+if test "${with_urlhost+set}" = set; then :
withval=$with_urlhost;
fi
@@ -4494,8 +3920,8 @@ then
else
URLHOST=$with_urlhost
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_urlhost" >&5
-printf "%s\n" "$with_urlhost" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_urlhost" >&5
+$as_echo "$with_urlhost" >&6; }
@@ -4510,121 +3936,220 @@ fp.close()
EOF
$PYTHON conftest.py
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for default mail host name" >&5
-printf %s "checking for default mail host name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default mail host name" >&5
+$as_echo_n "checking for default mail host name... " >&6; }
if test -z "$MAILHOST"
then
MAILHOST=`sed q conftest.out`
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAILHOST" >&5
-printf "%s\n" "$MAILHOST" >&6; }
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for default URL host component" >&5
-printf %s "checking for default URL host component... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAILHOST" >&5
+$as_echo "$MAILHOST" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default URL host component" >&5
+$as_echo_n "checking for default URL host component... " >&6; }
if test -z "$URLHOST"
then
URLHOST=`sed -n '$p' conftest.out`
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $URLHOST" >&5
-printf "%s\n" "$URLHOST" >&6; }
-rm -f conftest.out conftest.py
-
-# Checks for libraries.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $URLHOST" >&5
+$as_echo "$URLHOST" >&6; }
+rm -f conftest.out conftest.py
+
+# Checks for libraries.
+
+for ac_func in strerror setregid syslog
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test $ac_cv_func_syslog = no; then
+ # syslog is not in the default libraries. See if it's in some other.
+ # Additionally, for at least SCO OpenServer, syslog() is #defined to
+ # one of several _real_ functions in syslog.h, so we need to do the test
+ # with the appropriate include.
+ for lib in bsd socket inet; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslog in -l$lib" >&5
+$as_echo_n "checking for syslog in -l$lib... " >&6; }
+ Mailman_LIBS_save="$LIBS"; LIBS="$LIBS -l$lib"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include
+int
+main ()
+{
+syslog(LOG_DEBUG, "Just a test...");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ $as_echo "#define HAVE_SYSLOG 1" >>confdefs.h
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ LIBS="$Mailman_LIBS_save"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ unset Mailman_LIBS_save
+ done
+fi
+
+# Checks for header files.
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer to if __STDC__ is defined, since
+ # exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include
+#else
+# include
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
-ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
-if test "x$ac_cv_func_strerror" = xyes
-then :
- printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h
+ done
+ ac_cv_prog_CPP=$CPP
fi
-ac_fn_c_check_func "$LINENO" "setregid" "ac_cv_func_setregid"
-if test "x$ac_cv_func_setregid" = xyes
-then :
- printf "%s\n" "#define HAVE_SETREGID 1" >>confdefs.h
-
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
fi
-ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog"
-if test "x$ac_cv_func_syslog" = xyes
-then :
- printf "%s\n" "#define HAVE_SYSLOG 1" >>confdefs.h
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer to if __STDC__ is defined, since
+ # exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include
+#else
+# include
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+else
+ # Broken: fails on valid input.
+continue
fi
+rm -f conftest.err conftest.i conftest.$ac_ext
-if test $ac_cv_func_syslog = no; then
- # syslog is not in the default libraries. See if it's in some other.
- # Additionally, for at least SCO OpenServer, syslog() is #defined to
- # one of several _real_ functions in syslog.h, so we need to do the test
- # with the appropriate include.
- for lib in bsd socket inet; do
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for syslog in -l$lib" >&5
-printf %s "checking for syslog in -l$lib... " >&6; }
- Mailman_LIBS_save="$LIBS"; LIBS="$LIBS -l$lib"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include
-int
-main (void)
-{
-syslog(LOG_DEBUG, "Just a test...");
- ;
- return 0;
-}
+#include
_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; }
- printf "%s\n" "#define HAVE_SYSLOG 1" >>confdefs.h
-
- break
-else $as_nop
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
- LIBS="$Mailman_LIBS_save"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
- unset Mailman_LIBS_save
- done
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
fi
+rm -f conftest.err conftest.i conftest.$ac_ext
-# Checks for header files.
-# Autoupdate added the next two lines to ensure that your configure
-# script's behavior did not change. They are probably safe to remove.
-ac_header= ac_cache=
-for ac_item in $ac_header_c_list
-do
- if test $ac_cache; then
- ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
- if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
- printf "%s\n" "#define $ac_item 1" >> confdefs.h
- fi
- ac_header= ac_cache=
- elif test $ac_header; then
- ac_cache=$ac_item
- else
- ac_header=$ac_item
- fi
done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
-then :
-
-printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-printf %s "checking for grep that handles long lines and -e... " >&6; }
-if test ${ac_cv_path_GREP+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if test -z "$GREP"; then
ac_path_GREP_found=false
# Loop through the user's path and test for each of PROGNAME-LIST
@@ -4632,15 +4157,10 @@ else $as_nop
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- for ac_prog in grep ggrep
- do
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
@@ -4649,13 +4169,13 @@ case `"$ac_path_GREP" --version 2>&1` in
ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
ac_count=0
- printf %s 0123456789 >"conftest.in"
+ $as_echo_n 0123456789 >"conftest.in"
while :
do
cat "conftest.in" "conftest.in" >"conftest.tmp"
mv "conftest.tmp" "conftest.in"
cp "conftest.in" "conftest.nl"
- printf "%s\n" 'GREP' >> "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
"$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
as_fn_arith $ac_count + 1 && ac_count=$as_val
@@ -4683,17 +4203,16 @@ else
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-printf "%s\n" "$ac_cv_path_GREP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
GREP="$ac_cv_path_GREP"
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-printf %s "checking for egrep... " >&6; }
-if test ${ac_cv_path_EGREP+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
then ac_cv_path_EGREP="$GREP -E"
else
@@ -4704,15 +4223,10 @@ else $as_nop
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- for ac_prog in egrep
- do
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
@@ -4721,13 +4235,13 @@ case `"$ac_path_EGREP" --version 2>&1` in
ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
ac_count=0
- printf %s 0123456789 >"conftest.in"
+ $as_echo_n 0123456789 >"conftest.in"
while :
do
cat "conftest.in" "conftest.in" >"conftest.tmp"
mv "conftest.tmp" "conftest.in"
cp "conftest.in" "conftest.nl"
- printf "%s\n" 'EGREP' >> "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
"$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
as_fn_arith $ac_count + 1 && ac_count=$as_val
@@ -4756,196 +4270,192 @@ fi
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-printf "%s\n" "$ac_cv_path_EGREP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
EGREP="$ac_cv_path_EGREP"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include
+#include
+#include
+#include
-ac_fn_c_check_header_compile "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default"
-if test "x$ac_cv_header_syslog_h" = xyes
-then :
- printf "%s\n" "#define HAVE_SYSLOG_H 1" >>confdefs.h
+int
+main ()
+{
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-# Checks for typedefs, structures, and compiler characteristics.
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-printf %s "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test ${ac_cv_prog_CPP+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- # Double quotes because $CC needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include
- Syntax error
+#include
+
_ACEOF
-if ac_fn_c_try_cpp "$LINENO"
-then :
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
-else $as_nop
- # Broken: fails on valid input.
-continue
+else
+ ac_cv_header_stdc=no
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest*
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include
+#include
+
_ACEOF
-if ac_fn_c_try_cpp "$LINENO"
-then :
- # Broken: success on invalid input.
-continue
-else $as_nop
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok
-then :
- break
+else
+ ac_cv_header_stdc=no
fi
-
- done
- ac_cv_prog_CPP=$CPP
+rm -f conftest*
fi
- CPP=$ac_cv_prog_CPP
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
else
- ac_cv_prog_CPP=$CPP
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-printf "%s\n" "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include
- Syntax error
+#include
+#include
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
_ACEOF
-if ac_fn_c_try_cpp "$LINENO"
-then :
+if ac_fn_c_try_run "$LINENO"; then :
-else $as_nop
- # Broken: fails on valid input.
-continue
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
-if ac_fn_c_try_cpp "$LINENO"
-then :
- # Broken: success on invalid input.
-continue
-else $as_nop
- # Passes both tests.
-ac_preproc_ok=:
-break
+
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok
-then :
-else $as_nop
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+
+for ac_header in syslog.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default"
+if test "x$ac_cv_header_syslog_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYSLOG_H 1
+_ACEOF
+
fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+done
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
-printf %s "checking for uid_t in sys/types.h... " >&6; }
-if test ${ac_cv_type_uid_t+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if ${ac_cv_type_uid_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "uid_t" >/dev/null 2>&1
-then :
+ $EGREP "uid_t" >/dev/null 2>&1; then :
ac_cv_type_uid_t=yes
-else $as_nop
+else
ac_cv_type_uid_t=no
fi
-rm -rf conftest*
+rm -f conftest*
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
-printf "%s\n" "$ac_cv_type_uid_t" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
if test $ac_cv_type_uid_t = no; then
-printf "%s\n" "#define uid_t int" >>confdefs.h
+$as_echo "#define uid_t int" >>confdefs.h
-printf "%s\n" "#define gid_t int" >>confdefs.h
+$as_echo "#define gid_t int" >>confdefs.h
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5
-printf %s "checking type of array argument to getgroups... " >&6; }
-if test ${ac_cv_type_getgroups+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- if test "$cross_compiling" = yes
-then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5
+$as_echo_n "checking type of array argument to getgroups... " >&6; }
+if ${ac_cv_type_getgroups+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
ac_cv_type_getgroups=cross
-else $as_nop
+else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Thanks to Mike Rendell for this test. */
@@ -4955,7 +4465,7 @@ $ac_includes_default
#define MAX(x, y) ((x) > (y) ? (x) : (y))
int
-main (void)
+main ()
{
gid_t gidset[NGID];
int i, n;
@@ -4972,10 +4482,9 @@ main (void)
return n > 0 && gidset[n] != val.gval;
}
_ACEOF
-if ac_fn_c_try_run "$LINENO"
-then :
+if ac_fn_c_try_run "$LINENO"; then :
ac_cv_type_getgroups=gid_t
-else $as_nop
+else
ac_cv_type_getgroups=int
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -4989,30 +4498,35 @@ if test $ac_cv_type_getgroups = cross; then
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1
-then :
+ $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then :
ac_cv_type_getgroups=gid_t
-else $as_nop
+else
ac_cv_type_getgroups=int
fi
-rm -rf conftest*
+rm -f conftest*
fi
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5
-printf "%s\n" "$ac_cv_type_getgroups" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5
+$as_echo "$ac_cv_type_getgroups" >&6; }
-printf "%s\n" "#define GETGROUPS_T $ac_cv_type_getgroups" >>confdefs.h
+cat >>confdefs.h <<_ACEOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+_ACEOF
# Checks for library functions.
-ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
-if test "x$ac_cv_func_vsnprintf" = xyes
-then :
- printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h
+for ac_func in vsnprintf
+do :
+ ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
+if test "x$ac_cv_func_vsnprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VSNPRINTF 1
+_ACEOF
fi
+done
@@ -5111,8 +4625,8 @@ _ACEOF
case $ac_val in #(
*${as_nl}*)
case $ac_var in #(
- *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
esac
case $ac_var in #(
_ | IFS | as_nl) ;; #(
@@ -5142,15 +4656,15 @@ printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;}
/^ac_cv_env_/b end
t clear
:clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
t end
s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
:end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
if test -w "$cache_file"; then
if test "x$cache_file" != "x/dev/null"; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
if test ! -f "$cache_file" || test -h "$cache_file"; then
cat confcache >"$cache_file"
else
@@ -5164,8 +4678,8 @@ printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
fi
fi
else
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
fi
fi
rm -f confcache
@@ -5218,7 +4732,7 @@ U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
# 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
# will be set to the directory where LIBOBJS objects are built.
as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
@@ -5234,8 +4748,8 @@ LTLIBOBJS=$ac_ltlibobjs
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
@@ -5258,16 +4772,14 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
-as_nop=:
-if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
-then :
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
-else $as_nop
+else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
@@ -5277,46 +4789,46 @@ esac
fi
-
-# Reset variables that may have inherited troublesome values from
-# the environment.
-
-# IFS needs to be set, to space, tab, and newline, in precisely that order.
-# (If _AS_PATH_WALK were called with IFS unset, it would have the
-# side effect of setting IFS to empty, thus disabling word splitting.)
-# Quoting is to prevent editors from complaining about space-tab.
as_nl='
'
export as_nl
-IFS=" "" $as_nl"
-
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# Ensure predictable behavior from utilities with locale-dependent output.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# We cannot yet rely on "unset" to work, but we need these variables
-# to be unset--not just set to an empty or harmless value--now, to
-# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
-# also avoids known problems related to "unset" and subshell syntax
-# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
-for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
-do eval test \${$as_var+y} \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-
-# Ensure that fds 0, 1, and 2 are open.
-if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
-if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
# The user is always right.
-if ${PATH_SEPARATOR+false} :; then
+if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -5325,6 +4837,13 @@ if ${PATH_SEPARATOR+false} :; then
fi
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
@@ -5333,12 +4852,8 @@ case $0 in #((
for as_dir in $PATH
do
IFS=$as_save_IFS
- case $as_dir in #(((
- '') as_dir=./ ;;
- */) ;;
- *) as_dir=$as_dir/ ;;
- esac
- test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
@@ -5350,10 +4865,30 @@ if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
- printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# as_fn_error STATUS ERROR [LINENO LOG_FD]
@@ -5366,14 +4901,13 @@ as_fn_error ()
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
- printf "%s\n" "$as_me: error: $2" >&2
+ $as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
-
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
@@ -5400,20 +4934,18 @@ as_fn_unset ()
{ eval $1=; unset $1;}
}
as_unset=as_fn_unset
-
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
-then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
-else $as_nop
+else
as_fn_append ()
{
eval $1=\$$1\$2
@@ -5425,13 +4957,12 @@ fi # as_fn_append
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
-then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
-else $as_nop
+else
as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
@@ -5462,7 +4993,7 @@ as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-printf "%s\n" X/"$0" |
+$as_echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
@@ -5484,10 +5015,6 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# Determine whether it's possible to make 'echo' print without a newline.
-# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
-# for compatibility with existing Makefiles.
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
@@ -5501,12 +5028,6 @@ case `echo -n x` in #(((((
ECHO_N='-n';;
esac
-# For backward compatibility with old third-party macros, we provide
-# the shell variables $as_echo and $as_echo_n. New code should use
-# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
-as_echo='printf %s\n'
-as_echo_n='printf %s'
-
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
@@ -5548,7 +5069,7 @@ as_fn_mkdir_p ()
as_dirs=
while :; do
case $as_dir in #(
- *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
@@ -5557,7 +5078,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-printf "%s\n" X"$as_dir" |
+$as_echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -5620,7 +5141,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# values after options handling.
ac_log="
This file was extended by $as_me, which was
-generated by GNU Autoconf 2.71. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -5673,16 +5194,14 @@ $config_commands
Report bugs to the package provider."
_ACEOF
-ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
-ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config='$ac_cs_config_escaped'
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
config.status
-configured by $0, generated by GNU Autoconf 2.71,
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2021 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -5720,21 +5239,21 @@ do
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
--version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- printf "%s\n" "$ac_cs_version"; exit ;;
+ $as_echo "$ac_cs_version"; exit ;;
--config | --confi | --conf | --con | --co | --c )
- printf "%s\n" "$ac_cs_config"; exit ;;
+ $as_echo "$ac_cs_config"; exit ;;
--debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
case $ac_optarg in
- *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
'') as_fn_error $? "missing file argument" ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
--he | --h | --help | --hel | -h )
- printf "%s\n" "$ac_cs_usage"; exit ;;
+ $as_echo "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
@@ -5762,7 +5281,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
- \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
export CONFIG_SHELL
exec "\$@"
@@ -5776,7 +5295,7 @@ exec 5>>config.log
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
- printf "%s\n" "$ac_log"
+ $as_echo "$ac_log"
} >&5
_ACEOF
@@ -5828,8 +5347,8 @@ done
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
- test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
- test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
fi
# Have a temporary directory for convenience. Make it in the build tree
@@ -6057,7 +5576,7 @@ do
esac ||
as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
- case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
done
@@ -6065,17 +5584,17 @@ do
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
configure_input='Generated from '`
- printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
`' by configure.'
if test x"$ac_file" != x-; then
configure_input="$ac_file. $configure_input"
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-printf "%s\n" "$as_me: creating $ac_file" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
fi
# Neutralize special characters interpreted by sed in replacement strings.
case $configure_input in #(
*\&* | *\|* | *\\* )
- ac_sed_conf_input=`printf "%s\n" "$configure_input" |
+ ac_sed_conf_input=`$as_echo "$configure_input" |
sed 's/[\\\\&|]/\\\\&/g'`;; #(
*) ac_sed_conf_input=$configure_input;;
esac
@@ -6092,7 +5611,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-printf "%s\n" X"$ac_file" |
+$as_echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@@ -6116,9 +5635,9 @@ printf "%s\n" X"$ac_file" |
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
- ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -6175,8 +5694,8 @@ ac_sed_dataroot='
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_datarootdir_hack='
@@ -6219,9 +5738,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
"$ac_tmp/out"`; test -z "$ac_out"; } &&
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&5
-printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&2;}
rm -f "$ac_tmp/stdin"
@@ -6233,8 +5752,8 @@ which seems to be undefined. Please make sure it is defined" >&2;}
;;
- :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
;;
esac
@@ -6275,8 +5794,8 @@ if test "$no_create" != yes; then
$ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
@@ -6285,4 +5804,3 @@ chmod -R +x build
# Test for the Chinese codecs.
-
diff --git a/configure.in b/configure.ac
similarity index 86%
rename from configure.in
rename to configure.ac
index a39bef13..80c303d8 100644
--- a/configure.in
+++ b/configure.ac
@@ -16,10 +16,15 @@
dnl Process this file with autoconf to produce a configure script.
AC_REVISION($Revision: 8122 $)
-AC_PREREQ([2.71])
+AC_PREREQ([2.69])
AC_INIT
AC_CONFIG_SRCDIR([src/common.h])
+# Store the configure command and arguments for reconfigure target
+CONFIGURE_CMD=`echo "$0"`
+CONFIGURE_ARGS=`echo "$*"`
+AC_SUBST(CONFIGURE_CMD)
+AC_SUBST(CONFIGURE_ARGS)
# /usr/local/mailman is the default installation directory
AC_PREFIX_DEFAULT(/usr/local/mailman)
@@ -44,18 +49,46 @@ then
AC_PATH_PROG(with_python, python3, /usr/local/bin/python3)
fi
+# Set PYTHON variable for Makefile substitution
+PYTHON=$with_python
+AC_SUBST(PYTHON)
+
AC_MSG_CHECKING(Python interpreter)
if test ! -x $with_python
then
AC_MSG_ERROR([
-
-***** No Python interpreter found!
-***** Try including the configure option
-***** --with-python=/path/to/python/interpreter])
+ Python interpreter not found at $with_python
+ Please specify the correct path to Python using --with-python
+ ])
fi
-AC_SUBST(PYTHON)
-PYTHON=$with_python
-AC_MSG_RESULT($PYTHON)
+AC_MSG_RESULT($with_python)
+
+# Check for optional nntplib module
+AC_MSG_CHECKING(whether to enable NNTP support)
+AC_ARG_ENABLE(nntp,
+ [ --enable-nntp enable NNTP support (requires python3-nntplib)],
+ [enable_nntp=$enableval],
+ [enable_nntp=no]
+)
+AC_MSG_RESULT($enable_nntp)
+
+if test "$enable_nntp" = "yes"; then
+ AC_MSG_CHECKING(for Python nntplib module)
+ $with_python -c "import nntplib" >/dev/null 2>&1
+ if test $? -ne 0
+ then
+ AC_MSG_ERROR([
+ Python nntplib module not found but NNTP support was requested
+ Please install python3-nntplib package
+ On Debian/Ubuntu: apt-get install python3-nntplib
+ On RHEL/CentOS: yum install python3-nntplib
+ Or disable NNTP support with --disable-nntp
+ ])
+ fi
+ AC_MSG_RESULT(found)
+ AC_DEFINE(HAVE_NNTP, 1, [Define if NNTP support is enabled])
+fi
+AM_CONDITIONAL([HAVE_NNTP], [test "$enable_nntp" = "yes"])
# See if Python is new enough.
AC_MSG_CHECKING(Python version)
@@ -66,24 +99,23 @@ try:
v = sys.hexversion
except AttributeError:
v = 0
-if v >= 0x2040000:
+if v >= 0x3000000:
s = sys.version.split()[0]
else:
s = ""
-fp = open("conftest.out", "w")
-fp.write("%s\n" % s)
-fp.close()
+with open("conftest.out", "w") as fp:
+ fp.write("%s\n" % s)
EOF
changequote([, ])
-$PYTHON conftest.py
+$with_python conftest.py
version=`cat conftest.out`
rm -f conftest.out conftest.py
if test -z "$version"
then
AC_MSG_ERROR([
-***** $PYTHON is too old (or broken)
-***** Python 2.4 or newer is required])
+***** $with_python is too old (or broken)
+***** Python 3.0 or newer is required])
fi
AC_MSG_RESULT($version)
@@ -96,12 +128,11 @@ try:
res = 'ok'
except ImportError:
res = 'no'
-fp = open("conftest.out", "w")
-fp.write("%s\n" % res)
-fp.close()
+with open("conftest.out", "w") as fp:
+ fp.write("%s\n" % res)
EOF
changequote([, ])
-$PYTHON conftest.py
+$with_python conftest.py
havednspython=`cat conftest.out`
rm -f conftest.out conftest.py
if test "$havednspython" = "no"
@@ -127,22 +158,20 @@ except ImportError:
res = "not ok"
else:
res = "ok"
-fp = open("conftest.out", "w")
-fp.write("%s\n" % res)
-fp.close()
+with open("conftest.out", "w") as fp:
+ fp.write("%s\n" % res)
EOF
changequote([, ])
-$PYTHON conftest.py
+$with_python conftest.py
needemailpkg=`cat conftest.out`
rm -f conftest.out conftest.py
cat > getver.py < conftest.py < conftest.py < conftest.py <> fd, _(__doc__)
+ print(_(__doc__), file=fd)
if msg:
- print >> fd, msg
+ print(msg, file=fd)
sys.exit(code)
@@ -144,7 +144,7 @@ def pending_requests(mlist):
first = 0
when, addr, fullname, passwd, digest, lang = mlist.GetRecord(id)
if fullname:
- if isinstance(fullname, UnicodeType):
+ if isinstance(fullname, str):
fullname = fullname.encode(lcset, 'replace')
fullname = ' (%s)' % fullname
pending.append(' %s%s %s' % (addr, fullname, time.ctime(when)))
@@ -174,23 +174,21 @@ Cause: %(reason)s"""))
upending = []
charset = Utils.GetCharSet(mlist.preferred_language)
for s in pending:
- if isinstance(s, UnicodeType):
+ if isinstance(s, str):
upending.append(s)
else:
- upending.append(unicode(s, charset, 'replace'))
- # Make sure that the text we return from here can be encoded to a byte
+ upending.append(str(s, charset, 'replace'))
+ # Make sure that the text we return from here can be encoded to a unicode
# string in the charset of the list's language. This could fail if for
# example, the request was pended while the list's language was French,
# but then it was changed to English before checkdbs ran.
text = u'\n'.join(upending)
+ if isinstance(text, str):
+ return text
charset = Charset(Utils.GetCharSet(mlist.preferred_language))
incodec = charset.input_codec or 'ascii'
- outcodec = charset.output_codec or 'ascii'
- if isinstance(text, UnicodeType):
- return text.encode(outcodec, 'replace')
- # Be sure this is a byte string encodeable in the list's charset
- utext = unicode(text, incodec, 'replace')
- return utext.encode(outcodec, 'replace')
+ # Be sure this is a unicode string
+ return str(text, incodec, 'replace')
def auto_discard(mlist):
# Discard old held messages
diff --git a/cron/cull_bad_shunt b/cron/cull_bad_shunt
index 8d47af68..35cebc3d 100755
--- a/cron/cull_bad_shunt
+++ b/cron/cull_bad_shunt
@@ -63,9 +63,9 @@ def usage(code, msg=''):
fd = sys.stderr
else:
fd = sys.stdout
- print >> fd, _(__doc__)
+ print(_(__doc__), file=fd)
if msg:
- print >> fd, msg
+ print(msg, file=fd)
sys.exit(code)
@@ -88,21 +88,19 @@ def main():
return
now = time.time()
old = now - float(mm_cfg.BAD_SHUNT_STALE_AFTER)
- os.stat_float_times(True)
adir = mm_cfg.BAD_SHUNT_ARCHIVE_DIRECTORY
if (adir and os.access(adir, os.W_OK | os.X_OK)
and stat.S_ISDIR(os.stat(adir).st_mode)):
pass
else:
if adir:
- print >>sys.stderr, '%s: archive directory %s not usable.' % (
- PROGRAM, adir)
+ print('%s: archive directory %s not usable.', PROGRAM, adir, file=sys.stderr)
adir = None
for qdir in (mm_cfg.BADQUEUE_DIR, mm_cfg.SHUNTQUEUE_DIR):
try:
names = os.listdir(qdir)
- except OSError, e:
- if e.errno <> errno.ENOENT:
+ except OSError as e:
+ if e.errno != errno.ENOENT:
# OK if qdir doesn't exist, else
raise
continue
diff --git a/cron/disabled b/cron/disabled
index 0f09d74d..a195ab4d 100755
--- a/cron/disabled
+++ b/cron/disabled
@@ -158,7 +158,7 @@ def main():
# from the member.
disables = []
for member in mlist.getBouncingMembers():
- if mlist.getDeliveryStatus(member) <> MemberAdaptor.ENABLED:
+ if mlist.getDeliveryStatus(member) != MemberAdaptor.ENABLED:
continue
info = mlist.getBounceInfo(member)
if (Utils.midnight(info.date) + mlist.bounce_info_stale_after
diff --git a/cron/gate_news b/cron/gate_news
index e0de6193..69667f6d 100755
--- a/cron/gate_news
+++ b/cron/gate_news
@@ -33,7 +33,11 @@ import os
import time
import getopt
import socket
-import nntplib
+try:
+ import nntplib
+ NNTPLIB_AVAILABLE = True
+except ImportError:
+ NNTPLIB_AVAILABLE = False
import paths
# Import this /after/ paths so that the sys.path is properly hacked
@@ -67,7 +71,6 @@ class _ContinueLoop(Exception):
pass
-
def usage(code, msg=''):
if code:
fd = sys.stderr
@@ -79,10 +82,16 @@ def usage(code, msg=''):
sys.exit(code)
-
_hostcache = {}
def open_newsgroup(mlist):
+ # Check if nntplib is available
+ if not NNTPLIB_AVAILABLE:
+ syslog('fromusenet',
+ 'nntplib not available, cannot open newsgroup for list "%s"',
+ mlist.internal_name())
+ raise ImportError("nntplib not available")
+
# Split host:port if given
nntp_host, nntp_port = Utils.nntpsplit(mlist.nntp_host)
# Open up a "mode reader" connection to nntp server. This will be shared
@@ -115,32 +124,79 @@ def clearcache():
_hostcache.clear()
-
+
+
# This function requires the list to be locked.
def poll_newsgroup(mlist, conn, first, last, glock):
listname = mlist.internal_name()
- # NEWNEWS is not portable and has synchronization issues.
+ syslog('fromusenet', 'poll_newsgroup for %d -> %d', first, last)
+
for num in range(first, last):
glock.refresh()
try:
- headers = conn.head(repr(num))[3]
+ # Get the article headers
+ try:
+ result = conn.head(repr(num))
+ syslog('fromusenet', 'head() returned type: %s', type(result).__name__)
+
+ # Extract headers based on the return format
+ headers = None
+
+ if isinstance(result, tuple):
+ if len(result) > 3:
+ # Standard format: (response, number, id, headers)
+ headers = result[3]
+ elif len(result) == 2 and hasattr(result[1], 'lines'):
+ # Format with ArticleInfo object
+ headers = result[1].lines
+ elif len(result) == 2 and isinstance(result[1], list):
+ # Another possible format
+ headers = result[1]
+
+ # If we still don't have headers, try to find them in any element
+ if headers is None:
+ for item in result:
+ if isinstance(item, (list, tuple)) and item:
+ headers = item
+ break
+
+ if headers is None:
+ syslog('fromusenet', 'Could not extract headers from: %s', repr(result))
+ raise _ContinueLoop
+
+ except IndexError:
+ syslog('fromusenet', 'IndexError with result: %s', repr(result))
+ raise _ContinueLoop
+ except Exception as e:
+ syslog('fromusenet', 'Error getting headers for %d: %s', num, str(e))
+ raise _ContinueLoop
+
# I don't know how this happens, but skip an empty message.
if not headers:
+ syslog('fromusenet', 'Empty headers for message %d', num)
raise _ContinueLoop
+
found_to = 0
beenthere = 0
for header in headers:
+ # Make sure the header is a string
+ if not isinstance(header, str) and hasattr(header, 'decode'):
+ header = header.decode('utf-8', errors='replace')
+
i = header.find(':')
+ if i <= 0:
+ continue
+
value = header[:i].lower()
- if i > 0 and value == 'to':
+ if value == 'to':
found_to = 1
if value != 'x-beenthere':
continue
if header[i:] == ': %s' % mlist.GetListEmail():
beenthere = 1
break
+
if not beenthere:
- body = conn.body(repr(num))[3]
# Usenet originated messages will not have a Unix envelope
# (i.e. "From " header). This breaks Pipermail archiving, so
# we will synthesize one. Be sure to use the format searched
@@ -148,12 +204,62 @@ def poll_newsgroup(mlist, conn, first, last, glock):
# the -bounces address here in case any downstream clients use
# the envelope sender for bounces; I'm not sure about this,
# but it's the closest to the old semantics.
+
+ # Get the body of the article
+ try:
+ body_result = conn.body(repr(num))
+
+ # Extract body based on the return format
+ body = None
+
+ if isinstance(body_result, tuple):
+ if len(body_result) > 3:
+ body = body_result[3]
+ elif len(body_result) == 2 and hasattr(body_result[1], 'lines'):
+ body = body_result[1].lines
+ elif len(body_result) == 2 and isinstance(body_result[1], list):
+ body = body_result[1]
+
+ # If we still don't have the body, try to find it in any element
+ if body is None:
+ for item in body_result:
+ if isinstance(item, (list, tuple)) and item:
+ body = item
+ break
+
+ if body is None:
+ syslog('fromusenet', 'Could not extract body from: %s', repr(body_result))
+ raise _ContinueLoop
+
+ except Exception as e:
+ syslog('fromusenet', 'Error getting body for %d: %s', num, str(e))
+ raise _ContinueLoop
+
+ # Convert all headers and body items to strings if they're bytes
+ str_headers = []
+ for header in headers:
+ if not isinstance(header, str) and hasattr(header, 'decode'):
+ str_headers.append(header.decode('utf-8', errors='replace'))
+ else:
+ str_headers.append(str(header))
+
+ str_body = []
+ for line in body:
+ if not isinstance(line, str) and hasattr(line, 'decode'):
+ str_body.append(line.decode('utf-8', errors='replace'))
+ else:
+ str_body.append(str(line))
+
+ # Create the full message
lines = ['From %s %s' % (mlist.GetBouncesEmail(),
- time.ctime(time.time()))]
- lines.extend(headers)
+ time.ctime(time.time()))]
+ lines.extend(str_headers)
+ lines.append('')
+ lines.extend(str_body)
lines.append('')
- lines.extend(body)
lines.append('')
+
+ # Parse the message
p = Parser(Message.Message)
try:
msg = p.parsestr(NL.join(lines))
@@ -162,11 +268,14 @@ def poll_newsgroup(mlist, conn, first, last, glock):
'email package exception for %s:%d\n%s',
mlist.linked_newsgroup, num, e)
raise _ContinueLoop
+
+ # Handle To: header
if found_to:
del msg['X-Originally-To']
msg['X-Originally-To'] = msg['To']
del msg['To']
msg['To'] = mlist.GetListEmail()
+
# Post the message to the locked list
inq = get_switchboard(mm_cfg.INQUEUE_DIR)
inq.enqueue(msg,
@@ -174,12 +283,18 @@ def poll_newsgroup(mlist, conn, first, last, glock):
fromusenet = 1)
syslog('fromusenet',
'posted to list %s: %7d' % (listname, num))
+
except nntplib.NNTPError as e:
syslog('fromusenet',
'NNTP error for list %s: %7d' % (listname, num))
syslog('fromusenet', str(e))
except _ContinueLoop:
continue
+ except Exception as e:
+ syslog('fromusenet',
+ 'Unexpected error processing article %7d: %s', num, str(e))
+ continue
+
# Even if we don't post the message because it was seen on the
# list already, or if we skipped it as unparseable or empty,
# update the watermark. Note this used to be in the 'for' block
@@ -188,7 +303,8 @@ def poll_newsgroup(mlist, conn, first, last, glock):
mlist.usenet_watermark = num
-
+
+
def process_lists(glock):
for listname in Utils.list_names():
glock.refresh()
@@ -252,7 +368,8 @@ def process_lists(glock):
(listname, mlist.usenet_watermark))
-
+
+
def main():
lock = LockFile.LockFile(GATENEWS_LOCK_FILE,
# it's okay to hijack this
@@ -269,7 +386,8 @@ def main():
lock.unlock(unconditionally=1)
-
+
+
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
diff --git a/cron/mailpasswds b/cron/mailpasswds
index 13a7ab07..fdef0494 100755
--- a/cron/mailpasswds
+++ b/cron/mailpasswds
@@ -79,9 +79,9 @@ def usage(code, msg=''):
def tounicode(s, enc):
- if isinstance(s, UnicodeType):
+ if isinstance(s, str):
return s
- return unicode(s, enc, 'replace')
+ return str(s, enc, 'replace')
diff --git a/cron/nightly_gzip b/cron/nightly_gzip
index 25f2c9f9..00717d78 100755
--- a/cron/nightly_gzip
+++ b/cron/nightly_gzip
@@ -81,7 +81,7 @@ def usage(code, msg=''):
def compress(txtfile):
if VERBOSE:
print("gzip'ing:", txtfile)
- infp = open(txtfile)
+ infp = open(txtfile, 'rb')
outfp = gzip.open(txtfile+'.gz', 'wb', 6)
outfp.write(infp.read())
outfp.close()
@@ -127,7 +127,7 @@ def main():
print('Processing list:', name)
files = []
for f in allfiles:
- if f[-4:] <> '.txt':
+ if f[-4:] != '.txt':
continue
# stat both the .txt and .txt.gz files and append them only if
# the former is newer than the latter.
diff --git a/messages/Makefile.in b/messages/Makefile.in
index 8e4395c6..261ece5e 100644
--- a/messages/Makefile.in
+++ b/messages/Makefile.in
@@ -71,9 +71,11 @@ PROG= @PYTHON@ build/bin/pygettext.py
.po.mo:
-$(MSGFMT) -o $@ $<
+.NOTPARALLEL:
+
# Rules
-all: mofiles
+all: convertpofiles mofiles
catalogs: $(TARGETS)
@@ -112,6 +114,9 @@ doinstall: mofiles
$(INSTALL) -m $(FILEMODE) $$mo $$dir; \
done
+convertpofiles: $(wildcard */LC_MESSAGES/*.po)
+ ../scripts/convert_to_utf8 -d .
+
mofiles: $(MOFILES)
finish:
diff --git a/messages/ar/LC_MESSAGES/mailman.po b/messages/ar/LC_MESSAGES/mailman.po
index d388e467..9467c188 100755
--- a/messages/ar/LC_MESSAGES/mailman.po
+++ b/messages/ar/LC_MESSAGES/mailman.po
@@ -69,10 +69,12 @@ msgid "
Currently, there are no archives.
"
msgstr "
حالياً، لا يوجد أي أرشيفات.
"
#: Mailman/Archiver/HyperArch.py:821
+#, fuzzy
msgid "Gzip'd Text%(sz)s"
msgstr "نص مضغوط%(sz)s"
#: Mailman/Archiver/HyperArch.py:826
+#, fuzzy
msgid "Text%(sz)s"
msgstr "نص%(sz)s"
@@ -145,18 +147,22 @@ msgid "Third"
msgstr "ثالت"
#: Mailman/Archiver/HyperArch.py:938
+#, fuzzy
msgid "%(ord)s quarter %(year)i"
msgstr "%(ord)s ربع %(year)i"
#: Mailman/Archiver/HyperArch.py:945
+#, fuzzy
msgid "%(month)s %(year)i"
msgstr "%(month)s %(year)i"
#: Mailman/Archiver/HyperArch.py:950
+#, fuzzy
msgid "The Week Of Monday %(day)i %(month)s %(year)i"
msgstr "أسبوع الإثنين %(day)i %(month)s %(year)i"
#: Mailman/Archiver/HyperArch.py:954
+#, fuzzy
msgid "%(day)i %(month)s %(year)i"
msgstr "%(day)i %(month)s %(year)i"
@@ -165,10 +171,12 @@ msgid "Computing threaded index\n"
msgstr "يتم حساب فهرس النقاشات\n"
#: Mailman/Archiver/HyperArch.py:1319
+#, fuzzy
msgid "Updating HTML for article %(seq)s"
msgstr "تحديث نص HTML للمقالة %(seq)s"
#: Mailman/Archiver/HyperArch.py:1326
+#, fuzzy
msgid "article file %(filename)s is missing!"
msgstr "ملف المقالة %(filename)s مفقود!"
@@ -185,6 +193,7 @@ msgid "Pickling archive state into "
msgstr "كبس حالة الأرشيف في "
#: Mailman/Archiver/pipermail.py:453
+#, fuzzy
msgid "Updating index files for archive [%(archive)s]"
msgstr "تحديث ملفات الفهارس للأرشيف [%(archive)s]"
@@ -193,6 +202,7 @@ msgid " Thread"
msgstr " نقاش"
#: Mailman/Archiver/pipermail.py:597
+#, fuzzy
msgid "#%(counter)05d %(msgid)s"
msgstr "#%(counter)05d %(msgid)s"
@@ -230,6 +240,7 @@ msgid "disabled address"
msgstr "معطل"
#: Mailman/Bouncer.py:304
+#, fuzzy
msgid " The last bounce received from you was dated %(date)s"
msgstr "استقبل رد الرفض الأخير من قبلك بتاريخ %(date)s"
@@ -257,6 +268,7 @@ msgstr "مشرف"
#: Mailman/Cgi/options.py:101 Mailman/Cgi/private.py:108
#: Mailman/Cgi/rmlist.py:75 Mailman/Cgi/roster.py:59
#: Mailman/Cgi/subscribe.py:67
+#, fuzzy
msgid "No such list %(safelistname)s"
msgstr "لا يوجد قائمة بالإسم %(safelistname)s"
@@ -328,6 +340,7 @@ msgstr ""
" سوف يستلم هؤلاء الناس البريد إلى أن تحل المشكلة%(rm)r"
#: Mailman/Cgi/admin.py:268
+#, fuzzy
msgid "%(hostname)s mailing lists - Admin Links"
msgstr "%(hostname)s قوائم بريدية - ارتباطات إشرافية"
@@ -340,6 +353,7 @@ msgid "Mailman"
msgstr "ميلمان"
#: Mailman/Cgi/admin.py:310
+#, fuzzy
msgid ""
"
There currently are no publicly-advertised %(mailmanlink)s\n"
" mailing lists on %(hostname)s."
@@ -348,6 +362,7 @@ msgstr ""
" على %(hostname)s."
#: Mailman/Cgi/admin.py:316
+#, fuzzy
msgid ""
"
Below is the collection of publicly-advertised\n"
" %(mailmanlink)s mailing lists on %(hostname)s. Click on a list\n"
@@ -362,6 +377,7 @@ msgid "right "
msgstr "صحيح "
#: Mailman/Cgi/admin.py:325
+#, fuzzy
msgid ""
"To visit the administrators configuration page for an\n"
" unadvertised list, open a URL similar to this one, but with a '/' "
@@ -403,12 +419,14 @@ msgid "No valid variable name found."
msgstr "لا يوجد اسم متغير صحيح"
#: Mailman/Cgi/admin.py:395
+#, fuzzy
msgid ""
"%(realname)s Mailing list Configuration Help\n"
" %(varname)s Option"
msgstr "%(realname)s مساعدة ضبط القائمة البريدية %(varname)s خيار"
#: Mailman/Cgi/admin.py:402
+#, fuzzy
msgid "Mailman %(varname)s List Option Help"
msgstr "مساعدة خيارات قائمة ميلمان %(varname)s"
@@ -426,14 +444,17 @@ msgstr ""
"الخيار لهذه القائمة البريدية. ويمكنك أيضاً"
#: Mailman/Cgi/admin.py:431
+#, fuzzy
msgid "return to the %(categoryname)s options page."
msgstr "أن تعود إلى صفحة خيارات الـ %(categoryname)s"
#: Mailman/Cgi/admin.py:446
+#, fuzzy
msgid "%(realname)s Administration (%(label)s)"
msgstr "%(realname)s إشراف (%(label)s)"
#: Mailman/Cgi/admin.py:447
+#, fuzzy
msgid "%(realname)s mailing list administration %(label)s Section"
msgstr "الإشراف على القائمة البريدية %(realname)s قسم %(label)s"
@@ -513,6 +534,7 @@ msgid "Value"
msgstr "القيمة"
#: Mailman/Cgi/admin.py:668
+#, fuzzy
msgid ""
"Badly formed options entry:\n"
" %(record)s"
@@ -613,10 +635,12 @@ msgid "Move rule down"
msgstr "حرك القاعدة للأسفل:"
#: Mailman/Cgi/admin.py:870
+#, fuzzy
msgid " (Edit %(varname)s)"
msgstr " (حرر %(varname)s)"
#: Mailman/Cgi/admin.py:872
+#, fuzzy
msgid " (Details for %(varname)s)"
msgstr " (تفاصيل %(varname)s)"
@@ -656,6 +680,7 @@ msgid "(help)"
msgstr "(مساعدة)"
#: Mailman/Cgi/admin.py:930
+#, fuzzy
msgid "Find member %(link)s:"
msgstr "ابحث عن مشترك %(link)s:"
@@ -668,10 +693,12 @@ msgid "Bad regular expression: "
msgstr "صيغة نظامية سيئة: "
#: Mailman/Cgi/admin.py:1013
+#, fuzzy
msgid "%(allcnt)s members total, %(membercnt)s shown"
msgstr "%(allcnt)s مجموع المشتركين, %(membercnt)s تم عرضه"
#: Mailman/Cgi/admin.py:1016
+#, fuzzy
msgid "%(allcnt)s members total"
msgstr "%(allcnt)s مجموع المشتركين"
@@ -844,6 +871,7 @@ msgid ""
msgstr "
لعرض مشتركين أكثر، اضغط على المجال المناسب المعروض تحت:"
#: Mailman/Cgi/admin.py:1221
+#, fuzzy
msgid "from %(start)s to %(end)s"
msgstr "من %(start)s إلى %(end)s"
@@ -980,6 +1008,7 @@ msgid "Change list ownership passwords"
msgstr "غير كلمة سر ملكية القائمة"
#: Mailman/Cgi/admin.py:1364
+#, fuzzy
msgid ""
"The list administrators are the people who have ultimate control "
"over\n"
@@ -1144,8 +1173,9 @@ msgid "%(schange_to)s is already a member"
msgstr "عضو أصلاً"
#: Mailman/Cgi/admin.py:1620
+#, fuzzy
msgid "%(schange_to)s matches banned pattern %(spat)s"
-msgstr ""
+msgstr "عضو أصلاً"
#: Mailman/Cgi/admin.py:1622
msgid "Address %(schange_from)s changed to %(schange_to)s"
@@ -1185,6 +1215,7 @@ msgid "Not subscribed"
msgstr "غير مشترك"
#: Mailman/Cgi/admin.py:1773
+#, fuzzy
msgid "Ignoring changes to deleted member: %(user)s"
msgstr "تجاهل التعديلات لعنصر المحذوف: %(user)s"
@@ -1197,10 +1228,12 @@ msgid "Error Unsubscribing:"
msgstr "خطأ في إلغاء الاشتراك"
#: Mailman/Cgi/admindb.py:235 Mailman/Cgi/admindb.py:248
+#, fuzzy
msgid "%(realname)s Administrative Database"
msgstr "قاعدة بيانات الإشراف للمشرف %(realname)s"
#: Mailman/Cgi/admindb.py:238
+#, fuzzy
msgid "%(realname)s Administrative Database Results"
msgstr "نتائج قاعدة بيانات الإشراف للمشرف %(realname)s"
@@ -1229,6 +1262,7 @@ msgid "Discard all messages marked Defer"
msgstr "قم بإلغاء جميع الرسائل المحدد لها تأجيل"
#: Mailman/Cgi/admindb.py:298
+#, fuzzy
msgid "all of %(esender)s's held messages."
msgstr "جميع الرسائل المتوقفة لـ %(esender)s"
@@ -1249,6 +1283,7 @@ msgid "list of available mailing lists."
msgstr "قائمة بالقوئم البريدية الموجودة."
#: Mailman/Cgi/admindb.py:362
+#, fuzzy
msgid "You must specify a list name. Here is the %(link)s"
msgstr "يجب أن تحدد اسم القائمة. هنا هو الارتباط %(link)s"
@@ -1331,6 +1366,7 @@ msgid "The sender is now a member of this list"
msgstr "المرسل الآن عضو في هذه القائمة"
#: Mailman/Cgi/admindb.py:568
+#, fuzzy
msgid "Add %(esender)s to one of these sender filters:"
msgstr "أضف %(esender)s إلى أحد مصفيات المرسل:"
@@ -1351,6 +1387,7 @@ msgid "Rejects"
msgstr "رافضين"
#: Mailman/Cgi/admindb.py:584
+#, fuzzy
msgid ""
"Ban %(esender)s from ever subscribing to this\n"
" mailing list"
@@ -1363,6 +1400,7 @@ msgid ""
msgstr "انقر على رقم الرسالة لعرض الرسالة المفردة، أو يمكنك "
#: Mailman/Cgi/admindb.py:591
+#, fuzzy
msgid "view all messages from %(esender)s"
msgstr "عرض جميع الرسائل المرسلة من قبل %(esender)s"
@@ -1486,6 +1524,7 @@ msgstr ""
"إلغاؤه."
#: Mailman/Cgi/confirm.py:178
+#, fuzzy
msgid "System error, bad content: %(content)s"
msgstr "خطأ في النظام، محتوى سيء: %(content)s"
@@ -1521,6 +1560,7 @@ msgid "Confirm subscription request"
msgstr "أكد طلب الاشتراك"
#: Mailman/Cgi/confirm.py:259
+#, fuzzy
msgid ""
"Your confirmation is required in order to complete the\n"
" subscription request to the mailing list %(listname)s. Your\n"
@@ -1547,6 +1587,7 @@ msgstr ""
"اشتراكي
إذا كنت لم تعد تريد الاشتراك في هذه القائمة."
#: Mailman/Cgi/confirm.py:275
+#, fuzzy
msgid ""
"Your confirmation is required in order to continue with\n"
" the subscription request to the mailing list %(listname)s.\n"
@@ -1566,8 +1607,8 @@ msgid ""
" this mailing list, you can hit Cancel my subscription\n"
" request."
msgstr ""
-"إن تأكيدك مطلوب للاستمرار في طلب اشتراكك في القائمة البريدية "
-"%(listname)s.\n"
+"إن تأكيدك مطلوب للاستمرار في طلب اشتراكك في القائمة البريدية "
+"%(listname)s.\n"
"خيارات اشتراكك معروضة تحت، قم بأي تعديلات ضرورية واضغط على Subscribe to "
"list ... لإكمال عملية التأكيد. فور قيامك بتأكيد طلب اشتراكك، فإن المنظم "
"يجب عليه أن يقبل أو يرفض طلب عضويتك. ستستلم ملاحظة حول قراره.\n"
@@ -1593,6 +1634,7 @@ msgid "Preferred language:"
msgstr "اللغة المفضلة:"
#: Mailman/Cgi/confirm.py:317
+#, fuzzy
msgid "Subscribe to list %(listname)s"
msgstr "اشترك في القائمة %(listname)s"
@@ -1609,6 +1651,7 @@ msgid "Awaiting moderator approval"
msgstr "بانتظار موافقة المنظم"
#: Mailman/Cgi/confirm.py:386
+#, fuzzy
msgid ""
" You have successfully confirmed your subscription request to "
"the\n"
@@ -1661,6 +1704,7 @@ msgid "Subscription request confirmed"
msgstr "تم تأكيد طلب الاشتراك"
#: Mailman/Cgi/confirm.py:418
+#, fuzzy
msgid ""
" You have successfully confirmed your subscription request for\n"
" \"%(addr)s\" to the %(listname)s mailing list. A separate\n"
@@ -1686,6 +1730,7 @@ msgid "Unsubscription request confirmed"
msgstr "تم تأكيد إلغاء الاشتراك"
#: Mailman/Cgi/confirm.py:469
+#, fuzzy
msgid ""
" You have successfully unsubscribed from the %(listname)s "
"mailing\n"
@@ -1705,6 +1750,7 @@ msgid "Not available"
msgstr "غير متوفر"
#: Mailman/Cgi/confirm.py:498
+#, fuzzy
msgid ""
"Your confirmation is required in order to complete the\n"
" unsubscription request from the mailing list %(listname)s. "
@@ -1721,8 +1767,8 @@ msgid ""
"
Or hit Cancel and discard to cancel this unsubscription\n"
" request."
msgstr ""
-"تأكيدك مطلوب من أجل أن يتم إكمال طلب إلغاء الاشتراك من القائمة البريدية "
-"%(listname)s. أنت مسجل الآن بالعنوان:\n"
+"تأكيدك مطلوب من أجل أن يتم إكمال طلب إلغاء الاشتراك من القائمة البريدية "
+"%(listname)s. أنت مسجل الآن بالعنوان:\n"
"
الاسم الحقيقي: %(fullname)s\n"
"
العنوان الإلكتروني: %(addr)s\n"
"
\n"
@@ -1769,6 +1815,7 @@ msgid "Change of address request confirmed"
msgstr "تم تأكيد طلب تغيير العنوان"
#: Mailman/Cgi/confirm.py:571
+#, fuzzy
msgid ""
" You have successfully changed your address on the %(listname)s\n"
" mailing list from %(oldaddr)s to %(newaddr)s. "
@@ -1789,6 +1836,7 @@ msgid "globally"
msgstr "بشكل كامل عام"
#: Mailman/Cgi/confirm.py:605
+#, fuzzy
msgid ""
"Your confirmation is required in order to complete the\n"
" change of address request for the mailing list %(listname)s. "
@@ -1811,8 +1859,8 @@ msgid ""
"
Or hit Cancel and discard to cancel this change of address\n"
" request."
msgstr ""
-"تأكيدك مطلوب للاستمرار في طلب تغيير عنوانك في القائمة البريدية "
-"%(listname)s. أنت الآن مشترك بالعنوان \n"
+"تأكيدك مطلوب للاستمرار في طلب تغيير عنوانك في القائمة البريدية "
+"%(listname)s. أنت الآن مشترك بالعنوان \n"
"
\n"
@@ -1842,6 +1890,7 @@ msgid "Sender discarded message via web."
msgstr "المرسل أزال الرسالة من خلال الموقع."
#: Mailman/Cgi/confirm.py:674
+#, fuzzy
msgid ""
"The held message with the Subject:\n"
" header %(subject)s could not be found. The most "
@@ -1860,6 +1909,7 @@ msgid "Posted message canceled"
msgstr "تم إلغاء الرسالة المرسلة"
#: Mailman/Cgi/confirm.py:685
+#, fuzzy
msgid ""
" You have successfully canceled the posting of your message with\n"
" the Subject: header %(subject)s to the mailing list\n"
@@ -1880,6 +1930,7 @@ msgstr ""
"الرسالة المعلقة التي تم تحويلك إليها تم التعامل معها أصلاً من قبل المشرف."
#: Mailman/Cgi/confirm.py:735
+#, fuzzy
msgid ""
"Your confirmation is required in order to cancel the\n"
" posting of your message to the mailing list %(listname)s:\n"
@@ -1894,8 +1945,8 @@ msgid ""
"
Or hit the Continue awaiting approval button to continue to\n"
" allow the list moderator to approve or reject the message."
msgstr ""
-"تأكيدك مطلوب من أجل إلغاء إرسال رسالتك إلى القائمة البريدية "
-"%(listname)s:\n"
+"تأكيدك مطلوب من أجل إلغاء إرسال رسالتك إلى القائمة البريدية "
+"%(listname)s:\n"
"
المرسل: %(sender)s\n"
"
العنوان: %(subject)s\n"
"
السبب: %(reason)s\n"
@@ -1924,6 +1975,7 @@ msgid "Membership re-enabled."
msgstr "تم إعادة تمكين العضوية."
#: Mailman/Cgi/confirm.py:798
+#, fuzzy
msgid ""
" You have successfully re-enabled your membership in the\n"
" %(listname)s mailing list. You can now not available
"
msgstr "غير موجودة"
#: Mailman/Cgi/confirm.py:846
+#, fuzzy
msgid ""
"Your membership in the %(realname)s mailing list is\n"
" currently disabled due to excessive bounces. Your confirmation is\n"
@@ -2017,10 +2071,12 @@ msgid "administrative list overview"
msgstr "ملخص عام عن القائمة الاشرافية"
#: Mailman/Cgi/create.py:115
+#, fuzzy
msgid "List name must not include \"@\": %(safelistname)s"
msgstr "اسم القائمة يجب أن لا يحتوي على \"@\": %(safelistname)s"
#: Mailman/Cgi/create.py:122
+#, fuzzy
msgid "List already exists: %(safelistname)s"
msgstr "القائمة موجودة أصلاً: %(safelistname)s"
@@ -2054,18 +2110,22 @@ msgid "You are not authorized to create new mailing lists"
msgstr "أنت ليس مسموحاً لك بإنشاء قوائم بريدية جديدة"
#: Mailman/Cgi/create.py:182
+#, fuzzy
msgid "Unknown virtual host: %(safehostname)s"
msgstr "عنوان مستضيف تخيلي غير معروف: %(safehostname)s"
#: Mailman/Cgi/create.py:218 bin/newlist:219
+#, fuzzy
msgid "Bad owner email address: %(s)s"
msgstr "عنوان بريد مالك سيء: %(s)s"
#: Mailman/Cgi/create.py:223 bin/newlist:182 bin/newlist:223
+#, fuzzy
msgid "List already exists: %(listname)s"
msgstr "القائمة موجودة أصلاً: %(listname)s"
#: Mailman/Cgi/create.py:231 bin/newlist:217
+#, fuzzy
msgid "Illegal list name: %(s)s"
msgstr "اسم قائمة غير نظامي: %(s)s"
@@ -2078,6 +2138,7 @@ msgstr ""
"الموقع للمساعدة."
#: Mailman/Cgi/create.py:273 bin/newlist:265
+#, fuzzy
msgid "Your new mailing list: %(listname)s"
msgstr "قائمتك البريدية الجديدة: %(listname)s"
@@ -2086,6 +2147,7 @@ msgid "Mailing list creation results"
msgstr "نتائج إنشاء القائمة البريدية"
#: Mailman/Cgi/create.py:288
+#, fuzzy
msgid ""
"You have successfully created the mailing list\n"
" %(listname)s and notification has been sent to the list owner\n"
@@ -2107,6 +2169,7 @@ msgid "Create another list"
msgstr "أنشء قائمة بريدية أخرى"
#: Mailman/Cgi/create.py:312
+#, fuzzy
msgid "Create a %(hostname)s Mailing List"
msgstr "أنشء القائمة البريدية %(hostname)s"
@@ -2196,6 +2259,7 @@ msgstr ""
"المنظم بشكل افتراضي."
#: Mailman/Cgi/create.py:432
+#, fuzzy
msgid ""
"Initial list of supported languages.
Note that if you do not\n"
" select at least one initial language, the list will use the server\n"
@@ -2301,6 +2365,7 @@ msgid "List name is required."
msgstr "اسم القائمة مطلوب."
#: Mailman/Cgi/edithtml.py:154
+#, fuzzy
msgid "%(realname)s -- Edit html for %(template_info)s"
msgstr "%(realname)s -- عدل صيغة html لـ %(template_info)s"
@@ -2309,10 +2374,12 @@ msgid "Edit HTML : Error"
msgstr "تعديل HTML : خطأ"
#: Mailman/Cgi/edithtml.py:161
+#, fuzzy
msgid "%(safetemplatename)s: Invalid template"
msgstr "%(safetemplatename)s: قالب غير صالح"
#: Mailman/Cgi/edithtml.py:166 Mailman/Cgi/edithtml.py:167
+#, fuzzy
msgid "%(realname)s -- HTML Page Editing"
msgstr "%(realname)s -- تحريرصيغة صفحة HTML "
@@ -2371,10 +2438,12 @@ msgid "HTML successfully updated."
msgstr "تم تحديث HTML بنجاح."
#: Mailman/Cgi/listinfo.py:89
+#, fuzzy
msgid "%(hostname)s Mailing Lists"
msgstr "%(hostname)s القوائم البريدية لخادم الاستضافة"
#: Mailman/Cgi/listinfo.py:127
+#, fuzzy
msgid ""
"
There currently are no publicly-advertised\n"
" %(mailmanlink)s mailing lists on %(hostname)s."
@@ -2383,6 +2452,7 @@ msgstr ""
"%(hostname)s."
#: Mailman/Cgi/listinfo.py:131
+#, fuzzy
msgid ""
"
Below is a listing of all the public mailing lists on\n"
" %(hostname)s. Click on a list name to get more information "
@@ -2400,6 +2470,7 @@ msgid "right"
msgstr "صحيح"
#: Mailman/Cgi/listinfo.py:140
+#, fuzzy
msgid ""
" To visit the general information page for an unadvertised list,\n"
" open a URL similar to this one, but with a '/' and the %(adj)s\n"
@@ -2461,6 +2532,7 @@ msgstr "عنوان بريد إلكتروني غير نظامي"
#: Mailman/Cgi/options.py:183 Mailman/Cgi/options.py:240
#: Mailman/Cgi/options.py:264
+#, fuzzy
msgid "No such member: %(safeuser)s."
msgstr "لا يوجد مثل هذ العضو: %(safeuser)s"
@@ -2509,6 +2581,7 @@ msgid "Note: "
msgstr "ملاحظة: "
#: Mailman/Cgi/options.py:378
+#, fuzzy
msgid "List subscriptions for %(safeuser)s on %(hostname)s"
msgstr "اشتراكات القائمة لـ %(safeuser)s على الخادم %(hostname)s"
@@ -2536,6 +2609,7 @@ msgid "You are already using that email address"
msgstr "أنت تستعمل أصلاً ذلك العنوان البريدي الإلكتروني"
#: Mailman/Cgi/options.py:459
+#, fuzzy
msgid ""
"The new address you requested %(newaddr)s is already a member of the\n"
"%(listname)s mailing list, however you have also requested a global change "
@@ -2548,6 +2622,7 @@ msgstr ""
"تغيير كل قائمة بريدية تحتوي على العنوان %(safeuser)s. "
#: Mailman/Cgi/options.py:468
+#, fuzzy
msgid "The new address is already a member: %(newaddr)s"
msgstr "العنوان الجديد عضو أصلاً: %(newaddr)s"
@@ -2556,6 +2631,7 @@ msgid "Addresses may not be blank"
msgstr "العناوين يجب أن لا تكون فارغة"
#: Mailman/Cgi/options.py:488
+#, fuzzy
msgid "A confirmation message has been sent to %(newaddr)s. "
msgstr "تم إرسال رسالة تأكيد إلى: %(newaddr)s. "
@@ -2568,6 +2644,7 @@ msgid "Illegal email address provided"
msgstr "تم التزويد بعنوان غير نظامي"
#: Mailman/Cgi/options.py:501
+#, fuzzy
msgid "%(newaddr)s is already a member of the list."
msgstr "%(newaddr)s عضو أصلاً في القائمة."
@@ -2647,6 +2724,7 @@ msgstr ""
"إعلام فور اتخاذ منظمي القائمة قرارهم."
#: Mailman/Cgi/options.py:623
+#, fuzzy
msgid ""
"You have been successfully unsubscribed from the\n"
" mailing list %(fqdn_listname)s. If you were receiving digest\n"
@@ -2732,6 +2810,7 @@ msgid "day"
msgstr "يوم"
#: Mailman/Cgi/options.py:900
+#, fuzzy
msgid "%(days)d %(units)s"
msgstr "%(days)d %(units)s"
@@ -2744,6 +2823,7 @@ msgid "No topics defined"
msgstr "لا يوجد مواضيع معرفة"
#: Mailman/Cgi/options.py:940
+#, fuzzy
msgid ""
"\n"
"You are subscribed to this list with the case-preserved address\n"
@@ -2753,6 +2833,7 @@ msgstr ""
"أنت مشترك في هذه القائمة بالعنوان المحفوظ حالة أحرفه %(cpuser)s."
#: Mailman/Cgi/options.py:956
+#, fuzzy
msgid "%(realname)s list: member options login page"
msgstr "صفحة الدخول إلى خيارات عضو القائمة %(realname)s "
@@ -2761,10 +2842,12 @@ msgid "email address and "
msgstr "عنوان إلكتروني و "
#: Mailman/Cgi/options.py:960
+#, fuzzy
msgid "%(realname)s list: member options for user %(safeuser)s"
msgstr "خيارات عضو القائمة %(realname)s للمستخدم %(safeuser)s"
#: Mailman/Cgi/options.py:986
+#, fuzzy
msgid ""
"In order to change your membership option, you must\n"
" first log in by giving your %(extra)smembership password in the section\n"
@@ -2833,6 +2916,7 @@ msgid ""
msgstr "<مفقود>"
#: Mailman/Cgi/options.py:1140
+#, fuzzy
msgid "Requested topic is not valid: %(topicname)s"
msgstr "موضوع مطلوب غير صحيح: %(topicname)s"
@@ -2861,6 +2945,7 @@ msgid "Private archive - \"./\" and \"../\" not allowed in URL."
msgstr ""
#: Mailman/Cgi/private.py:109
+#, fuzzy
msgid "Private Archive Error - %(msg)s"
msgstr "خطأ في الأرشيف الخاص - %(msg)s"
@@ -2898,12 +2983,14 @@ msgid "Mailing list deletion results"
msgstr "نتائج إزالة القائمة البريدية"
#: Mailman/Cgi/rmlist.py:187
+#, fuzzy
msgid ""
"You have successfully deleted the mailing list\n"
" %(listname)s."
msgstr "لقد قمت بنجاح بحذف القائمة البريدية %(listname)s."
#: Mailman/Cgi/rmlist.py:191
+#, fuzzy
msgid ""
"There were some problems deleting the mailing list\n"
" %(listname)s. Contact your site administrator at "
@@ -2915,6 +3002,7 @@ msgstr ""
" من أجل التفاصيل."
#: Mailman/Cgi/rmlist.py:208
+#, fuzzy
msgid "Permanently remove mailing list %(realname)s"
msgstr "أزل القائمة %(realname)s بشكل دائم"
@@ -2978,6 +3066,7 @@ msgid "Invalid options to CGI script"
msgstr "خيارات غير صحيحة لبرنامج CGI"
#: Mailman/Cgi/roster.py:118
+#, fuzzy
msgid "%(realname)s roster authentication failed."
msgstr "فشل التحقق من الشخصية للجدول %(realname)s."
@@ -3044,6 +3133,7 @@ msgstr ""
"تعليمات أخرى."
#: Mailman/Cgi/subscribe.py:262
+#, fuzzy
msgid ""
"The email address you supplied is banned from this\n"
" mailing list. If you think this restriction is erroneous, please\n"
@@ -3067,6 +3157,7 @@ msgid ""
msgstr "اشتراكك غير مسموح بسبب أن العنوان البريدي المعطى غير مأمون."
#: Mailman/Cgi/subscribe.py:278
+#, fuzzy
msgid ""
"Confirmation from your email address is required, to prevent anyone from\n"
"subscribing you without permission. Instructions are being sent to you at\n"
@@ -3078,6 +3169,7 @@ msgstr ""
"اشتراكك لن يبدأ حتى تؤكد اشتراكك."
#: Mailman/Cgi/subscribe.py:290
+#, fuzzy
msgid ""
"Your subscription request was deferred because %(x)s. Your request has "
"been\n"
@@ -3097,6 +3189,7 @@ msgid "Mailman privacy alert"
msgstr "إنذار ميلمان حول الخصوصية"
#: Mailman/Cgi/subscribe.py:316
+#, fuzzy
msgid ""
"An attempt was made to subscribe your address to the mailing list\n"
"%(listaddr)s. You are already subscribed to this mailing list.\n"
@@ -3132,6 +3225,7 @@ msgid "This list only supports digest delivery."
msgstr "هذه القائمة تدعم فقط الإرسال على دفعات."
#: Mailman/Cgi/subscribe.py:344
+#, fuzzy
msgid "You have been successfully subscribed to the %(realname)s mailing list."
msgstr "لقد اشتركت بنجاح في القائمة البريدية %(realname)s."
@@ -3258,26 +3352,32 @@ msgid "n/a"
msgstr "غير ممكن"
#: Mailman/Commands/cmd_info.py:44
+#, fuzzy
msgid "List name: %(listname)s"
msgstr "اسم القائمة: %(listname)s"
#: Mailman/Commands/cmd_info.py:45
+#, fuzzy
msgid "Description: %(description)s"
msgstr "الشرح: %(description)s"
#: Mailman/Commands/cmd_info.py:46
+#, fuzzy
msgid "Postings to: %(postaddr)s"
msgstr "الإرسالات إلى: %(postaddr)s"
#: Mailman/Commands/cmd_info.py:47
+#, fuzzy
msgid "List Helpbot: %(requestaddr)s"
msgstr "مساعد القائمة الآلي: %(requestaddr)s"
#: Mailman/Commands/cmd_info.py:48
+#, fuzzy
msgid "List Owners: %(owneraddr)s"
msgstr "مالكي القائمة: %(owneraddr)s"
#: Mailman/Commands/cmd_info.py:49
+#, fuzzy
msgid "More information: %(listurl)s"
msgstr "معلومات إضافية: %(listurl)s"
@@ -3301,18 +3401,22 @@ msgstr ""
"هذا.\n"
#: Mailman/Commands/cmd_lists.py:44
+#, fuzzy
msgid "Public mailing lists at %(hostname)s:"
msgstr "القوائم البريدية العمومية على الخادم %(hostname)s:"
#: Mailman/Commands/cmd_lists.py:66
+#, fuzzy
msgid "%(i)3d. List name: %(realname)s"
msgstr "%(i)3d. اسم القائمة: %(realname)s"
#: Mailman/Commands/cmd_lists.py:67
+#, fuzzy
msgid " Description: %(description)s"
msgstr " الشرح: %(description)s"
#: Mailman/Commands/cmd_lists.py:68
+#, fuzzy
msgid " Requests to: %(requestaddr)s"
msgstr " الطلبات إلى: %(requestaddr)s"
@@ -3344,12 +3448,14 @@ msgstr ""
" ترسل الإجابة دائماً إلى عنوان الاشتراك\n"
#: Mailman/Commands/cmd_password.py:51 Mailman/Commands/cmd_password.py:66
+#, fuzzy
msgid "Your password is: %(password)s"
msgstr "كلمة سرك هي: %(password)s"
#: Mailman/Commands/cmd_password.py:57 Mailman/Commands/cmd_password.py:72
#: Mailman/Commands/cmd_password.py:95 Mailman/Commands/cmd_password.py:121
#: Mailman/Commands/cmd_set.py:149 Mailman/Commands/cmd_set.py:219
+#, fuzzy
msgid "You are not a member of the %(listname)s mailing list"
msgstr "أنت لست مشتركاً في القائمة البريدية %(listname)s "
@@ -3527,6 +3633,7 @@ msgstr ""
"لكلمة السر لهذه القائمة.\n"
#: Mailman/Commands/cmd_set.py:122
+#, fuzzy
msgid "Bad set command: %(subcmd)s"
msgstr "أمر set غير جيد: %(subcmd)s"
@@ -3547,6 +3654,7 @@ msgid "on"
msgstr "ممكن"
#: Mailman/Commands/cmd_set.py:154
+#, fuzzy
msgid " ack %(onoff)s"
msgstr " إعلام %(onoff)s"
@@ -3584,22 +3692,27 @@ msgid "due to bounces"
msgstr "بسبب رد رفض"
#: Mailman/Commands/cmd_set.py:186
+#, fuzzy
msgid " %(status)s (%(how)s on %(date)s)"
msgstr " %(status)s (%(how)s في %(date)s)"
#: Mailman/Commands/cmd_set.py:192
+#, fuzzy
msgid " myposts %(onoff)s"
msgstr " إرسالاتي %(onoff)s"
#: Mailman/Commands/cmd_set.py:195
+#, fuzzy
msgid " hide %(onoff)s"
msgstr " إخفاء %(onoff)s"
#: Mailman/Commands/cmd_set.py:199
+#, fuzzy
msgid " duplicates %(onoff)s"
msgstr " مكررات %(onoff)s"
#: Mailman/Commands/cmd_set.py:203
+#, fuzzy
msgid " reminders %(onoff)s"
msgstr " مذكر %(onoff)s"
@@ -3608,6 +3721,7 @@ msgid "You did not give the correct password"
msgstr "لم تقم بإعطاء كلمة السر الصحيحة"
#: Mailman/Commands/cmd_set.py:236 Mailman/Commands/cmd_set.py:283
+#, fuzzy
msgid "Bad argument: %(arg)s"
msgstr "معامل أمر غير جيد: %(arg)s"
@@ -3682,6 +3796,7 @@ msgstr ""
" أن تحدد بإضافة `address=' (بدون أقواس ولا علامات اقتباس)\n"
#: Mailman/Commands/cmd_subscribe.py:62
+#, fuzzy
msgid "Bad digest specifier: %(arg)s"
msgstr "معامل دفعات غير جيد: %(arg)s"
@@ -3690,6 +3805,7 @@ msgid "No valid address found to subscribe"
msgstr "لم يتم العثور على عنوان صحيح للاشتراك"
#: Mailman/Commands/cmd_subscribe.py:113
+#, fuzzy
msgid ""
"The email address you supplied is banned from this mailing list.\n"
"If you think this restriction is erroneous, please contact the list\n"
@@ -3726,6 +3842,7 @@ msgid "This list only supports digest subscriptions!"
msgstr "هذه القائمة تدعم فقط اشتراكات دفعات الرسائل!"
#: Mailman/Commands/cmd_subscribe.py:146
+#, fuzzy
msgid ""
"Your subscription request has been forwarded to the list administrator\n"
"at %(listowner)s for review."
@@ -3759,6 +3876,7 @@ msgstr ""
" `address=' (بدون أقواس ولا علامات اقتباس)\n"
#: Mailman/Commands/cmd_unsubscribe.py:62
+#, fuzzy
msgid "%(address)s is not a member of the %(listname)s mailing list"
msgstr "العنوان %(address)s ليس عضواً في القائمة البريدية %(listname)s"
@@ -4003,6 +4121,7 @@ msgid "Chinese (Taiwan)"
msgstr "الصينية (التايوانية)"
#: Mailman/Deliverer.py:53
+#, fuzzy
msgid ""
"Note: Since this is a list of mailing lists, administrative\n"
"notices like the password reminder will be sent to\n"
@@ -4016,14 +4135,17 @@ msgid " (Digest mode)"
msgstr "(وضع الدفعات)"
#: Mailman/Deliverer.py:79
+#, fuzzy
msgid "Welcome to the \"%(realname)s\" mailing list%(digmode)s"
msgstr "أهلاً في القائمة البريدية \"%(realname)s\" %(digmode)s"
#: Mailman/Deliverer.py:89
+#, fuzzy
msgid "You have been unsubscribed from the %(realname)s mailing list"
msgstr "تم إلغاء اشتراكك في القائمة البريدية %(realname)s"
#: Mailman/Deliverer.py:116
+#, fuzzy
msgid "%(listfullname)s mailing list reminder"
msgstr "مذكر القائمة البريدية %(listfullname)s"
@@ -4036,6 +4158,7 @@ msgid "Hostile subscription attempt detected"
msgstr "تم كشف محاولة اشتراك خبيثة"
#: Mailman/Deliverer.py:169
+#, fuzzy
msgid ""
"%(address)s was invited to a different mailing\n"
"list, but in a deliberate malicious attempt they tried to confirm the\n"
@@ -4047,6 +4170,7 @@ msgstr ""
"قد تحب أن تعرف. لا يوجد شيء مطلوب منك أن تفعله بعد."
#: Mailman/Deliverer.py:188
+#, fuzzy
msgid ""
"You invited %(address)s to your list, but in a\n"
"deliberate malicious attempt, they tried to confirm the invitation to a\n"
@@ -4059,6 +4183,7 @@ msgstr ""
"يوجد عمل مطلوب منك أن تعمله بعد."
#: Mailman/Deliverer.py:221
+#, fuzzy
msgid "%(listname)s mailing list probe message"
msgstr "رسالة جس النبض للقائمة البريدية %(listname)s"
@@ -4253,8 +4378,8 @@ msgid ""
" membership.\n"
"\n"
"
those messages too will get discarded. You may "
"want\n"
" to set up an\n"
-" autoresponse\n"
+" autoresponse\n"
" message for email to the -owner and -admin address."
msgstr ""
"مع أن مكتشف ردود الرفض الخاص بـ ميلمان قوي بشكل مقبول، إلا أنه من المستحيل "
@@ -4501,6 +4626,7 @@ msgstr ""
"كثيرة. سوف يتم عمل محاولة تنبيه للمشترك دائماً."
#: Mailman/Gui/Bounce.py:194
+#, fuzzy
msgid ""
"Bad value for %(property)s: %(val)s"
@@ -4611,8 +4737,9 @@ msgstr ""
"image/gif. اترك النوع الفرعي لإزالة جميع الأقسام التي تطابق نوع "
"المحتويات الرئيسي، مثل image.\n"
"
سيتم تجاهل الأسطر الفارغة.\n"
-"
أنظر أيضاً pass_mime_types من أجل الحصول على القائمة البيضاء لأنواع المحتويات."
+"
أنظر أيضاً pass_mime_types من أجل الحصول على القائمة البيضاء "
+"لأنواع المحتويات."
#: Mailman/Gui/ContentFilter.py:94
msgid ""
@@ -4628,8 +4755,8 @@ msgid ""
"Use this option to remove each message attachment that does\n"
" not have a matching content type. Requirements and formats "
"are\n"
-" exactly like filter_mime_types.\n"
"\n"
"
Note: if you add entries to this list but don't add\n"
@@ -4731,6 +4858,7 @@ msgstr ""
"مشرف الموقع."
#: Mailman/Gui/ContentFilter.py:171
+#, fuzzy
msgid "Bad MIME type ignored: %(spectype)s"
msgstr "نوع محتويات سيئ متجاهل: %(spectype)s"
@@ -4829,6 +4957,7 @@ msgid ""
msgstr "هل على ميلمان أن يرسل الدفعة التالية الآن إذا لم تكن فارغة؟"
#: Mailman/Gui/Digest.py:145
+#, fuzzy
msgid ""
"The next digest will be sent as volume\n"
" %(volume)s, number %(number)s"
@@ -4843,14 +4972,17 @@ msgid "There was no digest to send."
msgstr "لم يرسل أي دفعة."
#: Mailman/Gui/GUIBase.py:173
+#, fuzzy
msgid "Invalid value for variable: %(property)s"
msgstr "قيمة غير صالحة للمتحول: %(property)s"
#: Mailman/Gui/GUIBase.py:178
+#, fuzzy
msgid "Bad email address for option %(property)s: %(error)s"
msgstr "عنوان إلكتروني سيء للخيار%(property)s : %(error)s"
#: Mailman/Gui/GUIBase.py:204
+#, fuzzy
msgid ""
"The following illegal substitution variables were\n"
" found in the %(property)s string:\n"
@@ -4859,13 +4991,14 @@ msgid ""
"this\n"
" problem."
msgstr ""
-"تم إيجاد متغيرات التبديل غير النظامية التالية في مجموعة المحارف "
-"%(property)s:\n"
+"تم إيجاد متغيرات التبديل غير النظامية التالية في مجموعة المحارف "
+"%(property)s:\n"
" %(bad)s\n"
"
قد لا تعمل قائمتك بشكل صحيح إلى أن تقوم بتصحيح هذه "
"المشلكة."
#: Mailman/Gui/GUIBase.py:218
+#, fuzzy
msgid ""
"Your %(property)s string appeared to\n"
" have some correctable problems in its new value.\n"
@@ -4960,8 +5093,8 @@ msgid ""
"
In order to split the list ownership duties into\n"
" administrators and moderators, you must\n"
" set a separate moderator password,\n"
-" and also provide the email\n"
+" and also provide the email\n"
" addresses of the list moderators. Note that the field you\n"
" are changing here specifies the list administrators."
msgstr ""
@@ -4974,9 +5107,9 @@ msgstr ""
"و تدبير الإرسالات المعلقة. بالطبع فإن مشرفي القائمة يمكنهم أيضاً أن "
"يأخذوا على عاتقهم الطلبات المعلقة.\n"
"
ومن أجل تقسيم واجبات ملكية القائمة على مشرفين ومنظمين فعليك "
-"وضع كلمة سر منفصلة للمنظمين, وتزود أيضاً بـ العناوين البريدية لمنظمي القائمة. لاحظ "
-"أن الحقل الذي يتغير هنا يحدد مشرفي القائمة."
+"وضع كلمة سر منفصلة للمنظمين, وتزود أيضاً بـ العناوين البريدية لمنظمي القائمة. "
+"لاحظ أن الحقل الذي يتغير هنا يحدد مشرفي القائمة."
#: Mailman/Gui/General.py:102
msgid ""
@@ -5019,9 +5152,9 @@ msgstr ""
"و تدبير الإرسالات المعلقة. بالطبع فإن مشرفي القائمة يمكنهم أيضاً أن "
"يأخذوا على عاتقهم الطلبات المعلقة.\n"
"
There are many reasons not to introduce or override the\n"
@@ -5326,13 +5459,13 @@ msgid ""
" their own Reply-To: settings to convey their valid\n"
" return address. Another is that modifying Reply-To:\n"
" makes it much more difficult to send private replies. See `Reply-To'\n"
+" href=\"http://marc.merlins.org/netrants/reply-to-harmful."
+"html\">`Reply-To'\n"
" Munging Considered Harmful for a general discussion of "
"this\n"
" issue. See \n"
+" href=\"http://marc.merlins.org/netrants/reply-to-useful."
+"html\">\n"
" Reply-To Munging Considered Useful for a dissenting "
"opinion.\n"
"\n"
@@ -5354,8 +5487,9 @@ msgid ""
" Reply-To: header, it will not be changed."
msgstr ""
"هذا هو العنوان الذي سيوضع في ترويسة Reply-To: عندما يكون الخيار reply_goes_to_list قد ضبط على القيمة عنوان مصرح. "
+" href=\"?VARHELP=general/"
+"reply_goes_to_list\">reply_goes_to_list قد ضبط على القيمة عنوان "
+"مصرح. "
#: Mailman/Gui/General.py:305
msgid "Umbrella list settings"
@@ -5401,8 +5535,8 @@ msgid ""
" member list addresses, but rather to the owner of those member\n"
" lists. In that case, the value of this setting is appended to\n"
" the member's account name for such notices. `-owner' is the\n"
-" typical choice. This setting has no effect when \"umbrella_list"
-"\"\n"
+" typical choice. This setting has no effect when "
+"\"umbrella_list\"\n"
" is \"No\"."
msgstr ""
"عندما تضبط \"umbrella_list\" لتشير إلى أن هذه القائمة لها قوائم بريدية أخرى "
@@ -5677,8 +5811,8 @@ msgid ""
" does not affect the inclusion of the other List-*:\n"
" headers.)"
msgstr ""
-"إن ترويسة List-Post: هي إحدى الترويسات المنصوح بها من قبل RFC 2369.\n"
+"إن ترويسة List-Post: هي إحدى الترويسات المنصوح بها من قبل RFC 2369.\n"
" وبكل حال للقوائم البريدية الإعلانية فقطفقط مجموعة "
"انتقائية صغيرة من الناس يسمح لهم أن يرسلوا إلى القائمة، العضوية العامة غير "
"مسموح لها بالإرسال بشكل اعتيادي. القوائم من هذه الطبيعة تكون الترويسة "
@@ -6268,6 +6402,7 @@ msgstr ""
"موافقتهم."
#: Mailman/Gui/Privacy.py:104
+#, fuzzy
msgid ""
"This section allows you to configure subscription and\n"
" membership exposure policy. You can also control whether this\n"
@@ -6276,8 +6411,8 @@ msgid ""
" separate archive-related privacy settings."
msgstr ""
"يسمح لك هذا القسم أن تضبط سياسة إظهار الاشتراك والعضوية. ويمكنك أن تتحكم "
-"بكون هذه القائمة للعموم أم لا. انظر أيضاً إلى قسم خيارات أرشيفية من أجل خيارات خصوصية متعلقة بالأرشفة."
+"بكون هذه القائمة للعموم أم لا. انظر أيضاً إلى قسم خيارات أرشيفية من أجل خيارات خصوصية متعلقة بالأرشفة."
#: Mailman/Gui/Privacy.py:110
msgid "Subscribing"
@@ -6445,8 +6580,8 @@ msgid ""
" either individually or as a group. Any\n"
" posting from a non-member who is not explicitly accepted,\n"
" rejected, or discarded, will have their posting filtered by the\n"
-" general\n"
+" general\n"
" non-member rules.\n"
"\n"
"
In the text boxes below, add one address per line; start the\n"
@@ -6469,8 +6604,8 @@ msgstr ""
"
which says\n"
" whether messages from the list member can be posted directly "
@@ -6543,8 +6679,8 @@ msgid ""
"If a member posts this many times, within a period of time\n"
" the member is automatically moderated. Use 0 to disable. "
"See\n"
-" member_verbosity_interval for details on the time "
"period.\n"
"\n"
@@ -6952,8 +7088,8 @@ msgstr ""
"عندما يتم استلام إرسال من غير أعضاء فيتم مقارنة مرسل الرسالة بقائمة عناوين "
"محددة للقبول,\n"
-" والتعليق,\n"
+" والتعليق,\n"
" والرفض (رد رفض), \n"
" The body of the message can also be optionally scanned for\n"
" Subject: and Keywords: headers, as\n"
" specified by the topics_bodylines_limit\n"
+" href=\"?VARHELP=topics/"
+"topics_bodylines_limit\">topics_bodylines_limit\n"
" configuration variable."
msgstr ""
"يصنف مصفي الموضوع كل رسالة بريد قائمة حسب ويمكن اختيارياً تفحص نص الرسالة أيضاً من للبحث عن "
"ترويسات Subject: و Keywords: كما هو "
"محدد في متحول الضبط topics_bodylines_limit"
+" href=\"?VARHELP=topics/"
+"topics_bodylines_limit\">topics_bodylines_limit"
#: Mailman/Gui/Topics.py:72
msgid "How many body lines should the topic matcher scan?"
@@ -7317,6 +7455,7 @@ msgstr ""
"تحديد الموضوع يتطلب اسماً ووحدة متكررة. سيتم تجاهل العناوين الغير مكتملة."
#: Mailman/Gui/Topics.py:135
+#, fuzzy
msgid ""
"The topic pattern '%(safepattern)s' is not a\n"
" legal regular expression. It will be discarded."
@@ -7502,8 +7641,8 @@ msgid ""
" the linked\n"
" newsgroup fields are filled in."
msgstr ""
-"لا تستطيع أن تمكن النقل حتى تقوم بتعبيئة حقل خادم الأخبار و\n"
+"لا تستطيع أن تمكن النقل حتى تقوم بتعبيئة حقل خادم الأخبار و\n"
" حقل المجموعة "
"المربوطة."
@@ -7512,6 +7651,7 @@ msgid "%(listinfo_link)s list run by %(owner_link)s"
msgstr "القائمة %(listinfo_link)s مشغلة من قبل %(owner_link)s"
#: Mailman/HTMLFormatter.py:57
+#, fuzzy
msgid "%(realname)s administrative interface"
msgstr "واجهة الإدارة للقائمة %(realname)s"
@@ -7520,6 +7660,7 @@ msgid " (requires authorization)"
msgstr "(مطلوب التحقق من الهوية)"
#: Mailman/HTMLFormatter.py:61
+#, fuzzy
msgid "Overview of all %(hostname)s mailing lists"
msgstr "عرض عام لجميع القوائم البريدية للموقع %(hostname)s "
@@ -7540,6 +7681,7 @@ msgid "; it was disabled by the list administrator"
msgstr " وتم التعطيل من قبل مدير القائمة"
#: Mailman/HTMLFormatter.py:146
+#, fuzzy
msgid ""
"; it was disabled due to excessive bounces. The\n"
" last bounce was received on %(date)s"
@@ -7551,6 +7693,7 @@ msgid "; it was disabled for unknown reasons"
msgstr " وتم التعطيل لأسباب غير معروفة"
#: Mailman/HTMLFormatter.py:151
+#, fuzzy
msgid "Note: your list delivery is currently disabled%(reason)s."
msgstr "ملاحظة: توصيل قائمتك معطل الآن %(reason)s."
@@ -7563,6 +7706,7 @@ msgid "the list administrator"
msgstr "مدير القائمة"
#: Mailman/HTMLFormatter.py:157
+#, fuzzy
msgid ""
"
We have received some recent bounces from your\n"
" address. Your current bounce score is %(score)s out of "
@@ -7596,6 +7741,7 @@ msgstr ""
"تصفير معدل الرد الرافض الخاص بك تلقائياً إن تم تصحيح المشاكل قريباً."
#: Mailman/HTMLFormatter.py:181
+#, fuzzy
msgid ""
"(Note - you are subscribing to a list of mailing lists, so the %(type)s "
"notice will be sent to the admin address for your membership, %(addr)s.)
"
@@ -7638,6 +7784,7 @@ msgstr ""
"القائمة. سيتم تنبيهك لقرار منظم القائمة بالبريد."
#: Mailman/HTMLFormatter.py:208
+#, fuzzy
msgid ""
"This is %(also)sa private list, which means that the\n"
" list of members is not available to non-members."
@@ -7646,6 +7793,7 @@ msgstr ""
"لغير الأعضاء."
#: Mailman/HTMLFormatter.py:211
+#, fuzzy
msgid ""
"This is %(also)sa hidden list, which means that the\n"
" list of members is available only to the list administrator."
@@ -7653,6 +7801,7 @@ msgstr ""
"هذه %(also)s قائمة مخفية، مما يعني أن قائمة الأعضاء متوفرة فقط لمدير القائمة."
#: Mailman/HTMLFormatter.py:214
+#, fuzzy
msgid ""
"This is %(also)sa public list, which means that the\n"
" list of members list is available to everyone."
@@ -7667,6 +7816,7 @@ msgstr ""
"الغير مرغوب فيها)."
#: Mailman/HTMLFormatter.py:222
+#, fuzzy
msgid ""
"
(Note that this is an umbrella list, intended to\n"
" have only other mailing lists as members. Among other things,\n"
@@ -7682,6 +7832,7 @@ msgid "either "
msgstr "إما "
#: Mailman/HTMLFormatter.py:256
+#, fuzzy
msgid ""
"To unsubscribe from %(realname)s, get a password reminder,\n"
" or change your subscription options %(either)senter your "
@@ -7710,12 +7861,14 @@ msgid ""
msgstr "إذا تركت هذا الحقل فارغاً فسوف يطلب منك عنوانك الإلكتروني"
#: Mailman/HTMLFormatter.py:277
+#, fuzzy
msgid ""
"(%(which)s is only available to the list\n"
" members.)"
msgstr "(%(which)s هي متوفرة فقط لأعضاء القائمة.)"
#: Mailman/HTMLFormatter.py:281
+#, fuzzy
msgid ""
"(%(which)s is only available to the list\n"
" administrator.)"
@@ -7774,6 +7927,7 @@ msgid "The current archive"
msgstr "الأرشيف الحالي"
#: Mailman/Handlers/Acknowledge.py:59
+#, fuzzy
msgid "%(realname)s post acknowledgement"
msgstr "إعلام وصول الإرسال إلى %(realname)s"
@@ -7786,6 +7940,7 @@ msgid ""
msgstr ""
#: Mailman/Handlers/CalcRecips.py:79
+#, fuzzy
msgid ""
"Your urgent message to the %(realname)s mailing list was not authorized for\n"
"delivery. The original message as received by Mailman is attached.\n"
@@ -7860,6 +8015,7 @@ msgid "Message may contain administrivia"
msgstr "قد تحوي على تعليمات إدارية"
#: Mailman/Handlers/Hold.py:84
+#, fuzzy
msgid ""
"Please do *not* post administrative requests to the mailing\n"
"list. If you wish to subscribe, visit %(listurl)s or send a message with "
@@ -7896,10 +8052,12 @@ msgid "Posting to a moderated newsgroup"
msgstr "إرسال إلى قائمة إخبارية منظمة"
#: Mailman/Handlers/Hold.py:252
+#, fuzzy
msgid "Your message to %(listname)s awaits moderator approval"
msgstr "رسالتك إلى القائمة البريدية %(listname)s تنتظر موافقة المنظم"
#: Mailman/Handlers/Hold.py:271
+#, fuzzy
msgid "%(listname)s post from %(sender)s requires approval"
msgstr "إرسال إلى القائمة %(listname)s من قبل %(sender)s تحتاج للموافقة"
@@ -7940,6 +8098,7 @@ msgid "After content filtering, the message was empty"
msgstr "بعد تصفية المحتويات صارت الرسالة فارغة"
#: Mailman/Handlers/MimeDel.py:269
+#, fuzzy
msgid ""
"The attached message matched the %(listname)s mailing list's content "
"filtering\n"
@@ -7981,6 +8140,7 @@ msgid "The attached message has been automatically discarded."
msgstr "تم إهمال الرسالة المرفقة تلقائياً."
#: Mailman/Handlers/Replybot.py:75
+#, fuzzy
msgid "Auto-response for your message to the \"%(realname)s\" mailing list"
msgstr "رد تلقائي لرسالتك المرسلة إلى القائم البريدية \"%(realname)s\""
@@ -8004,6 +8164,7 @@ msgid "HTML attachment scrubbed and removed"
msgstr "فصل المرفق من نوع HTML وأزيل"
#: Mailman/Handlers/Scrubber.py:234 Mailman/Handlers/Scrubber.py:259
+#, fuzzy
msgid ""
"An HTML attachment was scrubbed...\n"
"URL: %(url)s\n"
@@ -8056,6 +8217,7 @@ msgstr ""
"الرابط : %(url)s\n"
#: Mailman/Handlers/Scrubber.py:347
+#, fuzzy
msgid "Skipped content of type %(partctype)s\n"
msgstr "أنواع المحتويات المتروكة %(partctype)s\n"
@@ -8085,6 +8247,7 @@ msgid "Message rejected by filter rule match"
msgstr "رفضت الرسالة بسبب تطابق قاعدة مصفي"
#: Mailman/Handlers/ToDigest.py:173
+#, fuzzy
msgid "%(realname)s Digest, Vol %(volume)d, Issue %(issue)d"
msgstr "%(realname)s دفعات, الجزء %(volume)d, الإصدار %(issue)d"
@@ -8121,6 +8284,7 @@ msgid "End of "
msgstr "نهاية "
#: Mailman/ListAdmin.py:309
+#, fuzzy
msgid "Posting of your message titled \"%(subject)s\""
msgstr "إرسال رسالتك المعنونة \"%(subject)s\""
@@ -8133,6 +8297,7 @@ msgid "Forward of moderated message"
msgstr "تحويل لرسالة منظمة"
#: Mailman/ListAdmin.py:405
+#, fuzzy
msgid "New subscription request to list %(realname)s from %(addr)s"
msgstr "طلب اشتراك جديد في القائمة %(realname)s من العنوان %(addr)s"
@@ -8146,6 +8311,7 @@ msgid "via admin approval"
msgstr "استمر في انتظار القبول"
#: Mailman/ListAdmin.py:466
+#, fuzzy
msgid "New unsubscription request from %(realname)s by %(addr)s"
msgstr "طلب إلغاء اشتراك من القائمة %(realname)s من قبل %(addr)s"
@@ -8158,10 +8324,12 @@ msgid "Original Message"
msgstr "الرسالة الأصلية"
#: Mailman/ListAdmin.py:526
+#, fuzzy
msgid "Request to mailing list %(realname)s rejected"
msgstr "تم رفض طلب إلى القائمة البريدية %(realname)s"
#: Mailman/MTA/Manual.py:66
+#, fuzzy
msgid ""
"The mailing list `%(listname)s' has been created via the through-the-web\n"
"interface. In order to complete the activation of this mailing list, the\n"
@@ -8185,14 +8353,17 @@ msgstr ""
"الأسطر التالية، وكذلك تشغيل البرنامج `newaliases':\n"
#: Mailman/MTA/Manual.py:82
+#, fuzzy
msgid "## %(listname)s mailing list"
msgstr "## %(listname)s mailing list"
#: Mailman/MTA/Manual.py:99
+#, fuzzy
msgid "Mailing list creation request for list %(listname)s"
msgstr "طلب إنشاء للقائمة %(listname)s"
#: Mailman/MTA/Manual.py:113
+#, fuzzy
msgid ""
"The mailing list `%(listname)s' has been removed via the through-the-web\n"
"interface. In order to complete the de-activation of this mailing list, "
@@ -8208,6 +8379,7 @@ msgstr ""
"يجب أن تحذف من الملف /etc/aliases:\n"
#: Mailman/MTA/Manual.py:123
+#, fuzzy
msgid ""
"\n"
"To finish removing your mailing list, you must edit your /etc/aliases (or\n"
@@ -8223,14 +8395,17 @@ msgstr ""
"## %(listname)s mailing list"
#: Mailman/MTA/Manual.py:142
+#, fuzzy
msgid "Mailing list removal request for list %(listname)s"
msgstr "طلب إزالة القائمة البريدية %(listname)s"
#: Mailman/MTA/Postfix.py:442
+#, fuzzy
msgid "checking permissions on %(file)s"
msgstr "تفحص أذونات الملف %(file)s"
#: Mailman/MTA/Postfix.py:452
+#, fuzzy
msgid "%(file)s permissions must be 0664 (got %(octmode)s)"
msgstr "أذونات الملف %(file)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
@@ -8244,35 +8419,43 @@ msgid "(fixing)"
msgstr "إصلاح"
#: Mailman/MTA/Postfix.py:470
+#, fuzzy
msgid "checking ownership of %(dbfile)s"
msgstr "التحقق من ملكية الملف %(dbfile)s"
#: Mailman/MTA/Postfix.py:478
+#, fuzzy
msgid "%(dbfile)s owned by %(owner)s (must be owned by %(user)s"
msgstr ""
"الملف %(dbfile)s مملوك من قبل %(owner)s (ويجب أن يكون مملوكاً من قبل %(user)s"
#: Mailman/MTA/Postfix.py:491
+#, fuzzy
msgid "%(dbfile)s permissions must be 0664 (got %(octmode)s)"
msgstr "أذونات الملف %(dbfile)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: Mailman/MailList.py:219
+#, fuzzy
msgid "Your confirmation is required to join the %(listname)s mailing list"
msgstr "تأكيدك مطلوب للانضمام إلى القائمة البريدية %(listname)s ."
#: Mailman/MailList.py:230
+#, fuzzy
msgid "Your confirmation is required to leave the %(listname)s mailing list"
msgstr "تأكيدك مطلوب لترك القائمة البريدية %(listname)s ."
#: Mailman/MailList.py:999 Mailman/MailList.py:1492
+#, fuzzy
msgid " from %(remote)s"
msgstr "من قبل %(remote)s"
#: Mailman/MailList.py:1043
+#, fuzzy
msgid "subscriptions to %(realname)s require moderator approval"
msgstr "تحتاج الاشتراكات في %(realname)s موافقة المنظم"
#: Mailman/MailList.py:1125 bin/add_members:299
+#, fuzzy
msgid "%(realname)s subscription notification"
msgstr "تنبيه اشتراك %(realname)s"
@@ -8281,6 +8464,7 @@ msgid "unsubscriptions require moderator approval"
msgstr "يحتاج إلغاء الاشتراك إلى موافقة المدير"
#: Mailman/MailList.py:1166
+#, fuzzy
msgid "%(realname)s unsubscribe notification"
msgstr "تنبيه إلغاء اشتراك %(realname)s"
@@ -8300,6 +8484,7 @@ msgid "via web confirmation"
msgstr "مجموعة محارف تأكيد سيئة"
#: Mailman/MailList.py:1396
+#, fuzzy
msgid "subscriptions to %(name)s require administrator approval"
msgstr "تحتاج الاشتراكات في %(name)s إلى موافقة المدير"
@@ -8318,6 +8503,7 @@ msgid "Last autoresponse notification for today"
msgstr "آخر تنبيه رد تلقائي لهذا اليوم"
#: Mailman/Queue/BounceRunner.py:360
+#, fuzzy
msgid ""
"The attached message was received as a bounce, but either the bounce format\n"
"was not recognized, or no member addresses could be extracted from it. "
@@ -8402,6 +8588,7 @@ msgid "Original message suppressed by Mailman site configuration\n"
msgstr ""
#: Mailman/htmlformat.py:675
+#, fuzzy
msgid "Delivered by Mailman version %(version)s"
msgstr "تم توصيلها من قبل برنامج ميلمان الاصدار %(version)s"
@@ -8490,6 +8677,7 @@ msgid "Server Local Time"
msgstr "الوقت المحلي للخادم"
#: Mailman/i18n.py:180
+#, fuzzy
msgid ""
"%(wday)s %(mon)s %(day)2i %(hh)02i:%(mm)02i:%(ss)02i %(tzname)s %(year)04i"
msgstr ""
@@ -8601,6 +8789,7 @@ msgstr ""
"files can be `-'.\n"
#: bin/add_members:162 bin/add_members:172
+#, fuzzy
msgid "Already a member: %(member)s"
msgstr "عضو مسجل أصلاً: %(member)s"
@@ -8609,10 +8798,12 @@ msgid "Bad/Invalid email address: blank line"
msgstr "عنوان إلكتروني سيء/غير صالح: سطر فارغ"
#: bin/add_members:180
+#, fuzzy
msgid "Bad/Invalid email address: %(member)s"
msgstr "عنوان إلكتروني سيء/غير صالح: %(member)s"
#: bin/add_members:182
+#, fuzzy
msgid "Hostile address (illegal characters): %(member)s"
msgstr "عنوان إلكتروني عدائي )أحرف غير صالحة(: %(member)s"
@@ -8622,16 +8813,19 @@ msgid "Invited: %(member)s"
msgstr "تم تسجيله: %(member)s"
#: bin/add_members:187
+#, fuzzy
msgid "Subscribed: %(member)s"
msgstr "تم تسجيله: %(member)s"
#: bin/add_members:237
+#, fuzzy
msgid "Bad argument to -w/--welcome-msg: %(arg)s"
msgstr "معاملات سيئة لـ -w/--welcome-msg : %(arg)s"
#: bin/add_members:244
+#, fuzzy
msgid "Bad argument to -a/--admin-notify: %(arg)s"
-msgstr ""
+msgstr "معاملات سيئة لـ -w/--welcome-msg : %(arg)s"
#: bin/add_members:252
msgid "Cannot read both digest and normal members from standard input."
@@ -8644,8 +8838,9 @@ msgstr ""
#: bin/add_members:261 bin/config_list:110 bin/export.py:271 bin/find_member:97
#: bin/inject:91 bin/list_admins:90 bin/list_members:252 bin/sync_members:222
#: cron/bumpdigests:86
+#, fuzzy
msgid "No such list: %(listname)s"
-msgstr ""
+msgstr "لا يوجد قائمة بالإسم %(safelistname)s"
#: bin/add_members:285 bin/change_pw:159 bin/check_db:114 bin/discard:83
#: bin/sync_members:244 bin/update:302 bin/update:323 bin/update:577
@@ -8707,10 +8902,11 @@ msgid "listname is required"
msgstr ""
#: bin/arch:143 bin/change_pw:107 bin/config_list:257
+#, fuzzy
msgid ""
"No such list \"%(listname)s\"\n"
"%(e)s"
-msgstr ""
+msgstr "لا يوجد قائمة بالإسم %(safelistname)s"
#: bin/arch:168
msgid "Cannot open mbox file %(mbox)s: %(msg)s"
@@ -8794,20 +8990,23 @@ msgid ""
msgstr ""
#: bin/change_pw:145
+#, fuzzy
msgid "Bad arguments: %(strargs)s"
-msgstr ""
+msgstr "معامل أمر غير جيد: %(arg)s"
#: bin/change_pw:149
msgid "Empty list passwords are not allowed"
msgstr ""
#: bin/change_pw:181
+#, fuzzy
msgid "New %(listname)s password: %(notifypassword)s"
-msgstr ""
+msgstr "كلمة السر الابتدائية للقائمة:"
#: bin/change_pw:190
+#, fuzzy
msgid "Your new %(listname)s list password"
-msgstr ""
+msgstr "كلمة السر الابتدائية للقائمة:"
#: bin/change_pw:191
msgid ""
@@ -8885,40 +9084,47 @@ msgid ""
msgstr ""
#: bin/check_perms:110
+#, fuzzy
msgid " checking gid and mode for %(path)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:122
msgid "%(path)s bad group (has: %(groupname)s, expected %(MAILMAN_GROUP)s)"
msgstr ""
#: bin/check_perms:151
+#, fuzzy
msgid "directory permissions must be %(octperms)s: %(path)s"
-msgstr ""
+msgstr "أذونات الملف %(dbfile)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: bin/check_perms:160
+#, fuzzy
msgid "source perms must be %(octperms)s: %(path)s"
-msgstr ""
+msgstr "أذونات الملف %(dbfile)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: bin/check_perms:171
+#, fuzzy
msgid "article db files must be %(octperms)s: %(path)s"
-msgstr ""
+msgstr "أذونات الملف %(dbfile)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: bin/check_perms:183
+#, fuzzy
msgid "checking mode for %(prefix)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:193
msgid "WARNING: directory does not exist: %(d)s"
msgstr ""
#: bin/check_perms:197
+#, fuzzy
msgid "directory must be at least 02775: %(d)s"
-msgstr ""
+msgstr "أذونات الملف %(file)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: bin/check_perms:209
+#, fuzzy
msgid "checking perms on %(private)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:214
msgid "%(private)s must not be other-readable"
@@ -8946,40 +9152,46 @@ msgid "checking cgi-bin permissions"
msgstr ""
#: bin/check_perms:278
+#, fuzzy
msgid " checking set-gid for %(path)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:282
msgid "%(path)s must be set-gid"
msgstr ""
#: bin/check_perms:292
+#, fuzzy
msgid "checking set-gid for %(wrapper)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:296
msgid "%(wrapper)s must be set-gid"
msgstr ""
#: bin/check_perms:306
+#, fuzzy
msgid "checking permissions on %(pwfile)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:315
+#, fuzzy
msgid "%(pwfile)s permissions must be exactly 0640 (got %(octmode)s)"
-msgstr ""
+msgstr "أذونات الملف %(file)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: bin/check_perms:340
msgid "checking permissions on list data"
msgstr ""
#: bin/check_perms:348
+#, fuzzy
msgid " checking permissions on: %(path)s"
-msgstr ""
+msgstr "تفحص أذونات الملف %(file)s"
#: bin/check_perms:356
+#, fuzzy
msgid "file permissions must be at least 660: %(path)s"
-msgstr ""
+msgstr "أذونات الملف %(file)s يجب أن تكون 0664 (وهي الآن %(octmode)s)"
#: bin/check_perms:401
msgid "No problems found"
@@ -9032,8 +9244,9 @@ msgid "Unix-From line changed: %(lineno)d"
msgstr ""
#: bin/cleanarch:111
+#, fuzzy
msgid "Bad status number: %(arg)s"
-msgstr ""
+msgstr "معامل أمر غير جيد: %(arg)s"
#: bin/cleanarch:167
msgid "%(messages)d messages found"
@@ -9130,14 +9343,16 @@ msgid " original address removed:"
msgstr ""
#: bin/clone_member:202
+#, fuzzy
msgid "Not a valid email address: %(toaddr)s"
-msgstr ""
+msgstr "عنوان إلكتروني سيء/غير صالح: %(member)s"
#: bin/clone_member:215
+#, fuzzy
msgid ""
"Error opening list \"%(listname)s\", skipping.\n"
"%(e)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/config_list:20
msgid ""
@@ -9222,12 +9437,14 @@ msgid "Non-standard property restored: %(k)s"
msgstr ""
#: bin/config_list:288
+#, fuzzy
msgid "Invalid value for property: %(k)s"
-msgstr ""
+msgstr "قيمة غير صالحة للمتحول: %(property)s"
#: bin/config_list:291
+#, fuzzy
msgid "Bad email address for option %(k)s: %(v)s"
-msgstr ""
+msgstr "عنوان إلكتروني سيء للخيار%(property)s : %(error)s"
#: bin/config_list:348
msgid "Only one of -i or -o is allowed"
@@ -9274,16 +9491,19 @@ msgid ""
msgstr ""
#: bin/discard:94
+#, fuzzy
msgid "Ignoring non-held message: %(f)s"
-msgstr ""
+msgstr "تجاهل التعديلات لعنصر المحذوف: %(user)s"
#: bin/discard:100
+#, fuzzy
msgid "Ignoring held msg w/bad id: %(f)s"
-msgstr ""
+msgstr "تجاهل التعديلات لعنصر المحذوف: %(user)s"
#: bin/discard:112
+#, fuzzy
msgid "Discarded held msg #%(id)s for list %(listname)s"
-msgstr ""
+msgstr "اشترك في القائمة %(listname)s"
#: bin/dumpdb:19
msgid ""
@@ -9327,8 +9547,9 @@ msgid "No filename given."
msgstr ""
#: bin/dumpdb:108
+#, fuzzy
msgid "Bad arguments: %(pargs)s"
-msgstr ""
+msgstr "معامل أمر غير جيد: %(arg)s"
#: bin/dumpdb:118
msgid "Please specify either -p or -m."
@@ -9578,8 +9799,9 @@ msgid ""
msgstr ""
#: bin/list_admins:97
+#, fuzzy
msgid "List: %(listname)s, \tOwners: %(owners)s"
-msgstr ""
+msgstr "مالكي القائمة: %(owneraddr)s"
#: bin/list_lists:19
msgid ""
@@ -9684,12 +9906,14 @@ msgid ""
msgstr ""
#: bin/list_members:198
+#, fuzzy
msgid "Bad --nomail option: %(why)s"
-msgstr ""
+msgstr "معامل دفعات غير جيد: %(arg)s"
#: bin/list_members:209
+#, fuzzy
msgid "Bad --digest option: %(kind)s"
-msgstr ""
+msgstr "معامل دفعات غير جيد: %(arg)s"
#: bin/list_members:213 bin/list_members:217 bin/list_members:221
#: bin/list_members:225
@@ -9873,8 +10097,9 @@ msgid ""
msgstr ""
#: bin/mailmanctl:280 cron/mailpasswds:119
+#, fuzzy
msgid "Site list is missing: %(sitelistname)s"
-msgstr ""
+msgstr "القائمة موجودة أصلاً: %(safelistname)s"
#: bin/mailmanctl:305
msgid "Run this program as root or as the %(name)s user, or use -u."
@@ -9885,8 +10110,9 @@ msgid "No command given."
msgstr ""
#: bin/mailmanctl:339
+#, fuzzy
msgid "Bad command: %(command)s"
-msgstr ""
+msgstr "أمر set غير جيد: %(subcmd)s"
#: bin/mailmanctl:344
msgid "Warning! You may encounter permission problems."
@@ -10100,8 +10326,9 @@ msgid ""
msgstr ""
#: bin/newlist:162
+#, fuzzy
msgid "Unknown language: %(lang)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/newlist:167
msgid "Enter the name of the list: "
@@ -10112,8 +10339,9 @@ msgid "Enter the email of the person running the list: "
msgstr ""
#: bin/newlist:193
+#, fuzzy
msgid "Initial %(listname)s password: "
-msgstr ""
+msgstr "كلمة السر الابتدائية للقائمة:"
#: bin/newlist:197
msgid "The list password cannot be empty"
@@ -10121,8 +10349,8 @@ msgstr ""
#: bin/newlist:220
msgid ""
-" - owner addresses need to be fully-qualified names like \"owner@example.com"
-"\", not just \"owner\"."
+" - owner addresses need to be fully-qualified names like \"owner@example."
+"com\", not just \"owner\"."
msgstr ""
#: bin/newlist:244
@@ -10290,16 +10518,19 @@ msgid "Could not open file for reading: %(filename)s."
msgstr ""
#: bin/remove_members:163
+#, fuzzy
msgid "Error opening list %(listname)s... skipping."
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/remove_members:173
+#, fuzzy
msgid "No such member: %(addr)s"
-msgstr ""
+msgstr "لا يوجد مثل هذ العضو: %(safeuser)s"
#: bin/remove_members:178
+#, fuzzy
msgid "User `%(addr)s' removed from list: %(listname)s."
-msgstr ""
+msgstr "تمت إزالة %(member)s من القائمة %(listname)s.\n"
#: bin/reset_pw.py:21
msgid ""
@@ -10322,8 +10553,9 @@ msgid ""
msgstr ""
#: bin/reset_pw.py:77
+#, fuzzy
msgid "Changing passwords for list: %(listname)s"
-msgstr ""
+msgstr "طلب إزالة القائمة البريدية %(listname)s"
#: bin/reset_pw.py:83
msgid "New password for member %(member)40s: %(randompw)s"
@@ -10360,8 +10592,9 @@ msgid "%(listname)s %(msg)s not found as %(filename)s"
msgstr ""
#: bin/rmlist:105
+#, fuzzy
msgid "No such list (or list already deleted): %(listname)s"
-msgstr ""
+msgstr "لا يوجد قائمة بالإسم %(safelistname)s"
#: bin/rmlist:108
msgid "No such list: %(listname)s. Removing its residual archives."
@@ -10495,8 +10728,9 @@ msgid "No argument to -f given"
msgstr ""
#: bin/sync_members:172
+#, fuzzy
msgid "Illegal option: %(opt)s"
-msgstr ""
+msgstr "اسم قائمة غير نظامي: %(s)s"
#: bin/sync_members:178
msgid "No listname given"
@@ -10631,8 +10865,9 @@ msgid ""
msgstr ""
#: bin/update:107
+#, fuzzy
msgid "Fixing language templates: %(listname)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/update:196 bin/update:711
msgid "WARNING: could not acquire lock for list: %(listname)s"
@@ -10786,8 +11021,9 @@ msgid "done"
msgstr ""
#: bin/update:691
+#, fuzzy
msgid "Updating mailing list: %(listname)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/update:694
msgid "Updating Usenet watermarks"
@@ -10992,16 +11228,18 @@ msgid ""
msgstr ""
#: bin/withlist:175
+#, fuzzy
msgid "Unlocking (but not saving) list: %(listname)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/withlist:179
msgid "Finalizing"
msgstr ""
#: bin/withlist:188
+#, fuzzy
msgid "Loading list %(listname)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/withlist:190
msgid "(locked)"
@@ -11012,8 +11250,9 @@ msgid "(unlocked)"
msgstr ""
#: bin/withlist:197
+#, fuzzy
msgid "Unknown list: %(listname)s"
-msgstr ""
+msgstr "قائمتك البريدية الجديدة: %(listname)s"
#: bin/withlist:237
msgid "No list name supplied."
@@ -11220,8 +11459,9 @@ msgid "Password // URL"
msgstr ""
#: cron/mailpasswds:222
+#, fuzzy
msgid "%(host)s mailing list memberships reminder"
-msgstr ""
+msgstr "مذكر القائمة البريدية %(listfullname)s"
#: cron/nightly_gzip:19
msgid ""
@@ -11497,9 +11737,6 @@ msgstr ""
#~ "تم اشتراك %(member)s بنجاح في القائمة %(listname)s.\n"
#~ "\n"
-#~ msgid "%(member)s has been removed from %(listname)s.\n"
-#~ msgstr "تمت إزالة %(member)s من القائمة %(listname)s.\n"
-
#~ msgid ""
#~ "\n"
#~ "