Subject: Apply SpamAssassin + ht://Dig support

From: Raphael Bossek <[email-masked]>
Date: Tue, 12 Jul 2005 11:17:40 +0200

Package: mailman
Severity: wishlist
Tags: patch

Hi, I've create a patch which integrate SpamAssassin and ht://Dig
support to Mailman. It would be nice to see this applied by default
in Debian's Mailman package.

-- 
Raphael Bossek
diff -Naur mailman-2.1.5/debian/cron.daily mailman-2.1.5-9.htdig+spamassasin.2/debian/cron.daily
--- mailman-2.1.5/debian/cron.daily	2005-07-11 08:36:23.089984352 +0200
+++ mailman-2.1.5-9.htdig+spamassasin.2/debian/cron.daily	2005-07-04 22:28:53.000000000 +0200
@@ -18,3 +18,9 @@
 then
     su -s /bin/sh list -c "/usr/bin/python /var/lib/mailman/cron/senddigests"
 fi
+
+# Regenerate htdig search file.
+if [ -x /usr/lib/cgi-bin/htsearch -a -e /var/lib/mailman/cron/nightly_htdig ]
+then
+    su -s /bin/sh list -c "/usr/bin/python /var/lib/mailman/cron/nightly_htdig"
+fi
diff -Naur mailman-2.1.5/debian/mm_cfg.py mailman-2.1.5-9.htdig+spamassasin.2/debian/mm_cfg.py
--- mailman-2.1.5/debian/mm_cfg.py	2005-07-11 08:36:23.091984048 +0200
+++ mailman-2.1.5-9.htdig+spamassasin.2/debian/mm_cfg.py	2005-07-05 10:39:42.000000000 +0200
@@ -93,5 +93,18 @@
 # read /usr/share/doc/mailman/README.POSTFIX first.
 # MTA='Postfix'
 
+#-------------------------------------------------------------
+# Uncomement if you intent to use ht://Dig as your indexer
+# for public and private lists.
+# USE_HTDIG = 1
+
+#-------------------------------------------------------------
+# Uncomment and change this SpamAssassin default configuration
+# for spam blocking your lists.
+# DEFAULT_SPAMASSASSIN_ENABLE = 1
+# DEFAULT_SPAMASSASSIN_DISCARD_SCORE = 10
+# DEFAULT_SPAMASSASSIN_HOLD_SCORE = 5
+# DEFAULT_SPAMASSASSIN_MEMBER_BONUS = 2
+
 # Note - if you're looking for something that is imported from mm_cfg, but you
 # didn't find it above, it's probably in /usr/lib/mailman/Mailman/Defaults.py.
diff -Naur mailman-2.1.5/debian/patches/00list mailman-2.1.5-9.htdig+spamassasin.2/debian/patches/00list
--- mailman-2.1.5/debian/patches/00list	2005-07-11 08:36:23.039991952 +0200
+++ mailman-2.1.5-9.htdig+spamassasin.2/debian/patches/00list	2005-07-04 22:28:53.000000000 +0200
@@ -33,4 +33,6 @@
 66_donot_let_cache_html_pages
 67_update_handle_old_versions
 68_translation_update_nl
+69_htdig_integration
+70_spamassassin_integration.dpatch
 99_js_templates
diff -Naur mailman-2.1.5/debian/patches/69_htdig_integration.dpatch mailman-2.1.5-9.htdig+spamassasin.2/debian/patches/69_htdig_integration.dpatch
--- mailman-2.1.5/debian/patches/69_htdig_integration.dpatch	1970-01-01 01:00:00.000000000 +0100
+++ mailman-2.1.5-9.htdig+spamassasin.2/debian/patches/69_htdig_integration.dpatch	2005-07-04 22:28:53.000000000 +0200
@@ -0,0 +1,10584 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 69_htdig_integration.dpatch by Richard Barrett <[email-masked]>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Integration of Mailman + htdig for public and private archives.
+## DP: Please refer to http://sourceforge.net/tracker/index.php?func=detail&aid=444884&group_id=103&atid=300103
+## DP: for future improvements and updates agains latest Mailman and
+## DP: htdig versions.
+
+@DPATCH@
+diff -Nru mailman-2.1.5/bin/blow_away_htdig mailman-2.1.5+htdig/bin/blow_away_htdig
+--- mailman-2.1.5/bin/blow_away_htdig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/bin/blow_away_htdig	2005-07-04 10:04:30.238420984 +0200
+@@ -0,0 +1,139 @@
++#! @PYTHON@
++# 
++# Copyright (C) 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++"""Blow away the per list htdig files.
++
++This script is for when you:
++    a. decide to stop using Mailman-htdig integration
++    b. move from local to remote htdig or vice-versa
++    c. are updgrading to a version of htdig which has an incompatible
++       index/db file format
++    d. want to force the creation of new per-list htdig conf files
++       and the list indexes.
++
++You really want to stop Mailman operating while you are running this. For
++instance, shutdown the MTA delivering mail to Mailman and remove Mailman's
++crontab.
++
++Usage: %(program)s [-v] [-h] [i] [listnames]
++
++Where:
++    --verbose / -v
++        print each list as htdig is run for it
++
++    --help / -h
++        print this message and exit
++
++    --config/ -c
++        delete htdig search indices for the lists
++        and recreate the htdig conf file for the lists
++
++    --indices / -i
++        only delete htdig search indices for the lists
++        leave the htdig conf file in place. This is overridden by 
++        the -c option
++
++    listnames
++        Optionally, only runs htdig for the named lists.  Without 
++        this, all archivable lists are processed.
++
++"""
++
++# this code was derived from the nightly_gzip cron script
++
++import sys
++import os
++from stat import *
++import time
++from stat import *
++import getopt
++import paths
++from Mailman import MailList
++from Mailman import Utils
++from Mailman import mm_cfg
++from Mailman.Archiver import HyperArch
++from Mailman.i18n import _
++
++program = sys.argv[0]
++
++def usage(code, msg=''):
++    print >> sys.stderr, _( __doc__)
++    if msg:
++        print msg
++    sys.exit(code)
++
++def main():
++    try:
++        opts, args = getopt.getopt(sys.argv[1:], 'vhic', 
++                                   ['verbose', 'help', 'indices', 'config'])
++    except getopt.error, msg:
++        usage(1, msg)
++
++    # defaults
++    verbose = 0
++    indices_only = 0
++    redo_configs = 0
++    for opt, arg in opts:
++        if opt in ('-h', '--help'):
++            usage(0)
++        elif opt in ('-v', '--verbose'):
++            verbose = 1
++        elif opt in ('-c', '--config'):
++            redo_configs = 1
++            indices_only = 0
++        elif opt in ('-i', '--indices') and not redo_configs:
++            indices_only = 1
++	
++    # limit to the specified lists?
++    if args:
++        listnames = args
++    else:
++        listnames = Utils.list_names()
++
++    # make sure htdig use is off for the moment in this process
++    mm_cfg.USE_HTDIG = 0
++
++    # process all the specified lists
++    for name in listnames:
++        mlist = MailList.MailList(name, lock=0)
++        if not mlist.archive:
++            continue
++        archive = HyperArch.HyperArchive(mlist)
++        if verbose:
++            if redo_configs:
++                print _('Blowing away all htdig indices of list %(name)s')
++                print _('Rebuilding htdig config of list %(name)s')
++            elif indices_only:
++                print _('Blowing away all htdig indices of list %(name)s')
++            else:
++                print _('Blowing away all htdig stuff of list %(name)s')
++        archive.remove_htdig(indices_only)
++        if redo_configs:
++            archive.setup_htdig()
++        archive.write_TOC()
++
++if __name__ == '__main__' and \
++   mm_cfg.USE_HTDIG and \
++   mm_cfg.ARCHIVE_TO_MBOX in (0, 2):
++    # we're only going to run this if messages are archived to the internal 
++    # archiver and we are using htdig to provide archive search
++    omask = os.umask(002)
++    try:
++        main()
++    finally:
++        os.umask(omask)
+diff -Nru mailman-2.1.5/bin/check_perms mailman-2.1.5+htdig/bin/check_perms
+--- mailman-2.1.5/bin/check_perms	2005-07-04 10:07:01.727391160 +0200
++++ mailman-2.1.5+htdig/bin/check_perms	2005-07-04 10:04:30.238420984 +0200
+@@ -55,6 +55,11 @@
+ 
+ # Gotta check the archives/private/*/database/* files
+ 
++DBDIRLIST = ['database']
++if mm_cfg.HTDIG_STRICT_FILE_PERM:
++    DBDIRLIST.append('htdig')
++
++
+ try:
+     True, False
+ except NameError:
+@@ -118,7 +123,7 @@
+         # checked in checkarchives() and checkarchivedbs() below.
+         private = mm_cfg.PRIVATE_ARCHIVE_FILE_DIR
+         if path == private or (os.path.commonprefix((path, private)) == private
+-                               and os.path.split(path)[1] == 'database'):
++                               and os.path.split(path)[1] in DBDIRLIST):
+             continue
+         # The directories under qfiles should have a more limited permission
+         if os.path.commonprefix((path, mm_cfg.QUEUE_DIR)) == mm_cfg.QUEUE_DIR:
+@@ -223,23 +228,29 @@
+     # or executable otherwise those files will be accessible when the archives
+     # are public.  That may not be a horrible breach, but let's close this off
+     # anyway.
++    # ditto archives/private/listname/htdig
+     for dir in os.listdir(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR):
+         if dir.endswith('.mbox'):
+             checkmboxfile(dir)
+-        dbdir = os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, dir, 'database')
+-        try:
+-            mode = statmode(dbdir)
+-        except OSError, e:
+-            if e.errno not in (errno.ENOENT, errno.ENOTDIR): raise
+-            continue
+-        if mode & S_IRWXO:
+-            STATE.ERRORS += 1
+-            print _('%(dbdir)s "other" perms must be 000'),
+-            if STATE.FIX:
+-                print _('(fixing)')
+-                os.chmod(dbdir, mode & ~S_IRWXO)
+-            else:
+-                print
++        dbdirlist = [os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, dir, 
++                                  'database')]
++        if mm_cfg.HTDIG_STRICT_FILE_PERM:
++            dbdirlist.append(os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, 
++                                          dir, 'htdig'))
++        for ddir in dbdirlist:
++            try:
++                mode = statmode(ddir)
++            except OSError, e:
++                if e.errno not in (errno.ENOENT, errno.ENOTDIR): raise
++                continue
++            if mode & S_IRWXO:
++                STATE.ERRORS += 1
++                print _('%(ddir)s "other" perms must be 000'),
++                if STATE.FIX:
++                    print _('(fixing)')
++                    os.chmod(ddir, mode & ~S_IRWXO)
++                else:
++                    print
+ 
+ def checkcgi():
+     cgidir = os.path.join(mm_cfg.EXEC_PREFIX, 'cgi-bin')
+diff -Nru mailman-2.1.5/bin/Makefile.in mailman-2.1.5+htdig/bin/Makefile.in
+--- mailman-2.1.5/bin/Makefile.in	2003-12-24 18:03:15.000000000 +0100
++++ mailman-2.1.5+htdig/bin/Makefile.in	2005-07-04 10:04:30.239420832 +0200
+@@ -48,7 +48,7 @@
+ 		version config_list list_lists dumpdb cleanarch \
+ 		list_admins genaliases change_pw mailmanctl qrunner inject \
+ 		unshunt fix_url.py convert.py transcheck b4b5-archfix \
+-		list_owners msgfmt.py show_qfiles discard rb-archfix
++		list_owners msgfmt.py show_qfiles discard rb-archfix blow_away_htdig
+ 
+ BUILDDIR=	../build/bin
+ 
+diff -Nru mailman-2.1.5/configure mailman-2.1.5+htdig/configure
+--- mailman-2.1.5/configure	2005-07-04 10:06:01.627527728 +0200
++++ mailman-2.1.5+htdig/configure	2005-07-04 10:04:30.240420680 +0200
+@@ -2068,6 +2068,7 @@
+ 
+ SCRIPTS="build/bin/add_members:bin/add_members \
+ build/bin/arch:bin/arch \
++build/bin/blow_away_htdig:bin/blow_away_htdig \
+ build/bin/change_pw:bin/change_pw \
+ build/bin/check_db:bin/check_db \
+ build/bin/check_perms:bin/check_perms \
+@@ -2111,6 +2112,10 @@
+ build/cron/gate_news:cron/gate_news \
+ build/cron/mailpasswds:cron/mailpasswds \
+ build/cron/nightly_gzip:cron/nightly_gzip \
++build/cron/nightly_htdig:cron/nightly_htdig \
++build/cron/remote_nightly_htdig:cron/remote_nightly_htdig \
++build/cron/remote_nightly_htdig_noshare:cron/remote_nightly_htdig_noshare \
++build/cron/remote_nightly_htdig.pl:cron/remote_nightly_htdig.pl \
+ build/cron/senddigests:cron/senddigests \
+ "
+ 
+diff -Nru mailman-2.1.5/configure.in mailman-2.1.5+htdig/configure.in
+--- mailman-2.1.5/configure.in	2003-12-24 18:11:48.000000000 +0100
++++ mailman-2.1.5+htdig/configure.in	2005-07-04 10:04:30.240420680 +0200
+@@ -544,6 +544,7 @@
+ AC_DEFUN(MM_SCRIPTS, [dnl
+ bin/add_members \
+ bin/arch \
++bin/blow_away_htdig \
+ bin/change_pw \
+ bin/check_db \
+ bin/check_perms \
+@@ -587,6 +588,10 @@
+ cron/gate_news \
+ cron/mailpasswds \
+ cron/nightly_gzip \
++cron/nightly_htdig \
++cron/remote_nightly_htdig \
++cron/remote_nightly_htdig_noshare \
++cron/remote_nightly_htdig.pl \
+ cron/senddigests \
+ ])
+ 
+diff -Nru mailman-2.1.5/configure.orig mailman-2.1.5+htdig/configure.orig
+--- mailman-2.1.5/configure.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/configure.orig	2005-07-04 10:04:30.246419768 +0200
+@@ -0,0 +1,2422 @@
++#! /bin/sh
++
++# From configure.in Revision: 2.39.2.4 
++
++# Guess values for system-dependent variables and create Makefiles.
++# Generated automatically using autoconf version 2.13 
++# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
++#
++# This configure script is free software; the Free Software Foundation
++# gives unlimited permission to copy, distribute and modify it.
++
++# Defaults:
++ac_help=
++ac_default_prefix=/usr/local
++# Any additions from configure.in:
++ac_default_prefix=/usr/lib/mailman
++ac_help="$ac_help
++  --with-python                specify path to Python interpreter"
++ac_help="$ac_help
++  --without-gcc               never use gcc"
++ac_help="$ac_help
++  --with-var-prefix     directory for mutable data [/var/mailman]"
++ac_help="$ac_help
++  --without-permcheck  skip the check for target directory permissions"
++ac_help="$ac_help
++  --with-username      specify a user name other than \"mailman\""
++ac_help="$ac_help
++  --with-groupname     specify a group name other than \"mailman\""
++ac_help="$ac_help
++  --with-mail-gid      group name mail programs run as"
++ac_help="$ac_help
++  --with-cgi-gid       group name CGI programs run as"
++ac_help="$ac_help
++  --with-cgi-ext       specify extension for CGI programs (include dot)"
++ac_help="$ac_help
++  --with-mailhost      specify the hostname part for outgoing email"
++ac_help="$ac_help
++  --with-urlhost       specify the hostname part of urls"
++
++# Initialize some variables set by options.
++# The variables have the same names as the options, with
++# dashes changed to underlines.
++build=NONE
++cache_file=./config.cache
++exec_prefix=NONE
++host=NONE
++no_create=
++nonopt=NONE
++no_recursion=
++prefix=NONE
++program_prefix=NONE
++program_suffix=NONE
++program_transform_name=s,x,x,
++silent=
++site=
++srcdir=
++target=NONE
++verbose=
++x_includes=NONE
++x_libraries=NONE
++bindir='${exec_prefix}/bin'
++sbindir='${exec_prefix}/sbin'
++libexecdir='${exec_prefix}/libexec'
++datadir='${prefix}/share'
++sysconfdir='${prefix}/etc'
++sharedstatedir='${prefix}/com'
++localstatedir='${prefix}/var'
++libdir='${exec_prefix}/lib'
++includedir='${prefix}/include'
++oldincludedir='/usr/include'
++infodir='${prefix}/info'
++mandir='${prefix}/man'
++
++# Initialize some other variables.
++subdirs=
++MFLAGS= MAKEFLAGS=
++SHELL=${CONFIG_SHELL-/bin/sh}
++# Maximum number of lines to put in a shell here document.
++ac_max_here_lines=12
++
++ac_prev=
++for ac_option
++do
++
++  # If the previous option needs an argument, assign it.
++  if test -n "$ac_prev"; then
++    eval "$ac_prev=\$ac_option"
++    ac_prev=
++    continue
++  fi
++
++  case "$ac_option" in
++  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
++  *) ac_optarg= ;;
++  esac
++
++  # Accept the important Cygnus configure options, so we can diagnose typos.
++
++  case "$ac_option" in
++
++  -bindir | --bindir | --bindi | --bind | --bin | --bi)
++    ac_prev=bindir ;;
++  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
++    bindir="$ac_optarg" ;;
++
++  -build | --build | --buil | --bui | --bu)
++    ac_prev=build ;;
++  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
++    build="$ac_optarg" ;;
++
++  -cache-file | --cache-file | --cache-fil | --cache-fi \
++  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
++    ac_prev=cache_file ;;
++  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
++  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
++    cache_file="$ac_optarg" ;;
++
++  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
++    ac_prev=datadir ;;
++  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
++  | --da=*)
++    datadir="$ac_optarg" ;;
++
++  -disable-* | --disable-*)
++    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
++    # Reject names that are not valid shell variable names.
++    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
++      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
++    fi
++    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
++    eval "enable_${ac_feature}=no" ;;
++
++  -enable-* | --enable-*)
++    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
++    # Reject names that are not valid shell variable names.
++    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
++      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
++    fi
++    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
++    case "$ac_option" in
++      *=*) ;;
++      *) ac_optarg=yes ;;
++    esac
++    eval "enable_${ac_feature}='$ac_optarg'" ;;
++
++  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
++  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
++  | --exec | --exe | --ex)
++    ac_prev=exec_prefix ;;
++  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
++  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
++  | --exec=* | --exe=* | --ex=*)
++    exec_prefix="$ac_optarg" ;;
++
++  -gas | --gas | --ga | --g)
++    # Obsolete; use --with-gas.
++    with_gas=yes ;;
++
++  -help | --help | --hel | --he)
++    # Omit some internal or obsolete options to make the list less imposing.
++    # This message is too long to be a string in the A/UX 3.1 sh.
++    cat << EOF
++Usage: configure [options] [host]
++Options: [defaults in brackets after descriptions]
++Configuration:
++  --cache-file=FILE       cache test results in FILE
++  --help                  print this message
++  --no-create             do not create output files
++  --quiet, --silent       do not print \`checking...' messages
++  --version               print the version of autoconf that created configure
++Directory and file names:
++  --prefix=PREFIX         install architecture-independent files in PREFIX
++                          [$ac_default_prefix]
++  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
++                          [same as prefix]
++  --bindir=DIR            user executables in DIR [EPREFIX/bin]
++  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
++  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
++  --datadir=DIR           read-only architecture-independent data in DIR
++                          [PREFIX/share]
++  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
++  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
++                          [PREFIX/com]
++  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
++  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
++  --includedir=DIR        C header files in DIR [PREFIX/include]
++  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
++  --infodir=DIR           info documentation in DIR [PREFIX/info]
++  --mandir=DIR            man documentation in DIR [PREFIX/man]
++  --srcdir=DIR            find the sources in DIR [configure dir or ..]
++  --program-prefix=PREFIX prepend PREFIX to installed program names
++  --program-suffix=SUFFIX append SUFFIX to installed program names
++  --program-transform-name=PROGRAM
++                          run sed PROGRAM on installed program names
++EOF
++    cat << EOF
++Host type:
++  --build=BUILD           configure for building on BUILD [BUILD=HOST]
++  --host=HOST             configure for HOST [guessed]
++  --target=TARGET         configure for TARGET [TARGET=HOST]
++Features and packages:
++  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
++  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
++  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
++  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
++  --x-includes=DIR        X include files are in DIR
++  --x-libraries=DIR       X library files are in DIR
++EOF
++    if test -n "$ac_help"; then
++      echo "--enable and --with options recognized:$ac_help"
++    fi
++    exit 0 ;;
++
++  -host | --host | --hos | --ho)
++    ac_prev=host ;;
++  -host=* | --host=* | --hos=* | --ho=*)
++    host="$ac_optarg" ;;
++
++  -includedir | --includedir | --includedi | --included | --include \
++  | --includ | --inclu | --incl | --inc)
++    ac_prev=includedir ;;
++  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
++  | --includ=* | --inclu=* | --incl=* | --inc=*)
++    includedir="$ac_optarg" ;;
++
++  -infodir | --infodir | --infodi | --infod | --info | --inf)
++    ac_prev=infodir ;;
++  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
++    infodir="$ac_optarg" ;;
++
++  -libdir | --libdir | --libdi | --libd)
++    ac_prev=libdir ;;
++  -libdir=* | --libdir=* | --libdi=* | --libd=*)
++    libdir="$ac_optarg" ;;
++
++  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
++  | --libexe | --libex | --libe)
++    ac_prev=libexecdir ;;
++  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
++  | --libexe=* | --libex=* | --libe=*)
++    libexecdir="$ac_optarg" ;;
++
++  -localstatedir | --localstatedir | --localstatedi | --localstated \
++  | --localstate | --localstat | --localsta | --localst \
++  | --locals | --local | --loca | --loc | --lo)
++    ac_prev=localstatedir ;;
++  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
++  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
++  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
++    localstatedir="$ac_optarg" ;;
++
++  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
++    ac_prev=mandir ;;
++  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
++    mandir="$ac_optarg" ;;
++
++  -nfp | --nfp | --nf)
++    # Obsolete; use --without-fp.
++    with_fp=no ;;
++
++  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++  | --no-cr | --no-c)
++    no_create=yes ;;
++
++  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++    no_recursion=yes ;;
++
++  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
++  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
++  | --oldin | --oldi | --old | --ol | --o)
++    ac_prev=oldincludedir ;;
++  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
++  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
++  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
++    oldincludedir="$ac_optarg" ;;
++
++  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
++    ac_prev=prefix ;;
++  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
++    prefix="$ac_optarg" ;;
++
++  -program-prefix | --program-prefix | --program-prefi | --program-pref \
++  | --program-pre | --program-pr | --program-p)
++    ac_prev=program_prefix ;;
++  -program-prefix=* | --program-prefix=* | --program-prefi=* \
++  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
++    program_prefix="$ac_optarg" ;;
++
++  -program-suffix | --program-suffix | --program-suffi | --program-suff \
++  | --program-suf | --program-su | --program-s)
++    ac_prev=program_suffix ;;
++  -program-suffix=* | --program-suffix=* | --program-suffi=* \
++  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
++    program_suffix="$ac_optarg" ;;
++
++  -program-transform-name | --program-transform-name \
++  | --program-transform-nam | --program-transform-na \
++  | --program-transform-n | --program-transform- \
++  | --program-transform | --program-transfor \
++  | --program-transfo | --program-transf \
++  | --program-trans | --program-tran \
++  | --progr-tra | --program-tr | --program-t)
++    ac_prev=program_transform_name ;;
++  -program-transform-name=* | --program-transform-name=* \
++  | --program-transform-nam=* | --program-transform-na=* \
++  | --program-transform-n=* | --program-transform-=* \
++  | --program-transform=* | --program-transfor=* \
++  | --program-transfo=* | --program-transf=* \
++  | --program-trans=* | --program-tran=* \
++  | --progr-tra=* | --program-tr=* | --program-t=*)
++    program_transform_name="$ac_optarg" ;;
++
++  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++  | -silent | --silent | --silen | --sile | --sil)
++    silent=yes ;;
++
++  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
++    ac_prev=sbindir ;;
++  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
++  | --sbi=* | --sb=*)
++    sbindir="$ac_optarg" ;;
++
++  -sharedstatedir | --sharedstatedir | --sharedstatedi \
++  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
++  | --sharedst | --shareds | --shared | --share | --shar \
++  | --sha | --sh)
++    ac_prev=sharedstatedir ;;
++  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
++  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
++  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
++  | --sha=* | --sh=*)
++    sharedstatedir="$ac_optarg" ;;
++
++  -site | --site | --sit)
++    ac_prev=site ;;
++  -site=* | --site=* | --sit=*)
++    site="$ac_optarg" ;;
++
++  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
++    ac_prev=srcdir ;;
++  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
++    srcdir="$ac_optarg" ;;
++
++  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
++  | --syscon | --sysco | --sysc | --sys | --sy)
++    ac_prev=sysconfdir ;;
++  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
++  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
++    sysconfdir="$ac_optarg" ;;
++
++  -target | --target | --targe | --targ | --tar | --ta | --t)
++    ac_prev=target ;;
++  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
++    target="$ac_optarg" ;;
++
++  -v | -verbose | --verbose | --verbos | --verbo | --verb)
++    verbose=yes ;;
++
++  -version | --version | --versio | --versi | --vers)
++    echo "configure generated by autoconf version 2.13"
++    exit 0 ;;
++
++  -with-* | --with-*)
++    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
++    # Reject names that are not valid shell variable names.
++    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
++      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
++    fi
++    ac_package=`echo $ac_package| sed 's/-/_/g'`
++    case "$ac_option" in
++      *=*) ;;
++      *) ac_optarg=yes ;;
++    esac
++    eval "with_${ac_package}='$ac_optarg'" ;;
++
++  -without-* | --without-*)
++    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
++    # Reject names that are not valid shell variable names.
++    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
++      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
++    fi
++    ac_package=`echo $ac_package| sed 's/-/_/g'`
++    eval "with_${ac_package}=no" ;;
++
++  --x)
++    # Obsolete; use --with-x.
++    with_x=yes ;;
++
++  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
++  | --x-incl | --x-inc | --x-in | --x-i)
++    ac_prev=x_includes ;;
++  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
++  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
++    x_includes="$ac_optarg" ;;
++
++  -x-libraries | --x-libraries | --x-librarie | --x-librari \
++  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
++    ac_prev=x_libraries ;;
++  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
++  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
++    x_libraries="$ac_optarg" ;;
++
++  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
++    ;;
++
++  *)
++    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
++      echo "configure: warning: $ac_option: invalid host type" 1>&2
++    fi
++    if test "x$nonopt" != xNONE; then
++      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
++    fi
++    nonopt="$ac_option"
++    ;;
++
++  esac
++done
++
++if test -n "$ac_prev"; then
++  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
++fi
++
++trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
++
++# File descriptor usage:
++# 0 standard input
++# 1 file creation
++# 2 errors and warnings
++# 3 some systems may open it to /dev/tty
++# 4 used on the Kubota Titan
++# 6 checking for... messages and results
++# 5 compiler messages saved in config.log
++if test "$silent" = yes; then
++  exec 6>/dev/null
++else
++  exec 6>&1
++fi
++exec 5>./config.log
++
++echo "\
++This file contains any messages produced by compilers while
++running configure, to aid debugging if configure makes a mistake.
++" 1>&5
++
++# Strip out --no-create and --no-recursion so they do not pile up.
++# Also quote any args containing shell metacharacters.
++ac_configure_args=
++for ac_arg
++do
++  case "$ac_arg" in
++  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++  | --no-cr | --no-c) ;;
++  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
++  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
++  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
++  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
++  esac
++done
++
++# NLS nuisances.
++# Only set these to C if already set.  These must not be set unconditionally
++# because not all systems understand e.g. LANG=C (notably SCO).
++# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
++# Non-C LC_CTYPE values break the ctype check.
++if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
++if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
++if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
++if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
++
++# confdefs.h avoids OS command line length limits that DEFS can exceed.
++rm -rf conftest* confdefs.h
++# AIX cpp loses on an empty file, so make sure it contains at least a newline.
++echo > confdefs.h
++
++# A filename unique to this package, relative to the directory that
++# configure is in, which we can look for to find out if srcdir is correct.
++ac_unique_file=src/common.h
++
++# Find the source files, if location was not specified.
++if test -z "$srcdir"; then
++  ac_srcdir_defaulted=yes
++  # Try the directory containing this script, then its parent.
++  ac_prog=$0
++  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
++  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
++  srcdir=$ac_confdir
++  if test ! -r $srcdir/$ac_unique_file; then
++    srcdir=..
++  fi
++else
++  ac_srcdir_defaulted=no
++fi
++if test ! -r $srcdir/$ac_unique_file; then
++  if test "$ac_srcdir_defaulted" = yes; then
++    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
++  else
++    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
++  fi
++fi
++srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
++
++# Prefer explicitly selected file to automatically selected ones.
++if test -z "$CONFIG_SITE"; then
++  if test "x$prefix" != xNONE; then
++    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
++  else
++    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++  fi
++fi
++for ac_site_file in $CONFIG_SITE; do
++  if test -r "$ac_site_file"; then
++    echo "loading site script $ac_site_file"
++    . "$ac_site_file"
++  fi
++done
++
++if test -r "$cache_file"; then
++  echo "loading cache $cache_file"
++  . $cache_file
++else
++  echo "creating cache $cache_file"
++  > $cache_file
++fi
++
++ac_ext=c
++# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
++cross_compiling=$ac_cv_prog_cc_cross
++
++ac_exeext=
++ac_objext=o
++if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
++  # Stardent Vistra SVR4 grep lacks -e, says [email-masked].
++  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
++    ac_n= ac_c='
++' ac_t='	'
++  else
++    ac_n=-n ac_c= ac_t=
++  fi
++else
++  ac_n= ac_c='\c' ac_t=
++fi
++
++
++
++
++# /usr/lib/mailman is the default installation directory
++
++
++
++# Check for Python!  Better be found on $PATH
++echo $ac_n "checking for --with-python""... $ac_c" 1>&6
++echo "configure:558: checking for --with-python" >&5
++# Check whether --with-python or --without-python was given.
++if test "${with_python+set}" = set; then
++  withval="$with_python"
++  :
++fi
++
++case "$with_python" in
++    "") ans="no";;
++    *)  ans="$with_python"
++esac
++echo "$ac_t""$ans" 1>&6
++
++if test -z "$with_python"
++then
++        # Extract the first word of "python", so it can be a program name with args.
++set dummy python; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:576: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_path_with_python'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  case "$with_python" in
++  /*)
++  ac_cv_path_with_python="$with_python" # Let the user override the test with a path.
++  ;;
++  ?:/*)			 
++  ac_cv_path_with_python="$with_python" # Let the user override the test with a dos path.
++  ;;
++  *)
++  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
++  ac_dummy="$PATH"
++  for ac_dir in $ac_dummy; do 
++    test -z "$ac_dir" && ac_dir=.
++    if test -f $ac_dir/$ac_word; then
++      ac_cv_path_with_python="$ac_dir/$ac_word"
++      break
++    fi
++  done
++  IFS="$ac_save_ifs"
++  test -z "$ac_cv_path_with_python" && ac_cv_path_with_python="/usr/bin/python"
++  ;;
++esac
++fi
++with_python="$ac_cv_path_with_python"
++if test -n "$with_python"; then
++  echo "$ac_t""$with_python" 1>&6
++else
++  echo "$ac_t""no" 1>&6
++fi
++
++fi
++
++echo $ac_n "checking Python interpreter""... $ac_c" 1>&6
++echo "configure:612: checking Python interpreter" >&5
++if test ! -x $with_python
++then
++    { echo "configure: error: 
++
++***** No Python interpreter found!
++***** Try including the configure option
++***** --with-python=/path/to/python/interpreter" 1>&2; exit 1; }
++fi
++
++PYTHON=$with_python
++echo "$ac_t""$PYTHON" 1>&6
++
++# See if Python is new enough.  2.1 or better is required, with 2.1.3
++# recommended.
++echo $ac_n "checking Python version""... $ac_c" 1>&6
++echo "configure:628: checking Python version" >&5
++
++cat > conftest.py <<EOF
++import sys
++try:
++    v = sys.hexversion
++except AttributeError:
++    v = 0
++# int of hexversion 0x2010000
++if v >= 0x2010000:
++    s = sys.version.split()[0]
++else:
++    s = ""
++fp = open("conftest.out", "w")
++fp.write("%s\n" % s)
++fp.close()
++EOF
++
++$PYTHON conftest.py
++version=`cat conftest.out`
++rm -f conftest.out conftest.py
++if test -z "$version"
++then
++    { echo "configure: error: 
++
++***** $PYTHON is too old (or broken)
++***** Python 2.1 or newer is required
++***** Python 2.1.3 or better is recommended" 1>&2; exit 1; }
++fi
++echo "$ac_t""$version" 1>&6
++
++# Make sure distutils is available.  Some Linux Python packages split
++# distutils into the "-devel" package, so they need both.
++echo $ac_n "checking that Python has a working distutils""... $ac_c" 1>&6
++echo "configure:662: checking that Python has a working distutils" >&5
++
++cat > conftest.py <<EOF
++try:
++    import distutils.errors
++    import distutils.sysconfig
++except ImportError:
++    res = "no"
++else:
++    try:
++        distutils.sysconfig.get_config_vars()
++    except distutils.errors.DistutilsPlatformError:
++        res = "no"
++    else:
++        res = "yes"
++fp = open("conftest.out", "w")
++fp.write("%s\n" % res)
++fp.close()
++EOF
++
++$PYTHON conftest.py
++havedistutils=`cat conftest.out`
++rm -f conftest.out conftest.py
++if test "$havedistutils" != "yes"
++then
++    { echo "configure: error: 
++
++***** Distutils is not available or is incomplete for $PYTHON
++***** If you installed Python from RPM (or other package manager)
++***** be sure to install the -devel package, or install Python
++***** from source.  See README.LINUX for details" 1>&2; exit 1; }
++fi
++echo "$ac_t""$havedistutils" 1>&6
++
++# Checks for programs.
++ac_aux_dir=
++for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
++  if test -f $ac_dir/install-sh; then
++    ac_aux_dir=$ac_dir
++    ac_install_sh="$ac_aux_dir/install-sh -c"
++    break
++  elif test -f $ac_dir/install.sh; then
++    ac_aux_dir=$ac_dir
++    ac_install_sh="$ac_aux_dir/install.sh -c"
++    break
++  fi
++done
++if test -z "$ac_aux_dir"; then
++  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
++fi
++ac_config_guess=$ac_aux_dir/config.guess
++ac_config_sub=$ac_aux_dir/config.sub
++ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
++
++# Find a good install program.  We prefer a C program (faster),
++# so one script is as good as another.  But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
++echo "configure:728: checking for a BSD compatible install" >&5
++if test -z "$INSTALL"; then
++if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
++  for ac_dir in $PATH; do
++    # Account for people who put trailing slashes in PATH elements.
++    case "$ac_dir/" in
++    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
++    *)
++      # OSF1 and SCO ODT 3.0 have their own names for install.
++      # Don't use installbsd from OSF since it installs stuff as root
++      # by default.
++      for ac_prog in ginstall scoinst install; do
++        if test -f $ac_dir/$ac_prog; then
++	  if test $ac_prog = install &&
++            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
++	    # AIX install.  It has an incompatible calling convention.
++	    :
++	  else
++	    ac_cv_path_install="$ac_dir/$ac_prog -c"
++	    break 2
++	  fi
++	fi
++      done
++      ;;
++    esac
++  done
++  IFS="$ac_save_IFS"
++
++fi
++  if test "${ac_cv_path_install+set}" = set; then
++    INSTALL="$ac_cv_path_install"
++  else
++    # As a last resort, use the slow shell script.  We don't cache a
++    # path for INSTALL within a source directory, because that will
++    # break other packages using the cache if that directory is
++    # removed, or if the path is relative.
++    INSTALL="$ac_install_sh"
++  fi
++fi
++echo "$ac_t""$INSTALL" 1>&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
++echo "configure:781: checking whether ${MAKE-make} sets \${MAKE}" >&5
++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
++if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  cat > conftestmake <<\EOF
++all:
++	@echo 'ac_maketemp="${MAKE}"'
++EOF
++# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
++eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
++if test -n "$ac_maketemp"; then
++  eval ac_cv_prog_make_${ac_make}_set=yes
++else
++  eval ac_cv_prog_make_${ac_make}_set=no
++fi
++rm -f conftestmake
++fi
++if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
++  echo "$ac_t""yes" 1>&6
++  SET_MAKE=
++else
++  echo "$ac_t""no" 1>&6
++  SET_MAKE="MAKE=${MAKE-make}"
++fi
++
++# Extract the first word of "true", so it can be a program name with args.
++set dummy true; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:810: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_path_TRUE'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  case "$TRUE" in
++  /*)
++  ac_cv_path_TRUE="$TRUE" # Let the user override the test with a path.
++  ;;
++  ?:/*)			 
++  ac_cv_path_TRUE="$TRUE" # Let the user override the test with a dos path.
++  ;;
++  *)
++  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
++  ac_dummy="$PATH:/bin:/usr/bin"
++  for ac_dir in $ac_dummy; do 
++    test -z "$ac_dir" && ac_dir=.
++    if test -f $ac_dir/$ac_word; then
++      ac_cv_path_TRUE="$ac_dir/$ac_word"
++      break
++    fi
++  done
++  IFS="$ac_save_ifs"
++  test -z "$ac_cv_path_TRUE" && ac_cv_path_TRUE="true"
++  ;;
++esac
++fi
++TRUE="$ac_cv_path_TRUE"
++if test -n "$TRUE"; then
++  echo "$ac_t""$TRUE" 1>&6
++else
++  echo "$ac_t""no" 1>&6
++fi
++
++
++# Find compiler, allow alternatives to gcc
++echo $ac_n "checking for --without-gcc""... $ac_c" 1>&6
++echo "configure:846: checking for --without-gcc" >&5
++# Check whether --with-gcc or --without-gcc was given.
++if test "${with_gcc+set}" = set; then
++  withval="$with_gcc"
++  
++        case $withval in
++        no)     CC=cc
++                without_gcc=yes;;
++        yes)    CC=gcc
++                without_gcc=no;;
++        *)      CC=$withval
++                without_gcc=$withval;;
++        esac
++else
++  without_gcc=no;
++fi
++
++echo "$ac_t""$without_gcc" 1>&6
++
++# If the user switches compilers, we can't believe the cache
++if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
++then
++  { echo "configure: error: cached CC is different -- throw away $cache_file
++(it is also a good idea to do 'make clean' before compiling)" 1>&2; exit 1; }
++fi
++
++# Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:875: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
++  ac_dummy="$PATH"
++  for ac_dir in $ac_dummy; do
++    test -z "$ac_dir" && ac_dir=.
++    if test -f $ac_dir/$ac_word; then
++      ac_cv_prog_CC="gcc"
++      break
++    fi
++  done
++  IFS="$ac_save_ifs"
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++  echo "$ac_t""$CC" 1>&6
++else
++  echo "$ac_t""no" 1>&6
++fi
++
++if test -z "$CC"; then
++  # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:905: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
++  ac_prog_rejected=no
++  ac_dummy="$PATH"
++  for ac_dir in $ac_dummy; do
++    test -z "$ac_dir" && ac_dir=.
++    if test -f $ac_dir/$ac_word; then
++      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
++        ac_prog_rejected=yes
++	continue
++      fi
++      ac_cv_prog_CC="cc"
++      break
++    fi
++  done
++  IFS="$ac_save_ifs"
++if test $ac_prog_rejected = yes; then
++  # We found a bogon in the path, so make sure we never use it.
++  set dummy $ac_cv_prog_CC
++  shift
++  if test $# -gt 0; then
++    # We chose a different compiler from the bogus one.
++    # However, it has the same basename, so the bogon will be chosen
++    # first if we set CC to just the basename; use the full file name.
++    shift
++    set dummy "$ac_dir/$ac_word" "$@"
++    shift
++    ac_cv_prog_CC="$@"
++  fi
++fi
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++  echo "$ac_t""$CC" 1>&6
++else
++  echo "$ac_t""no" 1>&6
++fi
++
++  if test -z "$CC"; then
++    case "`uname -s`" in
++    *win32* | *WIN32*)
++      # Extract the first word of "cl", so it can be a program name with args.
++set dummy cl; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:956: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
++  ac_dummy="$PATH"
++  for ac_dir in $ac_dummy; do
++    test -z "$ac_dir" && ac_dir=.
++    if test -f $ac_dir/$ac_word; then
++      ac_cv_prog_CC="cl"
++      break
++    fi
++  done
++  IFS="$ac_save_ifs"
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++  echo "$ac_t""$CC" 1>&6
++else
++  echo "$ac_t""no" 1>&6
++fi
++ ;;
++    esac
++  fi
++  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
++fi
++
++echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
++echo "configure:988: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
++
++ac_ext=c
++# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
++cross_compiling=$ac_cv_prog_cc_cross
++
++cat > conftest.$ac_ext << EOF
++
++#line 999 "configure"
++#include "confdefs.h"
++
++main(){return(0);}
++EOF
++if { (eval echo configure:1004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++  ac_cv_prog_cc_works=yes
++  # If we can't run a trivial program, we are probably using a cross compiler.
++  if (./conftest; exit) 2>/dev/null; then
++    ac_cv_prog_cc_cross=no
++  else
++    ac_cv_prog_cc_cross=yes
++  fi
++else
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  ac_cv_prog_cc_works=no
++fi
++rm -fr conftest*
++ac_ext=c
++# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
++cross_compiling=$ac_cv_prog_cc_cross
++
++echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
++if test $ac_cv_prog_cc_works = no; then
++  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
++fi
++echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
++echo "configure:1030: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
++echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
++cross_compiling=$ac_cv_prog_cc_cross
++
++echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
++echo "configure:1035: checking whether we are using GNU C" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  cat > conftest.c <<EOF
++#ifdef __GNUC__
++  yes;
++#endif
++EOF
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1044: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++  ac_cv_prog_gcc=yes
++else
++  ac_cv_prog_gcc=no
++fi
++fi
++
++echo "$ac_t""$ac_cv_prog_gcc" 1>&6
++
++if test $ac_cv_prog_gcc = yes; then
++  GCC=yes
++else
++  GCC=
++fi
++
++ac_test_CFLAGS="${CFLAGS+set}"
++ac_save_CFLAGS="$CFLAGS"
++CFLAGS=
++echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
++echo "configure:1063: checking whether ${CC-cc} accepts -g" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  echo 'void f(){}' > conftest.c
++if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
++  ac_cv_prog_cc_g=yes
++else
++  ac_cv_prog_cc_g=no
++fi
++rm -f conftest*
++
++fi
++
++echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
++if test "$ac_test_CFLAGS" = set; then
++  CFLAGS="$ac_save_CFLAGS"
++elif test $ac_cv_prog_cc_g = yes; then
++  if test "$GCC" = yes; then
++    CFLAGS="-g -O2"
++  else
++    CFLAGS="-g"
++  fi
++else
++  if test "$GCC" = yes; then
++    CFLAGS="-O2"
++  else
++    CFLAGS=
++  fi
++fi
++
++
++
++# Optimizer/debugger flags passed between Makefiles
++
++if test -z "$OPT"
++then
++        case $GCC in
++        yes)
++                case $ac_cv_prog_cc_g in
++                yes)    OPT="-g -O2";;
++                *)      OPT="-O2";;
++                esac
++                ;;
++        *)      OPT="-O";;
++        esac
++fi
++
++# We better be able to execute interpreters
++# Pull the hash mark out of the macro call to avoid m4 problems.
++ac_msg="whether #! works in shell scripts"
++echo $ac_n "checking $ac_msg""... $ac_c" 1>&6
++echo "configure:1115: checking $ac_msg" >&5
++if eval "test \"`echo '$''{'ac_cv_sys_interpreter'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++  echo '#! /bin/cat
++exit 69
++' > conftest
++chmod u+x conftest
++(SHELL=/bin/sh; export SHELL; ./conftest >/dev/null)
++if test $? -ne 69; then
++   ac_cv_sys_interpreter=yes
++else
++   ac_cv_sys_interpreter=no
++fi
++rm -f conftest
++fi
++
++echo "$ac_t""$ac_cv_sys_interpreter" 1>&6
++interpval="$ac_cv_sys_interpreter"
++
++if test "$ac_cv_sys_interpreter" != "yes"
++then
++    { echo "configure: error: 
++
++***** Cannot execute interpreter scripts?
++***** Are you sure you system doesn't support this?" 1>&2; exit 1; }
++fi
++
++
++# Check for an alternate data directory, separate from installation dir.
++default_var_prefix="/var/mailman"
++
++echo $ac_n "checking for --with-var-prefix""... $ac_c" 1>&6
++echo "configure:1148: checking for --with-var-prefix" >&5
++# Check whether --with-var-prefix or --without-var-prefix was given.
++if test "${with_var_prefix+set}" = set; then
++  withval="$with_var_prefix"
++  :
++fi
++
++case "$with_var_prefix" in
++        yes)    VAR_PREFIX="$default_var_prefix"; ans=$VAR_PREFIX;;
++        ""|no)  VAR_PREFIX="$prefix"; ans="no";;
++        *)      VAR_PREFIX="$with_var_prefix"; ans=$VAR_PREFIX;
++esac
++echo "$ac_t""$ans" 1>&6
++
++echo $ac_n "checking for --with-permcheck""... $ac_c" 1>&6
++echo "configure:1163: checking for --with-permcheck" >&5
++# Check whether --with-permcheck or --without-permcheck was given.
++if test "${with_permcheck+set}" = set; then
++  withval="$with_permcheck"
++  :
++fi
++
++if test -z "$with_permcheck"
++then
++        with_permcheck="yes"
++fi
++echo "$ac_t""$with_permcheck" 1>&6
++# Now make sure that $prefix is set up correctly.  It must be group
++# owned by the target group, it must have the group sticky bit set, and
++# it must be a+rx
++if test "$VAR_PREFIX" = "NONE"
++then
++    VAR_PREFIX=$ac_default_prefix
++    prefixcheck=$ac_default_prefix
++else
++    prefixcheck=$VAR_PREFIX
++fi
++
++# new macro for finding group names
++
++
++
++# new macro for finding UIDs
++
++
++# Check for some other uid to use than `mailman'
++echo $ac_n "checking for --with-username""... $ac_c" 1>&6
++echo "configure:1195: checking for --with-username" >&5
++# Check whether --with-username or --without-username was given.
++if test "${with_username+set}" = set; then
++  withval="$with_username"
++  :
++fi
++
++
++if test -z "$with_username"
++then
++        with_username="mailman"
++fi
++USERNAME=$with_username
++echo "$ac_t""$USERNAME" 1>&6
++
++# User `mailman' must exist
++
++echo $ac_n "checking for user name \"$USERNAME\"""... $ac_c" 1>&6
++echo "configure:1213: checking for user name \"$USERNAME\"" >&5
++
++# MAILMAN_USER == variable name
++# $USERNAME == user id to check for
++
++
++if test -z "$MAILMAN_USER"
++then
++    cat > conftest.py <<EOF
++import pwd
++uid = ''
++for user in "$USERNAME".split():
++    try:
++        try:
++            uname = pwd.getpwuid(int(user))[0]
++            break
++        except ValueError:
++            uname = pwd.getpwnam(user)[0]
++            break
++    except KeyError:
++        uname = ''
++fp = open("conftest.out", "w")
++fp.write("%s\n" % uname)
++fp.close()
++EOF
++    $PYTHON conftest.py
++    MAILMAN_USER=`cat conftest.out`
++fi
++
++rm -f conftest.out conftest.py
++if test -z "$MAILMAN_USER"
++then
++  if test "$with_permcheck" = "yes"
++  then
++    { echo "configure: error: 
++***** No \"$USERNAME\" user found!
++***** Your system must have a \"$USERNAME\" user defined
++***** (usually in your /etc/passwd file).  Please see the INSTALL
++***** file for details." 1>&2; exit 1; }
++  fi
++fi
++echo "$ac_t""okay" 1>&6
++
++
++# Check for some other gid to use than `mailman'
++echo $ac_n "checking for --with-groupname""... $ac_c" 1>&6
++echo "configure:1259: checking for --with-groupname" >&5
++# Check whether --with-groupname or --without-groupname was given.
++if test "${with_groupname+set}" = set; then
++  withval="$with_groupname"
++  :
++fi
++
++
++if test -z "$with_groupname"
++then
++        with_groupname="mailman"
++fi
++GROUPNAME=$with_groupname
++echo "$ac_t""$GROUPNAME" 1>&6
++
++
++# Target group must exist
++
++echo $ac_n "checking for group name \"$GROUPNAME\"""... $ac_c" 1>&6
++echo "configure:1278: checking for group name \"$GROUPNAME\"" >&5
++
++# MAILMAN_GROUP == variable name
++# $GROUPNAME == user id to check for
++
++
++if test -z "$MAILMAN_GROUP"
++then
++    cat > conftest.py <<EOF
++import grp
++gid = ''
++for group in "$GROUPNAME".split():
++    try:
++        try:
++            gname = grp.getgrgid(int(group))[0]
++            break
++        except ValueError:
++            gname = grp.getgrnam(group)[0]
++            break
++    except KeyError:
++        gname = ''
++fp = open("conftest.out", "w")
++fp.write("%s\n" % gname)
++fp.close()
++EOF
++    $PYTHON conftest.py
++    MAILMAN_GROUP=`cat conftest.out`
++fi
++
++rm -f conftest.out conftest.py
++if test -z "$MAILMAN_GROUP"
++then
++  if test "$with_permcheck" = "yes"
++  then
++    { echo "configure: error: 
++***** No \"$GROUPNAME\" group found!
++***** Your system must have a \"$GROUPNAME\" group defined
++***** (usually in your /etc/group file).  Please see the INSTALL
++***** file for details." 1>&2; exit 1; }
++  fi
++fi
++echo "$ac_t""okay" 1>&6
++
++
++echo $ac_n "checking permissions on $prefixcheck""... $ac_c" 1>&6
++echo "configure:1323: checking permissions on $prefixcheck" >&5
++
++cat > conftest.py <<EOF
++import os, grp
++from stat import *
++prefix = "$prefixcheck"
++groupname = "$GROUPNAME"
++mailmangroup = "$MAILMAN_GROUP"
++try:
++    mailmangid = grp.getgrnam(mailmangroup)[2]
++except KeyError:
++    mailmangid = -1
++problems = []
++try: statdata = os.stat(prefix)
++except OSError:
++    problems.append("Directory doesn't exist: " + prefix)
++else:
++    mode = statdata[ST_MODE]
++    gid = statdata[ST_GID]
++    if mailmangid <> gid:
++        problems.append("Directory must be owned by group " +
++                        groupname + ": " + prefix)
++    if (mode & S_ISGID) <> S_ISGID:
++        problems.append("Set-gid bit must be set for directory: " + prefix)
++    perms = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH
++    if (mode & perms) <> perms:
++        problems.append("Permissions should be at least 02775: " + prefix)
++if not problems:
++    msg = "okay\n"
++else:
++    msg = '***** ' + '\n***** '.join(problems) + '\n'
++fp = open("conftest.out", "w")
++fp.write(msg)
++fp.close()
++EOF
++
++$PYTHON conftest.py
++status=`cat conftest.out`
++rm -f conftest.out conftest.py
++if test "$with_permcheck" = "yes"
++then
++    if test "$status" != "okay"
++    then
++        { echo "configure: error: 
++***** Installation directory $prefixcheck is not configured properly!
++$status" 1>&2; exit 1; }
++    fi
++else
++    status="skipped"
++fi
++echo "$ac_t""$status" 1>&6
++
++
++# Now find the UIDs and GIDs
++# Support --with-mail-gid and --with-cgi-gid
++echo $ac_n "checking for mail wrapper group; i.e. --with-mail-gid""... $ac_c" 1>&6
++echo "configure:1379: checking for mail wrapper group; i.e. --with-mail-gid" >&5
++# Check whether --with-mail-gid or --without-mail-gid was given.
++if test "${with_mail_gid+set}" = set; then
++  withval="$with_mail_gid"
++  :
++fi
++
++if test -z "$with_mail_gid"
++then
++    with_mail_gid="mailman other mail daemon"
++fi
++
++# MAIL_GROUP == variable name
++# $with_mail_gid == user id to check for
++
++
++if test -z "$MAIL_GROUP"
++then
++    cat > conftest.py <<EOF
++import grp
++gid = ''
++for group in "$with_mail_gid".split():
++    try:
++        try:
++            gname = grp.getgrgid(int(group))[0]
++            break
++        except ValueError:
++            gname = grp.getgrnam(group)[0]
++            break
++    except KeyError:
++        gname = ''
++fp = open("conftest.out", "w")
++fp.write("%s\n" % gname)
++fp.close()
++EOF
++    $PYTHON conftest.py
++    MAIL_GROUP=`cat conftest.out`
++fi
++
++rm -f conftest.out conftest.py
++if test -z "$MAIL_GROUP"
++then
++  if test "$with_permcheck" = "yes"
++  then
++    { echo "configure: error: 
++***** No group name \"$with_mail_gid\" found for the mail wrapper program.
++***** This is the group that your mail server will use to run Mailman's
++***** programs.  You should specify an existing group with the
++***** --with-mail-gid configure option, or use --without-permcheck to
++***** skip this verification step.  See also your mail server's documentation,
++***** and Mailman's INSTALL file for details" 1>&2; exit 1; }
++  else
++    MAIL_GROUP=$with_mail_gid
++  fi
++fi
++echo "$ac_t""$MAIL_GROUP" 1>&6
++
++
++echo $ac_n "checking for CGI wrapper group; i.e. --with-cgi-gid""... $ac_c" 1>&6
++echo "configure:1438: checking for CGI wrapper group; i.e. --with-cgi-gid" >&5
++# Check whether --with-cgi-gid or --without-cgi-gid was given.
++if test "${with_cgi_gid+set}" = set; then
++  withval="$with_cgi_gid"
++  :
++fi
++
++if test -z "$with_cgi_gid"
++then
++    with_cgi_gid="www www-data nobody"
++fi
++
++
++# CGI_GROUP == variable name
++# $with_cgi_gid == user id to check for
++
++
++if test -z "$CGI_GROUP"
++then
++    cat > conftest.py <<EOF
++import grp
++gid = ''
++for group in "$with_cgi_gid".split():
++    try:
++        try:
++            gname = grp.getgrgid(int(group))[0]
++            break
++        except ValueError:
++            gname = grp.getgrnam(group)[0]
++            break
++    except KeyError:
++        gname = ''
++fp = open("conftest.out", "w")
++fp.write("%s\n" % gname)
++fp.close()
++EOF
++    $PYTHON conftest.py
++    CGI_GROUP=`cat conftest.out`
++fi
++
++rm -f conftest.out conftest.py
++if test -z "$CGI_GROUP"
++then
++  if test "$with_permcheck" = "yes"
++  then
++    { echo "configure: error: 
++***** No group name \"$with_cgi_gid\" found for the CGI wrapper program.
++***** This is the group that your web server will use to run Mailman's
++***** programs.  You should specify an existing group with the
++***** --with-cgi-gid configure option, or use --without-permcheck to
++***** skip this verification step.  See also your web server's documentation,
++***** and Mailman's INSTALL file for details" 1>&2; exit 1; }
++  else
++    CGI_GROUP=$with_cgi_gid
++  fi
++fi
++echo "$ac_t""$CGI_GROUP" 1>&6
++
++
++# Check for CGI extensions, required by some Web servers
++
++echo $ac_n "checking for CGI extensions""... $ac_c" 1>&6
++echo "configure:1500: checking for CGI extensions" >&5
++# Check whether --with-cgi-ext or --without-cgi-ext was given.
++if test "${with_cgi_ext+set}" = set; then
++  withval="$with_cgi_ext"
++  :
++fi
++
++if test -z "$with_cgi_ext"
++then
++        CGIEXT=''
++        with_cgi_ext='no'
++else
++        CGIEXT=$with_cgi_ext
++fi
++echo "$ac_t""$with_cgi_ext" 1>&6
++
++
++# figure out the default mail hostname and url host component
++
++echo $ac_n "checking for --with-mailhost""... $ac_c" 1>&6
++echo "configure:1520: checking for --with-mailhost" >&5
++# Check whether --with-mailhost or --without-mailhost was given.
++if test "${with_mailhost+set}" = set; then
++  withval="$with_mailhost"
++  :
++fi
++
++if test -z "$with_mailhost"
++then
++        MAILHOST=''
++        with_mailhost='no'
++else
++        MAILHOST=$with_mailhost
++fi
++echo "$ac_t""$with_mailhost" 1>&6
++
++
++echo $ac_n "checking for --with-urlhost""... $ac_c" 1>&6
++echo "configure:1538: checking for --with-urlhost" >&5
++# Check whether --with-urlhost or --without-urlhost was given.
++if test "${with_urlhost+set}" = set; then
++  withval="$with_urlhost"
++  :
++fi
++
++if test -z "$with_urlhost"
++then
++        URLHOST=''
++        with_urlhost='no'
++else
++        URLHOST=$with_urlhost
++fi
++echo "$ac_t""$with_urlhost" 1>&6
++
++
++cat > conftest.py <<EOF
++# python
++from socket import *
++fqdn = getfqdn()
++fp = open('conftest.out', 'w')
++print >> fp, fqdn
++print >> fp, fqdn
++fp.close()
++EOF
++$PYTHON conftest.py
++
++echo $ac_n "checking for default mail host name""... $ac_c" 1>&6
++echo "configure:1567: checking for default mail host name" >&5
++if test -z "$MAILHOST"
++then
++    MAILHOST=`sed q conftest.out`
++fi
++echo "$ac_t""$MAILHOST" 1>&6
++echo $ac_n "checking for default URL host component""... $ac_c" 1>&6
++echo "configure:1574: checking for default URL host component" >&5
++if test -z "$URLHOST"
++then
++    URLHOST=`sed -n '$p' conftest.out`
++fi
++echo "$ac_t""$URLHOST" 1>&6
++rm -f conftest.out conftest.py
++
++# Checks for libraries.
++for ac_func in strerror setregid syslog
++do
++echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
++echo "configure:1586: 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 1591 "configure"
++#include "confdefs.h"
++/* System header to define __stub macros and hopefully few prototypes,
++    which can conflict with char $ac_func(); below.  */
++#include <assert.h>
++/* Override any gcc2 internal prototype to avoid an error.  */
++/* We use char because int might match the return type of a gcc2
++    builtin and then its argument prototype would still apply.  */
++char $ac_func();
++
++int main() {
++
++/* The GNU C library defines this for functions which it implements
++    to always fail with ENOSYS.  Some functions are actually named
++    something starting with __ and the normal name is an alias.  */
++#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
++choke me
++#else
++$ac_func();
++#endif
++
++; return 0; }
++EOF
++if { (eval echo configure:1614: \"$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
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  eval "ac_cv_func_$ac_func=no"
++fi
++rm -f conftest*
++fi
++
++if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
++  echo "$ac_t""yes" 1>&6
++    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
++  cat >> confdefs.h <<EOF
++#define $ac_tr_func 1
++EOF
++ 
++else
++  echo "$ac_t""no" 1>&6
++fi
++done
++
++if test $ac_cv_func_syslog = no; then
++  # syslog is not in the default libraries.  See if it's in some other.
++  # Additionally, for at least SCO OpenServer, syslog() is #defined to
++  # one of several _real_ functions in syslog.h, so we need to do the test
++  # with the appropriate include.
++  for lib in bsd socket inet; do
++    echo $ac_n "checking for syslog in -l$lib""... $ac_c" 1>&6
++echo "configure:1645: checking for syslog in -l$lib" >&5
++    Mailman_LIBS_save="$LIBS"; LIBS="$LIBS -l$lib"
++    cat > conftest.$ac_ext <<EOF
++#line 1648 "configure"
++#include "confdefs.h"
++#include <syslog.h>
++int main() {
++syslog(LOG_DEBUG, "Just a test...");
++; return 0; }
++EOF
++if { (eval echo configure:1655: \"$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
++#define HAVE_SYSLOG 1
++EOF
++
++      break
++else
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  echo "$ac_t""no" 1>&6
++      LIBS="$Mailman_LIBS_save"
++fi
++rm -f conftest*
++    unset Mailman_LIBS_save
++  done
++fi
++
++# Checks for header files.
++echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
++echo "configure:1677: checking how to run the C preprocessor" >&5
++# On Suns, sometimes $CPP names a directory.
++if test -n "$CPP" && test -d "$CPP"; then
++  CPP=
++fi
++if test -z "$CPP"; then
++if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
++  echo $ac_n "(cached) $ac_c" 1>&6
++else
++    # This must be in double quotes, not single quotes, because CPP may get
++  # substituted into the Makefile and "${CC-cc}" will confuse make.
++  CPP="${CC-cc} -E"
++  # On the NeXT, cc -E runs the code through the compiler's parser,
++  # not just through cpp.
++  cat > conftest.$ac_ext <<EOF
++#line 1692 "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:1698: \"$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
++  :
++else
++  echo "$ac_err" >&5
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  CPP="${CC-cc} -E -traditional-cpp"
++  cat > conftest.$ac_ext <<EOF
++#line 1709 "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:1715: \"$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
++  :
++else
++  echo "$ac_err" >&5
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  CPP="${CC-cc} -nologo -E"
++  cat > conftest.$ac_ext <<EOF
++#line 1726 "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:1732: \"$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
++  :
++else
++  echo "$ac_err" >&5
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  CPP=/lib/cpp
++fi
++rm -f conftest*
++fi
++rm -f conftest*
++fi
++rm -f conftest*
++  ac_cv_prog_CPP="$CPP"
++fi
++  CPP="$ac_cv_prog_CPP"
++else
++  ac_cv_prog_CPP="$CPP"
++fi
++echo "$ac_t""$CPP" 1>&6
++
++echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
++echo "configure:1757: 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 1762 "configure"
++#include "confdefs.h"
++#include <stdlib.h>
++#include <stdarg.h>
++#include <string.h>
++#include <float.h>
++EOF
++ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
++{ (eval echo configure:1770: \"$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*
++  ac_cv_header_stdc=yes
++else
++  echo "$ac_err" >&5
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++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 1787 "configure"
++#include "confdefs.h"
++#include <string.h>
++EOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  egrep "memchr" >/dev/null 2>&1; then
++  :
++else
++  rm -rf conftest*
++  ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++fi
++
++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 1805 "configure"
++#include "confdefs.h"
++#include <stdlib.h>
++EOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  egrep "free" >/dev/null 2>&1; then
++  :
++else
++  rm -rf conftest*
++  ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++fi
++
++if test $ac_cv_header_stdc = yes; then
++  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
++if test "$cross_compiling" = yes; then
++  :
++else
++  cat > conftest.$ac_ext <<EOF
++#line 1826 "configure"
++#include "confdefs.h"
++#include <ctype.h>
++#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
++#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
++int main () { int i; for (i = 0; i < 256; i++)
++if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
++exit (0); }
++
++EOF
++if { (eval echo configure:1837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
++then
++  :
++else
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -fr conftest*
++  ac_cv_header_stdc=no
++fi
++rm -fr conftest*
++fi
++
++fi
++fi
++
++echo "$ac_t""$ac_cv_header_stdc" 1>&6
++if test $ac_cv_header_stdc = yes; then
++  cat >> confdefs.h <<\EOF
++#define STDC_HEADERS 1
++EOF
++
++fi
++
++for ac_hdr in syslog.h
++do
++ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
++echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
++echo "configure:1864: 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 1869 "configure"
++#include "confdefs.h"
++#include <$ac_hdr>
++EOF
++ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
++{ (eval echo configure:1874: \"$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*
++  eval "ac_cv_header_$ac_safe=yes"
++else
++  echo "$ac_err" >&5
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  eval "ac_cv_header_$ac_safe=no"
++fi
++rm -f conftest*
++fi
++if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
++  echo "$ac_t""yes" 1>&6
++    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
++  cat >> confdefs.h <<EOF
++#define $ac_tr_hdr 1
++EOF
++ 
++else
++  echo "$ac_t""no" 1>&6
++fi
++done
++
++
++# Checks for typedefs, structures, and compiler characteristics.
++echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
++echo "configure:1903: 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 1908 "configure"
++#include "confdefs.h"
++#include <sys/types.h>
++EOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  egrep "uid_t" >/dev/null 2>&1; then
++  rm -rf conftest*
++  ac_cv_type_uid_t=yes
++else
++  rm -rf conftest*
++  ac_cv_type_uid_t=no
++fi
++rm -f conftest*
++
++fi
++
++echo "$ac_t""$ac_cv_type_uid_t" 1>&6
++if test $ac_cv_type_uid_t = no; then
++  cat >> confdefs.h <<\EOF
++#define uid_t int
++EOF
++
++  cat >> confdefs.h <<\EOF
++#define gid_t int
++EOF
++
++fi
++
++echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
++echo "configure:1937: 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
++  if test "$cross_compiling" = yes; then
++  ac_cv_type_getgroups=cross
++else
++  cat > conftest.$ac_ext <<EOF
++#line 1945 "configure"
++#include "confdefs.h"
++
++/* Thanks to Mike Rendell for this test.  */
++#include <sys/types.h>
++#define NGID 256
++#undef MAX
++#define MAX(x, y) ((x) > (y) ? (x) : (y))
++main()
++{
++  gid_t gidset[NGID];
++  int i, n;
++  union { gid_t gval; long lval; }  val;
++
++  val.lval = -1;
++  for (i = 0; i < NGID; i++)
++    gidset[i] = val.gval;
++  n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
++                 gidset);
++  /* Exit non-zero if getgroups seems to require an array of ints.  This
++     happens when gid_t is short but getgroups modifies an array of ints.  */
++  exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
++}
++
++EOF
++if { (eval echo configure:1970: \"$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
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -fr conftest*
++  ac_cv_type_getgroups=int
++fi
++rm -fr conftest*
++fi
++
++if test $ac_cv_type_getgroups = cross; then
++        cat > conftest.$ac_ext <<EOF
++#line 1984 "configure"
++#include "confdefs.h"
++#include <unistd.h>
++EOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
++  rm -rf conftest*
++  ac_cv_type_getgroups=gid_t
++else
++  rm -rf conftest*
++  ac_cv_type_getgroups=int
++fi
++rm -f conftest*
++
++fi
++fi
++
++echo "$ac_t""$ac_cv_type_getgroups" 1>&6
++cat >> confdefs.h <<EOF
++#define GETGROUPS_T $ac_cv_type_getgroups
++EOF
++
++
++
++# Checks for library functions.
++for ac_func in vsnprintf
++do
++echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
++echo "configure:2012: 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 2017 "configure"
++#include "confdefs.h"
++/* System header to define __stub macros and hopefully few prototypes,
++    which can conflict with char $ac_func(); below.  */
++#include <assert.h>
++/* Override any gcc2 internal prototype to avoid an error.  */
++/* We use char because int might match the return type of a gcc2
++    builtin and then its argument prototype would still apply.  */
++char $ac_func();
++
++int main() {
++
++/* The GNU C library defines this for functions which it implements
++    to always fail with ENOSYS.  Some functions are actually named
++    something starting with __ and the normal name is an alias.  */
++#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
++choke me
++#else
++$ac_func();
++#endif
++
++; return 0; }
++EOF
++if { (eval echo configure:2040: \"$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
++  echo "configure: failed program was:" >&5
++  cat conftest.$ac_ext >&5
++  rm -rf conftest*
++  eval "ac_cv_func_$ac_func=no"
++fi
++rm -f conftest*
++fi
++
++if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
++  echo "$ac_t""yes" 1>&6
++    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
++  cat >> confdefs.h <<EOF
++#define $ac_tr_func 1
++EOF
++ 
++else
++  echo "$ac_t""no" 1>&6
++fi
++done
++
++
++
++
++
++
++
++SCRIPTS="build/bin/add_members:bin/add_members \
++build/bin/arch:bin/arch \
++build/bin/change_pw:bin/change_pw \
++build/bin/check_db:bin/check_db \
++build/bin/check_perms:bin/check_perms \
++build/bin/cleanarch:bin/cleanarch \
++build/bin/clone_member:bin/clone_member \
++build/bin/config_list:bin/config_list \
++build/bin/convert.py:bin/convert.py \
++build/bin/discard:bin/discard \
++build/bin/dumpdb:bin/dumpdb \
++build/bin/find_member:bin/find_member \
++build/bin/fix_url.py:bin/fix_url.py \
++build/bin/genaliases:bin/genaliases \
++build/bin/inject:bin/inject \
++build/bin/list_admins:bin/list_admins \
++build/bin/list_lists:bin/list_lists \
++build/bin/list_members:bin/list_members \
++build/bin/list_owners:bin/list_owners \
++build/bin/mailmanctl:bin/mailmanctl \
++build/bin/mmsitepass:bin/mmsitepass \
++build/bin/msgfmt.py:bin/msgfmt.py \
++build/bin/newlist:bin/newlist \
++build/bin/pygettext.py:bin/pygettext.py \
++build/bin/qrunner:bin/qrunner \
++build/bin/remove_members:bin/remove_members \
++build/bin/rmlist:bin/rmlist \
++build/bin/show_qfiles:bin/show_qfiles \
++build/bin/sync_members:bin/sync_members \
++build/bin/transcheck:bin/transcheck \
++build/bin/unshunt:bin/unshunt \
++build/bin/update:bin/update \
++build/bin/version:bin/version \
++build/bin/withlist:bin/withlist \
++build/bin/b4b5-archfix:bin/b4b5-archfix \
++build/bin/rb-archfix:bin/rb-archfix \
++build/contrib/check_perms_grsecurity.py:contrib/check_perms_grsecurity.py \
++build/contrib/qmail-to-mailman.py:contrib/qmail-to-mailman.py \
++build/contrib/rotatelogs.py:contrib/rotatelogs.py \
++build/cron/bumpdigests:cron/bumpdigests \
++build/cron/checkdbs:cron/checkdbs \
++build/cron/disabled:cron/disabled \
++build/cron/gate_news:cron/gate_news \
++build/cron/mailpasswds:cron/mailpasswds \
++build/cron/nightly_gzip:cron/nightly_gzip \
++build/cron/senddigests:cron/senddigests \
++"
++
++
++
++# These directories are temporary directories to store macro-expanded
++# scripts.  They're removed on a make distclean, so we make them here.
++mkdir -p build/bin build/contrib build/cron
++
++trap '' 1 2 15
++cat > confcache <<\EOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs.  It is not useful on other systems.
++# If it contains results you don't want to keep, you may remove or edit it.
++#
++# By default, configure uses ./config.cache as the cache file,
++# creating it if it does not exist already.  You can give configure
++# the --cache-file=FILE option to use a different cache file; that is
++# what configure does when it calls configure scripts in
++# subdirectories, so they share the cache.
++# Giving --cache-file=/dev/null disables caching, for debugging configure.
++# config.status only pays attention to the cache file if you give it the
++# --recheck option to rerun configure.
++#
++EOF
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++(set) 2>&1 |
++  case `(ac_space=' '; set | grep ac_space) 2>&1` in
++  *ac_space=\ *)
++    # `set' does not quote correctly, so add quotes (double-quote substitution
++    # turns \\\\ into \\, and sed turns \\ into \).
++    sed -n \
++      -e "s/'/'\\\\''/g" \
++      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
++    ;;
++  *)
++    # `set' quotes correctly as required by POSIX, so do not add quotes.
++    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
++    ;;
++  esac >> confcache
++if cmp -s $cache_file confcache; then
++  :
++else
++  if test -w $cache_file; then
++    echo "updating cache $cache_file"
++    cat confcache > $cache_file
++  else
++    echo "not updating unwritable cache $cache_file"
++  fi
++fi
++rm -f confcache
++
++trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++# Any assignment to VPATH causes Sun make to only execute
++# the first set of double-colon rules, so remove it if not needed.
++# If there is a colon in the path, we need to keep it.
++if test "x$srcdir" = x.; then
++  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
++fi
++
++trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
++
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++cat > conftest.defs <<\EOF
++s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
++s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
++s%\[%\\&%g
++s%\]%\\&%g
++s%\$%$$%g
++EOF
++DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
++rm -f conftest.defs
++
++
++# Without the "./", some shells look in PATH for config.status.
++: ${CONFIG_STATUS=./config.status}
++
++echo creating $CONFIG_STATUS
++rm -f $CONFIG_STATUS
++cat > $CONFIG_STATUS <<EOF
++#! /bin/sh
++# Generated automatically by configure.
++# Run this file to recreate the current configuration.
++# This directory was configured as follows,
++# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
++#
++# $0 $ac_configure_args
++#
++# Compiler output produced by configure, useful for debugging
++# configure, is in ./config.log if it exists.
++
++ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
++for ac_option
++do
++  case "\$ac_option" in
++  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
++    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
++  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
++    echo "$CONFIG_STATUS generated by autoconf version 2.13"
++    exit 0 ;;
++  -help | --help | --hel | --he | --h)
++    echo "\$ac_cs_usage"; exit 0 ;;
++  *) echo "\$ac_cs_usage"; exit 1 ;;
++  esac
++done
++
++ac_given_srcdir=$srcdir
++ac_given_INSTALL="$INSTALL"
++
++trap 'rm -fr `echo "misc/paths.py Mailman/Defaults.py Mailman/mm_cfg.py.dist
++           src/Makefile misc/Makefile bin/Makefile
++           Mailman/Makefile Mailman/Cgi/Makefile Mailman/Logging/Makefile
++           Mailman/Archiver/Makefile Mailman/Commands/Makefile
++           Mailman/Handlers/Makefile Mailman/Bouncers/Makefile
++           Mailman/Queue/Makefile Mailman/MTA/Makefile Mailman/Gui/Makefile
++           templates/Makefile cron/Makefile scripts/Makefile messages/Makefile
++           cron/crontab.in misc/mailman Makefile
++           tests/Makefile tests/bounces/Makefile tests/msgs/Makefile
++           $SCRIPTS" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
++EOF
++cat >> $CONFIG_STATUS <<EOF
++
++# Protect against being on the right side of a sed subst in config.status.
++sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
++ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
++$ac_vpsub
++$extrasub
++s%@SHELL@%$SHELL%g
++s%@CFLAGS@%$CFLAGS%g
++s%@CPPFLAGS@%$CPPFLAGS%g
++s%@CXXFLAGS@%$CXXFLAGS%g
++s%@FFLAGS@%$FFLAGS%g
++s%@DEFS@%$DEFS%g
++s%@LDFLAGS@%$LDFLAGS%g
++s%@LIBS@%$LIBS%g
++s%@exec_prefix@%$exec_prefix%g
++s%@prefix@%$prefix%g
++s%@program_transform_name@%$program_transform_name%g
++s%@bindir@%$bindir%g
++s%@sbindir@%$sbindir%g
++s%@libexecdir@%$libexecdir%g
++s%@datadir@%$datadir%g
++s%@sysconfdir@%$sysconfdir%g
++s%@sharedstatedir@%$sharedstatedir%g
++s%@localstatedir@%$localstatedir%g
++s%@libdir@%$libdir%g
++s%@includedir@%$includedir%g
++s%@oldincludedir@%$oldincludedir%g
++s%@infodir@%$infodir%g
++s%@mandir@%$mandir%g
++s%@with_python@%$with_python%g
++s%@PYTHON@%$PYTHON%g
++s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
++s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
++s%@INSTALL_DATA@%$INSTALL_DATA%g
++s%@SET_MAKE@%$SET_MAKE%g
++s%@TRUE@%$TRUE%g
++s%@CC@%$CC%g
++s%@OPT@%$OPT%g
++s%@VAR_PREFIX@%$VAR_PREFIX%g
++s%@MAILMAN_USER@%$MAILMAN_USER%g
++s%@MAILMAN_GROUP@%$MAILMAN_GROUP%g
++s%@MAIL_GROUP@%$MAIL_GROUP%g
++s%@CGI_GROUP@%$CGI_GROUP%g
++s%@CGIEXT@%$CGIEXT%g
++s%@MAILHOST@%$MAILHOST%g
++s%@URLHOST@%$URLHOST%g
++s%@CPP@%$CPP%g
++s%@SCRIPTS@%$SCRIPTS%g
++
++CEOF
++EOF
++
++cat >> $CONFIG_STATUS <<\EOF
++
++# Split the substitutions into bite-sized pieces for seds with
++# small command number limits, like on Digital OSF/1 and HP-UX.
++ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
++ac_file=1 # Number of current file.
++ac_beg=1 # First line for current file.
++ac_end=$ac_max_sed_cmds # Line after last line for current file.
++ac_more_lines=:
++ac_sed_cmds=""
++while $ac_more_lines; do
++  if test $ac_beg -gt 1; then
++    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
++  else
++    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
++  fi
++  if test ! -s conftest.s$ac_file; then
++    ac_more_lines=false
++    rm -f conftest.s$ac_file
++  else
++    if test -z "$ac_sed_cmds"; then
++      ac_sed_cmds="sed -f conftest.s$ac_file"
++    else
++      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
++    fi
++    ac_file=`expr $ac_file + 1`
++    ac_beg=$ac_end
++    ac_end=`expr $ac_end + $ac_max_sed_cmds`
++  fi
++done
++if test -z "$ac_sed_cmds"; then
++  ac_sed_cmds=cat
++fi
++EOF
++
++cat >> $CONFIG_STATUS <<EOF
++
++CONFIG_FILES=\${CONFIG_FILES-"misc/paths.py Mailman/Defaults.py Mailman/mm_cfg.py.dist
++           src/Makefile misc/Makefile bin/Makefile
++           Mailman/Makefile Mailman/Cgi/Makefile Mailman/Logging/Makefile
++           Mailman/Archiver/Makefile Mailman/Commands/Makefile
++           Mailman/Handlers/Makefile Mailman/Bouncers/Makefile
++           Mailman/Queue/Makefile Mailman/MTA/Makefile Mailman/Gui/Makefile
++           templates/Makefile cron/Makefile scripts/Makefile messages/Makefile
++           cron/crontab.in misc/mailman Makefile
++           tests/Makefile tests/bounces/Makefile tests/msgs/Makefile
++           $SCRIPTS"}
++EOF
++cat >> $CONFIG_STATUS <<\EOF
++for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
++  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
++  case "$ac_file" in
++  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
++       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
++  *) ac_file_in="${ac_file}.in" ;;
++  esac
++
++  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
++
++  # Remove last slash and all that follows it.  Not all systems have dirname.
++  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
++  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
++    # The file is in a subdirectory.
++    test ! -d "$ac_dir" && mkdir "$ac_dir"
++    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
++    # A "../" for each directory in $ac_dir_suffix.
++    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
++  else
++    ac_dir_suffix= ac_dots=
++  fi
++
++  case "$ac_given_srcdir" in
++  .)  srcdir=.
++      if test -z "$ac_dots"; then top_srcdir=.
++      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
++  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
++  *) # Relative path.
++    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
++    top_srcdir="$ac_dots$ac_given_srcdir" ;;
++  esac
++
++  case "$ac_given_INSTALL" in
++  [/$]*) INSTALL="$ac_given_INSTALL" ;;
++  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
++  esac
++
++  echo creating "$ac_file"
++  rm -f "$ac_file"
++  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
++  case "$ac_file" in
++  *Makefile*) ac_comsub="1i\\
++# $configure_input" ;;
++  *) ac_comsub= ;;
++  esac
++
++  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
++  sed -e "$ac_comsub
++s%@configure_input@%$configure_input%g
++s%@srcdir@%$srcdir%g
++s%@top_srcdir@%$top_srcdir%g
++s%@INSTALL@%$INSTALL%g
++" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
++fi; done
++rm -f conftest.s*
++
++EOF
++cat >> $CONFIG_STATUS <<EOF
++
++EOF
++cat >> $CONFIG_STATUS <<\EOF
++echo "configuration completed at" `date`
++exit 0
++EOF
++chmod +x $CONFIG_STATUS
++rm -fr confdefs* $ac_clean_files
++test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
++
++
++# Make sure all the build scripts are executable.
++chmod -R +x build
++
++# Test for the Chinese codecs.
++
+diff -Nru mailman-2.1.5/cron/crontab.in.in mailman-2.1.5+htdig/cron/crontab.in.in
+--- mailman-2.1.5/cron/crontab.in.in	2002-01-06 07:28:12.000000000 +0100
++++ mailman-2.1.5+htdig/cron/crontab.in.in	2005-07-04 10:04:30.247419616 +0200
+@@ -18,6 +18,11 @@
+ # or want to exclusively use a callback strategy instead of polling.
+ 0,5,10,15,20,25,30,35,40,45,50,55 * * * * @PYTHON@ -S @prefix@/cron/gate_news
+ #
++# At 2:19am every night, regenerate htdig search files.  Only
++# turn this on if the internal archiver is used and htdig
++# use enabled in mm_cfg.py with USE_HTDIG
++19 2 * * * @PYTHON@ -S @prefix@/cron/nightly_htdig
++#
+ # At 3:27am every night, regenerate the gzip'd archive file.  Only
+ # turn this on if the internal archiver is used and
+ # GZIP_ARCHIVE_TXT_FILES is false in mm_cfg.py
+diff -Nru mailman-2.1.5/cron/Makefile.in mailman-2.1.5+htdig/cron/Makefile.in
+--- mailman-2.1.5/cron/Makefile.in	2003-03-31 21:27:07.000000000 +0200
++++ mailman-2.1.5+htdig/cron/Makefile.in	2005-07-04 10:04:30.249419312 +0200
+@@ -42,7 +42,9 @@
+ SHELL=		/bin/sh
+ 
+ PROGRAMS=	checkdbs mailpasswds senddigests gate_news \
+-		nightly_gzip bumpdigests disabled
++		nightly_gzip bumpdigests disabled \
++		nightly_htdig remote_nightly_htdig \
++		remote_nightly_htdig_noshare remote_nightly_htdig.pl
+ FILES=  	crontab.in
+ 
+ BUILDDIR=	../build/cron
+diff -Nru mailman-2.1.5/cron/nightly_htdig mailman-2.1.5+htdig/cron/nightly_htdig
+--- mailman-2.1.5/cron/nightly_htdig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/cron/nightly_htdig	2005-07-04 10:04:30.251419008 +0200
+@@ -0,0 +1,155 @@
++#! @PYTHON@
++# 
++# Copyright (C) 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++"""Re-generate the htdig archive search files.
++
++This script should normally be run nightly from cron.  When run from the
++command line, the following usage is understood:
++
++Usage: %(program)s [-v] [-h] [listnames]
++
++Where:
++    --verbose / -v
++        print each list as htdig is run for it
++
++    listnames
++        Optionally, only runs htdig for the named lists.  Without 
++        this, all archivable lists are processed.
++
++    --help / -h
++        print this message and exit
++
++"""
++
++# this code was derived from the nightly_gzip cron script
++
++import sys
++import os
++from stat import *
++import time
++from types import *
++import getopt
++import paths
++import errno
++from Mailman import MailList
++from Mailman import Utils
++from Mailman import mm_cfg
++from Mailman.Archiver import HyperArch
++from Mailman.i18n import _
++
++program = sys.argv[0]
++
++def usage(code, msg=''):
++    print >> sys.stderr, _( __doc__)
++    if msg:
++        print msg
++    sys.exit(code)
++
++def main():
++    try:
++        opts, args = getopt.getopt(sys.argv[1:], 'vh', ['verbose', 'help'])
++    except getopt.error, msg:
++        usage(1, msg)
++
++    # defaults
++    verbose = 0
++    for opt, arg in opts:
++        if opt in ('-h', '--help'):
++            usage(0)
++        elif opt in ('-v', '--verbose'):
++            verbose = 1
++ 
++    # limit to the specified lists?
++    if args:
++        listnames = args
++    else:
++        listnames = Utils.list_names()
++
++    # process all the specified lists
++    for name in listnames:
++        mlist = MailList.MailList(name, lock=0)
++        if not mlist.archive:
++            continue
++        archive_dir = mlist.archive_dir()
++        try:
++            os.listdir(archive_dir)
++        except os.error:
++            # has the list received any messages?  if not,
++            # last_post_time will
++            # be zero, so it's not really a bogus archive dir.
++            if mlist.last_post_time > 0:
++                print _(
++                    'List %(name)s has a bogus archive dir: %(archive_dir)s')
++            continue
++        
++        # check htdig has been set up for this list and skip it if not
++        list_htdig_dir = os.path.join(archive_dir, 'htdig')
++        if not os.path.exists(list_htdig_dir):
++            if verbose:
++		print _('Skipping htdig for list; no htdig setup: %(name)s')
++            continue
++         
++        # check if there have been any archive files created since we
++        # last ran htdig and skip list if not. well actually we only
++        # test if the archive volume directories mod times have 
++        # changed        
++        recent_posts = None
++        rundig_run_file = os.path.join(list_htdig_dir, 'rundig_last_run')
++        archive = HyperArch.HyperArchive(mlist)
++        try:
++            last_rundig_time = os.stat(rundig_run_file)[ST_MTIME]
++        except OSError, e:
++            if e.errno <> errno.ENOENT: raise
++            open(rundig_run_file, 'w').close()
++            recent_posts = 1
++        else:
++            for volume in archive.archives:
++                archive_name = os.path.join(archive_dir, volume)
++                last_archive_change = os.stat(archive_name)[ST_MTIME]
++                if last_archive_change > last_rundig_time:
++                    recent_posts = 1
++                    break
++        if not recent_posts:
++            if verbose:
++                print _('Skipping htdig for list; no recent posts: %(name)s')
++            continue
++        
++        # ok, so running htdig is worthwhile
++        if verbose:
++            print _("htdig'ing archive of list: %(name)s")
++        htdig_conf_file = os.path.join(list_htdig_dir, name + '.conf')
++        cmd = '%s -c %s' % (mm_cfg.HTDIG_RUNDIG_PATH, htdig_conf_file)
++        status = (os.system(cmd) >> 8) & 0xff
++        if status:
++            print _('rundig failed for list %(name)s, exit code: %(status)s')
++        else:
++            os.utime(rundig_run_file, None)
++            archive.write_TOC()
++
++if __name__ == '__main__' and \
++   mm_cfg.USE_HTDIG and \
++   mm_cfg.ARCHIVE_TO_MBOX in (0, 2) and \
++   os.path.exists(mm_cfg.HTDIG_RUNDIG_PATH):
++    # we're only going to run the nightly rundig if messages are
++    # archived to the internal archiver, we are using htdig to provide
++    # archive search and we know where rundig is.
++    omask = os.umask(002)
++    try:
++        main()
++    finally:
++        os.umask(omask)
+diff -Nru mailman-2.1.5/cron/remote_nightly_htdig mailman-2.1.5+htdig/cron/remote_nightly_htdig
+--- mailman-2.1.5/cron/remote_nightly_htdig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/cron/remote_nightly_htdig	2005-07-04 10:04:30.253418704 +0200
+@@ -0,0 +1,163 @@
++#! @PYTHON@
++# 
++# Copyright (C) 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++"""Python script to re-generate the htdig archive search files. Read 
++INSTALL.htdig-mm to determine if you should be running this script.
++
++This script has to be edited before use to provide a value for the
++configuration parameter MAILMAN_PATH. The value should be the path 
++to Mailman's installation directory as seen by the script.
++
++This script should normally be run nightly from cron.  When run from the
++command line, the following usage is understood:
++
++Usage: %(program)s [-v] [-h] [listnames]
++
++Where:
++    --verbose / -v
++        print each list as htdig is run for it
++
++    --help / -h
++        print this message and exit
++
++    listnames
++        Optionally, only runs htdig for the named lists.  Without 
++        this, all archivable lists are processed.
++
++"""
++
++# this code was derived from the nightly_gzip cron script
++
++MAILMAN_PATH = ''
++
++import sys
++import os
++from stat import *
++import time
++import getopt
++import string
++from types import *
++import errno
++
++import urllib, urlparse
++import paths
++
++program = sys.argv[0]
++
++def usage(code, msg=''):
++    print >> sys.stderr, _( __doc__)
++    if msg:
++        print msg
++    sys.exit(code)
++
++def main():
++    try:
++        opts, args = getopt.getopt(sys.argv[1:], 'vhm', ['verbose', 'help'])
++    except getopt.error, msg:
++        usage(1, msg)
++    # defaults
++    verbose = 0
++    for opt, arg in opts:
++        if opt in ('-h', '--help'):
++            usage(0)
++        elif opt in ('-v', '--verbose'):
++            verbose = 1
++    # limit to the specified lists?
++    if args:
++        listnames = map(string.lower, args)
++    else:
++        listnames = Utils.list_names()
++    # process all the specified lists
++    for name in listnames:
++        mlist = MailList.MailList(name, lock=0)
++        if not mlist.archive:
++            continue
++        archive_dir = os.path.join(mm_cfg.REMOTE_PRIVATE_ARCHIVE_FILE_DIR,
++                                   name + '/')
++        try:
++            os.listdir(archive_dir)
++        except os.error:
++            # has the list received any messages?  if not, last_post_time 
++            # will be zero, so it's not really a bogus archive dir.
++            if mlist.last_post_time > 0:
++                print _(
++                     'List %(name)s has a bogus archive dir: %(archive_dir)s')
++            continue
++        # check htdig has been set up for this list and skip it if not
++        list_htdig_dir = os.path.join(archive_dir, 'htdig')
++        if not os.path.exists(list_htdig_dir):
++            if verbose:
++                print _(
++		  'Skipping remote htdig for list; nno htdig setup: %(name)s')
++            continue
++        # check if there have been any archive files created since we
++        # last ran htdig and skip list if not. well actually we only
++        # test if the archive volume directories mod times have changed        
++        recent_posts = None
++        rundig_run_file = os.path.join(list_htdig_dir, 'rundig_last_run')
++        archive = HyperArch.HyperArchive(mlist)
++        try:      
++            last_rundig_time = os.stat(rundig_run_file)[ST_MTIME]
++        except OSError, e:
++            if e.errno <> errno.ENOENT: raise
++            open(rundig_run_file, 'w').close()
++            recent_posts = 1
++        else:
++            for volume in archive.archives:
++                archive_name = os.path.join(archive_dir, volume)
++                last_archive_change = os.stat(archive_name)[ST_MTIME]
++                if last_archive_change > last_rundig_time:
++                    recent_posts = 1
++                    break
++        if not recent_posts:
++            if verbose:
++                print _('Skipping htdig for list; no recent posts: %(name)s')
++            continue
++        # ok, so running htdig is worthwhile
++        if verbose:
++            print _("htdig'ing archive of list: %(name)s")
++        htdig_conf_file = os.path.join(list_htdig_dir, name + '.conf')
++        cmd = '%s -c %s' % (mm_cfg.HTDIG_RUNDIG_PATH, htdig_conf_file)
++        status = (os.system(cmd) >> 8) & 0xff
++        if status:
++            print _('rundig failed for list %(name)s, exit code: %(status)s')
++        else:
++            os.utime(rundig_run_file, None)
++
++if __name__ == '__main__' and os.path.exists(MAILMAN_PATH):
++    # Access the mailman installation
++    sys.path = [MAILMAN_PATH] + sys.path
++    from Mailman import MailList
++    from Mailman import Utils
++    from Mailman import mm_cfg
++    from Mailman.Archiver import HyperArch
++    from Mailman.i18n import _
++    if mm_cfg.USE_HTDIG and \
++       mm_cfg.ARCHIVE_TO_MBOX in (0, 2) and \
++       os.path.exists(mm_cfg.HTDIG_RUNDIG_PATH):
++        # we're only going to run the nightly rundig if messages are archived to
++        # the internal archiver, we are using htdig to provide archive search
++        # and we know where rundig is.
++        omask = os.umask(002)
++        try:
++            main()
++        finally:
++            os.umask(omask)
++else:
++    print  'Invalid configuration variables'  
++    print  'Edit this script in accordance with INSTALL.htdig-mm'
+diff -Nru mailman-2.1.5/cron/remote_nightly_htdig_noshare mailman-2.1.5+htdig/cron/remote_nightly_htdig_noshare
+--- mailman-2.1.5/cron/remote_nightly_htdig_noshare	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/cron/remote_nightly_htdig_noshare	2005-07-04 10:04:30.255418400 +0200
+@@ -0,0 +1,151 @@
++#! @PYTHON@
++# 
++# Copyright (C) 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++"""Python script to re-generate the htdig archive search files. Read
++INSTALL.htdig-mm to determine if you should be running this script.
++
++This script has to be edited before use to provide values for the
++configuration parameters REMOTE_PRIVATE_ARCHIVE_FILE_DIR and
++HTDIG_RUNDIG_PATH. The values should be the same as those acquired by
++other of Mailman's python code from $prefix/Mailman/Defaults.py or 
++overridden in $prefix/Mailman/mm_cfg.py.
++
++This script should normally be run nightly from cron.  When run from the
++command line, the following usage is understood:
++
++Usage: %(program)s [-v] [-h] [listnames]
++
++Where:
++    --verbose / -v
++        print each list as htdig is run for it
++
++    --help /-h
++        print this message and exit
++
++    listnames
++        Optionally, only runs htdig for the named lists.  Without 
++        this, all archivable lists are processed.
++
++"""
++
++# this code was derived from the nightly_gzip cron script
++
++REMOTE_PRIVATE_ARCHIVE_FILE_DIR = ''
++HTDIG_RUNDIG_PATH = ''
++
++import sys
++import os
++from stat import *
++import time
++from types import *
++import getopt
++import urllib
++import urlparse
++import string
++import errno
++
++program = sys.argv[0]
++
++def usage(code, msg=''):
++    print __doc__ % globals()
++    if msg:
++        print msg
++    sys.exit(code)
++
++def main():
++    try:
++        opts, args = getopt.getopt(sys.argv[1:], 'vhm', ['verbose', 'help'])
++    except getopt.error, msg:
++        usage(1, msg)
++
++    # defaults
++    verbose = 0
++    for opt, arg in opts:
++        if opt in ('-h', '--help'):
++            usage(0)
++        elif opt in ('-v', '--verbose'):
++            verbose = 1
++    # limit to the specified lists?
++    if args:
++        listnames = map(string.lower, args)
++    else:
++        listnames = filter(lambda m: m[-5:] != '.mbox',
++                           os.listdir(REMOTE_PRIVATE_ARCHIVE_FILE_DIR))
++    # process all the specified lists
++    listnames.sort()
++    for name in listnames:
++        archive_dir = os.path.join(REMOTE_PRIVATE_ARCHIVE_FILE_DIR, name)
++        # check if this list has an archive and skip it if not
++        if not os.path.exists(archive_dir):
++            if verbose:
++                print 'Skipping remote htdig for list', name, 'no archive'
++            continue
++        # check htdig has been set up for this list and skip it if not
++        list_htdig_dir = os.path.join(archive_dir, 'htdig')
++        if not os.path.exists(list_htdig_dir):
++            if verbose:
++                print 'Skipping remote htdig for list', name, 'no htdig setup'
++            continue         
++        # check if there have been any archive files created since we
++        # last ran htdig and skip list if not. well actually we only
++        # test if the archive volume directories mod times have changed        
++        recent_posts = None
++        rundig_run_file = os.path.join(list_htdig_dir, 'rundig_last_run')
++        try:
++            last_rundig_time = os.stat(rundig_run_file)[ST_MTIME]
++        except OSError, e:
++            if e.errno <> errno.ENOENT: raise
++            open(rundig_run_file, 'w').close()
++            recent_posts = 1
++        else:
++            for volume in os.listdir(archive_dir):
++                archive_name = os.path.join(archive_dir, volume)
++                last_archive_change = os.stat(archive_name)[ST_MTIME]
++                if last_archive_change > last_rundig_time:
++                    recent_posts = 1
++                    break
++        if not recent_posts:
++            if verbose:
++                print 'Skipping htdig for list', name, 'no recent posts'
++            continue
++        # ok, so running htdig is worthwhile
++        if verbose:
++            print "htdig'ing archive of list", name
++        htdig_conf_file = os.path.join(list_htdig_dir, name + '.conf')
++        cmd = '%s -c %s' % (HTDIG_RUNDIG_PATH, htdig_conf_file)
++        status = (os.system(cmd) >> 8) & 0xff
++        if status:
++            print 'rundig failed for list %s, exit code: %s' % (name, status)
++        else:
++            os.utime(rundig_run_file, None)
++
++if __name__ == '__main__' and \
++   os.path.exists(REMOTE_PRIVATE_ARCHIVE_FILE_DIR) and \
++   os.path.exists(HTDIG_RUNDIG_PATH):
++    # we're only going to run the nightly rundig if we have a sensible
++    # set of configuration variables and we know where rundig is.
++    omask = os.umask(002)
++    try:
++        main()
++    finally:
++        os.umask(omask)
++else:
++    print "Invalid configuration variables"
++    print "Edit this script in accordance with INSTALL.htdig-mm"
++
++
+diff -Nru mailman-2.1.5/cron/remote_nightly_htdig.pl mailman-2.1.5+htdig/cron/remote_nightly_htdig.pl
+--- mailman-2.1.5/cron/remote_nightly_htdig.pl	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/cron/remote_nightly_htdig.pl	2005-07-04 10:04:30.257418096 +0200
+@@ -0,0 +1,151 @@
++#! /usr/bin/env perl
++# 
++# Copyright (C) 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++
++# this code was derived from the nightly_gzip cron script
++
++my $REMOTE_PRIVATE_ARCHIVE_FILE_DIR = '';
++my $HTDIG_RUNDIG_PATH = '';
++
++use strict;
++use File::Spec;
++use File::stat;
++use LWP::Simple;
++use Getopt::Long;
++
++my $doc = <<EOT;
++Perl version of the script to re-generate the htdig archive search files.
++
++Read INSTALL.htdig-mm to determine if you should be running this script.
++
++This script has to be edited before use to provide values for the
++configuration parameters REMOTE_PRIVATE_ARCHIVE_FILE_DIR and
++HTDIG_RUNDIG_PATH. The values should be the same as those acquired by
++Mailman's python scripts from \$prefix/Mailman/Defaults.py or overridden
++in \$prefix/Mailman/mm_cfg.py.
++
++This script should normally be run nightly from cron.  When run from the
++command line, the following usage is understood:
++
++Usage: remote_nightly_htdig.pl [-v] [-h] [listnames]
++
++Where:
++    --verbose / -v
++        print each list as htdig is run for it
++
++    --help / -h
++        print this message and exit
++
++    listnames
++        Optionally, only runs htdig for the named lists.  Without 
++        this, all archivable lists are processed.
++
++EOT
++
++my $VERBOSE = 0;
++my $omask;
++
++sub usage {
++    my ($code, $msg) = @_;
++    print $doc;
++    print $msg if $msg;
++    umask($omask);
++    exit($code);
++}
++
++sub main {
++    my $help;
++    GetOptions("verbose" => \$VERBOSE,
++               "help" => \$help);
++    if ($help) {
++        usage(0);
++    }
++    # limit to the specified lists?
++    my @listnames = ();
++    if (scalar(@ARGV)) {
++        @listnames = map lc, @ARGV;
++    } else {
++        opendir(DIR, $REMOTE_PRIVATE_ARCHIVE_FILE_DIR);
++        @listnames = grep { $_ ne '.' and $_ ne '..' and ! /\.mbox$/ } readdir DIR;
++        closedir(DIR);
++    }
++    # process all the specified lists
++    foreach my $name (@listnames) {
++        my $archive_dir = File::Spec->catfile($REMOTE_PRIVATE_ARCHIVE_FILE_DIR, $name);
++        next if (-e not $archive_dir);
++        # check htdig has been set up for this list and skip it if not
++        my $list_htdig_dir = File::Spec->catfile($archive_dir, 'htdig');
++        if (not -e $list_htdig_dir) {
++            print "Skipping remote htdig for list $name, no htdig setup\n" if $VERBOSE;
++            next
++        }
++        # check if there have been any archive files created since we
++        # last ran htdig and skip list if not. well actually we only
++        # test if the archive volume directories mod times have changed        
++        my $recent_posts = 0;
++        my $rundig_run_file = File::Spec->catfile($list_htdig_dir, 'rundig_last_run');
++        if (-e $rundig_run_file){      
++            my $last_rundig_time = stat($rundig_run_file)->mtime();
++            opendir(DIR, $archive_dir);
++            my @volumes = grep { $_ ne '.' and $_ ne '..' } readdir DIR;
++            closedir(DIR);
++            foreach my $volume (@volumes) {
++                my $archive_name = File::Spec->catfile($archive_dir, $volume);
++                my $last_archive_change = stat($archive_name)->mtime();
++                if ($last_archive_change > $last_rundig_time) {
++                    $recent_posts = 1;
++                    last;
++                }
++            }
++        } else {
++            $recent_posts = 1;
++        }
++        if (not $recent_posts) {
++            if ($VERBOSE) {
++                print "Skipping htdig for list $name, no recent posts\n";
++            }
++            next;
++        }
++        # ok, so running htdig is worthwhile
++        if ($VERBOSE) {
++            print "htdig'ing archive of list $name\n";
++        }
++        my $htdig_conf_file = File::Spec->catfile($list_htdig_dir, $name.'.conf');
++        my @cmd = ($HTDIG_RUNDIG_PATH, '-c', $htdig_conf_file);
++        my $status = system(@cmd) >> 8 & 0xFF;
++        if ($status) {
++            print "rundig failed for list, $name, exit code, $status\n";
++        } else {
++            system(("touch", $rundig_run_file));
++        }
++    }
++}
++
++if (-x $HTDIG_RUNDIG_PATH  and
++    -d $REMOTE_PRIVATE_ARCHIVE_FILE_DIR) {
++    # we're only going to run the nightly rundig if we have a sensible
++    # set of configuration variables and we know where rundig is.
++    $omask = umask;
++    umask(002);
++    eval { main() };
++    my $res = $@;
++    umask($omask);
++    die $res if ($res);
++} else {
++    die "Invalid configuration variables.\nEdit this script in accordance with INSTALL.htdig-mm\n";
++}
+diff -Nru mailman-2.1.5/INSTALL mailman-2.1.5+htdig/INSTALL
+--- mailman-2.1.5/INSTALL	2004-02-18 00:05:32.000000000 +0100
++++ mailman-2.1.5+htdig/INSTALL	2005-07-04 10:04:30.259417792 +0200
+@@ -471,6 +471,11 @@
+       -c option to mmsitepass to set this.
+ 
+ 
++    - If you want to use htdig for searching your mail archives using
++      the Mailman-htdig integration developed by Richard Barrett
++      ([email-masked]) then see the instructions in 
++      INSTALL.htdig-mm.
++
+ 6. Getting started
+ 
+     See the README file under the section "CREATE YOUR FIRST LIST" for
+diff -Nru mailman-2.1.5/INSTALL.htdig-mm mailman-2.1.5+htdig/INSTALL.htdig-mm
+--- mailman-2.1.5/INSTALL.htdig-mm	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/INSTALL.htdig-mm	2005-07-04 10:04:30.263417184 +0200
+@@ -0,0 +1,1551 @@
++Mailman Patch #444884 (Mailman-htdig integration) Installation Details
++----------------------------------------------------------------------
++ 
++
++The information below is also available in the INSTALL.htdig-mm.html file which
++is installed by this patch. 
++
++Table of Contents
++----------------
++ 
++
++*	Patch identification 
++*	Prerequisites 
++*	Current version 
++*	Changes introduced by this patch version 
++
++
++*	Introduction 
++*	Installing and Building Mailman with this patch 
++*	What is Installed by the Patch 
++*	Configuration of Mailman-htdig Integration 
++*	Health Warning on the packet! 
++*	Starting from Scratch (Again) 
++*	General 
++*	Permissions Considerations 
++*	htdig 
++*	Apache 
++
++
++*	Local htdig Configuration 
++*	Remote htdig Configuration 
++*	Upgrading an Existing Standard Mailman Installation 
++*	Changing from local to remote htdig or vice versa 
++*	Coping with htdig Upgrades 
++*	Changing the Addressing Scheme of your web_page_url 
++
++
++*	Operational Information 
++*	Notes and Warnings 
++*	Archive security problems resolved by htdig-2.1.3-0.2 patch 
++*	Private archive security problem prior to htdig-2.1.1-0.2.patch version 
++*	Maintaining archive security with htdig-2.1.1-0.2.patch version and later 
++*	Upgrading to htdig-2.1.1-0.2.patch or later from an earlier patch version 
++*	Redhat 7.1 and 7.2 installations 
++*	Apache/htdig issues 
++
++
++*	Contributors 
++*	History 
++*	Compatibility 
++*	Changes 
++
++
++*	Appendices 
++*	Appendix 1 -Technique for htdigging when Mailman's DEFAULT_URL uses the
++https scheme 
++
++
++
++
++Patch Identification�
++----------------
++
++Different versions of this patch are available for different versions of
++Mailman. There may be different versions of this patch for any given version of
++Mailman, typically as a results of MM version specific improvements or
++corrections of bugs in the patched code. The names of patch files for this patch
++are structured as follows: 
++
++
++    htdig-<MM-version-no>-<patch-version-no>.patch[.gz]
++ 
++
++Thus, for instance, patch file htdig-2.1.4-0.1.patch is patch version 0.1 for
++application to MM version 2.1.4 source code. 
++
++The <patch-version-no> is reset to 0.1 for the first patch version applicable to
++each new version of Mailman. 
++
++The .gz suffix, if present, says that the patch file has been compressed using
++gzip. 
++
++As a general rule, you should use the highest patch version number for the MM
++version you are installing. 
++
++Current Version�
++----------------
++
++The current version of this patch is for Mailman 2.1.5: 
++Mailman 2.1.5 	- 	htdig-2.1.5-0.1.patch 
++
++Be sure to read the notes in the cCanges section below about the patch version 
++you are going to use.
++
++Patches for previous versions of Mailman are frozen at the highest revision
++level they reached while those previous versions of MM were current. 
++
++Information about older Mailman and patch versions is given in the history
++section below. 
++
++Changes introduced by this patch version�
++----------------
++
++The following changes are introduced by version 0.1 of this patch: 
++
++*  Updated patch for MM 2.1.5 compatibility.
++*  Note: the templates in $build/templates/<lang>/for the following 
++   languages are NOT modified by this patch or by its precursor indexing 
++   patch: ca, eu, sr, sv
++    
++   The following files in a language's default template directory should be 
++   modified per the changes made to the en language templates after 
++   installation of this patch if that other language is used ;'
++                    
++       templates/<lang>/archidxfoot.html
++       templates/<lang>/archidxhead.html
++       templates/<lang>/archtoc.html
++       templates/<lang>/archtocentry.html
++       templates/<lang>/archtocnombox.html
++       templates/<lang>/article.html
++
++Prerequisites�[ toc ]
++----------------
++
++A working Htdig installation
++----------------
++
++You must have a working installation of htdig with htsearch available and
++installed on either the machine on which you are running Mailman or on another
++machine which has access to Mailman list archives via NFS or some similarly
++competent network file sharing scheme. 
++
++Regardless of how you configure things to provide Mailman's Web UI, if its gives
++normal operation of the /mailman/private CGI script for providing access to
++private list archives, it should also support access to htdig search results via
++the /mailman/mmsearch and /mailman/htdig CGI scripts. 
++
++Warning: This patch has been tested with HTdig 3.1.6 and no testing has been
++done with the Beta versions of HTdig 3.2 at the time of writing. You may or may
++not encounter problems/issues not described here if you use HTdig 3.2 beta or
++stable releases. 
++
++Other Mailman patches
++---------------- 
++
++Prior to installing this patch you may also need to install the other MM
++patches. This will depend on the version of Mailman and the version of this
++patch you are dealing with. For version 0.3 of this patch for MM 2.1.3 the
++latest version of patch #444879, indexing-2.1.3-x.y.patch , is required. It is
++available from: 
++
++*
++http://sourceforge.net/tracker/index.php?func=detail&aid=444879&group_id=103&
++atid=300103 
++*	http://www.openinfo.co.uk/mailman/patches/444879/index.html 
++
++
++For any other version of this patch details of its prerequisites are in the
++version of INSTALL.htdig-mm file which is installed by that patch. 
++
++Introduction�
++----------------
++
++This integration enables use of the htdig (http://www.htdig.org) search engine
++for searching mail list archives produced by pipermail, Mailman's built-in
++archiver. 
++
++You can use htdig without applying these patches to Mailman but you may find it
++awkward to achieve some of the features offered by this patch. 
++
++The main features of the patch are: 
++
++1.	per list search facility with a search form on each list's TOC page. 
++2.	maintenance of privacy of private archives. The user has to establish their
++credentials via the normal private archive access mechanism before any access
++via htdig is allowed. 
++3.	
++
++a common base URL for both public and private archive access via htsearch
++results. This means that htdig indices are unaffected by changing an archive
++from private to public and vice versa. All access to archives via htdig is
++controlled by wrapped CGI scripts called htdig.py and mmsearch.py. 
++
++Note that Mailman's attachment scrubber creates a problem when it extracts
++attachments from messages as they are being archived because it embeds absolute
++URLs to what it has extracted in the archived messages. This can only be fixed
++by running $prefix/bin/arch to rebuild the list's archive from its mbox file
++after changing its archive from private to public or vices versa. This problem
++is generic and unrelated to the use of this patch. One way resolving it is by
++use the Mailman-MHonArc integration patch #???????? available from 
++*	TBA 
++*	http://www.openinfo.co.uk/mailman/patches/mhonarc/index.html 
++
++
++4.	a choice of running htdig on the machine running Mailman (aka local htdig)
++or running htdig on another machine which has access to Mailman's archives via
++NFS or some similarly competent network file sharing scheme (aka remote htdig). 
++5.	cron activated scripts and crontab entry to run htdig regularly to maintain
++the per list search indices. 
++6.	automatic creation, deletion and maintenance of htdig configuration files
++and such. Beyond installing htdig and telling Mailman where it is via mm_cfg you
++do not have to do much other setup. 
++7.	htdig search related web page elements are retrieved from the
++$prefix/templates/ directory hierarchy so that site, virtual host, list and
++language tailoring of them can be done. 
++
++
++Installing and Building Mailman with this patch�
++----------------
++
++Create your Mailman build directory in the normal way. 
++
++You can apply the patch to either a fresh expansion of the Mailman source
++distribution or the one you used to build a currently working Mailman
++installation. 
++
++Execute the following command in the Mailman build directory: 
++
++
++    patch -p1 < path-to-htdig-2.m.n-x.y.patch
++ 
++
++Follow the configure and make procedures for regular Mailman as given in the
++$build/INSTALL file. 
++
++Then follow the Mailman-htdig configuration instructions given below. 
++
++What is Installed by the Patch�
++----------------
++The patch amends:
++ 
++
++$build/INSTALL 
++
++Adds a reference to this file to the standard installation notes. 
++
++$prefix/bin/check_perms 
++
++To set the permissions for access to $prefix/archive/private/<listname>/htdig/
++subdirectories to 2770. This prevents access by 'other', as a security measure. 
++
++$prefix/Mailman/Archiver/HyperArch.py 
++
++The changes in this file set up the per list htdig stuff such as config files
++and adds the search forms to the list TOC pages. 
++
++$prefix/Mailman/Queue/ArchRunner.py 
++
++The changes in this file rewrite a list's TOC page if, when archiving a new
++message for the list, the update time of the list's TOC page are after the last
++time that rundig was last run. This is is only of relevance when one of the
++remote_nightly_htdig series of cron scripts (see below) is being used. 
++
++The only deficiency with this approach is that if no message is sent to the list
++after rundig is run for the list the TOC page is not rewritten to reflect that
++rundig was run. 
++
++$prefix/Mailman/Cgi/private.py 
++
++There is a security hole in the released Mailman code via which private.py will
++serve files such as a list's archive pipermail.pck and files in the list's
++archive database sub-directory. This hole also allows access to the list's
++archive htdig sub-directory. Fixes for this are applied. As htdig.py (see below)
++is based on private.py the same security fix has been incorporated into it. 
++
++$build/Mailman/Defaults.py.in 
++
++Adds the default configuration variables needed to support the mailman-htdig
++integration 
++
++$build/cron/crontab.in.in 
++
++Adds the nightly_htdig cron script to the default crontab 
++
++$build/configure 
++$build/configure.in 
++$build/Makefile.in 
++$build/cron/Makefile.in 
++$build/src/Makefile.in 
++$build/bin/Makefile.in 
++
++Changes to configuration and Makefiles used for installing Mailman 
++
++
++
++The patch adds:
++ 
++
++$build/INSTALL.htdig-mm and $build/INSTALL.htdig-mm.html 
++
++These contain the material you are reading. 
++
++$prefix/cgi-bin/htdig 
++$prefix/Mailman/Cgi/htdig.py 
++
++these are a CGI script and its wrapper, which is always on the path of URLs
++returned from searches of htdig indices. The script provides secure access to
++such URLs in the same way that the $prefix/cgi-bin/private and
++$prefix/Mailman/Cgi/private.py. Both htdig.py and private.py ensures private
++archives are kept private, applying the same criteria for permitting access.
++Additionally, htdig.py delivers material from public archives without demanding
++any authentication. 
++
++$prefix/cgi-bin/mmsearch 
++$prefix/Mailman/Cgi/mmsearch.py 
++
++these are a CGI script and its wrapper. The script acts as a security wrapper
++for htdig's htsearch CGI script. It will only run htsearch if the user is
++authorized to access a list's archive. it applies the same criteria as
++$prefix/Mailman/Cgi/private.py. In the case of local htdig operation, this
++script runs htsearch as a sub-process and returns its results. In the case of
++remote htdig operation mmsearch runs htsearch on the remote machine via one or
++other of the CGI scripts remote_mmsearch and remote-mmsearch. 
++
++$prefix/Mailman/Cgi/remote_mmsearch 
++$prefix/Mailman/Cgi/remote-mmsearch 
++
++these are companion scripts of mmsearch for use with remote htdig operation.
++They are run by mmsearch via HTTP requests, and in turn run htsearch as a sub
++process, returning the results it delivers. 
++
++$prefix/bin/blow_away_htdig 
++
++this is a utility script for removing per list htdig data, e.g. the config file
++and indices/db files. This is necessary when: 
++a.	ceasing use of the Mailman-htdig integration 
++b.	moving from local to remote htdig or vice-versa 
++c.	upgrading to a version of htdig which has an incompatible index/db file
++format 
++d.	changing the addressing scheme (http versus https) in the web_page_url
++configuration variable of a list 
++e.	reconstructing per-list htdig configuration files after upgrading to
++htdig-2.1.1-0.2.patch or later from an earlier patch version, and prior to
++running nightly_htdig 
++
++
++$prefix/cron/nightly_htdig 
++$prefix/cron/remote_nightly_htdig 
++$prefix/cron/remote_nightly_htdig_noshare 
++$prefix/cron/remote_nightly_htdig.pl 
++
++These scripts all do the same thing; they can be installed as a cron task and
++run regularly to invoke htdig's rundig script to update mailing list search
++indices. Only one of these scripts is used, the choice of which depending on
++your system configuration. 
++
++nightly_htdig is used where Mailman and htdig run on the same system. 
++
++the remote_... scripts are used where Mailman and htdig live on different
++systems. You choose which one suits your needs best: 
++
++remote_nightly_htdig uses the same python files on both systems, that is the
++same .py and .pyc files are accessed, and it hence depends on compatible
++bytecode between the Mailman system and htdig system. It also accesses Mailman
++data files and depends on compatibility of data files contents, for example
++pickled Python values. This should work OK if the same version of python is
++being run on both systems even where the systems are not heterogeneous, for
++example one is Sun/Solaris and the other is PC/Linux. 
++
++remote_nightly_htdig_noshare shares no Python files between the two systems.
++While it is still written in Python it acquires information from the file system
++using directory listings and stat operations. 
++
++remote_nightly_htdig.pl is a rewrite of remote_nightly_htdig_noshare in Perl. It
++is for use where the htdig system does not have Python available on it: in which
++case, shame on you. 
++
++$prefix/templates/en/TOC_htsearch.html 
++$prefix/templates/en/htdig_access_error.html 
++$prefix/templates/en/htdig_auth_failure.html 
++$prefix/templates/en/htdig_conf.txt 
++
++These are English language templates special to the htdig integration: 
++
++TOC_htsearch.html 
++the HTML of the search form that is embedded in a list's archive TOC page. 
++htdig_access_error.html 
++HTML page returned by mmsearch.py in the event of an access error for a page
++access. 
++htdig_auth_failure.html 
++HTML page returned by mmsearch.py in the event of an authentication error for a
++page access. 
++htdig_conf.txt 
++template for the per-list htdig.conf files generated by the patched code. 
++
++
++Configuration of Mailman-htdig Integration�
++----------------
++
++Configuration of the Mailman-htdig integration is carried out on the Mailman
++side. While you must have to hand some information about your htdig
++installation, you should not have to tinker much with htdig for the integration
++to work. 
++
++Most of the configuration of the integration is done by values assigned to
++python variables in either $prefix/Mailman/Defaults.py or
++$prefix/Mailman/mm_cfg.py. 
++
++If you opt to run htdig on a different machine or under a different HTTP server
++to the one running the HTTP server which provides Mailman's Web UI you will also
++have to edit whichever of the patch's three htdig related cron scripts you opt
++to run (remote_nightly_htdig, remote_nightly_htdig_noshare, or
++remote_nightly_htdig.pl) to add a small amount of configuration information. 
++
++Health Warning on the packet!�
++----------------
++
++Be careful when editing configuration information in $prefix/Mailman/mm_cg.py:
++the only Mailman config file you should be editing. Check, double check and then
++recheck before going ahead. If you get either variable names or their values
++wrong a lot of confusion in the operation of both Mailman and htdig can result. 
++
++You (and others supporting you) can spend hours trying to identify problems and
++looking for non-existent bugs as a consequence of such editing errors. Expect to
++find errors in these instructions; compensate for them and tell me when you do
++(r.barrett at openinfo.co.uk). 
++
++Also do read the htdig documentation, release notes etc. This patch integrates a
++working htdig with htsearch available. These notes are about Mailman and
++integrating it with that working htdig. It is up to you to sort out the htdig
++end of things. 
++
++Starting from Scratch (Again)�
++----------------
++
++This is getting ahead of things but some of you may already be asking "What if
++I've already been using an older version of this patch and want to start
++afresh?", or "I want to change from local to remote htdig or vice versa?" 
++
++In these cases your friend will be the $prefix/bin/blow_away_htdig script. It
++removes existing htdig related stuff out of your Mailman installation to the
++extent that it was added by this patch and added to by the normal operation of
++pipermail and nightly_htdig. With that removed and a revised Mailman
++configuration, the patched code will start rebuilding the htdig data. 
++
++But before you get carried away with blow_away_htdig, read the rest of these
++notes. 
++
++General�
++----------------
++
++This patch adds a number of default variables to the file
++$prefix/Mailman/Defaults.py that affect operation of the Mailman-htdig
++integration. These are in addition to the standard Mailman defaults in that
++file. If, in the light of what is said below, you decide any of these are
++incorrect, you can override them in $prefix/Mailman/mm_cfg.py [NOT IN
++Defaults.py! See the comments in Defaults.py for why]. 
++
++By default the Mailman-htdig integration is NOT ENABLED by the installation of
++this patch; the default value of the USE_HTDIG variable in Defaults.py turns off
++the operation of the integration. You have to actively override that default in
++mm_cfg.py to turn on operation of the integration. 
++
++Once a list is created, changing most of these variables will have either no
++effect or a bad effect. You will need to run $prefix/bin/blow_away_htdig script
++and/or $prefix/bin/arch to rebuild the archive pages if you make significant
++changes to the Mailman-htdig integration configuration variables. 
++
++The install process will not overwrite an existing mm_cfg.py file so you can
++freely make changes to this file. If you are re-installing a later version of
++this patch you may have to change what is already configured in the existing
++file and, if necessary, add extra configuration variables to it. 
++
++Most of the Mailman-htdig control variables default to sensible values which you
++will not need to change, especially if you are using local htdig. The semantics
++of most variables apply to both local and remote htdig operation but with some
++the values assigned will depend on whether htdig is viewing things from the same
++or a remote machine. 
++
++The first two variables control what is indexed by htdig. The values assigned
++are both embedded in the HTML generated by pipermail in the list archives and
++added. Changing the values of these variables will mean that all previously
++generated HTML pages in list archives will be out of date and you will probably
++want to rebuild existing archives using $prefix/bin/arch: 
++
++ARCHIVE_INDEXING_ENABLE 
++
++Defines a string telling htdig that it should look at the following material
++when building it indices. 
++
++
++    Default: ARCHIVE_INDEXING_ENABLE = '<!--/htdig_noindex-->'
++ 
++ARCHIVE_INDEXING_DISABLE 
++
++Defines a string telling htdig that it not should not look at the following
++material when building it indices. 
++
++
++    Default: ARCHIVE_INDEXING_DISABLE = '<!--htdig_noindex-->'
++ 
++USE_HTDIG 
++
++Semantics: 0 - don't use integrated htdig, 1 - use it 
++
++Turns Mailman-htdig integration on or off. 
++
++
++    Defaults: USE_HTDIG = 0
++
++
++Notes: 
++1.	when USE_HTDIG is turned on the patched code in Mailman will start adding
++htdig stuff for any archiving-enabled mail lists as new posts for eachlist are
++handled by Mailman. Until a new post is made after enabling with USE_HTDIG an
++existing mail list's archive will not be htdig searchable. When the new post is
++handled: 
++a.	the list's personalised htdig config file is created 
++b.	necessary links to the htdig config file are created 
++c.	a search form is added to the TOC page for the list 
++
++
++Even with this done, htdig searches only become available when htdig indices are
++constructed. This is done when one or other of the patch's htdig related cron
++scripts are run (nightly_htdig, remote_nightly_htdig,
++remote_nightly_htdig_noshare, or remote_nightly_htdig.pl, depending on how you
++configure your system). These can be run from the command line ahead of their
++scheduled cron time to get htdig searches operational. 
++
++2.	Turning USE_HTDIG off will not remove htdig indices or search forms from
++existing archive-enabled lists. It will however stop htdig features from being
++added to newly created lists. If you want to eliminate htdig from your existing
++lists then use the $prefix/bin/blow_away_htdig script. 
++
++
++
++HTDIG_FILES_URL 
++
++This is the URL of the directory containing various HTML and Graphics files
++installed by htdig; files such as buttonr.gif, buttonl.gif and button1-10.gif.
++The URL must end with a '/'. 
++
++
++    Default: HTDIG_FILES_URL = '/htdig/'
++ 
++
++The default assumes the HTTP servers providing access to htdig and to Mailman's
++web UI are on the same machine and a symbolic link called 'htdig' has been put
++into your HTTP server's top level HTML directory which points to the directory
++your htdig install has put the actual files into; this link is often to
++/usr/share/htdig. This value will depend on your htdig installation decisions
++and HTTP server's configuration files (typically /etc/httpd/httpd.conf on a late
++model Apache installation) i.e the Alias through which the link to the htdig
++files are reached. 
++
++HTDIG_CONF_LINK_DIR 
++
++This is the name of a directory in which links to list specific htdig config
++files are placed. 
++
++
++    Default: HTDIG_CONF_LINK_DIR = os.path.join(VAR_PREFIX, 'archives', 'htdig')
++ 
++
++The VAR_PREFIX of the default is resolved to an actual file system path when
++when Mailman's 'make install' is run. The 'os.path.join' creates a full file
++system path by gluing together the three pieces when Mailman is run. This
++definition puts the directory alongside the default PUBLIC_ARCHIVE_FILE_DIR and
++PRIVATE_ARCHIVE_FILE_DIR. Unless you are changing the value of these variables
++you probably do not want to change HTDIG_CONF_LINK_DIR. 
++
++HTDIG_RUNDIG_PATH 
++
++This is the path in your file system to the rundig shell script that is
++installed as part of htdig. This tells one or other of the patch's htdig related
++cron scripts (nightly_htdig and remote_nightly_htdig) where to find rundig in
++order that they can execute it. 
++
++
++    Default: HTDIG_RUNDIG_PATH = '/usr/bin/rundig'
++ 
++HTDIG_HTSEARCH_PATH 
++
++This is the file path to the htsearch program in the htdig package. 
++
++
++    Default: HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'
++ 
++
++This value will depend on your htdig installation decisions. This path is used
++by either the mmsearch CGI script (for local htdig) or the
++remote_mmsearch/remote-mmsearch CGI script (for remote htdig) to execute
++htsearch as a sub-process. 
++
++HTDIG_EXCLUDED_URLS 
++
++See htdig's configuration file documentation. The value of this MM variable is
++inserted into per-list htdig.conf files when they are created as the value of an
++htdig excluded_urls directive. But if an exclusion in this value would prevent
++indexing of URLs for accessing the htdig.py cgi wrapper then that exclusion is
++omitted from that per-list htdig.conf file. 
++
++
++    Default: HTDIG_EXCLUDED_URLS = '/cgi-bin/ .cgi'
++
++
++Note: these are the same as the htdig 3.1.6 default values. 
++
++REMOTE_HTDIG 
++
++Semantics: 0 - htdig runs on local machine, 1 -on remote machine 
++
++Says whether htdig going to be run on the same machine as Mailman or on another
++machine. 
++
++
++    Default: REMOTE_HTDIG = 0
++ 
++REMOTE_PRIVATE_ARCHIVE_FILE_DIR 
++
++Only relevant if REMOTE_HTDIG = 1. It is the file system path to the directory
++in which Mailman stores private archives, as seen by the machine running htdig. 
++
++
++    Default: REMOTE_PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 
++                                              'archives', 'private')
++ 
++
++The VAR_PREFIX of the default is resolved to an actual file system path when
++when Mailman's 'make install' is run. The 'os.path.join' creates a full file
++system path by gluing together the three pieces when Mailman is run. If you
++assign a value to this in mm_cfg.py, just put the relevant explicit file system
++path in. 
++
++REMOTE_MMSEARCH_URL 
++
++Only relevant if REMOTE_HTDIG = 1. It is the URL on the htdig machine through
++which whichever of the the remote_mmsearch/remote-mmsearch CGI scripts you have
++opted to use can be reached via an HTTP request. 
++
++
++    Default: REMOTE_MMSEARCH_URL = '/cgi-bin/remote-mmsearch'
++ 
++HTDIG_STRICT_FILE_PERM 
++
++Semantics: 0 - 'other' access allowed, 1 - 'other' access denied 
++
++Says whether 'other' has access permissions for per-list
++$prefix/private/archives/<listname>/htdig/ directories. For local htdig
++operation such access is not required and is a security hole if allowd. Such
++access may be needed if remote htdig is used; see notes on "Apache".
++$prefix/bin/check_perms should be run after changing the value of this variable
++in mm_cfg.py to update access permissions of existing directories. 
++
++
++    Defaults: HTDIG_STRICT_FILE_PERM = 1
++
++
++HTDIG_EXTRAS 
++
++You can assign a string value to this config variable and that string will be
++included in all of your site's list specific htdig configuration files when they
++are created. The value of the string can be any attribute declarations as
++defined at http://www.htdig.org/confindex.html. 
++
++Be cautious in what you do with this. Most sites will not need to use this at
++all. But if you have some idiosyncratic htdig installation it might help
++overcome problems in integrating with Mailman. If you think you need to use it I
++suggest: 
++a.	You try creating a test list without assigning a value to HTDIG_EXTRAS in
++$prefix/Mailman/mm_cfg.py 
++b.	Enable archiving for that test list. 
++c.	Send a message to the test list so that its archive is created together with
++its htdig configuration file. 
++d.	Review the content of the list's htdig conf file in
++$prefix/archives/private/<listname>/htdig/<listname>.conf. 
++e.	You will see where the default value of HTDIG_EXTRAS from
++$prefix/Mailman/Defaults.py has been inserted. This value is onlyan htdig
++comment and does nothing. 
++f.	Consider whether what you will assign to HTDIG_EXTRAS in
++$prefix/Mailman/mm_cfg.py will make sense in the context of the rest of the
++htdig conf file's contents. 
++
++
++
++
++Permissions Considerations�
++----------------
++
++htdig�
++----------------
++
++Python scripts added by this patch (nightly_htdig and its relatives) run the
++htdig rundig script identified by HTDIG_RUNDIG_PATH to build search indices for
++Mailman archives. Code added by this patch generates per-list htdig
++configuration files which are passed as a parameter to the rundig script. These
++configuration files identify a list specific directory
++($prefix/archives/private/lt;listname>/htdig) in which list specific data files
++generated by and used by htdig are to be placed. 
++
++However, the rundig script identified by HTDIG_RUNDIG_PATH may attempt to
++generate some files in htdig's COMMON_DIR when it is first run by nightly_htdig;
++the files concerned are likely to be root2word.db, word2root.db, synonyms.db and
++possibly some others generated by htidg's htfuzzy program. The standard rundig
++script generates these files selectively if they do not already exist. Depending
++on how you have installed htdig and how the rundig script is first run, there
++may be a permissions problem when nightly_hdig executes rundig under the mailman
++UID if it tries to generate these files. 
++
++You may need to either give the mailman UID write permission over htdig's
++COMMON_DIR or, before the nightly_htdig script is first run, run htdig's htfuzzy
++executable with a sufficiently privileged UID in the manner that the rundig
++script would run htfuzzy, to create any necessary files in COMMON_DIR. 
++
++See htdig's documentation for further information on this topic. 
++
++Apache�
++----------------
++
++When remote_mmsearch or remote-mmsearch scripts are used as part of a remote
++htdig strategy you may encounter a file permissions problem. This is because
++these scripts, which in turn execute htsearch as a sub-process, will be run with
++UID and GID of the remote Apache server. 
++
++By default, the permissions of the per-list
++$prefix/private/archives/<listname>/htdig/ directories only allow access for the
++mailman UID and GID and hence the remotely executed htsearch will be unable to
++access them. 
++
++If this problem is encounterd, then you will have to use the
++HTDIG_STRICT_FILE_PERM configuration variable to say "open up the permissions"
++before running $prefix/bin/check_perms. You can then use a RewriteRule or
++similar in the Apache server's httpd.conf file to restrict access to
++$prefix/private/archives/<listname>/htdig/ directories via the web server. 
++
++Local htdig Configuration�
++----------------
++
++This configuration is for when you are running Mailman, htdig, the HTTP server
++used to provide Mailman's web UI and htdig's htsearch CGI script, on the same
++machine. 
++
++You will need to: 
++
++a.	If different to the default value, add the definition of HTDIG_RUNDIG_PATH
++to file $prefix/Mailman/mm_cfg.py. 
++b.	If different to the default value, add the definition of HTDIG_HTSEARCH_PATH
++to file $prefix/Mailman/mm_cfg.py. 
++c.	Add the definition of USE_HTDIG with the value 1 to
++$prefix/Mailman/mm_cfg.py. 
++
++
++
++        USE_HTDIG = 1
++ 
++
++If necessary you can override the values of any of the other configuration
++variables in file $prefix/Mailman/mm_cfg.py. 
++
++In particular you might need to change the HTDIG_FILES_URL variable from its
++default. This URL can be just the path i.e. absolute URL on the same server as
++that which serves Mailman's Web UI, or a full URL identifying the scheme (http),
++server, server port and path, for example
++http://mailer.yourdomain.tld:8080/htdig/ 
++
++Remote htdig Configuration�
++----------------
++
++This configuration is for when you are running htdig and an HTTP server
++providing access to htsearch via remote_mmsearch or remote-mmsearch on a
++different machine to that is running Mailman. 
++
++For this configuration to work, htdig's programs, both those run from command
++lines such as rundig and those run via CGI such as htsearch, must be able to see
++Mailman archives through NFS. In the examples below we'll assume that
++/mnt/mailman-archives on the htdig machine maps to $prefix/mailman/archives on
++the Mailman machine. 
++
++You should also arrange for he mailman UID and its GID to be common to both
++machines. Remember that when rundig is called on the htdig machine to produce
++search indices for each list it will be trying to write those files via NFS in
++Mailman's archive area and will thus need to run with an appropriate identity
++and permissions. 
++
++The differences between the local and remote configuration are: 
++
++1.	configuration values telling htdig where to find files are as viewed from
++the remote machine. 
++2.	configuration values giving URLs that refer to htdiggy things have to be as
++viewed from the Mailman machine. 
++
++
++You will need to: 
++
++1.	Add the definition of HTDIG_HTSEARCH_PATH to file $prefix/Mailman/mm_cfg.py.
++This is path to htdig's htsearch on the remote machine running htdig. For
++example: 
++
++
++    HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'
++ 
++2.	Add the definition of HTDIG_RUNDIG_PATH to file $prefix/Mailman/mm_cfg.py.
++This is path to rundig on the remote machine running htdig. For example: 
++
++
++    HTDIG_RUNDIG_PATH = '/usr/bin/rundig'
++ 
++3.	Add the definition of REMOTE_MMSEARCH_URL to file $prefix/Mailman/mm_cfg.py.
++This must be a full URL referring to one of Mailman's
++remote_mmsearch/remote-mmsearch CGI scripts on the remote htdig machine, as seen
++from the Mailman local machine. For example: 
++
++
++    REMOTE_MMSEARCH_URL = 'http://htdiggy.your.com/cgi-bin/remote-mmsearch'
++ 
++4.	Add the definition of HTDIG_FILES_URL to file $prefix/Mailman/mm_cfg.py.
++This must be a full URL referring to the directory containing htdig files on the
++remote htdig machine as seen from the Mailman local machine. This URL must end
++with a '/'. For example:
++
++
++    HTDIG_FILES_URL = 'http://htdiggy.your.com/htdig/'
++ 
++5.	Add the definition of REMOTE_PRIVATE_ARCHIVE_FILE_DIR to
++$prefix/Mailman/mm_cfg.py. This must be the absolute file system path to the
++directory in which Mailman stores private archives as seen by the machine
++running htdig. For example: 
++
++
++    REMOTE_PRIVATE_ARCHIVE_FILE_DIR = '/mnt/mailman-archives/private'
++ 
++6.	Add the definition of USE_HTDIG with the value 1 to
++$prefix/Mailman/mm_cfg.py. 
++
++
++    USE_HTDIG = 1
++ 
++7.	Add the definition of REMOTE_HTDIG with the value 1 to
++$prefix/Mailman/mm_cfg.py. 
++
++
++    REMOTE_HTDIG = 1
++ 
++8.	If necessary add the definition of HTDIG_STRICT_FILE_PERM with the value 0
++to $prefix/Mailman/mm_cfg.py. This may be needed it the UID/GID that Apache on
++the htdig server will run the remote mmsearch as is not mailman or in the
++mailman group. This change will open up a security hole which you may want to
++consider plugging; see under the heading "Apache permissions" for more details.
++
++
++    HTDIG_STRICT_FILE_PERM = 0
++ 
++
++
++You have to choose one of the two remote mmsearch scripts found in
++$prefix/Mailman/Cgi - remote-mmsearch (a Perl script) and remote_mmsearch (a
++Python script) - to use and transfer it to the htdig machine. You need to add
++this script to the directory in which the web server on the htdig machines
++expects to find CGI scripts. Having transferred the script to you htdig machine
++you will need to use a text editor to set the values of four configuration
++variables below the heading "Edit the following configuration variables to suit
++your installation", namely: 
++
++
++MAILTO 
++this is the default mail address for your installation. 
++VALID_IP_LIST 
++this is a list of IP numbers from which the script should accept an HTTP
++request. Normally this should be set to the IP number of your machine running
++Mailman. If the list is empty the script will accept HTTP requests from any
++machine and be vulnerable to the exploit described under the heading "Private
++archive security problem prior to htdig-2.1.1-0.2.patch version" above. 
++HTDIG_CONF_LINK_DIR 
++this is the file path to the directory in which links to list specific htdig
++config files are placed, as viewed from the remote machine running htdig. 
++HTDIG_HTSEARCH_PATH 
++this is the file path to the htsearch program in the htdig package as viewed
++from the remote machine running htdig. 
++
++
++See "What is Installed by the Patch" for an explanation of the differences
++between these remote mmsearch scripts which both do the same job: being a
++security wrapper around htdig's htsearch program to restrict searching of a
++list's archive indexes to users authorised to see the contents of that archive. 
++
++Note: You may need to change the '#!' on the first line of whichever of the
++remote-mmsearch (Perl) and remote_mmsearch (Python) scripts you opt for so that
++the correct interpreter is used for running the script on the remote htdig
++machine. You may also need to verify the supporting packages/modules used by the
++selected script are installed on that system. 
++
++
++You have to choose one of the three remote_nightly_htdig scripts found in
++$prefix/cron - remote_nightly_htdig, remote_nightly_htdig_noshare and
++remote_nightly_htdig.pl - and transfer it to the htdig machine. See above under
++heading "What is Installed by the Patch" for an explanation of the differences
++between these scripts, which all do the same basic job. You should add the
++script to the crontab for the mailman UID on the htdig machine. But first you
++need to edit the selected script to add some configuration information. What has
++to be added depends on which script you opt to use. In each case the variables
++concerned are declared near the top of the script and you just have to enter the
++appropriate values: 
++
++
++remote_nightly_htdig 
++
++you only need to set the value of the python variable MAILMAN_PATH to be the
++directory $prefix as seen from the htdig machine. The whole Mailman installation
++must be accessible via NFS in order to use this script. 
++
++remote_nightly_htdig_noshare 
++
++you need to copy the values for the following configuration variables from
++either $prefix/Mailman/mm_cfg.py or $prefix/Mailman/Defaults.py to the script:
++REMOTE_PRIVATE_ARCHIVE_FILE_DIR, HTDIG_RUNDIG_PATH. The variables declared in
++remote_nightly_htdig_noshare use the same names. This script only requires that
++the archives directory of the Mailman installation be accessible via NFS. 
++
++remote_nightly_htdig.pl 
++
++you need to copy the values for the following configuration variables from
++either $prefix/Mailman/mm_cfg.py or $prefix/Mailman/Defaults.py to the script:
++REMOTE_PRIVATE_ARCHIVE_FILE_DIR, HTDIG_RUNDIG_PATH. Being a Perl script, the
++variables in remote_nightly_htdig.pl use the same names but prefixed with the
++'$' character. This script only requires that the archives directory of the
++Mailman installation be accessible via NFS. 
++
++
++
++Note: You may need to change the '#!' on the first line of whichever of these
++scripts you opt for so that the correct interpreter is used for running the
++script on the remote htdig machine. You may also need to verify the supporting
++packages/modules used by the selected script are installed on that system. 
++
++As with the nightly_htdig script when running with local htdig, these scripts
++can be run from the command line using the mailman UID in order to get htdig to
++construct an initial set of indices. 
++
++
++Upgrading an Existing Standard Mailman Installation�
++----------------
++
++1.	You will want to suspend operation of Mailman while doing the upgrade.
++Consider doing a shutdown of the MTA delivering mail to Mailman and removing
++Mailman's crontab. 
++2.	Configure and install as described above. 
++3.	Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++4.	If your installation already has archives: 
++a.	Send a message to each of your archive-enabled lists. This will stimulate
++the setup of the new per list htdig config files in the Mailman archives. 
++b.	Consider rebuilding your existing archives with $prefix/bin/arch. This will
++embed the ARCHIVE_INDEXING_ENABLE and ARCHIVE_INDEXING_DISABLE in the
++regenerated archive pages and, after nightly_htdig has been run, give improved
++search results. 
++c.	Run the nightly_htdig script from the command line to generate an initial
++set of per-list htdig search indices. 
++
++
++Changing from local to remote htdig or vice versa�
++----------------
++
++1.	You will want to suspend operation of Mailman while making this change.
++Consider doing a shutdown of the MTA delivering mail to Mailman and removing
++Mailman's crontab. 
++2.	Run the $prefix/bin/blow_away_htdig script to remove all existing per list
++htdig config files and htdig indices/db files. 
++3.	Configure per the instructions above for the local or remote target. 
++4.	Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++5.	Send a message to each of your archive-enabled lists. This will stimulate
++the set up of the new per list htdig config files in Mailman archives. 
++6.	Run the nightly_htdig script from the command line to generate a new set of
++per list htdig search indices. 
++
++
++Coping with htdig Upgrades�
++----------------
++
++If you change the version of htdig you run, you may find that the indices built
++with the earlier version are not compatible with the newer version of htdig's
++programs. In that case do the following: 
++
++1.	You will want to suspend operation of Mailman while making this change.
++Consider doing a shutdown of the MTA delivering mail to Mailman and removing
++Mailman's crontab. 
++2.	Run the $prefix/bin/blow_away_htdig script with the -i flag to remove all
++existing per list htdig indices/db files. 
++3.	Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++4.	Run the nightly_htdig script from the command line to generate new sets of
++per-list htdig search indices. 
++
++
++Changing the Addressing Scheme of your web_page_url�
++----------------
++
++If you change the addressing scheme of the web_page_url for a list to or from
++http then you will need to rebuild the list's htdig configuration file(s) and
++the related htdig indices. Do the following: 
++
++1.	You may want to suspend operation of Mailman while making this change.
++Consider doing a shutdown of the MTA delivering mail to Mailman and removing
++Mailman's crontab. 
++2.	Run the $prefix/bin/blow_away_htdig script to remove all existing per list
++htdig material for the list(s) concerned. 
++3.	Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++4.	Send a message to each affected list to provoke reconstruction of the list's
++htdig config file(s). 
++5.	Run the nightly_htdig script from the command line to generate new sets of
++per list htdig search indices. 
++
++
++Operational Information�
++----------------
++
++If you have just turned USE_HTDIG on or just used $prefix/bin/blow_away_htdig
++(without the -i flag) there will be no per-list htdig information saved in the
++archives. 
++
++When the first post to each archive-enabled list is archived by pipermail, the
++per-list htdig config file will be constructed and some directories and links
++added to your Mailman archive directories. The htdig search form will be added
++to list's TOC page. 
++
++However, until one of the nightly_htdig scripts is run no htdig indices will be
++constructed. You can either wait for the script to run as a cron job or run it
++(while using the mailman UID) from the command line. 
++
++Notes and Warnings�
++----------------
++
++Archive security problems resolved by htdig-2.1.3-0.2 patch
++ 
++
++This patch is hopefully the final step in closing security holes in archive
++access. 
++
++In version htdig-2.1.3-0.1.patch, htdig.py was rebased on the standard MM
++release's private.py which had moved on since the snapshot of it used as the
++basis for htdig.py was originally taken. Among other things, htdig.py had been
++modified to prevent access to some files in list archive directories such as a
++list's archive pipermail.pck and files in the list's archive database
++sub-directory. 
++
++This rebasing action re-introduced to htdig.py the security holes, still extant
++in private.py despite it being later code, via which private.py would serve
++files such as a list's archive pipermail.pck and files in the list's archive
++database sub-directory. 
++
++The permissions on these files and directories mean that they are inaccessible
++via the web server using /pipermail/ URIs if a list's archive is public. 
++
++Additionally, check_perms is now modified so that the list archive htdig
++subdirectory permissions are set to 2770 by default. Prior to
++htdig-2.1.1-0.2.patch, this could not be done as the htsearch script, being run
++with uid and gid of the Apache server, could then not gain access to files in
++the htdig subdirectories. But, since the introduction of the mmsearch script,
++which runs with the mailman gid and spawns htsearch, it can. This prevents
++accees to the list archive htdig subdirectories via /pipemail/ URI's. Up until
++htdig-2.1.3-0.2.patch this could only be achieved by using a RewriteRule or
++similar in the Apache server's httpd.conf file. 
++The only residual problem is that the revised permissions on the archive htdig
++subdirectories may cause problems if the remote_mmsearch and remote-mmsearch are
++used. This is because they will be run with uid and gid of the Apache server. If
++this problem is encounterd, then you will have to manually add read and execute
++permissions for 'other' to the archive htdig subdirectories and read permission
++their contents, and then use RewriteRule or similar in the Apache server's
++httpd.conf file for protection. 
++
++The solution to this problem has been superceded in htdig-2.1.3-0.3.patch as
++follows: Introduced the HTDIG_STRICT_FILE_PERM Mailman config variable as part
++of dealing with htsearch access to per-list htdig directories permissions issue
++when operating with remote htdig. See under the "Apache" heading above. 
++
++Private archive security problem prior to htdig-2.1.1-0.2.patch version�
++----------------
++
++Versions of the Mailman-htdig integration patch installed by versions of this
++patch prior to htdig-2.1.1-0.2.patch allow a security exploit which can expose
++information, held in the per-list search indexes of private list archives, to
++unauthorised users. 
++
++Via the exploit an unauthoized user can submit a search query to htdig's
++htsearch CGI program without their having been authenticated as a user allowed
++to access the list archive concerned. The results, returned in good faith by
++htsearch, will expose some information that the user is not entitled to see. 
++
++However, the security breakdown is not complete. Attempts to follow links
++returned by htsearch, which go via the htdig CGI script installed by this patch,
++will be blocked if the user is not authorized to access the list archive. 
++
++Maintaining archive security with htdig-2.1.1-0.2.patch version and later�
++----------------
++
++With htdig-2.1.1-0.2.patch and later versions of the patch: 
++
++1.	htsearch is no longer used directly via CGI for searching list archives. 
++2.	The symbolic link named by the HTDIG_MAILMAN_LINK configuration variable is
++no longer used. Indeed, when upgrading earlier installations this symlink should
++be deleted and the configuration variable deleted. Without this symlink, on a
++normally configured system, htsearch no longer has the unaided ability to access
++the per-list htdig configuration and other list archive associated files. 
++3.	Thus, even if htsearch can be reached via CGI, it cannot undertake a search
++of list archives when requested to do so by an HTTP request which seeks to
++circumvent list archive security. 
++4.	A new script, $prefix/Mailman/Cgi/mmsearch.py, is now used to search list
++archives. This script applies the same user authentication as private.py and
++htdig.py. Only if a user is authorised to access a list, does mmsearch use
++htdig's htsearch to search a list's archive. In this case, mmsearch provides
++htsearch with the information it needs to access the per-list htdig
++configuration and other list archive associated files. 
++5.	Where htidg and Mailman are run on the same machine, mmsearch acts as a
++security wrapper, runs htsearch as a sub-process and list security is preserved
++by this means. 
++6.	Where htdig is run on a different machine to Mailman, mmsearch can perform
++user authentication but has problems in acting as a security wrapper for
++htsearch. The solution adopted is for one of two companion CGI scripts
++(remote-mmsearch written in Perl or remote_mmsearch written in Python) to be
++invoked on the remote htdig machine by an HTTP request made by mmsearch on the
++Mailman machine. These scripts run htsearch, providing it with the information
++it needs to access the per-list htdig configuration and other list archive
++associated files. But, such an HTTP request can be made by other means and thus
++the the same security exploit we are trying to avoid still exists. The only
++protection in the case of remote htdig operation is that the
++remote-mmsearch/remote_mmsearch scripts can be configured to operate only on
++HTTP requests originating from specified IP numbers. By restricting operation to
++requests originating on the Mailman server some semblance of list privacy can be
++preserved. 
++
++
++Upgrading to htdig-2.1.1-0.2.patch or later from an earlier patch version�
++----------------
++
++If you are upgrading a Mailman installation that has an earlier version of the
++the Mailman-htdig integration patch than that installed by htdig-2.1.1-0.2.patch
++or later, you need to make some changes to that installation: 
++
++1.	You must delete from your file system the symbolic link named by the
++HTDIG_MAILMAN_LINK Mailman configuration variable. This link previously gave
++htdig programs access to per list htdig configuration files. This is now done by
++other means and the symlink allows a security exploit that prejudices the
++privacy of list archives. 
++2.	You must delete the HTDIG_MAILMAN_LINK Mailman configuration variable from
++the $prefix/Mailman/mm-cfg.py file. 
++
++
++These changes are in addition to the normal installation instructions given
++below. Having configured and installed the newly patched version of Mailman you
++must: 
++
++1.	Run the script $prefix/bin/blow_away_htdig with the -c option to rebuild
++per-list htdig conf files and delete existing per-list search indexes. 
++2.	Run the $prefix/cron/nightly_htdig script from the command line to rebuild
++per-list search indexes using the revised per-list htdig conf files just created
++by blow_away_htdig. 
++
++
++Redhat 7.1 and 7.2 installations�
++----------------
++
++If you install htdig from the htdig-3.2.0 binary rpm of RH7.1/2 Binary CD 1 of 2
++you also have to install the htdig-web-3.2.0 binary rpm. This may be from RH
++7.1/2 Binary CD 2 of 2 or CD 1 of 2 depending on whether you are using actual
++CDs or downloaded CD images. 
++
++Apache/htdig issues�
++----------------
++
++htdig's graphics file must be accessible via you web server and the Mailman
++configuration variable HTDIG_FILES_URL setup accordingly. Depending on how you
++install htdig and Apache you may need to add Alias and/or ScriptAlias directives
++to you Apache configuration file to make the htdig components accessible. Check
++the Apache and htdig documentation. 
++
++Contributors�
++----------------
++
++Original author and maintainer: 
++Richard Barrett - <r.barrett at openinfo.co.uk> 
++Past bug fixes: 
++Nigel Metheringham <nigel.metheringham at vdata.co.uk> 
++Stephan Berndts <stb-mm at spline.de>
++Testers: 
++*	Mark T. Valites <valites at geneseo.edu> 
++*	Rehan van der Merwe <rehan at nha.co.za> 
++
++
++
++
++History�
++----------------
++
++Compatibility�
++----------------
++Version of patch 	Version of Mailman 
++htdig-2.1.5-0.1.patch 	Mailman 2.1.5 
++htdig-2.1.4-0.1.patch 	Mailman 2.1.4 
++htdig-2.1.3-0.5.patch 	Mailman 2.1.3 
++htdig-2.1.3-0.4.patch 	Mailman 2.1.3 
++htdig-2.1.3-0.3.patch 	Mailman 2.1.3 
++htdig-2.1.3-0.2.patch 	Mailman 2.1.3 
++htdig-2.1.3-0.1.patch 	Mailman 2.1.3 
++htdig-2.1.2-0.4.patch 	Mailman 2.1.2 
++htdig-2.1.2-0.3.patch 	Mailman 2.1.2 
++htdig-2.1.2-0.2.patch 	Mailman 2.1.2 
++htdig-2.1.2-0.1.patch 	Mailman 2.1.2 
++htdig-2.1.1-0.5.patch 	Mailman 2.1.1 
++htdig-2.1.1-0.4.patch 	Mailman 2.1.1 
++htdig-2.1.1-0.3.patch 	Mailman 2.1.1 
++htdig-2.1.1-0.2.patch 	Mailman 2.1.1 
++htdig-2.1.1-0.1.patch 	Mailman 2.1.1 
++htdig-2.1-0.3.patch 	Mailman 2.1 
++htdig-2.1-0.2.patch 	Mailman 2.1 
++htdig-2.1-0.1.patch 	Mailman 2.1 
++htdig-2.1b6-0.1.patch 	Mailman 2.1b6 
++htdig-2.1b5-0.1.patch 	Mailman 2.1b5 
++htdig-2.1b4-0.1.patch 	Mailman 2.1b4 
++htdig-2.1b3-0.3.patch 	Mailman 2.1b3 
++htdig-2.1b3-0.2.patch 	Mailman 2.1b3 
++htdig-2.1b3-0.1.patch 	Mailman 2.1b3 
++htdig-2.1b2-0.1.patch 	Mailman 2.1b2 
++htdig-2.0.13-0.2.patch 	Mailman 2.0.13 
++htdig-2.0.13-0.1.patch 	Mailman 2.0.13 
++htdig-2.0.12-0.1.patch 	Mailman 2.0.12 
++htdig-2.0.11-0.1.patch 	Mailman 2.0.11 
++htdig-2.0.10-0.2.patch 	Mailman 2.0.10 
++htdig-2.0.10-0.1.patch 	Mailman 2.0.10 
++htdig-2.0.9-0.1.patch 	Mailman 2.0.9 
++htdig-2.0.8-0.1.patch 	Mailman 2.0.8, 2.0.7, 2.0.6 and probably 2.0.3, 2.0.4
++and 2.0.5 
++
++Changes�
++----------------
++
++htdig-2.1.5-0.1.patch:
++1.  Updated patch for MM 2.1.5 compatibility.
++    
++    Note: the templates in $build/templates/<lang>/for the following 
++    languages are NOT modified by this patch or by its precursor indexing 
++    patch: ca, eu, sr, sv
++    
++    The following files in a language's default template directory should be 
++    modified per the changes made to the en language templates after 
++    installation of this patch if that other language is used ;'
++                    
++        templates/<lang>/archidxfoot.html
++        templates/<lang>/archidxhead.html
++        templates/<lang>/archtoc.html
++        templates/<lang>/archtocentry.html
++        templates/<lang>/archtocnombox.html
++        templates/<lang>/article.html
++
++htdig-2.1.4-0.1.patch:
++1.  Updated patch for MM 2.1.4 compatibility.
++2.  Removed untranslated versions of htdig.html from per-language directories
++    under $build/templates, with the exception of the default templates/en/ 
++    directory, that were present in previous versions of this patch.
++
++htdig-2.1.3-0.5.patch:
++1.  Modified htdig.py and private.py; the security changes introduced by
++    htdig-2.1.3-0.2 patch to these scripts incorrectly  blocked access to the
++    <listname>.mbox/<listname>.mbox file. The O.5 revison of the patch corrects
++    this error. This problem and a suggested fix were pointed out to me in a
++    private email by Stephan Berndts <stb-mm at spline.de> 
++
++htdig-2.1.3-0.4.patch:
++1.  Modified htdig.py and introduced htdig.html templates. The changes mean that 
++    if the user is challenged for authentication, when the credentials are 
++    submitted and accepted, the URL requested which led to the challenge is then 
++    presented.
++
++htdig-2.1.3-0.3.patch: 
++1.	Patch documentation layout revised and simplified. 
++2.	Changes to $prefix/bin/check_perms and $prefix/Mailman/Archiver/HyperArch.py
++to improve handling of htdig subdirectory permissions if remote htdig is used.
++End result is the same as with prior patch version in the case of local htdig. 
++3.	Introduced the HTDIG_STRICT_FILE_PERM Mailman config variable as part of
++dealing with htsearch access to per-list htdig directories permissions issue
++when operating with remote htdig. See under the "Apache" heading above. 
++
++
++htdig-2.1.3-0.2.patch: 
++1.	This patch is hopefully the final step in closing security holes in archive
++access. See the discussion below under the heading "Archive security problems
++resolved by htdig-2.1.3-0.2 patch". 
++
++
++htdig-2.1.3-0.1.patch: 
++1.	updated patch for MM 2.1.3 compatibility. 
++
++
++htdig-2.1.2-0.4.patch: 
++1.	corrected error in mmsearch.py and remote_mmsearch. This caused a problem if
++https was being used for accessing the archives as a pattern match to extract
++the list name was misused. 
++
++
++htdig-2.1.2-0.3.patch: 
++1.	updates HyperArch.py so htdig related code uses quick_maketext() function
++instead of the Utils.Maketext() function. 
++
++
++htdig-2.1.2-0.2.patch: 
++1.	corrects stupid error inserted in unpublished htdig-2.1.1-0.5.patch and
++carried forward into htdig-2.1.2-0.1.patch 
++
++
++htdig-2.1.2-0.1.patch: 
++1.	updated patch for MM 2.1.2 compatibility 
++
++
++htdig-2.1.1-0.5.patch: 
++1.	with previous version the protototype htdig_conf.txt contained an htdig
++exclude_urls directive for /cgi-bin/ and .cgi. If MM is configured so that the
++URL for accessing the htdig.py cgi wrapper matches these excluded URLS (for
++instance by running ./configure with --with-cgi-ext=".cgi") then nothing gets
++indexed by rundig. The revised patch: 
++a.	makes the excluded URL configurable through a MM config variable
++HTDIG_EXCLUDED_URLS which defaults to the old hard-wired value. 
++b.	when generating a list-specific htdig.conf file a check is made against
++HTDIG_EXCLUDED_URLS and if anything in it would prevent indexing of the URL for
++accessing the htdig.py cgi wrapper for that list, it is omitted from the
++exclude_urls directive in that htdig.conf file. 
++
++
++htdig-2.1.1-0.4.patch: 
++1.	mmsearch.py and its remote kin remote-mmsearch and mm_search were overly
++restrictive on the form fields they were willing to accept. Extended the list so
++that multi-page search results worked. 
++
++
++htdig-2.1.1-0.3.patch: 
++1.	corrects silly error in raising an excpetion in mmsearch.py. This will only
++show if there is a problem with mmsearch running the htsearch program. 
++
++
++htdig-2.1.1-0.2.patch: 
++1.	This version corrects a security exploit which allowed a URL to obtain an
++htsearch results page without the user being authorised to access the list. Any
++attempt to follows links on the results page were blocked correctly by
++$prefix/Mailman/htdig.py but there was leakage of private information from the
++list's search indexes on the page returned by htdig's htsearch CGI program. The
++exploit is removed by this patch's revisions. The following sections describe
++the problem, the solution and special actions required when updating a Mailman
++installation using an earlier version of this patch: 
++a.	Private archive security problem prior to htdig-2.1.1-0.2.patch version. 
++b.	Maintaining private archive security with htdig-2.1.1-0.2.patch version and
++later. 
++c.	Upgrading to htdig-2.1.1-0.2.patch or later from an earlier patch version. 
++
++Note that there is no patch revision to deal with this security problem for MM
++2.0.13 or earlier and you should seriously consider updating to MM 2.1.x if you
++want to implement this security fix. 
++
++
++htdig-2.1.1-0.1.patch: 
++1.	No functional change. Applies without offset warnings to MM 2.1.1 
++
++
++htdig-2.1-0.3.patch: 
++1.	corrects errors in the way $prefix/Mailman/htdig.py worked out content type
++of file being returned. 
++2.	$prefix/Mailman/htdig.py adopts revised method for establishing the default
++URL introduced in 2.1 and as used in $prefix/Mailman/MailList.py 
++3.	removed unecessary setup of variable DEFAULT_URL in cron scripts
++$prefix/cron/remote_nightly_htdig_noshare and
++$prefix/cron/remote_nightly_htdig.pl 
++4.	Changes references to DEFAULT_URL in this document to DEFAULT_URL_PATTERN. 
++
++
++htdig-2.1-0.2.patch: 
++1.	improved content type and security handling in $prefix/Mailman/htdig.py.
++Fixes bug with htdig.py and problem of interaction with bug in
++$prefix/scripts/driver script (see patch #668685 for more details) 
++
++
++htdig-2.1-0.1.patch: 
++1.	Reworked patch for compatibility with MM 2.1. 
++
++
++htdig-2.1b6-0.1.patch: 
++1.	Reworked patch for compatibility with MM 2.1b6. 
++
++
++htdig-2.1b5-0.1.patch: 
++1.	Reworked patch for compatibility with MM 2.1b5. 
++
++
++htdig-2.1b4-0.1.patch: 
++1.	Reworked patch for compatibility with MM 2.1b4. As a consequence, the
++remainder of the mailman-htdig integration templates that were strings declared
++in Mailman/Archiver/HyperArch.py have been extracted into files under the
++templates directory. Edit these with care if you must. 
++
++
++htdig-2.1b3-0.3.patch: 
++1.	Removed unecessary code dependency on Python 2.2 file() function 
++
++
++htdig-2.1b3-0.2.patch: 
++1.	Removed syntax error in htdig-2.1b3-0.1.patch which showed up as logged
++errors in the operation of the ArchRunner qrunner at line 721 of HyperArch.py 
++
++
++htdig-2.1b3-0.1.patch: 
++1.	Reworked patch for compatibility with MM 2.1b3 
++2.	Removed non-English language template files which were acting as
++placeholders until someone actually translated them. 
++3.	Removed updateTOC.py and replaced it with an alternate mechanism in a patch
++to $prefix/Mailma/Queue/ArchRunner.py to update list TOC page after reindexing
++by htdig. This new method is only exercised when the remote_nightly_htdig series
++of cron scripts are used. 
++4.	Changes to remote_nightly_htdig series of cron scripts to reflect demise of
++updateTOC cgi script. 
++5.	Multiple instances of code hygiene and conformance to MM "standards"
++cleanup. 
++6.	Tidied up this documentation. 
++
++
++htdig-2.1b2-0.1.patch: 
++1.	reworked patch for compatibility with MM 2.1b2 
++
++
++htdig-2.0.13-0.2.patch: 
++1.	Added license header 
++
++
++htdig-2.0.13-0.1.patch: 
++1.	Rebuilt patch to get no-comment application on Mailman 2.0.13 
++
++
++htdig-2.0.12-0.1.patch: 
++1.	Rebuilt patch to get no-comment application on Mailman 2.0.12 
++2.	Added HTDIG_EXTRAS xonfig variable to allow arbitrary htdig configuration
++parameters to be specified for addition to every htdig.conf file created i.e.
++site wide additions. 
++
++
++htdig-2.0.11-0.1.patch: 
++1.	No substantive change. Simply rebuilt patch to get no-comment application on
++Mailman 2.0.11 
++
++
++htdig-2.0.10-0.2.patch: 
++1.	Python 2.2 compatibility fixes to nightly_htdig cron script and its
++relatives. Doing import * inside a function removed. 
++2.	Added note on potential problems with htdig and file permissions. 
++
++
++htdig-2.0.10-0.1.patch: 
++1.	change in src/Makefile.in to get clean patch application to MM 2.0.10 
++
++
++htdig-2.0.9-0.1.patch: 
++1.	minor cosmetic changes to get clean patch application to MM 2.0.9 
++
++
++htdig-2.0.8-0.1.patch: 
++1.	resolves a problem with the integration of htdig when the web_page_url for a
++list, which is usually the same as DEFAULT_URL from either
++$prefix/Mailman/Defaults.py or $prefix/Mailman/mm_cfg.py, when it doesn't use
++the http addressing scheme. This arises because htdig will only build indices if
++the URLs for pages use the http addressing scheme. There is a work-around for
++this problem posted in htdig's mail archives - see the copy in Appendix 1 to
++this document. 
++2.	This patch revision implements the solution documented in that e-mail. If
++non-http URLs are used by the web_page_url of a list an additional htdig
++configuration file for use by htsearch is generated. 
++3.	In all other respects the operation of the Mailman-htdig integration remains
++unchanged. There is no benefit in upgrading to this revised patch unless you
++need to use other than http addressing in your DEFAULT_URL or set other than
++http addressing in the web_page_url configuration of any of your lists. 
++4.	If changing to or from a non-http addressing scheme then the per list htdig
++config files of the lists affected and their associated htdig indices must be
++reconstructed. See the section below entitled "Changing the Addressing Scheme of
++your web_page_url" for details of how to do this. 
++
++
++htdig-2.0.6-0.3.patch: 
++1.	adds support for remote htdig, that is: running htdig on a different system
++to Mailman. 
++2.	enhances the configurability of the integration. Some of the programmed
++assumptions made in previous versions are now configurable in mm_cfg.py. The
++configuration variables concerned default to the previous fixed values so that
++this version is backwards compatible with earlier versions. 
++3.	does some minor cosmetic code changes. 
++4.	extends the associated documentation. 
++
++
++
++
++Appendices�
++----------------
++
++Appendix 1 -Technique for htdigging when Mailman's web_page_url uses the https
++scheme
++ 
++
++
++A technique for htdigging when Mailman's web_page_url uses the https 
++addressing scheme is described in this archived e-mail: 
++http://www.htdig.org/mail/1999/10/0187.html
++
++The text of that e-mail is as follows:
++
++[htdig] Re: Help about htdig indexing https files
++
++------------------------------------------------------------------------
++Gilles Detillieux (grdetil at scrc.umanitoba.ca)
++Wed, 27 Oct 1999 10:18:31 -0500 (CDT) 
++
++
++Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] 
++Next message: Avi Rappoport: "[htdig] indexing SSL (was: Help building 
++the database)" 
++Previous message: Gilles Detillieux: "Re: Fw: [htdig] mutiple search 
++results" 
++In reply to: Torsten Neuer: "Re: Fw: [htdig] mutiple search results" 
++
++------------------------------------------------------------------------
++According to Edouard DESSIOUX: 
++> >Currently, htdig will not support URLs that begin with https://, even
++> >when using local_urls to bypass the server. A trick that might work 
++> >would be to index using http:// instead, but use local_urls to point 
++> >to the directory that contains the contents of the secure server. 
++> 
++> I used that, and now, when i use htsearch, it work, except the fact 
++> that all my URL are http://x.y.z/ instead of https://x.y.z/ 
++> 
++> >You'd need to use separate 
++> >configuration files for digging and searching, and use 
++> >url_part_aliases in each of these configuration files to rewrite the 
++> >http:// into https:// in the search results. 
++> 
++> This is the part i dont understand, and i would like you to explain. 
++
++
++It basically works as a search and replace. One url_part_aliases in the 
++configuration file used by htdig maps the http://x.y.z/ into some 
++special code like "*site", and another url_part_aliases in the 
++configuration file used by htsearch maps the "*site" back into the value 
++you want, i.e. https://x.y.z/. The substitution is left to right in 
++htdig, and right to left in htsearch. So, if you use the same config 
++file for both, or the same setting for both, you get back what you 
++started with (but saved some space in the database because of the 
++encoding). However, if you use two separate config files with different 
++url_part_aliases setting for htdig and htsearch, you can remap parts of 
++URLs from one substring to another. 
++
++
++I hope this makes things clearer. I thought the current description at 
++http://www.htdig.org/attrs.html#url_part_aliases was already quite 
++clear. 
++
++
++
++-- 
++Gilles R. Detillieux              E-mail: <[email-masked]>
++Spinal Cord Research Centre       WWW:    
++http://www.scrc.umanitoba.ca/~grdetil
++Dept. Physiology, U. of Manitoba  Phone:  (204)789-3766
++Winnipeg, MB  R3E 3J7  (Canada)   Fax:    (204)789-3930
++------------------------------------
+diff -Nru mailman-2.1.5/INSTALL.htdig-mm.html mailman-2.1.5+htdig/INSTALL.htdig-mm.html
+--- mailman-2.1.5/INSTALL.htdig-mm.html	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/INSTALL.htdig-mm.html	2005-07-04 10:04:30.268416424 +0200
+@@ -0,0 +1,1980 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
++<html>
++<head>
++	<title>OpenInfo Web Site</title> 
++	<meta name="Generator" content="BBEdit">
++	<meta name="Author" content="Richard Barrett">
++	<meta name="Keywords" content="">
++	<meta name="Description" content="Mailman Patch #444884">
++</head>
++<body>
++<h1 align="CENTER">Mailman Patch #444884 Installation Details</h1> 
++<p>
++	The information below is also available in the <code> INSTALL.htdig-mm </code> file which is installed by this patch. 
++</p>
++<h2><a name="toc"> Table of Contents</a></h2> 
++<ul>
++	<li>
++		<a href="#pident"> Patch identification </a> 
++	</li>
++	<li>
++		<a href="#prereq"> Prerequisites </a> 
++	</li>
++	<li>
++		<a href="#current"> Current version </a> 
++		<ul>
++			<li>
++				<a href="#updreason"> Changes introduced by this patch version </a> 
++			</li>
++		</ul>
++	</li>
++	<li>
++		<a href="#intro"> Introduction </a> 
++	</li>
++	<li>
++		<a href="#iandb"> Installing and Building Mailman with this patch </a> 
++	</li>
++	<li>
++		<a href="#what"> What is Installed by the Patch </a> 
++	</li>
++	<li>
++		<a href="#config"> Configuration of Mailman-htdig Integration </a> 
++		<ul>
++			<li>
++				<a href="#health"> Health Warning on the packet! </a> 
++			</li>
++			<li>
++				<a href="#scratch"> Starting from Scratch (Again) </a> 
++			</li>
++			<li>
++				<a href="#general"> General </a> 
++			</li>
++			<li>
++				<a href="#perms"> Permissions Considerations </a> 
++				<ul>
++					<li>
++						<a href="#htperms"> htdig </a> 
++					</li>
++					<li>
++						<a href="#aperms"> Apache </a> 
++					</li>
++				</ul>
++			</li>
++			<li>
++				<a href="#lconfig"> Local htdig Configuration </a> 
++			</li>
++			<li>
++				<a href="#rconfig"> Remote htdig Configuration </a> 
++			</li>
++			<li>
++				<a href="#upgrade"> Upgrading an Existing Standard Mailman Installation </a> 
++			</li>
++			<li>
++				<a href="#ltor"> Changing from local to remote htdig or vice versa </a> 
++			</li>
++			<li>
++				<a href="#coping"> Coping with htdig Upgrades </a> 
++			</li>
++			<li>
++				<a href="#achange"> Changing the Addressing Scheme of your web_page_url </a> 
++			</li>
++		</ul>
++	</li>
++	<li>
++		<a href="#ops"> Operational Information </a> 
++	</li>
++	<li>
++		<a href="#notes"> Notes and Warnings </a> 
++		<ul>
++			<li>
++				<a href="#secsol"> Archive security problems resolved by htdig-2.1.3-0.2 patch </a> 
++			</li>
++			<li>
++				<a href="#secprob"> Private archive security problem prior to htdig-2.1.1-0.2.patch version </a> 
++			</li>
++			<li>
++				<a href="#keepsec"> Maintaining archive security with htdig-2.1.1-0.2.patch version and later </a> 
++			</li>
++			<li>
++				<a href="#secupgd"> Upgrading to htdig-2.1.1-0.2.patch or later from an earlier patch version </a> 
++			</li>
++			<li>
++				<a href="#redhat7">Redhat 7.1 and 7.2 installations</a> 
++			</li>
++			<li>
++				<a href="#apachehtdig">Apache/htdig issues</a> 
++			</li>
++		</ul>
++	</li>
++	<li>
++		<a href="#contrib"> Contributors </a> 
++	</li>
++	<li>
++		<a href="#history"> History </a> 
++		<ul>
++			<li>
++				<a href="#compat"> Compatibility </a> 
++			</li>
++			<li>
++				<a href="#changes"> Changes </a> 
++			</li>
++		</ul>
++	</li>
++	<li>
++		<a href="#appendices"> Appendices </a> 
++		<ul>
++			<li>
++				<a href="#app1"> Appendix 1 -Technique for htdigging when Mailman's DEFAULT_URL uses the https scheme </a> 
++			</li>
++		</ul>
++	</li>
++</ul>
++<h2><a id="pident"> Patch Identification</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<p>
++	Different versions of this patch are available for different versions of Mailman. There may be different versions of this patch for any given version of Mailman, typically as a results of MM version specific improvements or corrections of bugs in the patched code. The names of patch files for this patch are structured as follows: 
++</p>
++<pre>
++    htdig-&lt;MM-version-no&gt;-&lt;patch-version-no&gt;.patch[.gz]</pre> 
++<p>
++	Thus, for instance, patch file <code>htdig-2.1.4-0.1.patch</code> is patch version <code>0.1</code> for application to MM version <code>2.1.4</code> source code. 
++</p>
++<p>
++	The <code> &lt;patch-version-no&gt; </code> is reset to <code> 0.1 </code> for the first patch version applicable to each new version of Mailman. 
++</p>
++<p>
++	The <code>.gz</code> suffix, if present, says that the patch file has been compressed using gzip. 
++</p>
++<p>
++	As a general rule, you should use the highest patch version number for the MM version you are installing. 
++</p>
++<h2><a id="current"> Current Version</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<p>
++	The current version of this patch is for Mailman 2.1.5: 
++</p>
++<table>
++	<tr>
++		<td nowrap>
++			Mailman 2.1.5 
++		</td>
++		<td>
++			- 
++		</td>
++		<td>
++			<code>htdig-2.1.5-0.1.patch</code>			
++		</td>
++	</tr>
++</table>
++<p>
++    Be sure to read the <a href="#changes">notes in the changes section below</a> about the patch version you are going to use.
++</p>
++<p>
++	Patches for previous versions of Mailman are frozen at the highest revision level they reached while those previous versions of MM were current. 
++</p>
++<p>
++	Information about older Mailman and patch versions is given in the <a href="#history"> history </a> section below. 
++</p>
++<h3><a id="updreason"> Changes introduced by this patch version</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	The following changes are introduced by version <code>0.1</code> of this patch: 
++</p>
++<ul>
++    <li>
++        updated patch for MM 2.1.5 compatibility.
++    </li>
++    <li>
++        Note: the templates in <code>$build/templates/&lt;lang&gt;/</code>for the following languages are NOT modified by this patch or by its precursor indexing patch: <code>ca, eu, sr, sv</code><br>
++        The following files in a language's default template directory should be modified per the changes made to the <code>en</code> language templates after installation of this patch if that other language is used ;'
++        <ul>
++            <li><code>templates/&lt;lang&gt;/archidxfoot.html</code></li>
++            <li><code>templates/&lt;lang&gt;/archidxhead.html</code></li>
++            <li><code>templates/&lt;lang&gt;/archtoc.html</code></li>
++            <li><code>templates/&lt;lang&gt;/archtocentry.html</code></li>
++            <li><code>templates/&lt;lang&gt;/archtocnombox.html</code></li>
++            <li><code>templates/&lt;lang&gt;/article.html</code></li>
++        </ul>
++    </li>
++</ul>
++<h2><a name="prereq"> Prerequisites</a>&nbsp;<a href="#toc">[ toc ]</a></h2><h3>A working Htdig installation</h3> 
++<p>
++	You must have a working installation of htdig with <code>htsearch</code> available and installed on either the machine on which you are running Mailman or on another machine which has access to Mailman list archives via NFS or some similarly competent network file sharing scheme. 
++</p>
++<p>
++	Regardless of how you configure things to provide Mailman's Web UI, if its gives normal operation of the <code>/mailman/private</code> CGI script for providing access to private list archives, it should also support access to htdig search results via the <code>/mailman/mmsearch</code> and <code>/mailman/htdig</code> CGI scripts. 
++</p>
++<p>
++	Warning: This patch has been tested with HTdig 3.1.6 and no testing has been done with the Beta versions of HTdig 3.2 at the time of writing. You may or may not encounter problems/issues not described here if you use HTdig 3.2 beta or stable releases. 
++</p>
++<h3>Other Mailman patches</h3> 
++<p>
++	Prior to installing this patch you may also need to install the other MM patches. This will depend on the version of Mailman and the version of this patch you are dealing with. For version <code>0.3</code> of this patch for MM 2.1.3 the latest version of patch <code>#444879</code>, 
++	<nobr>
++		<code>indexing-2.1.3-x.y.patch</code> 
++	</nobr>
++	, is required. It is available from: 
++</p>
++<ul>
++	<li>
++		<a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=444879&amp;group_id=103&amp;atid=300103"> 
++			<nobr>
++				http://sourceforge.net/tracker/index.php?func=detail&amp;aid=444879&amp;group_id=103&amp;atid=300103 
++			</nobr>
++		</a> 
++	</li>
++	<li>
++		<a href="http://www.openinfo.co.uk/mailman/patches/444879/index.html"> 
++			<nobr>
++				http://www.openinfo.co.uk/mailman/patches/444879/index.html 
++			</nobr>
++		</a> 
++	</li>
++</ul>
++<p>
++	For any other version of this patch details of its prerequisites are in the version of <code>INSTALL.htdig-mm</code> file which is installed by that patch. 
++</p>
++<h2><a name="intro"> Introduction</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<p>
++	This integration enables use of the htdig (<a href="http://www.htdig.org">http://www.htdig.org</a>) search engine for searching mail list archives produced by pipermail, Mailman's built-in archiver. 
++</p>
++<p>
++	You can use htdig without applying these patches to Mailman but you may find it awkward to achieve some of the features offered by this patch. 
++</p>
++<p>
++	The main features of the patch are: 
++</p>
++<ol>
++	<li>
++		per list search facility with a search form on each list's TOC page. 
++	</li>
++	<li>
++		maintenance of privacy of private archives. The user has to establish their credentials via the normal private archive access mechanism before any access via htdig is allowed. 
++	</li>
++	<li>
++		<p>
++			a common base URL for both public and private archive access via htsearch results. This means that htdig indices are unaffected by changing an archive from private to public and vice versa. All access to archives via htdig is controlled by wrapped CGI scripts called htdig.py and mmsearch.py. 
++		</p>
++		<p>
++			Note that Mailman's attachment scrubber creates a problem when it extracts attachments from messages as they are being archived because it embeds absolute URLs to what it has extracted in the archived messages. This can only be fixed by running <code>$prefix/bin/arch</code> to rebuild the list's archive from its mbox file after changing its archive from private to public or vices versa. This problem is generic and unrelated to the use of this patch. One way resolving it is by use the Mailman-MHonArc integration patch <code>#????????</code> available from 
++		</p>
++		<ul>
++			<li>
++				TBA 
++			</li>
++			<li>
++				<a href="http://www.openinfo.co.uk/mailman/patches/mhonarc/index.html"> 
++					<nobr>
++						http://www.openinfo.co.uk/mailman/patches/mhonarc/index.html 
++					</nobr>
++				</a> 
++			</li>
++		</ul>
++	</li>
++	<li>
++		a choice of running htdig on the machine running Mailman (aka local htdig) or running htdig on another machine which has access to Mailman's archives via NFS or some similarly competent network file sharing scheme (aka remote htdig). 
++	</li>
++	<li>
++		cron activated scripts and crontab entry to run htdig regularly to maintain the per list search indices. 
++	</li>
++	<li>
++		automatic creation, deletion and maintenance of htdig configuration files and such. Beyond installing htdig and telling Mailman where it is via mm_cfg you do not have to do much other setup. 
++	</li>
++	<li>
++		htdig search related web page elements are retrieved from the <code>$prefix/templates/</code> directory hierarchy so that site, virtual host, list and language tailoring of them can be done. 
++	</li>
++</ol>
++<h2><a name="iandb"> Installing and Building Mailman with this patch</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<p>
++	Create your Mailman build directory in the normal way. 
++</p>
++<p>
++	You can apply the patch to either a fresh expansion of the Mailman source distribution or the one you used to build a currently working Mailman installation. 
++</p>
++<p>
++	Execute the following command in the Mailman build directory: 
++</p>
++<pre>
++    patch -p1 &lt; path-to-htdig-2.m.n-x.y.patch</pre> 
++<p>
++	Follow the configure and make procedures for regular Mailman as given in the <code>$build/INSTALL</code> file. 
++</p>
++<p>
++	Then follow the Mailman-htdig configuration instructions given below. 
++</p>
++<h2><a name="what"> What is Installed by the Patch</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2><h3>The patch amends:</h3> 
++<dl>
++	<dt>
++		<code>$build/INSTALL</code> 
++	</dt>
++	<dd>
++		<p>
++			Adds a reference to this file to the standard installation notes. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/bin/check_perms</code> 
++	</dt>
++	<dd>
++		<p>
++			To set the permissions for access to <code>$prefix/archive/private/&lt;listname&gt;/htdig/</code> subdirectories to <code>2770</code>. This prevents access by 'other', as a security measure. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/Mailman/Archiver/HyperArch.py</code> 
++	</dt>
++	<dd>
++		<p>
++			The changes in this file set up the per list htdig stuff such as config files and adds the search forms to the list TOC pages. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/Mailman/Queue/ArchRunner.py</code> 
++	</dt>
++	<dd>
++		<p>
++			The changes in this file rewrite a list's TOC page if, when archiving a new message for the list, the update time of the list's TOC page are after the last time that <code>rundig</code> was last run. This is is only of relevance when one of the <code>remote_nightly_htdig</code> series of cron scripts (see below) is being used. 
++		</p>
++		<p>
++			The only deficiency with this approach is that if no message is sent to the list after <code>rundig</code> is run for the list the TOC page is not rewritten to reflect that rundig was run. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/Mailman/Cgi/private.py</code> 
++	</dt>
++	<dd>
++		<p>
++			There is a security hole in the released Mailman code via which <code>private.py</code> will serve files such as a list's archive <code>pipermail.pck</code> and files in the list's archive <code>database</code> sub-directory. This hole also allows access to the list's archive <code>htdig</code> sub-directory. Fixes for this are applied. As <code>htdig.py</code> (see below) is based on <code>private.py</code> the same security fix has been incorporated into it. 
++		</p>
++	</dd>
++	<dt>
++		<code>$build/Mailman/Defaults.py.in</code> 
++	</dt>
++	<dd>
++		<p>
++			Adds the default configuration variables needed to support the mailman-htdig integration 
++		</p>
++	</dd>
++	<dt>
++		<code>$build/cron/crontab.in.in</code> 
++	</dt>
++	<dd>
++		<p>
++			Adds the nightly_htdig cron script to the default crontab 
++		</p>
++	</dd>
++	<dt>
++		<code>$build/configure</code> 
++	</dt>
++	<dt>
++		<code>$build/configure.in</code> 
++	</dt>
++	<dt>
++		<code>$build/Makefile.in</code> 
++	</dt>
++	<dt>
++		<code>$build/cron/Makefile.in</code> 
++	</dt>
++	<dt>
++		<code>$build/src/Makefile.in</code> 
++	</dt>
++	<dt>
++		<code>$build/bin/Makefile.in</code> 
++	</dt>
++	<dd>
++		<p>
++			Changes to configuration and Makefiles used for installing Mailman 
++		</p>
++	</dd>
++</dl>
++<h3>The patch adds:</h3> 
++<dl>
++	<dt>
++		<code>$build/INSTALL.htdig-mm</code> and <code>$build/INSTALL.htdig-mm.html</code> 
++	</dt>
++	<dd>
++		<p>
++			These contain the material you are reading. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/cgi-bin/htdig</code> 
++	</dt>
++	<dt>
++		<code>$prefix/Mailman/Cgi/htdig.py</code> 
++	</dt>
++	<dd>
++		<p>
++			these are a CGI script and its wrapper, which is always on the path of URLs returned from searches of htdig indices. The script provides secure access to such URLs in the same way that the <code>$prefix/cgi-bin/private</code> and <code>$prefix/Mailman/Cgi/private.py</code>. Both <code>htdig.py</code> and <code>private.py</code> ensures private archives are kept private, applying the same criteria for permitting access. Additionally, <code>htdig.py</code> delivers material from public archives without demanding any authentication. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/cgi-bin/mmsearch </code> 
++	</dt>
++	<dt>
++		<code>$prefix/Mailman/Cgi/mmsearch.py</code> 
++	</dt>
++	<dd>
++		<p>
++			these are a CGI script and its wrapper. The script acts as a security wrapper for htdig's <code>htsearch</code> CGI script. It will only run <code>htsearch</code> if the user is authorized to access a list's archive. it applies the same criteria as <code>$prefix/Mailman/Cgi/private.py</code>. In the case of local htdig operation, this script runs <code>htsearch</code> as a sub-process and returns its results. In the case of remote htdig operation <code>mmsearch</code> runs <code>htsearch</code> on the remote machine via one or other of the CGI scripts <code>remote_mmsearch</code> and <code>remote-mmsearch</code>. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/Mailman/Cgi/remote_mmsearch</code> 
++	</dt>
++	<dt>
++		<code>$prefix/Mailman/Cgi/remote-mmsearch</code> 
++	</dt>
++	<dd>
++		<p>
++			these are companion scripts of <code>mmsearch</code> for use with remote htdig operation. They are run by <code>mmsearch</code> via HTTP requests, and in turn run <code>htsearch</code> as a sub process, returning the results it delivers. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/bin/blow_away_htdig</code> 
++	</dt>
++	<dd>
++		<p>
++			this is a utility script for removing per list htdig data, e.g. the config file and indices/db files. This is necessary when: 
++		</p>
++		<ol type="a">
++			<li>
++				ceasing use of the Mailman-htdig integration 
++			</li>
++			<li>
++				moving from local to remote htdig or vice-versa 
++			</li>
++			<li>
++				upgrading to a version of htdig which has an incompatible index/db file format 
++			</li>
++			<li>
++				changing the addressing scheme (http versus https) in the web_page_url configuration variable of a list 
++			</li>
++			<li>
++				reconstructing per-list htdig configuration files after upgrading to <code>htdig-2.1.1-0.2.patch</code> or later from an earlier patch version, and prior to running <code>nightly_htdig</code> 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>$prefix/cron/nightly_htdig</code> 
++	</dt>
++	<dt>
++		<code>$prefix/cron/remote_nightly_htdig</code> 
++	</dt>
++	<dt>
++		<code>$prefix/cron/remote_nightly_htdig_noshare</code> 
++	</dt>
++	<dt>
++		<code>$prefix/cron/remote_nightly_htdig.pl</code> 
++	</dt>
++	<dd>
++		<p>
++			These scripts all do the same thing; they can be installed as a cron task and run regularly to invoke htdig's <code>rundig</code> script to update mailing list search indices. Only one of these scripts is used, the choice of which depending on your system configuration. 
++		</p>
++		<p>
++			<code>nightly_htdig</code> is used where Mailman and htdig run on the same system. 
++		</p>
++		<p>
++			the <code>remote_...</code> scripts are used where Mailman and htdig live on different systems. You choose which one suits your needs best: 
++		</p>
++		<p>
++			<code>remote_nightly_htdig</code> uses the same python files on both systems, that is the same <code>.py</code> and <code>.pyc</code> files are accessed, and it hence depends on compatible bytecode between the Mailman system and htdig system. It also accesses Mailman data files and depends on compatibility of data files contents, for example pickled Python values. This should work OK if the same version of python is being run on both systems even where the systems are not heterogeneous, for example one is Sun/Solaris and the other is PC/Linux. 
++		</p>
++		<p>
++			<code>remote_nightly_htdig_noshare</code> shares no Python files between the two systems. While it is still written in Python it acquires information from the file system using directory listings and stat operations. 
++		</p>
++		<p>
++			<code>remote_nightly_htdig.pl</code> is a rewrite of <code>remote_nightly_htdig_noshare</code> in Perl. It is for use where the htdig system does not have Python available on it: in which case, shame on you. 
++		</p>
++	</dd>
++	<dt>
++		<code>$prefix/templates/en/TOC_htsearch.html</code> 
++	</dt>
++	<dt>
++		<code>$prefix/templates/en/htdig_access_error.html</code> 
++	</dt>
++	<dt>
++		<code>$prefix/templates/en/htdig_auth_failure.html</code> 
++	</dt>
++	<dt>
++		<code>$prefix/templates/en/htdig_conf.txt</code> 
++	</dt>
++	<dd>
++		<p>
++			These are English language templates special to the htdig integration: 
++		</p>
++		<dl>
++			<dt>
++				<code>TOC_htsearch.html</code> 
++			</dt>
++			<dd>
++				the HTML of the search form that is embedded in a list's archive TOC page. 
++			</dd>
++			<dt>
++				<code>htdig_access_error.html</code> 
++			</dt>
++			<dd>
++				HTML page returned by mmsearch.py in the event of an access error for a page access. 
++			</dd>
++			<dt>
++				<code>htdig_auth_failure.html</code> 
++			</dt>
++			<dd>
++				HTML page returned by mmsearch.py in the event of an authentication error for a page access. 
++			</dd>
++			<dt>
++				<code>htdig_conf.txt</code> 
++			</dt>
++			<dd>
++				template for the per-list <code>htdig.conf</code> files generated by the patched code. 
++			</dd>
++		</dl>
++	</dd>
++</dl>
++<h2><a name="config"> Configuration of Mailman-htdig Integration</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<p>
++	Configuration of the Mailman-htdig integration is carried out on the Mailman side. While you must have to hand some information about your htdig installation, you should not have to tinker much with htdig for the integration to work. 
++</p>
++<p>
++	Most of the configuration of the integration is done by values assigned to python variables in either <code>$prefix/Mailman/Defaults.py</code> or <code>$prefix/Mailman/mm_cfg.py</code>. 
++</p>
++<p>
++	If you opt to run htdig on a different machine or under a different HTTP server to the one running the HTTP server which provides Mailman's Web UI you will also have to edit whichever of the patch's three htdig related cron scripts you opt to run (<code>remote_nightly_htdig</code>, <code>remote_nightly_htdig_noshare</code>, or <code>remote_nightly_htdig.pl</code>) to add a small amount of configuration information. 
++</p>
++<h3><a name="health"> Health Warning on the packet!</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	Be careful when editing configuration information in <code>$prefix/Mailman/mm_cg.py</code>: the only Mailman config file you should be editing. Check, double check and then recheck before going ahead. If you get either variable names or their values wrong a lot of confusion in the operation of both Mailman and htdig can result. 
++</p>
++<p>
++	You (and others supporting you) can spend hours trying to identify problems and looking for non-existent bugs as a consequence of such editing errors. Expect to find errors in these instructions; compensate for them and tell me when you do (r.barrett at openinfo.co.uk). 
++</p>
++<p>
++	Also do read the htdig documentation, release notes etc. This patch integrates a working htdig with <code>htsearch</code> available. These notes are about Mailman and integrating it with that working htdig. It is up to you to sort out the htdig end of things. 
++</p>
++<h3><a name="scratch"> Starting from Scratch (Again)</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	This is getting ahead of things but some of you may already be asking "What if I've already been using an older version of this patch and want to start afresh?", or "I want to change from local to remote htdig or vice versa?" 
++</p>
++<p>
++	In these cases your friend will be the <code>$prefix/bin/blow_away_htdig</code> script. It removes existing htdig related stuff out of your Mailman installation to the extent that it was added by this patch and added to by the normal operation of pipermail and <code>nightly_htdig</code>. With that removed and a revised Mailman configuration, the patched code will start rebuilding the htdig data. 
++</p>
++<p>
++	But before you get carried away with <code>blow_away_htdig</code>, read the rest of these notes. 
++</p>
++<h3><a name="general"> General</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	This patch adds a number of default variables to the file <code>$prefix/Mailman/Defaults.py</code> that affect operation of the Mailman-htdig integration. These are in addition to the standard Mailman defaults in that file. If, in the light of what is said below, you decide any of these are incorrect, you can override them in $<code>prefix/Mailman/mm_cfg.py</code> [NOT IN <code>Defaults.py</code>! See the comments in Defaults.py for why]. 
++</p>
++<p>
++	By default the Mailman-htdig integration is NOT ENABLED by the installation of this patch; the default value of the <code>USE_HTDIG</code> variable in <code>Defaults.py</code> turns off the operation of the integration. You have to actively override that default in <code>mm_cfg.py</code> to turn on operation of the integration. 
++</p>
++<p>
++	Once a list is created, changing most of these variables will have either no effect or a bad effect. You will need to run <code>$prefix/bin/blow_away_htdig</code> script and/or <code>$prefix/bin/arch</code> to rebuild the archive pages if you make significant changes to the Mailman-htdig integration configuration variables. 
++</p>
++<p>
++	The install process will not overwrite an existing <code>mm_cfg.py</code> file so you can freely make changes to this file. If you are re-installing a later version of this patch you may have to change what is already configured in the existing file and, if necessary, add extra configuration variables to it. 
++</p>
++<p>
++	Most of the Mailman-htdig control variables default to sensible values which you will not need to change, especially if you are using local htdig. The semantics of most variables apply to both local and remote htdig operation but with some the values assigned will depend on whether htdig is viewing things from the same or a remote machine. 
++</p>
++<p>
++	The first two variables control what is indexed by htdig. The values assigned are both embedded in the HTML generated by pipermail in the list archives and added. Changing the values of these variables will mean that all previously generated HTML pages in list archives will be out of date and you will probably want to rebuild existing archives using <code>$prefix/bin/arch</code>: 
++</p>
++<dl>
++	<dt>
++		<code>ARCHIVE_INDEXING_ENABLE</code> 
++	</dt>
++	<dd>
++		<p>
++			Defines a string telling htdig that it should look at the following material when building it indices. 
++		</p>
++<pre>
++    Default: ARCHIVE_INDEXING_ENABLE = '&lt;!--/htdig_noindex--&gt;'</pre> 
++	</dd>
++	<dt>
++		<code>ARCHIVE_INDEXING_DISABLE</code> 
++	</dt>
++	<dd>
++		<p>
++			Defines a string telling htdig that it not should not look at the following material when building it indices. 
++		</p>
++<pre>
++    Default: ARCHIVE_INDEXING_DISABLE = '&lt;!--htdig_noindex--&gt;'</pre> 
++	</dd>
++	<dt>
++		<code>USE_HTDIG</code> 
++	</dt>
++	<dd>
++		<p>
++			Semantics: 0 - don't use integrated htdig, 1 - use it 
++		</p>
++		<p>
++			Turns Mailman-htdig integration on or off. 
++		</p>
++<pre>
++    Defaults: USE_HTDIG = 0
++</pre> 
++		<p>
++			Notes: 
++		</p>
++		<ol>
++			<li>
++				<p>
++					when <code>USE_HTDIG</code> is turned on the patched code in Mailman will start adding htdig stuff for any archiving-enabled mail lists as new posts for eachlist are handled by Mailman. Until a new post is made after enabling with <code>USE_HTDIG</code> an existing mail list's archive will not be htdig searchable. When the new post is handled: 
++				</p>
++				<ol type="a">
++					<li>
++						the list's personalised htdig config file is created 
++					</li>
++					<li>
++						necessary links to the htdig config file are created 
++					</li>
++					<li>
++						a search form is added to the TOC page for the list 
++					</li>
++				</ol>
++				<p>
++					Even with this done, htdig searches only become available when htdig indices are constructed. This is done when one or other of the patch's htdig related cron scripts are run (<code>nightly_htdig</code>, <code>remote_nightly_htdig</code>, remote_nightly_htdig_noshare, or <code>remote_nightly_htdig.pl</code>, depending on how you configure your system). These can be run from the command line ahead of their scheduled cron time to get htdig searches operational. 
++				</p>
++			</li>
++			<li>
++				<p>
++					Turning <code>USE_HTDIG</code> off will not remove htdig indices or search forms from existing archive-enabled lists. It will however stop htdig features from being added to newly created lists. If you want to eliminate htdig from your existing lists then use the <code>$prefix/bin/blow_away_htdig</code> script. 
++				</p>
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>HTDIG_FILES_URL</code> 
++	</dt>
++	<dd>
++		<p>
++			This is the URL of the directory containing various HTML and Graphics files installed by htdig; files such as <code>buttonr.gif</code>, <code>buttonl.gif</code> and <code>button1-10.gif</code>. The URL must end with a '/'. 
++		</p>
++<pre>
++    Default: HTDIG_FILES_URL = '/htdig/'</pre> 
++		<p>
++			The default assumes the HTTP servers providing access to htdig and to Mailman's web UI are on the same machine and a symbolic link called 'htdig' has been put into your HTTP server's top level HTML directory which points to the directory your htdig install has put the actual files into; this link is often to <code>/usr/share/htdig</code>. This value will depend on your htdig installation decisions and HTTP server's configuration files (typically <code>/etc/httpd/httpd.conf</code> on a late model Apache installation) i.e the Alias through which the link to the htdig files are reached. 
++		</p>
++	</dd>
++	<dt>
++		<code>HTDIG_CONF_LINK_DIR</code> 
++	</dt>
++	<dd>
++		<p>
++			This is the name of a directory in which links to list specific htdig config files are placed. 
++		</p>
++<pre>
++    Default: HTDIG_CONF_LINK_DIR = os.path.join(VAR_PREFIX, 'archives', 'htdig')</pre> 
++		<p>
++			The <code>VAR_PREFIX</code> of the default is resolved to an actual file system path when when Mailman's '<code>make install</code>' is run. The '<code>os.path.join</code>' creates a full file system path by gluing together the three pieces when Mailman is run. This definition puts the directory alongside the default <code>PUBLIC_ARCHIVE_FILE_DIR</code> and <code>PRIVATE_ARCHIVE_FILE_DIR</code>. Unless you are changing the value of these variables you probably do not want to change <code>HTDIG_CONF_LINK_DIR</code>. 
++		</p>
++	</dd>
++	<dt>
++		<code>HTDIG_RUNDIG_PATH</code> 
++	</dt>
++	<dd>
++		<p>
++			This is the path in your file system to the rundig shell script that is installed as part of htdig. This tells one or other of the patch's htdig related cron scripts (<code>nightly_htdig</code> and <code>remote_nightly_htdig</code>) where to find rundig in order that they can execute it. 
++		</p>
++<pre>
++    Default: HTDIG_RUNDIG_PATH = '/usr/bin/rundig'</pre> 
++	</dd>
++	<dt>
++		<code>HTDIG_HTSEARCH_PATH</code> 
++	</dt>
++	<dd>
++		<p>
++			This is the file path to the <code>htsearch</code> program in the htdig package. 
++		</p>
++<pre>
++    Default: HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'</pre> 
++		<p>
++			This value will depend on your htdig installation decisions. This path is used by either the <code>mmsearch</code> CGI script (for local htdig) or the <code>remote_mmsearch/remote-mmsearch</code> CGI script (for remote htdig) to execute <code>htsearch</code> as a sub-process. 
++		</p>
++	</dd>
++	<dt>
++		<code>HTDIG_EXCLUDED_URLS</code> 
++	</dt>
++	<dd>
++		<p>
++			See htdig's configuration file documentation. The value of this MM variable is inserted into per-list <code>htdig.conf</code> files when they are created as the value of an htdig <code>excluded_urls</code> directive. But if an exclusion in this value would prevent indexing of URLs for accessing the <code>htdig.py</code> cgi wrapper then that exclusion is omitted from that per-list <code>htdig.conf</code> file. 
++		</p>
++<pre>
++    Default: HTDIG_EXCLUDED_URLS = '/cgi-bin/ .cgi'
++</pre> 
++		<p>
++			Note: these are the same as the htdig 3.1.6 default values. 
++		</p>
++	</dd>
++	<dt>
++		<code>REMOTE_HTDIG</code> 
++	</dt>
++	<dd>
++		<p>
++			Semantics: 0 - htdig runs on local machine, 1 -on remote machine 
++		</p>
++		<p>
++			Says whether htdig going to be run on the same machine as Mailman or on another machine. 
++		</p>
++<pre>
++    Default: REMOTE_HTDIG = 0</pre> 
++	</dd>
++	<dt>
++		<code>REMOTE_PRIVATE_ARCHIVE_FILE_DI</code>R 
++	</dt>
++	<dd>
++		<p>
++			Only relevant if <code>REMOTE_HTDIG</code> = 1. It is the file system path to the directory in which Mailman stores private archives, as seen by the machine running htdig. 
++		</p>
++<pre>
++    Default: REMOTE_PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 
++                                              'archives', 'private')</pre> 
++		<p>
++			The <code>VAR_PREFIX</code> of the default is resolved to an actual file system path when when Mailman's '<code>make install</code>' is run. The '<code>os.path.join</code>' creates a full file system path by gluing together the three pieces when Mailman is run. If you assign a value to this in <code>mm_cfg.py</code>, just put the relevant explicit file system path in. 
++		</p>
++	</dd>
++	<dt>
++		<code>REMOTE_MMSEARCH_URL</code> 
++	</dt>
++	<dd>
++		<p>
++			Only relevant if <code>REMOTE_HTDIG</code> = 1. It is the URL on the htdig machine through which whichever of the the remote_mmsearch/remote-mmsearch CGI scripts you have opted to use can be reached via an HTTP request. 
++		</p>
++<pre>
++    Default: REMOTE_MMSEARCH_URL = '/cgi-bin/remote-mmsearch'</pre> 
++	</dd>
++	<dt>
++		<code>HTDIG_STRICT_FILE_PERM</code> 
++	</dt>
++	<dd>
++		<p>
++			Semantics: 0 - 'other' access allowed, 1 - 'other' access denied 
++		</p>
++		<p>
++			Says whether 'other' has access permissions for per-list <code>$prefix/private/archives/&lt;listname&gt;/htdig/</code> directories. For local htdig operation such access is not required and is a security hole if allowd. Such access may be needed if remote htdig is used; see notes on "<a href="#aperms">Apache</a>". <code>$prefix/bin/check_perms</code> should be run after changing the value of this variable in <code>mm_cfg.py</code> to update access permissions of existing directories. 
++		</p>
++<pre>
++    Defaults: HTDIG_STRICT_FILE_PERM = 1
++</pre> 
++	</dd>
++	<dt>
++		<code>HTDIG_EXTRAS</code> 
++	</dt>
++	<dd>
++		<p>
++			You can assign a string value to this config variable and that string will be included in all of your site's list specific htdig configuration files when they are created. The value of the string can be any attribute declarations as defined at http://www.htdig.org/confindex.html. 
++		</p>
++		<p>
++			Be cautious in what you do with this. Most sites will not need to use this at all. But if you have some idiosyncratic htdig installation it might help overcome problems in integrating with Mailman. If you think you need to use it I suggest: 
++		</p>
++		<ol type="a">
++			<li>
++				You try creating a test list without assigning a value to <code>HTDIG_EXTRAS</code> in <code>$prefix/Mailman/mm_cfg.py</code> 
++			</li>
++			<li>
++				Enable archiving for that test list. 
++			</li>
++			<li>
++				Send a message to the test list so that its archive is created together with its htdig configuration file. 
++			</li>
++			<li>
++				Review the content of the list's htdig conf file in <code>$prefix/archives/private/&lt;listname&gt;/htdig/&lt;listname&gt;.conf</code>. 
++			</li>
++			<li>
++				You will see where the default value of <code>HTDIG_EXTRAS</code> from <code>$prefix/Mailman/Defaults.py</code> has been inserted. This value is onlyan htdig comment and does nothing. 
++			</li>
++			<li>
++				Consider whether what you will assign to <code>HTDIG_EXTRAS</code> in $prefix/Mailman/mm_cfg.py will make sense in the context of the rest of the htdig conf file's contents. 
++			</li>
++		</ol>
++	</dd>
++</dl>
++<h3><a name="perms">Permissions Considerations</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> <h4><a id="htperms">htdig</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h4> 
++<p>
++	Python scripts added by this patch (<code>nightly_htdig</code> and its relatives) run the htdig <code>rundig</code> script identified by <code>HTDIG_RUNDIG_PATH</code> to build search indices for Mailman archives. Code added by this patch generates per-list htdig configuration files which are passed as a parameter to the <code>rundig</code> script. These configuration files identify a list specific directory (<code>$prefix/archives/private/lt;listname&gt;/htdig</code>) in which list specific data files generated by and used by htdig are to be placed. 
++</p>
++<p>
++	However, the <code>rundig</code> script identified by <code>HTDIG_RUNDIG_PATH</code> may attempt to generate some files in htdig's <code>COMMON_DIR</code> when it is first run by <code>nightly_htdig</code>; the files concerned are likely to be <code>root2word.db</code>, <code>word2root.db</code>, s<code>ynonyms.db</code> and possibly some others generated by htidg's <code>htfuzzy</code> program. The standard <code>rundig</code> script generates these files selectively if they do not already exist. Depending on how you have installed htdig and how the <code>rundig</code> script is first run, there may be a permissions problem when <code>nightly_hdig</code> executes rundig under the mailman <code>UID</code> if it tries to generate these files. 
++</p>
++<p>
++	You may need to either give the mailman UID write permission over htdig's <code>COMMON_DIR</code> or, before the <code>nightly_htdig</code> script is first run, run htdig's <code>htfuzzy</code> executable with a sufficiently privileged <code>UID</code> in the manner that the <code>rundig</code> script would run <code>htfuzzy</code>, to create any necessary files in <code>COMMON_DIR</code>. 
++</p>
++<p>
++	See htdig's documentation for further information on this topic. 
++</p>
++<h4><a id="aperms">Apache</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h4> 
++<p>
++	When <code>remote_mmsearch</code> or <code>remote-mmsearch</code> scripts are used as part of a remote htdig strategy you may encounter a file permissions problem. This is because these scripts, which in turn execute <code>htsearch</code> as a sub-process, will be run with UID and GID of the remote Apache server. 
++</p>
++<p>
++	By default, the permissions of the per-list <code>$prefix/private/archives/&lt;listname&gt;/htdig/</code> directories only allow access for the mailman UID and GID and hence the remotely executed <code>htsearch</code> will be unable to access them. 
++</p>
++<p>
++	If this problem is encounterd, then you will have to use the <code>HTDIG_STRICT_FILE_PERM</code> configuration variable to say "open up the permissions" before running <code>$prefix/bin/check_perms</code>. You can then use a <code>RewriteRule</code> or similar in the Apache server's <code>httpd.conf</code> file to restrict access to <code>$prefix/private/archives/&lt;listname&gt;/htdig/</code> directories via the web server. 
++</p>
++<h3><a name="lconfig"> Local htdig Configuration</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	This configuration is for when you are running Mailman, htdig, the HTTP server used to provide Mailman's web UI and htdig's htsearch CGI script, on the same machine. 
++</p>
++<p>
++	You will need to: 
++</p>
++<ol type="a">
++	<li>
++		If different to the default value, add the definition of <code>HTDIG_RUNDIG_PATH</code> to file <code>$prefix/Mailman/mm_cfg.py</code>. 
++	</li>
++	<li>
++		If different to the default value, add the definition of <code>HTDIG_HTSEARCH_PATH</code> to file <code>$prefix/Mailman/mm_cfg.py</code>. 
++	</li>
++	<li>
++		Add the definition of <code>USE_HTDIG</code> with the value 1 to <code>$prefix/Mailman/mm_cfg.py</code>. 
++	</li>
++</ol>
++<pre>
++        USE_HTDIG = 1</pre> 
++<p>
++	If necessary you can override the values of any of the other configuration variables in file <code>$prefix/Mailman/mm_cfg.py</code>. 
++</p>
++<p>
++	In particular you might need to change the <code>HTDIG_FILES_URL</code> variable from its default. This URL can be just the path i.e. absolute URL on the same server as that which serves Mailman's Web UI, or a full URL identifying the scheme (http), server, server port and path, for example http://mailer.yourdomain.tld:8080/htdig/ 
++</p>
++<h3><a name="rconfig"> Remote htdig Configuration</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	This configuration is for when you are running htdig and an HTTP server providing access to <code>htsearch</code> via <code>remote_mmsearch</code> or <code>remote-mmsearch</code> on a different machine to that is running Mailman. 
++</p>
++<p>
++	For this configuration to work, htdig's programs, both those run from command lines such as <code>rundig</code> and those run via CGI such as <code>htsearch</code>, must be able to see Mailman archives through NFS. In the examples below we'll assume that <code>/mnt/mailman-archives</code> on the htdig machine maps to <code>$prefix/mailman/archives</code> on the Mailman machine. 
++</p>
++<p>
++	You should also arrange for he mailman UID and its GID to be common to both machines. Remember that when <code>rundig</code> is called on the htdig machine to produce search indices for each list it will be trying to write those files via NFS in Mailman's archive area and will thus need to run with an appropriate identity and permissions. 
++</p>
++<p>
++	The differences between the local and remote configuration are: 
++</p>
++<ol>
++	<li>
++		configuration values telling htdig where to find files are as viewed from the remote machine. 
++	</li>
++	<li>
++		configuration values giving URLs that refer to htdiggy things have to be as viewed from the Mailman machine. 
++	</li>
++</ol>
++<p>
++	You will need to: 
++</p>
++<ol>
++	<li>
++		Add the definition of <code>HTDIG_HTSEARCH_PATH</code> to file <code>$prefix/Mailman/mm_cfg.py</code>. This is path to htdig's <code>htsearch</code> on the remote machine running htdig. For example: <pre>
++    HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'</pre> 
++	</li>
++	<li>
++		Add the definition of <code>HTDIG_RUNDIG_PATH</code> to file <code>$prefix/Mailman/mm_cfg.py</code>. This is path to <code>rundig</code> on the remote machine running htdig. For example: <pre>
++    HTDIG_RUNDIG_PATH = '/usr/bin/rundig'</pre> 
++	</li>
++	<li>
++		Add the definition of <code>REMOTE_MMSEARCH_URL</code> to file <code>$prefix/Mailman/mm_cfg.py</code>. This must be a full URL referring to one of Mailman's <code>remote_mmsearch/remote-mmsearch</code> CGI scripts on the remote htdig machine, as seen from the Mailman local machine. For example: <pre>
++    REMOTE_MMSEARCH_URL = 'http://htdiggy.your.com/cgi-bin/remote-mmsearch'</pre> 
++	</li>
++	<li>
++		Add the definition of <code>HTDIG_FILES_URL</code> to file <code>$prefix/Mailman/mm_cfg.py</code>. This must be a full URL referring to the directory containing htdig files on the remote htdig machine as seen from the Mailman local machine. This URL must end with a '/'. For example:<pre>
++    HTDIG_FILES_URL = 'http://htdiggy.your.com/htdig/'</pre> 
++	</li>
++	<li>
++		Add the definition of <code>REMOTE_PRIVATE_ARCHIVE_FILE_DIR</code> to <code>$prefix/Mailman/mm_cfg.py</code>. This must be the absolute file system path to the directory in which Mailman stores private archives as seen by the machine running htdig. For example: <pre>
++    REMOTE_PRIVATE_ARCHIVE_FILE_DIR = '/mnt/mailman-archives/private'</pre> 
++	</li>
++	<li>
++		Add the definition of <code>USE_HTDIG</code> with the value 1 to $<code>prefix/Mailman/mm_cfg.py</code>. <pre>
++    USE_HTDIG = 1</pre> 
++	</li>
++	<li>
++		Add the definition of <code>REMOTE_HTDIG</code> with the value 1 to <code>$prefix/Mailman/mm_cfg.py</code>. <pre>
++    REMOTE_HTDIG = 1</pre> 
++	</li>
++	<li>
++		If necessary add the definition of <code>HTDIG_STRICT_FILE_PERM</code> with the value 0 to <code>$prefix/Mailman/mm_cfg.py</code>. This may be needed it the UID/GID that Apache on the htdig server will run the remote mmsearch as is not mailman or in the mailman group. This change will open up a security hole which you may want to consider plugging; see under the heading "<a href="#aperms">Apache permissions</a>" for more details.<pre>
++    HTDIG_STRICT_FILE_PERM = 0</pre> 
++	</li>
++</ol>
++<p>
++	You have to choose one of the two remote mmsearch scripts found in <code>$prefix/Mailman/Cgi</code> - <code>remote-mmsearch</code> (a Perl script) and <code>remote_mmsearch</code> (a Python script) - to use and transfer it to the htdig machine. You need to add this script to the directory in which the web server on the htdig machines expects to find CGI scripts. Having transferred the script to you htdig machine you will need to use a text editor to set the values of four configuration variables below the heading "Edit the following configuration variables to suit your installation", namely: 
++</p>
++<blockquote>
++	<dl>
++		<dt>
++			<code>MAILTO</code> 
++		</dt>
++		<dd>
++			this is the default mail address for your installation. 
++		</dd>
++		<dt>
++			<code>VALID_IP_LIST</code> 
++		</dt>
++		<dd>
++			this is a list of IP numbers from which the script should accept an HTTP request. Normally this should be set to the IP number of your machine running Mailman. If the list is empty the script will accept HTTP requests from any machine and be vulnerable to the exploit described under the heading <a href="#secprob">"Private archive security problem prior to <code>htdig-2.1.1-0.2.patch version</code>"</a> above. 
++		</dd>
++		<dt>
++			<code>HTDIG_CONF_LINK_DIR</code> 
++		</dt>
++		<dd>
++			this is the file path to the directory in which links to list specific htdig config files are placed, as viewed from the remote machine running htdig. 
++		</dd>
++		<dt>
++			<code>HTDIG_HTSEARCH_PATH</code> 
++		</dt>
++		<dd>
++			this is the file path to the <code>htsearch</code> program in the htdig package as viewed from the remote machine running htdig. 
++		</dd>
++	</dl>
++	<p>
++		See <a href="#what">"What is Installed by the Patch"</a> for an explanation of the differences between these remote mmsearch scripts which both do the same job: being a security wrapper around htdig's <code>htsearch</code> program to restrict searching of a list's archive indexes to users authorised to see the contents of that archive. 
++	</p>
++	<p>
++		Note: You may need to change the '<code>#!</code>' on the first line of whichever of the <code>remote-mmsearch</code> (Perl) and <code>remote_mmsearch</code> (Python) scripts you opt for so that the correct interpreter is used for running the script on the remote htdig machine. You may also need to verify the supporting packages/modules used by the selected script are installed on that system. 
++	</p>
++</blockquote>
++<p>
++	You have to choose one of the three <code>remote_nightly_htdig</code> scripts found in <code>$prefix/cron</code> - <code>remote_nightly_htdig</code>, <code>remote_nightly_htdig_noshare</code> and <code>remote_nightly_htdig.pl</code> - and transfer it to the htdig machine. See above under heading <a href="#what">"What is Installed by the Patch"</a> for an explanation of the differences between these scripts, which all do the same basic job. You should add the script to the crontab for the mailman UID on the htdig machine. But first you need to edit the selected script to add some configuration information. What has to be added depends on which script you opt to use. In each case the variables concerned are declared near the top of the script and you just have to enter the appropriate values: 
++</p>
++<blockquote>
++	<dl>
++		<dt>
++			<code>remote_nightly_htdig</code> 
++		</dt>
++		<dd>
++			<p>
++				you only need to set the value of the python variable <code>MAILMAN_PATH</code> to be the directory <code>$prefix</code> as seen from the htdig machine. The whole Mailman installation must be accessible via NFS in order to use this script. 
++			</p>
++		</dd>
++		<dt>
++			<code>remote_nightly_htdig_noshare</code> 
++		</dt>
++		<dd>
++			<p>
++				you need to copy the values for the following configuration variables from either $prefix/Mailman/mm_cfg.py or $prefix/Mailman/Defaults.py to the script: <code>REMOTE_PRIVATE_ARCHIVE_FILE_DIR</code>, <code>HTDIG_RUNDIG_PATH</code>. The variables declared in <code>remote_nightly_htdig_noshare</code> use the same names. This script only requires that the archives directory of the Mailman installation be accessible via NFS. 
++			</p>
++		</dd>
++		<dt>
++			<code>remote_nightly_htdig.pl</code> 
++		</dt>
++		<dd>
++			<p>
++				you need to copy the values for the following configuration variables from either <code>$prefix/Mailman/mm_cfg.py</code> or <code>$prefix/Mailman/Defaults.py</code> to the script: <code>REMOTE_PRIVATE_ARCHIVE_FILE_DIR</code>, <code>HTDIG_RUNDIG_PATH</code>. Being a Perl script, the variables in <code>remote_nightly_htdig.pl</code> use the same names but prefixed with the '$' character. This script only requires that the archives directory of the Mailman installation be accessible via NFS. 
++			</p>
++		</dd>
++	</dl>
++	<p>
++		Note: You may need to change the '<code>#!</code>' on the first line of whichever of these scripts you opt for so that the correct interpreter is used for running the script on the remote htdig machine. You may also need to verify the supporting packages/modules used by the selected script are installed on that system. 
++	</p>
++	<p>
++		As with the <code>nightly_htdig</code> script when running with local htdig, these scripts can be run from the command line using the mailman UID in order to get htdig to construct an initial set of indices. 
++	</p>
++</blockquote>
++<h3><a name="upgrade"> Upgrading an Existing Standard Mailman Installation</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<ol>
++	<li>
++		You will want to suspend operation of Mailman while doing the upgrade. Consider doing a shutdown of the MTA delivering mail to Mailman and removing Mailman's crontab. 
++	</li>
++	<li>
++		Configure and install as described above. 
++	</li>
++	<li>
++		Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++	</li>
++	<li>
++		If your installation already has archives: 
++		<ol type="a">
++			<li>
++				Send a message to each of your archive-enabled lists. This will stimulate the setup of the new per list htdig config files in the Mailman archives. 
++			</li>
++			<li>
++				Consider rebuilding your existing archives with <code>$prefix/bin/arch</code>. This will embed the <code>ARCHIVE_INDEXING_ENABLE</code> and <code>ARCHIVE_INDEXING_DISABLE</code> in the regenerated archive pages and, after <code>nightly_htdig</code> has been run, give improved search results. 
++			</li>
++			<li>
++				Run the nightly_htdig script from the command line to generate an initial set of per-list htdig search indices. 
++			</li>
++		</ol>
++	</li>
++</ol>
++<h3><a name="ltor"> Changing from local to remote htdig or vice versa</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<ol>
++	<li>
++		You will want to suspend operation of Mailman while making this change. Consider doing a shutdown of the MTA delivering mail to Mailman and removing Mailman's crontab. 
++	</li>
++	<li>
++		Run the <code>$prefix/bin/blow_away_htdig</code> script to remove all existing per list htdig config files and htdig indices/db files. 
++	</li>
++	<li>
++		Configure per the instructions above for the local or remote target. 
++	</li>
++	<li>
++		Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++	</li>
++	<li>
++		Send a message to each of your archive-enabled lists. This will stimulate the set up of the new per list htdig config files in Mailman archives. 
++	</li>
++	<li>
++		Run the <code>nightly_htdig</code> script from the command line to generate a new set of per list htdig search indices. 
++	</li>
++</ol>
++<h3><a name="coping"> Coping with htdig Upgrades</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	If you change the version of htdig you run, you may find that the indices built with the earlier version are not compatible with the newer version of htdig's programs. In that case do the following: 
++</p>
++<ol>
++	<li>
++		You will want to suspend operation of Mailman while making this change. Consider doing a shutdown of the MTA delivering mail to Mailman and removing Mailman's crontab. 
++	</li>
++	<li>
++		Run the <code>$prefix/bin/blow_away_htdig</code> script with the <code>-i</code> flag to remove all existing per list htdig indices/db files. 
++	</li>
++	<li>
++		Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++	</li>
++	<li>
++		Run the <code>nightly_htdig</code> script from the command line to generate new sets of per-list htdig search indices. 
++	</li>
++</ol>
++<h3><a name="achange"> Changing the Addressing Scheme of your web_page_url</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	If you change the addressing scheme of the <code>web_page_url</code> for a list to or from http then you will need to rebuild the list's htdig configuration file(s) and the related htdig indices. Do the following: 
++</p>
++<ol>
++	<li>
++		You may want to suspend operation of Mailman while making this change. Consider doing a shutdown of the MTA delivering mail to Mailman and removing Mailman's crontab. 
++	</li>
++	<li>
++		Run the <code>$prefix/bin/blow_away_htdig</code> script to remove all existing per list htdig material for the list(s) concerned. 
++	</li>
++	<li>
++		Restart Mailman's crontab and restart your MTA's delivery to Mailman. 
++	</li>
++	<li>
++		Send a message to each affected list to provoke reconstruction of the list's htdig config file(s). 
++	</li>
++	<li>
++		Run the <code>nightly_htdig</code> script from the command line to generate new sets of per list htdig search indices. 
++	</li>
++</ol>
++<h2><a name="ops"> Operational Information</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<p>
++	If you have just turned <code>USE_HTDIG</code> on or just used <code>$prefix/bin/blow_away_htdig</code> (without the <code>-i</code> flag) there will be no per-list htdig information saved in the archives. 
++</p>
++<p>
++	When the first post to each archive-enabled list is archived by pipermail, the per-list htdig config file will be constructed and some directories and links added to your Mailman archive directories. The htdig search form will be added to list's TOC page. 
++</p>
++<p>
++	However, until one of the <code>nightly_htdig</code> scripts is run no htdig indices will be constructed. You can either wait for the script to run as a cron job or run it (while using the mailman UID) from the command line. 
++</p>
++<h2><a name="notes"> Notes and Warnings</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> <h3><a id="secsol"> Archive security problems resolved by htdig-2.1.3-0.2 patch</a></h3> 
++<p>
++	This patch is hopefully the final step in closing security holes in archive access. 
++</p>
++<p>
++	In version <code>htdig-2.1.3-0.1.patch</code>, <code>htdig.py</code> was rebased on the standard MM release's <code>private.py</code> which had moved on since the snapshot of it used as the basis for <code>htdig.py</code> was originally taken. Among other things, <code>htdig.py</code> had been modified to prevent access to some files in list archive directories such as a list's archive <code>pipermail.pck</code> and files in the list's archive <code>database</code> sub-directory. 
++</p>
++<p>
++	This rebasing action re-introduced to <code>htdig.py</code> the security holes, still extant in <code>private.py</code> despite it being later code, via which <code>private.py</code> would serve files such as a list's archive <code>pipermail.pck</code> and files in the list's archive <code>database</code> sub-directory. 
++</p>
++<p>
++	The permissions on these files and directories mean that they are inaccessible via the web server using <code>/pipermail/</code> URIs if a list's archive is public. 
++</p>
++<p>
++	Additionally, <code>check_perms</code> is now modified so that the list archive <code>htdig</code> subdirectory permissions are set to 2770 by default. Prior to <code>htdig-2.1.1-0.2.patch</code>, this could not be done as the <code>htsearch</code> script, being run with uid and gid of the Apache server, could then not gain access to files in the htdig subdirectories. But, since the introduction of the <code>mmsearch</code> script, which runs with the mailman gid and spawns <code>htsearch</code>, it can. This prevents accees to the list archive <code>htdig</code> subdirectories via <code>/pipemail/</code> URI's. Up until <code>htdig-2.1.3-0.2.patch</code> this could only be achieved by using a <code>RewriteRule</code> or similar in the Apache server's <code>httpd.conf</code> file. 
++</p>
++<del>
++	The only residual problem is that the revised permissions on the archive htdig subdirectories may cause problems if the remote_mmsearch and remote-mmsearch are used. This is because they will be run with uid and gid of the Apache server. If this problem is encounterd, then you will have to manually add read and execute permissions for 'other' to the archive htdig subdirectories and read permission their contents, and then use <code>RewriteRule</code> or similar in the Apache server's <code>httpd.conf</code> file for protection. 
++</del>
++<p>
++	The solution to this problem has been superceded in <code>htdig-2.1.3-0.3.patch</code> as follows: Introduced the <code>HTDIG_STRICT_FILE_PERM</code> Mailman config variable as part of dealing with <code>htsearch</code> access to per-list <code>htdig</code> directories permissions issue when operating with remote htdig. See under the "<a href="#aperms">Apache</a>" heading above. 
++</p>
++<h3><a name="secprob"> Private archive security problem prior to htdig-2.1.1-0.2.patch version</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	Versions of the Mailman-htdig integration patch installed by versions of this patch prior to htdig-2.1.1-0.2.patch allow a security exploit which can expose information, held in the per-list search indexes of private list archives, to unauthorised users. 
++</p>
++<p>
++	Via the exploit an unauthoized user can submit a search query to htdig's htsearch CGI program without their having been authenticated as a user allowed to access the list archive concerned. The results, returned in good faith by htsearch, will expose some information that the user is not entitled to see. 
++</p>
++<p>
++	However, the security breakdown is not complete. Attempts to follow links returned by htsearch, which go via the htdig CGI script installed by this patch, will be blocked if the user is not authorized to access the list archive. 
++</p>
++<h3><a name="keepsec"> Maintaining archive security with htdig-2.1.1-0.2.patch version and later</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	With htdig-2.1.1-0.2.patch and later versions of the patch: 
++</p>
++<ol>
++	<li>
++		htsearch is no longer used directly via CGI for searching list archives. 
++	</li>
++	<li>
++		The symbolic link named by the HTDIG_MAILMAN_LINK configuration variable is no longer used. Indeed, when upgrading earlier installations this symlink should be deleted and the configuration variable deleted. Without this symlink, on a normally configured system, htsearch no longer has the unaided ability to access the per-list htdig configuration and other list archive associated files. 
++	</li>
++	<li>
++		Thus, even if htsearch can be reached via CGI, it cannot undertake a search of list archives when requested to do so by an HTTP request which seeks to circumvent list archive security. 
++	</li>
++	<li>
++		A new script, $prefix/Mailman/Cgi/mmsearch.py, is now used to search list archives. This script applies the same user authentication as private.py and htdig.py. Only if a user is authorised to access a list, does mmsearch use htdig's htsearch to search a list's archive. In this case, mmsearch provides htsearch with the information it needs to access the per-list htdig configuration and other list archive associated files. 
++	</li>
++	<li>
++		Where htidg and Mailman are run on the same machine, mmsearch acts as a security wrapper, runs htsearch as a sub-process and list security is preserved by this means. 
++	</li>
++	<li>
++		Where htdig is run on a different machine to Mailman, mmsearch can perform user authentication but has problems in acting as a security wrapper for htsearch. The solution adopted is for one of two companion CGI scripts (remote-mmsearch written in Perl or remote_mmsearch written in Python) to be invoked on the remote htdig machine by an HTTP request made by mmsearch on the Mailman machine. These scripts run htsearch, providing it with the information it needs to access the per-list htdig configuration and other list archive associated files. But, such an HTTP request can be made by other means and thus the the same security exploit we are trying to avoid still exists. The only protection in the case of remote htdig operation is that the remote-mmsearch/remote_mmsearch scripts can be configured to operate only on HTTP requests originating from specified IP numbers. By restricting operation to requests originating on the Mailman server some semblance of list privacy can be preserved. 
++	</li>
++</ol>
++<h3><a name="secupgd"> Upgrading to htdig-2.1.1-0.2.patch or later from an earlier patch version</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	If you are upgrading a Mailman installation that has an earlier version of the the Mailman-htdig integration patch than that installed by <code>htdig-2.1.1-0.2.patch</code> or later, you need to make some changes to that installation: 
++</p>
++<ol>
++	<li>
++		You must delete from your file system the symbolic link named by the <code>HTDIG_MAILMAN_LINK</code> Mailman configuration variable. This link previously gave htdig programs access to per list htdig configuration files. This is now done by other means and the symlink allows a security exploit that prejudices the privacy of list archives. 
++	</li>
++	<li>
++		You must delete the <code>HTDIG_MAILMAN_LINK</code> Mailman configuration variable from the <code>$prefix/Mailman/mm-cfg.py</code> file. 
++	</li>
++</ol>
++<p>
++	These changes are in addition to the normal installation instructions given below. Having configured and installed the newly patched version of Mailman you must: 
++</p>
++<ol>
++	<li>
++		Run the script <code>$prefix/bin/blow_away_htdig</code> with the <code>-c</code> option to rebuild per-list htdig conf files and delete existing per-list search indexes. 
++	</li>
++	<li>
++		Run the <code>$prefix/cron/nightly_htdig</code> script from the command line to rebuild per-list search indexes using the revised per-list htdig conf files just created by <code>blow_away_htdig</code>. 
++	</li>
++</ol>
++<h3><a id="redhat7">Redhat 7.1 and 7.2 installations</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	If you install htdig from the htdig-3.2.0 binary rpm of RH7.1/2 Binary CD 1 of 2 you also have to install the htdig-web-3.2.0 binary rpm. This may be from RH 7.1/2 Binary CD 2 of 2 or CD 1 of 2 depending on whether you are using actual CDs or downloaded CD images. 
++</p>
++<h3><a id="apachehtdig">Apache/htdig issues</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<p>
++	htdig's graphics file must be accessible via you web server and the Mailman configuration variable <code>HTDIG_FILES_URL</code> setup accordingly. Depending on how you install htdig and Apache you may need to add <code>Alias</code> and/or <code>ScriptAlias</code> directives to you Apache configuration file to make the htdig components accessible. Check the Apache and htdig documentation. 
++</p>
++<h2><a name="contrib"> Contributors</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> 
++<dl>
++	<dt>
++		Original author and maintainer: 
++	</dt>
++	<dd>
++		Richard Barrett - &lt;r.barrett at openinfo.co.uk&gt; 
++	</dd>
++	<dt>
++		Past bug fixes: 
++	</dt>
++	<dd>
++        <ul>
++            <li>
++                Nigel Metheringham &lt;nigel.metheringham at vdata.co.uk&gt; 
++            </li>
++            <li>
++                Stephan Berndts &lt;stb-mm at spline.de&gt; 
++            </li>
++        </ul>
++	</dd>
++	<dt>
++		Testers: 
++	</dt>
++	<dd>
++		<ul>
++			<li>
++				Mark T. Valites &lt;valites at geneseo.edu&gt; 
++			</li>
++			<li>
++				Rehan van der Merwe &lt;rehan at nha.co.za&gt; 
++			</li>
++		</ul>
++	</dd>
++</dl>
++<h2><a name="history"> History</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> <h3><a name="compat"> Compatibility</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<table border="1">
++	<tr valign="top">
++		<th width="50%">
++			Version of patch 
++		</th>
++		<th width="50%">
++			Version of Mailman 
++		</th>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.5-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.5 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.4-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.4 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.3-0.5.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.3-0.4.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.3-0.3.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.3-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.3-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.2-0.4.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.2 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.2-0.3.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.2 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.2-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.2 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.2-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.2 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.1-0.5.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.1-0.4.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.1-0.3.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.1-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1.1-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1-0.3.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b6-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b6 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b5-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b5 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b4-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b4 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b3-0.3.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b3-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b3-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b3 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.1b2-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.1b2 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.13-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.13 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.13-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.13 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.12-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.12 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.11-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.11 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.10-0.2.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.10 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.10-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.10 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.9-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.9 
++		</td>
++	</tr>
++	<tr>
++		<td>
++			<code>htdig-2.0.8-0.1.patch</code> 
++		</td>
++		<td>
++			Mailman 2.0.8, 2.0.7, 2.0.6 and probably 2.0.3, 2.0.4 and 2.0.5 
++		</td>
++	</tr>
++</table>
++<h3><a id="changes">Changes</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h3> 
++<dl>
++    <dt>
++		<code>htdig-2.1.5-0.1.patch:</code> 
++	</dt>
++    <dd>
++        <ol>
++            <li>
++                updated patch for MM 2.1.5 compatibility.
++            </li>
++            <li>
++                Note: the templates in <code>$build/templates/&lt;lang&gt;/</code>for the following languages are NOT modified by this patch or by its precursor indexing patch: <code>ca, eu, sr, sv</code><br>
++                The following files in a language's default template directory should be modified per the changes made to the <code>en</code> language templates after installation of this patch if that other language is used ;'
++                <ul>
++                    <li><code>templates/&lt;lang&gt;/archidxfoot.html</code></li>
++                    <li><code>templates/&lt;lang&gt;/archidxhead.html</code></li>
++                    <li><code>templates/&lt;lang&gt;/archtoc.html</code></li>
++                    <li><code>templates/&lt;lang&gt;/archtocentry.html</code></li>
++                    <li><code>templates/&lt;lang&gt;/archtocnombox.html</code></li>
++                    <li><code>templates/&lt;lang&gt;/article.html</code></li>
++                </ul>
++            </li>
++        </ol>
++	</dd>
++    <dt>
++		<code>htdig-2.1.4-0.1.patch:</code> 
++	</dt>
++    <dd>
++        <ol>
++            <li>
++                updated patch for MM 2.1.4 compatibility.
++            </li>
++            <li>
++                removed untranslated versions of <code>htdig.html</code> from per-language directories under <code>$build/templates</code>, with the exception of the default <code>templates/en/</code> directory, that were present in previous versions of this patch.
++            </li>
++        </ol>
++	</dd>
++    <dt>
++		<code>htdig-2.1.3-0.5.patch:</code> 
++	</dt>
++    <dd>
++        <ol>
++            <li>
++                Modified <code>htdig.py</code> and <code>private.py</code>; the security changes introduced by <code>htdig-2.1.3-0.2 patch</code> to these scripts incorrectly  blocked access to the <code>&lt;listname&gt;.mbox/&lt;listname&gt;.mbox</code> file. The <code>O.5</code> revison of the patch corrects this error. This problem and a suggested fix were pointed out to me in a private email by Stephan Berndts &lt;stb-mm at spline.de&gt;
++            </li>
++        </ol>
++	</dd>
++    <dt>
++		<code>htdig-2.1.3-0.4.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++	            Modified <code>htdig.py</code> and introduced <code>htdig.html</code> templates. The changes mean that if the user is challenged for authentication, when the credentials are submitted and accepted, the URL requested which led to the challenge is then presented. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.3-0.3.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Patch documentation layout revised and simplified. 
++			</li>
++			<li>
++				Changes to <code>$prefix/bin/check_perms</code> and <code>$prefix/Mailman/Archiver/HyperArch.py</code> to improve handling of htdig subdirectory permissions if remote htdig is used. End result is the same as with prior patch version in the case of local htdig. 
++			</li>
++			<li>
++				Introduced the <code>HTDIG_STRICT_FILE_PERM</code> Mailman config variable as part of dealing with <code>htsearch</code> access to per-list <code>htdig</code> directories permissions issue when operating with remote htdig. See under the "<a href="#aperms">Apache</a>" heading above. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.3-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				This patch is hopefully the final step in closing security holes in archive access. See the discussion below under the heading <a href="#secsol"> "Archive security problems resolved by <code>htdig-2.1.3-0.2 patch</code>"</a>. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.3-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				updated patch for MM 2.1.3 compatibility. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.2-0.4.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				corrected error in mmsearch.py and remote_mmsearch. This caused a problem if https was being used for accessing the archives as a pattern match to extract the list name was misused. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.2-0.3.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				updates <code>HyperArch.py</code> so htdig related code uses <code>quick_maketext()</code> function instead of the <code>Utils.Maketext()</code> function. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.2-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				corrects stupid error inserted in unpublished <code>htdig-2.1.1-0.5.patch</code> and carried forward into <code>htdig-2.1.2-0.1.patch</code> 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.2-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				updated patch for MM 2.1.2 compatibility 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.1-0.5.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				with previous version the protototype htdig_conf.txt contained an htdig exclude_urls directive for <code>/cgi-bin/</code> and <code>.cgi</code>. If MM is configured so that the URL for accessing the <code>htdig.py</code> cgi wrapper matches these excluded URLS (for instance by running <code>./configure</code> with <code>--with-cgi-ext=".cgi"</code>) then nothing gets indexed by <code>rundig</code>. The revised patch: 
++				<ol type="a">
++					<li>
++						makes the excluded URL configurable through a MM config variable <code>HTDIG_EXCLUDED_URLS</code> which defaults to the old hard-wired value. 
++					</li>
++					<li>
++						when generating a list-specific <code>htdig.conf</code> file a check is made against <code>HTDIG_EXCLUDED_URLS</code> and if anything in it would prevent indexing of the URL for accessing the <code>htdig.py</code> cgi wrapper for that list, it is omitted from the exclude_urls directive in that <code>htdig.conf</code> file. 
++					</li>
++				</ol>
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.1-0.4.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				<code>mmsearch.py</code> and its remote kin <code>remote-mmsearch</code> and <code>mm_search</code> were overly restrictive on the form fields they were willing to accept. Extended the list so that multi-page search results worked. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.1-0.3.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				corrects silly error in raising an excpetion in <code>mmsearch.py</code>. This will only show if there is a problem with <code>mmsearch</code> running the <code>htsearch</code> program. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.1-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				This version corrects a security exploit which allowed a URL to obtain an <code>htsearch</code> results page without the user being authorised to access the list. Any attempt to follows links on the results page were blocked correctly by <code>$prefix/Mailman/htdig.py</code> but there was leakage of private information from the list's search indexes on the page returned by htdig's <code>htsearch</code> CGI program. The exploit is removed by this patch's revisions. The following sections describe the problem, the solution and special actions required when updating a Mailman installation using an earlier version of this patch: 
++				<ol type="a">
++					<li>
++						<a href="#secprob">Private archive security problem prior to <code>htdig-2.1.1-0.2.patch</code> version</a>. 
++					</li>
++					<li>
++						<a href="#keepsec">Maintaining private archive security with <code>htdig-2.1.1-0.2.patch</code> version and later</a>. 
++					</li>
++					<li>
++						<a href="#secupgd">Upgrading to <code>htdig-2.1.1-0.2.patch</code> or later from an earlier patch version</a>. 
++					</li>
++				</ol>
++				Note that there is no patch revision to deal with this security problem for MM 2.0.13 or earlier and you should seriously consider updating to MM 2.1.x if you want to implement this security fix. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1.1-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				No functional change. Applies without offset warnings to MM 2.1.1 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1-0.3.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				corrects errors in the way <code>$prefix/Mailman/htdig.py</code> worked out content type of file being returned. 
++			</li>
++			<li>
++				<code>$prefix/Mailman/htdig.py</code> adopts revised method for establishing the default URL introduced in 2.1 and as used in <code>$prefix/Mailman/MailList.py </code> 
++			</li>
++			<li>
++				removed unecessary setup of variable <code>DEFAULT_URL</code> in cron scripts <code>$prefix/cron/remote_nightly_htdig_noshare</code> and <code>$prefix/cron/remote_nightly_htdig.pl</code> 
++			</li>
++			<li>
++				Changes references to <code>DEFAULT_URL</code> in this document to <code>DEFAULT_URL_PATTERN</code>. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				improved content type and security handling in <code>$prefix/Mailman/htdig.py</code>. Fixes bug with <code>htdig.py</code> and problem of interaction with bug in <code>$prefix/scripts/driver</code> script (see patch #668685 for more details) 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Reworked patch for compatibility with MM 2.1. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b6-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Reworked patch for compatibility with MM 2.1b6. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b5-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Reworked patch for compatibility with MM 2.1b5. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b4-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Reworked patch for compatibility with MM 2.1b4. As a consequence, the remainder of the mailman-htdig integration templates that were strings declared in <code>Mailman/Archiver/HyperArch.py</code> have been extracted into files under the templates directory. Edit these with care if you must. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b3-0.3.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Removed unecessary code dependency on Python 2.2 file() function 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b3-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Removed syntax error in <code>htdig-2.1b3-0.1.patch</code> which showed up as logged errors in the operation of the ArchRunner qrunner at line 721 of <code>HyperArch.py</code> 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b3-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Reworked patch for compatibility with MM 2.1b3 
++			</li>
++			<li>
++				Removed non-English language template files which were acting as placeholders until someone actually translated them. 
++			</li>
++			<li>
++				Removed <code>updateTOC.py</code> and replaced it with an alternate mechanism in a patch to <code>$prefix/Mailma/Queue/ArchRunner.py</code> to update list TOC page after reindexing by htdig. This new method is only exercised when the <code>remote_nightly_htdig</code> series of cron scripts are used. 
++			</li>
++			<li>
++				Changes to <code>remote_nightly_htdig</code> series of cron scripts to reflect demise of <code>updateTOC</code> cgi script. 
++			</li>
++			<li>
++				Multiple instances of code hygiene and conformance to MM "standards" cleanup. 
++			</li>
++			<li>
++				Tidied up this documentation. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.1b2-0.1.patch: </code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				reworked patch for compatibility with MM 2.1b2 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.13-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Added license header 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.13-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Rebuilt patch to get no-comment application on Mailman 2.0.13 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.12-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Rebuilt patch to get no-comment application on Mailman 2.0.12 
++			</li>
++			<li>
++				Added <code>HTDIG_EXTRAS</code> xonfig variable to allow arbitrary htdig configuration parameters to be specified for addition to every <code>htdig.conf</code> file created i.e. site wide additions. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.11-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				No substantive change. Simply rebuilt patch to get no-comment application on Mailman 2.0.11 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.10-0.2.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				Python 2.2 compatibility fixes to <code>nightly_htdig</code> cron script and its relatives. Doing <code>import *</code> inside a function removed. 
++			</li>
++			<li>
++				Added note on potential problems with htdig and file permissions. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.10-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				change in <code>src/Makefile.in</code> to get clean patch application to MM 2.0.10 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.9-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				minor cosmetic changes to get clean patch application to MM 2.0.9 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.8-0.1.patch:</code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				resolves a problem with the integration of htdig when the <code>web_page_url</code> for a list, which is usually the same as <code>DEFAULT_URL</code> from either <code>$prefix/Mailman/Defaults.py</code> or <code>$prefix/Mailman/mm_cfg.py</code>, when it doesn't use the http addressing scheme. This arises because htdig will only build indices if the URLs for pages use the http addressing scheme. There is a work-around for this problem posted in htdig's mail archives - see the copy in <a href="#app1">Appendix 1</a> to this document. 
++			</li>
++			<li>
++				This patch revision implements the solution documented in that e-mail. If non-http URLs are used by the <code>web_page_url</code> of a list an additional htdig configuration file for use by htsearch is generated. 
++			</li>
++			<li>
++				In all other respects the operation of the Mailman-htdig integration remains unchanged. There is no benefit in upgrading to this revised patch unless you need to use other than http addressing in your DEFAULT_URL or set other than http addressing in the <code>web_page_url</code> configuration of any of your lists. 
++			</li>
++			<li>
++				If changing to or from a non-http addressing scheme then the per list htdig config files of the lists affected and their associated htdig indices must be reconstructed. See the section below entitled <a href="#achange">"Changing the Addressing Scheme of your web_page_url"</a> for details of how to do this. 
++			</li>
++		</ol>
++	</dd>
++	<dt>
++		<code>htdig-2.0.6-0.3.patch: </code> 
++	</dt>
++	<dd>
++		<ol>
++			<li>
++				adds support for remote htdig, that is: running htdig on a different system to Mailman. 
++			</li>
++			<li>
++				enhances the configurability of the integration. Some of the programmed assumptions made in previous versions are now configurable in <code>mm_cfg.py</code>. The configuration variables concerned default to the previous fixed values so that this version is backwards compatible with earlier versions. 
++			</li>
++			<li>
++				does some minor cosmetic code changes. 
++			</li>
++			<li>
++				extends the associated documentation. 
++			</li>
++		</ol>
++	</dd>
++</dl>
++<h2><a name="appendices"> Appendices</a>&nbsp;<a href="#toc">[&nbsp;toc&nbsp;]</a></h2> <h3><a name="app1"> Appendix 1 -Technique for htdigging when Mailman's web_page_url uses the https scheme</a></h3> <pre>
++A technique for htdigging when Mailman's web_page_url uses the https 
++addressing scheme is described in this archived e-mail: 
++http://www.htdig.org/mail/1999/10/0187.html
++
++The text of that e-mail is as follows:
++
++[htdig] Re: Help about htdig indexing https files
++
++------------------------------------------------------------------------
++Gilles Detillieux (grdetil at scrc.umanitoba.ca)
++Wed, 27 Oct 1999 10:18:31 -0500 (CDT) 
++
++
++Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] 
++Next message: Avi Rappoport: "[htdig] indexing SSL (was: Help building 
++the database)" 
++Previous message: Gilles Detillieux: "Re: Fw: [htdig] mutiple search 
++results" 
++In reply to: Torsten Neuer: "Re: Fw: [htdig] mutiple search results" 
++
++------------------------------------------------------------------------
++According to Edouard DESSIOUX: 
++&gt; &gt;Currently, htdig will not support URLs that begin with https://, even
++&gt; &gt;when using local_urls to bypass the server. A trick that might work 
++&gt; &gt;would be to index using http:// instead, but use local_urls to point 
++&gt; &gt;to the directory that contains the contents of the secure server. 
++&gt; 
++&gt; I used that, and now, when i use htsearch, it work, except the fact 
++&gt; that all my URL are http://x.y.z/ instead of https://x.y.z/ 
++&gt; 
++&gt; &gt;You'd need to use separate 
++&gt; &gt;configuration files for digging and searching, and use 
++&gt; &gt;url_part_aliases in each of these configuration files to rewrite the 
++&gt; &gt;http:// into https:// in the search results. 
++&gt; 
++&gt; This is the part i dont understand, and i would like you to explain. 
++
++
++It basically works as a search and replace. One url_part_aliases in the 
++configuration file used by htdig maps the http://x.y.z/ into some 
++special code like "*site", and another url_part_aliases in the 
++configuration file used by htsearch maps the "*site" back into the value 
++you want, i.e. https://x.y.z/. The substitution is left to right in 
++htdig, and right to left in htsearch. So, if you use the same config 
++file for both, or the same setting for both, you get back what you 
++started with (but saved some space in the database because of the 
++encoding). However, if you use two separate config files with different 
++url_part_aliases setting for htdig and htsearch, you can remap parts of 
++URLs from one substring to another. 
++
++
++I hope this makes things clearer. I thought the current description at 
++http://www.htdig.org/attrs.html#url_part_aliases was already quite 
++clear. 
++
++
++
++-- 
++Gilles R. Detillieux              E-mail: &lt;[email-masked]&gt;
++Spinal Cord Research Centre       WWW:    
++http://www.scrc.umanitoba.ca/~grdetil
++Dept. Physiology, U. of Manitoba  Phone:  (204)789-3766
++Winnipeg, MB  R3E 3J7  (Canada)   Fax:    (204)789-3930
++------------------------------------</pre> 
++</body>
++</html>
+diff -Nru mailman-2.1.5/Mailman/Archiver/HyperArch.py mailman-2.1.5+htdig/Mailman/Archiver/HyperArch.py
+--- mailman-2.1.5/Mailman/Archiver/HyperArch.py	2003-12-26 21:41:30.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Archiver/HyperArch.py	2005-07-04 10:04:30.270416120 +0200
+@@ -29,10 +29,14 @@
+ 
+ import sys
+ import re
++import string
+ import errno
+ import urllib
++import urlparse
+ import time
+ import os
++from stat import *
++import errno
+ import types
+ import HyperDatabase
+ import pipermail
+@@ -603,6 +607,9 @@
+         self.lang = maillist.preferred_language
+         self.charset = Utils.GetCharSet(maillist.preferred_language)
+ 
++        if mm_cfg.USE_HTDIG:
++            self.setup_htdig()
++
+         if hasattr(self.maillist,'archive_volume_frequency'):
+             if self.maillist.archive_volume_frequency == 0:
+                 self.ARCHIVE_PERIOD='year'
+@@ -713,7 +720,7 @@
+              "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
+              "fullarch": '../%s.mbox/%s.mbox' % (listname, listname),
+              "size": sizeof(mbox, mlist.preferred_language),
+-             'meta': '',
++             'meta': '', "htsearch": '',
+              }
+         # Avoid i18n side-effects
+         otrans = i18n.get_translation()
+@@ -734,6 +741,30 @@
+                 d["archive_listing_end"] = quick_maketext(
+                     'archlistend.html',
+                     mlist=mlist)
++                if mm_cfg.USE_HTDIG:
++                    list_htdig_dir = os.path.join(self.maillist.archive_dir(),  
++                                                  'htdig')
++                    rundig_file = os.path.join(list_htdig_dir, 'rundig_last_run')
++                    try:
++                        last_rundig_mtime = os.stat(rundig_file)[ST_MTIME]
++                        lastrun = time.strftime("%A, %d %b %Y %H:%M:%S %Z",        
++                                    time.localtime(last_rundig_mtime))
++                    except OSError, e:
++                        if e.errno <> errno.ENOENT: raise
++                        lastrun = '[has yet to be built for this new list]'
++                    h = {"listname": self.maillist.internal_name(),
++                         "mmsearchcgi": mlist.GetScriptURL('mmsearch', absolute=1),
++                         "lastrun": lastrun,
++                         "htsearchconf": '',
++                        }
++                    conf_name_search = self.maillist.internal_name() + \
++                               '.htsearch.conf'
++                    conf_file_search = os.path.join(list_htdig_dir, 
++                                    conf_name_search)
++                    if os.path.exists(conf_file_search):
++                        h['htsearchconf'] = '.htsearch'
++                    d["htsearch"] = quick_maketext('TOC_htsearch.html', dict=h,
++                                                    mlist=self.maillist)
+ 
+                 accum = []
+                 for a in self.archives:
+@@ -784,6 +815,131 @@
+              },
+             mlist=self.maillist)
+ 
++    def remove_htdig(self, indices_only):
++        list_htdig_dir = os.path.join(self.maillist.archive_dir(), 'htdig')
++        if not os.path.exists(list_htdig_dir):
++            return
++        conf_name_dig = self.maillist.internal_name() + '.conf'
++        conf_file_dig = os.path.join(list_htdig_dir, conf_name_dig)
++        conf_name_search = self.maillist.internal_name() + '.htsearch.conf'
++        conf_file_search = os.path.join(list_htdig_dir, conf_name_search)
++        dual_conf_files = None
++        if os.path.exists(conf_file_search):
++            dual_conf_files = 1
++        if indices_only:
++            cfd = open(conf_file_dig, 'r')
++            conf_data_dig = cfd.readlines()
++            cfd.close()
++            if dual_conf_files:
++                cfd = open(conf_file_search, 'r')
++                conf_data_search = cfd.readlines()
++                cfd.close()
++            os.system('rm -rf ' + list_htdig_dir + '/*')            
++            cfd = open(conf_file_dig, 'w')
++            cfd.writelines(conf_data_dig)
++            cfd.close()
++            if dual_conf_files:
++                cfd = open(conf_file_search, 'w')
++                cfd.writelines(conf_data_search)
++                cfd.close()
++        else:
++            os.system('rm -rf ' + list_htdig_dir)
++            conf_file_link_dig = os.path.join(mm_cfg.HTDIG_CONF_LINK_DIR, conf_name_dig)
++            os.unlink(conf_file_link_dig)
++            if dual_conf_files:
++                conf_file_link_search = os.path.join(mm_cfg.HTDIG_CONF_LINK_DIR, conf_name_search)
++                os.unlink(conf_file_link_search)
++
++    def setup_htdig(self):
++        listname = self.maillist.internal_name()
++        # we want to make a directory to put the mail list's htdig stuff in
++        list_htdig_dir = os.path.join(self.maillist.archive_dir(), 'htdig')
++        hperm = 02775
++        if mm_cfg.HTDIG_STRICT_FILE_PERM:
++            hperm = 02770
++        # but we bug out if this has already been done
++        try:
++            os.mkdir(list_htdig_dir, hperm)
++        except OSError, e:
++            if e.errno <> errno.EEXIST: raise
++            return
++        # assemble the mapping for characterising the htdig config
++        htdigfiles = mm_cfg.HTDIG_FILES_URL
++        if mm_cfg.HTDIG_FILES_URL[-1] == '/':
++            htdigfile = htdigfiles[:-1]
++        d = {'databases': list_htdig_dir,
++             "filepath": self.maillist.archive_dir() + '/',
++             "maintainer": Utils.get_site_email(),
++             "indexing_enable": mm_cfg.ARCHIVE_INDEXING_ENABLE,
++             "indexing_disable": mm_cfg.ARCHIVE_INDEXING_DISABLE,
++             "htdig_url": htdigfiles,
++             "htdig_extras": mm_cfg.HTDIG_EXTRAS,
++             "mmsearchcgi": self.maillist.GetScriptURL('mmsearch', absolute=1),
++            }
++        # we need to changes paths to be relative to file system of
++        # remote machine if we are not running htdig on mailman machine
++        if mm_cfg.REMOTE_HTDIG:
++            d['filepath'] = os.path.join(
++                                       mm_cfg.REMOTE_PRIVATE_ARCHIVE_FILE_DIR,
++                                       listname + '/')
++            d['databases'] = os.path.join(d['filepath'], 'htdig')
++        # now the URL through which htdig access to the pipermail data will go
++        starturl_dig = self.maillist.GetScriptURL('htdig') + '/'
++        starturl_search = starturl_dig
++        # we need to know if the addressing scheme for the URL as htdig cannot
++        # cope with other than http (https for instance) when building indices
++        # we'll need different conf files for htdig and htsearch in that case
++        dual_conf_files = None
++        urlbits = urlparse.urlparse(starturl_dig)
++        if urlbits[0] != 'http':
++            urlbits = ('http',) + urlbits[1:]
++            starturl_dig = urlparse.urlunparse(urlbits)
++            dual_conf_files = 1
++        # check that the excluded_urls wil not exclude the htdig cgi url
++        excluded_urls = []
++        for exc in mm_cfg.HTDIG_EXCLUDED_URLS.split():
++            if starturl_dig.find(exc) == -1:
++                excluded_urls.append(exc) 
++        d['excluded_urls'] = string.join(excluded_urls)
++        # create htdig config files. we may need one for digging and another
++        # for searching if the addressing scheme is https these config files
++        # are slightly different we'll put the files in the directory we just 
++        # created above
++        conf_name_dig = listname + '.conf'
++        d['url_part_aliases'] = starturl_dig + " *mm-htdig*"
++        d['starturl'] = starturl_dig
++        d['urlpath'] = starturl_dig
++        conf_file_dig = os.path.join(list_htdig_dir, conf_name_dig)
++        fd = open(conf_file_dig, 'w')
++        fd.write(quick_maketext('htdig_conf.txt', dict=d, mlist=self.maillist))
++        fd.close()
++        # we need symlinks so that htdig will be able to find the config files
++        conf_file_link_dig = os.path.join(mm_cfg.HTDIG_CONF_LINK_DIR, 
++                                          conf_name_dig)
++        try:
++            os.unlink(conf_file_link_dig)
++        except OSError, e:
++            if e.errno <> errno.ENOENT: raise
++        os.symlink(conf_file_dig, conf_file_link_dig)
++        # make the second conf file and link to it for htsearch if necessary 
++        if dual_conf_files:
++            conf_name_search = listname + '.htsearch.conf'
++            d['url_part_aliases'] = starturl_search + " *mm-htdig*"
++            d['starturl'] = starturl_search
++            d['urlpath'] = starturl_search
++            conf_file_search = os.path.join(list_htdig_dir, conf_name_search)
++            fd = open(conf_file_search, 'w')
++            fd.write(quick_maketext('htdig_conf.txt', dict=d, 
++                                    mlist=self.maillist))
++            fd.close()
++            conf_file_link_search = os.path.join(mm_cfg.HTDIG_CONF_LINK_DIR, 
++                                                 conf_name_search)
++            try:
++                os.unlink(conf_file_link_search)
++            except OSError, e:
++                if e.errno <> errno.ENOENT: raise
++            os.symlink(conf_file_search, conf_file_link_search)
++
+     def GetArchLock(self):
+         if self._lock_file:
+             return 1
+diff -Nru mailman-2.1.5/Mailman/Cgi/htdig.py mailman-2.1.5+htdig/Mailman/Cgi/htdig.py
+--- mailman-2.1.5/Mailman/Cgi/htdig.py	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Cgi/htdig.py	2005-07-04 10:04:30.272415816 +0200
+@@ -0,0 +1,194 @@
++# Copyright (C) 1998-2003 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++"""Provide a password-interface wrapper around private archives.
++"""
++
++import os
++import sys
++import cgi
++import mimetypes
++import re
++import string
++
++from Mailman import mm_cfg
++from Mailman import Utils
++from Mailman import MailList
++from Mailman import Errors
++from Mailman import i18n
++from Mailman.htmlformat import *
++from Mailman.Logging.Syslog import syslog
++
++# Set up i18n.  Until we know which list is being requested, we use the
++# server's default.
++_ = i18n._
++i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
++
++
++
++def true_path(path):
++    "Ensure that the path is safe by removing .."
++    path = path.replace('../', '')
++    path = path.replace('./', '')
++    return path[1:]
++
++
++
++def guess_type(url, strict):
++    if hasattr(mimetypes, 'common_types'):
++        return mimetypes.guess_type(url, strict)
++    return mimetypes.guess_type(url)
++
++
++
++def main():
++    doc = Document()
++    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
++
++    parts = Utils.GetPathPieces()
++    if not parts:
++        doc.SetTitle(_("Sought (htdig) Archive Error"))
++        doc.AddItem(Header(3, _("You must specify a list.")))
++        print doc.Format()
++        return
++
++    path = os.environ.get('PATH_INFO')
++    # BAW: This needs to be converted to the Site module abstraction
++    true_filename = os.path.join(
++        mm_cfg.PRIVATE_ARCHIVE_FILE_DIR,
++        true_path(path))
++
++    listname = parts[0].lower()
++    mboxfile = ''
++    if len(parts) == 2:
++        mboxfile = parts[1]
++
++    # See if it's the list's mbox file is being requested
++    if listname.endswith('.mbox') and mboxfile.endswith('.mbox') and \
++           listname[:-5] == mboxfile[:-5]:
++        listname = listname[:-5]
++    else:
++        mboxfile = ''
++
++    # If it's a directory, we have to append index.html in this script.  We
++    # must also check for a gzipped file, because the text archives are
++    # usually stored in compressed form.
++    wasdir = 0
++    if os.path.isdir(true_filename):
++        true_filename = true_filename + '/index.html'
++        wasdir = 1
++    if not os.path.exists(true_filename) and \
++           os.path.exists(true_filename + '.gz'):
++        true_filename = true_filename + '.gz'
++
++    try:
++        mlist = MailList.MailList(listname, lock=0)
++    except Errors.MMListError, e:
++        # Avoid cross-site scripting attacks
++        safelistname = Utils.websafe(listname)
++        msg = _('No such list <em>%(safelistname)s</em>')
++        doc.SetTitle(_("Sought (htdig) Archive Error - %(msg)s"))
++        doc.AddItem(Header(2, msg))
++        print doc.Format()
++        syslog('error', 'No such list "%s": %s\n', listname, e)
++        return
++
++    # If the path is not:
++    #  <list name>.mbox/<list name>.mbox
++    # it should conform to:
++    #  <list name>/<archive name (but not htdig or database)>/...
++    #  <list name>/<file_name which must end in .txt, .txt.gz or .html>
++    #  and any filenames starting with '.' are also not allowed
++    num_parts = len(parts)
++    if not mboxfile and num_parts > 1 and \
++       (parts[1] in ('database', 'htdig') or \
++        (num_parts == 2 and \
++          not re.compile(r'\.(html|txt|txt\.gz)$').search(true_filename) \
++        ) or parts[-1][0] == '.' \
++       ):
++        msg = _('Invalid archive file requested')
++        doc.SetTitle(msg)
++        doc.AddItem(Header(2, msg))
++        print doc.Format()
++        syslog('error', 'Invalid archive file requested: %s', true_filename)
++        return
++
++    i18n.set_language(mlist.preferred_language)
++    doc.set_language(mlist.preferred_language)
++
++    if mlist.archive_private:
++        message = ''
++        cgidata = cgi.FieldStorage()
++        username = cgidata.getvalue('username', '')
++        password = cgidata.getvalue('password', '')
++
++        if not mlist.WebAuthenticate((mm_cfg.AuthUser,
++                                      mm_cfg.AuthListModerator,
++                                      mm_cfg.AuthListAdmin,
++                                      mm_cfg.AuthSiteAdmin),
++                                     password, username):
++            if cgidata.has_key('submit'):
++                # This is a re-authorization attempt
++                message = Bold(FontSize('+1', _('Authorization failed.'))).Format()
++            # Output the password form
++            charset = Utils.GetCharSet(mlist.preferred_language)
++            print 'Content-type: text/html; charset=' + charset + '\n\n'
++            while path and path[0] == '/':
++                path=path[1:]  # Remove leading /'s
++            # Bring them back to the same point when they login
++            actionURL = mlist.GetScriptURL('htdig', absolute=1)
++            mbox_extra_bit = ''
++            if mboxfile:
++                mbox_extra_bit = '.mbox'
++            if len(parts) > 1:
++                actionURL = actionURL + mbox_extra_bit + '/' + string.join(parts[1:], '/')
++            if wasdir:
++                actionURL = actionURL + '/index.html'
++            print Utils.maketext(
++                'htdig.html',
++                {'action'  : actionURL,
++                 'realname': mlist.real_name,
++                 'message' : message,
++                }, mlist=mlist)
++            return
++        lang = mlist.getMemberLanguage(username)
++        i18n.set_language(lang)
++        doc.set_language(lang)
++
++    # Authorization confirmed... output the desired file
++    try:
++        ctype, enc = guess_type(path, strict=0)
++        if ctype is None:
++            ctype = 'text/html'
++        if mboxfile:
++            f = open(os.path.join(mlist.archive_dir() + '.mbox',
++                                  mlist.internal_name() + '.mbox'))
++            ctype = 'text/plain'
++        elif true_filename.endswith('.gz'):
++            import gzip
++            f = gzip.open(true_filename, 'r')
++        else:
++            f = open(true_filename, 'r')
++    except IOError:
++        msg = _('Sought (htdig) archive file not found')
++        doc.SetTitle(msg)
++        doc.AddItem(Header(2, msg))
++        print doc.Format()
++        syslog('error', 'Sought (htdig) archive file not found: %s', true_filename)
++    else:
++        print 'Content-type: %s\n' % ctype
++        sys.stdout.write(f.read())
++        f.close()
+diff -Nru mailman-2.1.5/Mailman/Cgi/mmsearch.py mailman-2.1.5+htdig/Mailman/Cgi/mmsearch.py
+--- mailman-2.1.5/Mailman/Cgi/mmsearch.py	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Cgi/mmsearch.py	2005-07-04 10:04:30.273415664 +0200
+@@ -0,0 +1,228 @@
++# Copyright (C) 2003 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++"""Provide an authentication wrapper around htdig's htsearch.
++
++In order to search a list's archive the HTTP request must present a valid 
++cookie authorizing access to the list's archives for private archives. 
++This cookie must be obtained by the same process as the user must 
++adopt for accessing the archive via the private.py script.
++
++The basic premise is that htsearch cannot reach a list's htdig conf file
++unless this script enhances the environment in which htsearch runs to
++provide access to a list's htdig conf file.
++
++If the use authenticates OK for a private archive, or the archive is public,
++this script:
++
++a. in the case of local htdig, this script enhances the environment with 
++'CONFIG-DIR' pointing to MM's list htdig conf files, and runs htsearch.
++
++b. in the case of remote htdig, this script performs a HTTP request to a
++companion CGI script running on the htdig machine. This request can of
++course be forged easily. The only protection available is the the companion
++script can optionaaly check the IP number from which requests to it are made
++and reject them if they do not come from the MM server.
++"""
++
++import sys
++import os
++import cgi
++import re
++import popen2
++import exceptions
++import types
++import httplib
++import urllib
++import urlparse
++
++from Mailman import mm_cfg
++from Mailman import Utils
++from Mailman import MailList
++from Mailman import Errors
++from Mailman import i18n
++from Mailman.htmlformat import *
++from Mailman.Logging.Syslog import syslog
++
++
++# Set up i18n.  Until we know which list is being requested, we use the
++# server's default.
++_ = i18n._
++i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
++
++errors = {'cgi': _('CGI problem.'),
++          'info': _('Path info.'),
++          'list': _('The requested list cannot be accessed.'),
++          'htsearch': _('search failed'),
++          'auth': Utils.maketext('htdig_auth_failure.html', dict=None, raw=0)
++         }
++
++class _search_exception(exceptions.Exception):
++    
++    def __init__(self, listname, reason, detail):
++        self.listname = listname
++        self.reason = reason 
++        self.detail = detail
++
++    def __str__(self):
++        return 'listname: %s, reason: %s, detail: %s' % (self.listname, self.reason, self.detail)
++
++
++def true_path(path):
++    "Ensure that the path is safe by removing .."
++    path = path.replace("../", "")
++    path = path.replace("./", "")
++    return path[1:]
++
++def make_inserts(listname):
++    urlbase =  mm_cfg.DEFAULT_URL or \
++               mm_cfg.DEFAULT_URL_PATTERN % mm_cfg.DEFAULT_URL_HOST
++    return {
++            'mailto': Utils.get_site_email(),
++            'listinfo_link': urlbase + '/listinfo/' + listname,
++            'referer': os.environ.get('HTTP_REFERER', _('Referer not known')),
++            'uri': os.environ.get('REQUEST_URI', _('URI not known')),
++           }
++
++def error_quit(why):
++    d = make_inserts(why.listname)
++    d['error'] = errors[why.reason] + ' ' + why.detail
++    charset = Utils.GetCharSet(mm_cfg.DEFAULT_SERVER_LANGUAGE)
++    stuff = 'Content-type: text/html; charset=' + charset + '\n\n'
++    stuff += Utils.maketext('htdig_access_error.html', dict=d, 
++                         lang=mm_cfg.DEFAULT_SERVER_LANGUAGE)
++    print stuff
++    syslog('error', "htsearch for list: %s, cause: %s, detail: %s" % \
++           (why.listname, why.reason, why.detail))
++    sys.exit(0)
++
++_required_fields = ('method',
++                    'format',
++                    'sort',
++                    'config',
++                   )
++
++_allowed_fields = {'method': 0,
++                   'format': 0,
++                   'sort': 0,
++                   'config': 1,
++                   'words': 0,
++                   'submit': 0,
++                   'restrict': 0,
++                   'exclude': 0,
++                   'page': 0,
++                  }
++
++def check_params(listname, fs, detail):
++    detail = detail + ' fields: ' + ','.join(fs.keys())
++    for fieldname in _required_fields:
++        if not fs.has_key(fieldname):
++            raise _search_exception(listname, 'cgi',  '-5-' + detail)
++    fieldhash = {}
++    for fieldname in fs.keys():
++        if not _allowed_fields.has_key(fieldname):
++            raise _search_exception(listname, 'cgi', '-6- ' + detail)
++        if  type(fs[fieldname]) is types.ListType:
++            raise _search_exception(listname, 'cgi', '-8- ' + detail)        
++        fieldhash[fieldname] = fs[fieldname].value
++    return urllib.urlencode(fieldhash)
++
++_extract_listname_pat = re.compile(r'^([^\.]+)(|\.htsearch)$')
++	
++def main():
++    try:
++        try:
++            request_method = os.environ['REQUEST_METHOD']
++            form = cgi.FieldStorage()
++        except:
++            raise _search_exception('', 'cgi', 'No list -1-')
++        list_info = Utils.GetPathPieces()
++        if not list_info or len(list_info) != 1:
++            raise _search_exception('', 'info', 'No list -2-')
++        path_listname = list_info[0].lower()
++        # Check right number of expected fields and get them
++        # url encoded
++        params = check_params(path_listname, form, 'Field count -4-')
++        # Extract the listname from the form
++        lnm = _extract_listname_pat.match(form['config'].value)
++        if not lnm:
++            raise _search_exception('', 'list', 'No list -3-')
++        listname = lnm.group(1)
++        # Access the list OK?
++        if path_listname != listname:
++            raise _search_exception(listname, 'list', '%s:%s' % (path_listname, listname))
++        try:
++            mlist = MailList.MailList(listname, lock=0)
++        except:
++            raise _search_exception(listname, 'list', '-11-')
++        # We only need to authorize the user if it's a private archive 
++        if mlist.archive_private:
++            if not mlist.WebAuthenticate((mm_cfg.AuthUser,
++                                             mm_cfg.AuthListModerator,
++                                             mm_cfg.AuthListAdmin,
++                                             mm_cfg.AuthSiteAdmin),
++                                            '', ''):
++                raise _search_exception(listname, 'auth', '-10-')
++        if mm_cfg.REMOTE_HTDIG:
++            #  We are going to do an HTTP request to the server that is
++            # running htsearch and then return the response.
++            headers = {"Content-type": "application/x-www-form-urlencoded",
++                       "Accept": "text/plain, text/html"}
++            urlbits = urlparse.urlsplit(mm_cfg.REMOTE_MMSEARCH_URL)
++            hostbit = urlbits[1]
++            uribit = urlbits[2] + '/' + listname
++            conn = httplib.HTTPConnection(hostbit)
++            conn.request("POST", uribit, params, headers)
++            response = conn.getresponse()
++            if response.status == 200:
++                ctype = response.getheader('Content-type', 'text/html')
++                print "Content-type: %s\n\n" % ctype
++                print response.read()
++                conn.close()
++            else:
++                syslog('error', "remote htsearch failed, url: %s, response code: %d" % \
++                       (mm_cfg.REMOTE_MMSEARCH_URL, response.status))
++                conn.close()
++                raise _search_exception(listname, 'cgi', 
++                                        ' -9- %d' % response.status)
++        else:
++            # We are going to execute htsearch and return its response.
++            # We need to let htsearch get at the list specific htdig
++            # conf file
++            os.environ['CONFIG_DIR'] = mm_cfg.HTDIG_CONF_LINK_DIR
++            cmd = "%s" % mm_cfg.HTDIG_HTSEARCH_PATH
++            child = popen2.Popen3(cmd)
++            if request_method == 'POST':
++                os.environ['CONTENT_LENGTH'] = str(len(params))
++                child.tochild.write(params)
++            child.tochild.close()
++            response = ''
++            while (1):
++                data = child.fromchild.read()
++                if data == "": 
++                    break
++                response += data
++            exitstatus = child.wait()
++            exitstatus = (exitstatus >> 8) & 0xff
++            if exitstatus:
++                syslog('error', "htsearch for list: %s, existatus: %s" % \
++                       (listname, str(exitstatus)))
++            if not response:
++                raise _search_exception(listname, 'htsearch', '-12-') 
++            print response
++    except _search_exception, e:
++        error_quit(e)
++    sys.exit(0)
+diff -Nru mailman-2.1.5/Mailman/Cgi/private.py mailman-2.1.5+htdig/Mailman/Cgi/private.py
+--- mailman-2.1.5/Mailman/Cgi/private.py	2005-07-04 10:07:01.542419280 +0200
++++ mailman-2.1.5+htdig/Mailman/Cgi/private.py	2005-07-04 10:04:30.273415664 +0200
+@@ -21,6 +21,7 @@
+ import sys
+ import cgi
+ import mimetypes
++import re
+ 
+ from Mailman import mm_cfg
+ from Mailman import Utils
+@@ -69,7 +70,7 @@
+ 
+     listname = parts[0].lower()
+     mboxfile = ''
+-    if len(parts) > 1:
++    if len(parts) == 2:
+         mboxfile = parts[1]
+ 
+     # See if it's the list's mbox file is being requested
+@@ -100,6 +101,26 @@
+         syslog('error', 'No such list "%s": %s\n', listname, e)
+         return
+ 
++    # If the path is not:
++    #  <list name>.mbox/<list name>.mbox
++    # it should conform to:
++    #  <list name>/<archive name (but not htdig or database)>/...
++    #  <list name>/<file_name which must end in .txt, .txt.gz or .html>
++    #  and any filenames starting with '.' are also not allowed
++    num_parts = len(parts)
++    if not mboxfile and num_parts > 1 and \
++       (parts[1] in ('database', 'htdig') or \
++        (num_parts == 2 and \
++          not re.compile(r'\.(html|txt|txt\.gz)$').search(true_filename) \
++        ) or parts[-1][0] == '.' \
++       ):
++        msg = _('Invalid archive file requested')
++        doc.SetTitle(msg)
++        doc.AddItem(Header(2, msg))
++        print doc.Format()
++        syslog('error', 'Invalid archive file requested: %s', true_filename)
++        return
++
+     i18n.set_language(mlist.preferred_language)
+     doc.set_language(mlist.preferred_language)
+ 
+diff -Nru mailman-2.1.5/Mailman/Cgi/private.py.orig mailman-2.1.5+htdig/Mailman/Cgi/private.py.orig
+--- mailman-2.1.5/Mailman/Cgi/private.py.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Cgi/private.py.orig	2005-07-04 10:04:08.207770152 +0200
+@@ -0,0 +1,162 @@
++# Copyright (C) 1998-2003 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++"""Provide a password-interface wrapper around private archives.
++"""
++
++import os
++import sys
++import cgi
++import mimetypes
++
++from Mailman import mm_cfg
++from Mailman import Utils
++from Mailman import MailList
++from Mailman import Errors
++from Mailman import i18n
++from Mailman.htmlformat import *
++from Mailman.Logging.Syslog import syslog
++
++# Set up i18n.  Until we know which list is being requested, we use the
++# server's default.
++_ = i18n._
++i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
++
++
++
++def true_path(path):
++    "Ensure that the path is safe by removing .."
++    parts = [x for x in path.split('/') if x not in ('.', '..')]
++    return '/'.join(parts)[1:]
++
++
++def guess_type(url, strict):
++    if hasattr(mimetypes, 'common_types'):
++        return mimetypes.guess_type(url, strict)
++    return mimetypes.guess_type(url)
++
++
++
++def main():
++    doc = Document()
++    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
++
++    parts = Utils.GetPathPieces()
++    if not parts:
++        doc.SetTitle(_("Private Archive Error"))
++        doc.AddItem(Header(3, _("You must specify a list.")))
++        print doc.Format()
++        return
++
++    path = os.environ.get('PATH_INFO')
++    # BAW: This needs to be converted to the Site module abstraction
++    true_filename = os.path.join(
++        mm_cfg.PRIVATE_ARCHIVE_FILE_DIR,
++        true_path(path))
++
++    listname = parts[0].lower()
++    mboxfile = ''
++    if len(parts) > 1:
++        mboxfile = parts[1]
++
++    # See if it's the list's mbox file is being requested
++    if listname.endswith('.mbox') and mboxfile.endswith('.mbox') and \
++           listname[:-5] == mboxfile[:-5]:
++        listname = listname[:-5]
++    else:
++        mboxfile = ''
++
++    # If it's a directory, we have to append index.html in this script.  We
++    # must also check for a gzipped file, because the text archives are
++    # usually stored in compressed form.
++    if os.path.isdir(true_filename):
++        true_filename = true_filename + '/index.html'
++    if not os.path.exists(true_filename) and \
++           os.path.exists(true_filename + '.gz'):
++        true_filename = true_filename + '.gz'
++
++    try:
++        mlist = MailList.MailList(listname, lock=0)
++    except Errors.MMListError, e:
++        # Avoid cross-site scripting attacks
++        safelistname = Utils.websafe(listname)
++        msg = _('No such list <em>%(safelistname)s</em>')
++        doc.SetTitle(_("Private Archive Error - %(msg)s"))
++        doc.AddItem(Header(2, msg))
++        print doc.Format()
++        syslog('error', 'No such list "%s": %s\n', listname, e)
++        return
++
++    i18n.set_language(mlist.preferred_language)
++    doc.set_language(mlist.preferred_language)
++
++    cgidata = cgi.FieldStorage()
++    username = cgidata.getvalue('username', '')
++    password = cgidata.getvalue('password', '')
++
++    is_auth = 0
++    realname = mlist.real_name
++    message = ''
++
++    if not mlist.WebAuthenticate((mm_cfg.AuthUser,
++                                  mm_cfg.AuthListModerator,
++                                  mm_cfg.AuthListAdmin,
++                                  mm_cfg.AuthSiteAdmin),
++                                 password, username):
++        if cgidata.has_key('submit'):
++            # This is a re-authorization attempt
++            message = Bold(FontSize('+1', _('Authorization failed.'))).Format()
++        # Output the password form
++        charset = Utils.GetCharSet(mlist.preferred_language)
++        print 'Content-type: text/html; charset=' + charset + '\n\n'
++        while path and path[0] == '/':
++            path=path[1:]  # Remove leading /'s
++        print Utils.maketext(
++            'private.html',
++            {'action'  : mlist.GetScriptURL('private', absolute=1),
++             'realname': mlist.real_name,
++             'message' : message,
++             }, mlist=mlist)
++        return
++
++    lang = mlist.getMemberLanguage(username)
++    i18n.set_language(lang)
++    doc.set_language(lang)
++
++    # Authorization confirmed... output the desired file
++    try:
++        ctype, enc = guess_type(path, strict=0)
++        if ctype is None:
++            ctype = 'text/html'
++        if mboxfile:
++            f = open(os.path.join(mlist.archive_dir() + '.mbox',
++                                  mlist.internal_name() + '.mbox'))
++            ctype = 'text/plain'
++        elif true_filename.endswith('.gz'):
++            import gzip
++            f = gzip.open(true_filename, 'r')
++        else:
++            f = open(true_filename, 'r')
++    except IOError:
++        msg = _('Private archive file not found')
++        doc.SetTitle(msg)
++        doc.AddItem(Header(2, msg))
++        print doc.Format()
++        syslog('error', 'Private archive file not found: %s', true_filename)
++    else:
++        print 'Content-type: %s\n' % ctype
++        sys.stdout.write(f.read())
++        f.close()
+diff -Nru mailman-2.1.5/Mailman/Cgi/remote_mmsearch mailman-2.1.5+htdig/Mailman/Cgi/remote_mmsearch
+--- mailman-2.1.5/Mailman/Cgi/remote_mmsearch	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Cgi/remote_mmsearch	2005-07-04 10:04:30.274415512 +0200
+@@ -0,0 +1,242 @@
++#! /usr/bin/python
++
++# Copyright (C) 2003 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++"""Provide an authentication wrapper around htdig's htsearch when
++it is running on a different machine to Mailman.
++
++This relies on htsearch not normally being able to access per list htdig 
++conf files for list archives without the intervention of this script,
++which inserts a 'CONFIG_DIR' environment variable to enable that acccess.
++
++The security available with this script is limited as it cannot
++consult the user authentication information held by Mailman. Instead
++we rely on the mmsearch CGI script on the Mailman server doing that and 
++then passing the request to this script using an HTTP request. 
++
++The only protection against malicious request to this script is to restrict
++this script to responding only when an HTTP request originates from a machine
++with a particular IP number: e.g. we only allow requests from our 'trusted'
++MM server.
++"""
++
++# Edit the following configuration variables to suit your installation
++#
++# For example:
++#
++#MAILTO = [email-masked]'
++#VALID_IP_LIST = ['192.168.1.111']
++#HTDIG_CONF_LINK_DIR = '/var/lib/mailman/archives/htdig'
++#HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'
++
++MAILTO = ''
++VALID_IP_LIST = []
++HTDIG_CONF_LINK_DIR = ''
++HTDIG_HTSEARCH_PATH = ''
++
++# End of things for you to edit
++
++import sys
++import os
++import cgi
++import re
++import popen2
++import exceptions
++import types
++import httplib
++import urllib
++import urlparse
++
++errors = {'cgi': 'CGI problem.',
++          'info': 'Path info.',
++          'list': 'The requested list cannot be accessed.',
++          'htsearch': 'htearch failed',
++          'auth': 'Authentication failure.',
++         }
++
++class _search_exception(exceptions.Exception):
++    
++    def __init__(self, listname, reason, detail):
++        self.listname = listname
++        self.reason = reason 
++        self.detail = detail
++
++    def __str__(self):
++        return 'listname: %s, reason: %s' % (self.listname, self.reason)
++    	
++
++def true_path(path):
++    "Ensure that the path is safe by removing .."
++    path = path.replace("../", "")
++    path = path.replace("./", "")
++    return path[1:]
++
++def GetPathPieces(envar='PATH_INFO'):
++    path = os.environ.get(envar)
++    if path:
++        return [p for p in path.split('/') if p]
++    return None
++
++def make_inserts(listname):
++    return {
++            'mailto': MAILTO,
++            'listname': listname,
++            'referer': os.environ.get('HTTP_REFERER', 'Referer not known'),
++            'uri': os.environ.get('REQUEST_URI', 'URI not known'),
++           }
++
++def error_quit(why):
++    d = make_inserts(why.listname)
++    d['error'] = errors[why.reason] + ' ' + why.detail
++    print """\
++Content-type: text/html
++
++<HTML>
++<HEAD>
++    <TITLE>htdig Archives Access Failure</TITLE> 
++</HEAD>
++<BODY BGCOLOR="#ffffff">
++<H1>htdig Archives Access Failure</H1> 
++%(error)s
++<P>
++    Searching the archives of list %(listname)s failed.
++</P>
++<P>
++    If this problem persists then please e-mail the following information to the 
++<A HREF="mailto:%(mailto)s">%(mailto)s</A>:
++</P>
++<PRE>
++    %(referer)s
++    %(uri)s
++</PRE>
++<HR>
++</BODY>
++</HTML>
++""" % d
++    sys.exit(0)
++
++_required_fields = ('method',
++                    'format',
++                    'sort',
++                    'config',
++                   )
++
++_allowed_fields = {'method': 0,
++                   'format': 0,
++                   'sort': 0,
++                   'config': 1,
++                   'words': 0,
++                   'submit': 0,
++                   'restrict': 0,
++                   'exclude': 0,
++                   'page': 0,
++                  }
++
++def check_params(listname, fs, detail):
++    detail = detail + ' fields: ' + ','.join(fs.keys())
++    for fieldname in _required_fields:
++        if not fs.has_key(fieldname):
++            raise _search_exception(listname, 'cgi',  '-5-' + detail)
++    fieldhash = {}
++    for fieldname in fs.keys():
++        if not _allowed_fields.has_key(fieldname):
++            raise _search_exception(listname, 'cgi', '-6- ' + detail)
++        if type(fs[fieldname]) is types.ListType:
++            raise _search_exception(listname, 'cgi', '-8- ' + detail)        
++        fieldhash[fieldname] = fs[fieldname].value
++    return urllib.urlencode(fieldhash)
++
++_extract_listname_pat = re.compile(r'^([^\.]+)(|\.htsearch)$')
++	
++def main():
++    try:
++        try:
++            request_method = os.environ['REQUEST_METHOD']
++            form = cgi.FieldStorage()
++        except:
++            raise _search_exception('', 'cgi', 'No list -1-')
++        list_info = GetPathPieces()
++        if not list_info or len(list_info) != 1:
++            raise _search_exception('', 'info', 'No list -2-')
++        path_listname = list_info[0].lower()
++        # Check right number of expected fields and get them
++        # url encoded
++        params = check_params(path_listname, form, 'Field count -4-')
++        # Extract the listname from the form
++        lnm = _extract_listname_pat.match(form['config'].value)
++        if not lnm:
++            raise _search_exception('', 'list', 'No list -3-')
++        listname = lnm.group(1)
++        # Access the list OK?
++        if path_listname != listname:
++            raise _search_exception(listname, 'list', '%s:%s' % \
++                                    (path_listname, listname))
++        # We check to origin IP of the request if restrictions are specified
++        if len(VALID_IP_LIST):
++            try:
++                request_bits = os.environ['REMOTE_ADDR'].split('.')
++                for ip in VALID_IP_LIST:
++                    valid_bits = ip.split('.')
++                    for i in range(4):
++                    	if request_bits[i] != valid_bits[i]: 
++                            break
++                    else:
++                    	break
++                else:
++                    raise _search_exception(listname, 'auth', ' -10- %s' % \
++                                            os.environ['REMOTE_ADDR'])
++            except _search_exception:
++                raise
++            except:
++                raise _search_exception(listname, 'auth', ' -12-')
++        # We are going to call execute htsearch and return its response.
++        # We need to let htsearch get at the list specific htdig
++        # conf file
++        if request_method == 'POST':
++            os.environ['CONTENT_LENGTH'] = str(len(params))
++        else:
++            raise _search_exception(listname, 'auth', ' -11- method')
++        os.environ['CONFIG_DIR'] = HTDIG_CONF_LINK_DIR
++        cmd = HTDIG_HTSEARCH_PATH
++        child = popen2.Popen3(cmd)
++        child.tochild.write(params)
++        child.tochild.close()
++        response = ''
++        while (1):
++            data = child.fromchild.read()
++            if data == "": 
++                break
++            response += data
++        exitstatus = child.wait()
++        exitstatus = (exitstatus >> 8) & 0xff
++        if exitstatus:
++            raise _search_exception(listname, 'htsearch', ' -12-  exit: %d' \
++                                    % existatus, )
++        if not response:
++            raise _search_exception(listname, 'htsearch', ' -13-') 
++        print response
++    except _search_exception, e:
++        error_quit(e)
++    sys.exit(0)
++
++if __name__ == '__main__' and \
++   MAILTO and \
++   os.path.isdir(HTDIG_CONF_LINK_DIR) and \
++   os.access(HTDIG_HTSEARCH_PATH, os.X_OK):
++    main()
++else:
++    error_quit(_search_exception('', 'cgi', '-14- misconfigured'))
+diff -Nru mailman-2.1.5/Mailman/Cgi/remote-mmsearch mailman-2.1.5+htdig/Mailman/Cgi/remote-mmsearch
+--- mailman-2.1.5/Mailman/Cgi/remote-mmsearch	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Cgi/remote-mmsearch	2005-07-04 10:04:30.274415512 +0200
+@@ -0,0 +1,229 @@
++#! /usr/bin/perl
++
++# Copyright (C) 2003 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++my $doc = <<EOT;
++Provide an authentication wrapper around htdig's htsearch when
++it is running on a different machine to Mailman.
++
++This relies on htsearch not normally being able to access per list htdig 
++conf files for list archives without the intervention of this script,
++which inserts a 'CONFIG_DIR' environment variable to enable that acccess.
++
++The security available with this script is limited as it cannot
++consult the user authentication information held by Mailman. Instead
++we rely on the mmsearch CGI script on the Mailman server doing that and 
++then passing the request to this script using an HTTP request. 
++
++The only protection against malicious request to this script is to restrict
++this script to responding only when an HTTP request originates from a machine
++with a particular IP number: e.g. we only allow requests from our 'trusted'
++MM server.
++EOT
++
++# Edit the following configuration variables to suit your installation.
++#
++# For example:
++# 
++#my $MAILTO = [email-masked]';
++#my @VALID_IP_LIST = ('192.168.1.111');
++#my $HTDIG_CONF_LINK_DIR = '/var/lib/mailman/archives/htdig';
++#my $HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch';
++
++my $MAILTO = '';
++my @VALID_IP_LIST = ();
++my $HTDIG_CONF_LINK_DIR = '';
++my $HTDIG_HTSEARCH_PATH = '';
++
++# End of things for you to edit
++
++use CGI;
++use URI::Escape;
++use IPC::Open2;
++
++my %errors = ('cgi' => 'CGI problem.',
++              'info' => 'Path info.',
++              'list' => 'The requested list cannot be accesssed.',
++              'htsearch' => 'htearch failed',
++              'auth' => 'Authentication failure.',
++             );
++
++sub true_path {
++    my $path = shift;
++    $path =~ s/\.\.\///g;
++    $path =~ s/\.\///g;
++    return substr $path, 1;
++}
++
++sub GetPathPieces {
++    my $path = $ENV{'PATH_INFO'};
++    if ($path) {
++        my @pathbits = ();
++        foreach my $bit (split /\//, $path ) {
++            push (@pathbits, $bit) if $bit;
++        }
++        return @pathbits if scalar @pathbits;
++    }
++    return ();
++}
++
++my @required_fields = ('method',
++                       'format',
++                       'sort',
++                       'config',
++                      );
++
++my %allowed_fields = ('method' => 0,
++                      'format' => 0,
++                      'sort' => 0,
++                      'config' => 1,
++                      'words' => 0,
++                      'submit' => 0,
++                      'restrict' => 0,
++                      'exclude' => 0,
++                      'page' => 0,
++                     );
++
++sub error_quit {
++    my ($listname, $reason, $detail)  = @_;
++    my $fault = $errors{$reason} . " $detail";
++    my $mailto = $MAILTO;
++    my $referer = $ENV{'HTTP_REFERER'} ; # 'Referer not known'
++    my $uri = $ENV{'REQUEST_URI'};      # 'URI not known'
++    print <<EOT;
++Content-type: text/html
++
++<HTML>
++<HEAD>
++    <TITLE>htdig Archives Access Failure</TITLE> 
++</HEAD>
++<BODY BGCOLOR="#ffffff">
++<H1>htdig Archives Access Failure</H1> 
++$fault
++<P>
++    Searching the archives of list $listname failed.
++</P>
++<P>
++    If this problem persists then please e-mail the following information to the 
++<A HREF="mailto:$mailto">$mailto</A>:
++</P>
++<PRE>
++    $referer
++    $uri
++</PRE>
++<HR>
++</BODY>
++</HTML>
++EOT
++    exit(0);
++}
++
++sub check_params {
++    my ($listname, $query, $detail) = @_;
++    my @fieldnames = $query->param();
++    $detail = "$detail  fields: " . join(',', @fieldnames);
++    foreach my $fieldname (@required_fields) {
++        if (! $query->param($fieldname)) {
++            error_quit($listname, 'cgi', " -5- $detail");
++        }
++    }
++    my @urlencoded = ();
++    foreach my $fieldname (@fieldnames) {
++        if (! exists $allowed_fields{$fieldname}) {
++            error_quit($listname, 'cgi', "-6- $detail|$fieldname");
++        }
++        my $fc = $query->param($fieldname);
++        if (ref(\$fc) ne 'SCALAR') {
++            error_quit($listname , 'cgi', "-8- $detail|$fieldname");
++        }
++        push @urlencoded, "$fieldname=" . uri_escape($fc);
++    }
++    return join '&', @urlencoded;
++}
++
++sub doit {
++    my $request_method = $ENV{'REQUEST_METHOD'};
++    my $query = CGI::new();
++    my @list_info = GetPathPieces();
++    if (scalar(@list_info) != 1) {
++        error_quit('', 'info', '-2-');
++    }
++    my $path_listname = lc $list_info[0];
++    my $encoded_params = check_params($path_listname, $query, 'Field count -4-');
++    my $listname;
++    if ($query->param('config') =~ /^([^\.]+)(|\.htsearch)$/) {
++        $listname = $1;
++    } else {
++        error_quit('', 'list', '-3-');
++    }
++    if ($path_listname ne $listname) {
++        error_quit($listname, 'list', "$path_listname:$listname");
++    }
++    if (scalar @VALID_IP_LIST) {
++        my $remote_addr = $ENV{'REMOTE_ADDR'};
++        my @request_bits = split /\./, $remote_addr;
++        my $got_a_match = 0;
++        my $ip;
++        foreach $ip (@VALID_IP_LIST) {
++            @valid_bits = split /\./, $ip;
++            my $mismatch = 0;
++            for (my $i=0; $i<4; $i++) {
++                if ($request_bits[$i] ne $valid_bits[$i]) {
++                    $mismatch = 1;
++                    last;
++                }
++            }
++            if (! $mismatch) {
++                $got_a_match = 1;
++                last;
++            }
++        }
++        if (! $got_a_match) {
++            error_quit($listname, 'auth', "-10- $remote_addr");
++        }
++    }
++    $ENV{'CONFIG_DIR'} = $HTDIG_CONF_LINK_DIR;
++    my $cmd = $HTDIG_HTSEARCH_PATH;
++    if ($request_method eq 'POST') {
++       $ENV{'CONTENT_LENGTH'} = length $encoded_params;
++    } else {
++        error_quit($listname, 'auth', "-11- method");
++    }
++    my $child_pid = open2(\*Readchild, \*Writechild, $cmd);
++    print Writechild $encoded_params;
++    close Writechild;
++    my $response = '';
++    while (<Readchild>) {
++        $response .= $_;
++    }
++    my $rc = waitpid $child_pid, 0;
++    my $exitstatus = ($? >> 8) & 0xff;
++    if ($exitstatus) {
++        error_quit($listname, 'htsearch', "-12- exit: $existstatus");
++    }
++    if (! $response) {
++        error_quit($listname, 'htsearch', "-13-");
++    }
++    print $response;
++    exit 0;
++}
++
++if ($MAILTO and -d $HTDIG_CONF_LINK_DIR and -x $HTDIG_HTSEARCH_PATH) {
++    doit();
++} else {
++    error_quit('', 'cgi', '-14- misconfigured');
++}
+diff -Nru mailman-2.1.5/Mailman/Defaults.py.in mailman-2.1.5+htdig/Mailman/Defaults.py.in
+--- mailman-2.1.5/Mailman/Defaults.py.in	2005-07-04 10:07:01.529421256 +0200
++++ mailman-2.1.5+htdig/Mailman/Defaults.py.in	2005-07-04 10:04:30.275415360 +0200
+@@ -1247,6 +1247,71 @@
+ # Import a bunch of version numbers
+ from Version import *
+ 
++# htdig integration parameters
++# if you set USE_HTDIG then you must also set HTDIG_HTSEARCH_PATH
++# and HTDIG_RUNDIG_PATH to suit your htdig installation. They must point to
++# the htsearch program and rundig script in your file system, for instance:
++# HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'
++# HTDIG_RUNDIG_PATH = '/usr/bin/rundig'
++USE_HTDIG = 0    # 0 - don't use integrated htdig, 1 - use it
++HTDIG_FILES_URL = '/htdig/'
++HTDIG_CONF_LINK_DIR = os.path.join(VAR_PREFIX, 'archives', 'htdig')
++HTDIG_HTSEARCH_PATH = '/usr/lib/cgi-bin/htsearch'
++HTDIG_RUNDIG_PATH = '/usr/bin/rundig'
++
++# the value of this string is assigned as the value of an htdig 
++# 'excluded_urls:' configuration directive when per-list htdig.conf 
++# files are generated. Conflicts can arise depending on the values you 
++# assign to DEFAULT_URL_PATTERN and CGIEXT and list names themselves. 
++# The code attempts to avoid this problem when generating each  per-list 
++# htdig.conf and will, if necessary, modify the value obtained from 
++# HTDIG_EXCLUDED_URLS on a list-by-list basis.
++HTDIG_EXCLUDED_URLS = '/cgi-bin/ .cgi'
++
++# you can use the HTDIG_EXTRAS parameter to add arbitrary htdig 
++# configuration attributes to per list htdig config files. The string 
++# value you specify is inserted verbatim at the top of each htdig conf 
++# file when it is generated. The default value does nothing. Make sure
++# you understand what you are doing before you fool with this facility.
++HTDIG_EXTRAS = """\
++# start of extra site specific htdig configuration attributes
++#
++# replace these line with your htdig config attribute declarations
++# as defined at http://www.htdig.org/confindex.html
++#
++# end of extra site specific htdig configuration attributes
++"""
++
++# remote htdig support parameters for mailman-htdig integration
++# provides support for running htdig on a different machine from the one
++# running mailman but one having NFS access to the installation directory 
++# of the Mailman package.
++# set REMOTE_HTDIG if you are running htdig on a different machine to
++# Mailman. Has no effect unless you also set REMOTE_HTDIG
++# REMOTE_PRIVATE_ARCHIVE_FILE_DIR  is the absolute path to the directory in 
++# which Mailman stores private archives as seen by the machine running htdig.
++# It should resolve to the same directory as PRIVATE_ARCHIVE_FILE_DIR when
++# viewed from the remote system.
++# REMOTE_MMSEARCH_URL is the URL for the mmsearch's companion CGI script 
++# script on the remote htdig machine. This should reach one of either
++# remote_mmsearch or remote-mmsearch
++# HTDIG_STRICT_FILE_PERM says whether 'other' does not have permission to
++# access per-list htdig directory (True) or not (False). False may be 
++# appropriate if REMOTE_HTDIG is True and the UID and GID the remote Apache
++# server runs CGI scripts as is not the/in the mailman user/group. 
++# Weaker security but prevents permissions problems for 
++# remote_mmsearch/remote-mmseach
++REMOTE_HTDIG = 0 # 0 - htdig runs on Mailman machine, 1 - runs on remote machine
++REMOTE_PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'private')
++REMOTE_MMSEARCH_URL = '/cgi-bin/remote_mmsearch'
++HTDIG_STRICT_FILE_PERM = 1
++
++# Disable this default for htdig integration in mailman. We are able to
++# index private pages in secure manner.
++if USE_HTDIG == 0:
++    ARCHIVE_INDEXING_ENABLE = '<!--/htdig_noindex-->'
++    ARCHIVE_INDEXING_DISABLE = '<!--htdig_noindex-->'
++ 
+ # Vgg: Language descriptions and charsets dictionary, any new supported
+ # language must have a corresponding entry here. Key is the name of the
+ # directories that hold the localized texts. Data are tuples with first
+diff -Nru mailman-2.1.5/Mailman/Defaults.py.in.orig mailman-2.1.5+htdig/Mailman/Defaults.py.in.orig
+--- mailman-2.1.5/Mailman/Defaults.py.in.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Defaults.py.in.orig	2005-07-04 10:04:08.195771976 +0200
+@@ -0,0 +1,1295 @@
++# -*- python -*-
++
++# Copyright (C) 1998-2004 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++"""Distributed default settings for significant Mailman config variables.
++"""
++
++# NEVER make site configuration changes to this file.  ALWAYS make them in
++# mm_cfg.py instead, in the designated area.  See the comments in that file
++# for details.
++
++
++import os
++
++def seconds(s): return s
++def minutes(m): return m * 60
++def hours(h): return h * 60 * 60
++def days(d): return d * 60 * 60 * 24
++
++# Some convenient constants
++try:
++    True, False
++except NameError:
++    True = 1
++    False = 0
++
++Yes = yes = On = on = True
++No = no = Off = off = False
++
++
++
++#####
++# General system-wide defaults
++#####
++
++# Should image logos be used?  Set this to 0 to disable image logos from "our
++# sponsors" and just use textual links instead (this will also disable the
++# shortcut "favicon").  Otherwise, this should contain the URL base path to
++# the logo images (and must contain the trailing slash)..  If you want to
++# disable Mailman's logo footer altogther, hack
++# Mailman/htmlformat.py:MailmanLogo(), which also contains the hardcoded links
++# and image names.
++IMAGE_LOGOS = '/doc/mailman/images/'
++
++# The name of the Mailman favicon
++SHORTCUT_ICON = 'mm-icon.png'
++
++# Don't change MAILMAN_URL, unless you want to point it at one of the mirrors.
++MAILMAN_URL = 'http://www.gnu.org/software/mailman/index.html'
++#MAILMAN_URL = 'http://www.list.org/'
++#MAILMAN_URL = 'http://mailman.sf.net/'
++
++# Mailman needs to know about (at least) two fully-qualified domain names
++# (fqdn); 1) the hostname used in your urls, and 2) the hostname used in email
++# addresses for your domain.  For example, if people visit your Mailman system
++# with "http://www.dom.ain/mailman" then your url fqdn is "www.dom.ain", and
++# if people send mail to your system via "[email-masked]" then your email
++# fqdn is "dom.ain".  DEFAULT_URL_HOST controls the former, and
++# DEFAULT_EMAIL_HOST controls the latter.  Mailman also needs to know how to
++# map from one to the other (this is especially important if you're running
++# with virtual domains).  You use "add_virtualhost(urlfqdn, emailfqdn)" to add
++# new mappings.
++#
++# If you don't need to change DEFAULT_EMAIL_HOST and DEFAULT_URL_HOST in your
++# mm_cfg.py, then you're done; the default mapping is added automatically.  If
++# however you change either variable in your mm_cfg.py, then be sure to also
++# include the following:
++#
++#     add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
++#
++# because otherwise the default mappings won't be correct.
++DEFAULT_EMAIL_HOST = '@MAILHOST@'
++DEFAULT_URL_HOST = '@URLHOST@'
++DEFAULT_URL_PATTERN = 'http://%s/cgi-bin/mailman/'
++
++# DEFAULT_HOST_NAME has been replaced with DEFAULT_EMAIL_HOST, however some
++# sites may have the former in their mm_cfg.py files.  If so, we'll believe
++# that, otherwise we'll believe DEFAULT_EMAIL_HOST.  Same for DEFAULT_URL.
++DEFAULT_HOST_NAME = None
++DEFAULT_URL = None
++
++HOME_PAGE         = 'index.html'
++MAILMAN_SITE_LIST = 'mailman'
++
++# Normally when a site administrator authenticates to a web page with the site
++# password, they get a cookie which authorizes them as the list admin.  It
++# makes me nervous to hand out site auth cookies because if this cookie is
++# cracked or intercepted, the intruder will have access to every list on the
++# site.  OTOH, it's dang handy to not have to re-authenticate to every list on
++# the site.  Set this value to Yes to allow site admin cookies.
++ALLOW_SITE_ADMIN_COOKIES = No
++
++# Command that is used to convert text/html parts into plain text.  This
++# should output results to standard output.  %(filename)s will contain the
++# name of the temporary file that the program should operate on.
++HTML_TO_PLAIN_TEXT_COMMAND = '/usr/bin/lynx -dump %(filename)s'
++
++
++
++#####
++# Virtual domains
++#####
++
++# Set up your virtual host mappings here.  This is primarily used for the
++# thru-the-web list creation, so its effects are currently fairly limited.
++# Use add_virtualhost() call to add new mappings.  The keys are strings as
++# determined by Utils.get_domain(), the values are as appropriate for
++# DEFAULT_HOST_NAME.
++VIRTUAL_HOSTS = {}
++
++# When set to Yes, the listinfo and admin overviews of lists on the machine
++# will be confined to only those lists whose web_page_url configuration option
++# host is included within the URL by which the page is visited - only those
++# "on the virtual host".  When set to No, all advertised (i.e. public) lists
++# are included in the overview.
++VIRTUAL_HOST_OVERVIEW = On
++
++
++# Helper function; use this in your mm_cfg.py files.  If optional emailhost is
++# omitted it defaults to urlhost with the first name stripped off, e.g.
++#
++# add_virtualhost('www.dom.ain')
++# VIRTUAL_HOST['www.dom.ain']
++# ==> 'dom.ain'
++#
++def add_virtualhost(urlhost, emailhost=None):
++    DOT = '.'
++    if emailhost is None:
++        emailhost = DOT.join(urlhost.split(DOT)[1:])
++    VIRTUAL_HOSTS[urlhost.lower()] = emailhost.lower()
++
++# And set the default
++add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
++
++
++
++#####
++# Spam avoidance defaults
++#####
++
++# This variable contains a list of 2-tuple of the format (header, regex) which
++# the Mailman/Handlers/SpamDetect.py module uses to match against the current
++# message.  If the regex matches the given header in the current message, then
++# it is flagged as spam.  header is case-insensitive and should not include
++# the trailing colon.  regex is always matched with re.IGNORECASE.
++#
++# Note that the more searching done, the slower the whole process gets.  Spam
++# detection is run against all messages coming to either the list, or the
++# -owners address, unless the message is explicitly approved.
++KNOWN_SPAMMERS = []
++
++
++
++#####
++# Web UI defaults
++#####
++
++# Almost all the colors used in Mailman's web interface are parameterized via
++# the following variables.  This lets you easily change the color schemes for
++# your preferences without having to do major surgery on the source code.
++# Note that in general, the template colors are not included here since it is
++# easy enough to override the default template colors via site-wide,
++# vdomain-wide, or list-wide specializations.
++
++WEB_BG_COLOR = 'white'                            # Page background
++WEB_HEADER_COLOR = '#99ccff'                      # Major section headers
++WEB_SUBHEADER_COLOR = '#fff0d0'                   # Minor section headers
++WEB_ADMINITEM_COLOR = '#dddddd'                   # Option field background
++WEB_ADMINPW_COLOR = '#99cccc'                     # Password box color
++WEB_ERROR_COLOR = 'red'                           # Error message foreground
++WEB_LINK_COLOR = ''                               # If true, forces LINK=
++WEB_ALINK_COLOR = ''                              # If true, forces ALINK=
++WEB_VLINK_COLOR = ''                              # If true, forces VLINK=
++WEB_HIGHLIGHT_COLOR = '#dddddd'                   # If true, alternating rows
++                                                  # in listinfo & admin display
++
++
++#####
++# Archive defaults
++#####
++
++# The url template for the public archives.  This will be used in several
++# places, including the List-Archive: header, links to the archive on the
++# list's listinfo page, and on the list's admin page.
++#
++# This should be a string with "%(listname)s" somewhere in it.  Mailman will
++# interpolate the name of the list into this.  You can also include a
++# "%(hostname)s" in the string, into which Mailman will interpolate
++# the host name (usually DEFAULT_URL_HOST).
++PUBLIC_ARCHIVE_URL = 'http://%(hostname)s/pipermail/%(listname)s'
++
++# Are archives on or off by default?
++DEFAULT_ARCHIVE = On
++
++# Are archives public or private by default?
++# 0=public, 1=private
++DEFAULT_ARCHIVE_PRIVATE = 0
++
++# ARCHIVE_TO_MBOX
++#-1 - do not do any archiving
++# 0 - do not archive to mbox, use builtin mailman html archiving only
++# 1 - archive to mbox to use an external archiving mechanism only
++# 2 - archive to both mbox and builtin mailman html archiving -
++#     use this to make both external archiving mechanism work and
++#     mailman's builtin html archiving.  the flat mail file can be
++#     useful for searching, external archivers, etc.
++ARCHIVE_TO_MBOX = 2
++
++# 0 - yearly
++# 1 - monthly
++# 2 - quarterly
++# 3 - weekly
++# 4 - daily
++DEFAULT_ARCHIVE_VOLUME_FREQUENCY = 1
++DEFAULT_DIGEST_VOLUME_FREQUENCY = 1
++
++# These variables control the use of an external archiver.  Normally if
++# archiving is turned on (see ARCHIVE_TO_MBOX above and the list's archive*
++# attributes) the internal Pipermail archiver is used.  This is the default if
++# both of these variables are set to No.  When either is set, the value should
++# be a shell command string which will get passed to os.popen().  This string
++# can contain the following substitution strings:
++#
++#     %(listname)s -- gets the internal name of the list
++#     %(hostname)s -- gets the email hostname for the list
++#
++# being archived will be substituted for this.  Please note that os.popen() is
++# used.
++#
++# Note that if you set one of these variables, you should set both of them
++# (they can be the same string).  This will mean your external archiver will
++# be used regardless of whether public or private archives are selected.
++PUBLIC_EXTERNAL_ARCHIVER = No
++PRIVATE_EXTERNAL_ARCHIVER = No
++
++# A filter module that converts from multipart messages to "flat" messages
++# (i.e. containing a single payload).  This is required for Pipermail, and you
++# may want to set it to 0 for external archivers.  You can also replace it
++# with your own module as long as it contains a process() function that takes
++# a MailList object and a Message object.  It should raise
++# Errors.DiscardMessage if it wants to throw the message away.  Otherwise it
++# should modify the Message object as necessary.
++ARCHIVE_SCRUBBER = 'Mailman.Handlers.Scrubber'
++
++# This variable defines what happens to text/html subparts.  They can be
++# stripped completely, escaped, or filtered through an external program.  The
++# legal values are:
++# 0 - Strip out text/html parts completely, leaving a notice of the removal in
++#     the message.  If the outer part is text/html, the entire message is
++#     discarded.
++# 1 - Remove any embedded text/html parts, leaving them as HTML-escaped
++#     attachments which can be separately viewed.  Outer text/html parts are
++#     simply HTML-escaped.
++# 2 - Leave it inline, but HTML-escape it
++# 3 - Remove text/html as attachments but don't HTML-escape them. Note: this
++#     is very dangerous because it essentially means anybody can send an HTML
++#     email to your site containing evil JavaScript or web bugs, or other
++#     nasty things, and folks viewing your archives will be susceptible.  You
++#     should only consider this option if you do heavy moderation of your list
++#     postings.
++#
++# Note: given the current archiving code, it is not possible to leave
++# text/html parts inline and un-escaped.  I wouldn't think it'd be a good idea
++# to do anyway.
++#
++# The value can also be a string, in which case it is the name of a command to
++# filter the HTML page through.  The resulting output is left in an attachment
++# or as the entirety of the message when the outer part is text/html.  The
++# format of the string must include a "%(filename)s" which will contain the
++# name of the temporary file that the program should operate on.  It should
++# write the processed message to stdout.  Set this to
++# HTML_TO_PLAIN_TEXT_COMMAND to specify an HTML to plain text conversion
++# program.
++ARCHIVE_HTML_SANITIZER = 1
++
++# Set this to Yes to enable gzipping of the downloadable archive .txt file.
++# Note that this is /extremely/ inefficient, so an alternative is to just
++# collect the messages in the associated .txt file and run a cron job every
++# night to generate the txt.gz file.  See cron/nightly_gzip for details.
++GZIP_ARCHIVE_TXT_FILES = No
++
++# This sets the default `clobber date' policy for the archiver.  When a
++# message is to be archived either by Pipermail or an external archiver,
++# Mailman can modify the Date: header to be the date the message was received
++# instead of the Date: in the original message.  This is useful if you
++# typically receive messages with outrageous dates.  Set this to 0 to retain
++# the date of the original message, or to 1 to always clobber the date.  Set
++# it to 2 to perform `smart overrides' on the date; when the date is outside
++# ARCHIVER_ALLOWABLE_SANE_DATE_SKEW (either too early or too late), then the
++# received date is substituted instead.
++ARCHIVER_CLOBBER_DATE_POLICY = 2
++ARCHIVER_ALLOWABLE_SANE_DATE_SKEW = days(15)
++
++# Pipermail archives contain the raw email addresses of the posting authors.
++# Some view this as a goldmine for spam harvesters.  Set this to Yes to
++# moderately obscure email addresses, but note that this breaks mailto: URLs
++# in the archives too.
++ARCHIVER_OBSCURES_EMAILADDRS = Yes
++
++# Pipermail assumes that messages bodies contain US-ASCII text.
++# Change this option to define a different character set to be used as
++# the default character set for the archive.  The term "character set"
++# is used in MIME to refer to a method of converting a sequence of
++# octets into a sequence of characters.  If you change the default
++# charset, you might need to add it to VERBATIM_ENCODING below.
++DEFAULT_CHARSET = None
++
++# Most character set encodings require special HTML entity characters to be
++# quoted, otherwise they won't look right in the Pipermail archives.  However
++# some character sets must not quote these characters so that they can be
++# rendered properly in the browsers.  The primary issue is multi-byte
++# encodings where the octet 0x26 does not always represent the & character.
++# This variable contains a list of such characters sets which are not
++# HTML-quoted in the archives.
++VERBATIM_ENCODING = ['iso-2022-jp']
++
++# When the archive is public, should Mailman also make the raw Unix mbox file
++# publically available?
++PUBLIC_MBOX = No
++
++
++
++#####
++# Delivery defaults
++#####
++
++# Final delivery module for outgoing mail.  This handler is used for message
++# delivery to the list via the smtpd, and to an individual user.  This value
++# must be a string naming a module in the Mailman.Handlers package.
++#
++# WARNING: Sendmail has security holes and should be avoided.  In fact, you
++# must read the Mailman/Handlers/Sendmail.py file before it will work for
++# you.
++#
++#DELIVERY_MODULE = 'Sendmail'
++DELIVERY_MODULE = 'SMTPDirect'
++
++# MTA should name a module in Mailman/MTA which provides the MTA specific
++# functionality for creating and removing lists.  Some MTAs like Exim can be
++# configured to automatically recognize new lists, in which case the MTA
++# variable should be set to None.  Use 'Manual' to print new aliases to
++# standard out (or send an email to the site list owner) for manual twiddling
++# of an /etc/aliases style file.  Use 'Postfix' if you are using the Postfix
++# MTA -- but then also see POSTFIX_STYLE_VIRTUAL_DOMAINS.
++MTA = 'Manual'
++
++# If you set MTA='Postfix', then you also want to set the following variable,
++# depending on whether you're using virtual domains in Postfix, and which
++# style of virtual domain you're using.  Set this flag to false if you're not
++# using virtual domains in Postfix, or if you're using Sendmail-style virtual
++# domains (where all addresses are visible in all domains).  If you're using
++# Postfix-style virtual domains, where aliases should only show up in the
++# virtual domain, set this variable to the list of host_name values to write
++# separate virtual entries for.  I.e. if you run dom1.ain, dom2.ain, and
++# dom3.ain, but only dom2 and dom3 are virtual, set this variable to the list
++# ['dom2.ain', 'dom3.ain'].  Matches are done against the host_name attribute
++# of the mailing lists.  See README.POSTFIX for details.
++POSTFIX_STYLE_VIRTUAL_DOMAINS = []
++
++# These variables describe the program to use for regenerating the aliases.db
++# and virtual-mailman.db files, respectively, from the associated plain text
++# files.  The file being updated will be appended to this string (with a
++# separating space), so it must be appropriate for os.system().
++POSTFIX_ALIAS_CMD = '/usr/sbin/postalias'
++POSTFIX_MAP_CMD = '/usr/sbin/postmap'
++
++# Ceiling on the number of recipients that can be specified in a single SMTP
++# transaction.  Set to 0 to submit the entire recipient list in one
++# transaction.  Only used with the SMTPDirect DELIVERY_MODULE.
++SMTP_MAX_RCPTS = 500
++
++# Ceiling on the number of SMTP sessions to perform on a single socket
++# connection.  Some MTAs have limits.  Set this to 0 to do as many as we like
++# (i.e. your MTA has no limits).  Set this to some number great than 0 and
++# Mailman will close the SMTP connection and re-open it after this number of
++# consecutive sessions.
++SMTP_MAX_SESSIONS_PER_CONNECTION = 0
++
++# Maximum number of simultaneous subthreads that will be used for SMTP
++# delivery.  After the recipients list is chunked according to SMTP_MAX_RCPTS,
++# each chunk is handed off to the smptd by a separate such thread.  If your
++# Python interpreter was not built for threads, this feature is disabled.  You
++# can explicitly disable it in all cases by setting MAX_DELIVERY_THREADS to
++# 0.  This feature is only supported with the SMTPDirect DELIVERY_MODULE.
++#
++# NOTE: This is an experimental feature and limited testing shows that it may
++# in fact degrade performance, possibly due to Python's global interpreter
++# lock.  Use with caution.
++MAX_DELIVERY_THREADS = 0
++
++# SMTP host and port, when DELIVERY_MODULE is 'SMTPDirect'.  Make sure the
++# host exists and is resolvable (i.e., if it's the default of "localhost" be
++# sure there's a localhost entry in your /etc/hosts file!)
++SMTPHOST = 'localhost'
++SMTPPORT = 0                                      # default from smtplib
++
++# Command for direct command pipe delivery to sendmail compatible program,
++# when DELIVERY_MODULE is 'Sendmail'.
++SENDMAIL_CMD = '/usr/lib/sendmail'
++
++# Set these variables if you need to authenticate to your NNTP server for
++# Usenet posting or reading.  If no authentication is necessary, specify None
++# for both variables.
++NNTP_USERNAME = None
++NNTP_PASSWORD = None
++
++# Set this if you have an NNTP server you prefer gatewayed lists to use.
++DEFAULT_NNTP_HOST = ''
++
++# These variables controls how headers must be cleansed in order to be
++# accepted by your NNTP server.  Some servers like INN reject messages
++# containing prohibited headers, or duplicate headers.  The NNTP server may
++# reject the message for other reasons, but there's little that can be
++# programmatically done about that.  See Mailman/Queue/NewsRunner.py
++#
++# First, these headers (case ignored) are removed from the original message.
++NNTP_REMOVE_HEADERS = ['nntp-posting-host', 'nntp-posting-date', 'x-trace',
++                       'x-complaints-to', 'xref', 'date-received', 'posted',
++                       'posting-version', 'relay-version', 'received']
++
++# Next, these headers are left alone, unless there are duplicates in the
++# original message.  Any second and subsequent headers are rewritten to the
++# second named header (case preserved).
++NNTP_REWRITE_DUPLICATE_HEADERS = [
++    ('to', 'X-Original-To'),
++    ('cc', 'X-Original-Cc'),
++    ('content-transfer-encoding', 'X-Original-Content-Transfer-Encoding'),
++    ('mime-version', 'X-MIME-Version'),
++    ]
++
++# All `normal' messages which are delivered to the entire list membership go
++# through this pipeline of handler modules.  Lists themselves can override the
++# global pipeline by defining a `pipeline' attribute.
++GLOBAL_PIPELINE = [
++    # These are the modules that do tasks common to all delivery paths.
++    'SpamDetect',
++    'Approve',
++    'Replybot',
++    'Moderate',
++    'Hold',
++    'MimeDel',
++    'Emergency',
++    'Tagger',
++    'CalcRecips',
++    'AvoidDuplicates',
++    'Cleanse',
++    'CookHeaders',
++    # And now we send the message to the digest mbox file, and to the arch and
++    # news queues.  Runners will provide further processing of the message,
++    # specific to those delivery paths.
++    'ToDigest',
++    'ToArchive',
++    'ToUsenet',
++    # Now we'll do a few extra things specific to the member delivery
++    # (outgoing) path, finally leaving the message in the outgoing queue.
++    'AfterDelivery',
++    'Acknowledge',
++    'ToOutgoing',
++    ]
++
++# This is the pipeline which messages sent to the -owner address go through
++OWNER_PIPELINE = [
++    'SpamDetect',
++    'Replybot',
++    'OwnerRecips',
++    'ToOutgoing',
++    ]
++
++
++# This defines syslog() format strings for the SMTPDirect delivery module (see
++# DELIVERY_MODULE above).  Valid %()s string substitutions include:
++#
++#     time -- the time in float seconds that it took to complete the smtp
++#     hand-off of the message from Mailman to your smtpd.
++#
++#     size -- the size of the entire message, in bytes
++#
++#     #recips -- the number of actual recipients for this message.
++#
++#     #refused -- the number of smtp refused recipients (use this only in
++#     SMTP_LOG_REFUSED).
++#
++#     listname -- the `internal' name of the mailing list for this posting
++#
++#     msg_<header> -- the value of the delivered message's given header.  If
++#     the message had no such header, then "n/a" will be used.  Note though
++#     that if the message had multiple such headers, then it is undefined
++#     which will be used.
++#
++#     allmsg_<header> - Same as msg_<header> above, but if there are multiple
++#     such headers in the message, they will all be printed, separated by
++#     comma-space.
++#
++#     sender -- the "sender" of the messages, which will be the From: or
++#     envelope-sender as determeined by the USE_ENVELOPE_SENDER variable
++#     below.
++#
++# The format of the entries is a 2-tuple with the first element naming the
++# file in logs/ to print the message to, and the second being a format string
++# appropriate for Python's %-style string interpolation.  The file name is
++# arbitrary; qfiles/<name> will be created automatically if it does not
++# exist.
++
++# The format of the message printed for every delivered message, regardless of
++# whether the delivery was successful or not.  Set to None to disable the
++# printing of this log message.
++SMTP_LOG_EVERY_MESSAGE = (
++    'smtp',
++    '%(msg_message-id)s smtp for %(#recips)d recips, completed in %(time).3f seconds')
++
++# This will only be printed if there were no immediate smtp failures.
++# Mutually exclusive with SMTP_LOG_REFUSED.
++SMTP_LOG_SUCCESS = (
++    'post',
++    'post to %(listname)s from %(sender)s, size=%(size)d, message-id=%(msg_message-id)s, success')
++
++# This will only be printed if there were any addresses which encountered an
++# immediate smtp failure.  Mutually exclusive with SMTP_LOG_SUCCESS.
++SMTP_LOG_REFUSED = (
++    'post',
++    'post to %(listname)s from %(sender)s, size=%(size)d, message-id=%(msg_message-id)s, %(#refused)d failures')
++
++# This will be logged for each specific recipient failure.  Additional %()s
++# keys are:
++#
++#     recipient -- the failing recipient address
++#     failcode  -- the smtp failure code
++#     failmsg   -- the actual smtp message, if available
++SMTP_LOG_EACH_FAILURE = (
++    'smtp-failure',
++    'delivery to %(recipient)s failed with code %(failcode)d: %(failmsg)s')
++
++# These variables control the format and frequency of VERP-like delivery for
++# better bounce detection.  VERP is Variable Envelope Return Path, defined
++# here:
++#
++# http://cr.yp.to/proto/verp.txt
++#
++# This involves encoding the address of the recipient as we (Mailman) know it
++# into the envelope sender address (i.e. the SMTP `MAIL FROM:' address).
++# Thus, no matter what kind of forwarding the recipient has in place, should
++# it eventually bounce, we will receive an unambiguous notice of the bouncing
++# address.
++#
++# However, we're technically only "VERP-like" because we're doing the envelope
++# sender encoding in Mailman, not in the MTA.  We do require cooperation from
++# the MTA, so you must be sure your MTA can be configured for extended address
++# semantics.
++#
++# The first variable describes how to encode VERP envelopes.  It must contain
++# these three string interpolations:
++#
++# %(bounces)s -- the list-bounces mailbox will be set here
++# %(mailbox)s -- the recipient's mailbox will be set here
++# %(host)s    -- the recipient's host name will be set here
++#
++# This example uses the default below.
++#
++# FQDN list address is: [email-masked]
++# Recipient is:         [email-masked]
++#
++# The envelope sender will be mylist-bounces+aperson=[email-masked]
++#
++# Note that your MTA /must/ be configured to deliver such an addressed message
++# to mylist-bounces!
++VERP_FORMAT = '%(bounces)s+%(mailbox)s=%(host)s'
++
++# The second describes a regular expression to unambiguously decode such an
++# address, which will be placed in the To: header of the bounce message by the
++# bouncing MTA.  Getting this right is critical -- and tricky.  Learn your
++# Python regular expressions.  It must define exactly three named groups,
++# bounces, mailbox and host, with the same definition as above.  It will be
++# compiled case-insensitively.
++VERP_REGEXP = r'^(?P<bounces>[^+]+?)\+(?P<mailbox>[^=]+)=(?P<host>[^@]+)@.*$'
++
++# VERP format and regexp for probe messages
++VERP_PROBE_FORMAT = '%(bounces)s+%(token)s'
++VERP_PROBE_REGEXP = r'^(?P<bounces>[^+]+?)\+(?P<token>[^@]+)@.*$'
++
++# A perfect opportunity for doing VERP is the password reminders, which are
++# already addressed individually to each recipient.  Set this to Yes to enable
++# VERPs on all password reminders.
++VERP_PASSWORD_REMINDERS = No
++
++# Another good opportunity is when regular delivery is personalized.  Here
++# again, we're already incurring the performance hit for addressing each
++# individual recipient.  Set this to Yes to enable VERPs on all personalized
++# regular deliveries (personalized digests aren't supported yet).
++VERP_PERSONALIZED_DELIVERIES = No
++
++# And finally, we can VERP normal, non-personalized deliveries.  However,
++# because it can be a significant performance hit, we allow you to decide how
++# often to VERP regular deliveries.  This is the interval, in number of
++# messages, to do a VERP recipient address.  The same variable controls both
++# regular and digest deliveries.  Set to 0 to disable occasional VERPs, set to
++# 1 to VERP every delivery, or to some number > 1 for only occasional VERPs.
++VERP_DELIVERY_INTERVAL = 0
++
++# For nicer confirmation emails, use a VERP-like format which encodes the
++# confirmation cookie in the reply address.  This lets us put a more user
++# friendly Subject: on the message, but requires cooperation from the MTA.
++# Format is like VERP_FORMAT above, but with the following substitutions:
++#
++# %(confirm)s -- the list-confirm mailbox will be set here
++# %(cookie)s  -- the confirmation cookie will be set here
++VERP_CONFIRM_FORMAT = '%(addr)s+%(cookie)s'
++
++# This is analogous to VERP_REGEXP, but for splitting apart the
++# VERP_CONFIRM_FORMAT.
++VERP_CONFIRM_REGEXP = r'^(?P<addr>[^+]+?)\+(?P<cookie>[^@]+)@.*$'
++
++# Set this to Yes to enable VERP-like (more user friendly) confirmations
++VERP_CONFIRMATIONS = No
++
++# This is the maximum number of automatic responses sent to an address because
++# of -request messages or posting hold messages.  This limit prevents response
++# loops between Mailman and misconfigured remote email robots.  Mailman
++# already inhibits automatic replies to any message labeled with a header
++# "Precendence: bulk|list|junk".  This is a fallback safety valve so it should
++# be set fairly high.  Set to 0 for no limit (probably useful only for
++# debugging).
++MAX_AUTORESPONSES_PER_DAY = 10
++
++
++
++#####
++# Qrunner defaults
++#####
++
++# Which queues should the qrunner master watchdog spawn?  This is a list of
++# 2-tuples containing the name of the qrunner class (which must live in a
++# module of the same name within the Mailman.Queue package), and the number of
++# parallel processes to fork for each qrunner.  If more than one process is
++# used, each will take an equal subdivision of the hash space.
++
++# BAW: Eventually we may support weighted hash spaces.
++# BAW: Although not enforced, the # of slices must be a power of 2
++
++QRUNNERS = [
++    ('ArchRunner',     1), # messages for the archiver
++    ('BounceRunner',   1), # for processing the qfile/bounces directory
++    ('CommandRunner',  1), # commands and bounces from the outside world
++    ('IncomingRunner', 1), # posts from the outside world
++    ('NewsRunner',     1), # outgoing messages to the nntpd
++    ('OutgoingRunner', 1), # outgoing messages to the smtpd
++    ('VirginRunner',   1), # internally crafted (virgin birth) messages
++    ('RetryRunner',    1), # retry temporarily failed deliveries
++    ]
++
++# Set this to Yes to use the `Maildir' delivery option.  If you change this
++# you will need to re-run bin/genaliases for MTAs that don't use list
++# auto-detection.
++#
++# WARNING: If you want to use Maildir delivery, you /must/ start Mailman's
++# qrunner as root, or you will get permission problems.
++#
++# NOTE: Maildir delivery is experimental for Mailman 2.1.
++USE_MAILDIR = No
++# NOTE: If you set USE_MAILDIR = Yes, add the following line to your mm_cfg.py
++# file (uncommented of course!)
++# QRUNNERS.append(('MaildirRunner', 1))
++
++# After processing every file in the qrunner's slice, how long should the
++# runner sleep for before checking the queue directory again for new files?
++# This can be a fraction of a second, or zero to check immediately
++# (essentially busy-loop as fast as possible).
++QRUNNER_SLEEP_TIME = seconds(1)
++
++# When a message that is unparsable (by the email package) is received, what
++# should we do with it?  The most common cause of unparsable messages is
++# broken MIME encapsulation, and the most common cause of that is viruses like
++# Nimda.  Set this variable to No to discard such messages, or to Yes to store
++# them in qfiles/bad subdirectory.
++QRUNNER_SAVE_BAD_MESSAGES = Yes
++
++# This flag causes Mailman to fsync() its data files after writing and
++# flushing its contents.  While this ensures the data is written to disk,
++# avoiding data loss, it may be a performance killer.  Note that this flag
++# affects both message pickles and MailList config.pck files.
++SYNC_AFTER_WRITE = No
++
++
++
++#####
++# General defaults
++#####
++
++# The default language for this server.  Whenever we can't figure out the list
++# context or user context, we'll fall back to using this language.  See
++# LC_DESCRIPTIONS below for legal values.
++DEFAULT_SERVER_LANGUAGE = 'en'
++
++# When allowing only members to post to a mailing list, how is the sender of
++# the message determined?  If this variable is set to Yes, then first the
++# message's envelope sender is used, with a fallback to the sender if there is
++# no envelope sender.  Set this variable to No to always use the sender.
++#
++# The envelope sender is set by the SMTP delivery and is thus less easily
++# spoofed than the sender, which is typically just taken from the From: header
++# and thus easily spoofed by the end-user.  However, sometimes the envelope
++# sender isn't set correctly and this will manifest itself by postings being
++# held for approval even if they appear to come from a list member.  If you
++# are having this problem, set this variable to No, but understand that some
++# spoofed messages may get through.
++USE_ENVELOPE_SENDER = No
++
++# Membership tests for posting purposes are usually performed by looking at a
++# set of headers, passing the test if any of their values match a member of
++# the list.  Headers are checked in the order given in this variable.  The
++# value None means use the From_ (envelope sender) header.  Field names are
++# case insensitive.
++SENDER_HEADERS = ('from', None, 'reply-to', 'sender')
++
++# How many members to display at a time on the admin cgi to unsubscribe them
++# or change their options?
++DEFAULT_ADMIN_MEMBER_CHUNKSIZE = 30
++
++# how many bytes of a held message post should be displayed in the admindb web
++# page?  Use a negative number to indicate the entire message, regardless of
++# size (though this will slow down rendering those pages).
++ADMINDB_PAGE_TEXT_LIMIT = 4096
++
++# Set this variable to Yes to allow list owners to delete their own mailing
++# lists.  You may not want to give them this power, in which case, setting
++# this variable to No instead requires list removal to be done by the site
++# administrator, via the command line script bin/rmlist.
++OWNERS_CAN_DELETE_THEIR_OWN_LISTS = No
++
++# Set this variable to Yes to allow list owners to set the "personalized"
++# flags on their mailing lists.  Turning these on tells Mailman to send
++# separate email messages to each user instead of batching them together for
++# delivery to the MTA.  This gives each member a more personalized message,
++# but can have a heavy impact on the performance of your system.
++OWNERS_CAN_ENABLE_PERSONALIZATION = No
++
++# Should held messages be saved on disk as Python pickles or as plain text?
++# The former is more efficient since we don't need to go through the
++# parse/generate roundtrip each time, but the latter might be preferred if you
++# want to edit the held message on disk.
++HOLD_MESSAGES_AS_PICKLES = Yes
++
++# This variable controls the order in which list-specific category options are
++# presented in the admin cgi page.
++ADMIN_CATEGORIES = [
++    # First column
++    'general', 'passwords', 'language', 'members', 'nondigest', 'digest',
++    # Second column
++    'privacy', 'bounce', 'archive', 'gateway', 'autoreply',
++    'contentfilter', 'topics',
++    ]
++
++# See "Bitfield for user options" below; make this a sum of those options, to
++# make all new members of lists start with those options flagged.  We assume
++# by default that people don't want to receive two copies of posts.  Note
++# however that the member moderation flag's initial value is controlled by the
++# list's config variable default_member_moderation.
++DEFAULT_NEW_MEMBER_OPTIONS = 256
++
++# Specify the type of passwords to use, when Mailman generates the passwords
++# itself, as would be the case for membership requests where the user did not
++# fill in a password, or during list creation, when auto-generation of admin
++# passwords was selected.
++#
++# Set this value to Yes for classic Mailman user-friendly(er) passwords.
++# These generate semi-pronounceable passwords which are easier to remember.
++# Set this value to No to use more cryptographically secure, but harder to
++# remember, passwords -- if your operating system and Python version support
++# the necessary feature (specifically that /dev/urandom be available).
++USER_FRIENDLY_PASSWORDS = Yes
++# This value specifies the default lengths of member and list admin passwords
++MEMBER_PASSWORD_LENGTH = 8
++ADMIN_PASSWORD_LENGTH = 10
++
++
++
++#####
++# List defaults.  NOTE: Changing these values does NOT change the
++# configuration of an existing list.  It only defines the default for new
++# lists you subsequently create.
++#####
++
++# Should a list, by default be advertised?  What is the default maximum number
++# of explicit recipients allowed?  What is the default maximum message size
++# allowed?
++DEFAULT_LIST_ADVERTISED = Yes
++DEFAULT_MAX_NUM_RECIPIENTS = 10
++DEFAULT_MAX_MESSAGE_SIZE = 40           # KB
++
++# These format strings will be expanded w.r.t. the dictionary for the
++# mailing list instance.
++DEFAULT_SUBJECT_PREFIX  = "[%(real_name)s] "
++DEFAULT_MSG_HEADER = ""
++DEFAULT_MSG_FOOTER = """_______________________________________________
++%(real_name)s mailing list
++%(real_name)s@%(host_name)s
++%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
++"""
++
++# Mail command processor will ignore mail command lines after designated max.
++DEFAULT_MAIL_COMMANDS_MAX_LINES = 25
++
++# Is the list owner notified of admin requests immediately by mail, as well as
++# by daily pending-request reminder?
++DEFAULT_ADMIN_IMMED_NOTIFY = Yes
++
++# Is the list owner notified of subscribes/unsubscribes?
++DEFAULT_ADMIN_NOTIFY_MCHANGES = No
++
++# Should list members, by default, have their posts be moderated?
++DEFAULT_DEFAULT_MEMBER_MODERATION = No
++
++# Should non-member posts which are auto-discarded also be forwarded to the
++# moderators?
++DEFAULT_FORWARD_AUTO_DISCARDS = Yes
++
++# What shold happen to non-member posts which are do not match explicit
++# non-member actions?
++# 0 = Accept
++# 1 = Hold
++# 2 = Reject
++# 3 = Discard
++DEFAULT_GENERIC_NONMEMBER_ACTION = 1
++
++# Bounce if 'To:', 'Cc:', or 'Resent-To:' fields don't explicitly name list?
++# This is an anti-spam measure
++DEFAULT_REQUIRE_EXPLICIT_DESTINATION = Yes
++
++# Alternate names acceptable as explicit destinations for this list.
++DEFAULT_ACCEPTABLE_ALIASES ="""
++"""
++# For mailing lists that have only other mailing lists for members:
++DEFAULT_UMBRELLA_LIST = No
++
++# For umbrella lists, the suffix for the account part of address for
++# administrative notices (subscription confirmations, password reminders):
++DEFAULT_UMBRELLA_MEMBER_ADMIN_SUFFIX = "-owner"
++
++# This variable controls whether monthly password reminders are sent.
++DEFAULT_SEND_REMINDERS = Yes
++
++# Send welcome messages to new users?
++DEFAULT_SEND_WELCOME_MSG = Yes
++
++# Send goodbye messages to unsubscribed members?
++DEFAULT_SEND_GOODBYE_MSG = Yes
++
++# Wipe sender information, and make it look like the list-admin
++# address sends all messages
++DEFAULT_ANONYMOUS_LIST = No
++
++# {header-name: regexp} spam filtering - we include some for example sake.
++DEFAULT_BOUNCE_MATCHING_HEADERS = """
++# Lines that *start* with a '#' are comments.
++to: [email-masked]
++message-id: relay.comanche.denmark.eu
++from: [email-masked]
++from: [email-masked]
++"""
++
++# Mailman can be configured to "munge" Reply-To: headers for any passing
++# messages.  One the one hand, there are a lot of good reasons not to munge
++# Reply-To: but on the other, people really seem to want this feature.  See
++# the help for reply_goes_to_list in the web UI for links discussing the
++# issue.
++# 0 - Reply-To: not munged
++# 1 - Reply-To: set back to the list
++# 2 - Reply-To: set to an explicit value (reply_to_address)
++DEFAULT_REPLY_GOES_TO_LIST = 0
++
++# Mailman can be configured to strip any existing Reply-To: header, or simply
++# extend any existing Reply-To: with one based on the above setting.
++DEFAULT_FIRST_STRIP_REPLY_TO = No
++
++# SUBSCRIBE POLICY
++# 0 - open list (only when ALLOW_OPEN_SUBSCRIBE is set to 1) **
++# 1 - confirmation required for subscribes
++# 2 - admin approval required for subscribes
++# 3 - both confirmation and admin approval required
++#
++# ** please do not choose option 0 if you are not allowing open
++# subscribes (next variable)
++DEFAULT_SUBSCRIBE_POLICY = 1
++
++# Does this site allow completely unchecked subscriptions?
++ALLOW_OPEN_SUBSCRIBE = No
++
++# The default policy for unsubscriptions.  0 (unmoderated unsubscribes) is
++# highly recommended!
++# 0 - unmoderated unsubscribes
++# 1 - unsubscribes require approval
++DEFAULT_UNSUBSCRIBE_POLICY = 0
++
++# Private_roster == 0: anyone can see, 1: members only, 2: admin only.
++DEFAULT_PRIVATE_ROSTER = 1
++
++# When exposing members, make them unrecognizable as email addrs, so
++# web-spiders can't pick up addrs for spam purposes.
++DEFAULT_OBSCURE_ADDRESSES = Yes
++
++# RFC 2369 defines List-* headers which are added to every message sent
++# through to the mailing list membership.  These are a very useful aid to end
++# users and should always be added.  However, not all MUAs are compliant and
++# if a list's membership has many such users, they may clamor for these
++# headers to be suppressed.  By setting this variable to Yes, list owners will
++# be given the option to suppress these headers.  By setting it to No, list
++# owners will not be given the option to suppress these headers (although some
++# header suppression may still take place, i.e. for announce-only lists, or
++# lists with no archives).
++ALLOW_RFC2369_OVERRIDES = Yes
++
++# Defaults for content filtering on mailing lists.  DEFAULT_FILTER_CONTENT is
++# a flag which if set to true, turns on content filtering.
++DEFAULT_FILTER_CONTENT = No
++
++# DEFAULT_FILTER_MIME_TYPES is a list of MIME types to be removed.  This is a
++# list of strings of the format "maintype/subtype" or simply "maintype".
++# E.g. "text/html" strips all html attachments while "image" strips all image
++# types regardless of subtype (jpeg, gif, etc.).
++DEFAULT_FILTER_MIME_TYPES = []
++
++# DEFAULT_PASS_MIME_TYPES is a list of MIME types to be passed through.  Format is the same as DEFAULT_FILTER_MIME_TYPES
++DEFAULT_PASS_MIME_TYPES = ['multipart/mixed',
++                           'multipart/alternative',
++                           'text/plain']
++
++# Whether text/html should be converted to text/plain after content filtering
++# is performed.  Conversion is done according to HTML_TO_PLAIN_TEXT_COMMAND
++DEFAULT_CONVERT_HTML_TO_PLAINTEXT = Yes
++
++# Default action to take on filtered messages.
++# 0 = Discard, 1 = Reject, 2 = Forward, 3 = Preserve
++DEFAULT_FILTER_ACTION = 0
++
++# Whether to allow list owners to preserve content filtered messages to a
++# special queue on the disk.
++OWNERS_CAN_PRESERVE_FILTERED_MESSAGES = Yes
++
++# Check for administrivia in messages sent to the main list?
++DEFAULT_ADMINISTRIVIA = Yes
++
++
++
++#####
++# Digestification defaults.  Same caveat applies here as with list defaults.
++#####
++
++# Will list be available in non-digested form?
++DEFAULT_NONDIGESTABLE = Yes
++
++# Will list be available in digested form?
++DEFAULT_DIGESTABLE = Yes
++DEFAULT_DIGEST_HEADER = ""
++DEFAULT_DIGEST_FOOTER = DEFAULT_MSG_FOOTER
++
++DEFAULT_DIGEST_IS_DEFAULT = No
++DEFAULT_MIME_IS_DEFAULT_DIGEST = No
++DEFAULT_DIGEST_SIZE_THRESHHOLD = 30     # KB
++DEFAULT_DIGEST_SEND_PERIODIC = Yes
++
++# Headers which should be kept in both RFC 1153 (plain) and MIME digests.  RFC
++# 1153 also specifies these headers in this exact order, so order matters.
++MIME_DIGEST_KEEP_HEADERS = [
++    'Date', 'From', 'To', 'Cc', 'Subject', 'Message-ID', 'Keywords',
++    # I believe we should also keep these headers though.
++    'In-Reply-To', 'References', 'Content-Type', 'MIME-Version',
++    'Content-Transfer-Encoding', 'Precedence', 'Reply-To',
++    # Mailman 2.0 adds these headers
++    'Message',
++    ]
++
++PLAIN_DIGEST_KEEP_HEADERS = [
++    'Message', 'Date', 'From',
++    'Subject', 'To', 'Cc',
++    'Message-ID', 'Keywords',
++    'Content-Type',
++    ]
++
++
++
++#####
++# Bounce processing defaults.  Same caveat applies here as with list defaults.
++#####
++
++# Should we do any bounced mail response at all?
++DEFAULT_BOUNCE_PROCESSING = Yes
++
++# How often should the bounce qrunner process queued detected bounces?
++REGISTER_BOUNCES_EVERY = minutes(15)
++
++# Bounce processing works like this: when a bounce from a member is received,
++# we look up the `bounce info' for this member. If there is no bounce info,
++# this is the first bounce we've received from this member.  In that case, we
++# record today's date, and initialize the bounce score (see below for initial
++# value).
++#
++# If there is existing bounce info for this member, we look at the last bounce
++# receive date.  If this date is farther away from today than the `bounce
++# expiration interval', we throw away all the old data and initialize the
++# bounce score as if this were the first bounce from the member.
++#
++# Otherwise, we increment the bounce score.  If we can determine whether the
++# bounce was soft or hard (i.e. transient or fatal), then we use a score value
++# of 0.5 for soft bounces and 1.0 for hard bounces.  Note that we only score
++# one bounce per day.  If the bounce score is then greater than the `bounce
++# threshold' we disable the member's address.
++#
++# After disabling the address, we can send warning messages to the member,
++# providing a confirmation cookie/url for them to use to re-enable their
++# delivery.  After a configurable period of time, we'll delete the address.
++# When we delete the address due to bouncing, we'll send one last message to
++# the member.
++
++# Bounce scores greater than this value get disabled.
++DEFAULT_BOUNCE_SCORE_THRESHOLD = 5.0
++
++# Bounce information older than this interval is considered stale, and is
++# discarded.
++DEFAULT_BOUNCE_INFO_STALE_AFTER = days(7)
++
++# The number of notifications to send to the disabled/removed member before we
++# remove them from the list.  A value of 0 means we remove the address
++# immediately (with one last notification).  Note that the first one is sent
++# upon change of status to disabled.
++DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS = 3
++
++# The interval of time between disabled warnings.
++DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS_INTERVAL = days(7)
++
++# Does the list owner get messages to the -bounces (and -admin) address that
++# failed to match by the bounce detector?
++DEFAULT_BOUNCE_UNRECOGNIZED_GOES_TO_LIST_OWNER = Yes
++
++# Notifications on bounce actions.  The first specifies whether the list owner
++# should get a notification when a member is disabled due to bouncing, while
++# the second specifies whether the owner should get one when the member is
++# removed due to bouncing.
++DEFAULT_BOUNCE_NOTIFY_OWNER_ON_DISABLE = Yes
++DEFAULT_BOUNCE_NOTIFY_OWNER_ON_REMOVAL = Yes
++
++
++
++#####
++# General time limits
++#####
++
++# Default length of time a pending request is live before it is evicted from
++# the pending database.
++PENDING_REQUEST_LIFE = days(3)
++
++# How long should messages which have delivery failures continue to be
++# retried?  After this period of time, a message that has failed recipients
++# will be dequeued and those recipients will never receive the message.
++DELIVERY_RETRY_PERIOD = days(5)
++
++# How long should we wait before we retry a temporary delivery failure?
++DELIVERY_RETRY_WAIT = hours(1)
++
++
++
++#####
++# Lock management defaults
++#####
++
++# These variables control certain aspects of lock acquisition and retention.
++# They should be tuned as appropriate for your environment.  All variables are
++# specified in units of floating point seconds.  YOU MAY NEED TO TUNE THESE
++# VARIABLES DEPENDING ON THE SIZE OF YOUR LISTS, THE PERFORMANCE OF YOUR
++# HARDWARE, NETWORK AND GENERAL MAIL HANDLING CAPABILITIES, ETC.
++
++# Set this to On to turn on MailList object lock debugging messages, which
++# will be written to logs/locks.  If you think you're having lock problems, or
++# just want to tune the locks for your system, turn on lock debugging.
++LIST_LOCK_DEBUGGING = Off
++
++# This variable specifies how long the lock will be retained for a specific
++# operation on a mailing list.  Watch your logs/lock file and if you see a lot
++# of lock breakages, you might need to bump this up.  However if you set this
++# too high, a faulty script (or incorrect use of bin/withlist) can prevent the
++# list from being used until the lifetime expires.  This is probably one of
++# the most crucial tuning variables in the system.
++LIST_LOCK_LIFETIME = hours(5)
++
++# This variable specifies how long an attempt will be made to acquire a list
++# lock by the incoming qrunner process.  If the lock acquisition times out,
++# the message will be re-queued for later delivery.
++LIST_LOCK_TIMEOUT = seconds(10)
++
++# Set this to On to turn on lock debugging messages for the pending requests
++# database, which will be written to logs/locks.  If you think you're having
++# lock problems, or just want to tune the locks for your system, turn on lock
++# debugging.
++PENDINGDB_LOCK_DEBUGGING = Off
++
++
++
++#####
++# Nothing below here is user configurable.  Most of these values are in this
++# file for internal system convenience.  Don't change any of them or override
++# any of them in your mm_cfg.py file!
++#####
++
++# These directories are used to find various important files in the Mailman
++# installation.  PREFIX and EXEC_PREFIX are set by configure and should point
++# to the installation directory of the Mailman package.
++PYTHON          = '@PYTHON@'
++PREFIX          = '@prefix@'
++EXEC_PREFIX     = '@exec_prefix@'
++VAR_PREFIX      = '@VAR_PREFIX@'
++
++# Work around a bogus autoconf 2.12 bug
++if EXEC_PREFIX == '${prefix}':
++    EXEC_PREFIX = PREFIX
++
++# CGI extension, change using configure script
++CGIEXT = '@CGIEXT@'
++
++# Group id that group-owns the Mailman installation
++MAILMAN_USER = '@MAILMAN_USER@'
++MAILMAN_GROUP = '@MAILMAN_GROUP@'
++
++# Enumeration for Mailman cgi widget types
++Toggle      = 1
++Radio       = 2
++String      = 3
++Text        = 4
++Email       = 5
++EmailList   = 6
++Host        = 7
++Number      = 8
++FileUpload  = 9
++Select      = 10
++Topics      = 11
++Checkbox    = 12
++# An "extended email list".  Contents must be an email address or a ^-prefixed
++# regular expression.  Used in the sender moderation text boxes.
++EmailListEx = 13
++# Extended spam filter widget
++HeaderFilter  = 14
++
++# Actions
++DEFER = 0
++APPROVE = 1
++REJECT = 2
++DISCARD = 3
++SUBSCRIBE = 4
++UNSUBSCRIBE = 5
++ACCEPT = 6
++HOLD = 7
++
++# Standard text field width
++TEXTFIELDWIDTH = 40
++
++# Bitfield for user options.  See DEFAULT_NEW_MEMBER_OPTIONS above to set
++# defaults for all new lists.
++Digests             = 0 # handled by other mechanism, doesn't need a flag.
++DisableDelivery     = 1 # Obsolete; use set/getDeliveryStatus()
++DontReceiveOwnPosts = 2 # Non-digesters only
++AcknowledgePosts    = 4
++DisableMime         = 8 # Digesters only
++ConcealSubscription = 16
++SuppressPasswordReminder = 32
++ReceiveNonmatchingTopics = 64
++Moderate = 128
++DontReceiveDuplicates = 256
++
++# A mapping between short option tags and their flag
++OPTINFO = {'hide'    : ConcealSubscription,
++           'nomail'  : DisableDelivery,
++           'ack'     : AcknowledgePosts,
++           'notmetoo': DontReceiveOwnPosts,
++           'digest'  : 0,
++           'plain'   : DisableMime,
++           'nodupes' : DontReceiveDuplicates
++           }
++
++# Authentication contexts.
++#
++# Mailman defines the following roles:
++
++# - User, a normal user who has no permissions except to change their personal
++#   option settings
++# - List creator, someone who can create and delete lists, but cannot
++#   (necessarily) configure the list.
++# - List moderator, someone who can tend to pending requests such as
++#   subscription requests, or held messages
++# - List administrator, someone who has total control over a list, can
++#   configure it, modify user options for members of the list, subscribe and
++#   unsubscribe members, etc.
++# - Site administrator, someone who has total control over the entire site and
++#   can do any of the tasks mentioned above.  This person usually also has
++#   command line access.
++
++UnAuthorized = 0
++AuthUser = 1          # Joe Shmoe User
++AuthCreator = 2       # List Creator / Destroyer
++AuthListAdmin = 3     # List Administrator (total control over list)
++AuthListModerator = 4 # List Moderator (can only handle held requests)
++AuthSiteAdmin = 5     # Site Administrator (total control over everything)
++
++# Useful directories
++LIST_DATA_DIR   = os.path.join(VAR_PREFIX, 'lists')
++LOG_DIR         = os.path.join(VAR_PREFIX, 'logs')
++LOCK_DIR        = os.path.join(VAR_PREFIX, 'locks')
++DATA_DIR        = os.path.join(VAR_PREFIX, 'data')
++SPAM_DIR        = os.path.join(VAR_PREFIX, 'spam')
++WRAPPER_DIR     = os.path.join(EXEC_PREFIX, 'mail')
++BIN_DIR         = os.path.join(PREFIX, 'bin')
++SCRIPTS_DIR     = os.path.join(PREFIX, 'scripts')
++TEMPLATE_DIR    = os.path.join(PREFIX, 'templates')
++MESSAGES_DIR    = os.path.join(PREFIX, 'messages')
++PUBLIC_ARCHIVE_FILE_DIR  = os.path.join(VAR_PREFIX, 'archives', 'public')
++PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'private')
++
++# Directories used by the qrunner subsystem
++QUEUE_DIR       = os.path.join(VAR_PREFIX, 'qfiles')
++INQUEUE_DIR     = os.path.join(QUEUE_DIR, 'in')
++OUTQUEUE_DIR    = os.path.join(QUEUE_DIR, 'out')
++CMDQUEUE_DIR    = os.path.join(QUEUE_DIR, 'commands')
++BOUNCEQUEUE_DIR = os.path.join(QUEUE_DIR, 'bounces')
++NEWSQUEUE_DIR   = os.path.join(QUEUE_DIR, 'news')
++ARCHQUEUE_DIR   = os.path.join(QUEUE_DIR, 'archive')
++SHUNTQUEUE_DIR  = os.path.join(QUEUE_DIR, 'shunt')
++VIRGINQUEUE_DIR = os.path.join(QUEUE_DIR, 'virgin')
++BADQUEUE_DIR    = os.path.join(QUEUE_DIR, 'bad')
++RETRYQUEUE_DIR  = os.path.join(QUEUE_DIR, 'retry')
++MAILDIR_DIR     = os.path.join(QUEUE_DIR, 'maildir')
++
++# Other useful files
++PIDFILE = "/var/run/mailman/mailman.pid"
++SITE_PW_FILE = os.path.join(DATA_DIR, 'adm.pw')
++LISTCREATOR_PW_FILE = os.path.join(DATA_DIR, 'creator.pw')
++
++# Import a bunch of version numbers
++from Version import *
++
++# Vgg: Language descriptions and charsets dictionary, any new supported
++# language must have a corresponding entry here. Key is the name of the
++# directories that hold the localized texts. Data are tuples with first
++# element being the description, as described in the catalogs, and second
++# element is the language charset.  I have chosen code from /usr/share/locale
++# in my GNU/Linux. :-)
++def _(s):
++    return s
++
++LC_DESCRIPTIONS = {}
++
++def add_language(code, description, charset):
++    LC_DESCRIPTIONS[code] = (description, charset)
++
++add_language('ca',    _('Catalan'),             'iso-8859-1')
++add_language('cs',    _('Czech'),               'iso-8859-2')
++add_language('da',    _('Danish'),              'iso-8859-1')
++add_language('de',    _('German'),              'iso-8859-1')
++add_language('en',    _('English (USA)'),       'us-ascii')
++add_language('es',    _('Spanish (Spain)'),     'iso-8859-1')
++add_language('et',    _('Estonian'),            'iso-8859-15')
++add_language('eu',    _('Euskara'),             'iso-8859-15') # Basque
++add_language('fi',    _('Finnish'),             'iso-8859-1')
++add_language('fr',    _('French'),              'iso-8859-1')
++add_language('hr',    _('Croatian'),            'iso-8859-2')
++add_language('hu',    _('Hungarian'),           'iso-8859-2')
++add_language('it',    _('Italian'),             'iso-8859-1')
++add_language('ja',    _('Japanese'),            'euc-jp')
++add_language('ko',    _('Korean'),              'euc-kr')
++add_language('lt',    _('Lithuanian'),          'iso-8859-13')
++add_language('nl',    _('Dutch'),               'iso-8859-1')
++add_language('no',    _('Norwegian'),           'iso-8859-1')
++add_language('pl',    _('Polish'),              'iso-8859-2')
++add_language('pt',    _('Portuguese'),          'iso-8859-1')
++add_language('pt_BR', _('Portuguese (Brazil)'), 'iso-8859-1')
++add_language('ro',    _('Romanian'),            'iso-8859-2')
++add_language('ru',    _('Russian'),             'koi8-r')
++add_language('sr',    _('Serbian'),             'utf-8')
++add_language('sl',    _('Slovenian'),           'iso-8859-2')
++add_language('sv',    _('Swedish'),             'iso-8859-1')
++add_language('tr',    _('Turkish'),             'iso-8859-9')
++add_language('uk',    _('Ukrainian'),           'utf-8')
++add_language('zh_CN', _('Chinese (China)'),     'gb2312')
++add_language('zh_TW', _('Chinese (Taiwan)'),    'big5')
++
++del _
+diff -Nru mailman-2.1.5/Mailman/Queue/ArchRunner.py mailman-2.1.5+htdig/Mailman/Queue/ArchRunner.py
+--- mailman-2.1.5/Mailman/Queue/ArchRunner.py	2003-12-01 02:50:40.000000000 +0100
++++ mailman-2.1.5+htdig/Mailman/Queue/ArchRunner.py	2005-07-04 10:04:30.275415360 +0200
+@@ -17,17 +17,33 @@
+ """Archive queue runner."""
+ 
+ import time
++import errno
++import os
++from stat import *
+ from email.Utils import parsedate_tz, mktime_tz, formatdate
+ 
+ from Mailman import mm_cfg
+ from Mailman import LockFile
+ from Mailman.Queue.Runner import Runner
++from Mailman import MailList
++from Mailman import Utils
++from Mailman.Archiver import HyperArch
+ 
++# Part of the Mailman-htdig integration.
++# This controls how often _doperiodic() will try to deal with the
++# consequences of a remote machine having reindexed mail archives
++# and hence the need for the MM machine to update affected lists  
++# TOC pages to reflect the datetime when the htdigging was done.
++CHECK_REMOTE_RUNDIG_EFFECTS = 10
+ 
+ 
+ class ArchRunner(Runner):
+     QDIR = mm_cfg.ARCHQUEUE_DIR
+ 
++    def __init__(self, slice=None, numslices=1):
++        Runner.__init__(self, slice, numslices)
++        self._periodic_htdig_check = CHECK_REMOTE_RUNDIG_EFFECTS
++
+     def _dispose(self, mlist, msg, msgdata):
+         # Support clobber_date, i.e. setting the date in the archive to the
+         # received date, not the (potentially bogus) Date: header of the
+@@ -74,3 +90,35 @@
+             mlist.Save()
+         finally:
+             mlist.Unlock()
++
++    def _doperiodic(self):
++        """Do some processing `every once in a while'.
++
++        If the mailman-htdig archiving is being used then we want to ensure
++        that the TOC page for each list has been updated since the last time
++        htdigging of the list was done. This is only necessary if we are
++        running htdig on a different machine to Mailman.
++
++        """
++
++        if mm_cfg.USE_HTDIG and mm_cfg.REMOTE_HTDIG:
++            self._periodic_htdig_check -= 1
++            if self._periodic_htdig_check <= 0: 
++                self._periodic_htdig_check = CHECK_REMOTE_RUNDIG_EFFECTS
++                listnames = Utils.list_names()
++                for name in listnames:
++                    mlist = MailList.MailList(name, lock=0)
++                    if not mlist.last_post_time > 0: continue
++                    arch_dir = mlist.archive_dir()
++                    rundig_run_file = os.path.join(arch_dir, 'htdig', 
++                                                   'rundig_last_run')
++                    toc_file = os.path.join(arch_dir, 'index.html')
++                    try:
++                        last_rundig_time = os.stat(rundig_run_file)[ST_MTIME]
++                        last_toc_time = os.stat(toc_file)[ST_MTIME]
++                    except OSError, e:
++                        if e.errno <> errno.ENOENT: raise
++                    else:
++                        if last_rundig_time > last_toc_time:
++                            HyperArch.HyperArchive(mlist).write_TOC()
++
+diff -Nru mailman-2.1.5/Makefile.in mailman-2.1.5+htdig/Makefile.in
+--- mailman-2.1.5/Makefile.in	2005-07-04 10:07:01.715392984 +0200
++++ mailman-2.1.5+htdig/Makefile.in	2005-07-04 10:04:30.276415208 +0200
+@@ -43,7 +43,7 @@
+ 
+ VAR_DIRS= \
+ 	logs archives lists locks data spam qfiles \
+-	archives/private archives/public
++	archives/private archives/public archives/htdig
+ 
+ ARCH_INDEP_DIRS= \
+ 	bin templates scripts cron pythonlib \
+diff -Nru mailman-2.1.5/src/Makefile.in mailman-2.1.5+htdig/src/Makefile.in
+--- mailman-2.1.5/src/Makefile.in	2005-07-04 10:07:01.591411832 +0200
++++ mailman-2.1.5+htdig/src/Makefile.in	2005-07-04 10:05:00.156872688 +0200
+@@ -71,7 +71,8 @@
+ # Fixed definitions
+ 
+ CGI_PROGS= admindb admin confirm create edithtml listinfo options \
+-	private rmlist roster subscribe savannah
++	private rmlist roster subscribe savannah \
++	htdig mmsearch
+ 
+ COMMONOBJS= common.o vsnprintf.o
+ 
+@@ -79,7 +80,7 @@
+ 
+ #ALIAS_PROGS= addaliases
+ 
+-SUID_CGI_PROGS= private
++SUID_CGI_PROGS= private htdig mmsearch
+ 
+ SUID_MAIL_PROGS=
+ 
+diff -Nru mailman-2.1.5/templates/da/archtoc.html mailman-2.1.5+htdig/templates/da/archtoc.html
+--- mailman-2.1.5/templates/da/archtoc.html	2003-09-22 05:52:33.000000000 +0200
++++ mailman-2.1.5+htdig/templates/da/archtoc.html	2005-07-04 10:04:30.276415208 +0200
+@@ -12,6 +12,7 @@
+       eller du kan <a href="%(fullarch)s">downloade hele arkivet</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/da/archtoc.html.orig mailman-2.1.5+htdig/templates/da/archtoc.html.orig
+--- mailman-2.1.5/templates/da/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/da/archtoc.html.orig	2005-07-04 10:04:30.279414752 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>%(listname)s arkivet</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>%(listname)s arkivet </h1>
++     <p>
++      Du kan se <a href="%(listinfo)s">mere information om denne liste</a>
++      eller du kan <a href="%(fullarch)s">downloade hele arkivet</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/en/archtoc.html mailman-2.1.5+htdig/templates/en/archtoc.html
+--- mailman-2.1.5/templates/en/archtoc.html	2002-11-18 22:04:56.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/archtoc.html	2005-07-04 10:04:30.281414448 +0200
+@@ -12,6 +12,7 @@
+       or you can <a href="%(fullarch)s">download the full raw archive</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/en/archtoc.html.orig mailman-2.1.5+htdig/templates/en/archtoc.html.orig
+--- mailman-2.1.5/templates/en/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/archtoc.html.orig	2005-07-04 10:04:30.283414144 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>The %(listname)s Archives</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>The %(listname)s Archives </h1>
++     <p>
++      You can get <a href="%(listinfo)s">more information about this list</a>
++      or you can <a href="%(fullarch)s">download the full raw archive</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/en/archtocnombox.html mailman-2.1.5+htdig/templates/en/archtocnombox.html
+--- mailman-2.1.5/templates/en/archtocnombox.html	2003-12-01 01:17:34.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/archtocnombox.html	2005-07-04 10:04:30.285413840 +0200
+@@ -10,6 +10,7 @@
+      <p>
+       You can get <a href="%(listinfo)s">more information about this list</a>.
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/en/archtocnombox.html.orig mailman-2.1.5+htdig/templates/en/archtocnombox.html.orig
+--- mailman-2.1.5/templates/en/archtocnombox.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/archtocnombox.html.orig	2005-07-04 10:04:30.286413688 +0200
+@@ -0,0 +1,18 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>The %(listname)s Archives</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>The %(listname)s Archives </h1>
++     <p>
++      You can get <a href="%(listinfo)s">more information about this list</a>.
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/en/htdig_access_error.html mailman-2.1.5+htdig/templates/en/htdig_access_error.html
+--- mailman-2.1.5/templates/en/htdig_access_error.html	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/htdig_access_error.html	2005-07-04 10:04:30.288413384 +0200
+@@ -0,0 +1,22 @@
++<HTML>
++<HEAD>
++    <TITLE>htdig Archives Access Failure</TITLE> 
++</HEAD>
++<BODY BGCOLOR="#ffffff">
++<H1>htdig Archives Access Failure</H1> 
++%(error)s
++<P>
++    If you want to make another attempt to access a list archive then go via the 
++    list users <A HREF="%(listinfo_link)s">information page</A>.
++</P>
++<P>
++    If this problem persists then please e-mail the following information to the 
++<A HREF="mailto:%(mailto)s">%(mailto)s</A>:
++</P>
++<PRE>
++    %(referer)s
++    %(uri)s
++</PRE>
++<HR>
++</BODY>
++</HTML>
+diff -Nru mailman-2.1.5/templates/en/htdig_auth_failure.html mailman-2.1.5+htdig/templates/en/htdig_auth_failure.html
+--- mailman-2.1.5/templates/en/htdig_auth_failure.html	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/htdig_auth_failure.html	2005-07-04 10:04:30.290413080 +0200
+@@ -0,0 +1,22 @@
++<P>
++    You are not authorised to access the URL referenced.
++</P>
++<P>
++    This access failure may be due to: 
++</P>
++<OL>
++    <LI>
++        If cookies are disabled in your browser then your attempt to 
++        authenticate yourself for access to the desired list will have 
++        been compromised. You should enable cookies in your browser and 
++        try again. 
++    </LI>
++    <LI>
++        You have not attempted to authenticate yourself and are trying 
++        to access private data. 
++    </LI>
++    <LI>
++        An earlier attempt to authenticate yourself for access to private 
++        data failed. 
++    </LI>
++</OL>
+diff -Nru mailman-2.1.5/templates/en/htdig_conf.txt mailman-2.1.5+htdig/templates/en/htdig_conf.txt
+--- mailman-2.1.5/templates/en/htdig_conf.txt	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/htdig_conf.txt	2005-07-04 10:04:30.292412776 +0200
+@@ -0,0 +1,53 @@
++# There is nothing to language translate in this template which is for the
++# Mailman-htdig integration
++#
++# This is taken from the example config file for ht://Dig, with most comments excised
++# See the htdig.conf from the distribution you have installed
++#
++# This is the template for the per mailing list htddig.conf files
++#
++%(htdig_extras)s
++database_dir: %(databases)s
++start_url: %(starturl)s
++limit_urls_to: ${start_url}
++local_urls: %(urlpath)s=%(filepath)s
++local_urls_only: true
++url_part_aliases: %(url_part_aliases)s
++script_name: %(mmsearchcgi)s
++noindex_end: %(indexing_enable)s
++noindex_start: %(indexing_disable)s
++exclude_urls: %(excluded_urls)s
++bad_extensions: .wav .gz .z .sit .au .zip .tar .hqx .exe .com .gif \
++                .jpg .jpeg .aiff .class .map .ram .tgz .bin .rpm .mpg .mov .avi 
++maintainer: %(maintainer)s
++max_head_length: 10000
++max_doc_size: 200000
++no_excerpt_show_top: true
++search_algorithm: exact:1 synonyms:0.5 endings:0.1
++template_map: Long long ${common_dir}/long.html \
++              Short short ${common_dir}/short.html
++template_name: short
++next_page_text: <img src="%(htdig_url)s/buttonr.gif" border="0" align="middle" width="30" height="30" alt="next">
++no_next_page_text:
++prev_page_text: <img src="%(htdig_url)s/buttonl.gif" border="0" align="middle" width="30" height="30" alt="prev">
++no_prev_page_text:
++page_number_text: '<img src="%(htdig_url)s/button1.gif" border="0" align="middle" width="30" height="30" alt="1">' \
++            '<img src="%(htdig_url)s/button2.gif" border="0" align="middle" width="30" height="30" alt="2">' \
++            '<img src="%(htdig_url)s/button3.gif" border="0" align="middle" width="30" height="30" alt="3">' \
++            '<img src="%(htdig_url)s/button4.gif" border="0" align="middle" width="30" height="30" alt="4">' \
++            '<img src="%(htdig_url)s/button5.gif" border="0" align="middle" width="30" height="30" alt="5">' \
++            '<img src="%(htdig_url)s/button6.gif" border="0" align="middle" width="30" height="30" alt="6">' \
++            '<img src="%(htdig_url)s/button7.gif" border="0" align="middle" width="30" height="30" alt="7">' \
++            '<img src="%(htdig_url)s/button8.gif" border="0" align="middle" width="30" height="30" alt="8">' \
++            '<img src="%(htdig_url)s/button9.gif" border="0" align="middle" width="30" height="30" alt="9">' \
++            '<img src="%(htdig_url)s/button10.gif" border="0" align="middle" width="30" height="30" alt="10">'
++no_page_number_text: '<img src="%(htdig_url)s/button1.gif" border="2" align="middle" width="30" height="30" alt="1">' \
++            '<img src="%(htdig_url)s/button2.gif" border="2" align="middle" width="30" height="30" alt="2">' \
++            '<img src="%(htdig_url)s/button3.gif" border="2" align="middle" width="30" height="30" alt="3">' \
++            '<img src="%(htdig_url)s/button4.gif" border="2" align="middle" width="30" height="30" alt="4">' \
++            '<img src="%(htdig_url)s/button5.gif" border="2" align="middle" width="30" height="30" alt="5">' \
++            '<img src="%(htdig_url)s/button6.gif" border="2" align="middle" width="30" height="30" alt="6">' \
++            '<img src="%(htdig_url)s/button7.gif" border="2" align="middle" width="30" height="30" alt="7">' \
++            '<img src="%(htdig_url)s/button8.gif" border="2" align="middle" width="30" height="30" alt="8">' \
++            '<img src="%(htdig_url)s/button9.gif" border="2" align="middle" width="30" height="30" alt="9">' \
++            '<img src="%(htdig_url)s/button10.gif" border="2" align="middle" width="30" height="30" alt="10">'
+diff -Nru mailman-2.1.5/templates/en/htdig.html mailman-2.1.5+htdig/templates/en/htdig.html
+--- mailman-2.1.5/templates/en/htdig.html	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/htdig.html	2005-07-04 10:04:30.293412624 +0200
+@@ -0,0 +1,43 @@
++<html>
++<head>
++    <title>%(realname)s Private Archives Authentication</title>
++</head>
++<body bgcolor="#ffffff">
++<FORM METHOD=POST ACTION="%(action)s">
++%(message)s
++  <TABLE WIDTH="100%%" BORDER="0" CELLSPACING="4" CELLPADDING="5">
++    <TR>
++      <TD COLSPAN="2" WIDTH="100%%" BGCOLOR="#99CCFF" ALIGN="CENTER">
++	<B><FONT COLOR="#000000" SIZE="+1">%(realname)s Private
++	    Archives Authentication</FONT></B>
++      </TD>
++    </TR>
++    <tr>
++        <TD><div ALIGN="Right">Email address:</div></TD>
++        <TD><INPUT TYPE="text" NAME="username" SIZE="30"></TD>
++    </tr>
++    <tr>
++      <TD><div ALIGN="Right">Password:</div></TD>
++      <TD><INPUT TYPE="password" NAME="password" SIZE="30"></TD>
++    </tr>
++    <tr>
++      <td colspan=2 align="middle"><INPUT type="SUBMIT"
++                                          name="submit"
++					  value="Let me in...">
++      </td>
++    </tr>
++  </TABLE>
++      <p><strong><em>Important:</em></strong> From this point on, you
++      must have cookies enabled in your browser, otherwise no
++      administrative changes will take effect.
++
++      <p>Session cookies are used in Mailman's
++      administrative interface so that you don't need to
++      re-authenticate with every administrative operation.  This
++      cookie will expire automatically when you exit your browser, or
++      you can explicitly expire the cookie by hitting the
++      <em>Logout</em> link under <em>Other Administrative
++      Activities</em> (which you'll see once you successfully log in).
++</FORM>
++</body>
++</html>
+diff -Nru mailman-2.1.5/templates/en/TOC_htsearch.html mailman-2.1.5+htdig/templates/en/TOC_htsearch.html
+--- mailman-2.1.5/templates/en/TOC_htsearch.html	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/en/TOC_htsearch.html	2005-07-04 10:04:30.295412320 +0200
+@@ -0,0 +1,40 @@
++     <p>
++     To search this archive fill in the following form:
++     </p>
++     <p>
++       <form method="post" action="%(mmsearchcgi)s">
++       <font size="-1">
++       Match: <select name="method">
++         <option value="and">All
++         <option value="or">Any
++         <option value="boolean">Boolean
++       </select>
++       Format: <select name="format">
++         <option value="short">Short
++         <option value="long">Long
++       </select>
++       Sort by: <select name="sort">
++         <option value="score">Score
++         <option value="time">Time
++         <option value="title">Title
++         <option value="revscore">Reverse Score
++         <option value="revtime">Reverse Time
++         <option value="revtitle">Reverse Title
++       </select>
++       </font>
++       <input type="hidden" name="config" value="%(listname)s%(htsearchconf)s">
++       <!-- input type="hidden" name="restrict" value="">
++       <input type="hidden" name="exclude" value="" -->
++       <br>
++       Search:
++         <input type="text" size="30" name="words" value="">
++         <input type="submit" value="Search">
++       </form>
++     </p>
++     <p>
++         <STRONG>Note:</STRONG>The archive search index was last rebuilt at 
++         %(lastrun)s. Any postings after that will not be found by 
++         a search. Index rebuild is usally done once every 24 hours for 
++         this list. You can use a "View by date" link below to access 
++         more recent postings.
++     </p>
+diff -Nru mailman-2.1.5/templates/fr/archtoc.html mailman-2.1.5+htdig/templates/fr/archtoc.html
+--- mailman-2.1.5/templates/fr/archtoc.html	2002-12-27 16:41:04.000000000 +0100
++++ mailman-2.1.5+htdig/templates/fr/archtoc.html	2005-07-04 10:04:30.297412016 +0200
+@@ -11,6 +11,7 @@
+ 	propos de cette  liste</a> ou vous pouvez&nbsp; <a href="%(fullarch)s">t&eacute;l&eacute;charger les archives compl&egrave;tes</a>
+        (%(size)s).      
+ 	</p>
++     %(htsearch)s
+         %(noarchive_msg)s      
+ 	%(archive_listing_start)s      
+ 	%(archive_listing)s 
+diff -Nru mailman-2.1.5/templates/fr/archtoc.html.orig mailman-2.1.5+htdig/templates/fr/archtoc.html.orig
+--- mailman-2.1.5/templates/fr/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/fr/archtoc.html.orig	2005-07-04 10:04:30.299411712 +0200
+@@ -0,0 +1,19 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<html>
++<head>
++  <title>Les Archives de %(listname)s</title>
++  <meta name="robots" content="noindex,follow">
++  %(meta)s
++</head>
++<body bgcolor="#ffffff">
++	<h1>Les Archives de %(listname)s</h1>
++        <p>vous pouvez obtenir <a href="%(listinfo)s">plus d' informations &agrave;
++	propos de cette  liste</a> ou vous pouvez&nbsp; <a href="%(fullarch)s">t&eacute;l&eacute;charger les archives compl&egrave;tes</a>
++       (%(size)s).      
++	</p>
++        %(noarchive_msg)s      
++	%(archive_listing_start)s      
++	%(archive_listing)s 
++      	%(archive_listing_end)s        
++</body>
++</html>
+diff -Nru mailman-2.1.5/templates/hr/archtoc.html mailman-2.1.5+htdig/templates/hr/archtoc.html
+--- mailman-2.1.5/templates/hr/archtoc.html	2003-12-01 00:04:02.000000000 +0100
++++ mailman-2.1.5+htdig/templates/hr/archtoc.html	2005-07-04 10:04:30.301411408 +0200
+@@ -12,6 +12,7 @@
+       ili mo�ete <a href="%(fullarch)s">downloadati cijelu arhivu</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/hr/archtoc.html.orig mailman-2.1.5+htdig/templates/hr/archtoc.html.orig
+--- mailman-2.1.5/templates/hr/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/hr/archtoc.html.orig	2005-07-04 10:04:30.302411256 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>%(listname)s Arhiva</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>%(listname)s Arhiva </h1>
++     <p>
++      Mo�ete dobiti <a href="%(listinfo)s">vi�e informacija o ovoj listi</a>
++      ili mo�ete <a href="%(fullarch)s">downloadati cijelu arhivu</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/hu/archtoc.html mailman-2.1.5+htdig/templates/hu/archtoc.html
+--- mailman-2.1.5/templates/hu/archtoc.html	2002-12-12 04:30:15.000000000 +0100
++++ mailman-2.1.5+htdig/templates/hu/archtoc.html	2005-07-04 10:04:30.304410952 +0200
+@@ -12,6 +12,7 @@
+       vagy let�ltheted a <a href="%(fullarch)s">teljes nyers arch�vum�t</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/hu/archtoc.html.orig mailman-2.1.5+htdig/templates/hu/archtoc.html.orig
+--- mailman-2.1.5/templates/hu/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/hu/archtoc.html.orig	2005-07-04 10:04:30.306410648 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>A(z) %(listname)s Arch�vum</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++	 %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++	 <h1>A(z) %(listname)s Arch�vum </h1>
++     <p>
++      Tov�bbi inform�ci�kat <a href="%(listinfo)s">a list�r�l itt olvashatsz</a>
++      vagy let�ltheted a <a href="%(fullarch)s">teljes nyers arch�vum�t</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/it/archtoc.html mailman-2.1.5+htdig/templates/it/archtoc.html
+--- mailman-2.1.5/templates/it/archtoc.html	2002-11-18 22:04:56.000000000 +0100
++++ mailman-2.1.5+htdig/templates/it/archtoc.html	2005-07-04 10:04:30.308410344 +0200
+@@ -12,6 +12,7 @@
+      o puoi <a href="%(fullarch)s">scaricare l'intero archivio grezzo</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/it/archtoc.html.orig mailman-2.1.5+htdig/templates/it/archtoc.html.orig
+--- mailman-2.1.5/templates/it/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/it/archtoc.html.orig	2005-07-04 10:04:30.309410192 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++	  <title>Gli archivi della lista %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++	  <h1>Gli archivi della lista %(listname)s</h1>
++     <p>
++     Puoi ottenere <a href="%(listinfo)s">ulteriori informazioni su questa lista</a>
++     o puoi <a href="%(fullarch)s">scaricare l'intero archivio grezzo</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/it/archtocnombox.html mailman-2.1.5+htdig/templates/it/archtocnombox.html
+--- mailman-2.1.5/templates/it/archtocnombox.html	2003-12-28 23:16:30.000000000 +0100
++++ mailman-2.1.5+htdig/templates/it/archtocnombox.html	2005-07-04 10:04:30.311409888 +0200
+@@ -10,6 +10,7 @@
+      <p>
+       <a href="%(listinfo)s">Maggiori informazioni su questa lista</a>.
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/it/archtocnombox.html.orig mailman-2.1.5+htdig/templates/it/archtocnombox.html.orig
+--- mailman-2.1.5/templates/it/archtocnombox.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/it/archtocnombox.html.orig	2005-07-04 10:04:30.313409584 +0200
+@@ -0,0 +1,18 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Gli archivi di %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Gli archivi di %(listname)s</h1>
++     <p>
++      <a href="%(listinfo)s">Maggiori informazioni su questa lista</a>.
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/ja/archtoc.html mailman-2.1.5+htdig/templates/ja/archtoc.html
+--- mailman-2.1.5/templates/ja/archtoc.html	2004-01-23 01:54:16.000000000 +0100
++++ mailman-2.1.5+htdig/templates/ja/archtoc.html	2005-07-04 10:04:30.315409280 +0200
+@@ -12,6 +12,7 @@
+       <a href="%(fullarch)s">�����Υ᡼���mbox�����ǥ����������</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/ja/archtoc.html.orig mailman-2.1.5+htdig/templates/ja/archtoc.html.orig
+--- mailman-2.1.5/templates/ja/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/ja/archtoc.html.orig	2005-07-04 10:04:30.316409128 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>%(listname)s ��¸���</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>%(listname)s ��¸���</h1>
++     <p>
++      <a href="%(listinfo)s">�ꥹ�Ȥΰ���</a> *
++      <a href="%(fullarch)s">�����Υ᡼���mbox�����ǥ����������</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/lt/archtoc.html mailman-2.1.5+htdig/templates/lt/archtoc.html
+--- mailman-2.1.5/templates/lt/archtoc.html	2002-12-24 20:05:13.000000000 +0100
++++ mailman-2.1.5+htdig/templates/lt/archtoc.html	2005-07-04 10:04:30.318408824 +0200
+@@ -11,6 +11,7 @@
+       <a href="%(fullarch)s">�ia - atsisi�sti vis� forumo archyv�</a>.
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/lt/archtoc.html.orig mailman-2.1.5+htdig/templates/lt/archtoc.html.orig
+--- mailman-2.1.5/templates/lt/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/lt/archtoc.html.orig	2005-07-04 10:04:30.320408520 +0200
+@@ -0,0 +1,19 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Forumo %(listname)s archyvai</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Forumo %(listname)s archyvai</h1>
++     <p>
++      <a href="%(listinfo)s">Paspaud� �ia galite su�inoti daugiau apie forum�</a>;
++      <a href="%(fullarch)s">�ia - atsisi�sti vis� forumo archyv�</a>.
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/no/archtoc.html mailman-2.1.5+htdig/templates/no/archtoc.html
+--- mailman-2.1.5/templates/no/archtoc.html	2002-11-18 22:04:57.000000000 +0100
++++ mailman-2.1.5+htdig/templates/no/archtoc.html	2005-07-04 10:04:30.322408216 +0200
+@@ -12,6 +12,7 @@
+       eller du kan <a href="%(fullarch)s">laste ned hele arkivet</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/no/archtoc.html.orig mailman-2.1.5+htdig/templates/no/archtoc.html.orig
+--- mailman-2.1.5/templates/no/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/no/archtoc.html.orig	2005-07-04 10:04:30.324407912 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>%(listname)s arkivet</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>%(listname)s arkivet </h1>
++     <p>
++      Du kan se <a href="%(listinfo)s">mer informasjon om denne listen</a>
++      eller du kan <a href="%(fullarch)s">laste ned hele arkivet</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/no/archtocnombox.html mailman-2.1.5+htdig/templates/no/archtocnombox.html
+--- mailman-2.1.5/templates/no/archtocnombox.html	2003-12-31 00:49:01.000000000 +0100
++++ mailman-2.1.5+htdig/templates/no/archtocnombox.html	2005-07-04 10:04:30.325407760 +0200
+@@ -10,6 +10,7 @@
+      <p>
+       Du kan se <a href="%(listinfo)s">mer informasjon om denne listen</a>.
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/no/archtocnombox.html.orig mailman-2.1.5+htdig/templates/no/archtocnombox.html.orig
+--- mailman-2.1.5/templates/no/archtocnombox.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/no/archtocnombox.html.orig	2005-07-04 10:04:30.327407456 +0200
+@@ -0,0 +1,18 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>%(listname)s arkivet</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>%(listname)s arkivet </h1>
++     <p>
++      Du kan se <a href="%(listinfo)s">mer informasjon om denne listen</a>.
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/pl/archtoc.html mailman-2.1.5+htdig/templates/pl/archtoc.html
+--- mailman-2.1.5/templates/pl/archtoc.html	2003-04-20 06:52:59.000000000 +0200
++++ mailman-2.1.5+htdig/templates/pl/archtoc.html	2005-07-04 10:04:30.329407152 +0200
+@@ -12,6 +12,7 @@
+       albo <a href="%(fullarch)s">�ci�gn�� ca�e archiwum</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/pl/archtoc.html.orig mailman-2.1.5+htdig/templates/pl/archtoc.html.orig
+--- mailman-2.1.5/templates/pl/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/pl/archtoc.html.orig	2005-07-04 10:04:30.332406696 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Archiwum listy %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Archiwum listy %(listname)s</h1>
++     <p>
++      Mo�esz odwiedzi� <a href="%(listinfo)s">stron� informacyjn� tej listy</a>,
++      albo <a href="%(fullarch)s">�ci�gn�� ca�e archiwum</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/pt/archtoc.html mailman-2.1.5+htdig/templates/pt/archtoc.html
+--- mailman-2.1.5/templates/pt/archtoc.html	2003-04-09 07:09:01.000000000 +0200
++++ mailman-2.1.5+htdig/templates/pt/archtoc.html	2005-07-04 10:04:30.333406544 +0200
+@@ -13,6 +13,7 @@
+ 	  n�o processado</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/pt/archtoc.html.orig mailman-2.1.5+htdig/templates/pt/archtoc.html.orig
+--- mailman-2.1.5/templates/pt/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/pt/archtoc.html.orig	2005-07-04 10:04:30.335406240 +0200
+@@ -0,0 +1,21 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Arquivos de %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Arquivos de %(listname)s</h1>
++     <p>
++      Pode ter <a href="%(listinfo)s">mais informa��o sobre esta lista</a>
++      ou pode <a href="%(fullarch)s">descarregar o arquivo completo, 
++	  n�o processado</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/ro/archtoc.html mailman-2.1.5+htdig/templates/ro/archtoc.html
+--- mailman-2.1.5/templates/ro/archtoc.html	2003-12-13 17:35:53.000000000 +0100
++++ mailman-2.1.5+htdig/templates/ro/archtoc.html	2005-07-04 10:04:30.337405936 +0200
+@@ -13,6 +13,7 @@
+       sau pute�i <a href="%(fullarch)s">desc�rca �ntreaga arhiv� �n form� brut�</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/ro/archtoc.html.orig mailman-2.1.5+htdig/templates/ro/archtoc.html.orig
+--- mailman-2.1.5/templates/ro/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/ro/archtoc.html.orig	2005-07-04 10:04:30.339405632 +0200
+@@ -0,0 +1,21 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Arhivele listei %(listname)s</title>
++     <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-2">
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Arhivele listei de discu�ii %(listname)s</h1>
++     <p>
++      Pute�i ob�ine <a href="%(listinfo)s">mai multe detalii despre aceast� list�</a>
++      sau pute�i <a href="%(fullarch)s">desc�rca �ntreaga arhiv� �n form� brut�</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/ru/archtoc.html mailman-2.1.5+htdig/templates/ru/archtoc.html
+--- mailman-2.1.5/templates/ru/archtoc.html	2002-11-18 22:04:57.000000000 +0100
++++ mailman-2.1.5+htdig/templates/ru/archtoc.html	2005-07-04 10:04:30.341405328 +0200
+@@ -11,6 +11,7 @@
+      ��������.  �� ����� ������ <a href="%(fullarch)s">���������</a> ����
+      ����� � ������� mbox (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/ru/archtoc.html.orig mailman-2.1.5+htdig/templates/ru/archtoc.html.orig
+--- mailman-2.1.5/templates/ru/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/ru/archtoc.html.orig	2005-07-04 10:04:30.342405176 +0200
+@@ -0,0 +1,19 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>����� %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>����� %(listname)s</h1>
++     <p><a href="%(listinfo)s">�����</a> �� ������� ���������� � ������
++     ��������.  �� ����� ������ <a href="%(fullarch)s">���������</a> ����
++     ����� � ������� mbox (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/sl/archtoc.html mailman-2.1.5+htdig/templates/sl/archtoc.html
+--- mailman-2.1.5/templates/sl/archtoc.html	2003-10-04 04:57:36.000000000 +0200
++++ mailman-2.1.5+htdig/templates/sl/archtoc.html	2005-07-04 10:04:30.344404872 +0200
+@@ -12,6 +12,7 @@
+       ali pa <a href="%(fullarch)s">prenesete celoten raw arhiv</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/sl/archtoc.html.orig mailman-2.1.5+htdig/templates/sl/archtoc.html.orig
+--- mailman-2.1.5/templates/sl/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/sl/archtoc.html.orig	2005-07-04 10:04:30.346404568 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Arhivi za seznam %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Arhivi za seznam %(listname)s</h1>
++     <p>
++      Ogledate si lahko <a href="%(listinfo)s">dodatne informacije o tem seznamu</a>
++      ali pa <a href="%(fullarch)s">prenesete celoten raw arhiv</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
+diff -Nru mailman-2.1.5/templates/tr/archtoc.html mailman-2.1.5+htdig/templates/tr/archtoc.html
+--- mailman-2.1.5/templates/tr/archtoc.html	2004-04-25 04:30:04.000000000 +0200
++++ mailman-2.1.5+htdig/templates/tr/archtoc.html	2005-07-04 10:04:30.348404264 +0200
+@@ -12,6 +12,7 @@
+       veya <a href="%(fullarch)s">t�m ar�ivi indirebilirsiniz</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/tr/archtoc.html.orig mailman-2.1.5+htdig/templates/tr/archtoc.html.orig
+--- mailman-2.1.5/templates/tr/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/tr/archtoc.html.orig	2005-07-04 10:04:30.349404112 +0200
+@@ -0,0 +1,21 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>%(listname)s Ar�ivleri</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>%(listname)s Ar�ivleri </h1>
++     <p>
++      <a href="%(listinfo)s">Bu listeyle ilgili daha fazla bilgi</a> alabilirsiniz
++      veya <a href="%(fullarch)s">t�m ar�ivi indirebilirsiniz</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
++
+diff -Nru mailman-2.1.5/templates/uk/archtoc.html mailman-2.1.5+htdig/templates/uk/archtoc.html
+--- mailman-2.1.5/templates/uk/archtoc.html	2003-09-22 05:52:35.000000000 +0200
++++ mailman-2.1.5+htdig/templates/uk/archtoc.html	2005-07-04 10:04:30.351403808 +0200
+@@ -12,6 +12,7 @@
+       або <a href="%(fullarch)s">завантажити архів у форматі mbox</a>
+       (%(size)s).
+      </p>
++     %(htsearch)s
+      %(noarchive_msg)s
+      %(archive_listing_start)s
+      %(archive_listing)s
+diff -Nru mailman-2.1.5/templates/uk/archtoc.html.orig mailman-2.1.5+htdig/templates/uk/archtoc.html.orig
+--- mailman-2.1.5/templates/uk/archtoc.html.orig	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+htdig/templates/uk/archtoc.html.orig	2005-07-04 10:04:30.353403504 +0200
+@@ -0,0 +1,20 @@
++<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
++<HTML>
++  <HEAD>
++     <title>Архів %(listname)s</title>
++     <META NAME="robots" CONTENT="noindex,follow">
++     %(meta)s
++  </HEAD>
++  <BODY BGCOLOR="#ffffff">
++     <h1>Архіви %(listname)s</h1>
++     <p>
++      Ви можете отримати <a href="%(listinfo)s">докладну інформацію  про цей список розсилання</a>
++      або <a href="%(fullarch)s">завантажити архів у форматі mbox</a>
++      (%(size)s).
++     </p>
++     %(noarchive_msg)s
++     %(archive_listing_start)s
++     %(archive_listing)s
++     %(archive_listing_end)s
++     </BODY>
++     </HTML>
diff -Naur mailman-2.1.5/debian/patches/70_spamassassin_integration.dpatch mailman-2.1.5-9.htdig+spamassasin.2/debian/patches/70_spamassassin_integration.dpatch
--- mailman-2.1.5/debian/patches/70_spamassassin_integration.dpatch	1970-01-01 01:00:00.000000000 +0100
+++ mailman-2.1.5-9.htdig+spamassasin.2/debian/patches/70_spamassassin_integration.dpatch	2005-07-06 08:15:48.000000000 +0200
@@ -0,0 +1,276 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 70_spamassassin_integration.dpatch based on work by Jon Parise <[email-masked]>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Integration of Mailman + SpamAssassin.
+## DP: Please refer to http://sourceforge.net/tracker/index.php?func=detail&aid=640518&group_id=103&atid=300103 for the original implementation.
+## DP: This patch base on work by Will Andrews and Greg Veldman.
+## DP: Please refer to http://firepipe.net/patches/mm215-sa.diff
+## DP: for the original patch.
+
+@DPATCH@
+diff -Naur mailman-2.1.5/Mailman/Defaults.py.in mailman-2.1.5+sa/Mailman/Defaults.py.in
+--- mailman-2.1.5/Mailman/Defaults.py.in	2005-07-05 09:34:11.742719848 +0200
++++ mailman-2.1.5+sa/Mailman/Defaults.py.in	2005-07-05 09:34:57.351786216 +0200
+@@ -447,6 +447,7 @@
+ # global pipeline by defining a `pipeline' attribute.
+ GLOBAL_PIPELINE = [
+     # These are the modules that do tasks common to all delivery paths.
++    'SpamAssassin',
+     'SpamDetect',
+     'Approve',
+     'Replybot',
+@@ -1172,6 +1173,17 @@
+            'nodupes' : DontReceiveDuplicates
+            }
+ 
++## Default SpamAssassin variables
++# global variables
++SPAMASSASSIN_SPAMD_HOST = 'localhost'
++SPAMASSASSIN_SPAMD_PORT = 783
++SPAMASSASSIN_PROTOCOL_VERSION = "SPAMC/1.3"
++# list variables
++DEFAULT_SPAMASSASSIN_DISCARD_SCORE = 10
++DEFAULT_SPAMASSASSIN_HOLD_SCORE = 5
++DEFAULT_SPAMASSASSIN_MEMBER_BONUS = 2
++DEFAULT_SPAMASSASSIN_ENABLE = 1
++
+ # Authentication contexts.
+ #
+ # Mailman defines the following roles:
+diff -Naur mailman-2.1.5/Mailman/Gui/Privacy.py mailman-2.1.5+sa/Mailman/Gui/Privacy.py
+--- mailman-2.1.5/Mailman/Gui/Privacy.py	2005-07-05 09:34:10.256945720 +0200
++++ mailman-2.1.5+sa/Mailman/Gui/Privacy.py	2005-07-05 09:34:57.351786216 +0200
+@@ -42,6 +42,7 @@
+                     ('sender',      _('Sender&nbsp;filters')),
+                     ('recipient',   _('Recipient&nbsp;filters')),
+                     ('spam',        _('Spam&nbsp;filters')),
++                    ('sa',          _('SpamAssassin&nbsp;filters')),
+                     ]
+         return None
+ 
+@@ -405,12 +406,39 @@
+              bracketing it.""")),
+           ]
+ 
++        sa_rtn = [
++           _("""This section allows you to configure
++           <a href="http://spamassassin.org/">SpamAssassin</a> filters.
++           """),
++
++           _("SpamAssassin filters"),
++
++            ('sa_enable', mm_cfg.Radio, (_('No'), _('Yes')), 0,
++            _('Enable SpamAssassin.'),
++            _("""Enables SpamAssassin or not.  Note that this depends on
++            SpamAssassin being enabled on the site.""")),
++           ('sa_hold_score', mm_cfg.Number, 5, 0,
++            _('SpamAssassin score required to be held for moderation.'),
++            _("""Hold score: The SpamAssassin score that a message post to
++            the list must achieve before it is held for moderation.""")),
++           ('sa_discard_score', mm_cfg.Number, 5, 0,
++            _('SpamAssassin score required to be discarded.'),
++            _("""Discard score: The SpamAssassin score that a message post to
++            the list must achieve before it is discarded altogether.""")),
++           ('sa_member_bonus', mm_cfg.Number, 5, 0,
++            _('Bonus score subtracted for members.'),
++            _("""Member bonus: The bonus provided to a member of the list,
++            to increase the likelihood that their message will be posted.""")),
++          ]
++
+         if subcat == 'sender':
+             return sender_rtn
+         elif subcat == 'recipient':
+             return recip_rtn
+         elif subcat == 'spam':
+             return spam_rtn
++        elif subcat == 'sa':
++            return sa_rtn
+         else:
+             return subscribing_rtn
+ 
+diff -Naur mailman-2.1.5/Mailman/Handlers/SpamAssassin.py mailman-2.1.5+sa/Mailman/Handlers/SpamAssassin.py
+--- mailman-2.1.5/Mailman/Handlers/SpamAssassin.py	1970-01-01 01:00:00.000000000 +0100
++++ mailman-2.1.5+sa/Mailman/Handlers/SpamAssassin.py	2005-07-05 09:34:57.352786064 +0200
+@@ -0,0 +1,140 @@
++# Copyright (C) 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
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++# 
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++# 
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software 
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++"""Perform spam detection using SpamAssassin.
++
++SpamAssassin:   http://www.spamassassin.org/
++
++Messages are passed to the spamd (SpamAssassin) daemon for analysis and
++scoring.  Depending on the score, messages may be rejected or held for
++moderation.
++"""
++
++import re
++import socket
++import string
++
++from Mailman import mm_cfg
++from Mailman import Errors
++from Mailman.Handlers import Hold
++from Mailman.Logging.Syslog import syslog
++
++# First, play footsie with _ so that the following are marked as translated,
++# but aren't actually translated until we need the text later on.
++def _(s):
++    return s
++
++
++class SpamAssassinDiscard(Errors.DiscardMessage):
++    """The message scored above the discard threshold"""
++
++    reason = _('SpamAssassin identified this message as spam')
++    rejection = _('Your message was identified as spam.')
++
++
++class SpamAssassinHold(Errors.HoldMessage):
++    """The message scored above the hold threshold"""
++
++    reason = _('SpamAssassin identified this message as spam')
++    rejection = _('Your message was identified as spam.')
++
++
++def process(mlist, msg, msgdata):
++    if msgdata.get('approved'):
++        return
++    # check that this list wants spamassassin checking in the first place
++    if mlist.sa_enable == 0:
++        return
++    # Pass the flattened string representation of the message to spamd.
++    score, symbols = check_message(str(msg))
++    # If the member bonus has been enabled, check if the sender is a member.
++    if mlist.sa_member_bonus:
++        # Look for the sender(s) in the membership roster.
++        for sender in msg.get_senders():
++            if mlist.isMember(sender):
++                break
++        else:
++            sender = None    
++        # If the sender is a member, apply the bonus to the score.
++        if sender:
++            score = score - mlist.sa_member_bonus
++    # Should this message be discarded?
++    if score > mlist.sa_discard_score:
++        listname = mlist.real_name
++        sender = msg.get_sender()
++        syslog('vette', '%s post from %s discarded: '
++                        'SpamAssassin score was %s (discard threshold is %s)'
++                          % (listname, sender, score, mlist.sa_discard_score))
++        raise SpamAssassinDiscard
++    # If not, should it be held for approval?
++    elif score > mlist.sa_hold_score:
++        listname = mlist.real_name
++        sender = msg.get_sender()
++        syslog('vette', '%s post from %s held: '
++                        'SpamAssassin score was %s (hold threshold is %s)'
++                          % (listname, sender, score, mlist.sa_hold_score))
++        Hold.hold_for_approval(mlist, msg, msgdata,
++                               SpamAssassinHold(score, symbols))
++
++# Compile the regular expressions for interpreting spamd's results.
++resp_re = re.compile(r'^SPAMD/([\d.]+)\s+(-?\d+)\s+(.*)')
++spam_re = re.compile(r'^Spam:\s*(True|False)\s*;\s*(-?[\d.]+)\s*/\s*(-?[\d.]+)')
++
++
++def check_message(message):
++    score = -1
++    symbols = ''
++
++    try:
++        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
++        sock.connect((mm_cfg.SPAMASSASSIN_SPAMD_HOST,
++		      mm_cfg.SPAMASSASSIN_SPAMD_PORT))
++        # Build the spamd request header.
++        header = 'SYMBOLS %s\r\nUser: %s\r\nContent-length: %s\r\n\r\n' % \
++                 (mm_cfg.SPAMASSASSIN_PROTOCOL_VERSION, mm_cfg.MAILMAN_USER,
++		  len(message))
++        # Send the header and message to spamd for analysis.
++        sock.send(header)
++        sock.send(message)
++        sock.shutdown(1)
++        # Create a file description from the socket.
++        fd = sock.makefile('r')
++        # Get the result code from spamd.
++        line = fd.readline()
++        match = resp_re.match(line)
++        if not match:
++            syslog('error', 'failed to get result code from spamd')
++            # Return the default score and symbols.
++            return score, symbols
++        if not match.group(2) == '0':
++            syslog('error', 'spamd returned non-zero code: %s' % match.group(3))
++            # Return the default score and symbols.
++            return score, symbols
++        # Get the message's score.
++        line = fd.readline()
++        while line and not line == '\r\n':
++            match = spam_re.match(line)
++            if match: score = float(match.group(2))
++            line = fd.readline()
++        # Read in the symbols representing the spam report.
++        symbols = fd.read()
++        symbols = string.replace(symbols, '\r\n', '\n')
++    except socket.error:
++        pass
++    except IOError:
++        pass
++    # Return the score and symbols from spamd.
++    return score, symbols
+diff -Naur mailman-2.1.5/Mailman/MailList.py mailman-2.1.5+sa/Mailman/MailList.py
+--- mailman-2.1.5/Mailman/MailList.py	2005-07-05 09:34:10.266944200 +0200
++++ mailman-2.1.5+sa/Mailman/MailList.py	2005-07-05 09:35:34.690109928 +0200
+@@ -383,6 +383,12 @@
+         else:
+             self.encode_ascii_prefixes = 2
+ 
++        # SpamAssassin variables
++        self.sa_enable = mm_cfg.DEFAULT_SPAMASSASSIN_ENABLE
++        self.sa_hold_score = mm_cfg.DEFAULT_SPAMASSASSIN_HOLD_SCORE
++        self.sa_discard_score = mm_cfg.DEFAULT_SPAMASSASSIN_DISCARD_SCORE
++        self.sa_member_bonus = mm_cfg.DEFAULT_SPAMASSASSIN_MEMBER_BONUS
++
+ 
+     #
+     # Web API support via administrative categories
+@@ -665,7 +671,7 @@
+     #
+     def CheckVersion(self, stored_state):
+         """Auto-update schema if necessary."""
+-        if self.data_version >= mm_cfg.DATA_FILE_VERSION:
++        if self.data_version >= mm_cfg.DATA_FILE_VERSION and self.__dict__.has_key('sa_enable'):
+             return
+         # Initialize any new variables
+         self.InitVars()
+diff -Naur mailman-2.1.5/Mailman/versions.py mailman-2.1.5+sa/Mailman/versions.py
+--- mailman-2.1.5/Mailman/versions.py	2005-07-05 09:34:10.267944048 +0200
++++ mailman-2.1.5+sa/Mailman/versions.py	2005-07-05 09:34:57.353785912 +0200
+@@ -394,6 +394,12 @@
+     add_only_if_missing('encode_ascii_prefixes', encode)
+     add_only_if_missing('news_moderation', 0)
+     add_only_if_missing('header_filter_rules', [])
++    add_only_if_missing('sa_enable', mm_cfg.DEFAULT_SPAMASSASSIN_ENABLE)
++    add_only_if_missing('sa_hold_score', mm_cfg.DEFAULT_SPAMASSASSIN_HOLD_SCORE)
++    add_only_if_missing('sa_discard_score',
++                        mm_cfg.DEFAULT_SPAMASSASSIN_DISCARD_SCORE)
++    add_only_if_missing('sa_member_bonus',
++                        mm_cfg.DEFAULT_SPAMASSASSIN_MEMBER_BONUS)
+ 
+ 
+ 
diff -Naur mailman-2.1.5/debian/postinst mailman-2.1.5-9.htdig+spamassasin.2/debian/postinst
--- mailman-2.1.5/debian/postinst	2005-07-11 08:36:23.092983896 +0200
+++ mailman-2.1.5-9.htdig+spamassasin.2/debian/postinst	2005-07-07 21:56:57.000000000 +0200
@@ -159,6 +159,9 @@
 # turn this on if the internal archiver is used and
 # GZIP_ARCHIVE_TXT_FILES is false in mm_cfg.py
 27 3 * * * list [ -x /usr/lib/mailman/cron/nightly_gzip ] && /usr/lib/mailman/cron/nightly_gzip
+#
+# At 5:00am every night, regenerate the ht://Dig index files.
+0 5 * * * list [ -x /usr/lib/mailman/cron/nightly_htdig -a -x /usr/lib/cgi-bin/htsearch ] && /usr/lib/mailman/cron/nightly_htdig
 EOF
     elif dpkg --compare-versions "$2" lt 2.1; then
         # In versions before 2.1, /etc/cron.{daily,monthly}/mailman did 
@@ -206,6 +209,13 @@
 27 3 * * * list [ -x /usr/lib/mailman/cron/nightly_gzip ] && /usr/lib/mailman/cron/nightly_gzip
 EOF
     fi
+    if dpkg --compare-versions "$2" lt "2.1.5-10"; then
+	grep -q '/usr/lib/mailman/cron/nightly_htdig' /etc/cron.d/mailman || cat >> /etc/cron.d/mailman <<EOF
+#
+# At 5:00am every night, regenerate the ht://Dig index files.
+0 5 * * * list [ -x /usr/lib/mailman/cron/nightly_htdig -a -x /usr/lib/cgi-bin/htsearch ] && /usr/lib/mailman/cron/nightly_htdig
+EOF
+    fi
 
     # This fuckup got in 2.1-4, it should be removed at sarge + 1
     for pattern in '0 8 \* \* \* /usr/lib/mailman/cron/checkdbs'\