e7a395
diff --git a/Mailman/MTA/Manual.py b/Mailman/MTA/Manual.py
e7a395
index 92e1c03..0abde2e 100644
e7a395
--- a/Mailman/MTA/Manual.py
e7a395
+++ b/Mailman/MTA/Manual.py
e7a395
@@ -25,7 +25,7 @@ from Mailman import mm_cfg
e7a395
 from Mailman import Message
e7a395
 from Mailman import Utils
e7a395
 from Mailman.Queue.sbcache import get_switchboard
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import _, C_
e7a395
 from Mailman.MTA.Utils import makealiases
e7a395
 
e7a395
 try:
e7a395
@@ -74,12 +74,12 @@ Here are the entries for the /etc/aliases file:
e7a395
         outfp = sfp
e7a395
     else:
e7a395
         if not quiet:
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
 To finish creating your mailing list, you must edit your /etc/aliases (or
e7a395
 equivalent) file by adding the following lines, and possibly running the
e7a395
 `newaliases' program:
e7a395
 """)
e7a395
-        print _("""\
e7a395
+        print C_("""\
e7a395
 ## %(listname)s mailing list""")
e7a395
         outfp = sys.stdout
e7a395
     # Common path
e7a395
@@ -120,7 +120,7 @@ Here are the entries in the /etc/aliases file that should be removed:
e7a395
 """)
e7a395
         outfp = sfp
e7a395
     else:
e7a395
-        print _("""
e7a395
+        print C_("""
e7a395
 To finish removing your mailing list, you must edit your /etc/aliases (or
e7a395
 equivalent) file by removing the following lines, and possibly running the
e7a395
 `newaliases' program:
e7a395
diff --git a/Mailman/MTA/Postfix.py b/Mailman/MTA/Postfix.py
e7a395
index 8506b9b..d7a2d06 100644
e7a395
--- a/Mailman/MTA/Postfix.py
e7a395
+++ b/Mailman/MTA/Postfix.py
e7a395
@@ -27,7 +27,7 @@ from stat import *
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman import Utils
e7a395
 from Mailman import LockFile
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 from Mailman.MTA.Utils import makealiases
e7a395
 from Mailman.Logging.Syslog import syslog
e7a395
 
e7a395
@@ -317,7 +317,7 @@ def checkperms(state):
e7a395
     targetmode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
e7a395
     for file in ALIASFILE, VIRTFILE:
e7a395
         if state.VERBOSE:
e7a395
-            print _('checking permissions on %(file)s')
e7a395
+            print C_('checking permissions on %(file)s')
e7a395
         stat = None
e7a395
         try:
e7a395
             stat = os.stat(file)
e7a395
@@ -327,9 +327,9 @@ def checkperms(state):
e7a395
         if stat and (stat[ST_MODE] & targetmode) <> targetmode:
e7a395
             state.ERRORS += 1
e7a395
             octmode = oct(stat[ST_MODE])
e7a395
-            print _('%(file)s permissions must be 066x (got %(octmode)s)'),
e7a395
+            print C_('%(file)s permissions must be 066x (got %(octmode)s)'),
e7a395
             if state.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(file, stat[ST_MODE] | targetmode)
e7a395
             else:
e7a395
                 print
e7a395
@@ -345,7 +345,7 @@ def checkperms(state):
e7a395
                 raise
e7a395
             continue
e7a395
         if state.VERBOSE:
e7a395
-            print _('checking ownership of %(dbfile)s')
e7a395
+            print C_('checking ownership of %(dbfile)s')
e7a395
         user = mm_cfg.MAILMAN_USER
e7a395
         ownerok = stat[ST_UID] == pwd.getpwnam(user)[2]
e7a395
         if not ownerok:
e7a395
@@ -353,10 +353,10 @@ def checkperms(state):
e7a395
                 owner = pwd.getpwuid(stat[ST_UID])[0]
e7a395
             except KeyError:
e7a395
                 owner = 'uid %d' % stat[ST_UID]
e7a395
-            print _('%(dbfile)s owned by %(owner)s (must be owned by %(user)s'),
e7a395
+            print C_('%(dbfile)s owned by %(owner)s (must be owned by %(user)s'),
e7a395
             state.ERRORS += 1
e7a395
             if state.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 uid = pwd.getpwnam(user)[2]
e7a395
                 gid = grp.getgrnam(mm_cfg.MAILMAN_GROUP)[2]
e7a395
                 os.chown(dbfile, uid, gid)
e7a395
diff --git a/Mailman/i18n.py b/Mailman/i18n.py
e7a395
index 5f926b7..0cfdb99 100644
e7a395
--- a/Mailman/i18n.py
e7a395
+++ b/Mailman/i18n.py
e7a395
@@ -15,6 +15,7 @@
e7a395
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
e7a395
 # USA.
e7a395
 
e7a395
+import locale
e7a395
 import sys
e7a395
 import time
e7a395
 import gettext
e7a395
@@ -25,6 +26,15 @@ from Mailman.SafeDict import SafeDict
e7a395
 
e7a395
 _translation = None
e7a395
 
e7a395
+
e7a395
+def _get_ctype_charset():
e7a395
+    old = locale.setlocale(locale.LC_CTYPE, '')
e7a395
+    charset = locale.nl_langinfo(locale.CODESET)
e7a395
+    locale.setlocale(locale.LC_CTYPE, old)
e7a395
+    return charset
e7a395
+
e7a395
+_ctype_charset = _get_ctype_charset()
e7a395
+
e7a395
 
e7a395
 
e7a395
 def set_language(language=None):
e7a395
@@ -54,7 +64,7 @@ if _translation is None:
e7a395
 
e7a395
 
e7a395
 
e7a395
-def _(s):
e7a395
+def _(s, frame = 1):
e7a395
     if s == '':
e7a395
         return s
e7a395
     assert s
e7a395
@@ -70,7 +80,7 @@ def _(s):
e7a395
     # original string is 1) locals dictionary, 2) globals dictionary.
e7a395
     #
e7a395
     # First, get the frame of the caller
e7a395
-    frame = sys._getframe(1)
e7a395
+    frame = sys._getframe(frame)
e7a395
     # A `safe' dictionary is used so we won't get an exception if there's a
e7a395
     # missing key in the dictionary.
e7a395
     dict = SafeDict(frame.f_globals.copy())
e7a395
@@ -95,6 +105,19 @@ def _(s):
e7a395
 
e7a395
 
e7a395
 
e7a395
+def tolocale(s):
e7a395
+    global _ctype_charset
e7a395
+    if isinstance(s, UnicodeType):
e7a395
+        return s
e7a395
+    source = _translation.charset ()
e7a395
+    if not source:
e7a395
+        return s
e7a395
+    return unicode(s, source, 'replace').encode(_ctype_charset, 'replace')
e7a395
+
e7a395
+def C_(s):
e7a395
+    return tolocale(_(s, 2))
e7a395
+    
e7a395
+
e7a395
 def ctime(date):
e7a395
     # Don't make these module globals since we have to do runtime translation
e7a395
     # of the strings anyway.
e7a395
diff --git a/bin/add_members b/bin/add_members
e7a395
index 77f11af..763ee16 100755
e7a395
--- a/bin/add_members
e7a395
+++ b/bin/add_members
e7a395
@@ -81,6 +81,7 @@ from Mailman import mm_cfg
e7a395
 from Mailman import i18n
e7a395
 
e7a395
 _ = i18n._
e7a395
+C_ = i18n.C_
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -89,7 +90,7 @@ def usage(status, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(status)
e7a395
@@ -116,7 +117,7 @@ class Tee:
e7a395
         self.__outfp = outfp
e7a395
 
e7a395
     def write(self, msg):
e7a395
-        sys.stdout.write(msg)
e7a395
+        sys.stdout.write(i18n.tolocale(msg))
e7a395
         self.__outfp.write(msg)
e7a395
 
e7a395
 
e7a395
@@ -191,26 +192,26 @@ def main():
e7a395
             elif arg.lower()[0] == 'n':
e7a395
                 send_welcome_msg = 0
e7a395
             else:
e7a395
-                usage(1, _('Bad argument to -w/--welcome-msg: %(arg)s'))
e7a395
+                usage(1, C_('Bad argument to -w/--welcome-msg: %(arg)s'))
e7a395
         elif opt in ('-a', '--admin-notify'):
e7a395
             if arg.lower()[0] == 'y':
e7a395
                 admin_notif = 1
e7a395
             elif arg.lower()[0] == 'n':
e7a395
                 admin_notif = 0
e7a395
             else:
e7a395
-                usage(1, _('Bad argument to -a/--admin-notify: %(arg)s'))
e7a395
+                usage(1, C_('Bad argument to -a/--admin-notify: %(arg)s'))
e7a395
 
e7a395
     if dfile is None and nfile is None:
e7a395
         usage(1)
e7a395
 
e7a395
     if dfile == "-" and nfile == "-":
e7a395
-        usage(1, _('Cannot read both digest and normal members '
e7a395
-                   'from standard input.'))
e7a395
+        usage(1, C_('Cannot read both digest and normal members '
e7a395
+                    'from standard input.'))
e7a395
 
e7a395
     try:
e7a395
         mlist = MailList.MailList(listname)
e7a395
     except Errors.MMUnknownListError:
e7a395
-        usage(1, _('No such list: %(listname)s'))
e7a395
+        usage(1, C_('No such list: %(listname)s'))
e7a395
 
e7a395
     # Set up defaults
e7a395
     if send_welcome_msg is None:
e7a395
@@ -230,7 +231,7 @@ def main():
e7a395
             nmembers = readfile(nfile)
e7a395
 
e7a395
         if not dmembers and not nmembers:
e7a395
-            usage(0, _('Nothing to do.'))
e7a395
+            usage(0, C_('Nothing to do.'))
e7a395
 
e7a395
         s = StringIO()
e7a395
         i18n.set_language(mlist.preferred_language)
e7a395
diff --git a/bin/arch b/bin/arch
e7a395
index a98ae2a..8fdca6a 100644
e7a395
--- a/bin/arch
e7a395
+++ b/bin/arch
e7a395
@@ -70,7 +70,7 @@ from Mailman.Archiver.HyperArch import HyperArchive
e7a395
 from Mailman.LockFile import LockFile
e7a395
 from Mailman import i18n
e7a395
 
e7a395
-_ = i18n._
e7a395
+C_ = i18n.C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
e7a395
@@ -82,7 +82,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -122,7 +122,7 @@ def main():
e7a395
 
e7a395
     # grok arguments
e7a395
     if len(args) < 1:
e7a395
-        usage(1, _('listname is required'))
e7a395
+        usage(1, C_('listname is required'))
e7a395
     listname = args[0].lower().strip()
e7a395
 
e7a395
     if len(args) < 2:
e7a395
@@ -140,7 +140,7 @@ def main():
e7a395
         try:
e7a395
             mlist = MailList(listname)
e7a395
         except Errors.MMListError, e:
e7a395
-            usage(2, _('No such list "%(listname)s"\n%(e)s'))
e7a395
+            usage(2, C_('No such list "%(listname)s"\n%(e)s'))
e7a395
         if mbox is None:
e7a395
             mbox = mlist.ArchiveFileName()
e7a395
 
e7a395
@@ -165,7 +165,7 @@ def main():
e7a395
         try:
e7a395
             fp = open(mbox)
e7a395
         except IOError, msg:
e7a395
-            usage(3, _('Cannot open mbox file %(mbox)s: %(msg)s'))
e7a395
+            usage(3, C_('Cannot open mbox file %(mbox)s: %(msg)s'))
e7a395
         # Maybe wipe the old archives
e7a395
         if wipe:
e7a395
             if mlist.scrub_nondigest:
e7a395
diff --git a/bin/b4b5-archfix b/bin/b4b5-archfix
e7a395
index 1bdaeda..22d8839 100644
e7a395
--- a/bin/b4b5-archfix
e7a395
+++ b/bin/b4b5-archfix
e7a395
@@ -44,7 +44,7 @@ import cPickle as pickle
e7a395
 
e7a395
 # Required to get the right classes for unpickling
e7a395
 import paths
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 
e7a395
@@ -55,7 +55,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
diff --git a/bin/change_pw b/bin/change_pw
e7a395
index 67d5639..35be13d 100644
e7a395
--- a/bin/change_pw
e7a395
+++ b/bin/change_pw
e7a395
@@ -77,6 +77,7 @@ from Mailman import Message
e7a395
 from Mailman import i18n
e7a395
 
e7a395
 _ = i18n._
e7a395
+C_ = i18n.C_
e7a395
 
e7a395
 SPACE = ' '
e7a395
 
e7a395
@@ -87,7 +88,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -103,7 +104,7 @@ def openlist(listname):
e7a395
         try:
e7a395
             mlist = MailList.MailList(listname, lock=0)
e7a395
         except Errors.MMListError, e:
e7a395
-            usage(1, _('No such list "%(listname)s"\n%(e)s'))
e7a395
+            usage(1, C_('No such list "%(listname)s"\n%(e)s'))
e7a395
         _listcache[listname] = mlist
e7a395
     return mlist
e7a395
 
e7a395
@@ -155,7 +156,7 @@ def main():
e7a395
                 listnames[name] = 1
e7a395
 
e7a395
     if not listnames:
e7a395
-        print >> sys.stderr, _('Nothing to do.')
e7a395
+        print >> sys.stderr, C_('Nothing to do.')
e7a395
         sys.exit(0)
e7a395
 
e7a395
     # Set the password on the lists
e7a395
@@ -177,7 +178,7 @@ def main():
e7a395
             mlist.Unlock()
e7a395
 
e7a395
         # Notification
e7a395
-        print _('New %(listname)s password: %(notifypassword)s')
e7a395
+        print C_('New %(listname)s password: %(notifypassword)s')
e7a395
         if not quiet:
e7a395
             otrans = i18n.get_translation()
e7a395
             i18n.set_language(mlist.preferred_language)
e7a395
diff --git a/bin/check_db b/bin/check_db
e7a395
index b1157bc..40fa0a2 100755
e7a395
--- a/bin/check_db
e7a395
+++ b/bin/check_db
e7a395
@@ -59,7 +59,7 @@ import paths
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman import Utils
e7a395
 from Mailman.MailList import MailList
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 
e7a395
@@ -70,7 +70,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -111,12 +111,12 @@ def main():
e7a395
 
e7a395
     listnames = [n.lower().strip() for n in listnames]
e7a395
     if not listnames:
e7a395
-        print _('Nothing to do.')
e7a395
+        print C_('Nothing to do.')
e7a395
         sys.exit(0)
e7a395
 
e7a395
     for listname in listnames:
e7a395
         if not Utils.list_exists(listname):
e7a395
-            print _('No list named:'), listname
e7a395
+            print C_('No list named:'), listname
e7a395
             continue
e7a395
         mlist = MailList(listname, lock=0)
e7a395
         pfile = os.path.join(mlist.fullpath(), 'config.pck')
e7a395
@@ -125,7 +125,7 @@ def main():
e7a395
         dlast = dfile + '.last'
e7a395
 
e7a395
         if verbose:
e7a395
-            print _('List:'), listname
e7a395
+            print C_('List:'), listname
e7a395
 
e7a395
         for file in (pfile, plast, dfile, dlast):
e7a395
             status = 0
e7a395
@@ -145,7 +145,7 @@ def main():
e7a395
                 else:
e7a395
                     print '    %s: %s' % (file, status)
e7a395
             elif verbose:
e7a395
-                print _('   %(file)s: okay')
e7a395
+                print C_('   %(file)s: okay')
e7a395
 
e7a395
 
e7a395
 
e7a395
diff --git a/bin/check_perms b/bin/check_perms
e7a395
index 1f45f84..f0c6795 100755
e7a395
--- a/bin/check_perms
e7a395
+++ b/bin/check_perms
e7a395
@@ -45,7 +45,7 @@ directory.  You must run this from the installation directory instead.
e7a395
     raise
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman.mm_cfg import MAILMAN_USER, MAILMAN_GROUP
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 # Let KeyErrors percolate
e7a395
 MAILMAN_GID = grp.getgrnam(MAILMAN_GROUP)[2]
e7a395
@@ -107,7 +107,7 @@ def checkwalk(arg, dirname, names):
e7a395
     for name in names:
e7a395
         path = os.path.join(dirname, name)
e7a395
         if arg.VERBOSE:
e7a395
-            print _('    checking gid and mode for %(path)s')
e7a395
+            print C_('    checking gid and mode for %(path)s')
e7a395
         try:
e7a395
             mode, gid = statgidmode(path)
e7a395
         except OSError, e:
e7a395
@@ -119,10 +119,10 @@ def checkwalk(arg, dirname, names):
e7a395
             except KeyError:
e7a395
                 groupname = '<anon gid %d>' % gid
e7a395
             arg.ERRORS += 1
e7a395
-            print _('%(path)s bad group (has: %(groupname)s, '
e7a395
-                    'expected %(MAILMAN_GROUP)s)'),
e7a395
+            print C_('%(path)s bad group (has: %(groupname)s, '
e7a395
+                     'expected %(MAILMAN_GROUP)s)'),
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chown(path, -1, MAILMAN_GID)
e7a395
             else:
e7a395
                 print
e7a395
@@ -148,19 +148,19 @@ def checkwalk(arg, dirname, names):
e7a395
         octperms = oct(targetperms)
e7a395
         if S_ISDIR(mode) and (mode & targetperms) <> targetperms:
e7a395
             arg.ERRORS += 1
e7a395
-            print _('directory permissions must be %(octperms)s: %(path)s'),
e7a395
+            print C_('directory permissions must be %(octperms)s: %(path)s'),
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(path, mode | targetperms)
e7a395
             else:
e7a395
                 print
e7a395
         elif os.path.splitext(path)[1] in ('.py', '.pyc', '.pyo'):
e7a395
             octperms = oct(PYFILEPERMS)
e7a395
             if mode & PYFILEPERMS <> PYFILEPERMS:
e7a395
-                print _('source perms must be %(octperms)s: %(path)s'),
e7a395
+                print C_('source perms must be %(octperms)s: %(path)s'),
e7a395
                 arg.ERRORS += 1
e7a395
                 if STATE.FIX:
e7a395
-                    print _('(fixing)')
e7a395
+                    print C_('(fixing)')
e7a395
                     os.chmod(path, mode | PYFILEPERMS)
e7a395
                 else:
e7a395
                     print
e7a395
@@ -168,10 +168,10 @@ def checkwalk(arg, dirname, names):
e7a395
             # Article files must be group writeable
e7a395
             octperms = oct(ARTICLEFILEPERMS)
e7a395
             if mode & ARTICLEFILEPERMS <> ARTICLEFILEPERMS:
e7a395
-                print _('article db files must be %(octperms)s: %(path)s'),
e7a395
+                print C_('article db files must be %(octperms)s: %(path)s'),
e7a395
                 arg.ERRORS += 1
e7a395
                 if STATE.FIX:
e7a395
-                    print _('(fixing)')
e7a395
+                    print C_('(fixing)')
e7a395
                     os.chmod(path, mode | ARTICLEFILEPERMS)
e7a395
                 else:
e7a395
                     print
e7a395
@@ -180,7 +180,7 @@ def checkall():
e7a395
     # first check PREFIX
e7a395
     if STATE.VERBOSE:
e7a395
         prefix = mm_cfg.PREFIX
e7a395
-        print _('checking mode for %(prefix)s')
e7a395
+        print C_('checking mode for %(prefix)s')
e7a395
     dirs = {}
e7a395
     for d in (mm_cfg.PREFIX, mm_cfg.EXEC_PREFIX, mm_cfg.VAR_PREFIX,
e7a395
               mm_cfg.CONFIG_DIR, mm_cfg.DATA_DIR, mm_cfg.LOCK_DIR,
e7a395
@@ -191,13 +191,13 @@ def checkall():
e7a395
             mode = statmode(d)
e7a395
         except OSError, e:
e7a395
             if e.errno <> errno.ENOENT: raise
e7a395
-            print _('WARNING: directory does not exist: %(d)s')
e7a395
+            print C_('WARNING: directory does not exist: %(d)s')
e7a395
             continue
e7a395
         if (mode & DIRPERMS) <> DIRPERMS:
e7a395
             STATE.ERRORS += 1
e7a395
-            print _('directory must be at least 02775: %(d)s'),
e7a395
+            print C_('directory must be at least 02775: %(d)s'),
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(d, mode | DIRPERMS)
e7a395
             else:
e7a395
                 print
e7a395
@@ -207,14 +207,14 @@ def checkall():
e7a395
 def checkarchives():
e7a395
     private = mm_cfg.PRIVATE_ARCHIVE_FILE_DIR
e7a395
     if STATE.VERBOSE:
e7a395
-        print _('checking perms on %(private)s')
e7a395
+        print C_('checking perms on %(private)s')
e7a395
     # private archives must not be other readable
e7a395
     mode = statmode(private)
e7a395
     if mode & S_IROTH:
e7a395
         STATE.ERRORS += 1
e7a395
-        print _('%(private)s must not be other-readable'),
e7a395
+        print C_('%(private)s must not be other-readable'),
e7a395
         if STATE.FIX:
e7a395
-            print _('(fixing)')
e7a395
+            print C_('(fixing)')
e7a395
             os.chmod(private, mode & ~S_IROTH)
e7a395
         else:
e7a395
             print
e7a395
@@ -238,9 +238,9 @@ def checkmboxfile(mboxdir):
e7a395
         mode = statmode(mboxfile)
e7a395
         if (mode & MBOXPERMS) <> MBOXPERMS:
e7a395
             STATE.ERRORS = STATE.ERRORS + 1
e7a395
-            print _('mbox file must be at least 0660:'), mboxfile
e7a395
+            print C_('mbox file must be at least 0660:'), mboxfile
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(mboxfile, mode | MBOXPERMS)
e7a395
             else:
e7a395
                 print
e7a395
@@ -261,9 +261,9 @@ def checkarchivedbs():
e7a395
             continue
e7a395
         if mode & S_IRWXO:
e7a395
             STATE.ERRORS += 1
e7a395
-            print _('%(dbdir)s "other" perms must be 000'),
e7a395
+            print C_('%(dbdir)s "other" perms must be 000'),
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(dbdir, mode & ~S_IRWXO)
e7a395
             else:
e7a395
                 print
e7a395
@@ -271,18 +271,18 @@ def checkarchivedbs():
e7a395
 def checkcgi():
e7a395
     cgidir = os.path.join(mm_cfg.EXEC_PREFIX, 'cgi-bin')
e7a395
     if STATE.VERBOSE:
e7a395
-        print _('checking cgi-bin permissions')
e7a395
+        print C_('checking cgi-bin permissions')
e7a395
     exes = os.listdir(cgidir)
e7a395
     for f in exes:
e7a395
         path = os.path.join(cgidir, f)
e7a395
         if STATE.VERBOSE:
e7a395
-            print _('    checking set-gid for %(path)s')
e7a395
+            print C_('    checking set-gid for %(path)s')
e7a395
         mode = statmode(path)
e7a395
         if mode & S_IXGRP and not mode & S_ISGID:
e7a395
             STATE.ERRORS += 1
e7a395
-            print _('%(path)s must be set-gid'),
e7a395
+            print C_('%(path)s must be set-gid'),
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(path, mode | S_ISGID)
e7a395
             else:
e7a395
                 print
e7a395
@@ -290,13 +290,13 @@ def checkcgi():
e7a395
 def checkmail():
e7a395
     wrapper = os.path.join(mm_cfg.WRAPPER_DIR, 'mailman')
e7a395
     if STATE.VERBOSE:
e7a395
-        print _('checking set-gid for %(wrapper)s')
e7a395
+        print C_('checking set-gid for %(wrapper)s')
e7a395
     mode = statmode(wrapper)
e7a395
     if not mode & S_ISGID:
e7a395
         STATE.ERRORS += 1
e7a395
-        print _('%(wrapper)s must be set-gid'),
e7a395
+        print C_('%(wrapper)s must be set-gid'),
e7a395
         if STATE.FIX:
e7a395
-            print _('(fixing)')
e7a395
+            print C_('(fixing)')
e7a395
             os.chmod(wrapper, mode | S_ISGID)
e7a395
 
e7a395
 def checkadminpw():
e7a395
@@ -304,7 +304,7 @@ def checkadminpw():
e7a395
                    os.path.join(mm_cfg.DATA_DIR, 'creator.pw')):
e7a395
         targetmode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP
e7a395
         if STATE.VERBOSE:
e7a395
-            print _('checking permissions on %(pwfile)s')
e7a395
+            print C_('checking permissions on %(pwfile)s')
e7a395
         try:
e7a395
             mode = statmode(pwfile)
e7a395
         except OSError, e:
e7a395
@@ -313,10 +313,10 @@ def checkadminpw():
e7a395
         if mode <> targetmode:
e7a395
             STATE.ERRORS += 1
e7a395
             octmode = oct(mode)
e7a395
-            print _('%(pwfile)s permissions must be exactly 0640 '
e7a395
-                    '(got %(octmode)s)'),
e7a395
+            print C_('%(pwfile)s permissions must be exactly 0640 '
e7a395
+                     '(got %(octmode)s)'),
e7a395
             if STATE.FIX:
e7a395
-                print _('(fixing)')
e7a395
+                print C_('(fixing)')
e7a395
                 os.chmod(pwfile, targetmode)
e7a395
             else:
e7a395
                 print
e7a395
@@ -338,7 +338,7 @@ def checkdata():
e7a395
                   'digest.mbox', 'pending.pck',
e7a395
                   'request.db', 'request.db.tmp')
e7a395
     if STATE.VERBOSE:
e7a395
-        print _('checking permissions on list data')
e7a395
+        print C_('checking permissions on list data')
e7a395
     # BAW: This needs to be converted to the Site module abstraction
e7a395
     for dir in os.listdir(mm_cfg.LIST_DATA_DIR):
e7a395
         if not os.path.isdir(os.path.join(mm_cfg.LIST_DATA_DIR, dir)):
e7a395
@@ -346,7 +346,7 @@ def checkdata():
e7a395
         for file in checkfiles:
e7a395
             path = os.path.join(mm_cfg.LIST_DATA_DIR, dir, file)
e7a395
             if STATE.VERBOSE:
e7a395
-                print _('    checking permissions on: %(path)s')
e7a395
+                print C_('    checking permissions on: %(path)s')
e7a395
             try:
e7a395
                 mode = statmode(path)
e7a395
             except OSError, e:
e7a395
@@ -354,9 +354,9 @@ def checkdata():
e7a395
                 continue
e7a395
             if (mode & targetmode) <> targetmode:
e7a395
                 STATE.ERRORS += 1
e7a395
-                print _('file permissions must be at least 660: %(path)s'),
e7a395
+                print C_('file permissions must be at least 660: %(path)s'),
e7a395
                 if STATE.FIX:
e7a395
-                    print _('(fixing)')
e7a395
+                    print C_('(fixing)')
e7a395
                     os.chmod(path, mode | targetmode)
e7a395
                 else:
e7a395
                     print
e7a395
@@ -368,7 +368,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -399,7 +399,7 @@ if __name__ == '__main__':
e7a395
     checkmta()
e7a395
 
e7a395
     if not STATE.ERRORS:
e7a395
-        print _('No problems found')
e7a395
+        print C_('No problems found')
e7a395
     else:
e7a395
-        print _('Problems found:'), STATE.ERRORS
e7a395
-        print _('Re-run as %(MAILMAN_USER)s (or root) with -f flag to fix')
e7a395
+        print C_('Problems found:'), STATE.ERRORS
e7a395
+        print C_('Re-run as %(MAILMAN_USER)s (or root) with -f flag to fix')
e7a395
diff --git a/bin/cleanarch b/bin/cleanarch
e7a395
index a848533..0994bca 100644
e7a395
--- a/bin/cleanarch
e7a395
+++ b/bin/cleanarch
e7a395
@@ -53,7 +53,7 @@ import getopt
e7a395
 import mailbox
e7a395
 
e7a395
 import paths
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 cre = re.compile(mailbox.UnixMailbox._fromlinepattern)
e7a395
 
e7a395
@@ -69,7 +69,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -80,7 +80,7 @@ def escape_line(line, lineno, quiet, output):
e7a395
     if output:
e7a395
         sys.stdout.write('>' + line)
e7a395
     if not quiet:
e7a395
-        print >> sys.stderr, _('Unix-From line changed: %(lineno)d')
e7a395
+        print >> sys.stderr, C_('Unix-From line changed: %(lineno)d')
e7a395
         print >> sys.stderr, line[:-1]
e7a395
 
e7a395
 
e7a395
@@ -108,7 +108,7 @@ def main():
e7a395
             try:
e7a395
                 status = int(arg)
e7a395
             except ValueError:
e7a395
-                usage(1, _('Bad status number: %(arg)s'))
e7a395
+                usage(1, C_('Bad status number: %(arg)s'))
e7a395
 
e7a395
     if args:
e7a395
         usage(1)
e7a395
@@ -164,7 +164,7 @@ def main():
e7a395
                 print >> sys.stderr
e7a395
                 statuscnt = 0
e7a395
         prevline = line
e7a395
-    print >> sys.stderr, _('%(messages)d messages found')
e7a395
+    print >> sys.stderr, C_('%(messages)d messages found')
e7a395
 
e7a395
 
e7a395
 
e7a395
diff --git a/bin/clone_member b/bin/clone_member
e7a395
index 915c540..d9ff224 100755
e7a395
--- a/bin/clone_member
e7a395
+++ b/bin/clone_member
e7a395
@@ -72,7 +72,7 @@ import paths
e7a395
 from Mailman import MailList
e7a395
 from Mailman import Utils
e7a395
 from Mailman import Errors
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -81,7 +81,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -91,14 +91,14 @@ def usage(code, msg=''):
e7a395
 def dolist(mlist, options):
e7a395
     SPACE = ' '
e7a395
     if not options.quiet:
e7a395
-        print _('processing mailing list:'), mlist.internal_name()
e7a395
+        print C_('processing mailing list:'), mlist.internal_name()
e7a395
 
e7a395
     # scan the list owners.  TBD: mlist.owner keys should be lowercase?
e7a395
     oldowners = mlist.owner[:]
e7a395
     oldowners.sort()
e7a395
     if options.admintoo:
e7a395
         if not options.quiet:
e7a395
-            print _('    scanning list owners:'), SPACE.join(oldowners)
e7a395
+            print C_('    scanning list owners:'), SPACE.join(oldowners)
e7a395
         newowners = {}
e7a395
         foundp = 0
e7a395
         for owner in mlist.owner:
e7a395
@@ -116,9 +116,9 @@ def dolist(mlist, options):
e7a395
         if not options.quiet:
e7a395
             if newowners <> oldowners:
e7a395
                 print
e7a395
-                print _('    new list owners:'), SPACE.join(newowners)
e7a395
+                print C_('    new list owners:'), SPACE.join(newowners)
e7a395
             else:
e7a395
-                print _('(no change)')
e7a395
+                print C_('(no change)')
e7a395
 
e7a395
     # see if the fromaddr is a digest member or regular member
e7a395
     if options.lfromaddr in mlist.getDigestMemberKeys():
e7a395
@@ -127,7 +127,7 @@ def dolist(mlist, options):
e7a395
         digest = 0
e7a395
     else:
e7a395
         if not options.quiet:
e7a395
-            print _('    address not found:'), options.fromaddr
e7a395
+            print C_('    address not found:'), options.fromaddr
e7a395
         return
e7a395
     # Check for banned to address.
e7a395
     pattern = mlist.GetBannedPattern(options.toaddr)
e7a395
@@ -142,13 +142,13 @@ def dolist(mlist, options):
e7a395
             mlist.changeMemberAddress(options.fromaddr, options.toaddr,
e7a395
                                       not options.remove)
e7a395
         if not options.quiet:
e7a395
-            print _('    clone address added:'), options.toaddr
e7a395
+            print C_('    clone address added:'), options.toaddr
e7a395
     except Errors.MMAlreadyAMember:
e7a395
         if not options.quiet:
e7a395
-            print _('    clone address is already a member:'), options.toaddr
e7a395
+            print C_('    clone address is already a member:'), options.toaddr
e7a395
 
e7a395
     if options.remove:
e7a395
-        print _('    original address removed:'), options.fromaddr
e7a395
+        print C_('    original address removed:'), options.fromaddr
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -199,7 +199,7 @@ def main():
e7a395
     try:
e7a395
         Utils.ValidateEmail(toaddr)
e7a395
     except Errors.EmailAddressError:
e7a395
-        usage(1, _('Not a valid email address: %(toaddr)s'))
e7a395
+        usage(1, C_('Not a valid email address: %(toaddr)s'))
e7a395
     lfromaddr = fromaddr.lower()
e7a395
     options.toaddr = toaddr
e7a395
     options.fromaddr = fromaddr
e7a395
@@ -212,7 +212,7 @@ def main():
e7a395
         try:
e7a395
             mlist = MailList.MailList(listname)
e7a395
         except Errors.MMListError, e:
e7a395
-            print _('Error opening list "%(listname)s", skipping.\n%(e)s')
e7a395
+            print C_('Error opening list "%(listname)s", skipping.\n%(e)s')
e7a395
             continue
e7a395
         try:
e7a395
             dolist(mlist, options)
e7a395
diff --git a/bin/config_list b/bin/config_list
e7a395
index 25d4fb6..e23dac2 100644
e7a395
--- a/bin/config_list
e7a395
+++ b/bin/config_list
e7a395
@@ -76,6 +76,7 @@ from Mailman import Errors
e7a395
 from Mailman import i18n
e7a395
 
e7a395
 _ = i18n._
e7a395
+C_ = i18n.C_
e7a395
 
e7a395
 NL = '\n'
e7a395
 nonasciipat = re.compile(r'[\x80-\xff]')
e7a395
@@ -87,7 +88,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -106,7 +107,7 @@ def do_output(listname, outfile):
e7a395
         try:
e7a395
             mlist = MailList.MailList(listname, lock=0)
e7a395
         except Errors.MMListError:
e7a395
-            usage(1, _('No such list: %(listname)s'))
e7a395
+            usage(1, C_('No such list: %(listname)s'))
e7a395
         # Preamble for the config info. PEP263 charset and capture time.
e7a395
         language = mlist.preferred_language
e7a395
         charset = Utils.GetCharSet(language)
e7a395
@@ -114,7 +115,7 @@ def do_output(listname, outfile):
e7a395
         if not charset:
e7a395
             charset = 'us-ascii'
e7a395
         when = time.ctime(time.time())
e7a395
-        print >> outfp, _('''\
e7a395
+        print >> outfp, C_('''\
e7a395
 # -*- python -*-
e7a395
 # -*- coding: %(charset)s -*-
e7a395
 ## "%(listname)s" mailing list configuration settings
e7a395
@@ -140,7 +141,7 @@ def do_list_categories(mlist, k, subcat, outfp):
e7a395
     if info is None:
e7a395
         return
e7a395
     charset = Utils.GetCharSet(mlist.preferred_language)
e7a395
-    print >> outfp, '##', k.capitalize(), _('options')
e7a395
+    print >> outfp, '##', k.capitalize(), C_('options')
e7a395
     print >> outfp, '#'
e7a395
     # First, massage the descripton text, which could have obnoxious
e7a395
     # leading whitespace on second and subsequent lines due to
e7a395
@@ -199,7 +200,7 @@ def do_list_categories(mlist, k, subcat, outfp):
e7a395
                     outfp.write('"""\n')
e7a395
         elif vtype in (mm_cfg.Radio, mm_cfg.Toggle):
e7a395
             print >> outfp, '#'
e7a395
-            print >> outfp, '#', _('legal values are:')
e7a395
+            print >> outfp, '#', C_('legal values are:')
e7a395
             # TBD: This is disgusting, but it's special cased
e7a395
             # everywhere else anyway...
e7a395
             if varname == 'subscribe_policy' and \
e7a395
@@ -253,7 +254,7 @@ def do_input(listname, infile, checkonly, verbose):
e7a395
     try:
e7a395
         mlist = MailList.MailList(listname, lock=not checkonly)
e7a395
     except Errors.MMListError, e:
e7a395
-        usage(1, _('No such list "%(listname)s"\n%(e)s'))
e7a395
+        usage(1, C_('No such list "%(listname)s"\n%(e)s'))
e7a395
     savelist = 0
e7a395
     guibyprop = getPropertyMap(mlist)
e7a395
     try:
e7a395
@@ -266,16 +267,16 @@ def do_input(listname, infile, checkonly, verbose):
e7a395
             if k in ('mlist', '__builtins__'):
e7a395
                 continue
e7a395
             if not hasattr(mlist, k):
e7a395
-                print >> sys.stderr, _('attribute "%(k)s" ignored')
e7a395
+                print >> sys.stderr, C_('attribute "%(k)s" ignored')
e7a395
                 continue
e7a395
             if verbose:
e7a395
-                print >> sys.stderr, _('attribute "%(k)s" changed')
e7a395
+                print >> sys.stderr, C_('attribute "%(k)s" changed')
e7a395
             missing = []
e7a395
             gui, wtype = guibyprop.get(k, (missing, missing))
e7a395
             if gui is missing:
e7a395
                 # This isn't an official property of the list, but that's
e7a395
                 # okay, we'll just restore it the old fashioned way
e7a395
-                print >> sys.stderr, _('Non-standard property restored: %(k)s')
e7a395
+                print >> sys.stderr, C_('Non-standard property restored: %(k)s')
e7a395
                 setattr(mlist, k, v)
e7a395
             else:
e7a395
                 # BAW: This uses non-public methods.  This logic taken from
e7a395
@@ -283,9 +284,9 @@ def do_input(listname, infile, checkonly, verbose):
e7a395
                 try:
e7a395
                     validval = gui._getValidValue(mlist, k, wtype, v)
e7a395
                 except ValueError:
e7a395
-                    print >> sys.stderr, _('Invalid value for property: %(k)s')
e7a395
+                    print >> sys.stderr, C_('Invalid value for property: %(k)s')
e7a395
                 except Errors.EmailAddressError:
e7a395
-                    print >> sys.stderr, _(
e7a395
+                    print >> sys.stderr, C_(
e7a395
                         'Bad email address for option %(k)s: %(v)s')
e7a395
                 else:
e7a395
                     # BAW: Horrible hack, but then this is special cased
e7a395
@@ -342,13 +343,13 @@ def main():
e7a395
 
e7a395
     # sanity check
e7a395
     if infile is not None and outfile is not None:
e7a395
-        usage(1, _('Only one of -i or -o is allowed'))
e7a395
+        usage(1, C_('Only one of -i or -o is allowed'))
e7a395
     if infile is None and outfile is None:
e7a395
-        usage(1, _('One of -i or -o is required'))
e7a395
+        usage(1, C_('One of -i or -o is required'))
e7a395
 
e7a395
     # get the list name
e7a395
     if len(args) <> 1:
e7a395
-        usage(1, _('List name is required'))
e7a395
+        usage(1, C_('List name is required'))
e7a395
     listname = args[0].lower().strip()
e7a395
 
e7a395
     if outfile:
e7a395
diff --git a/bin/convert.py b/bin/convert.py
e7a395
index b0d6a05..ad7228b 100644
e7a395
--- a/bin/convert.py
e7a395
+++ b/bin/convert.py
e7a395
@@ -25,7 +25,7 @@ This script is intended to be run as a bin/withlist script, i.e.
e7a395
 
e7a395
 import paths
e7a395
 from Mailman import Utils
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 def convert(mlist):
e7a395
     for attr in ('msg_header', 'msg_footer', 'digest_header', 'digest_footer',
e7a395
@@ -35,10 +35,10 @@ def convert(mlist):
e7a395
         t = Utils.to_dollar(s)
e7a395
         setattr(mlist, attr, t)
e7a395
     mlist.use_dollar_strings = 1
e7a395
-    print _('Saving list')
e7a395
+    print C_('Saving list')
e7a395
     mlist.Save()
e7a395
 
e7a395
 
e7a395
 
e7a395
 if __name__ == '__main__':
e7a395
-    print _(__doc__.replace('%', '%%'))
e7a395
+    print C_(__doc__.replace('%', '%%'))
e7a395
diff --git a/bin/discard b/bin/discard
e7a395
index c301984..34cb811 100644
e7a395
--- a/bin/discard
e7a395
+++ b/bin/discard
e7a395
@@ -41,7 +41,7 @@ import getopt
e7a395
 import paths
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman.MailList import MailList
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 try:
e7a395
     True, False
e7a395
@@ -58,7 +58,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -80,7 +80,7 @@ def main():
e7a395
 
e7a395
     files = args
e7a395
     if not files:
e7a395
-        print _('Nothing to do.')
e7a395
+        print C_('Nothing to do.')
e7a395
 
e7a395
     # Mapping from listnames to sequence of request ids
e7a395
     discards = {}
e7a395
@@ -91,13 +91,13 @@ def main():
e7a395
         basename = os.path.basename(f)
e7a395
         mo = cre.match(basename)
e7a395
         if not mo:
e7a395
-            print >> sys.stderr, _('Ignoring non-held message: %(f)s')
e7a395
+            print >> sys.stderr, C_('Ignoring non-held message: %(f)s')
e7a395
             continue
e7a395
         listname, id = mo.group('listname', 'id')
e7a395
         try:
e7a395
             id = int(id)
e7a395
         except (ValueError, TypeError):
e7a395
-            print >> sys.stderr, _('Ignoring held msg w/bad id: %(f)s')
e7a395
+            print >> sys.stderr, C_('Ignoring held msg w/bad id: %(f)s')
e7a395
             continue
e7a395
         discards.setdefault(listname, []).append(id)
e7a395
 
e7a395
@@ -109,7 +109,7 @@ def main():
e7a395
                 # No comment, no preserve, no forward, no forwarding address
e7a395
                 mlist.HandleRequest(id, mm_cfg.DISCARD, '', False, False, '')
e7a395
                 if not quiet:
e7a395
-                    print _('Discarded held msg #%(id)s for list %(listname)s')
e7a395
+                    print C_('Discarded held msg #%(id)s for list %(listname)s')
e7a395
             mlist.Save()
e7a395
         finally:
e7a395
             mlist.Unlock()
e7a395
diff --git a/bin/dumpdb b/bin/dumpdb
e7a395
index c8e4246..0b58fae 100644
e7a395
--- a/bin/dumpdb
e7a395
+++ b/bin/dumpdb
e7a395
@@ -54,7 +54,7 @@ from types import StringType
e7a395
 
e7a395
 import paths
e7a395
 # Import this /after/ paths so that the sys.path is properly hacked
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 COMMASPACE = ', '
e7a395
@@ -72,7 +72,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__) % globals()
e7a395
+    print >> fd, C_(__doc__) % globals()
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -102,10 +102,10 @@ def main():
e7a395
             doprint = False
e7a395
 
e7a395
     if len(args) < 1:
e7a395
-        usage(1, _('No filename given.'))
e7a395
+        usage(1, C_('No filename given.'))
e7a395
     elif len(args) > 1:
e7a395
         pargs = COMMASPACE.join(args)
e7a395
-        usage(1, _('Bad arguments: %(pargs)s'))
e7a395
+        usage(1, C_('Bad arguments: %(pargs)s'))
e7a395
     else:
e7a395
         filename = args[0]
e7a395
 
e7a395
@@ -115,7 +115,7 @@ def main():
e7a395
         elif filename.endswith('.pck'):
e7a395
             filetype = 0
e7a395
         else:
e7a395
-            usage(1, _('Please specify either -p or -m.'))
e7a395
+            usage(1, C_('Please specify either -p or -m.'))
e7a395
 
e7a395
     # Handle dbs
e7a395
     pp = pprint.PrettyPrinter(indent=4)
e7a395
@@ -130,16 +130,16 @@ def main():
e7a395
     try:
e7a395
         cnt = 1
e7a395
         if doprint:
e7a395
-            print _('[----- start %(typename)s file -----]')
e7a395
+            print C_('[----- start %(typename)s file -----]')
e7a395
         while True:
e7a395
             try:
e7a395
                 obj = load(fp)
e7a395
             except EOFError:
e7a395
                 if doprint:
e7a395
-                    print _('[----- end %(typename)s file -----]')
e7a395
+                    print C_('[----- end %(typename)s file -----]')
e7a395
                 break
e7a395
             if doprint:
e7a395
-                print _('<----- start object %(cnt)s ----->')
e7a395
+                print C_('<----- start object %(cnt)s ----->')
e7a395
                 if isinstance(obj, StringType):
e7a395
                     print obj
e7a395
                 else:
e7a395
diff --git a/bin/find_member b/bin/find_member
e7a395
index a1701bf..99e4ee6 100755
e7a395
--- a/bin/find_member
e7a395
+++ b/bin/find_member
e7a395
@@ -64,7 +64,7 @@ import paths
e7a395
 from Mailman import Utils
e7a395
 from Mailman import MailList
e7a395
 from Mailman import Errors
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 AS_MEMBER = 0x01
e7a395
 AS_OWNER = 0x02
e7a395
@@ -76,7 +76,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -94,7 +94,7 @@ def scanlists(options):
e7a395
         try:
e7a395
             mlist = MailList.MailList(listname, lock=0)
e7a395
         except Errors.MMListError:
e7a395
-            print _('No such list: %(listname)s')
e7a395
+            print C_('No such list: %(listname)s')
e7a395
             continue
e7a395
         if options.owners:
e7a395
             owners = mlist.owner
e7a395
@@ -156,12 +156,12 @@ def main():
e7a395
             pass
e7a395
 
e7a395
     if not args:
e7a395
-        usage(1, _('Search regular expression required'))
e7a395
+        usage(1, C_('Search regular expression required'))
e7a395
 
e7a395
     options.regexps = args
e7a395
 
e7a395
     if not options.listnames:
e7a395
-        print _('No lists to search')
e7a395
+        print C_('No lists to search')
e7a395
         return
e7a395
 
e7a395
     matches = scanlists(options)
e7a395
@@ -170,13 +170,13 @@ def main():
e7a395
     for k in addrs:
e7a395
         hits = matches[k]
e7a395
         lists = hits.keys()
e7a395
-        print k, _('found in:')
e7a395
+        print k, C_('found in:')
e7a395
         for name in lists:
e7a395
             aswhat = hits[name]
e7a395
             if aswhat & AS_MEMBER:
e7a395
                 print '    ', name
e7a395
             if aswhat & AS_OWNER:
e7a395
-                print '    ', name, _('(as owner)')
e7a395
+                print '    ', name, C_('(as owner)')
e7a395
 
e7a395
 
e7a395
 
e7a395
diff --git a/bin/fix_url.py b/bin/fix_url.py
e7a395
index d2731c1..6523ce2 100644
e7a395
--- a/bin/fix_url.py
e7a395
+++ b/bin/fix_url.py
e7a395
@@ -43,12 +43,12 @@ import getopt
e7a395
 
e7a395
 import paths
e7a395
 from Mailman import mm_cfg
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 
e7a395
 
e7a395
 def usage(code, msg=''):
e7a395
-    print _(__doc__.replace('%', '%%'))
e7a395
+    print C_(__doc__.replace('%', '%%'))
e7a395
     if msg:
e7a395
         print msg
e7a395
     sys.exit(code)
e7a395
@@ -82,12 +82,12 @@ def fix_url(mlist, *args):
e7a395
         mailhost = mm_cfg.DEFAULT_EMAIL_HOST
e7a395
 
e7a395
     if verbose:
e7a395
-        print _('Setting web_page_url to: %(web_page_url)s')
e7a395
+        print C_('Setting web_page_url to: %(web_page_url)s')
e7a395
     mlist.web_page_url = web_page_url
e7a395
     if verbose:
e7a395
-        print _('Setting host_name to: %(mailhost)s')
e7a395
+        print C_('Setting host_name to: %(mailhost)s')
e7a395
     mlist.host_name = mailhost
e7a395
-    print _('Saving list')
e7a395
+    print C_('Saving list')
e7a395
     mlist.Save()
e7a395
     mlist.Unlock()
e7a395
 
e7a395
diff --git a/bin/genaliases b/bin/genaliases
e7a395
index 77bc290..c49cba6 100644
e7a395
--- a/bin/genaliases
e7a395
+++ b/bin/genaliases
e7a395
@@ -40,7 +40,7 @@ import paths                                      # path hacking
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman import Utils
e7a395
 from Mailman import MailList
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 try:
e7a395
     True, False
e7a395
@@ -55,7 +55,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
diff --git a/bin/inject b/bin/inject
e7a395
index 432c292..fa91f5e 100644
e7a395
--- a/bin/inject
e7a395
+++ b/bin/inject
e7a395
@@ -48,7 +48,7 @@ import paths
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman import Utils
e7a395
 from Mailman import Post
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -57,7 +57,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -81,14 +81,14 @@ def main():
e7a395
         elif opt in ('-q', '--queue'):
e7a395
             qdir = os.path.join(mm_cfg.QUEUE_DIR, arg)
e7a395
             if not os.path.isdir(qdir):
e7a395
-                usage(1, _('Bad queue directory: %(qdir)s'))
e7a395
+                usage(1, C_('Bad queue directory: %(qdir)s'))
e7a395
         elif opt in ('-l', '--listname'):
e7a395
             listname = arg.lower()
e7a395
 
e7a395
     if listname is None:
e7a395
-        usage(1, _('A list name is required'))
e7a395
+        usage(1, C_('A list name is required'))
e7a395
     elif not Utils.list_exists(listname):
e7a395
-        usage(1, _('No such list: %(listname)s'))
e7a395
+        usage(1, C_('No such list: %(listname)s'))
e7a395
 
e7a395
     if len(args) == 0:
e7a395
         # Use standard input
e7a395
diff --git a/bin/list_admins b/bin/list_admins
e7a395
index b86a5eb..f9304c7 100644
e7a395
--- a/bin/list_admins
e7a395
+++ b/bin/list_admins
e7a395
@@ -45,7 +45,7 @@ import getopt
e7a395
 import paths
e7a395
 from Mailman import MailList, Utils
e7a395
 from Mailman import Errors
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 COMMASPACE = ', '
e7a395
 
e7a395
@@ -58,7 +58,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -87,14 +87,14 @@ def main():
e7a395
        try:
e7a395
            mlist = MailList.MailList(listname, lock=0)
e7a395
        except Errors.MMListError, e:
e7a395
-           print _('No such list: %(listname)s')
e7a395
+           print C_('No such list: %(listname)s')
e7a395
            continue
e7a395
 
e7a395
        if vhost and vhost <> mlist.host_name:
e7a395
            continue
e7a395
 
e7a395
        owners = COMMASPACE.join(mlist.owner)
e7a395
-       print _('List: %(listname)s, \tOwners: %(owners)s')
e7a395
+       print C_('List: %(listname)s, \tOwners: %(owners)s')
e7a395
 
e7a395
 
e7a395
 
e7a395
diff --git a/bin/list_lists b/bin/list_lists
e7a395
index 870759b..004db2a 100644
e7a395
--- a/bin/list_lists
e7a395
+++ b/bin/list_lists
e7a395
@@ -47,7 +47,7 @@ from Mailman import mm_cfg
e7a395
 from Mailman import MailList
e7a395
 from Mailman import Utils
e7a395
 from Mailman import Errors
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 program = sys.argv[0]
e7a395
 
e7a395
@@ -56,7 +56,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -102,18 +102,18 @@ def main():
e7a395
         longest = max(len(mlist.real_name), longest)
e7a395
 
e7a395
     if not mlists and not bare:
e7a395
-        print _('No matching mailing lists found')
e7a395
+        print C_('No matching mailing lists found')
e7a395
         return
e7a395
 
e7a395
     if not bare:
e7a395
-        print len(mlists), _('matching mailing lists found:')
e7a395
+        print len(mlists), C_('matching mailing lists found:')
e7a395
 
e7a395
     format = '%%%ds - %%.%ds' % (longest, 77 - longest)
e7a395
     for mlist in mlists:
e7a395
         if bare:
e7a395
             print mlist.internal_name()
e7a395
         else:
e7a395
-            description = mlist.description or _('[no description available]')
e7a395
+            description = mlist.description or C_('[no description available]')
e7a395
             print '   ', format % (mlist.real_name, description)
e7a395
 
e7a395
 
e7a395
diff --git a/bin/list_members b/bin/list_members
e7a395
index cb57408..7e51ddc 100755
e7a395
--- a/bin/list_members
e7a395
+++ b/bin/list_members
e7a395
@@ -76,7 +76,7 @@ from Mailman import Utils
e7a395
 from Mailman import MailList
e7a395
 from Mailman import Errors
e7a395
 from Mailman import MemberAdaptor
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 from email.Utils import formataddr
e7a395
 
e7a395
@@ -104,7 +104,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -188,7 +188,7 @@ def main():
e7a395
             if i >= 0:
e7a395
                 why = opt[i+1:]
e7a395
                 if why not in WHYCHOICES.keys():
e7a395
-                    usage(1, _('Bad --nomail option: %(why)s'))
e7a395
+                    usage(1, C_('Bad --nomail option: %(why)s'))
e7a395
         elif opt == '-d':
e7a395
             digest = True
e7a395
             if args and args[0] in ('mime', 'plain'):
e7a395
@@ -199,7 +199,7 @@ def main():
e7a395
             if i >= 0:
e7a395
                 kind = opt[i+1:]
e7a395
                 if kind not in ('mime', 'plain'):
e7a395
-                    usage(1, _('Bad --digest option: %(kind)s'))
e7a395
+                    usage(1, C_('Bad --digest option: %(kind)s'))
e7a395
         elif opt in ('-i', '--invalid'):
e7a395
             invalidonly = True
e7a395
         elif opt in ('-u', '--unicode'):
e7a395
@@ -221,7 +221,7 @@ def main():
e7a395
         try:
e7a395
             fp = open(outfile, 'w')
e7a395
         except IOError:
e7a395
-            print >> sys.stderr, _('Could not open file for writing:'), outfile
e7a395
+            print >> sys.stderr, C_('Could not open file for writing:'), outfile
e7a395
             sys.exit(1)
e7a395
     else:
e7a395
         fp = sys.stdout
e7a395
@@ -229,7 +229,7 @@ def main():
e7a395
     try:
e7a395
         mlist = MailList.MailList(listname, lock=False)
e7a395
     except Errors.MMListError, e:
e7a395
-        print >> sys.stderr, _('No such list: %(listname)s')
e7a395
+        print >> sys.stderr, C_('No such list: %(listname)s')
e7a395
         sys.exit(1)
e7a395
 
e7a395
     # Get the lowercased member addresses
e7a395
diff --git a/bin/list_owners b/bin/list_owners
e7a395
index 4c2d908..adcba10 100644
e7a395
--- a/bin/list_owners
e7a395
+++ b/bin/list_owners
e7a395
@@ -45,7 +45,7 @@ import getopt
e7a395
 import paths
e7a395
 from Mailman import Utils
e7a395
 from Mailman.MailList import MailList
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 
e7a395
@@ -62,7 +62,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
diff --git a/bin/mailmanctl b/bin/mailmanctl
e7a395
index 3d59d57..2a5085d 100644
e7a395
--- a/bin/mailmanctl
e7a395
+++ b/bin/mailmanctl
e7a395
@@ -111,7 +111,7 @@ from Mailman import Utils
e7a395
 from Mailman import LockFile
e7a395
 from Mailman import Errors
e7a395
 from Mailman.MailList import MailList
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 from Mailman.Logging.Syslog import syslog
e7a395
 from Mailman.Logging.Utils import LogStdErr
e7a395
 
e7a395
@@ -136,7 +136,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -152,17 +152,17 @@ def kill_watcher(sig):
e7a395
     except (IOError, ValueError), e:
e7a395
         # For i18n convenience
e7a395
         pidfile = mm_cfg.PIDFILE
e7a395
-        print >> sys.stderr, _('PID unreadable in: %(pidfile)s')
e7a395
+        print >> sys.stderr, C_('PID unreadable in: %(pidfile)s')
e7a395
         print >> sys.stderr, e
e7a395
-        print >> sys.stderr, _('Is qrunner even running?')
e7a395
+        print >> sys.stderr, C_('Is qrunner even running?')
e7a395
         return
e7a395
     try:
e7a395
         os.kill(pid, sig)
e7a395
     except OSError, e:
e7a395
         if e.errno <> errno.ESRCH: raise
e7a395
-        print >> sys.stderr, _('No child with pid: %(pid)s')
e7a395
+        print >> sys.stderr, C_('No child with pid: %(pid)s')
e7a395
         print >> sys.stderr, e
e7a395
-        print >> sys.stderr, _('Stale pid file removed.')
e7a395
+        print >> sys.stderr, C_('Stale pid file removed.')
e7a395
         os.unlink(mm_cfg.PIDFILE)
e7a395
 
e7a395
 
e7a395
@@ -266,19 +266,19 @@ def acquire_lock(force):
e7a395
         status = qrunner_state()
e7a395
         if status == 1:
e7a395
             # host matches and proc exists
e7a395
-            print >> sys.stderr, _("""\
e7a395
+            print >> sys.stderr, C_("""\
e7a395
 The master qrunner lock could not be acquired because it appears as if another
e7a395
 master qrunner is already running.
e7a395
 """)
e7a395
         elif status == 0:
e7a395
             # host matches but no proc
e7a395
-            print >> sys.stderr, _("""\
e7a395
+            print >> sys.stderr, C_("""\
e7a395
 The master qrunner lock could not be acquired.  It appears as though there is
e7a395
 a stale master qrunner lock.  Try re-running mailmanctl with the -s flag.
e7a395
 """)
e7a395
         else:
e7a395
             # host doesn't even match
e7a395
-            print >> sys.stderr, _("""\
e7a395
+            print >> sys.stderr, C_("""\
e7a395
 The master qrunner lock could not be acquired, because it appears as if some
e7a395
 process on some other host may have acquired it.  We can't test for stale
e7a395
 locks across host boundaries, so you'll have to do this manually.  Or, if you
e7a395
@@ -325,7 +325,7 @@ def check_for_site_list():
e7a395
     try:
e7a395
         sitelist = MailList(sitelistname, lock=0)
e7a395
     except Errors.MMUnknownListError:
e7a395
-        print >> sys.stderr, _('Site list is missing: %(sitelistname)s')
e7a395
+        print >> sys.stderr, C_('Site list is missing: %(sitelistname)s')
e7a395
         syslog('error', 'Site list is missing: %s', mm_cfg.MAILMAN_SITE_LIST)
e7a395
         sys.exit(1)
e7a395
 
e7a395
@@ -350,7 +350,7 @@ def check_privs():
e7a395
         os.setuid(uid)
e7a395
     elif myuid <> uid:
e7a395
         name = mm_cfg.MAILMAN_USER
e7a395
-        usage(1, _(
e7a395
+        usage(1, C_(
e7a395
             'Run this program as root or as the %(name)s user, or use -u.'))
e7a395
 
e7a395
 
e7a395
@@ -381,10 +381,10 @@ def main():
e7a395
             quiet = 1
e7a395
 
e7a395
     if len(args) < 1:
e7a395
-        usage(1, _('No command given.'))
e7a395
+        usage(1, C_('No command given.'))
e7a395
     elif len(args) > 1:
e7a395
         command = COMMASPACE.join(args)
e7a395
-        usage(1, _('Bad command: %(command)s'))
e7a395
+        usage(1, C_('Bad command: %(command)s'))
e7a395
 
e7a395
     command = args[0].lower()
e7a395
 
e7a395
@@ -392,7 +392,7 @@ def main():
e7a395
         check_privs()
e7a395
     else:
e7a395
         if command != 'status':
e7a395
-	    print _('Warning!  You may encounter permission problems.')
e7a395
+	    print C_('Warning!  You may encounter permission problems.')
e7a395
 
e7a395
     # Handle the commands
e7a395
     if command == 'stop':
e7a395
@@ -400,26 +400,26 @@ def main():
e7a395
         # giving cron/qrunner a ctrl-c or KeyboardInterrupt.  This will
e7a395
         # effectively shut everything down.
e7a395
         if not quiet:
e7a395
-            print _("Shutting down Mailman's master qrunner")
e7a395
+            print C_("Shutting down Mailman's master qrunner")
e7a395
         kill_watcher(signal.SIGTERM)
e7a395
     elif command == 'restart':
e7a395
         # Sent the master qrunner process a SIGHUP.  This will cause the
e7a395
         # master qrunner to kill and restart all the worker qrunners, and to
e7a395
         # close and re-open its log files.
e7a395
         if not quiet:
e7a395
-            print _("Restarting Mailman's master qrunner")
e7a395
+            print C_("Restarting Mailman's master qrunner")
e7a395
         kill_watcher(signal.SIGINT)
e7a395
     elif command == 'reopen':
e7a395
         if not quiet:
e7a395
-            print _('Re-opening all log files')
e7a395
+            print C_('Re-opening all log files')
e7a395
         kill_watcher(signal.SIGHUP)
e7a395
     elif command == 'status':
e7a395
         status, pid = mailman_status()
e7a395
         if not quiet:
e7a395
             if status == 0:
e7a395
-                print _("mailman (pid %(pid)d) is running...")
e7a395
+                print C_("mailman (pid %(pid)d) is running...")
e7a395
             else:
e7a395
-                print _("mailman is stopped")
e7a395
+                print C_("mailman is stopped")
e7a395
         sys.exit(status)
e7a395
     elif command == 'start':
e7a395
         # First, complain loudly if there's no site list.
e7a395
@@ -455,7 +455,7 @@ def main():
e7a395
         if pid:
e7a395
             # parent
e7a395
             if not quiet:
e7a395
-                print _("Starting Mailman's master qrunner.")
e7a395
+                print C_("Starting Mailman's master qrunner.")
e7a395
             # Give up the lock "ownership".  This just means the foreground
e7a395
             # process won't close/unlock the lock when it finalizes this lock
e7a395
             # instance.  We'll let the mater watcher subproc own the lock.
e7a395
diff --git a/bin/mmsitepass b/bin/mmsitepass
e7a395
index 0bb6e77..bb4cc71 100755
e7a395
--- a/bin/mmsitepass
e7a395
+++ b/bin/mmsitepass
e7a395
@@ -43,7 +43,7 @@ import getopt
e7a395
 
e7a395
 import paths
e7a395
 from Mailman import Utils
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 
e7a395
@@ -54,7 +54,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -70,34 +70,34 @@ def main():
e7a395
 
e7a395
     # Defaults
e7a395
     siteadmin = 1
e7a395
-    pwdesc = _('site')
e7a395
+    pwdesc = C_('site')
e7a395
 
e7a395
     for opt, arg in opts:
e7a395
         if opt in ('-h', '--help'):
e7a395
             usage(0)
e7a395
         elif opt in ('-c', '--listcreator'):
e7a395
             siteadmin = 0
e7a395
-            pwdesc = _('list creator')
e7a395
+            pwdesc = C_('list creator')
e7a395
 
e7a395
     if len(args) == 1:
e7a395
         pw1 = args[0]
e7a395
     else:
e7a395
         try:
e7a395
-            pw1 = getpass.getpass(_('New %(pwdesc)s password: '))
e7a395
-            pw2 = getpass.getpass(_('Again to confirm password: '))
e7a395
+            pw1 = getpass.getpass(C_('New %(pwdesc)s password: '))
e7a395
+            pw2 = getpass.getpass(C_('Again to confirm password: '))
e7a395
             if pw1 <> pw2:
e7a395
-                print _('Passwords do not match; no changes made.')
e7a395
+                print C_('Passwords do not match; no changes made.')
e7a395
                 sys.exit(1)
e7a395
         except KeyboardInterrupt:
e7a395
-            print _('Interrupted...')
e7a395
+            print C_('Interrupted...')
e7a395
             sys.exit(0)
e7a395
     # Set the site password by writing it to a local file.  Make sure the
e7a395
     # permissions don't allow other+read.
e7a395
     Utils.set_global_password(pw1, siteadmin)
e7a395
     if Utils.check_global_password(pw1, siteadmin):
e7a395
-        print _('Password changed.')
e7a395
+        print C_('Password changed.')
e7a395
     else:
e7a395
-        print _('Password change failed.')
e7a395
+        print C_('Password change failed.')
e7a395
 
e7a395
 
e7a395
 
e7a395
diff --git a/bin/newlist b/bin/newlist
e7a395
index c14b77f..7000396 100755
e7a395
--- a/bin/newlist
e7a395
+++ b/bin/newlist
e7a395
@@ -104,6 +104,7 @@ from Mailman import Message
e7a395
 from Mailman import i18n
e7a395
 
e7a395
 _ = i18n._
e7a395
+C_ = i18n.C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 
e7a395
@@ -114,7 +115,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -147,12 +148,12 @@ def main():
e7a395
 
e7a395
     # Is the language known?
e7a395
     if lang not in mm_cfg.LC_DESCRIPTIONS.keys():
e7a395
-        usage(1, _('Unknown language: %(lang)s'))
e7a395
+        usage(1, C_('Unknown language: %(lang)s'))
e7a395
 
e7a395
     if len(args) > 0:
e7a395
         listname = args[0]
e7a395
     else:
e7a395
-        listname = raw_input(_('Enter the name of the list: '))
e7a395
+        listname = raw_input(C_('Enter the name of the list: '))
e7a395
     listname = listname.lower()
e7a395
 
e7a395
     if '@' in listname:
e7a395
@@ -167,22 +168,22 @@ def main():
e7a395
     web_page_url = mm_cfg.DEFAULT_URL_PATTERN % urlhost
e7a395
 
e7a395
     if Utils.list_exists(listname):
e7a395
-        usage(1, _('List already exists: %(listname)s'))
e7a395
+        usage(1, C_('List already exists: %(listname)s'))
e7a395
 
e7a395
     if len(args) > 1:
e7a395
         owner_mail = args[1]
e7a395
     else:
e7a395
         owner_mail = raw_input(
e7a395
-            _('Enter the email of the person running the list: '))
e7a395
+            C_('Enter the email of the person running the list: '))
e7a395
 
e7a395
     if len(args) > 2:
e7a395
         listpasswd = args[2]
e7a395
     else:
e7a395
-        listpasswd = getpass.getpass(_('Initial %(listname)s password: '))
e7a395
+        listpasswd = getpass.getpass(C_('Initial %(listname)s password: '))
e7a395
     # List passwords cannot be empty
e7a395
     listpasswd = listpasswd.strip()
e7a395
     if not listpasswd:
e7a395
-        usage(1, _('The list password cannot be empty'))
e7a395
+        usage(1, C_('The list password cannot be empty'))
e7a395
 
e7a395
     mlist = MailList.MailList()
e7a395
     try:
e7a395
@@ -202,11 +203,11 @@ def main():
e7a395
             finally:
e7a395
                 os.umask(oldmask)
e7a395
         except Errors.BadListNameError, s:
e7a395
-            usage(1, _('Illegal list name: %(s)s'))
e7a395
+            usage(1, C_('Illegal list name: %(s)s'))
e7a395
         except Errors.EmailAddressError, s:
e7a395
-            usage(1, _('Bad owner email address: %(s)s'))
e7a395
+            usage(1, C_('Bad owner email address: %(s)s'))
e7a395
         except Errors.MMListAlreadyExistsError:
e7a395
-            usage(1, _('List already exists: %(listname)s'))
e7a395
+            usage(1, C_('List already exists: %(listname)s'))
e7a395
 
e7a395
         # Assign domain-specific attributes
e7a395
         mlist.host_name = host_name
e7a395
@@ -227,7 +228,7 @@ def main():
e7a395
 
e7a395
     # And send the notice to the list owner
e7a395
     if not quiet:
e7a395
-        print _('Hit enter to notify %(listname)s owner...'),
e7a395
+        print C_('Hit enter to notify %(listname)s owner...'),
e7a395
         sys.stdin.readline()
e7a395
         siteowner = Utils.get_site_email(mlist.host_name, 'owner')
e7a395
         text = Utils.maketext(
e7a395
diff --git a/bin/qrunner b/bin/qrunner
e7a395
index 20fe830..29bba0f 100644
e7a395
--- a/bin/qrunner
e7a395
+++ b/bin/qrunner
e7a395
@@ -78,7 +78,7 @@ import signal
e7a395
 
e7a395
 import paths
e7a395
 from Mailman import mm_cfg
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 from Mailman.Logging.Syslog import syslog
e7a395
 from Mailman.Logging.Utils import LogStdErr
e7a395
 
e7a395
@@ -95,7 +95,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -175,8 +175,8 @@ def main():
e7a395
                     name = runnername[:-len('Runner')]
e7a395
                 else:
e7a395
                     name = runnername
e7a395
-                print _('%(name)s runs the %(runnername)s qrunner')
e7a395
-            print _('All runs all the above qrunners')
e7a395
+                print C_('%(name)s runs the %(runnername)s qrunner')
e7a395
+            print C_('All runs all the above qrunners')
e7a395
             sys.exit(0)
e7a395
         elif opt in ('-o', '--once'):
e7a395
             once = 1
e7a395
@@ -212,7 +212,7 @@ def main():
e7a395
     if len(args) <> 0:
e7a395
         usage(1)
e7a395
     if len(runners) == 0:
e7a395
-        usage(1, _('No runner name given.'))
e7a395
+        usage(1, C_('No runner name given.'))
e7a395
 
e7a395
     # Before we startup qrunners, we redirect the stderr to mailman syslog.
e7a395
     # We assume !AS_SUBPROC is running for debugging purpose and don't
e7a395
diff --git a/bin/rb-archfix b/bin/rb-archfix
e7a395
index fceadc2..2b1bef6 100644
e7a395
--- a/bin/rb-archfix
e7a395
+++ b/bin/rb-archfix
e7a395
@@ -52,7 +52,7 @@ import cPickle as pickle
e7a395
 
e7a395
 # Required to get the right classes for unpickling
e7a395
 import paths
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 PROGRAM = sys.argv[0]
e7a395
 
e7a395
@@ -63,7 +63,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
diff --git a/bin/remove_members b/bin/remove_members
e7a395
index a7b4ebb..33aa6a2 100755
e7a395
--- a/bin/remove_members
e7a395
+++ b/bin/remove_members
e7a395
@@ -66,7 +66,7 @@ import paths
e7a395
 from Mailman import MailList
e7a395
 from Mailman import Utils
e7a395
 from Mailman import Errors
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 try:
e7a395
     True, False
e7a395
@@ -81,7 +81,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -153,14 +153,14 @@ def main():
e7a395
         try:
e7a395
             addresses = addresses + ReadFile(filename)
e7a395
         except IOError:
e7a395
-            print _('Could not open file for reading: %(filename)s.')
e7a395
+            print C_('Could not open file for reading: %(filename)s.')
e7a395
 
e7a395
     for listname in listnames:
e7a395
        try:
e7a395
            # open locked
e7a395
            mlist = MailList.MailList(listname)
e7a395
        except Errors.MMListError:
e7a395
-           print _('Error opening list %(listname)s... skipping.')
e7a395
+           print C_('Error opening list %(listname)s... skipping.')
e7a395
            continue
e7a395
 
e7a395
        if all:
e7a395
@@ -170,12 +170,12 @@ def main():
e7a395
            for addr in addresses:
e7a395
                if not mlist.isMember(addr):
e7a395
                    if not alllists:
e7a395
-                       print _('No such member: %(addr)s')
e7a395
+                       print C_('No such member: %(addr)s')
e7a395
                    continue
e7a395
                mlist.ApprovedDeleteMember(addr, 'bin/remove_members',
e7a395
                                           admin_notif, userack)
e7a395
                if alllists:
e7a395
-                   print _("User `%(addr)s' removed from list: %(listname)s.")
e7a395
+                   print C_("User `%(addr)s' removed from list: %(listname)s.")
e7a395
            mlist.Save()
e7a395
        finally:
e7a395
            mlist.Unlock()
e7a395
diff --git a/bin/rmlist b/bin/rmlist
e7a395
index f61b41d..4d1ce50 100755
e7a395
--- a/bin/rmlist
e7a395
+++ b/bin/rmlist
e7a395
@@ -46,7 +46,7 @@ import paths
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman import Utils
e7a395
 from Mailman import MailList
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 try:
e7a395
     True, False
e7a395
@@ -61,7 +61,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -70,15 +70,15 @@ def usage(code, msg=''):
e7a395
 
e7a395
 def remove_it(listname, filename, msg):
e7a395
     if os.path.islink(filename):
e7a395
-        print _('Removing %(msg)s')
e7a395
+        print C_('Removing %(msg)s')
e7a395
         os.unlink(filename)
e7a395
     elif os.path.isdir(filename):
e7a395
-        print _('Removing %(msg)s')
e7a395
+        print C_('Removing %(msg)s')
e7a395
         shutil.rmtree(filename)
e7a395
     elif os.path.isfile(filename):
e7a395
         os.unlink(filename)
e7a395
     else:
e7a395
-        print _('%(listname)s %(msg)s not found as %(filename)s')
e7a395
+        print C_('%(listname)s %(msg)s not found as %(filename)s')
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -102,13 +102,13 @@ def main():
e7a395
 
e7a395
     if not Utils.list_exists(listname):
e7a395
         if not removeArchives:
e7a395
-            usage(1, _('No such list (or list already deleted): %(listname)s'))
e7a395
+            usage(1, C_('No such list (or list already deleted): %(listname)s'))
e7a395
         else:
e7a395
-            print _(
e7a395
+            print C_(
e7a395
                 'No such list: %(listname)s.  Removing its residual archives.')
e7a395
 
e7a395
     if not removeArchives:
e7a395
-        print _('Not removing archives.  Reinvoke with -a to remove them.')
e7a395
+        print C_('Not removing archives.  Reinvoke with -a to remove them.')
e7a395
 
e7a395
 
e7a395
     REMOVABLES = []
e7a395
@@ -122,7 +122,7 @@ def main():
e7a395
             sys.modules[modname].remove(mlist)
e7a395
 
e7a395
         REMOVABLES = [
e7a395
-            (os.path.join(mm_cfg.LIST_DATA_DIR, listname), _('list info')),
e7a395
+            (os.path.join(mm_cfg.LIST_DATA_DIR, listname), C_('list info')),
e7a395
             ]
e7a395
 
e7a395
     # Remove any stale locks associated with the list
e7a395
@@ -130,7 +130,7 @@ def main():
e7a395
         fn_listname = filename.split('.')[0]
e7a395
         if fn_listname == listname:
e7a395
             REMOVABLES.append((os.path.join(mm_cfg.LOCK_DIR, filename),
e7a395
-                               _('stale lock file')))
e7a395
+                               C_('stale lock file')))
e7a395
 
e7a395
     # Remove any held messages for this list
e7a395
     for filename in os.listdir(mm_cfg.DATA_DIR):
e7a395
@@ -138,18 +138,18 @@ def main():
e7a395
                          re.IGNORECASE)
e7a395
         if cre.match(filename):
e7a395
             REMOVABLES.append((os.path.join(mm_cfg.DATA_DIR, filename),
e7a395
-                               _('held message file')))
e7a395
+                               C_('held message file')))
e7a395
 
e7a395
     if removeArchives:
e7a395
         REMOVABLES.extend([
e7a395
             (os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, listname),
e7a395
-             _('private archives')),
e7a395
+             C_('private archives')),
e7a395
             (os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, listname + '.mbox'),
e7a395
-             _('private archives')),
e7a395
+             C_('private archives')),
e7a395
             (os.path.join(mm_cfg.PUBLIC_ARCHIVE_FILE_DIR, listname),
e7a395
-             _('public archives')),
e7a395
+             C_('public archives')),
e7a395
             (os.path.join(mm_cfg.PUBLIC_ARCHIVE_FILE_DIR, listname + '.mbox'),
e7a395
-             _('public archives')),
e7a395
+             C_('public archives')),
e7a395
             ])
e7a395
 
e7a395
     for dir, msg in REMOVABLES:
e7a395
diff --git a/bin/show_qfiles b/bin/show_qfiles
e7a395
index 0dbe9fe..686a652 100644
e7a395
--- a/bin/show_qfiles
e7a395
+++ b/bin/show_qfiles
e7a395
@@ -37,7 +37,7 @@ import getopt
e7a395
 from cPickle import load
e7a395
 
e7a395
 import paths
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 try:
e7a395
     True, False
e7a395
@@ -52,7 +52,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
diff --git a/bin/sync_members b/bin/sync_members
e7a395
index 13d0b2b..d302243 100755
e7a395
--- a/bin/sync_members
e7a395
+++ b/bin/sync_members
e7a395
@@ -86,7 +86,7 @@ from Mailman import MailList
e7a395
 from Mailman import Errors
e7a395
 from Mailman import Utils
e7a395
 from Mailman.UserDesc import UserDesc
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -97,7 +97,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -112,7 +112,7 @@ def yesno(opt):
e7a395
     elif yesno in ('n', 'no'):
e7a395
         return 0
e7a395
     else:
e7a395
-        usage(1, _('Bad choice: %(yesno)s'))
e7a395
+        usage(1, C_('Bad choice: %(yesno)s'))
e7a395
         # no return
e7a395
 
e7a395
 
e7a395
@@ -135,7 +135,7 @@ def main():
e7a395
         elif opt in ('-n', '--no-change'):
e7a395
             dryrun = 1
e7a395
             i += 1
e7a395
-            print _('Dry run mode')
e7a395
+            print C_('Dry run mode')
e7a395
         elif opt in ('-d', '--digest'):
e7a395
             digest = 1
e7a395
             i += 1
e7a395
@@ -156,11 +156,11 @@ def main():
e7a395
             i += 1
e7a395
         elif opt in ('-f', '--file'):
e7a395
             if filename is not None:
e7a395
-                usage(1, _('Only one -f switch allowed'))
e7a395
+                usage(1, C_('Only one -f switch allowed'))
e7a395
             try:
e7a395
                 filename = sys.argv[i+1]
e7a395
             except IndexError:
e7a395
-                usage(1, _('No argument to -f given'))
e7a395
+                usage(1, C_('No argument to -f given'))
e7a395
             i += 2
e7a395
         elif opt in ('-a', '--notifyadmin'):
e7a395
             notifyadmin = 1
e7a395
@@ -169,17 +169,17 @@ def main():
e7a395
             notifyadmin = yesno(opt)
e7a395
             i += 1
e7a395
         elif opt[0] == '-':
e7a395
-            usage(1, _('Illegal option: %(opt)s'))
e7a395
+            usage(1, C_('Illegal option: %(opt)s'))
e7a395
         else:
e7a395
             try:
e7a395
                 listname = sys.argv[i].lower()
e7a395
                 i += 1
e7a395
             except IndexError:
e7a395
-                usage(1, _('No listname given'))
e7a395
+                usage(1, C_('No listname given'))
e7a395
             break
e7a395
 
e7a395
     if listname is None or filename is None:
e7a395
-        usage(1, _('Must have a listname and a filename'))
e7a395
+        usage(1, C_('Must have a listname and a filename'))
e7a395
 
e7a395
     # read the list of addresses to sync to from the file
e7a395
     if filename == '-':
e7a395
@@ -188,7 +188,7 @@ def main():
e7a395
         try:
e7a395
             fp = open(filename)
e7a395
         except IOError, (code, msg):
e7a395
-            usage(1, _('Cannot read address file: %(filename)s: %(msg)s'))
e7a395
+            usage(1, C_('Cannot read address file: %(filename)s: %(msg)s'))
e7a395
         try:
e7a395
             filemembers = fp.readlines()
e7a395
         finally:
e7a395
@@ -200,7 +200,7 @@ def main():
e7a395
         addr = filemembers[i].strip()
e7a395
         if addr == '' or addr[:1] == '#':
e7a395
             del filemembers[i]
e7a395
-            print _('Ignore  :  %(addr)30s')
e7a395
+            print C_('Ignore  :  %(addr)30s')
e7a395
 
e7a395
     # first filter out any invalid addresses
e7a395
     filemembers = email.Utils.getaddresses(filemembers)
e7a395
@@ -209,17 +209,17 @@ def main():
e7a395
         try:
e7a395
             Utils.ValidateEmail(addr)
e7a395
         except Errors.EmailAddressError:
e7a395
-            print _('Invalid :  %(addr)30s')
e7a395
+            print C_('Invalid :  %(addr)30s')
e7a395
             invalid = 1
e7a395
     if invalid:
e7a395
-        print _('You must fix the preceding invalid addresses first.')
e7a395
+        print C_('You must fix the preceding invalid addresses first.')
e7a395
         sys.exit(1)
e7a395
 
e7a395
     # get the locked list object
e7a395
     try:
e7a395
         mlist = MailList.MailList(listname)
e7a395
     except Errors.MMListError, e:
e7a395
-        print _('No such list: %(listname)s')
e7a395
+        print C_('No such list: %(listname)s')
e7a395
         sys.exit(1)
e7a395
 
e7a395
     try:
e7a395
@@ -241,7 +241,7 @@ def main():
e7a395
                 needsadding[laddr] = (name, addr)
e7a395
 
e7a395
         if not needsadding and not addrs:
e7a395
-            print _('Nothing to do.')
e7a395
+            print C_('Nothing to do.')
e7a395
             sys.exit(0)
e7a395
 
e7a395
         enc = sys.getdefaultencoding()
e7a395
@@ -257,7 +257,7 @@ def main():
e7a395
                 if not dryrun:
e7a395
                     mlist.ApprovedAddMember(userdesc, welcome, notifyadmin)
e7a395
                 s = email.Utils.formataddr((name, addr)).encode(enc, 'replace')
e7a395
-                print _('Added  : %(s)s')
e7a395
+                print C_('Added  : %(s)s')
e7a395
             except Errors.MMAlreadyAMember:
e7a395
                 pass
e7a395
             except Errors.MembershipIsBanned, pattern:
e7a395
@@ -277,7 +277,7 @@ def main():
e7a395
                     # get rid of this member's entry
e7a395
                     mlist.removeMember(addr)
e7a395
             s = email.Utils.formataddr((name, addr)).encode(enc, 'replace')
e7a395
-            print _('Removed: %(s)s')
e7a395
+            print C_('Removed: %(s)s')
e7a395
 
e7a395
         mlist.Save()
e7a395
     finally:
e7a395
diff --git a/bin/transcheck b/bin/transcheck
e7a395
index 1fb3301..e375316 100755
e7a395
--- a/bin/transcheck
e7a395
+++ b/bin/transcheck
e7a395
@@ -36,7 +36,7 @@ import os
e7a395
 import getopt
e7a395
 
e7a395
 import paths
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 program = sys.argv[0]
e7a395
 
e7a395
@@ -47,7 +47,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
diff --git a/bin/unshunt b/bin/unshunt
e7a395
index 842cc0f..e17ecae 100644
e7a395
--- a/bin/unshunt
e7a395
+++ b/bin/unshunt
e7a395
@@ -38,7 +38,7 @@ import getopt
e7a395
 import paths
e7a395
 from Mailman import mm_cfg
e7a395
 from Mailman.Queue.sbcache import get_switchboard
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
 
e7a395
 
e7a395
@@ -47,7 +47,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -82,7 +82,7 @@ def main():
e7a395
         except Exception, e:
e7a395
             # If there are any unshunting errors, log them and continue trying
e7a395
             # other shunted messages.
e7a395
-            print >> sys.stderr, _(
e7a395
+            print >> sys.stderr, C_(
e7a395
                 'Cannot unshunt message %(filebase)s, skipping:\n%(e)s')
e7a395
         else:
e7a395
             # Unlink the .bak file left by dequeue()
e7a395
diff --git a/bin/update b/bin/update
e7a395
index d74cae9..0ac5ffe 100755
e7a395
--- a/bin/update
e7a395
+++ b/bin/update
e7a395
@@ -52,7 +52,7 @@ from Mailman import MailList
e7a395
 from Mailman import Message
e7a395
 from Mailman import Pending
e7a395
 from Mailman.LockFile import TimeOutError
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 from Mailman.Queue.Switchboard import Switchboard
e7a395
 from Mailman.OldStyleMemberships import OldStyleMemberships
e7a395
 from Mailman.MemberAdaptor import BYBOUNCE, ENABLED
e7a395
@@ -104,7 +104,7 @@ def make_varabs(relpath):
e7a395
 
e7a395
 def move_language_templates(mlist):
e7a395
     listname = mlist.internal_name()
e7a395
-    print _('Fixing language templates: %(listname)s')
e7a395
+    print C_('Fixing language templates: %(listname)s')
e7a395
     # Mailman 2.1 has a new cascading search for its templates, defined and
e7a395
     # described in Utils.py:maketext().  Putting templates in the top level
e7a395
     # templates/ subdir or the lists/<listname> subdir is deprecated and no
e7a395
@@ -193,8 +193,8 @@ def dolist(listname):
e7a395
     try:
e7a395
         mlist.Lock(0.5)
e7a395
     except TimeOutError:
e7a395
-        print >> sys.stderr, _('WARNING: could not acquire lock for list: '
e7a395
-                               '%(listname)s')
e7a395
+        print >> sys.stderr, C_('WARNING: could not acquire lock for list: '
e7a395
+                                '%(listname)s')
e7a395
         return 1
e7a395
 
e7a395
     # Sanity check the invariant that every BYBOUNCE disabled member must have
e7a395
@@ -212,13 +212,13 @@ def dolist(listname):
e7a395
         # re-disable them if necessary.
e7a395
         n = len(noinfo)
e7a395
         if n > 0:
e7a395
-            print _(
e7a395
+            print C_(
e7a395
                 'Resetting %(n)s BYBOUNCEs disabled addrs with no bounce info')
e7a395
             for addr in noinfo.keys():
e7a395
                 mlist.setDeliveryStatus(addr, ENABLED)
e7a395
 
e7a395
     # Update the held requests database
e7a395
-    print _("""Updating the held requests database.""")
e7a395
+    print C_("""Updating the held requests database.""")
e7a395
     mlist._UpdateRecords()
e7a395
 
e7a395
     mbox_dir = make_varabs('archives/private/%s.mbox' % (listname))
e7a395
@@ -240,7 +240,7 @@ def dolist(listname):
e7a395
     else:
e7a395
         # this shouldn't happen, but hey, just in case
e7a395
         if not os.path.isdir(mbox_dir):
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
 For some reason, %(mbox_dir)s exists as a file.  This won't work with
e7a395
 b6, so I'm renaming it to %(mbox_dir)s.tmp and proceeding.""")
e7a395
             os.rename(mbox_dir, "%s.tmp" % (mbox_dir))
e7a395
@@ -252,7 +252,7 @@ b6, so I'm renaming it to %(mbox_dir)s.tmp and proceeding.""")
e7a395
     # private one existing
e7a395
     if os.path.isfile(o_pri_mbox_file) and os.path.isfile(o_pub_mbox_file):
e7a395
         if mlist.archive_private:
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
 
e7a395
 %(listname)s has both public and private mbox archives.  Since this list
e7a395
 currently uses private archiving, I'm installing the private mbox archive
e7a395
@@ -267,7 +267,7 @@ script.
e7a395
         o_pub_mbox_file)
e7a395
             os.rename(o_pub_mbox_file, "%s.preb6" % (o_pub_mbox_file))
e7a395
         else:
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
 %s has both public and private mbox archives.  Since this list
e7a395
 currently uses public archiving, I'm installing the public mbox file
e7a395
 archive file (%s) as the active one, and renaming
e7a395
@@ -284,7 +284,7 @@ script.
e7a395
     # move private archive mbox there if it's around
e7a395
     # and take into account all sorts of absurdities
e7a395
     #
e7a395
-    print _('- updating old private mbox file')
e7a395
+    print C_('- updating old private mbox file')
e7a395
     if os.path.exists(o_pri_mbox_file):
e7a395
         if os.path.isfile(o_pri_mbox_file):
e7a395
             os.rename(o_pri_mbox_file, mbox_file)
e7a395
@@ -292,21 +292,21 @@ script.
e7a395
             newname = "%s.mm_install-dunno_what_this_was_but_its_in_the_way" \
e7a395
                       % o_pri_mbox_file
e7a395
             os.rename(o_pri_mbox_file, newname)
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
     unknown file in the way, moving
e7a395
         %(o_pri_mbox_file)s
e7a395
     to
e7a395
         %(newname)s""")
e7a395
         else:
e7a395
             # directory
e7a395
-            print _('Nothing to do.')
e7a395
+            print C_('Nothing to do.')
e7a395
 
e7a395
 
e7a395
     #
e7a395
     # move public archive mbox there if it's around
e7a395
     # and take into account all sorts of absurdities.
e7a395
     #
e7a395
-    print _('- updating old public mbox file')
e7a395
+    print C_('- updating old public mbox file')
e7a395
     if os.path.exists(o_pub_mbox_file):
e7a395
         if os.path.isfile(o_pub_mbox_file):
e7a395
             os.rename(o_pub_mbox_file, mbox_file)
e7a395
@@ -314,13 +314,13 @@ script.
e7a395
             newname = "%s.mm_install-dunno_what_this_was_but_its_in_the_way" \
e7a395
                       % o_pub_mbox_file
e7a395
             os.rename(o_pub_mbox_file, newname)
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
     unknown file in the way, moving
e7a395
         %(o_pub_mbox_file)s
e7a395
     to
e7a395
         %(newname)s""")
e7a395
         else: # directory
e7a395
-            print _('Nothing to do.')
e7a395
+            print C_('Nothing to do.')
e7a395
 
e7a395
     #
e7a395
     # move the html archives there
e7a395
@@ -350,7 +350,7 @@ script.
e7a395
         b4_tmpl_dir = os.path.join(tmpl_dir, mlist._internal_name)
e7a395
         new_tmpl_dir = os.path.join(list_dir, mlist._internal_name)
e7a395
         if os.path.exists(b4_tmpl_dir):
e7a395
-            print _("""\
e7a395
+            print C_("""\
e7a395
 - This list looks like it might have <= b4 list templates around""")
e7a395
             for f in os.listdir(b4_tmpl_dir):
e7a395
                 o_tmpl = os.path.join(b4_tmpl_dir, f)
e7a395
@@ -358,12 +358,12 @@ script.
e7a395
                 if os.path.exists(o_tmpl):
e7a395
                     if not os.path.exists(n_tmpl):
e7a395
                         os.rename(o_tmpl, n_tmpl)
e7a395
-                        print _('- moved %(o_tmpl)s to %(n_tmpl)s')
e7a395
+                        print C_('- moved %(o_tmpl)s to %(n_tmpl)s')
e7a395
                     else:
e7a395
-                        print _("""\
e7a395
+                        print C_("""\
e7a395
 - both %(o_tmpl)s and %(n_tmpl)s exist, leaving untouched""")
e7a395
                 else:
e7a395
-                    print _("""\
e7a395
+                    print C_("""\
e7a395
 - %(o_tmpl)s doesn't exist, leaving untouched""")
e7a395
     #
e7a395
     # Move all the templates to the en language subdirectory as required for
e7a395
@@ -393,23 +393,23 @@ def remove_old_sources(module):
e7a395
     src = '%s/%s' % (mm_cfg.PREFIX, module)
e7a395
     pyc = src + "c"
e7a395
     if os.path.isdir(src):
e7a395
-        print _('removing directory %(src)s and everything underneath')
e7a395
+        print C_('removing directory %(src)s and everything underneath')
e7a395
         shutil.rmtree(src)
e7a395
     elif os.path.exists(src):
e7a395
-        print _('removing %(src)s')
e7a395
+        print C_('removing %(src)s')
e7a395
         try:
e7a395
             os.unlink(src)
e7a395
         except os.error, rest:
e7a395
-            print _("Warning: couldn't remove %(src)s -- %(rest)s")
e7a395
+            print C_("Warning: couldn't remove %(src)s -- %(rest)s")
e7a395
     if module.endswith('.py') and os.path.exists(pyc):
e7a395
         try:
e7a395
             os.unlink(pyc)
e7a395
         except os.error, rest:
e7a395
-            print _("couldn't remove old file %(pyc)s -- %(rest)s")
e7a395
+            print C_("couldn't remove old file %(pyc)s -- %(rest)s")
e7a395
 
e7a395
 
e7a395
 def update_qfiles():
e7a395
-    print _('updating old qfiles')
e7a395
+    print C_('updating old qfiles')
e7a395
     prefix = `time.time()` + '+'
e7a395
     # Be sure the qfiles/in directory exists (we don't really need the
e7a395
     # switchboard object, but it's convenient for creating the directory).
e7a395
@@ -527,7 +527,7 @@ def dequeue(filebase):
e7a395
                 # This message was unparsable, most likely because its
e7a395
                 # MIME encapsulation was broken.  For now, there's not
e7a395
                 # much we can do about it.
e7a395
-                print _('message is unparsable: %(filebase)s')
e7a395
+                print C_('message is unparsable: %(filebase)s')
e7a395
                 msgfp.close()
e7a395
                 msgfp = None
e7a395
                 if mm_cfg.QRUNNER_SAVE_BAD_MESSAGES:
e7a395
@@ -560,7 +560,7 @@ def update_pending():
e7a395
     except IOError, e:
e7a395
         if e.errno <> errno.ENOENT: raise
e7a395
     else:
e7a395
-        print _('Updating Mailman 2.0 pending_subscriptions.db database')
e7a395
+        print C_('Updating Mailman 2.0 pending_subscriptions.db database')
e7a395
         db = marshal.load(fp)
e7a395
         # Convert to the pre-Mailman 2.1.5 format
e7a395
         db = Pending._update(db)
e7a395
@@ -571,10 +571,10 @@ def update_pending():
e7a395
         except IOError, e:
e7a395
             if e.errno <> errno.ENOENT: raise
e7a395
         else:
e7a395
-            print _('Updating Mailman 2.1.4 pending.pck database')
e7a395
+            print C_('Updating Mailman 2.1.4 pending.pck database')
e7a395
             db = cPickle.load(fp)
e7a395
     if db is None:
e7a395
-        print _('Nothing to do.')
e7a395
+        print C_('Nothing to do.')
e7a395
         return
e7a395
     # Now upgrade the database to the 2.1.5 format.  Each list now has its own
e7a395
     # pending.pck file, but only the RE_ENABLE operation actually recorded the
e7a395
@@ -595,7 +595,7 @@ def update_pending():
e7a395
             op = val[0]
e7a395
             data = val[1:]
e7a395
         except (IndexError, ValueError):
e7a395
-            print _('Ignoring bad pended data: %(key)s: %(val)s')
e7a395
+            print C_('Ignoring bad pended data: %(key)s: %(val)s')
e7a395
             continue
e7a395
         if op in (Pending.UNSUBSCRIPTION, Pending.CHANGE_OF_ADDRESS):
e7a395
             # data[0] is the address being unsubscribed
e7a395
@@ -611,7 +611,7 @@ def update_pending():
e7a395
             # data[0] is the hold id.  There better only be one entry per id
e7a395
             id = data[0]
e7a395
             if holds_by_id.has_key(id):
e7a395
-                print _('WARNING: Ignoring duplicate pending ID: %(id)s.')
e7a395
+                print C_('WARNING: Ignoring duplicate pending ID: %(id)s.')
e7a395
             else:
e7a395
                 holds_by_id[id] = (key, val)
e7a395
     # Now we have to lock every list and re-pend all the appropriate
e7a395
@@ -664,7 +664,7 @@ def update_pending():
e7a395
 def main():
e7a395
     errors = 0
e7a395
     # get rid of old stuff
e7a395
-    print _('getting rid of old source files')
e7a395
+    print C_('getting rid of old source files')
e7a395
     for mod in ('Mailman/Archiver.py', 'Mailman/HyperArch.py',
e7a395
                 'Mailman/HyperDatabase.py', 'Mailman/pipermail.py',
e7a395
                 'Mailman/smtplib.py', 'Mailman/Cookie.py',
e7a395
@@ -674,29 +674,29 @@ def main():
e7a395
         remove_old_sources(mod)
e7a395
     listnames = Utils.list_names()
e7a395
     if not listnames:
e7a395
-        print _('no lists == nothing to do, exiting')
e7a395
+        print C_('no lists == nothing to do, exiting')
e7a395
         return
e7a395
     #
e7a395
     # for people with web archiving, make sure the directories
e7a395
     # in the archiving are set with proper perms for b6.
e7a395
     #
e7a395
     if os.path.isdir("%s/public_html/archives" % mm_cfg.PREFIX):
e7a395
-        print _("""\
e7a395
+        print C_("""\
e7a395
 fixing all the perms on your old html archives to work with b6
e7a395
 If your archives are big, this could take a minute or two...""")
e7a395
         os.path.walk("%s/public_html/archives" % mm_cfg.PREFIX,
e7a395
                      archive_path_fixer, "")
e7a395
-        print _('done')
e7a395
+        print C_('done')
e7a395
     for listname in listnames:
e7a395
-        print _('Updating mailing list: %(listname)s')
e7a395
+        print C_('Updating mailing list: %(listname)s')
e7a395
         errors = errors + dolist(listname)
e7a395
         print
e7a395
-    print _('Updating Usenet watermarks')
e7a395
+    print C_('Updating Usenet watermarks')
e7a395
     wmfile = os.path.join(mm_cfg.DATA_DIR, 'gate_watermarks')
e7a395
     try:
e7a395
         fp = open(wmfile)
e7a395
     except IOError:
e7a395
-        print _('- nothing to update here')
e7a395
+        print C_('- nothing to update here')
e7a395
     else:
e7a395
         d = marshal.load(fp)
e7a395
         fp.close()
e7a395
@@ -708,7 +708,7 @@ If your archives are big, this could take a minute or two...""")
e7a395
             try:
e7a395
                 mlist.Lock(0.5)
e7a395
             except TimeOutError:
e7a395
-                print >> sys.stderr, _(
e7a395
+                print >> sys.stderr, C_(
e7a395
                     'WARNING: could not acquire lock for list: %(listname)s')
e7a395
                 errors = errors + 1
e7a395
             else:
e7a395
@@ -719,7 +719,7 @@ If your archives are big, this could take a minute or two...""")
e7a395
                 mlist.Save()
e7a395
                 mlist.Unlock()
e7a395
         os.unlink(wmfile)
e7a395
-        print _('- usenet watermarks updated and gate_watermarks removed')
e7a395
+        print C_('- usenet watermarks updated and gate_watermarks removed')
e7a395
     # In Mailman 2.1, the pending database format and file name changed, but
e7a395
     # in Mailman 2.1.5 it changed again.  This should update all existing
e7a395
     # files to the 2.1.5 format.
e7a395
@@ -733,7 +733,7 @@ If your archives are big, this could take a minute or two...""")
e7a395
     # There's no good way of figuring this out for releases prior to 2.0beta2
e7a395
     # :(
e7a395
     if lastversion == NOTFRESH:
e7a395
-        print _("""
e7a395
+        print C_("""
e7a395
 
e7a395
 NOTE NOTE NOTE NOTE NOTE
e7a395
 
e7a395
@@ -760,7 +760,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__) % globals()
e7a395
+    print >> fd, C_(__doc__) % globals()
e7a395
     if msg:
e7a395
         print >> sys.stderr, msg
e7a395
     sys.exit(code)
e7a395
@@ -790,15 +790,15 @@ if __name__ == '__main__':
e7a395
     hextversion = hex(thisversion)
e7a395
     if lastversion == thisversion and not force:
e7a395
         # nothing to do
e7a395
-        print _('No updates are necessary.')
e7a395
+        print C_('No updates are necessary.')
e7a395
         sys.exit(0)
e7a395
     if lastversion > thisversion and not force:
e7a395
-        print _("""\
e7a395
+        print C_("""\
e7a395
 Downgrade detected, from version %(hexlversion)s to version %(hextversion)s
e7a395
 This is probably not safe.
e7a395
 Exiting.""")
e7a395
         sys.exit(1)
e7a395
-    print _('Upgrading from version %(hexlversion)s to %(hextversion)s')
e7a395
+    print C_('Upgrading from version %(hexlversion)s to %(hextversion)s')
e7a395
     errors = main()
e7a395
     if not errors:
e7a395
         # Record the version we just upgraded to
e7a395
@@ -807,7 +807,7 @@ Exiting.""")
e7a395
         fp.close()
e7a395
     else:
e7a395
         lockdir = mm_cfg.LOCK_DIR
e7a395
-        print _('''\
e7a395
+        print C_('''\
e7a395
 
e7a395
 ERROR:
e7a395
 
e7a395
diff --git a/bin/version b/bin/version
e7a395
index 72c50b8..4efba6f 100644
e7a395
--- a/bin/version
e7a395
+++ b/bin/version
e7a395
@@ -21,6 +21,6 @@
e7a395
 
e7a395
 import paths
e7a395
 import Mailman.mm_cfg
e7a395
-from Mailman.i18n import _
e7a395
+from Mailman.i18n import C_
e7a395
 
e7a395
-print _('Using Mailman version:'), Mailman.mm_cfg.VERSION
e7a395
+print C_('Using Mailman version:'), Mailman.mm_cfg.VERSION
e7a395
diff --git a/bin/withlist b/bin/withlist
e7a395
index 38ab9ab..b23588a 100644
e7a395
--- a/bin/withlist
e7a395
+++ b/bin/withlist
e7a395
@@ -154,7 +154,7 @@ def usage(code, msg=''):
e7a395
         fd = sys.stderr
e7a395
     else:
e7a395
         fd = sys.stdout
e7a395
-    print >> fd, _(__doc__)
e7a395
+    print >> fd, C_(__doc__)
e7a395
     if msg:
e7a395
         print >> fd, msg
e7a395
     sys.exit(code)
e7a395
@@ -172,11 +172,11 @@ def atexit():
e7a395
     if m.Locked():
e7a395
         if VERBOSE:
e7a395
             listname = m.internal_name()
e7a395
-            print >> sys.stderr, _(
e7a395
+            print >> sys.stderr, C_(
e7a395
                 'Unlocking (but not saving) list: %(listname)s')
e7a395
         m.Unlock()
e7a395
     if VERBOSE:
e7a395
-        print >> sys.stderr, _('Finalizing')
e7a395
+        print >> sys.stderr, C_('Finalizing')
e7a395
     del m
e7a395
 
e7a395
 
e7a395
@@ -185,16 +185,16 @@ def do_list(listname, args, func):
e7a395
     global m
e7a395
     # first try to open mailing list
e7a395
     if VERBOSE:
e7a395
-        print >> sys.stderr, _('Loading list %(listname)s'),
e7a395
+        print >> sys.stderr, C_('Loading list %(listname)s'),
e7a395
         if LOCK:
e7a395
-            print >> sys.stderr, _('(locked)')
e7a395
+            print >> sys.stderr, C_('(locked)')
e7a395
         else:
e7a395
-            print >> sys.stderr, _('(unlocked)')
e7a395
+            print >> sys.stderr, C_('(unlocked)')
e7a395
 
e7a395
     try:
e7a395
         m = MailList.MailList(listname, lock=LOCK)
e7a395
     except Errors.MMUnknownListError:
e7a395
-        print >> sys.stderr, _('Unknown list: %(listname)s')
e7a395
+        print >> sys.stderr, C_('Unknown list: %(listname)s')
e7a395
         m = None
e7a395
 
e7a395
     # try to import the module and run the callable
e7a395
@@ -234,7 +234,7 @@ def main():
e7a395
             all = True
e7a395
 
e7a395
     if len(args) < 1 and not all:
e7a395
-        warning = _('No list name supplied.')
e7a395
+        warning = C_('No list name supplied.')
e7a395
         if interact:
e7a395
             # Let them keep going
e7a395
             print warning
e7a395
@@ -243,7 +243,7 @@ def main():
e7a395
             usage(1, warning)
e7a395
 
e7a395
     if all and not run:
e7a395
-        usage(1, _('--all requires --run'))
e7a395
+        usage(1, C_('--all requires --run'))
e7a395
 
e7a395
     # The default for interact is 1 unless -r was given
e7a395
     if interact is None:
e7a395
@@ -263,11 +263,11 @@ def main():
e7a395
             module = run[:i]
e7a395
             callable = run[i+1:]
e7a395
         if VERBOSE:
e7a395
-            print >> sys.stderr, _('Importing %(module)s...')
e7a395
+            print >> sys.stderr, C_('Importing %(module)s...')
e7a395
         __import__(module)
e7a395
         mod = sys.modules[module]
e7a395
         if VERBOSE:
e7a395
-            print >> sys.stderr, _('Running %(module)s.%(callable)s()...')
e7a395
+            print >> sys.stderr, C_('Running %(module)s.%(callable)s()...')
e7a395
         func = getattr(mod, callable)
e7a395
 
e7a395
     if all:
e7a395
@@ -288,7 +288,7 @@ def main():
e7a395
         namespace = globals().copy()
e7a395
         namespace.update(locals())
e7a395
         if dolist:
e7a395
-            ban = _("The variable `m' is the %(listname)s MailList instance")
e7a395
+            ban = C_("The variable `m' is the %(listname)s MailList instance")
e7a395
         else:
e7a395
             ban = None
e7a395
         code.InteractiveConsole(namespace).interact(ban)