? rejects.txt
Index: INSTALL
===================================================================
RCS file: /cvsroot/mailman/mailman/INSTALL,v
retrieving revision 1.48
retrieving revision 1.48.2.1
diff -u -r1.48 -r1.48.2.1
--- INSTALL	16 Nov 2000 21:57:37 -0000	1.48
+++ INSTALL	2 Jul 2002 16:28:37 -0000	1.48.2.1
@@ -1,5 +1,5 @@
 Mailman - The GNU Mailing List Management System
-Copyright (C) 1998,1999,2000 Free Software Foundation, Inc.
+Copyright (C) 1998,1999,2000,2001,2002 Free Software Foundation, Inc.
 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 This file contains installation instructions for GNU Mailman, which is
@@ -19,12 +19,12 @@
 0. Installation requirements
 
     You must have the Python interpreter installed somewhere on your
-    system.  Currently Python 1.5.2 or later is required (Python 2.0
-    should work fine).  For information about obtaining Python source
-    code, RPM packages, or pre-compiled binaries please see:
+    system.  Currently Python 1.5.2 or later is required, but the
+    latest stable releases of Python 2.1.3 and 2.2.1 are recommended.
+    For information about obtaining Python source code, RPM packages,
+    or pre-compiled binaries please see:
 
         http://www.python.org
-        http://www.pythonlabs.com
 
     You must also have an ANSI C compiler in order to build the
     wrapper programs which are used for improved security.  The GNU C
@@ -180,6 +180,28 @@
       --with-gcc=no
             Don't use gcc, even if it is found.  `cc' must be found on
             your $PATH
+
+    You may also need to set the "mailhost" and the "wwwhost"
+    values.  The mailhost value is what is used as the domain part of
+    an email address, e.g. the "dom.ain" in "aperson@dom.ain".  The
+    "wwwhost" is the domain part of your urls, e.g. the "www.dom.ain"
+    in "http://www.dom.ain/mailman/listinfo".
+
+    The configure script tries to guess these based on system
+    information, but it may fail or be incorrect.  If it fails, the
+    configure script will exit.  In either case you can set these host
+    values by setting the environment variables $MAILHOST and $WWWHOST
+    before you run configure, e.g.:
+
+        % MAILHOST=mail.dom.ain
+        % WWWHOST=www.dom.ain
+        % export MAILHOST WWWHOST
+        % ./configure ...
+
+    Note that if you do not set $WWWHOST, the value for $MAILHOST will
+    be used automatically.  Also, you can always change these values
+    by adding some settings to your mm_cfg.py file after you've built
+    and installed Mailman.  See below for details.
 
 
 3. Check your installation
Index: NEWS
===================================================================
RCS file: /cvsroot/mailman/mailman/NEWS,v
retrieving revision 1.25.2.15
retrieving revision 1.25.2.16
diff -u -r1.25.2.15 -r1.25.2.16
--- NEWS	20 May 2002 15:22:32 -0000	1.25.2.15
+++ NEWS	2 Jul 2002 17:34:17 -0000	1.25.2.16
@@ -1,8 +1,23 @@
 Mailman - The GNU Mailing List Management System
-Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 Here is a history of user visible changes to Mailman.
+
+2.0.12 (02-Jul-2002)
+
+    - Implemented a guard against some reply loops and 'bot
+      subscription attacks.  Specifically, if a message to -request
+      has a Precedence: bulk (or list, or junk) header, the command is
+      ignored.  Well-behaved 'bots should always include such a
+      header.
+
+    - Changes to the configure script so that you can pass in the mail
+      host and web host by setting the environment variables MAILHOST
+      and WWWHOST respectively.  configure will also exit if it can't
+      figure out these values (usually due to broken dns).
+
+    - Closed another minor cross-site scripting vulnerability.
 
 2.0.11 (20-May-2002)
 
Index: README
===================================================================
RCS file: /cvsroot/mailman/mailman/README,v
retrieving revision 1.53.2.1
retrieving revision 1.53.2.2
diff -u -r1.53.2.1 -r1.53.2.2
--- README	3 Jan 2001 16:48:18 -0000	1.53.2.1
+++ README	2 Jul 2002 16:28:55 -0000	1.53.2.2
@@ -1,5 +1,5 @@
 Mailman - The GNU Mailing List Management System
-Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 INTRODUCTION
@@ -36,7 +36,9 @@
 
         http://www.python.org
 
-    It should work fine with Python 1.6 and 2.0.
+    It should work fine with the latest stable Python releases,
+    version 2.1.3 and 2.2.1.  These releases are recommended over
+    Python 1.5.2.
 
     You will also need an ANSI C compiler; gcc (the GNU C compiler)
     works just fine.  Mailman currently works only on Unix-alike
Index: configure
===================================================================
RCS file: /cvsroot/mailman/mailman/configure,v
retrieving revision 1.49
retrieving revision 1.49.2.1
diff -u -r1.49 -r1.49.2.1
--- configure	22 Sep 2000 16:56:44 -0000	1.49
+++ configure	2 Jul 2002 16:30:50 -0000	1.49.2.1
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# From configure.in Revision: 1.50 
+# From configure.in Revision: 1.51 
 
 # Guess values for system-dependent variables and create Makefiles.
 # Generated automatically using autoconf version 2.13 
@@ -1454,10 +1454,26 @@
 # attempt to figure out the default hostname and URL
 from socket import *
 import string
-fqdn = None
-www = None
-host, aliases, ipaddrs = gethostbyaddr(gethostbyname(gethostname()))
-aliases.insert(0, host)
+import sys
+import os
+def barf(fqdn, www):
+    sys.stdout = sys.stderr
+    print 'host info not found, set \$MAILHOST and/or \$WWWHOST environ vars'
+    print '\$MAILHOST=%s, \$WWWHOST=%s' % (fqdn, www)
+    sys.exit(1)
+fqdn = os.environ.get('MAILHOST')
+www = os.environ.get('WWWHOST')
+aliases = []
+if fqdn:
+    aliases.append(fqdn)
+if www:
+    aliases.append(www)
+if not fqdn:
+    try:
+        host, aliases, ipaddrs = gethostbyaddr(gethostbyname(gethostname()))
+    except herror:
+        barf(fqdn, www)
+    aliases.insert(0, host)
 for h in aliases:
     parts = string.split(h, '.')
     if 5 > 1:
@@ -1467,6 +1483,10 @@
             fqdn = h
     if www and fqdn:
         break
+if fqdn is None:
+    barf(fqdn, www)
+if www is None:
+    www = fqdn
 fp = open('conftest.out', 'w')
 if not www and fqdn:
     fp.write('%s\n%s\n' % (fqdn, fqdn))
@@ -1478,16 +1498,20 @@
 fp.close()
 EOF
 $PYTHON conftest.py
+if [ "$?" == "1" ]
+then
+    exit
+fi
 
 echo $ac_n "checking for default fully qualified host name""... $ac_c" 1>&6
-echo "configure:1484: checking for default fully qualified host name" >&5
+echo "configure:1508: checking for default fully qualified host name" >&5
 if test -z "$FQDN"
 then
     FQDN=`head -1 conftest.out`
 fi
 echo "$ac_t""$FQDN" 1>&6
 echo $ac_n "checking for default URL host component""... $ac_c" 1>&6
-echo "configure:1491: checking for default URL host component" >&5
+echo "configure:1515: checking for default URL host component" >&5
 if test -z "$URL"
 then
     URL=`tail -1 conftest.out`
@@ -1499,12 +1523,12 @@
 for ac_func in strerror setregid syslog
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1503: checking for $ac_func" >&5
+echo "configure:1527: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1508 "configure"
+#line 1532 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1527,7 +1551,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1558,17 +1582,17 @@
   # with the appropriate include.
   for lib in bsd socket inet; do
     echo $ac_n "checking for syslog in -l$lib""... $ac_c" 1>&6
-echo "configure:1562: checking for syslog in -l$lib" >&5
+echo "configure:1586: checking for syslog in -l$lib" >&5
     Mailman_LIBS_save="$LIBS"; LIBS="$LIBS -l$lib"
     cat > conftest.$ac_ext <<EOF
-#line 1565 "configure"
+#line 1589 "configure"
 #include "confdefs.h"
 #include <syslog.h>
 int main() {
 syslog(LOG_DEBUG, "Just a test...");
 ; return 0; }
 EOF
-if { (eval echo configure:1572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
       cat >> confdefs.h <<\EOF
@@ -1590,7 +1614,7 @@
 
 # Checks for header files.
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1594: checking how to run the C preprocessor" >&5
+echo "configure:1618: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1605,13 +1629,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1609 "configure"
+#line 1633 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1615: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1639: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1622,13 +1646,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1626 "configure"
+#line 1650 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1632: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1656: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1639,13 +1663,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1643 "configure"
+#line 1667 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1649: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1673: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1670,12 +1694,12 @@
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1674: checking for ANSI C header files" >&5
+echo "configure:1698: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1679 "configure"
+#line 1703 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1683,7 +1707,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1711: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1700,7 +1724,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1704 "configure"
+#line 1728 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1718,7 +1742,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1722 "configure"
+#line 1746 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1739,7 +1763,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1743 "configure"
+#line 1767 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1750,7 +1774,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:1754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1777,17 +1801,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1781: checking for $ac_hdr" >&5
+echo "configure:1805: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1786 "configure"
+#line 1810 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1791: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1816,12 +1840,12 @@
 
 # Checks for typedefs, structures, and compiler characteristics.
 echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1820: checking for uid_t in sys/types.h" >&5
+echo "configure:1844: checking for uid_t in sys/types.h" >&5
 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1825 "configure"
+#line 1849 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
@@ -1850,7 +1874,7 @@
 fi
 
 echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
-echo "configure:1854: checking type of array argument to getgroups" >&5
+echo "configure:1878: checking type of array argument to getgroups" >&5
 if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1858,7 +1882,7 @@
   ac_cv_type_getgroups=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 1862 "configure"
+#line 1886 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Rendell for this test.  */
@@ -1883,7 +1907,7 @@
 }
 
 EOF
-if { (eval echo configure:1887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
     ac_cv_type_getgroups=gid_t
 else
@@ -1897,7 +1921,7 @@
 
 if test $ac_cv_type_getgroups = cross; then
         cat > conftest.$ac_ext <<EOF
-#line 1901 "configure"
+#line 1925 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 EOF
@@ -1925,12 +1949,12 @@
 for ac_func in vsnprintf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1929: checking for $ac_func" >&5
+echo "configure:1953: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1934 "configure"
+#line 1958 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1953,7 +1977,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
Index: configure.in
===================================================================
RCS file: /cvsroot/mailman/mailman/configure.in,v
retrieving revision 1.51
retrieving revision 1.51.2.1
diff -u -r1.51 -r1.51.2.1
--- configure.in	22 Sep 2000 16:56:44 -0000	1.51
+++ configure.in	2 Jul 2002 16:30:50 -0000	1.51.2.1
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,7 +15,7 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 dnl Process this file with autoconf to produce a configure script.
-AC_REVISION($Revision: 1.51 $)
+AC_REVISION($Revision: 1.51.2.1 $)
 AC_PREREQ(2.0)
 AC_INIT(src/alias-wrapper.c)
 
@@ -397,10 +397,26 @@
 # attempt to figure out the default hostname and URL
 from socket import *
 import string
-fqdn = None
-www = None
-host, aliases, ipaddrs = gethostbyaddr(gethostbyname(gethostname()))
-aliases.insert(0, host)
+import sys
+import os
+def barf(fqdn, www):
+    sys.stdout = sys.stderr
+    print 'host info not found, set \$MAILHOST and/or \$WWWHOST environ vars'
+    print '\$MAILHOST=%s, \$WWWHOST=%s' % (fqdn, www)
+    sys.exit(1)
+fqdn = os.environ.get('MAILHOST')
+www = os.environ.get('WWWHOST')
+aliases = []
+if fqdn:
+    aliases.append(fqdn)
+if www:
+    aliases.append(www)
+if not fqdn:
+    try:
+        host, aliases, ipaddrs = gethostbyaddr(gethostbyname(gethostname()))
+    except herror:
+        barf(fqdn, www)
+    aliases.insert(0, host)
 for h in aliases:
     parts = string.split(h, '.')
     if len(parts) > 1:
@@ -410,6 +426,10 @@
             fqdn = h
     if www and fqdn:
         break
+if fqdn is None:
+    barf(fqdn, www)
+if www is None:
+    www = fqdn
 fp = open('conftest.out', 'w')
 if not www and fqdn:
     fp.write('%s\n%s\n' % (fqdn, fqdn))
@@ -421,6 +441,10 @@
 fp.close()
 EOF
 $PYTHON conftest.py
+if [ "$?" == "1" ]
+then
+    exit
+fi
 changequote([, ])
 AC_MSG_CHECKING(for default fully qualified host name)
 if test -z "$FQDN"
Index: Mailman/MailCommandHandler.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Attic/MailCommandHandler.py,v
retrieving revision 1.70
retrieving revision 1.70.2.1
diff -u -r1.70 -r1.70.2.1
--- Mailman/MailCommandHandler.py	1 Aug 2000 22:03:23 -0000	1.70
+++ Mailman/MailCommandHandler.py	2 Jul 2002 16:33:23 -0000	1.70.2.1
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -110,11 +110,23 @@
         self.AddToResponse(text, trunc=trunc, prefix=prefix)
 	
     def ParseMailCommands(self, msg):
-        # Break any infloops.  If this has come from a Mailman server then
-        # it'll have this header.  It's still possible to infloop between two
-        # servers because there's no guaranteed way to know it came from a
-        # bot.
-        if msg.get('x-beenthere') or msg.get('list-id'):
+        # Break any mail loops, as defined by the presence of a
+        #
+        # 1. Precedence: header with values "bulk", "list", or "junk"
+        # 2. Mailman X-BeenThere: header, regardless of the value.
+        # 3. An RFC 2369 List-Id: header
+        #
+        # Note further that some misconfigured list managers don't include any
+        # of these clues, so there's little we can do to break loops in that
+        # case, except throttle the number of responses sent to any one
+        # requester in a day.  That's a job for MM2.1.
+        precedence = msg.get('precedence', '').lower()
+        ack = msg.get('x-ack', '').lower()
+        beenthere = msg.get('x-beenthere', '')
+        listid = msg.get('list-id', '')
+        if (precedence in ('bulk', 'list', 'junk') or
+            beenthere or listid) and not ack == 'yes':
+            # Then
             return
         # check the autoresponse stuff
         if self.autorespond_requests:
Index: Mailman/Utils.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Utils.py,v
retrieving revision 1.104.2.8
retrieving revision 1.104.2.9
diff -u -r1.104.2.8 -r1.104.2.9
--- Mailman/Utils.py	20 May 2002 14:37:32 -0000	1.104.2.8
+++ Mailman/Utils.py	2 Jul 2002 17:04:17 -0000	1.104.2.9
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -422,8 +422,7 @@
 
 
 def QuoteHyperChars(str):
-    from cgi import escape
-    return escape(str, quote=1)
+    return cgi.escape(str, quote=1)
 
 
 
@@ -631,7 +630,7 @@
     elif os.environ.has_key('SCRIPT_NAME') and os.environ.has_key('PATH_INFO'):
         url = os.environ['SCRIPT_NAME'] + os.environ['PATH_INFO']
     if escape:
-        return cgi.escape(url)
+        return QuoteHyperChars(url)
     return url
 
 
Index: Mailman/Version.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Version.py,v
retrieving revision 1.20.2.11
retrieving revision 1.20.2.12
diff -u -r1.20.2.11 -r1.20.2.12
--- Mailman/Version.py	20 May 2002 15:16:08 -0000	1.20.2.11
+++ Mailman/Version.py	2 Jul 2002 17:23:32 -0000	1.20.2.12
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,7 +15,7 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 # Mailman version
-VERSION = "2.0.11"
+VERSION = "2.0.12"
 
 # And as a hex number in the manner of PY_VERSION_HEX
 ALPHA = 0xa
@@ -27,7 +27,7 @@
 
 MAJOR_REV = 2
 MINOR_REV = 0
-MICRO_REV = 11
+MICRO_REV = 12
 REL_LEVEL = FINAL
 # at most 15 beta releases!
 REL_SERIAL = 0
Index: Mailman/Cgi/admin.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admin.py,v
retrieving revision 1.82.2.5
retrieving revision 1.82.2.6
diff -u -r1.82.2.5 -r1.82.2.6
--- Mailman/Cgi/admin.py	27 Nov 2001 20:23:53 -0000	1.82.2.5
+++ Mailman/Cgi/admin.py	2 Jul 2002 17:04:17 -0000	1.82.2.6
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -68,7 +68,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attack
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         FormatAdminOverview('No such list <em>%s</em>' % safelistname)
         syslog('error', 'Someone tried to access the admin interface for a '
                'non-existent list: %s' % listname)
Index: Mailman/Cgi/admindb.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admindb.py,v
retrieving revision 1.36.2.7
retrieving revision 1.36.2.8
diff -u -r1.36.2.7 -r1.36.2.8
--- Mailman/Cgi/admindb.py	1 Apr 2002 18:47:46 -0000	1.36.2.7
+++ Mailman/Cgi/admindb.py	2 Jul 2002 17:04:17 -0000	1.36.2.8
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -67,7 +67,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attack
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         handle_no_list(doc, 'No such list <em>%s</em><p>' % safelistname)
         syslog('error', 'No such list "%s": %s\n' % (listname, e))
         return
@@ -207,10 +207,10 @@
             return
         raise
     t = Table(cellspacing=0, cellpadding=0, width='100%')
-    t.AddRow([Bold('From:'), cgi.escape(sender)])
+    t.AddRow([Bold('From:'), Utils.QuoteHyperChars(sender)])
     row, col = t.GetCurrentRowIndex(), t.GetCurrentCellIndex()
     t.AddCellInfo(row, col-1, align='right')
-    t.AddRow([Bold('Subject:'), cgi.escape(subject)])
+    t.AddRow([Bold('Subject:'), Utils.QuoteHyperChars(subject)])
     t.AddCellInfo(row+1, col-1, align='right')
     t.AddRow([Bold('Reason:'), reason])
     t.AddCellInfo(row+2, col-1, align='right')
@@ -248,12 +248,12 @@
     t.AddCellInfo(row, col-1, align='right')
     t.AddRow([Bold('Message Headers:'),
               TextArea('headers-%d' % id,
-                       cgi.escape(string.join(msg.headers, '')),
+                       Utils.QuoteHyperChars(string.join(msg.headers, '')),
                        rows=10, cols=80)])
     row, col = t.GetCurrentRowIndex(), t.GetCurrentCellIndex()
     t.AddCellInfo(row, col-1, align='right')
     t.AddRow([Bold('Message Excerpt:'),
-              TextArea('fulltext-%d' % id, cgi.escape(text),
+              TextArea('fulltext-%d' % id, Utils.QuoteHyperChars(text),
                        rows=10, cols=80)])
     t.AddCellInfo(row+1, col-1, align='right')
     form.AddItem(t)
Index: Mailman/Cgi/edithtml.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/edithtml.py,v
retrieving revision 1.12.2.1
retrieving revision 1.12.2.2
diff -u -r1.12.2.1 -r1.12.2.2
--- Mailman/Cgi/edithtml.py	27 Nov 2001 20:23:53 -0000	1.12.2.1
+++ Mailman/Cgi/edithtml.py	2 Jul 2002 17:04:17 -0000	1.12.2.2
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -50,7 +50,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attack
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         doc.AddItem(Header(2, 'No such list <em>%s</em>' % safelistname))
         print doc.Format(bgcolor='#ffffff')
         syslog('error', 'No such list "%s": %s\n' % (listname, e))
@@ -77,7 +77,7 @@
                 break
         else:
             # Avoid cross-site scripting attack
-            safetmplname = cgi.escape(template_name)
+            safetmplname = Utils.QuoteHyperChars(template_name)
             doc.SetTitle('Edit HTML : Error')
             doc.AddItem(Header(2, "%s: Invalid template" % safetmplname))
             doc.AddItem(mlist.GetMailmanFooter())
Index: Mailman/Cgi/handle_opts.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/Attic/handle_opts.py,v
retrieving revision 1.30.2.4
retrieving revision 1.30.2.5
diff -u -r1.30.2.4 -r1.30.2.5
--- Mailman/Cgi/handle_opts.py	27 Nov 2001 20:23:53 -0000	1.30.2.4
+++ Mailman/Cgi/handle_opts.py	2 Jul 2002 17:04:17 -0000	1.30.2.5
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -35,7 +35,7 @@
     if user:
         # Avoid cross-site scripting attack
         url = '%s/%s' % (mlist.GetScriptURL('options'),
-                         Utils.ObscureEmail(cgi.escape(user)))
+                         Utils.ObscureEmail(Utils.QuoteHyperChars(user)))
         results = results + '<p>Continue to ' + \
                   Link(url, 'edit your personal options').Format() + \
                   '.'
@@ -66,7 +66,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attack
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         doc.AddItem(Header(2, "Error"))
         doc.AddItem(Bold('No such list <em>%s</em>' % safelistname))
         print doc.Format(bgcolor="#ffffff")
@@ -110,7 +110,7 @@
     if not Utils.FindMatchingAddresses(user, mlist.members,
                                        mlist.digest_members):
         # Avoid cross-site scripting attack
-        safeuser = cgi.escape(user)
+        safeuser = Utils.QuoteHyperChars(user)
         PrintResults(mlist, operation, doc, "%s not a member!<p>" % safeuser)
 
     if form.has_key("unsub"):
Index: Mailman/Cgi/listinfo.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/listinfo.py,v
retrieving revision 1.21.2.1
retrieving revision 1.21.2.2
diff -u -r1.21.2.1 -r1.21.2.2
--- Mailman/Cgi/listinfo.py	27 Nov 2001 20:23:53 -0000	1.21.2.1
+++ Mailman/Cgi/listinfo.py	2 Jul 2002 17:04:17 -0000	1.21.2.2
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -43,7 +43,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attack
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         FormatListinfoOverview('No such list <em>%s</em>' % safelistname)
         syslog('error', 'listinfo: no such list "%s": %s' % (listname, e))
         return
Index: Mailman/Cgi/options.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/options.py,v
retrieving revision 1.18.2.1
retrieving revision 1.18.2.2
diff -u -r1.18.2.1 -r1.18.2.2
--- Mailman/Cgi/options.py	27 Nov 2001 20:23:54 -0000	1.18.2.1
+++ Mailman/Cgi/options.py	2 Jul 2002 17:04:17 -0000	1.18.2.2
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -55,7 +55,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attacks
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         doc.AddItem(Header(2, "Error"))
         doc.AddItem(Bold('No such list <em>%s</em>' % safelistname))
         print doc.Format()
@@ -67,7 +67,7 @@
     if not mlist.members.has_key(user) and \
             not mlist.digest_members.has_key(user):
         # Avoid cross-site scripting attacks
-        safeuser = cgi.escape(user)
+        safeuser = Utils.QuoteHyperChars(user)
         doc.AddItem(Header(2, "Error"))
         doc.AddItem(Bold("%s: No such member %s." % (listname, safeuser)))
         doc.AddItem(mlist.GetMailmanFooter())
Index: Mailman/Cgi/private.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/private.py,v
retrieving revision 1.23.2.1
retrieving revision 1.23.2.2
diff -u -r1.23.2.1 -r1.23.2.2
--- Mailman/Cgi/private.py	27 Nov 2001 20:23:54 -0000	1.23.2.1
+++ Mailman/Cgi/private.py	2 Jul 2002 17:04:17 -0000	1.23.2.2
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -131,7 +131,7 @@
         mlist.IsListInitialized()
     except Errors.MMListError, e:
         # Avoid cross-site scripting attacks
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         msg = 'No such list <em>%s</em>' % safelistname
         doc.SetTitle("Private Archive Error - %s" % msg)
         doc.AddItem(Header(2, msg))
@@ -193,8 +193,8 @@
             f = open(true_filename, 'r')
     except IOError:
         # Avoid cross-site scripting attacks
-        safetruefilename = cgi.escape(true_filename)
-        safepath = cgi.escape(path)
+        safetruefilename = Utils.QuoteHyperChars(true_filename)
+        safepath = Utils.QuoteHyperChars(path)
         print 'Content-type: text/html\n'
 
         print "<H3>Archive File Not Found</H3>"
Index: Mailman/Cgi/roster.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/roster.py,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.2
diff -u -r1.11.2.1 -r1.11.2.2
--- Mailman/Cgi/roster.py	27 Nov 2001 20:23:54 -0000	1.11.2.1
+++ Mailman/Cgi/roster.py	2 Jul 2002 17:04:17 -0000	1.11.2.2
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -48,7 +48,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attacks
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         error_page('No such list <em>%s</em>' % safelistname)
         syslog('error', 'roster: no such list "%s": %s' % (listname, e))
         return
Index: Mailman/Cgi/subscribe.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/subscribe.py,v
retrieving revision 1.29.2.2
retrieving revision 1.29.2.3
diff -u -r1.29.2.2 -r1.29.2.3
--- Mailman/Cgi/subscribe.py	27 Nov 2001 20:23:54 -0000	1.29.2.2
+++ Mailman/Cgi/subscribe.py	2 Jul 2002 17:04:17 -0000	1.29.2.3
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -45,7 +45,7 @@
         mlist = MailList.MailList(listname, lock=0)
     except Errors.MMListError, e:
         # Avoid cross-site scripting attacks
-        safelistname = cgi.escape(listname)
+        safelistname = Utils.QuoteHyperChars(listname)
         doc.AddItem(Header(2, "Error"))
         doc.AddItem(Bold('No such list <em>%s</em>' % safelistname))
         print doc.Format(bgcolor="#ffffff")
@@ -118,7 +118,7 @@
         if not member:
             doc.AddItem(Header(2, "Error"))
             doc.AddItem(Bold("%s has no subscribed addr <i>%s</i>."
-                             % (mlist.real_name, addr)))
+                             % (mlist.real_name, Utils.QuoteHyperChars(addr))))
             doc.AddItem(mlist.GetMailmanFooter())
             print doc.Format(bgcolor="#ffffff")
             return
Index: admin/www/download.ht
===================================================================
RCS file: /cvsroot/mailman/mailman/admin/www/download.ht,v
retrieving revision 1.5.2.14
retrieving revision 1.5.2.15
diff -u -r1.5.2.14 -r1.5.2.15
--- admin/www/download.ht	20 May 2002 15:17:42 -0000	1.5.2.14
+++ admin/www/download.ht	2 Jul 2002 17:24:54 -0000	1.5.2.15
@@ -60,9 +60,9 @@
 <h3>Downloading</h3>
 
 <p>Version
-(<!-VERSION--->2.0.11<!-VERSION--->,
+(<!-VERSION--->2.0.12<!-VERSION--->,
 released on
-<!-DATE--->May 20 2002<!-DATE--->)
+<!-DATE--->Jul  2 2002<!-DATE--->)
 is the current GNU release.  It is available from the following mirror sites:
 
 <ul>
Index: admin/www/download.html
===================================================================
RCS file: /cvsroot/mailman/mailman/admin/www/download.html,v
retrieving revision 1.6.2.16
retrieving revision 1.6.2.17
diff -u -r1.6.2.16 -r1.6.2.17
--- admin/www/download.html	20 May 2002 15:17:42 -0000	1.6.2.16
+++ admin/www/download.html	2 Jul 2002 17:24:55 -0000	1.6.2.17
@@ -1,7 +1,7 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <!-- THIS PAGE IS AUTOMATICALLY GENERATED.  DO NOT EDIT. -->
-<!-- Mon May 20 11:16:31 2002 -->
+<!-- Tue Jul  2 13:24:21 2002 -->
 <!-- USING HT2HTML 2.0 -->
 <!-- SEE http://ht2html.sf.net -->
 <!-- User-specified headers:
@@ -246,9 +246,9 @@
 <h3>Downloading</h3>
 
 <p>Version
-(<!-VERSION--->2.0.11<!-VERSION--->,
+(<!-VERSION--->2.0.12<!-VERSION--->,
 released on
-<!-DATE--->May 20 2002<!-DATE--->)
+<!-DATE--->Jul  2 2002<!-DATE--->)
 is the current GNU release.  It is available from the following mirror sites:
 
 <ul>
Index: src/common.c
===================================================================
RCS file: /cvsroot/mailman/mailman/src/common.c,v
retrieving revision 1.26.2.1
retrieving revision 1.26.2.2
diff -u -r1.26.2.1 -r1.26.2.2
--- src/common.c	29 May 2001 13:20:27 -0000	1.26.2.1
+++ src/common.c	2 Jul 2002 17:24:29 -0000	1.26.2.2
@@ -96,15 +96,9 @@
 		printf("<title>Mailman CGI error!!!</title>\n");
 		printf("</head><body>\n");
 		printf("<h1>Mailman CGI error!!!</h1>\n");
-		printf("The expected gid of the Mailman CGI wrapper did ");
-		printf("not match the gid as set by the Web server.");
-		printf("<p>The most likely cause is that Mailman was ");
-		printf("configured and installed incorrectly.  Please ");
-		printf("read the INSTALL instructions again, paying close ");
-		printf("attention to the <tt>--with-cgi-gid</tt> configure ");
-		printf("option.  This entry is being stored in your syslog:");
+		printf("This entry is being stored in your syslog:");
 		printf("\n<pre>\n");
-		printf(log_entry);
+		printf("%s\n", log_entry);
 		printf("</pre>\n");
 	}
 	else