[Pkg-dspam-commits] [pkg-dspam-commits] r200 - in branches/experimental/debian: . patches

Julien Valroff julien-guest at alioth.debian.org
Wed Aug 12 10:56:30 UTC 2009


Author: julien-guest
Date: Wed Aug 12 10:56:29 2009
New Revision: 200

Log:
Updates for recent git updates, removed various ucf calls

Added:
   branches/experimental/debian/patches/complete_l10n.dpatch   (contents, props changed)
   branches/experimental/debian/patches/remove-daily-quarantine-pref-from-webui.dpatch   (contents, props changed)
   branches/experimental/debian/patches/templates_fr.dpatch   (contents, props changed)
   branches/experimental/debian/patches/where-to-find-txt-files.dpatch   (contents, props changed)
Modified:
   branches/experimental/debian/TODO.Debian
   branches/experimental/debian/changelog
   branches/experimental/debian/control
   branches/experimental/debian/copyright
   branches/experimental/debian/dspam-apache2.conf
   branches/experimental/debian/dspam-webfrontend.dirs
   branches/experimental/debian/dspam-webfrontend.install
   branches/experimental/debian/dspam-webfrontend.lintian-overrides
   branches/experimental/debian/dspam-webfrontend.postinst
   branches/experimental/debian/dspam-webfrontend.postrm
   branches/experimental/debian/dspam.cron.daily
   branches/experimental/debian/dspam.default
   branches/experimental/debian/dspam.install
   branches/experimental/debian/dspam.manpages
   branches/experimental/debian/libdspam7-drv-mysql.cron.daily
   branches/experimental/debian/libdspam7-drv-mysql.postrm
   branches/experimental/debian/libdspam7-drv-pgsql.postrm
   branches/experimental/debian/patches/00list
   branches/experimental/debian/patches/clean-manpages.dpatch
   branches/experimental/debian/patches/drivers-in-usr_lib_dspam.dpatch
   branches/experimental/debian/patches/dspam-default.prefs-in_etc.dpatch
   branches/experimental/debian/patches/dspam-webfrontend-config-debian.dpatch
   branches/experimental/debian/patches/dspam_notify.dpatch
   branches/experimental/debian/patches/path-to-dspam_for-training-script.dpatch
   branches/experimental/debian/patches/update-dspam.conf.dpatch
   branches/experimental/debian/rules

Modified: branches/experimental/debian/TODO.Debian
==============================================================================
--- branches/experimental/debian/TODO.Debian	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/TODO.Debian	Wed Aug 12 10:56:29 2009	(r200)
@@ -1,4 +1,7 @@
 TODO list for DSPAM debian packages
 
-* Move the .cgi files out of /var/www/dspam/; requires configuring
-  apache2-suexec-custom.
+* Move the .cgi files out of /var/www/dspam/
+  See discussion at:
+  http://lists.alioth.debian.org/pipermail/pkg-dspam-misc/2009-August/000649.html
+
+* Install some or all of the contribs (TB plugin as a separate package?)

Modified: branches/experimental/debian/changelog
==============================================================================
--- branches/experimental/debian/changelog	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/changelog	Wed Aug 12 10:56:29 2009	(r200)
@@ -1,4 +1,4 @@
-dspam (3.9.0~beta1+git20090802-1) experimental; urgency=low
+dspam (3.9.0~beta2-1) experimental; urgency=low
 
   [ Kurt B. Kaiser ]
   * debian/rules: don't use --build config option if host equals target.
@@ -23,7 +23,7 @@
     - Clean up customize-cgi.txt and add it to README.Debian. 
 
   [ Julien Valroff ]
-  * New upstream development snapshot
+  * New upstream beta
     (Closes: #418736, #491387, #505010, #514498, #522645)
   * Bump Standards to 3.8.2
   * Bump debhelper compatibility to 7
@@ -37,13 +37,11 @@
   * Fix DM-Upload-Allowed field (remove XS- prefix)
   * Add TODO.Debian file to describe planned changes to DSPAM Debian packages
   * Fix watch file to track upstream releases on new hosting location
-  * Install dspam_notify script for daily quarantine summary and add its manpage
   * Remove /var/run/dspam from dspam.dirs to make lintian happy - the init
     script makes sure the directory is created before starting dspam
   * Install examples scripts using dh_installexamples
   * Update SQL schemas and make sure the databases are updated when upgrading
     from 3.6.8 using dbconfig-common
-  * Use --debconf-ok when calling ucf
   * Set default database name and user name to dspam for both MySQL and PgSQL
   * Make dspam-webfrontend suggest apache2
   * Remove Aurélien Labrosse from Uploaders (Closes: #503488)
@@ -53,13 +51,17 @@
   * Remove lintian overrides for files in /var/www/ - moving these files
     is on the task list
   * Fix MySQL daily cronjob to work correctly when using storage profiles
+  * Make MySQL daily cronjob quiet
   * Fix build-dependencies to use current automake version and use
     unversionned libmysqclient-dev
   * Drop runtime dependencies on debconf - unneeded as this package
     is "required"
-  * Purge ucf database on package purge
+  * Purge ucf database and ucf config files on package purge
+  * Remove unused lintian overrides
+  * Add patch to allow complete translation of the WebUI
+  * Add description to all patches
 
- -- Julien Valroff <julien at kirya.net>  Sun, 02 Aug 2009 10:44:15 +0200
+ -- Julien Valroff <julien at kirya.net>  Wed, 12 Aug 2009 10:05:46 +0200
 
 dspam (3.6.8-9) unstable; urgency=low
 

Modified: branches/experimental/debian/control
==============================================================================
--- branches/experimental/debian/control	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/control	Wed Aug 12 10:56:29 2009	(r200)
@@ -42,7 +42,7 @@
 Package: dspam-webfrontend
 Priority: extra
 Architecture: all
-Depends: ${misc:Depends}, dspam (>= ${source:Version}), ucf, libgd-gd2-noxpm-perl | libgd-gd2-perl, libgd-graph3d-perl
+Depends: ${misc:Depends}, dspam (>= ${source:Version}), ucf (>= 0.28), libgd-gd2-noxpm-perl | libgd-gd2-perl, libgd-graph3d-perl
 Suggests: apache2, apache2-suexec (>= 2.2.9-3), libapache2-mod-perl2, libapache2-mod-auth-kerb | libapache2-mod-auth-mysql | libapache2-mod-auth-openid | libapache2-mod-auth-pam | libapache2-mod-auth-pgsql | libapache2-mod-auth-plain | libapache2-mod-auth-radius | libapache2-mod-auth-sys-group
 Description: Webfrontend for DSPAM anti-spam filter
  DSPAM is a dedicated statistical filter with minimal resources. It includes

Modified: branches/experimental/debian/copyright
==============================================================================
--- branches/experimental/debian/copyright	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/copyright	Wed Aug 12 10:56:29 2009	(r200)
@@ -7,7 +7,6 @@
 
 DSPAM v3.9.0
 Copyright (c) 2002-2009 DSPAM Project
-
 Original Work By
   Lead development: Jonathan A. Zdziarski <jonathan at nuclearelephant.com>
   Postgres driver: Rustam Aliyev <rustam at azernews.com>
@@ -25,6 +24,11 @@
   Dov Zamir
   Stevan Bajic
 
+inet_ntoa_r() in src/util.c is licensed under BSD licence
+
+On Debian systems, the complete text of the GNU General Public License
+can be found in /usr/share/common-licenses/BSD
+
 This package is licensed under the GPL-2.
 
 You should have received a copy of the GNU General Public License

Modified: branches/experimental/debian/dspam-apache2.conf
==============================================================================
--- branches/experimental/debian/dspam-apache2.conf	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam-apache2.conf	Wed Aug 12 10:56:29 2009	(r200)
@@ -17,18 +17,22 @@
     Servername 127.0.0.123
     SuexecUserGroup dspam dspam
     Alias /dspam /var/www/dspam/
-    Alias /etc/dspam /etc/dspam
+    Alias /usr/share/dspam /usr/share/dspam/
     LogLevel debug
     <Directory /var/www/dspam/>
         Addhandler cgi-script .cgi
         Options +ExecCGI +MultiViews -Indexes
-        AuthType Basic
         AllowOverride None
+        AuthType Basic
         AuthName "DSPAM Control Center"
         AuthUserFile /etc/dspam/passwd
         Require valid-user
         DirectoryIndex dspam.cgi
     </Directory>
+    <Directory /usr/share/dspam/>
+        Options -Indexes
+        AllowOverride None
+    </Directory>
 </VirtualHost>
 
 # The above configuration is provided only as an example.  For serious work

Modified: branches/experimental/debian/dspam-webfrontend.dirs
==============================================================================
--- branches/experimental/debian/dspam-webfrontend.dirs	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam-webfrontend.dirs	Wed Aug 12 10:56:29 2009	(r200)
@@ -1,2 +0,0 @@
-var/www/dspam/
-etc/dspam/templates/

Modified: branches/experimental/debian/dspam-webfrontend.install
==============================================================================
--- branches/experimental/debian/dspam-webfrontend.install	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam-webfrontend.install	Wed Aug 12 10:56:29 2009	(r200)
@@ -1,9 +1,13 @@
 webui/cgi-bin/*.cgi 			var/www/dspam/
-webui/cgi-bin/templates/*.html		usr/share/dspam/templates/
+webui/cgi-bin/templates/*.html		etc/dspam/templates/
+webui/cgi-bin/templates/fr/*.html	etc/dspam/templates/fr
+webui/cgi-bin/templates/he/*.html	etc/dspam/templates/he
+webui/cgi-bin/templates/ro/*.html	etc/dspam/templates/ro
+webui/cgi-bin/templates/strings.txt	etc/dspam/templates/
 webui/cgi-bin/configure.pl		usr/share/dspam/
 webui/htdocs/base.css 			usr/share/dspam/
 webui/htdocs/dspam.js			usr/share/dspam/
 webui/htdocs/dspam-logo-small.gif	usr/share/dspam/
-webui/cgi-bin/admins 			usr/share/dspam/
-webui/cgi-bin/rgb.txt			usr/share/dspam/
-debian/dspam-apache2.conf		usr/share/dspam/
+webui/cgi-bin/admins 			etc/dspam/
+webui/cgi-bin/rgb.txt			etc/dspam/
+debian/dspam-apache2.conf		etc/dspam/

Modified: branches/experimental/debian/dspam-webfrontend.lintian-overrides
==============================================================================
--- branches/experimental/debian/dspam-webfrontend.lintian-overrides	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam-webfrontend.lintian-overrides	Wed Aug 12 10:56:29 2009	(r200)
@@ -1,2 +1,2 @@
-dspam-webfrontend: script-not-executable ./etc/dspam/webfrontend.conf
 dspam-webfrontend: script-not-executable ./usr/share/dspam/configure.pl
+dspam-webfrontend: script-not-executable ./etc/dspam/templates/strings.txt

Modified: branches/experimental/debian/dspam-webfrontend.postinst
==============================================================================
--- branches/experimental/debian/dspam-webfrontend.postinst	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam-webfrontend.postinst	Wed Aug 12 10:56:29 2009	(r200)
@@ -24,21 +24,6 @@
             dpkg-statoverride --update --add dspam dspam 0644 \
                               /etc/dspam/webfrontend.conf
         fi
-
-	for i in base.css dspam-logo-small.gif rgb.txt dspam.js \
-		dspam-apache2.conf admins
-	do
-		ucf /usr/share/dspam/$i /etc/dspam/$i
-		ucfr dspam-webfrontend /etc/dspam/$i
-	done
-
-        for i in /usr/share/dspam/templates/*
-        do
-            base=`basename $i`
-            ucf /usr/share/dspam/templates/$base /etc/dspam/templates/$base
-            ucfr dspam-webfrontend /etc/dspam/templates/$base
-        done
-
     ;;
 
     reconfigure|abort-upgrade|abort-remove|abort-deconfigure)

Modified: branches/experimental/debian/dspam-webfrontend.postrm
==============================================================================
--- branches/experimental/debian/dspam-webfrontend.postrm	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam-webfrontend.postrm	Wed Aug 12 10:56:29 2009	(r200)
@@ -31,18 +31,16 @@
         # remove obsolete conffile:
         rm -f /etc/dspam/dspam-apache.conf || true
 
-	for i in base.css dspam-logo-small.gif rgb.txt dspam.js \
-                dspam-apache2.conf admins webfrontend.conf
+	for i in `ucfq --with-colons dspam-webfrontend | cut -d":" -f1`
         do
-                ucf --purge /etc/dspam/$i
-        done
+		for ext in '~' '%' .bak .ucf-new .ucf-old .ucf-dist;  do
+			rm -f $i$ext
+			rm -f $i
+		done
 
-        for i in /usr/share/dspam/templates/*
-        do
-            base=`basename $i`
-            ucf --purge /etc/dspam/templates/$base
+                ucf --purge $i
+		ucfr --purge dspam-webfrontend $i
         done
-
     ;;
 
     upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)

Modified: branches/experimental/debian/dspam.cron.daily
==============================================================================
--- branches/experimental/debian/dspam.cron.daily	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam.cron.daily	Wed Aug 12 10:56:29 2009	(r200)
@@ -12,15 +12,5 @@
   fi
 fi
 
-# sends the daily quarantine email
-case "$DAILY_QUARANTINE_SUMMARY" in
-     [Yy]*)
-        /usr/bin/dspam_notify
-        ;;
-     *)
-        exit 0
-        ;;
-esac
-
 exit 0
 

Modified: branches/experimental/debian/dspam.default
==============================================================================
--- branches/experimental/debian/dspam.default	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam.default	Wed Aug 12 10:56:29 2009	(r200)
@@ -8,8 +8,3 @@
 
 # Options for dspam.
 #OPTIONS="--debug"
-
-# Should the daily quarantine summary email
-# be sent by the daily cronjob
-# Make sure you edit /etc/dspam/dspam_notify.conf
-#DAILY_QUARANTINE_SUMMARY="yes"

Modified: branches/experimental/debian/dspam.install
==============================================================================
--- branches/experimental/debian/dspam.install	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam.install	Wed Aug 12 10:56:29 2009	(r200)
@@ -17,4 +17,3 @@
 debian/tmp/usr/bin/cssconvert       usr/bin/
 debian/tmp/usr/bin/csscompress      usr/bin/
 debian/dspam_notify.conf	    etc/dspam/
-debian/tmp/usr/bin/dspam_notify     usr/bin/

Modified: branches/experimental/debian/dspam.manpages
==============================================================================
--- branches/experimental/debian/dspam.manpages	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/dspam.manpages	Wed Aug 12 10:56:29 2009	(r200)
@@ -7,7 +7,6 @@
 debian/manpages/csscompress.1
 debian/manpages/cssconvert.1
 debian/manpages/cssstat.1 
-debian/manpages/dspam_notify.1
 man/dspam.1
 man/dspam_clean.1  
 man/dspam_train.1

Modified: branches/experimental/debian/libdspam7-drv-mysql.cron.daily
==============================================================================
--- branches/experimental/debian/libdspam7-drv-mysql.cron.daily	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/libdspam7-drv-mysql.cron.daily	Wed Aug 12 10:56:29 2009	(r200)
@@ -36,9 +36,9 @@
     if [ -z "$MYSQL_HOST" ] || \
        [ ` echo "${MYSQL_HOST}" | cut -c1 ` = "/" ]; then
         /usr/bin/mysql --defaults-file=$MYSQLCONF_PASSWD \
-	               --user=$MYSQL_USER $MYSQL_DB < $PURGE
+	               --user=$MYSQL_USER $MYSQL_DB < $PURGE > /dev/null
     else
-        /usr/bin/mysql --defaults-file=$MYSQLCONF_PASSWD --host=$MYSQL_HOST --user=$MYSQL_USER $MYSQL_DB < $PURGE
+        /usr/bin/mysql --defaults-file=$MYSQLCONF_PASSWD --host=$MYSQL_HOST --user=$MYSQL_USER $MYSQL_DB < $PURGE > /dev/null
     fi
 
     rm "$MYSQLCONF_PASSWD"

Modified: branches/experimental/debian/libdspam7-drv-mysql.postrm
==============================================================================
--- branches/experimental/debian/libdspam7-drv-mysql.postrm	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/libdspam7-drv-mysql.postrm	Wed Aug 12 10:56:29 2009	(r200)
@@ -26,7 +26,7 @@
     done
     rm -f /etc/dspam/dspam.d/mysql.conf
     if [ -x /usr/bin/ucf ]; then
-      ucf --debconf-ok --purge /etc/dspam/dspam.d/mysql.conf
+      ucf --purge /etc/dspam/dspam.d/mysql.conf
     fi
   ;;
 

Modified: branches/experimental/debian/libdspam7-drv-pgsql.postrm
==============================================================================
--- branches/experimental/debian/libdspam7-drv-pgsql.postrm	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/libdspam7-drv-pgsql.postrm	Wed Aug 12 10:56:29 2009	(r200)
@@ -26,7 +26,7 @@
     done
     rm -f /etc/dspam/dspam.d/pgsql.conf
     if [ -x /usr/bin/ucf ]; then
-      ucf --debconf-ok --purge /etc/dspam/dspam.d/pgsql.conf
+      ucf --purge /etc/dspam/dspam.d/pgsql.conf
     fi
   ;;
 

Modified: branches/experimental/debian/patches/00list
==============================================================================
--- branches/experimental/debian/patches/00list	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/00list	Wed Aug 12 10:56:29 2009	(r200)
@@ -6,4 +6,8 @@
 background-dspam.dpatch
 clean-manpages.dpatch
 path-to-dspam_for-training-script.dpatch
-dspam_notify.dpatch
+#dspam_notify.dpatch
+remove-daily-quarantine-pref-from-webui.dpatch
+where-to-find-txt-files.dpatch
+complete_l10n.dpatch
+templates_fr.dpatch

Modified: branches/experimental/debian/patches/clean-manpages.dpatch
==============================================================================
--- branches/experimental/debian/patches/clean-manpages.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/clean-manpages.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -2,7 +2,7 @@
 ## clean-manpages.dpatch by Julien Valroff <julien at kirya.net>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
+## DP: Various fixes to manpages
 
 @DPATCH@
 diff -urNad dspam-3.9.0~alpha2+git20090720~/man/dspam.1 dspam-3.9.0~alpha2+git20090720/man/dspam.1

Added: branches/experimental/debian/patches/complete_l10n.dpatch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/experimental/debian/patches/complete_l10n.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -0,0 +1,3104 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## complete_l10n.dpatch by Julien Valroff <julien at kirya.net>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Allows the webui to be completely translated
+
+ at DPATCH@
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/admin.cgi dspam-3.9.0~beta2/webui/cgi-bin/admin.cgi
+--- dspam-3.9.0~beta2~/webui/cgi-bin/admin.cgi	2009-08-12 10:08:27.308734348 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/admin.cgi	2009-08-12 10:08:27.492734815 +0200
+@@ -20,11 +20,16 @@
+ 
+ use strict;
+ use Time::Local;
+-use vars qw { %CONFIG %DATA %FORM };
++use vars qw { %CONFIG %LANG %DATA %FORM };
+ require "ctime.pl";
+ 
+ # Read configuration parameters common to all CGI scripts
+ require "/etc/dspam/webfrontend.conf";
++if (-s "$CONFIG{'TEMPLATES'}/strings.txt") {
++        require "$CONFIG{'TEMPLATES'}/strings.txt";
++} else {
++        require "$CONFIG{'TEMPLATES'}/../strings.txt";
++}
+ 
+ #
+ # The current CGI script
+@@ -47,7 +52,7 @@
+   close(FILE);
+ 
+   if (!$admin) {
+-    &error("Access Denied");
++    &error($LANG{'error_access_denied'});
+   }
+ };
+ 
+@@ -82,7 +87,7 @@
+ %FORM = &ReadParse;
+ 
+ if ($ENV{'REMOTE_USER'} eq "") { 
+-  &error("System Error. I was unable to determine your identity.");
++  &error($LANG{'error_no_identity'});
+ }
+ 
+ if ($FORM{'template'} eq "" || $FORM{'template'} !~ /^([A-Z0-9]*)$/i) {
+@@ -117,7 +122,7 @@
+   &DisplayPreferences;
+ }
+ 
+-&error("Invalid Command $FORM{'COMMAND'}");
++&error("$LANG{'error_invalid_command'} $FORM{'COMMAND'}");
+ 
+ #
+ # Preferences Functions
+@@ -198,7 +203,7 @@
+         "' enableWhitelist "
+         . quotemeta($FORM{'enableWhitelist'}) . "> /dev/null");
+     } else {
+-      open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
++      open(FILE, ">$FILE") || do { &error("$LANG{'error_cannot_write_prefs'}: $!"); };
+       print FILE <<_END;
+ trainingMode=$FORM{'trainingMode'}
+ spamAction=$FORM{'spamAction'}
+@@ -366,7 +371,7 @@
+   my ($c_daily) = 0; 
+ 
+   if (! -e $LOG) {
+-    &error("No historical data is available.");
++    &error($LANG{'error_no_historic'});
+   }
+ 
+   # Initialize each individual time period
+@@ -404,7 +409,7 @@
+     $block_weekly[$_]		= 0;
+   }
+ 
+-  open(LOG, "<$LOG") || &error("Unable to open logfile: $!");
++  open(LOG, "<$LOG") || &error("$LANG{'error_cannot_open_log'}: $!");
+   while(<LOG>) {
+     my($t_log, $c_log, $signature, $e_log) = (split(/\t/))[0,1,3,5];
+     next if ($t_log > time);
+@@ -716,10 +721,11 @@
+   my($error) = @_;
+   $FORM{'template'} = "error";
+   $DATA{'MESSAGE'} = <<_end;
+-The following error occured while trying to process your request: <BR>
++$LANG{'error_message_part1'}
++<BR>
+ <B>$error</B><BR>
+ <BR>
+-If this problem persists, please contact your administrator.
++$LANG{'error_message_part2'}
+ _end
+   &output(%DATA);
+ }
+@@ -805,7 +811,7 @@
+     }
+                                                                                 
+     if (! -e $FILE) {
+-      &error("Unable to load default preferences");
++      &error($LANG{'error_load_default_prefs'});
+     }
+                                                                                 
+     open(FILE, "<$FILE");
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/admin.cgi.orig dspam-3.9.0~beta2/webui/cgi-bin/admin.cgi.orig
+--- dspam-3.9.0~beta2~/webui/cgi-bin/admin.cgi.orig	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/admin.cgi.orig	2009-08-12 10:08:27.496733524 +0200
+@@ -0,0 +1,821 @@
++#!/usr/bin/perl
++
++# $Id: admin.cgi,v 1.18 2009/07/20 22:18:22 sbajic Exp $
++# DSPAM
++# COPYRIGHT (C) DSPAM PROJECT 2002-2009
++#
++# 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; version 2
++# of the License.
++#
++# 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.
++
++use strict;
++use Time::Local;
++use vars qw { %CONFIG %DATA %FORM };
++require "ctime.pl";
++
++# Read configuration parameters common to all CGI scripts
++require "/etc/dspam/webfrontend.conf";
++
++#
++# The current CGI script
++#
++
++$CONFIG{'ME'}		    = "admin.cgi";
++
++#
++# Check Permissions
++#
++do {
++  my($admin) = 0;
++  open(FILE, "</etc/dspam/admins");
++  while(<FILE>) {
++    chomp;
++    if ($_ eq $ENV{'REMOTE_USER'}) {
++      $admin = 1;
++    }
++  }
++  close(FILE);
++
++  if (!$admin) {
++    &error("Access Denied");
++  }
++};
++
++$| = 1;
++
++#
++# Determine which extensions are available
++#
++                                                                                
++if ($CONFIG{'AUTODETECT'} == 1 || $CONFIG{'AUTODETECT'} eq "") {
++  $CONFIG{'PREFERENCES_EXTENSION'} = 0;
++  $CONFIG{'LARGE_SCALE'} = 0;
++  $CONFIG{'DOMAIN_SCALE'} = 0;
++  do {
++    my $x = `$CONFIG{'DSPAM'} --version`;
++    if ($x =~ /--enable-preferences-extension/) {
++      $CONFIG{'PREFERENCES_EXTENSION'} = 1;
++    }
++    if ($x =~ /--enable-large-scale/) {
++      $CONFIG{'LARGE_SCALE'} = 1;
++    }
++    if ($x =~ /--enable-domain-scale/) {
++      $CONFIG{'DOMAIN_SCALE'} = 1;
++    }
++  };
++}
++
++#
++# Parse Form Variables
++#
++
++%FORM = &ReadParse;
++
++if ($ENV{'REMOTE_USER'} eq "") { 
++  &error("System Error. I was unable to determine your identity.");
++}
++
++if ($FORM{'template'} eq "" || $FORM{'template'} !~ /^([A-Z0-9]*)$/i) {
++  $FORM{'template'} = "status";
++}
++
++#
++# Set up initial display variables
++#
++$DATA{'REMOTE_USER'} = $ENV{'REMOTE_USER'};
++
++#
++# Display DSPAM Version
++#
++$DATA{'DSPAMVERSION'} = $CONFIG{'DSPAM_VERSION'};
++
++#
++# Process Commands
++#
++
++# Status
++if ($FORM{'template'} eq "status") {
++  &DisplayStatus;
++
++# User Statistics
++
++} elsif ($FORM{'template'} eq "user") {
++  &DisplayUserStatistics;
++
++# Preferences
++} elsif ($FORM{'template'} eq "preferences") {
++  &DisplayPreferences;
++}
++
++&error("Invalid Command $FORM{'COMMAND'}");
++
++#
++# Preferences Functions
++#
++
++sub DisplayPreferences {
++  my(%PREFS, $FILE, $USER);
++
++  if ($FORM{'username'} eq "") {
++    $USER = "default";
++  } else {
++    $USER = $FORM{'username'};
++  }
++
++  $DATA{'USERNAME'} = $USER;
++
++  if ($FORM{'username'} eq "" || $FORM{'username'} eq "default") {
++    $FILE = "/etc/dspam/default.prefs";
++  } else {
++    $FILE = GetPath($FORM{'username'}) . ".prefs";
++  }
++
++  if ($FORM{'submit'} ne "") {
++
++    if ($FORM{'enableBNR'} ne "on") {
++      $FORM{'enableBNR'} = "off";
++    }
++                                                                                
++    if ($FORM{'optIn'} ne "on") {
++      $FORM{'optIn'} = "off";
++    }
++
++    if ($FORM{'optOut'} ne "on") {
++      $FORM{'optOut'} = "off";
++    }
++
++    if ($FORM{'enableWhitelist'} ne "on") {
++      $FORM{'enableWhitelist'} = "off";
++    }
++
++    if ($FORM{'showFactors'} ne "on") {
++      $FORM{'showFactors'} = "off";
++    }
++
++    if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
++
++      if ($FORM{'spamSubject'} eq "") {
++        $FORM{'spamSubject'} = "''";
++      } else {
++        $FORM{'spamSubject'} = quotemeta($FORM{'spamSubject'});
++      }
++
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' trainingMode " . quotemeta($FORM{'trainingMode'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' spamAction " . quotemeta($FORM{'spamAction'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' signatureLocation "
++        . quotemeta($FORM{'signatureLocation'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' spamSubject " . $FORM{'spamSubject'} . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' statisticalSedation "
++        . quotemeta($FORM{'statisticalSedation'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' enableBNR "
++        . quotemeta($FORM{'enableBNR'}) . "> /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' optOut "
++        . quotemeta($FORM{'optOut'}) . ">/dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' optIn "
++        . quotemeta($FORM{'optIn'}) . ">/dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' showFactors "
++        . quotemeta($FORM{'showFactors'}) . "> /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
++        "' enableWhitelist "
++        . quotemeta($FORM{'enableWhitelist'}) . "> /dev/null");
++    } else {
++      open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
++      print FILE <<_END;
++trainingMode=$FORM{'trainingMode'}
++spamAction=$FORM{'spamAction'}
++spamSubject=$FORM{'spamSubject'}
++statisticalSedation=$FORM{'statisticalSedation'}
++enableBNR=$FORM{'enableBNR'}
++enableWhitelist=$FORM{'enableWhitelist'}
++signatureLocation=$FORM{'signatureLocation'}
++showFactors=$FORM{'showFactors'}
++_END
++      close(FILE);
++    }
++  }
++
++  if (! -e $FILE) {
++    %PREFS = GetPrefs($USER, "/etc/dspam/default.prefs");
++  } else {
++    %PREFS = GetPrefs($USER, $FILE);
++  }
++
++  $DATA{"SEDATION_$PREFS{'statisticalSedation'}"} = "CHECKED";
++  $DATA{"S_".$PREFS{'trainingMode'}} = "CHECKED";
++  $DATA{"S_LOC_".uc($PREFS{'signatureLocation'})} = "CHECKED";
++  $DATA{"S_ACTION_".uc($PREFS{'spamAction'})} = "CHECKED"; 
++  $DATA{"SPAM_SUBJECT"} = $PREFS{'spamSubject'};
++  if ($PREFS{'optIn'} eq "on") {
++    $DATA{'C_OPTIN'} = "CHECKED";
++  }
++  if ($PREFS{'optOut'} eq "on") {
++    $DATA{'C_OPTOUT'} = "CHECKED";
++  }
++
++  if ($PREFS{"enableBNR"} eq "on") {
++    $DATA{"C_BNR"} = "CHECKED";
++  }
++  if ($PREFS{"showFactors"} eq "on") {
++    $DATA{"C_FACTORS"} = "CHECKED";
++  }
++  if ($PREFS{"enableWhitelist"} eq "on") {
++    $DATA{"C_WHITELIST"} = "CHECKED";
++  }
++
++  &output(%DATA);
++}
++
++#
++# User Statistics
++#
++
++sub DisplayUserStatistics {
++  my($b) = "rowEven";
++
++  my ($sl_total) = 0;
++  my ($il_total) = 0;
++  my ($sm_total) = 0;
++  my ($fp_total) = 0;
++  my ($sc_total) = 0;
++  my ($ic_total) = 0;
++  my ($mailbox_total) = 0;
++  
++  open(IN, "$CONFIG{'DSPAM_STATS'}|");
++  while(<IN>) {
++    chomp;
++    if ($b eq "rowEven") {
++      $b = "rowOdd";
++    } else {
++      $b = "rowEven";
++    }
++    s/:/ /g;
++    my($username, $sl, $il, $fp, $sm, $sc, $ic) = (split(/\s+/))[0,2,4,6,8,10,12]; 
++    if ($sl eq "") {
++      $_ = <IN>;
++      s/:/ /g;
++      ($sl, $il, $fp, $sm, $sc, $ic) = (split(/\s+/))[2,4,6,8,10,12];
++    }
++
++    my(%PREFS) = GetPrefs($username, GetPath($username).".prefs");
++    $PREFS{'enableBNR'} = "OFF" if ($PREFS{'enableBNR'} ne "on");
++    $PREFS{'enableWhitelist'} = "OFF" if ($PREFS{'enableWhitelist'} ne "on");
++    $PREFS{'spamAction'} = ucfirst($PREFS{'spamAction'});
++    $PREFS{'enableBNR'} = uc($PREFS{'enableBNR'});
++    $PREFS{'enableWhitelist'} = uc($PREFS{'enableWhitelist'});
++     
++    my($mailbox) = GetPath($username).".mbox";
++    my($mailbox_size, $mailbox_display);
++    if ( -e $mailbox ) {
++    	$mailbox_size = -s $mailbox;
++    	$mailbox_display = sprintf("%2.1f KB", ($mailbox_size / 1024));
++    	$mailbox_total += $mailbox_size;
++    }
++    else {
++    	$mailbox_display = "--";
++    }
++    
++    $sl_total += $sl;
++    $il_total += $il;
++    $sm_total += $sm;
++    $fp_total += $fp;
++    $sc_total += $sc;
++    $ic_total += $ic;
++    
++    $DATA{'TABLE'} .= qq!<tr><td class=\"$b\"><a href="$CONFIG{'DSPAM_CGI'}?user=$username">$username</A></td>!.
++                      "	<td class=\"$b rowDivider\" align=\"right\">$mailbox_display</td>".
++                      "	<td class=\"$b rowDivider\">$sl</td>".
++                      "	<td class=\"$b\">$il</td>".
++                      " <td class=\"$b\">$fp</td>".
++                      "	<td class=\"$b\">$sm</td>".
++                      " <td class=\"$b\">$sc</td>".
++                      "	<td class=\"$b\">$ic</td>".
++                      "	<td class=\"$b rowDivider\">$PREFS{'trainingMode'}</td>".
++                      "	<td class=\"$b\">$PREFS{'spamAction'}</td>".
++                      "	<td class=\"$b\">$PREFS{'enableBNR'}</td>".
++                      "	<td class=\"$b\">$PREFS{'enableWhitelist'}</td>".
++                      "	<td class=\"$b\">$PREFS{'statisticalSedation'}</td>".
++                      "	<td class=\"$b\">$PREFS{'signatureLocation'}</td>".
++                      "</tr>\n";
++  }
++  close(IN);
++
++  my($mailbox_total_display) = sprintf("%2.1f KB", ($mailbox_total / 1024));
++
++  $b = "rowHighlight";
++  $DATA{'TABLE'} .= "<tr><td class=\"$b\">Total</td>".
++                    "	<td class=\"$b rowDivider\" align=\"right\">$mailbox_total_display</td>".
++                    "	<td class=\"$b rowDivider\">$sl_total</td>".
++                    "	<td class=\"$b\">$il_total</td>".
++                    "	<td class=\"$b\">$sm_total</td>".
++                    "	<td class=\"$b\">$fp_total</td>".
++                    "	<td class=\"$b\">$sc_total</td>".
++                    "	<td class=\"$b\">$ic_total</td>".
++                    "	<td class=\"$b rowDivider\">&nbsp;</td>".
++                    "	<td class=\"$b\">&nbsp;</td>".
++                    "	<td class=\"$b\">&nbsp;</td>".
++                    "	<td class=\"$b\">&nbsp;</td>".
++                    "	<td class=\"$b\">&nbsp;</td>".
++                    "	<td class=\"$b\">&nbsp;</td>".
++                   "</tr>\n";
++
++  &output(%DATA);
++}
++
++#
++# Status Functions
++#
++
++sub DisplayStatus {
++  my($LOG) = "$CONFIG{'DSPAM_HOME'}/system.log";
++  my(@spam_daily, @nonspam_daily, @period_daily, @fp_daily, @sm_daily, 
++     @inoc_daily, @whitelist_daily, @corpus_daily, @virus_daily,
++     @black_daily, @block_daily);
++  my(@spam_weekly, @nonspam_weekly, @period_weekly, @fp_weekly, @sm_weekly,
++     @inoc_weekly, @whitelist_weekly, @corpus_weekly, @virus_weekly,
++     @black_weekly, @block_weekly);
++  my(%msgpersecond);
++  my($keycount_exectime);
++  my($last_message);
++  my(%classes);
++
++  my ($min, $hour, $mday, $mon, $year) = (localtime(time))[1,2,3,4,5];
++  my ($hmstart) = time - 60;
++  my ($daystart) = timelocal(0, 0, 0, $mday, $mon, $year);
++  my ($periodstart) = $daystart - (3600*24*24); # 2 Weeks ago
++  my ($dailystart) = time - (3600*23);
++  my ($c_weekly) = 0; # Cursor to most recent time slot
++  my ($c_daily) = 0; 
++
++  if (! -e $LOG) {
++    &error("No historical data is available.");
++  }
++
++  # Initialize each individual time period
++
++  for(0..23) {
++    my($h) = To12Hour($hour-(23-$_));
++    $period_daily[$_]		= $h;
++    $spam_daily[$_]		= 0;
++    $nonspam_daily[$_]		= 0;
++    $sm_daily[$_]		= 0;
++    $fp_daily[$_]		= 0;
++    $inoc_daily[$_]		= 0;
++    $whitelist_daily[$_]	= 0;
++    $corpus_daily[$_]		= 0;
++    $virus_daily[$_]		= 0;
++    $black_daily[$_]		= 0;
++    $block_daily[$_]		= 0;
++  }
++
++  for(0..24) {
++    my($d) = $daystart - (3600*24*(24-$_));
++    my ($lday, $lmon, $lyear) = (localtime($d))[3,4,5];
++    $lmon++;
++    $lyear += 1900;
++    $period_weekly[$_]		= "$lmon/$lday/$lyear";
++    $spam_weekly[$_]		= 0;
++    $nonspam_weekly[$_]		= 0;
++    $sm_weekly[$_]		= 0;
++    $fp_weekly[$_]		= 0;
++    $inoc_weekly[$_]		= 0;
++    $whitelist_weekly[$_]	= 0;
++    $corpus_weekly[$_]		= 0;
++    $virus_weekly[$_]		= 0;
++    $black_weekly[$_]		= 0;
++    $block_weekly[$_]		= 0;
++  }
++
++  open(LOG, "<$LOG") || &error("Unable to open logfile: $!");
++  while(<LOG>) {
++    my($t_log, $c_log, $signature, $e_log) = (split(/\t/))[0,1,3,5];
++    next if ($t_log > time);
++
++    $last_message = $t_log;
++
++    # Only Parse Log Data in our Time Period
++    if ($t_log>=$periodstart) {
++      my($tmin, $thour, $tday, $tmon, $tyear) = (localtime($t_log))[1,2,3,4,5];
++      $tmon++;
++      $tyear += 1900;
++
++      # Weekly Graph
++      $c_weekly = 0;
++      while($period_weekly[$c_weekly] ne "$tmon/$tday/$tyear" && $c_weekly<24) {
++        $c_weekly++;
++      }
++
++      if ($c_log eq "E") {
++        if ($classes{$signature} eq "S") {
++          $spam_weekly[$c_weekly]--;
++          $spam_weekly[$c_weekly] = 0 if ($spam_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "I") {
++          $nonspam_weekly[$c_weekly]--;
++          $nonspam_weekly[$c_weekly] = 0 if ($nonspam_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "W") {
++          $whitelist_weekly[$c_weekly]--;
++          $whitelist_weekly[$c_weekly] = 0 if ($whitelist_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "F") {
++          $spam_weekly[$c_weekly]++; $fp_weekly[$c_weekly]--;
++          $fp_weekly[$c_weekly] = 0 if ($fp_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "M") {
++          $sm_weekly[$c_weekly]--; $nonspam_weekly[$c_weekly]++;
++          $sm_weekly[$c_weekly] = 0 if ($sm_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "N") {
++          $inoc_weekly[$c_weekly]--;
++          $inoc_weekly[$c_weekly] = 0 if ($inoc_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "C") {
++          $corpus_weekly[$c_weekly]--;
++          $corpus_weekly[$c_weekly] = 0 if ($corpus_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "V") {
++          $virus_weekly[$c_weekly]--;
++          $virus_weekly[$c_weekly] = 0 if ($virus_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "A") {
++          $black_weekly[$c_weekly]--;
++          $black_weekly[$c_weekly] = 0 if ($black_weekly[$c_weekly]<0);
++        } elsif ($classes{$signature} eq "O") {
++          $block_weekly[$c_weekly]--;
++          $block_weekly[$c_weekly] = 0 if ($block_weekly[$c_weekly]<0);
++        }
++      } else {
++       $classes{$signature} = $c_log;
++      }
++
++      if ($c_log eq "S") { $spam_weekly[$c_weekly]++; }
++      if ($c_log eq "I") { $nonspam_weekly[$c_weekly]++; }
++      if ($c_log eq "W") { $whitelist_weekly[$c_weekly]++; }
++      if ($c_log eq "F")
++        { $spam_weekly[$c_weekly]--; $fp_weekly[$c_weekly]++;
++          $spam_weekly[$c_weekly] = 0 if ($spam_weekly[$c_weekly]<0); }
++      if ($c_log eq "M")
++        { $sm_weekly[$c_weekly]++; $nonspam_weekly[$c_weekly]--;
++          $nonspam_weekly[$c_weekly] = 0 if ($nonspam_weekly[$c_weekly]<0); }
++      if ($c_log eq "N") { $inoc_weekly[$c_weekly]++; }
++      if ($c_log eq "C") { $corpus_weekly[$c_weekly]++; }
++      if ($c_log eq "V") { $virus_weekly[$c_weekly]++; }
++      if ($c_log eq "A") { $black_weekly[$c_weekly]++; }
++      if ($c_log eq "O") { $block_weekly[$c_weekly]++; }
++
++
++      # Daily Graph
++      if ($t_log>=$dailystart) {
++        while($period_daily[$c_daily] ne To12Hour($thour) && $c_daily<24) {
++          $c_daily++;
++        }
++
++
++        if ($c_log eq "E") {
++          if ($classes{$signature} eq "S") {
++            $spam_daily[$c_daily]--;
++            $spam_daily[$c_daily] = 0 if ($spam_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "I") {
++            $nonspam_daily[$c_daily]--;
++            $nonspam_daily[$c_daily] = 0 if ($nonspam_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "W") {
++            $whitelist_daily[$c_daily]--;
++            $whitelist_daily[$c_daily] = 0 if ($whitelist_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "F") {
++            $spam_daily[$c_daily]++; $fp_daily[$c_daily]--;
++            $fp_daily[$c_daily] = 0 if ($fp_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "M") {
++            $sm_daily[$c_daily]--; $nonspam_daily[$c_daily]++;
++            $sm_daily[$c_daily] = 0 if ($sm_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "N") {
++            $inoc_daily[$c_daily]--;
++            $inoc_daily[$c_daily] = 0 if ($inoc_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "C") {
++            $corpus_daily[$c_daily]--;
++            $corpus_daily[$c_daily] = 0 if ($corpus_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "V") {
++            $virus_daily[$c_daily]--;
++            $virus_daily[$c_daily] = 0 if ($virus_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "A") {
++            $black_daily[$c_daily]--;
++            $black_daily[$c_daily] = 0 if ($black_daily[$c_daily]<0);
++          } elsif ($classes{$signature} eq "O") {
++            $block_daily[$c_daily]--;
++            $block_daily[$c_daily] = 0 if ($block_daily[$c_daily]<0);
++          }
++        }
++
++        if ($c_log eq "S") { $spam_daily[$c_daily]++; }
++        if ($c_log eq "I") { $nonspam_daily[$c_daily]++; }
++        if ($c_log eq "W") { $whitelist_daily[$c_daily]++; }
++        if ($c_log eq "F")
++          { $spam_daily[$c_daily]--; $fp_daily[$c_daily]++;
++            $spam_daily[$c_daily] = 0 if ($spam_daily[$c_daily]<0); }
++        if ($c_log eq "M")
++          { $sm_daily[$c_daily]++; $nonspam_daily[$c_daily]--;
++            $nonspam_daily[$c_daily] = 0 if ($nonspam_daily[$c_daily]<0); }
++        if ($c_log eq "N") { $inoc_daily[$c_daily]++; }
++        if ($c_log eq "C") { $corpus_daily[$c_daily]++; }
++        if ($c_log eq "V") { $virus_daily[$c_daily]++; }
++        if ($c_log eq "A") { $black_daily[$c_daily]++; }
++        if ($c_log eq "O") { $block_daily[$c_daily]++; }
++      }
++
++      # Last Half-Minute
++      if ($t_log>=$hmstart) {
++        $msgpersecond{$t_log}++;
++        $DATA{'AVG_PROCESSING_TIME'} += $e_log;
++        $keycount_exectime++;
++      }
++    }
++  }
++
++  close(LOG);
++
++  # Calculate Avg. Messages Per Second
++  foreach(values(%msgpersecond)) {
++    $DATA{'AVG_MSG_PER_SECOND'} += $_;
++  }
++  $DATA{'AVG_MSG_PER_SECOND'} /= 60;
++  $DATA{'AVG_MSG_PER_SECOND'} = sprintf("%2.2f", $DATA{'AVG_MSG_PER_SECOND'});
++
++  # Calculate Avg. Processing Time
++  if ($keycount_exectime == 0) {
++    $DATA{'AVG_PROCESSING_TIME'} = 0;
++  } else {
++    $DATA{'AVG_PROCESSING_TIME'} /= $keycount_exectime;
++  }
++  $DATA{'AVG_PROCESSING_TIME'} = sprintf("%01.6f", $DATA{'AVG_PROCESSING_TIME'});
++
++  # Calculate Number of processes, Uptime and Mail Queue length
++  $DATA{'DSPAM_PROCESSES'} = `$CONFIG{'DSPAM_PROCESSES'}`;
++  $DATA{'UPTIME'} = `uptime`;
++  $DATA{'MAIL_QUEUE'} = `$CONFIG{'MAIL_QUEUE'}`;
++  
++  # Calculate Graphs
++  $DATA{'SPAM_TODAY'}               = $spam_weekly[24];
++  $DATA{'NONSPAM_TODAY'}            = $nonspam_weekly[24];
++  $DATA{'SM_TODAY'}                 = $sm_weekly[24];
++  $DATA{'FP_TODAY'}                 = $fp_weekly[24];
++  $DATA{'INOC_TODAY'}               = $inoc_weekly[24];
++  $DATA{'WHITE_TODAY'}              = $whitelist_weekly[24];
++  $DATA{'CORPUS_TODAY'}             = $corpus_weekly[24];
++  $DATA{'VIRUS_TODAY'}              = $virus_weekly[24];
++  $DATA{'BLACK_TODAY'}              = $black_weekly[24];
++  $DATA{'BLOCK_TODAY'}              = $block_weekly[24];
++  $DATA{'TOTAL_TODAY'}              = $DATA{'SPAM_TODAY'}
++                                      + $DATA{'NONSPAM_TODAY'}
++                                      + $DATA{'SM_TODAY'}
++                                      + $DATA{'FP_TODAY'}
++                                      + $DATA{'INOC_TODAY'}
++                                      + $DATA{'WHITE_TODAY'}
++                                      + $DATA{'CORPUS_TODAY'}
++                                      + $DATA{'VIRUS_TODAY'}
++                                      + $DATA{'BLACK_TODAY'}
++                                      + $DATA{'BLOCK_TODAY'};
++
++  $DATA{'SPAM_THIS_HOUR'}           = $spam_daily[23];
++  $DATA{'NONSPAM_THIS_HOUR'}        = $nonspam_daily[23];
++  $DATA{'SM_THIS_HOUR'}             = $sm_daily[23];
++  $DATA{'FP_THIS_HOUR'}             = $fp_daily[23];
++  $DATA{'INOC_THIS_HOUR'}           = $inoc_daily[23];
++  $DATA{'WHITE_THIS_HOUR'}          = $whitelist_daily[23];
++  $DATA{'CORPUS_THIS_HOUR'}         = $corpus_daily[23];
++  $DATA{'VIRUS_THIS_HOUR'}          = $virus_daily[23];
++  $DATA{'BLACK_THIS_HOUR'}          = $black_daily[23];
++  $DATA{'BLOCK_THIS_HOUR'}          = $block_daily[23];
++  $DATA{'TOTAL_THIS_HOUR'}          = $DATA{'SPAM_THIS_HOUR'} +
++                                      + $DATA{'NONSPAM_THIS_HOUR'} 
++                                      + $DATA{'SM_THIS_HOUR'}
++                                      + $DATA{'FP_THIS_HOUR'} 
++                                      + $DATA{'INOC_THIS_HOUR'}
++                                      + $DATA{'WHITE_THIS_HOUR'}
++                                      + $DATA{'CORPUS_THIS_HOUR'}
++                                      + $DATA{'VIRUS_THIS_HOUR'}
++                                      + $DATA{'BLACK_THIS_HOUR'}
++                                      + $DATA{'BLOCK_THIS_HOUR'};
++
++  $DATA{'DATA_DAILY'} = join(",", @spam_daily)
++                      . "_"
++                      . join(",", @nonspam_daily)
++                      . "_"
++                      . join(",", @sm_daily)
++                      . "_"
++                      . join(",", @fp_daily)
++                      . "_"
++                      . join(",", @inoc_daily)
++                      . "_"
++                      . join(",", @whitelist_daily)
++                      . "_"
++                      . join(",", @corpus_daily)
++                      . "_"
++                      . join(",", @virus_daily)
++                      . "_"
++                      . join(",", @black_daily)
++                      . "_"
++                      . join(",", @block_daily)
++                      . "_"
++                      . join(",", @period_daily); 
++
++  $DATA{'DATA_WEEKLY'} = join(",", @spam_weekly)
++                      . "_"
++                      . join(",", @nonspam_weekly)
++                      . "_"
++                      . join(",", @sm_weekly)
++                      . "_"
++                      . join(",", @fp_weekly)
++                      . "_"
++                      . join(",", @inoc_weekly)
++                      . "_"
++                      . join(",", @whitelist_weekly)
++                      . "_"
++                      . join(",", @corpus_weekly)
++                      . "_"
++                      . join(",", @virus_weekly)
++                      . "_"
++                      . join(",", @black_weekly)
++                      . "_"
++                      . join(",", @block_weekly)
++                      . "_"
++                      . join(",", @period_weekly);
++
++  foreach(@spam_daily)		{ $DATA{'TS_DAILY'} += $_; };
++  foreach(@nonspam_daily)	{ $DATA{'TI_DAILY'} += $_; }
++  foreach(@sm_daily)		{ $DATA{'SM_DAILY'} += $_; }
++  foreach(@fp_daily)		{ $DATA{'FP_DAILY'} += $_; }
++  foreach(@inoc_daily)		{ $DATA{'INOC_DAILY'} += $_; }
++  foreach(@whitelist_daily)	{ $DATA{'TI_DAILY'} += $_; $DATA{'WHITE_DAILY'} += $_; }
++  foreach(@corpus_daily)	{ $DATA{'CORPUS_DAILY'} += $_; }
++  foreach(@virus_daily)		{ $DATA{'TS_DAILY'} += $_; $DATA{'VIRUS_DAILY'} += $_; }
++  foreach(@black_daily)		{ $DATA{'TS_DAILY'} += $_; $DATA{'BLACK_DAILY'} += $_; }
++  foreach(@block_daily)		{ $DATA{'TS_DAILY'} += $_; $DATA{'BLOCK_DAILY'} += $_; }
++
++  foreach(@spam_weekly)		{ $DATA{'TS_WEEKLY'} += $_; }
++  foreach(@nonspam_weekly)	{ $DATA{'TI_WEEKLY'} += $_; }
++  foreach(@sm_weekly)		{ $DATA{'SM_WEEKLY'} += $_; }
++  foreach(@fp_weekly)		{ $DATA{'FP_WEEKLY'} += $_; }
++  foreach(@inoc_weekly)		{ $DATA{'INOC_WEEKLY'} += $_; }
++  foreach(@whitelist_weekly)	{ $DATA{'TI_WEEKLY'} += $_; $DATA{'WHITE_WEEKLY'} += $_; }
++  foreach(@corpus_weekly)	{ $DATA{'CORPUS_WEEKLY'} += $_; }
++  foreach(@virus_weekly)	{ $DATA{'TS_WEEKLY'} += $_; $DATA{'VIRUS_WEEKLY'} += $_; }
++  foreach(@black_weekly)	{ $DATA{'TS_WEEKLY'} += $_; $DATA{'BLACK_WEEKLY'} += $_; }
++  foreach(@block_weekly)	{ $DATA{'TS_WEEKLY'} += $_; $DATA{'BLOCK_WEEKLY'} += $_; }
++
++  &output(%DATA);
++}
++
++#
++# Global Functions
++#
++
++sub output {
++  if ($FORM{'template'} eq "" || $FORM{'template'} !~ /^([A-Z0-9]*)$/i) {
++    $FORM{'template'} = "performance";
++  }
++  print "Expires: now\n";
++  print "Pragma: no-cache\n";
++  print "Cache-control: no-cache\n";
++  print "Content-type: text/html\n\n";
++  my(%DATA) = @_;
++  $DATA{'WEB_ROOT'} = $CONFIG{'WEB_ROOT'};
++
++  open(FILE, "<$CONFIG{'TEMPLATES'}/nav_admin_$FORM{'template'}.html");
++  while(<FILE>) { 
++    s/\$CGI\$/$CONFIG{'ME'}/g;
++    s/\$([A-Z0-9_]*)\$/$DATA{$1}/g; 
++    print;
++  }
++  close(FILE);
++  exit;
++}
++
++sub SafeVars {
++  my(%PAIRS) = @_;
++  my($url, $key);
++  foreach $key (keys(%PAIRS)) {
++    my($value) = $PAIRS{$key};
++    $value =~ s/([^A-Z0-9])/sprintf("%%%x", ord($1))/gie;
++    $url .= "$key=$value&";
++  }
++  $url =~ s/\&$//;
++  return $url;
++}
++
++sub error {
++  my($error) = @_;
++  $FORM{'template'} = "error";
++  $DATA{'MESSAGE'} = <<_end;
++The following error occured while trying to process your request: <BR>
++<B>$error</B><BR>
++<BR>
++If this problem persists, please contact your administrator.
++_end
++  &output(%DATA);
++}
++
++sub ReadParse {
++  my(@pairs, %FORM);
++  if ($ENV{'REQUEST_METHOD'} =~ /GET/i)
++    { @pairs = split(/&/, $ENV{'QUERY_STRING'}); }
++  else {
++    my($buffer);
++    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
++    @pairs = split(/\&/, $buffer);
++  }
++  foreach(@pairs) {
++    my($name, $value) = split(/\=/, $_);
++
++    $name =~ tr/+/ /;
++    $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
++    $value =~ tr/+/ /;
++    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
++    $value =~ s/<!--(.|\n)*-->//g;
++    $FORM{$name} = $value;
++  }
++  return %FORM;
++}
++
++sub To12Hour {
++  my($h) = @_;
++  if ($h < 0) { $h += 24; }
++  if ($h>11) { $h -= 12 if ($h>12) ; $h .= ":00pm"; }
++  else { $h = "12" if ($h == 0); $h .= ":00am"; }
++  return $h;
++}
++
++
++sub GetPath {
++  my($USER, $VPOPUSERNAME, $VPOPDOMAIN);
++  my($UN) = @_;
++
++  # Domain-scale
++  if ($CONFIG{'DOMAIN_SCALE'} == 1) {
++    $VPOPUSERNAME = (split(/@/, $UN))[0];
++    $VPOPDOMAIN = (split(/@/, $UN))[1];
++    $USER = "$CONFIG{'DSPAM_HOME'}/data/$VPOPDOMAIN/$VPOPUSERNAME/$VPOPUSERNAME";
++
++  # Normal scale
++  } elsif ($CONFIG{'LARGE_SCALE'} == 0) {
++    $USER = "$CONFIG{'DSPAM_HOME'}/data/$UN/$UN";
++
++  # Large-scale
++  } else {
++    if (length($UN)>1) {
++      $USER = "$CONFIG{'DSPAM_HOME'}/data/" . substr($UN, 0, 1) .
++      "/". substr($UN, 1, 1) . "/$UN/$UN";
++    } else {
++      $USER = "$CONFIG{'DSPAM_HOME'}/data/$UN/$UN";
++    }
++  }
++
++  return $USER;
++}
++
++sub GetPrefs {
++  my(%PREFS);
++  my($USER, $FILE) = @_;
++
++  if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
++
++    if ($USER eq "") {
++      $USER = "default";
++    }
++
++    open(PIPE, "$CONFIG{'DSPAM_BIN'}/dspam_admin agg pref ".quotemeta($USER)."|");
++    while(<PIPE>) {
++      chomp;
++      my($directive, $value) = split(/\=/);
++      $PREFS{$directive} = $value;
++    }
++    close(PIPE);
++  } else {
++    if (! -e $FILE) {
++      $FILE = "/etc/dspam/default.prefs";
++    }
++                                                                                
++    if (! -e $FILE) {
++      &error("Unable to load default preferences");
++    }
++                                                                                
++    open(FILE, "<$FILE");
++    while(<FILE>) {
++      chomp;
++      my($directive, $value) = split(/\=/);
++      $PREFS{$directive} = $value;
++    }
++    close(FILE);
++  }
++
++  return %PREFS;
++}
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/admingraph.cgi dspam-3.9.0~beta2/webui/cgi-bin/admingraph.cgi
+--- dspam-3.9.0~beta2~/webui/cgi-bin/admingraph.cgi	2009-08-12 10:08:27.248734587 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/admingraph.cgi	2009-08-12 10:08:27.496733524 +0200
+@@ -21,10 +21,15 @@
+ use CGI ':standard';
+ use GD::Graph::bars;
+ use strict;
+-use vars qw { %CONFIG %FORM @spam @nonspam @period @data @inoc @sm @fp @wh @corpus @virus @black @block };
++use vars qw { %CONFIG %FORM %LANG @spam @nonspam @period @data @inoc @sm @fp @wh @corpus @virus @black @block };
+ 
+ # Read configuration parameters common to all CGI scripts
+ require "/etc/dspam/webfrontend.conf";
++if (-s "$CONFIG{'TEMPLATES'}/strings.txt") {
++        require "$CONFIG{'TEMPLATES'}/strings.txt";
++} else {
++        require "$CONFIG{'TEMPLATES'}/../strings.txt";
++}
+ 
+ %FORM = &ReadParse();
+ 
+@@ -49,7 +54,7 @@
+ my $mygraph = GD::Graph::bars->new(500, 250);
+ $mygraph->set(
+     x_label     => "$FORM{'x_label'}",
+-    y_label     => 'Number of Messages',
++    y_label     => $LANG{'graph_legend_nb_messages'},
+     title       => "$FORM{'title'}",
+     legend_placement => 'RT',
+     legend_spacing => 2,
+@@ -83,7 +88,10 @@
+ }
+ 
+ $mygraph->set_legend_font(GD::gdMediumBoldFont);
+-$mygraph->set_legend(' Inoculations',' Corpusfeds',' Virus',' Blacklisted (RBL)',' Blocklisted',' Auto-Whitelisted',' Spam', ' Nonspam',' Spam Misses',' False Positives');
++#$mygraph->set_legend(' Inoculations',' Corpusfeds',' Virus',' Blacklisted (RBL)',' Blocklisted',' Auto-Whitelisted',' Spam', ' Nonspam',' Spam Misses',' False Positives');
++$mygraph->set_legend(" $LANG{'graph_legend_inoculations'}", " $LANG{'graph_legend_corpusfeds'}", " $LANG{'graph_legend_virus'}", 
++	" $LANG{'graph_legend_RBL'}", " $LANG{'graph_legend_blocklisted'}", " $LANG{'graph_legend_whitelisted'}", " $LANG{'graph_legend_spam'}",
++	" $LANG{'graph_legend_nonspam'}", " $LANG{'graph_legend_spam_misses'}", " $LANG{'graph_legend_falsepositives'}");
+ my $myimage = $mygraph->plot(\@data) or die $mygraph->error;
+                                                                                 
+ print "Content-type: image/png\n\n";
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/dspam.cgi dspam-3.9.0~beta2/webui/cgi-bin/dspam.cgi
+--- dspam-3.9.0~beta2~/webui/cgi-bin/dspam.cgi	2009-08-12 10:08:27.308734348 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/dspam.cgi	2009-08-12 10:08:27.496733524 +0200
+@@ -20,12 +20,17 @@
+ 
+ use strict;
+ use Time::Local;
+-use vars qw { %CONFIG %DATA %FORM $MAILBOX $CURRENT_USER $USER $TMPFILE};
++use vars qw { %CONFIG %DATA %LANG %FORM $MAILBOX $CURRENT_USER $USER $TMPFILE};
+ use vars qw { $CURRENT_STORE };
+ require "ctime.pl";
+ 
+ # Read configuration parameters common to all CGI scripts
+ require "/etc/dspam/webfrontend.conf";
++if (-s "$CONFIG{'TEMPLATES'}/strings.txt") {
++	require "$CONFIG{'TEMPLATES'}/strings.txt";
++} else {
++	require "$CONFIG{'TEMPLATES'}/../strings.txt";
++}
+ 
+ if($CONFIG{"DATE_FORMAT"}) {
+   use POSIX qw(strftime);
+@@ -105,7 +110,7 @@
+ $TMPFILE = $USER . ".tmp";
+ 
+ if ($CURRENT_USER eq "") {
+-  &error("System Error. I was unable to determine your identity.");
++  &error($LANG{'error_no_identity'});
+ }
+ 
+ if ($FORM{'template'} eq "" || $FORM{'template'} !~ /^([A-Z0-9]*)$/i) {
+@@ -185,7 +190,7 @@
+ } elsif ($FORM{'template'} eq "fragment") {
+   &DisplayFragment;
+ } else {
+-  &error("Invalid Command $FORM{'COMMAND'}");
++  &error("LANG{'error_invalid_command'} $FORM{'COMMAND'}");
+ }
+ 
+ #
+@@ -249,7 +254,7 @@
+ 
+   my($LOG) = "$USER.log";
+   if (! -e $LOG) {
+-    &error("No historical data is available");
++    &error("$LANG{'error_no_historic'}");
+   }
+ 
+   # Preseed retraining information and delivery errors
+@@ -363,34 +368,34 @@
+ 
+     my($cl, $cllabel);
+     $class = $rec{$signature}->{'class'} if ($rec{$signature}->{'class'} ne "");
+-    if ($class eq "S") { $cl = "spam"; $cllabel="SPAM"; }
+-    elsif ($class eq "I") { $cl = "innocent"; $cllabel="Good"; }
++    if ($class eq "S") { $cl = "spam"; $cllabel=$LANG{'history_label_spam'}; }
++    elsif ($class eq "I") { $cl = "innocent"; $cllabel=$LANG{'history_label_innocent'}; }
+     elsif ($class eq "F") {
+       if ($rec{$signature}->{'count'} % 2 != 0) {
+-        $cl = "false"; $cllabel="Miss"; 
++        $cl = "false"; $cllabel=$LANG{'history_label_miss'}; 
+       } else {
+-        $cl = "innocent"; $cllabel="Good"; 
++        $cl = "innocent"; $cllabel=$LANG{'history_label_innocent'}; 
+       }
+     }
+     elsif ($class eq "M") { 
+       if ($rec{$signature}->{'count'} % 2 != 0) {
+-          $cl = "missed"; $cllabel="Miss"; 
++          $cl = "missed"; $cllabel=$LANG{'history_label_miss'}; 
+       } else {
+-          $cl = "spam"; $cllabel="SPAM";
++          $cl = "spam"; $cllabel=$LANG{'history_label_spam'};
+       }
+     }
+-    elsif ($class eq "W") { $cl = "whitelisted"; $cllabel="Whitelist"; }
+-    elsif ($class eq "V") { $cl = "virus"; $cllabel="Virus"; }
+-    elsif ($class eq "A") { $cl = "blacklisted"; $cllabel="RBL"; }
+-    elsif ($class eq "O") { $cl = "blocklisted"; $cllabel="BLOCK"; }
+-    elsif ($class eq "N") { $cl = "inoculation"; $cllabel="SPAM"; }
+-    elsif ($class eq "C") { $cl = "corpus"; $cllabel="Corpus"; }
+-    elsif ($class eq "U") { $cl = "unknown"; $cllabel="UNKN"; }
+-    elsif ($class eq "E") { $cl = "error"; $cllabel="Error"; }
++    elsif ($class eq "W") { $cl = "whitelisted"; $cllabel=$LANG{'history_label_whitelist'}; }
++    elsif ($class eq "V") { $cl = "virus"; $cllabel=$LANG{'history_label_virus'}; }
++    elsif ($class eq "A") { $cl = "blacklisted"; $cllabel=$LANG{'history_label_rbl'}; }
++    elsif ($class eq "O") { $cl = "blocklisted"; $cllabel=$LANG{'history_label_block'}; }
++    elsif ($class eq "N") { $cl = "inoculation"; $cllabel=$LANG{'history_label_spam'}; }
++    elsif ($class eq "C") { $cl = "corpus"; $cllabel=$LANG{'history_label_corpus'}; }
++    elsif ($class eq "U") { $cl = "unknown"; $cllabel=$LANG{'history_label_unknown'}; }
++    elsif ($class eq "E") { $cl = "error"; $cllabel=$LANG{'history_label_error'}; }
+     if ($messageid ne "") {
+       if ($rec{$messageid}->{'resend'} ne "") {
+         $cl = "relay";
+-        $cllabel = "Resend";
++        $cllabel = $LANG{'history_label_resend'};
+       }
+       $rec{$messageid}->{'resend'} = $signature;
+     }
+@@ -406,18 +411,18 @@
+     $subject = substr($subject, 0, $CONFIG{'MAX_COL_LEN'}) . "..." if (length($subject)>$CONFIG{'MAX_COL_LEN'});
+ 
+     my($rclass);
+-    $rclass = "spam" if ($class eq "I" || $class eq "W" || $class eq "F");
+-    $rclass = "innocent" if ($class eq "S" || $class eq "M" || $class eq "V" || $class eq "A" || $class eq "O");
++    $rclass = $LANG{'history_retrain_as_spam'} if ($class eq "I" || $class eq "W" || $class eq "F");
++    $rclass = $LANG{'history_retrain_as_innocent'} if ($class eq "S" || $class eq "M" || $class eq "V" || $class eq "A" || $class eq "O");
+ 
+     my($retrain);
+     if ($rec{$signature}->{'class'} =~ /^(M|F)$/ && $rec{$signature}->{'count'} % 2 != 0) {
+-      $retrain = "<b>Retrained</b>";
++      $retrain = "<b>$LANG{'history_retrained'}</b>";
+     } 
+ 
+     if ($retrain eq "") {
+-      $retrain = qq!<A HREF="$MYURL&show=$show&history_page=$history_page&retrain=$rclass&signatureID=$signature">As ! . ucfirst($rclass) . "</A>";
++      $retrain = qq!<A HREF="$MYURL&show=$show&history_page=$history_page&retrain=$rclass&signatureID=$signature">$LANG{'history_retrain_as'} ! . ucfirst($rclass) . "</A>";
+     } else {
+-      $retrain .= qq! (<A HREF="$MYURL&show=$show&history_page=$history_page&retrain=$rclass&signatureID=$signature">Undo</A>)!;
++      $retrain .= qq! (<A HREF="$MYURL&show=$show&history_page=$history_page&retrain=$rclass&signatureID=$signature">$LANG{'history_retrain_undo'}</A>)!;
+     }
+ 
+     my($path) = "$USER.frag/$signature.frag";
+@@ -496,29 +501,35 @@
+   }
+ 
+   $DATA{'SHOW'} = $show;
+-  $DATA{'SHOW_SELECTOR'} .=  "Show: <a href=\"$MYURL&show=all\">";
++  $DATA{'SHOW_SELECTOR'} .=  "$LANG{'history_show'}: <a href=\"$MYURL&show=all\">";
+   if ($show eq "all") {
+-    $DATA{'SHOW_SELECTOR'} .= "<strong>all</strong>";
++    $DATA{'SHOW_SELECTOR'} .= "<strong>$LANG{'history_show_all'}</strong>";
+   } else {
+-    $DATA{'SHOW_SELECTOR'} .= "all";
++    $DATA{'SHOW_SELECTOR'} .= "$LANG{'history_show_all'}";
+   }
+   $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=spam\">";
+   if ($show eq "spam") {
+-    $DATA{'SHOW_SELECTOR'} .= "<strong>spam</strong>";
++    $DATA{'SHOW_SELECTOR'} .= "<strong>$LANG{'history_show_spam'}</strong>";
+   } else {
+-    $DATA{'SHOW_SELECTOR'} .= "spam";
++    $DATA{'SHOW_SELECTOR'} .= "$LANG{'history_show_spam'}";
+   }
+   $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=innocent\">";
+   if ($show eq "innocent") {
+-    $DATA{'SHOW_SELECTOR'} .= "<strong>innocent</strong>";
++    $DATA{'SHOW_SELECTOR'} .= "<strong>$LANG{'history_show_innocent'}</strong>";
+   } else {
+-    $DATA{'SHOW_SELECTOR'} .= "innocent";
++    $DATA{'SHOW_SELECTOR'} .= "$LANG{'history_show_innocent'}";
++  }
++  $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=virus\">";
++  if ($show eq "innocent") {
++    $DATA{'SHOW_SELECTOR'} .= "<strong>$LANG{'history_show_virus'}</strong>";
++  } else {
++    $DATA{'SHOW_SELECTOR'} .= "$LANG{'history_show_virus'}";
+   }
+   $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=whitelisted\">";
+   if ($show eq "whitelisted") {
+-    $DATA{'SHOW_SELECTOR'} .= "<strong>whitelisted</strong>";
++    $DATA{'SHOW_SELECTOR'} .= "<strong>$LANG{'history_show_whitelisted'}</strong>";
+   } else {
+-    $DATA{'SHOW_SELECTOR'} .= "whitelisted";
++    $DATA{'SHOW_SELECTOR'} .= "$LANG{'history_show_whitelisted'}";
+   }
+   $DATA{'SORT_SELECTOR'} .=  "</a>";
+ 
+@@ -543,10 +554,10 @@
+   my ($dailystart) = time - (3600*23);
+ 
+   if (! -e $LOG) {
+-    &error("No historical data is available.");
++    &error($LANG{'error_no_historic'});
+   }
+ 
+-  open(LOG, "<$LOG") || &error("Unable to open logfile: $!");
++  open(LOG, "<$LOG") || &error("$LANG{'error_cannot_open_log'}: $!");
+   while(<LOG>) {
+     my($t_log, $c_log) = split(/\t/);
+ 
+@@ -689,7 +700,7 @@
+         . quotemeta($FORM{'enableWhitelist'}) . "> /dev/null");
+ 
+     } else {
+-      open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
++      open(FILE, ">$FILE") || do { &error("$LANG{'error_cannot_write_prefs'}: $!"); };
+       print FILE <<_END;
+ trainingMode=$FORM{'trainingMode'}
+ spamAction=$FORM{'spamAction'}
+@@ -731,9 +742,9 @@
+   }
+ 
+   if ($CONFIG{'OPTMODE'} eq "OUT") {
+-    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optOut " . $DATA{'C_OPTOUT'} . ">Disable DSPAM filtering<br>";
++    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optOut " . $DATA{'C_OPTOUT'} . ">$LANG{'option_disable_filtering'}<br>";
+   } elsif ($CONFIG{'OPTMODE'} eq "IN") {
+-    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optIn " . $DATA{'C_OPTIN'} . ">Enable DSPAM filtering<br>";
++    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optIn " . $DATA{'C_OPTIN'} . ">$LANG{'option_enable_filtering'}<br>";
+   } else {
+     $DATA{"OPTION"} = "";
+   }
+@@ -758,7 +769,7 @@
+ sub ProcessFalsePositive {
+   my(@buffer, %head, $found);
+   if ($FORM{'signatureID'} eq "") {
+-    &error("No Message ID Specified");
++    &error($LANG{'error_no_sigid'});
+   }
+   open(FILE, "<$MAILBOX");
+   while(<FILE>) {
+@@ -896,7 +907,7 @@
+   my(@buffer);
+ 
+   if ($FORM{'signatureID'} eq "") {
+-    &error("No Message ID Specified");
++    &error($LANG{'error_no_sigid'});
+   }
+ 
+   $DATA{'MESSAGE_ID'} = $FORM{'signatureID'};
+@@ -1142,27 +1153,27 @@
+   $DATA{'SORTBY'} = $sortBy;
+   $DATA{'SORT_QUARANTINE'} .=  "<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=Rating&user=$FORM{'user'}\">";
+   if ($sortBy eq "Rating") {
+-    $DATA{'SORT_QUARANTINE'} .= "<strong>Rating</strong>";
++    $DATA{'SORT_QUARANTINE'} .= "<strong>$LANG{'quarantine_rating'}</strong>";
+   } else {
+-    $DATA{'SORT_QUARANTINE'} .= "Rating";
++    $DATA{'SORT_QUARANTINE'} .= "$LANG{'quarantine_rating'}";
+   }
+   $DATA{'SORT_QUARANTINE'} .=  "</a></th>\n\t<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=Date&user=$FORM{'user'}\">";
+   if ($sortBy eq "Date") {
+-    $DATA{'SORT_QUARANTINE'} .= "<strong>Date</strong>";
++    $DATA{'SORT_QUARANTINE'} .= "<strong>$LANG{'quarantine_date'}</strong>";
+   } else {
+-    $DATA{'SORT_QUARANTINE'} .= "Date";
++    $DATA{'SORT_QUARANTINE'} .= "$LANG{'quarantine_date'}";
+   }
+   $DATA{'SORT_QUARANTINE'} .=  "</a></th>\n\t<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=From&user=$FORM{'user'}\">";
+   if ($sortBy eq "From") {
+-    $DATA{'SORT_QUARANTINE'} .= "<strong>From</strong>";
++    $DATA{'SORT_QUARANTINE'} .= "<strong>$LANG{'quarantine_from'}</strong>";
+   } else {
+-    $DATA{'SORT_QUARANTINE'} .= "From";
++    $DATA{'SORT_QUARANTINE'} .= "$LANG{'quarantine_from'}";
+   }
+   $DATA{'SORT_QUARANTINE'} .=  "</a></th>\n\t<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=Subject&user=$FORM{'user'}\">";
+   if ($sortBy eq "Subject") {
+-    $DATA{'SORT_QUARANTINE'} .= "<strong>Subject</strong>";
++    $DATA{'SORT_QUARANTINE'} .= "<strong>$LANG{'quarantine_subject'}</strong>";
+   } else {
+-    $DATA{'SORT_QUARANTINE'} .= "Subject";
++    $DATA{'SORT_QUARANTINE'} .= "$LANG{'quarantine_subject'}";
+   }
+   $DATA{'SORT_QUARANTINE'} .=  "</a></th>";
+ 
+@@ -1399,7 +1410,7 @@
+ 
+ sub AddAlert {
+   if ($FORM{'ALERT'} eq "") {
+-    &error("No Alert Specified");
++    &error($LANG{'error_no_alert_specified'});
+   }
+   open(FILE, ">>$USER.alerts");
+   print FILE "$FORM{'ALERT'}\n";
+@@ -1411,7 +1422,7 @@
+   my($line, @alerts);
+   $line = 0;
+   if ($FORM{'line'} eq "") {
+-    &Error("No Alert Specified");
++    &Error($LANG{'no_alert_specified'});
+   }
+   open(FILE, "<$USER.alerts");
+   while(<FILE>) {
+@@ -1434,7 +1445,7 @@
+   $DATA{'ALERTS'} = <<_end;
+ <table border="0" cellspacing="0" cellpadding="2">
+ 	<tr>
+-		<th>Alert Name</th>
++		<th>$LANG{'alert_name'}</th>
+ 		<th>&nbsp;</th>
+ 	</tr>
+ _end
+@@ -1448,7 +1459,7 @@
+     while(<FILE>) {
+       s/</&lt;/g;
+       s/>/&gt;/g;
+-      $DATA{'ALERTS'} .= qq!<tr><td class="$rowclass">$_</td><td class="$rowclass">[<a href="$CONFIG{'ME'}?command=deleteAlert&user=$FORM{'user'}&template=alerts&line=$line">Remove</a>]</td></tr>\n!;
++      $DATA{'ALERTS'} .= qq!<tr><td class="$rowclass">$_</td><td class="$rowclass">[<a href="$CONFIG{'ME'}?command=deleteAlert&user=$FORM{'user'}&template=alerts&line=$line">$LANG{'remove_alert'}</a>]</td></tr>\n!;
+       $line++;
+ 
+       if ($rowclass eq "rowEven") {
+@@ -1494,11 +1505,11 @@
+   # Check admin permissions
+   do {
+     if ($CONFIG{'ADMIN'} == 1) {
+-      $DATA{'NAV_ADMIN'} = qq!<li><a href="admin.cgi">Administrative Suite</a></li>!;
+-      $DATA{'FORM_USER'} = qq!<form action="$CONFIG{'ME'}"><input type=hidden name="template" value="$FORM{'template'}">Statistical SPAM Protection for <INPUT TYPE=TEXT NAME=user SIZE=16 value="$CURRENT_USER"> <input type=submit value="Change"></form>!;
++      $DATA{'NAV_ADMIN'} = qq!<li><a href="admin.cgi">$LANG{'admin_suite'}</a></li>!;
++      $DATA{'FORM_USER'} = qq!<form action="$CONFIG{'ME'}"><input type=hidden name="template" value="$FORM{'template'}">$LANG{'user_form'} <INPUT TYPE=TEXT NAME=user SIZE=16 value="$CURRENT_USER"> <input type=submit value=$LANG{'user_form_submit'}></form>!;
+     } else {
+       $DATA{'NAV_ADMIN'} = '';
+-      $DATA{'FORM_USER'} = "Statistical SPAM Protection for <strong>$CURRENT_USER</strong>";
++      $DATA{'FORM_USER'} = "$LANG{'user_form'} <strong>$CURRENT_USER</strong>";
+     }
+   };
+ 
+@@ -1533,10 +1544,11 @@
+   my($error) = @_;
+   $FORM{'template'} = "error";
+   $DATA{'MESSAGE'} = <<_end;
+-The following error occured while trying to process your request: <BR>
++$LANG{'error_message_part1'}
++<BR>
+ <B>$error</B><BR>
+ <BR>
+-If this problem persists, please contact your administrator.
++$LANG{'error_message_part2'}
+ _end
+   &output(%DATA);
+   exit;
+@@ -1578,7 +1590,8 @@
+   }
+   close(FILE);   
+   if ($f == 0) {
+-    $f = "Empty";
++    $f = $LANG{'empty'};
++    #$f = "Empty";
+   }
+ 
+   $DATA{'TOTAL_QUARANTINED_MESSAGES'} = $f;
+@@ -1624,7 +1637,7 @@
+     return $PATH;
+   }
+ 
+-  &error("Unable to determine filesystem scale");
++  &error($LANG{'error_filesystem_scale'});
+ }
+ 
+ 
+@@ -1647,7 +1660,7 @@
+   if (keys(%PREFS) eq "0" || $CONFIG{'PREFERENCES_EXTENSION'} != 1) {
+ 
+     if (! -e "$DEFAULT_PREFS") {
+-      &error("Unable to load default preferences");
++      &error($LANG{'error_load_default_prefs'});
+     }
+     open(FILE, "<$DEFAULT_PREFS");
+     while(<FILE>) {
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/dspam.cgi.orig dspam-3.9.0~beta2/webui/cgi-bin/dspam.cgi.orig
+--- dspam-3.9.0~beta2~/webui/cgi-bin/dspam.cgi.orig	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/dspam.cgi.orig	2009-08-12 10:08:27.496733524 +0200
+@@ -0,0 +1,1671 @@
++#!/usr/bin/perl
++
++# $Id: dspam.cgi,v 1.37 2009/07/26 12:23:47 sbajic Exp $
++# DSPAM
++# COPYRIGHT (C) DSPAM PROJECT 2002-2009
++#
++# 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; version 2
++# of the License.
++#
++# 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.
++
++use strict;
++use Time::Local;
++use vars qw { %CONFIG %DATA %FORM $MAILBOX $CURRENT_USER $USER $TMPFILE};
++use vars qw { $CURRENT_STORE };
++require "ctime.pl";
++
++# Read configuration parameters common to all CGI scripts
++require "/etc/dspam/webfrontend.conf";
++
++if($CONFIG{"DATE_FORMAT"}) {
++  use POSIX qw(strftime);
++}
++
++#
++# The current CGI script
++#
++
++$CONFIG{'ME'} = "dspam.cgi";
++
++$| = 1;
++
++#
++# Determine which extensions are available
++#
++
++if ($CONFIG{'AUTODETECT'} == 1 || $CONFIG{'AUTODETECT'} eq "") {
++  $CONFIG{'PREFERENCES_EXTENSION'} = 0;
++  $CONFIG{'LARGE_SCALE'} = 0;
++  $CONFIG{'DOMAIN_SCALE'} = 0;
++  do {
++    my $x = `$CONFIG{'DSPAM'} --version`;
++    if ($x =~ /--enable-preferences-extension/) {
++      $CONFIG{'PREFERENCES_EXTENSION'} = 1;
++    }
++    if ($x =~ /--enable-large-scale/) {
++      $CONFIG{'LARGE_SCALE'} = 1;
++    }
++    if ($x =~ /--enable-domain-scale/) {
++      $CONFIG{'DOMAIN_SCALE'} = 1;
++    }
++  };
++}
++
++#
++# Determine admin status
++#
++
++$CONFIG{'ADMIN'} = 0;
++if ($ENV{'REMOTE_USER'} ne "") {
++  open(FILE, "</etc/dspam/admins");
++  while(<FILE>) {
++    chomp;
++    if ($_ eq $ENV{'REMOTE_USER'}) {
++      $CONFIG{'ADMIN'} = 1;
++    }
++  }
++  close(FILE);
++}
++
++#
++# Configure Filesystem
++#
++
++%FORM = &ReadParse;
++
++$CURRENT_USER = $ENV{'REMOTE_USER'};
++
++if ($FORM{'user'} ne "" && $CONFIG{'ADMIN'} == 1) {
++  $CURRENT_USER = $FORM{'user'};
++} else {
++  $FORM{'user'} = $CURRENT_USER ;
++}
++
++$CONFIG{'DSPAM_ARGS'} =~ s/%CURRENT_USER%/$CURRENT_USER/g;
++
++# Current Store
++do {
++  my(%PREF) = GetPrefs($CURRENT_USER);
++  $CURRENT_STORE = $PREF{"localStore"};
++  if ($CURRENT_STORE eq "") { $CURRENT_STORE = $CURRENT_USER; }
++};
++
++$USER = GetPath($CURRENT_STORE);
++$MAILBOX = $USER . ".mbox";
++$TMPFILE = $USER . ".tmp";
++
++if ($CURRENT_USER eq "") {
++  &error("System Error. I was unable to determine your identity.");
++}
++
++if ($FORM{'template'} eq "" || $FORM{'template'} !~ /^([A-Z0-9]*)$/i) {
++  $FORM{'template'} = "performance";
++}
++
++my($MYURL);
++$MYURL = "$CONFIG{'ME'}?user=$FORM{'user'}&template=$FORM{'template'}";
++
++#
++# Set up initial display variables
++#
++&CheckQuarantine;
++$DATA{'REMOTE_USER'} = $CURRENT_USER;
++
++#
++# Display DSPAM Version
++#
++$DATA{'DSPAMVERSION'} = $CONFIG{'DSPAM_VERSION'};
++
++#
++# Process Commands
++#
++
++# Performance
++if ($FORM{'template'} eq "performance") {
++  if ($FORM{'command'} eq "resetStats") {
++    &ResetStats;
++    redirect($MYURL);
++  } elsif ($FORM{'command'} eq "tweak") {
++    &Tweak;
++    redirect($MYURL);
++  } else {
++    &DisplayIndex;
++  }
++
++# Quarantine
++} elsif ($FORM{'template'} eq "quarantine") {
++  if ($FORM{'command'} eq "viewMessage") {
++    &Quarantine_ViewMessage;
++  } else {
++    $MYURL .= "&sortby=$FORM{'sortby'}" if ($FORM{'sortby'} ne "");
++    if ($FORM{'command'} eq "processQuarantine") {
++      &ProcessQuarantine;
++      redirect($MYURL);
++    } elsif ($FORM{'command'} eq "processFalsePositive") {
++      &ProcessFalsePositive;
++      redirect($MYURL);
++    } else {
++      &DisplayQuarantine;
++    }
++  }
++
++# Alerts
++} elsif ($FORM{'template'} eq "alerts") {
++  if ($FORM{'command'} eq "addAlert") {
++    &AddAlert;
++    redirect($MYURL);
++  } elsif ($FORM{'command'} eq "deleteAlert") {
++    &DeleteAlert;
++    redirect($MYURL);
++  } else {
++    &DisplayAlerts;
++  }
++
++# Preferences
++} elsif ($FORM{'template'} eq "preferences") {
++  &DisplayPreferences;
++
++# Analysis
++} elsif ($FORM{'template'} eq "analysis") {
++  &DisplayAnalysis;
++
++# History
++} elsif ($FORM{'template'} eq "history") {
++  &DisplayHistory;
++} elsif ($FORM{'template'} eq "fragment") {
++  &DisplayFragment;
++} else {
++  &error("Invalid Command $FORM{'COMMAND'}");
++}
++
++#
++# History Functions
++# 
++
++sub DisplayFragment {
++  $FORM{'signatureID'} =~ s/\///g;
++  $DATA{'FROM'} = $FORM{'from'};
++  $DATA{'SUBJECT'} = $FORM{'subject'};
++  $DATA{'INFO'} = $FORM{'info'};
++  $DATA{'TIME'} = $FORM{'time'};
++  open(FILE, "<$USER.frag/$FORM{'signatureID'}.frag") || &error($!);
++  while(<FILE>) {
++    s/</&lt\;/g;
++    s/>/&gt\;/g;
++    $DATA{'MESSAGE'} .= $_;
++  }
++  close(FILE);
++  &output(%DATA);
++}
++
++sub DisplayHistory {
++  my($all_lines , $begin, $history_pages, $rec, $history_page);
++  unless ($history_page = $FORM{'history_page'}) { $history_page = 1;}
++
++  my(@buffer, @history, $line, %rec);
++  my($rowclass) = "rowEven";
++
++  if ($CONFIG{'HISTORY_PER_PAGE'} == 0) {
++    $CONFIG{'HISTORY_PER_PAGE'} = 50;
++  }
++
++  my($show) = $FORM{'show'};
++  if ($show eq "") {
++    $show = "all";
++  }
++
++  if ($FORM{'command'} eq "retrainChecked") {
++    foreach my $i (0 .. $#{ $FORM{retrain_checked} }) {
++        my ($retrain, $signature) = split(/:/, $FORM{retrain_checked}[$i]);
++        if ($retrain eq "innocent") {
++          $FORM{'signatureID'} = $signature;
++          &ProcessFalsePositive();
++          undef $FORM{'signatureID'};
++         } elsif ($retrain eq "innocent" or $retrain eq "spam") {
++           system("$CONFIG{'DSPAM'} --source=error --class=" . quotemeta($retrain) . " --signature=" . quotemeta($signature) . " --user " . quotemeta("$CURRENT_USER"));
++         }
++    }
++  redirect("$MYURL&show=$show&history_page=$history_page");
++  } else {
++    if ($FORM{'retrain'} ne "") {
++       if ($FORM{'retrain'} eq "innocent") {
++         &ProcessFalsePositive();
++       } else {
++         system("$CONFIG{'DSPAM'} --source=error --class=" . quotemeta($FORM{'retrain'}) . " --signature=" . quotemeta($FORM{'signatureID'}) . " --user " . quotemeta("$CURRENT_USER"));
++       }
++    redirect("$MYURL&show=$show&history_page=$history_page");
++    }
++  }
++
++  my($LOG) = "$USER.log";
++  if (! -e $LOG) {
++    &error("No historical data is available");
++  }
++
++  # Preseed retraining information and delivery errors
++ 
++  open(LOG, "< $LOG") or die "Can't open log file $LOG";
++  while(<LOG>) {
++    my($time, $class, $from, $signature, $subject, $info, $messageid) 
++      = split(/\t/, $_);
++    next if ($signature eq "");
++
++    # not good to check for messages to show here, we're skipping
++    # the retraining data so retrained messages won't show
++
++    if ($class eq "M" || $class eq "F" || $class eq "E" || $class eq "U") {
++      if ($class eq "E" || $class eq "U") {
++        $rec{$signature}->{'info'} = $info;
++      } elsif ($class eq "F" || $class eq "M") {
++        $rec{$signature}->{'class'} = $class;
++        $rec{$signature}->{'count'}++;
++        $rec{$signature}->{'info'} = $info 
++          if ($rec{$signature}->{'info'} eq "");
++      }
++      # filter out resents if there are any.  Since it's the same
++      # message we only allow retraining on the 1st occurence of it.
++    } elsif ($messageid == ''
++	     || $rec{$signature}->{'messageid'} != $messageid
++	     || $CONFIG{'HISTORY_DUPLICATES'} ne "no") {
++
++      # skip unwanted messages
++      next if ($class ne "S" && $show eq "spam");
++      next if ($class ne "I" && $show eq "innocent");
++      next if ($class ne "W" && $show eq "whitelisted");
++      next if ($class ne "V" && $show eq "virus");
++      next if ($class ne "A" && $show eq "blacklisted");
++      next if ($class ne "O" && $show eq "blocklisted");
++
++      $rec{$signature}->{'time'} = $time;
++      $rec{$signature}->{'class'} = $class;
++      $rec{$signature}->{'from'} = $from;
++      $rec{$signature}->{'signature'} = $signature;
++      $rec{$signature}->{'subject'} = $subject;
++      $rec{$signature}->{'info'} = $info;
++      $rec{$signature}->{'messageid'} = $messageid;
++
++      unshift(@buffer, $rec{$signature});
++    }
++  }
++  close(LOG);
++
++  if($CONFIG{'HISTORY_SIZE'} < ($#buffer+1)) {
++    $history_pages = int($CONFIG{'HISTORY_SIZE'} / $CONFIG{'HISTORY_PER_PAGE'});
++    $history_pages += 1 if($CONFIG{'HISTORY_SIZE'} % $CONFIG{'HISTORY_PER_PAGE'});
++  } else {
++    $history_pages = int( ($#buffer+1) / $CONFIG{'HISTORY_PER_PAGE'});
++    $history_pages += 1 if(($#buffer+1) % $CONFIG{'HISTORY_PER_PAGE'});
++  }
++  $begin = int(($history_page - 1) * $CONFIG{'HISTORY_PER_PAGE'}) ;
++
++  # Now lets just keep the information that we really need. 
++  @buffer = splice(@buffer, $begin,$CONFIG{'HISTORY_PER_PAGE'});
++
++  my $retrain_checked_msg_no = 0;
++  my $counter = 0;
++  while ($rec = pop at buffer) {
++    $counter++;
++    my($time, $class, $from, $signature, $subject, $info, $messageid);
++
++    $time = $rec->{'time'};
++    $class = $rec->{'class'};
++    $from = $rec->{'from'};
++    $signature = $rec->{'signature'};
++    $subject = $rec->{'subject'};
++    $info = $rec->{'info'};
++    $messageid = $rec->{'messageid'};
++
++    next if ($signature eq "");
++    next if ($rec{$signature}->{'displayed'} ne "");
++    next if ($class eq "E");
++    $rec{$signature}->{'displayed'} = 1;
++
++    # Resends of retrained messages will need the original from/subject line
++    if ($messageid ne "") {
++      $from = $rec{$messageid}->{'from'} 
++        if ($from eq "<None Specified>");
++      $subject = $rec{$messageid}->{'subject'} 
++        if ($subject eq "<None Specified>");
++
++      $rec{$messageid}->{'from'} = $from 
++        if ($rec{$messageid}->{'from'} eq "");
++      $rec{$messageid}->{'subject'} = $subject 
++        if ($rec{$messageid}->{'subject'} eq "");
++    }
++
++    $from = "<None Specified>" if ($from eq "");
++    $subject = "<None Specified>" if ($subject eq "");
++
++    my $ctime;
++    if($CONFIG{"DATE_FORMAT"}) {
++      $ctime = strftime($CONFIG{"DATE_FORMAT"}, localtime($time));
++    } else {
++      $ctime = ctime($time);
++      my(@t) = split(/\:/, (split(/\s+/, $ctime))[3]);
++      my($x) = (split(/\s+/, $ctime))[0];
++      my($m) = "a";
++      if ($t[0]>=12) { $t[0] -= 12; $m = "p"; }
++      if ($t[0] == 0) { $t[0] = 12; }
++      $ctime = "$x $t[0]:$t[1]$m";
++    }
++
++    # Set the appropriate type and label for this message
++
++    my($cl, $cllabel);
++    $class = $rec{$signature}->{'class'} if ($rec{$signature}->{'class'} ne "");
++    if ($class eq "S") { $cl = "spam"; $cllabel="SPAM"; }
++    elsif ($class eq "I") { $cl = "innocent"; $cllabel="Good"; }
++    elsif ($class eq "F") {
++      if ($rec{$signature}->{'count'} % 2 != 0) {
++        $cl = "false"; $cllabel="Miss"; 
++      } else {
++        $cl = "innocent"; $cllabel="Good"; 
++      }
++    }
++    elsif ($class eq "M") { 
++      if ($rec{$signature}->{'count'} % 2 != 0) {
++          $cl = "missed"; $cllabel="Miss"; 
++      } else {
++          $cl = "spam"; $cllabel="SPAM";
++      }
++    }
++    elsif ($class eq "W") { $cl = "whitelisted"; $cllabel="Whitelist"; }
++    elsif ($class eq "V") { $cl = "virus"; $cllabel="Virus"; }
++    elsif ($class eq "A") { $cl = "blacklisted"; $cllabel="RBL"; }
++    elsif ($class eq "O") { $cl = "blocklisted"; $cllabel="BLOCK"; }
++    elsif ($class eq "N") { $cl = "inoculation"; $cllabel="SPAM"; }
++    elsif ($class eq "C") { $cl = "corpus"; $cllabel="Corpus"; }
++    elsif ($class eq "U") { $cl = "unknown"; $cllabel="UNKN"; }
++    elsif ($class eq "E") { $cl = "error"; $cllabel="Error"; }
++    if ($messageid ne "") {
++      if ($rec{$messageid}->{'resend'} ne "") {
++        $cl = "relay";
++        $cllabel = "Resend";
++      }
++      $rec{$messageid}->{'resend'} = $signature;
++    }
++
++    $info = $rec{$signature}->{'info'} if ($rec{$signature}->{'info'} ne "");
++
++    $from =~ s/</&lt;/g;
++    $from =~ s/>/&gt;/g;
++    $subject =~ s/</&lt;/g;
++    $subject =~ s/>/&gt;/g;
++
++    $from = substr($from, 0, $CONFIG{'MAX_COL_LEN'}) . "..." if (length($from)>$CONFIG{'MAX_COL_LEN'});
++    $subject = substr($subject, 0, $CONFIG{'MAX_COL_LEN'}) . "..." if (length($subject)>$CONFIG{'MAX_COL_LEN'});
++
++    my($rclass);
++    $rclass = "spam" if ($class eq "I" || $class eq "W" || $class eq "F");
++    $rclass = "innocent" if ($class eq "S" || $class eq "M" || $class eq "V" || $class eq "A" || $class eq "O");
++
++    my($retrain);
++    if ($rec{$signature}->{'class'} =~ /^(M|F)$/ && $rec{$signature}->{'count'} % 2 != 0) {
++      $retrain = "<b>Retrained</b>";
++    } 
++
++    if ($retrain eq "") {
++      $retrain = qq!<A HREF="$MYURL&show=$show&history_page=$history_page&retrain=$rclass&signatureID=$signature">As ! . ucfirst($rclass) . "</A>";
++    } else {
++      $retrain .= qq! (<A HREF="$MYURL&show=$show&history_page=$history_page&retrain=$rclass&signatureID=$signature">Undo</A>)!;
++    }
++
++    my($path) = "$USER.frag/$signature.frag";
++    if (-e $path) {
++      my(%pairs);
++      $pairs{'template'} = "fragment";
++      $pairs{'signatureID'} = $signature;
++      my($sub) = $subject;
++      $sub =~ s/#//g;
++      $sub =~ s/(['])/\\$1/g;
++      $pairs{'subject'} = $sub;
++      $pairs{'from'} = $from;
++      $pairs{'info'} = $info;
++      $pairs{'time'} = $ctime;
++      $pairs{'user'} = $FORM{'user'};
++      my($url) = &SafeVars(%pairs);
++      $from = qq!<a href="javascript:openwin(580,400,1,'$CONFIG{'ME'}?$url')">$from</a>!;
++    }
++
++    my $retrain_action = "";
++    if ( $class eq "V" || $class eq "A" || $class eq "O" || $class eq "U" || $class eq "") {
++      $retrain_action = qq!&nbsp;</td>!;
++    } else {
++      $retrain_action = qq! <input name="msgid$retrain_checked_msg_no" type="checkbox" value="$rclass:$signature" id="checkbox-$counter" onclick="checkboxclicked(this)">$retrain</td>!;
++    }
++
++    my($entry) = <<_END;
++<tr>
++	<td class="$cl $rowclass" nowrap="true"><small>$cllabel</td>
++        <td class="$rowclass" nowrap="true"><small>
++	$retrain_action
++	<td class="$rowclass" nowrap="true"><small>$ctime</td>
++	<td class="$rowclass" nowrap="true"><small>$from</td>
++	<td class="$rowclass" nowrap="true"><small>$subject</td>
++	<td class="$rowclass" nowrap="true"><small>$info</td>
++</tr>
++_END
++
++    $retrain_checked_msg_no++;
++    push(@history, $entry);
++
++    if ($rowclass eq "rowEven") {
++      $rowclass = "rowOdd";
++    } else {
++      $rowclass = "rowEven";
++    }
++
++  }
++
++  my $entry = <<_END;
++	<input name="history_page" type="hidden" value="$history_page">
++_END
++  push(@history, $entry);
++
++  while($line = pop(@history)) { $DATA{'HISTORY'} .= $line; }
++
++  if ($CONFIG{'HISTORY_PER_PAGE'} > 0) {
++    $DATA{'HISTORYPAGES'} = "<div class=\"historypages\">[";
++    if (($history_pages > 1) && ($history_page > 1)) {
++      my $i = $history_page-1;
++      $DATA{'HISTORYPAGES'} = "<a href=\"$MYURL&show=$show&history_page=$i\">&nbsp;&lt;&nbsp;</a>";
++    }
++    for(my $i = 1; $i <= $history_pages; $i++) {
++  
++      if ($i == $history_page) {
++        $DATA{'HISTORYPAGES'} .= "<a href=\"$MYURL&show=$show&history_page=$i\"><big><strong>&nbsp;$i&nbsp;</strong></big></a>";
++      } else {
++        $DATA{'HISTORYPAGES'} .= "<a href=\"$MYURL&show=$show&history_page=$i\">&nbsp;$i&nbsp;</a>";
++      }
++    }
++    if (($history_pages > 1) && ($history_page < $history_pages)) {
++      my $i = $history_page+1;
++      $DATA{'HISTORYPAGES'} .= "<a href=\"$MYURL&show=$show&history_page=$i\">&nbsp;&gt;&nbsp;</a>";
++    }
++    $DATA{'HISTORYPAGES'} .= "]</div>";
++  }
++
++  $DATA{'SHOW'} = $show;
++  $DATA{'SHOW_SELECTOR'} .=  "Show: <a href=\"$MYURL&show=all\">";
++  if ($show eq "all") {
++    $DATA{'SHOW_SELECTOR'} .= "<strong>all</strong>";
++  } else {
++    $DATA{'SHOW_SELECTOR'} .= "all";
++  }
++  $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=spam\">";
++  if ($show eq "spam") {
++    $DATA{'SHOW_SELECTOR'} .= "<strong>spam</strong>";
++  } else {
++    $DATA{'SHOW_SELECTOR'} .= "spam";
++  }
++  $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=innocent\">";
++  if ($show eq "innocent") {
++    $DATA{'SHOW_SELECTOR'} .= "<strong>innocent</strong>";
++  } else {
++    $DATA{'SHOW_SELECTOR'} .= "innocent";
++  }
++  $DATA{'SHOW_SELECTOR'} .=  "</a> | <a href=\"$MYURL&show=whitelisted\">";
++  if ($show eq "whitelisted") {
++    $DATA{'SHOW_SELECTOR'} .= "<strong>whitelisted</strong>";
++  } else {
++    $DATA{'SHOW_SELECTOR'} .= "whitelisted";
++  }
++  $DATA{'SORT_SELECTOR'} .=  "</a>";
++
++  &output(%DATA);
++}
++
++#
++# Analysis Functions
++#
++
++sub DisplayAnalysis {
++  my($LOG) = "$USER.log";
++
++  my %Stats=(
++    daily	=> {},
++    weekly	=> {},
++  );
++
++  my ($min, $hour, $mday, $mon, $year) = (localtime(time))[1,2,3,4,5];
++  my ($daystart) = timelocal(0, 0, 0, $mday, $mon, $year);
++  my ($periodstart) = $daystart - (3600*24*13); # 2 Weeks ago
++  my ($dailystart) = time - (3600*23);
++
++  if (! -e $LOG) {
++    &error("No historical data is available.");
++  }
++
++  open(LOG, "<$LOG") || &error("Unable to open logfile: $!");
++  while(<LOG>) {
++    my($t_log, $c_log) = split(/\t/);
++
++    # Only Parse Log Data in our Time Period
++    if ($t_log>=$periodstart) {
++      my($tmin, $thour, $tday, $tmon) = (localtime($t_log))[1,2,3,4];
++      $tmon++;
++
++      foreach my $period (qw( weekly daily )) {
++        my $idx;
++        if ($period eq "weekly") {
++          $idx="$tmon/$tday";
++        } else { 
++          ($t_log>=$dailystart) || next;
++          $idx=To12Hour($thour);
++        }
++        if (!exists $Stats{$period}->{$idx}) {
++          $Stats{$period}->{$idx}={
++		nonspam	=>	0,
++		spam	=>	0,
++		title	=>	$idx,
++		idx	=>	$t_log,
++          };
++        }
++        my $hr=$Stats{$period}->{$idx};
++        if ($c_log eq "S" || $c_log eq "V" || $c_log eq "A" || $c_log eq "O") {
++          $hr->{spam}++;
++        }
++        if ($c_log eq "I" || $c_log eq "W") {
++          $hr->{nonspam}++;
++        }
++        if ($c_log eq "F") {
++          $hr->{spam}--;
++          ($hr->{spam}<0) && ($hr->{spam}=0);
++          $hr->{nonspam}++;
++        }
++        if ($c_log eq "M") {
++          $hr->{nonspam}--;
++          ($hr->{nonspam}<0) && ($hr->{nonspam}=0);
++          $hr->{spam}++;
++        }
++      }
++    }
++  }
++  close(LOG);
++
++  foreach my $period (qw( daily weekly )) {
++    my $uc_period=uc($period);
++    my $hk="DATA_$uc_period";
++    my %lst=();
++    foreach my $hr (sort {$a->{idx}<=>$b->{idx}} (values %{$Stats{$period}})) {
++      foreach my $type (qw( spam nonspam title )) {
++        (exists $lst{$type}) || ($lst{$type}=[]);
++        push(@{$lst{$type}},$hr->{$type});
++        my $totk="";
++        if ($type eq "spam") { $totk="S"; }
++        elsif ($type eq "nonspam") { $totk="I"; }
++        ($totk eq "") && next;
++        my $sk="T${totk}_$uc_period";
++        (exists $DATA{$sk}) || ($DATA{$sk}=0);
++        $DATA{$sk}+=$hr->{$type};
++      }
++    }
++    $DATA{$hk}=join("_",
++		join(",",@{$lst{spam}}),
++		join(",",@{$lst{nonspam}}),
++		join(",",@{$lst{title}}),
++	);
++  }
++
++  &output(%DATA);
++}
++
++#
++# Preferences Functions
++#
++
++sub DisplayPreferences {
++  my(%PREFS);
++  my($FILE) = "/etc/dspam/default.prefs";
++
++  my $username = $CURRENT_USER;
++
++  if ($FORM{'submit'} ne "") {
++
++    if ($FORM{'enableBNR'} ne "on") {
++      $FORM{'enableBNR'} = "off";
++    }
++
++    if ($FORM{'optIn'} ne "on") {
++      $FORM{'optIn'} = "off";
++    }
++
++    if ($FORM{'optOut'} ne "on") {
++      $FORM{'optOut'} = "off";
++    }
++
++    if ($FORM{'showFactors'} ne "on") {
++      $FORM{'showFactors'} = "off";
++    }
++                                                                                
++    if ($FORM{'enableWhitelist'} ne "on") {
++      $FORM{'enableWhitelist'} = "off";
++    }
++
++    if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
++
++      if ($FORM{'spamSubject'} eq "") {
++        $FORM{'spamSubject'} = "''";
++      } else {
++        $FORM{'spamSubject'} = quotemeta($FORM{'spamSubject'});
++      }
++
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " trainingMode " . quotemeta($FORM{'trainingMode'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " spamAction " . quotemeta($FORM{'spamAction'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " signatureLocation "
++        . quotemeta($FORM{'signatureLocation'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " spamSubject " . $FORM{'spamSubject'} . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " statisticalSedation "
++        . quotemeta($FORM{'statisticalSedation'}) . " > /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " enableBNR "
++        . quotemeta($FORM{'enableBNR'}) . "> /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " optOut "
++        . quotemeta($FORM{'optOut'}) . ">/dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " optIn "
++        . quotemeta($FORM{'optIn'}) . ">/dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " showFactors "
++        . quotemeta($FORM{'showFactors'}) . "> /dev/null");
++      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
++        " enableWhitelist "
++        . quotemeta($FORM{'enableWhitelist'}) . "> /dev/null");
++
++    } else {
++      open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
++      print FILE <<_END;
++trainingMode=$FORM{'trainingMode'}
++spamAction=$FORM{'spamAction'}
++spamSubject=$FORM{'spamSubject'}
++statisticalSedation=$FORM{'statisticalSedation'}
++enableBNR=$FORM{'enableBNR'}
++optIn=$FORM{'optIn'}
++optOut=$FORM{'optOut'}
++showFactors=$FORM{'showFactors'}
++enableWhitelist=$FORM{'enableWhitelist'}
++signatureLocation=$FORM{'signatureLocation'}
++_END
++      close(FILE);
++    }
++  redirect("$CONFIG{'ME'}?user=$FORM{'user'}&template=preferences");
++  }
++
++  %PREFS = GetPrefs();
++
++  $DATA{"SEDATION_$PREFS{'statisticalSedation'}"} = "CHECKED";
++  $DATA{"S_".$PREFS{'trainingMode'}} = "CHECKED";
++  $DATA{"S_ACTION_".uc($PREFS{'spamAction'})} = "CHECKED"; 
++  $DATA{"S_LOC_".uc($PREFS{'signatureLocation'})} = "CHECKED";
++  $DATA{"SPAM_SUBJECT"} = $PREFS{'spamSubject'};
++  if ($PREFS{'optIn'} eq "on") {
++    $DATA{'C_OPTIN'} = "CHECKED";
++  }
++  if ($PREFS{'optOut'} eq "on") {
++    $DATA{'C_OPTOUT'} = "CHECKED";
++  }
++  if ($PREFS{"enableBNR"} eq "on") {
++    $DATA{"C_BNR"} = "CHECKED";
++  }
++  if ($PREFS{"showFactors"} eq "on") {
++    $DATA{"C_FACTORS"} = "CHECKED"; 
++  }
++  if ($PREFS{"enableWhitelist"} eq "on") {
++    $DATA{"C_WHITELIST"} = "CHECKED";
++  }
++
++  if ($CONFIG{'OPTMODE'} eq "OUT") {
++    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optOut " . $DATA{'C_OPTOUT'} . ">Disable DSPAM filtering<br>";
++  } elsif ($CONFIG{'OPTMODE'} eq "IN") {
++    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optIn " . $DATA{'C_OPTIN'} . ">Enable DSPAM filtering<br>";
++  } else {
++    $DATA{"OPTION"} = "";
++  }
++
++  &output(%DATA);
++}
++
++#
++# Quarantine Functions
++#
++
++sub ProcessQuarantine {
++  if ($FORM{'manyNotSpam'} ne "") {
++    &Quarantine_ManyNotSpam;
++  } else {
++    &Quarantine_DeleteSpam;
++  }
++  &CheckQuarantine;
++  return;
++}
++
++sub ProcessFalsePositive {
++  my(@buffer, %head, $found);
++  if ($FORM{'signatureID'} eq "") {
++    &error("No Message ID Specified");
++  }
++  open(FILE, "<$MAILBOX");
++  while(<FILE>) {
++    s/\r?\n$//;
++    push(@buffer, $_);
++  }
++  close(FILE);
++
++  while($#buffer>=0) {
++    my($buff, $mode, @temp);
++    $mode = 0;
++    @temp = ();
++    while(($buff !~ /^From /) && ($#buffer>=0)) {
++      $buff = $buffer[0];
++      if ($buff =~ /^From /) {
++        if ($mode == 0) { $mode = 1; }
++        else { next; }
++      }
++      $buff = shift(@buffer);
++      if ($buff !~ /^From /) {
++        push(@temp, $buff);
++      }
++      next;
++    }
++    foreach(@temp) {
++      last if ($_ eq "");
++      my($key, $val) = split(/\: ?/, $_, 2);
++      $head{$key} = $val;
++    }
++    if ($head{'X-DSPAM-Signature'} eq $FORM{'signatureID'}) {
++      $found = 1;
++      open(PIPE, "|$CONFIG{'DSPAM'} $CONFIG{'DSPAM_ARGS'}  >$TMPFILE 2>&1") || &error($!);
++      foreach(@temp) {
++        print PIPE "$_\n";
++      }
++      close(PIPE);
++    }
++  }
++
++  # Couldn't find the message, so just retrain on signature
++  if (!$found) {
++    system("$CONFIG{'DSPAM'} --source=error --class=innocent --signature=" . quotemeta($FORM{'signatureID'}) . " --user " . quotemeta("$CURRENT_USER"));
++  }
++
++  if ($?) {
++    my(@log);
++    open(LOG, "<$TMPFILE");
++    @log = <LOG>;
++    close(LOG);
++    unlink("$TMPFILE");
++    &error("<PRE>".join('', @log)."</PRE>");
++  }
++
++  unlink("$TMPFILE");
++  $FORM{$FORM{'signatureID'}} = "on";
++  &Quarantine_DeleteSpam();
++  return;
++}
++
++sub Quarantine_ManyNotSpam {
++  my(@buffer, @errors);
++
++  open(FILE, "<$MAILBOX");
++  while(<FILE>) {
++    s/\r?\n$//;
++    push(@buffer, $_);
++  }
++  close(FILE);
++
++  open(FILE, ">$MAILBOX") || &error($!);
++  open(RETRAIN, ">>$USER.retrain.log");
++
++  while($#buffer>=0) {
++    my($buff, $mode, @temp, %head, $delivered);
++    $mode = 0;
++    while(($buff !~ /^From /) && ($#buffer>=0)) {
++      $buff = $buffer[0];
++      if ($buff =~ /^From /) {
++        if ($mode == 0) {
++          $mode = 1;
++          $buff = shift(@buffer);
++          push(@temp, $buff);
++          $buff = "";
++          next;
++        } else {
++          next;
++        }
++      }
++      $buff = shift(@buffer);
++      push(@temp, $buff);
++      next;
++    }
++    foreach(@temp) {
++      last if ($_ eq "");
++      my($key, $val) = split(/\: ?/, $_, 2);
++      $head{$key} = $val;
++    }
++    $delivered = 0;
++    if ($FORM{$head{'X-DSPAM-Signature'}} ne "") {
++      my($err);
++      $err = &Deliver(@temp);
++      if ($err eq "") {
++        $delivered = 1;
++      } else {
++        push(@errors, $err);
++      }
++    }
++    if (!$delivered) {
++      foreach(@temp) {
++        print FILE "$_\n";
++      }
++    } else {
++      print RETRAIN time . "\t$head{'X-DSPAM-Signature'}\tinnocent\n";
++    }
++  }
++  close(RETRAIN);
++  close(FILE);
++  if (@errors > 0) {
++    &error(join("<BR>", @errors));
++  }
++  return;
++}
++
++sub Deliver {
++  my(@temp) = @_;
++  open(PIPE, "|$CONFIG{'DSPAM'} $CONFIG{'DSPAM_ARGS'}") || return $!;
++  foreach(@temp) {
++    print PIPE "$_\n" || return $!;
++  }
++  close(PIPE) || return $!;
++  return "";
++}
++
++sub Quarantine_ViewMessage {
++  my(@buffer);
++
++  if ($FORM{'signatureID'} eq "") {
++    &error("No Message ID Specified");
++  }
++
++  $DATA{'MESSAGE_ID'} = $FORM{'signatureID'};
++
++  open(FILE, "<$MAILBOX");
++  while(<FILE>) {
++    s/\r?\n//;
++    push(@buffer, $_);
++  }
++  close(FILE);
++
++  while($#buffer>=0) {
++    my($buff, $mode, @temp, %head);
++    $mode = 0;
++    @temp = ();
++    while(($buff !~ /^From /) && ($#buffer>=0)) {
++      $buff = $buffer[0];
++      if ($buff =~ /^From /) {
++        if ($mode == 0) { $mode = 1; }
++        else { next; }
++      }
++      $buff = shift(@buffer);
++      if ($buff !~ /^From /) {
++        push(@temp, $buff);
++      }
++      next;
++    }
++    foreach(@temp) {
++      last if ($_ eq "");
++      my($key, $val) = split(/\: ?/, $_, 2);
++      $head{$key} = $val;
++    }
++    if ($head{'X-DSPAM-Signature'} eq $FORM{'signatureID'}) {
++      foreach(@temp) {
++        s/</\&lt\;/g;
++        s/>/\&gt\;/g;
++        $DATA{'MESSAGE'} .= "$_\n";
++      }
++    }
++  }
++  $FORM{'template'} = "viewmessage";
++  &output(%DATA);
++}
++
++sub Quarantine_DeleteSpam {
++  my(@buffer);
++  if ($FORM{'deleteAll'} ne "") {
++    my($sz);
++
++    my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
++     $atime,$mtime,$ctime,$blksize,$blocks)
++     = stat("$USER.mbox");
++                                                                                
++    open(FILE, "<$USER.mbox.size");
++    $sz = <FILE>;
++    close(FILE); 
++    chomp($sz);
++
++    if ($sz == $size) {
++      open(FILE, ">$MAILBOX");
++      close(FILE);
++      unlink("$USER.mbox.size");
++      unlink("$USER.mboxwarn");
++    } else {
++      return;
++    }
++
++    $FORM{'template'} = "performance";
++    &CheckQuarantine;
++    redirect("$CONFIG{'ME'}?user=$FORM{'user'}&template=$FORM{'template'}");
++    return; 
++  }
++  open(FILE, "<$MAILBOX");
++  while(<FILE>) {
++    s/\r?\n//;
++    push(@buffer, $_);
++  }
++  close(FILE);
++ 
++
++  open(FILE, ">$MAILBOX");
++ 
++  while($#buffer>=0) {
++    my($buff, $mode, @temp, %head);
++    $mode = 0;
++    while(($buff !~ /^From /) && ($#buffer>=0)) {
++      $buff = $buffer[0];
++      if ($buff =~ /^From /) {
++        if ($mode == 0) { 
++          $mode = 1; 
++          $buff = shift(@buffer); 
++          push(@temp, $buff); 
++          $buff = ""; 
++          next; 
++        } else { 
++          next; 
++        }
++      }
++      $buff = shift(@buffer);
++      push(@temp, $buff);
++      next;
++    }
++    foreach(@temp) {
++      last if ($_ eq "");
++      my($key, $val) = split(/\: ?/, $_, 2);
++      $head{$key} = $val;
++    }
++    if ($FORM{$head{'X-DSPAM-Signature'}} eq "") {
++      foreach(@temp) {
++        print FILE "$_\n";
++      }
++    }
++  }
++  close(FILE);
++  return;
++}
++
++sub by_rating { $a->{'rating'} <=> $b->{'rating'} }
++sub by_subject { lc($a->{'Subject'}) cmp lc($b->{'Subject'}) }
++sub by_from { lc($a->{'From'}) cmp lc($b->{'From'}) }
++
++sub DisplayQuarantine {
++  my(@alerts);
++
++  my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
++   $atime,$mtime,$ctime,$blksize,$blocks)
++   = stat("$USER.mbox");
++
++  open(FILE, ">$USER.mbox.size");
++  print(FILE "$size");
++  close(FILE);
++
++  open(FILE, ">$MAILBOX.stamp");
++  close(FILE);
++  chmod 0660, "$MAILBOX.stamp";
++
++  open(FILE, "<$USER.alerts");
++  while(<FILE>) {
++    chomp;
++    push(@alerts, $_);
++  }
++  close(FILE);
++
++  my($next, @buffer, $rowclass, $mode, $markclass, $marklabel, @headings);
++  $rowclass="rowEven";
++  open(FILE, "<$MAILBOX");
++  while(<FILE>) {
++    s/\r?\n//;
++    if ($_ ne "") {
++      if ($mode eq "") { 
++        if ($_ =~ /^From /) {
++          $mode = 1;
++        } else { 
++          next; 
++        } 
++      }
++      push(@buffer, $_);
++      next;
++    }
++    next if ($mode eq "");
++
++    my($new, $start, $alert);
++    $alert = 0;
++    $new = {};
++    foreach(@buffer) {
++      my($al);
++      foreach $al (@alerts) {
++        if (/$al/i) {
++          $alert = 1;
++        }
++      }
++      if ($_ =~ /^From /) {
++        my(@a) = split(/ /, $_);
++        my($x) = 2;
++        for (0..$#a) { 
++          if (($a[$_] =~ /\@|>/) && ($_>$x)) { 
++            $x = $_ + 1;
++          }
++        }
++        for(1..$x) { shift(@a); }
++        $start = join(" ", @a);
++      } else {
++        my($key, $val) = split(/\: ?/, $_, 2);
++        $new->{$key} = $val; 
++      }
++    }
++    if ($rowclass eq "rowEven") { 
++      $rowclass = "rowOdd";
++    } else { 
++      $rowclass = "rowEven";
++    }
++
++    $new->{'alert'} = $alert;
++
++    if ($alert) { $rowclass="rowAlert"; }
++
++    $new->{'Sub2'} = $new->{'X-DSPAM-Signature'};
++    if (length($new->{'Subject'})>$CONFIG{'MAX_COL_LEN'}) {
++      $new->{'Subject'} = substr($new->{'Subject'}, 0, $CONFIG{'MAX_COL_LEN'}) . "...";
++    } 
++ 
++    if (length($new->{'From'})>$CONFIG{'MAX_COL_LEN'}) {
++      $new->{'From'} = substr($new->{'From'}, 0, $CONFIG{'MAX_COL_LEN'}) . "...";
++    }
++
++    if ($new->{'Subject'} eq "") {
++      $new->{'Subject'} = "<None Specified>";
++    }
++
++#   $new->{'rating'} = $new->{'X-DSPAM-Probability'} * $new->{'X-DSPAM-Confidence'};
++    $new->{'rating'} = $new->{'X-DSPAM-Confidence'};
++
++    foreach(keys(%$new)) {
++      next if ($_ eq "X-DSPAM-Signature");
++      $new->{$_} =~ s/</\&lt\;/g;
++      $new->{$_} =~ s/>/\&gt\;/g;
++    }
++
++    push(@headings, $new);
++
++    @buffer = ();
++    $mode = "";
++    next;
++  }
++
++  my($sortBy) = $FORM{'sortby'};
++  if ($sortBy eq "") {
++    $sortBy = $CONFIG{'SORT_DEFAULT'};
++  }
++  if ($sortBy eq "Rating") {
++    @headings = sort by_rating @headings;
++  }
++  if ($sortBy eq "Subject") {
++    @headings = sort by_subject @headings;
++  }
++  if ($sortBy eq "From") {
++    @headings = sort by_from @headings;
++  }
++  if ($sortBy eq "Date") {
++    @headings = reverse @headings;
++  }
++
++  $DATA{'SORTBY'} = $sortBy;
++  $DATA{'SORT_QUARANTINE'} .=  "<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=Rating&user=$FORM{'user'}\">";
++  if ($sortBy eq "Rating") {
++    $DATA{'SORT_QUARANTINE'} .= "<strong>Rating</strong>";
++  } else {
++    $DATA{'SORT_QUARANTINE'} .= "Rating";
++  }
++  $DATA{'SORT_QUARANTINE'} .=  "</a></th>\n\t<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=Date&user=$FORM{'user'}\">";
++  if ($sortBy eq "Date") {
++    $DATA{'SORT_QUARANTINE'} .= "<strong>Date</strong>";
++  } else {
++    $DATA{'SORT_QUARANTINE'} .= "Date";
++  }
++  $DATA{'SORT_QUARANTINE'} .=  "</a></th>\n\t<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=From&user=$FORM{'user'}\">";
++  if ($sortBy eq "From") {
++    $DATA{'SORT_QUARANTINE'} .= "<strong>From</strong>";
++  } else {
++    $DATA{'SORT_QUARANTINE'} .= "From";
++  }
++  $DATA{'SORT_QUARANTINE'} .=  "</a></th>\n\t<th><a href=\"$CONFIG{'ME'}?user=$FORM{'user'}&template=quarantine&sortby=Subject&user=$FORM{'user'}\">";
++  if ($sortBy eq "Subject") {
++    $DATA{'SORT_QUARANTINE'} .= "<strong>Subject</strong>";
++  } else {
++    $DATA{'SORT_QUARANTINE'} .= "Subject";
++  }
++  $DATA{'SORT_QUARANTINE'} .=  "</a></th>";
++
++
++  my($row, $rowclass, $counter);
++  $rowclass = "rowEven";
++  $counter = 0;
++  for $row (@headings) {
++    $counter++;
++    my($rating, $url, $markclass, $outclass);
++    $rating = sprintf("%3.0f%%", $row->{'rating'} * 100.0);
++    if ($row->{'rating'} > 0.8) {
++	$markclass = "high";
++    } else {
++	if ($row->{'rating'} < 0.7) {
++	    $markclass = "low";
++	} else {
++	    $markclass = "medium";
++	}
++    }
++
++    my(%PAIRS);
++    $PAIRS{'signatureID'} = $row->{'X-DSPAM-Signature'};
++    $PAIRS{'command'}  = "viewMessage";
++    $PAIRS{'user'} = $CURRENT_USER;
++    $PAIRS{'template'} = "quarantine";
++    $url = &SafeVars(%PAIRS);
++
++    if ($row->{'alert'}) {
++      $outclass = "rowAlert";
++    } else {
++      $outclass = $rowclass;
++    }
++
++    my(@ptfields) = split(/\s+/, $row->{'X-DSPAM-Processed'});
++    my(@times) = split(/\:/, $ptfields[3]);
++    my($ptime);
++    if($CONFIG{"DATE_FORMAT"}) {
++      my($month);
++      $month->{'Jan'}=0;
++      $month->{'Feb'}=1;
++      $month->{'Mar'}=2;
++      $month->{'Apr'}=3;
++      $month->{'May'}=4;
++      $month->{'Jun'}=5;
++      $month->{'Jul'}=6;
++      $month->{'Aug'}=7;
++      $month->{'Sep'}=8;
++      $month->{'Oct'}=9;
++      $month->{'Nov'}=10;
++      $month->{'Dec'}=11;
++      $ptime = strftime($CONFIG{"DATE_FORMAT"}, $times[2],$times[1],$times[0],$ptfields[2],$month->{$ptfields[1]},$ptfields[4]-1900);
++    } else {
++      my($mer) = "a";
++      if ($times[0] > 12) { $times[0] -= 12; $mer = "p"; }
++      if ($times[0] == 0) { $times[0] = "12"; }
++      $ptime = "$ptfields[1] $ptfields[2] $times[0]:$times[1]$mer";
++      }
++
++    $DATA{'QUARANTINE'} .= <<_END;
++<tr>
++	<td class="$outclass" nowrap="true"><input type="checkbox" name="$row->{'X-DSPAM-Signature'}" id="checkbox-$counter" onclick="checkboxclicked(this)"></td>
++	<td class="$outclass $markclass" nowrap="true">$rating</td>
++        <td class="$outclass" nowrap="true">$ptime</td>
++	<td class="$outclass" nowrap="true">$row->{'From'}</td>
++	<td class="$outclass" nowrap="true"><a href="$CONFIG{'ME'}?$url">$row->{'Subject'}</a></td>
++</tr>
++_END
++
++    if ($rowclass eq "rowEven") {
++      $rowclass = "rowOdd";
++    } else {
++      $rowclass = "rowEven";
++    }
++  }
++
++  &output(%DATA);
++}
++
++#
++# Performance Functions
++#
++
++sub ResetStats {
++  my($ts, $ti, $tm, $fp, $sc, $ic);
++  my($group);
++  open(FILE, "<$USER.stats");
++  chomp($ts = <FILE>);
++  chomp($group = <FILE>); 
++  close(FILE);
++  ($ts, $ti, $tm, $fp, $sc, $ic) = split(/\,/, $ts);
++  
++  if ($group ne "") {
++    my($GROUP) = GetPath($group) . ".stats";
++    my($gts, $gti, $gtm, $gfp, $gsc, $gic);
++    open(FILE, "<$GROUP");
++    chomp($gts = <FILE>);
++    close(FILE);
++    ($gts, $gti, $gtm, $gfp, $gsc, $gic) = split(/\,/, $gts);
++    $ts       -= $gts;
++    $ti       -= $gti;
++    $tm       -= $gtm;
++    $fp       -= $gfp;
++    $sc       -= $gsc;
++    $ic       -= $gic;
++  }
++
++  open(FILE, ">$USER.rstats");
++  print FILE "$ts" . "," . "$ti" . "," . "$tm" . "," .
++             "$fp" . "," . "$sc" . "," . "$ic\n";
++  close(FILE);
++}
++
++sub Tweak {
++  my($ts, $ti, $tm, $fp, $sc, $ic);
++  open(FILE, "<$USER.rstats");
++  chomp($ts = <FILE>);
++  close(FILE);
++  ($ts, $ti, $tm, $fp, $sc, $ic) = split(/\,/, $ts);
++  $tm++;
++  open(FILE, ">$USER.rstats");
++  print FILE "$ts,$ti,$tm,$fp,$sc,$ic\n";
++  close(FILE);
++}
++
++sub DisplayIndex {
++  my($spam, $innocent, $ratio, $fp, $misses);
++  my($rts, $rti, $rtm, $rfp, $sc, $ic, $overall, $fpratio, $monthly, 
++     $real_missed, $real_caught, $real_fp, $real_innocent);
++  my($time) = ctime(time);
++  my($group);
++
++  open(FILE, "<$USER.stats");
++  chomp($spam = <FILE>);
++  chomp($group = <FILE>); 
++  close(FILE);
++  ($spam, $innocent, $misses, $fp, $sc, $ic) = split(/\,/, $spam);
++
++  if ($group ne "") {
++    my($GROUP) = GetPath($group) . ".stats";
++    my($gspam, $ginnocent, $gmisses, $gfp, $gsc, $gic);
++    open(FILE, "<$GROUP");
++    chomp($gspam = <FILE>);
++    close(FILE);
++    ($gspam, $ginnocent, $gfp, $gmisses, $gsc, $gic) = split(/\,/, $gspam);
++    $spam     -= $gspam;
++    $innocent -= $ginnocent;
++    $misses   -= $gmisses;
++    $fp       -= $gfp;
++    $sc       -= $gsc;
++    $ic       -= $gic;
++  }
++
++  if ($spam+$innocent>0) { 
++    $ratio = sprintf("%2.3f", 
++      (($spam+$misses)/($spam+$misses+$fp+$innocent)*100)); 
++  } else { 
++    $ratio = 0; 
++  }
++
++  if (open(FILE, "<$USER.rstats")) {
++    my($rstats);
++   
++    chomp($rstats = <FILE>);
++    ($rts, $rti, $rtm, $rfp) = split(/\,/, $rstats);
++    close(FILE);
++    $real_missed = $misses-$rtm;
++    $real_caught = $spam-$rts;
++    $real_fp = $fp-$rfp;
++    if ($real_fp < 0) { $real_fp = 0; }
++    $real_innocent = $innocent-$rti; 
++    if (($spam-$rts > 0) && ($spam-$rts + $misses-$rtm != 0) &&
++        ($real_caught+$real_missed>0) && ($real_fp+$real_innocent>0)) {
++      $monthly = sprintf("%2.3f", 
++        (100.0-(($real_missed)/($real_caught+$real_missed))*100.0));
++      $overall = sprintf("%2.3f", 
++        (100-((($real_missed+$real_fp) / 
++        ($real_fp+$real_innocent+$real_caught+$real_missed))*100)));
++    } else {
++      if ($real_caught == 0 && $real_missed > 0) {
++        $monthly = 0;
++        $overall = 0;
++      } else {
++        $monthly = 100;
++        $overall = 100;
++      }
++    }
++
++    if ($real_fp+$real_innocent>0) {
++      $fpratio = sprintf("%2.3f", ($real_fp/($real_fp+$real_innocent)*100));
++    } else {
++      $fpratio = 0;
++    }
++
++  } else {
++    $rts = $spam+$misses;
++    $rti = $innocent;
++    $rtm = $misses;
++    $rfp = $fp;
++    open(FILE, ">$USER.rstats");
++    print FILE "$rts,$rti,$rtm,$rfp\n";
++    close(FILE);
++    $monthly = "N/A";
++    $fpratio = "N/A";
++    $overall = "N/A";
++  }
++
++  $DATA{'TIME'} = $time;
++  $DATA{'TOTAL_SPAM_SCANNED'} = $spam;
++  $DATA{'TOTAL_SPAM_LEARNED'} = $misses;
++  $DATA{'TOTAL_NONSPAM_SCANNED'} = $innocent;
++  $DATA{'TOTAL_NONSPAM_LEARNED'} = $fp;
++  $DATA{'SPAM_RATIO'} = $ratio;
++  $DATA{'SPAM_ACCURACY'} = $monthly;
++  $DATA{'NONSPAM_ERROR_RATE'} = $fpratio;
++  $DATA{'OVERALL_ACCURACY'} = $overall;
++  $DATA{'TOTAL_SPAM_CORPUSFED'} = $sc;
++  $DATA{'TOTAL_NONSPAM_CORPUSFED'} = $ic;
++  $DATA{'TOTAL_SPAM_MISSED'} = $real_missed;
++  $DATA{'TOTAL_SPAM_CAUGHT'} = $real_caught;
++  $DATA{'TOTAL_NONSPAM_MISSED'} = $real_fp;
++  $DATA{'TOTAL_NONSPAM_CAUGHT'} = $real_innocent;
++
++  if ($CURRENT_USER !~ /\@/) {
++    $DATA{'LOCAL_DOMAIN'} = "\@$CONFIG{'LOCAL_DOMAIN'}";
++  }  
++
++  &output(%DATA);
++}
++
++#
++# Alert Functions
++#
++
++sub AddAlert {
++  if ($FORM{'ALERT'} eq "") {
++    &error("No Alert Specified");
++  }
++  open(FILE, ">>$USER.alerts");
++  print FILE "$FORM{'ALERT'}\n";
++  close(FILE);
++  return;
++}
++                                                                                
++sub DeleteAlert {
++  my($line, @alerts);
++  $line = 0;
++  if ($FORM{'line'} eq "") {
++    &Error("No Alert Specified");
++  }
++  open(FILE, "<$USER.alerts");
++  while(<FILE>) {
++    if ($line != $FORM{'line'}) {
++      push(@alerts, $_);
++    }
++    $line++;
++  }
++  close(FILE);
++                                                                                
++  open(FILE, ">$USER.alerts");
++  foreach(@alerts) { print FILE $_; }
++  close(FILE);
++  return;
++}
++
++sub DisplayAlerts {
++  my($supp);
++  
++  $DATA{'ALERTS'} = <<_end;
++<table border="0" cellspacing="0" cellpadding="2">
++	<tr>
++		<th>Alert Name</th>
++		<th>&nbsp;</th>
++	</tr>
++_end
++
++  my($rowclass);
++  $rowclass = "rowEven";
++
++  do {
++    my($line) = 0;
++    open(FILE, "<$USER.alerts");
++    while(<FILE>) {
++      s/</&lt;/g;
++      s/>/&gt;/g;
++      $DATA{'ALERTS'} .= qq!<tr><td class="$rowclass">$_</td><td class="$rowclass">[<a href="$CONFIG{'ME'}?command=deleteAlert&user=$FORM{'user'}&template=alerts&line=$line">Remove</a>]</td></tr>\n!;
++      $line++;
++
++      if ($rowclass eq "rowEven") {
++	$rowclass = "rowOdd";
++      } else {
++	$rowclass = "rowEven";
++      }
++    }
++  }; 
++
++$DATA{'ALERTS'} .= <<_end;
++</table>
++_end
++
++  &output(%DATA);
++  exit;
++}
++
++#
++# Global Functions
++#
++
++sub redirect {
++  my($loc) = @_;
++  print "Expires: now\n";
++  print "Pragma: no-cache\n";
++  print "Cache-control: no-cache\n";
++  print "Location: $loc\n\n";
++  exit(0);
++  }
++
++sub output {
++  if ($FORM{'template'} eq "" || $FORM{'template'} !~ /^([A-Z0-9]*)$/i) {
++    $FORM{'template'} = "performance";
++  }
++  print "Expires: now\n";
++  print "Pragma: no-cache\n";
++  print "Cache-control: no-cache\n";
++  print "Content-type: text/html\n\n";
++  my(%DATA) = @_;
++  $DATA{'WEB_ROOT'} = $CONFIG{'WEB_ROOT'};
++
++  # Check admin permissions
++  do {
++    if ($CONFIG{'ADMIN'} == 1) {
++      $DATA{'NAV_ADMIN'} = qq!<li><a href="admin.cgi">Administrative Suite</a></li>!;
++      $DATA{'FORM_USER'} = qq!<form action="$CONFIG{'ME'}"><input type=hidden name="template" value="$FORM{'template'}">Statistical SPAM Protection for <INPUT TYPE=TEXT NAME=user SIZE=16 value="$CURRENT_USER"> <input type=submit value="Change"></form>!;
++    } else {
++      $DATA{'NAV_ADMIN'} = '';
++      $DATA{'FORM_USER'} = "Statistical SPAM Protection for <strong>$CURRENT_USER</strong>";
++    }
++  };
++
++  open(FILE, "<$CONFIG{'TEMPLATES'}/nav_$FORM{'template'}.html");
++  while(<FILE>) { 
++    s/\$CGI\$/$CONFIG{'ME'}/g;
++    if ($CONFIG{'ADMIN'} == 1 && $FORM{'user'}) {
++      s/\$USER\$/user=$FORM{'user'}&/g;
++    } else {
++      s/\$USER\$//g;
++    }
++    s/\$([A-Z0-9_]*)\$/$DATA{$1}/g; 
++    print;
++  }
++  close(FILE);
++  exit(0);
++}
++
++sub SafeVars {
++  my(%PAIRS) = @_;
++  my($url, $key);
++  foreach $key (keys(%PAIRS)) {
++    my($value) = $PAIRS{$key};
++    $value =~ s/([^A-Z0-9])/sprintf("%%%x", ord($1))/gie;
++    $url .= "$key=$value&";
++  }
++  $url =~ s/\&$//;
++  return $url;
++}
++
++sub error {
++  my($error) = @_;
++  $FORM{'template'} = "error";
++  $DATA{'MESSAGE'} = <<_end;
++The following error occured while trying to process your request: <BR>
++<B>$error</B><BR>
++<BR>
++If this problem persists, please contact your administrator.
++_end
++  &output(%DATA);
++  exit;
++}
++
++sub ReadParse {
++  my(@pairs, %FORM);
++  if ($ENV{'REQUEST_METHOD'} =~ /GET/i)
++    { @pairs = split(/&/, $ENV{'QUERY_STRING'}); }
++  else {
++    my($buffer);
++    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
++    @pairs = split(/\&/, $buffer);
++  }
++  foreach(@pairs) {
++    my($name, $value) = split(/\=/, $_);
++
++    $name =~ tr/+/ /;
++    $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
++    $value =~ tr/+/ /;
++    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
++    $value =~ s/<!--(.|\n)*-->//g;
++
++    if ($name =~ /^msgid[\d]+$/) {
++	push(@{ $FORM{retrain_checked} }, $value);
++    } else {
++	$FORM{$name} = $value;
++    }
++  }
++  return %FORM;
++}
++
++sub CheckQuarantine {
++  my($f)=0;
++  open(FILE, "<$MAILBOX");
++  while(<FILE>) {
++    next unless (/^From /);
++    $f++;
++  }
++  close(FILE);   
++  if ($f == 0) {
++    $f = "Empty";
++  }
++
++  $DATA{'TOTAL_QUARANTINED_MESSAGES'} = $f;
++}
++
++sub To12Hour {
++  my($h) = @_;
++  if ($h < 0) { $h += 24; }
++  if ($h>11) { $h -= 12 if ($h>12) ; $h .= "p"; }
++  else { $h = "12" if ($h == 0); $h .= "a"; }
++  return $h;
++}
++
++sub GetPath {
++  my($USER) = @_;
++  my($PATH);
++
++  # Domain-scale
++  if ($CONFIG{'DOMAIN_SCALE'} == 1) {
++    my($VPOPUSERNAME, $VPOPDOMAIN);
++
++    $VPOPUSERNAME = (split(/@/, $USER))[0];
++    $VPOPDOMAIN = (split(/@/, $USER))[1];
++    $VPOPDOMAIN = "local" if ($VPOPDOMAIN eq "");
++
++    $PATH = "$CONFIG{'DSPAM_HOME'}/data/$VPOPDOMAIN/$VPOPUSERNAME/" .
++            "$VPOPUSERNAME";
++    return $PATH;
++
++  # Normal scale
++  } elsif ($CONFIG{'LARGE_SCALE'} == 0) {
++    $PATH = "$CONFIG{'DSPAM_HOME'}/data/$USER/$USER";
++    return $PATH;
++                                                                                
++  # Large-scale
++  } else {
++    if (length($USER)>1) {
++      $PATH = "$CONFIG{'DSPAM_HOME'}/data/" . substr($USER, 0, 1) .
++        "/". substr($USER, 1, 1) . "/$USER/$USER";
++    } else {
++      $PATH = "$CONFIG{'DSPAM_HOME'}/data/$USER/$USER";
++    }
++    return $PATH;
++  }
++
++  &error("Unable to determine filesystem scale");
++}
++
++
++sub GetPrefs {
++  my(%PREFS);
++
++  my($FILE) = "$USER.prefs";
++  my($DEFAULT_PREFS) = "/etc/dspam/default.prefs";
++
++  if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
++    open(PIPE, "$CONFIG{'DSPAM_BIN'}/dspam_admin agg pref " . quotemeta($CURRENT_USER) . "|");
++    while(<PIPE>) {
++      chomp;
++      my($directive, $value) = split(/\=/);
++      $PREFS{$directive} = $value;
++    }
++    close(PIPE);
++  }
++
++  if (keys(%PREFS) eq "0" || $CONFIG{'PREFERENCES_EXTENSION'} != 1) {
++
++    if (! -e "$DEFAULT_PREFS") {
++      &error("Unable to load default preferences");
++    }
++    open(FILE, "<$DEFAULT_PREFS");
++    while(<FILE>) {
++      chomp;
++      my($directive, $value) = split(/\=/);
++      $PREFS{$directive} = $value;
++    }
++    close(FILE);
++
++    if( -e $FILE) {
++      open(FILE, "<$FILE");
++      while(<FILE>) {
++	chomp;
++	my($directive, $value) = split(/\=/);
++	$PREFS{$directive} = $value;
++      }
++      close(FILE);
++    }
++  }
++  return %PREFS
++}
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/graph.cgi dspam-3.9.0~beta2/webui/cgi-bin/graph.cgi
+--- dspam-3.9.0~beta2~/webui/cgi-bin/graph.cgi	2009-08-12 10:08:27.252734844 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/graph.cgi	2009-08-12 10:08:27.496733524 +0200
+@@ -22,10 +22,15 @@
+ use GD::Graph::lines3d;
+ use GD::Graph::lines;
+ use strict;
+-use vars qw { %CONFIG %FORM @spam_day @nonspam_day @period @data };
++use vars qw { %CONFIG %FORM %LANG @spam_day @nonspam_day @period @data };
+ 
+ # Read configuration parameters common to all CGI scripts
+ require "/etc/dspam/webfrontend.conf";
++if (-s "$CONFIG{'TEMPLATES'}/strings.txt") {
++        require "$CONFIG{'TEMPLATES'}/strings.txt";
++} else {
++        require "$CONFIG{'TEMPLATES'}/../strings.txt";
++}
+ 
+ %FORM = &ReadParse();
+ 
+@@ -47,7 +52,7 @@
+ }
+ $mygraph->set(
+     x_label     => "$FORM{'x_label'}",
+-    y_label     => 'Number of Messages',
++    y_label     => $LANG{'graph_legend_nb_messages'},
+ #   title       => "$FORM{'title'}",
+     line_width   => 2,
+     dclrs => [ qw(lred dgreen) ],
+@@ -64,7 +69,7 @@
+ #         dclrs => [ qw( darkorchid2 mediumvioletred deeppink darkturquoise ) ],
+ 
+ $mygraph->set_legend_font(GD::gdMediumBoldFont);
+-$mygraph->set_legend('SPAM', 'Good');
++$mygraph->set_legend(" $LANG{'graph_legend_spam'}", " $LANG{'graph_legend_good'}");
+ my $myimage = $mygraph->plot(\@data) or die $mygraph->error;
+                                                                                 
+ print "Content-type: image/png\n\n";
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/strings.txt dspam-3.9.0~beta2/webui/cgi-bin/templates/strings.txt
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/strings.txt	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/strings.txt	2009-08-12 10:08:21.284764058 +0200
+@@ -0,0 +1,67 @@
++#!/usr/bin/perl
++
++$LANG{'empty'}				= "Empty";
++$LANG{'admin_suite'}			= "Administrative Suite";
++$LANG{'alert_name'}			= "Alert Name";
++$LANG{'remove_alert'}			= "Remove";
++$LANG{'user_form'}                      = "Statistical SPAM Protection for";
++$LANG{'user_form_submit'}               = "Change";
++
++$LANG{'option_disable_filtering'}	= "Disable DSPAM filtering";
++$LANG{'option_enable_filtering'}	= "Enable DSPAM filtering";
++
++$LANG{'quarantine_rating'}   		= "Rating";
++$LANG{'quarantine_date'}       		= "Date";
++$LANG{'quarantine_from'}      		= "From";
++$LANG{'quarantine_subject'}   		= "Subject";
++
++$LANG{'history_show'}                   = "Afficher&nbsp;";
++$LANG{'history_show_all'}               = "tous";
++$LANG{'history_show_spam'}              = "spam";
++$LANG{'history_show_innocent'}          = "innocent";
++$LANG{'history_show_virus'}             = "virus";
++$LANG{'history_show_whitelisted'}       = "whitelisted";
++$LANG{'history_retrain_as_spam'}        = "spam";
++$LANG{'history_retrain_as_innocent'}    = "innocent";
++$LANG{'history_retrain_as'}             = "As ";
++$LANG{'history_retrain_undo'}           = "Undo";
++$LANG{'history_retrained'}              = "Retrained";
++$LANG{'history_label_resend'}           = "Resend";
++$LANG{'history_label_whitelist'}        = "Whitelist";
++$LANG{'history_label_spam'}             = "SPAM";
++$LANG{'history_label_innocent'}		= "Good";
++$LANG{'history_label_miss'}             = "Miss";
++$LANG{'history_label_virus'}            = "Virus";
++$LANG{'history_label_RBL'}              = "RBL";
++$LANG{'history_label_block'}            = "BLOCK";
++$LANG{'history_label_corpus'}           = "Corpus";
++$LANG{'history_label_unknown'}          = "UNKN";
++$LANG{'history_label_error'}            = "Error";
++
++$LANG{'error_no_historic'}              = "No historical data is available.";
++$LANG{'error_cannot_open_log'}          = "Unable to open logfile";
++$LANG{'error_no_identity'}              = "System Error. I was unable to determine your identity.";
++$LANG{'error_invalid_command'}          = "Invalid Command";
++$LANG{'error_cannot_write_prefs'}       = "Unable to write preferences";
++$LANG{'error_no_sigid'}                 = "No Message ID Specified";
++$LANG{'error_no_alert_specified'}       = "No Alert Specified.";
++$LANG{'error_message_part1'}            = "The following error occured while trying to process your request:";
++$LANG{'error_message_part2'}            = "If this problem persists, please contact your administrator.";
++$LANG{'error_filesystem_scale'}         = "Unable to determine filesystem scale";
++$LANG{'error_load_default_prefs'}       = "Unable to load default preferences";
++$LANG{'error_access_denied'}            = "Access Denied";
++
++$LANG{'graph_legend_nb_messages'}       = "Number of Messages";
++$LANG{'graph_legend_spam'}              = "SPAM";
++$LANG{'graph_legend_good'}              = "Good";
++$LANG{'graph_legend_inoculations'}      = "Inoculations";
++$LANG{'graph_legend_corpusfeds'}        = "Corpusfeds";
++$LANG{'graph_legend_virus'}             = "Virus";
++$LANG{'graph_legend_RBL'}               = "Blacklisted (RBL)";
++$LANG{'graph_legend_blocklisted'}       = "Blocklisted";
++$LANG{'graph_legend_whitelisted'}       = "Auto-Whitelisted";
++$LANG{'graph_legend_nonspam'}           = "Nonspam";
++$LANG{'graph_legend_spam_misses'}       = "Spam Misses";
++$LANG{'graph_legend_falsepositives'}    = "False Positives";
++
++1;

Modified: branches/experimental/debian/patches/drivers-in-usr_lib_dspam.dpatch
==============================================================================
--- branches/experimental/debian/patches/drivers-in-usr_lib_dspam.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/drivers-in-usr_lib_dspam.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -2,7 +2,7 @@
 ## drivers-in-usr_lib_dspam.dpatch by Julien Valroff <julien at kirya.net>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
+## DP: Default hash storage driver is installed in /usr/lib/dspam
 
 @DPATCH@
 diff -urNad dspam-3.9.0~git20090606~/src/dspam.conf.in dspam-3.9.0~git20090606/src/dspam.conf.in

Modified: branches/experimental/debian/patches/dspam-default.prefs-in_etc.dpatch
==============================================================================
--- branches/experimental/debian/patches/dspam-default.prefs-in_etc.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/dspam-default.prefs-in_etc.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -2,7 +2,7 @@
 ## dspam-default.prefs-in_etc.dpatch by Julien Valroff <julien at kirya.net>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
+## DP: default.prefs file is installed in /etc/dspam
 
 @DPATCH@
 diff -urNad dspam-3.9.0~git+alpha2+git20090627~/src/pref.c dspam-3.9.0~git+alpha2+git20090627/src/pref.c

Modified: branches/experimental/debian/patches/dspam-webfrontend-config-debian.dpatch
==============================================================================
--- branches/experimental/debian/patches/dspam-webfrontend-config-debian.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/dspam-webfrontend-config-debian.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -2,12 +2,12 @@
 ## dspam-webfrontend-config-debian.dpatch by Julien Valroff <julien at kirya.net>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
+## DP: Debian configuration for the WebUI
 
 @DPATCH@
-diff -urNad dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/admin.cgi dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/admin.cgi
---- dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/admin.cgi	2009-06-27 12:13:57.000000000 +0200
-+++ dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/admin.cgi	2009-07-19 18:09:29.000000000 +0200
+diff -urNad dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/admin.cgi dspam-3.9.0~beta1+git20090802/webui/cgi-bin/admin.cgi
+--- dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/admin.cgi	2009-07-21 18:31:31.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/webui/cgi-bin/admin.cgi	2009-08-02 15:45:34.000000000 +0200
 @@ -24,7 +24,7 @@
  require "ctime.pl";
  
@@ -48,7 +48,7 @@
    } else {
      %PREFS = GetPrefs($USER, $FILE);
    }
-@@ -730,7 +730,7 @@
+@@ -821,7 +821,7 @@
      close(PIPE);
    } else {
      if (! -e $FILE) {
@@ -57,11 +57,11 @@
      }
                                                                                  
      if (! -e $FILE) {
-diff -urNad dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/admingraph.cgi dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/admingraph.cgi
---- dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/admingraph.cgi	2009-06-27 12:13:57.000000000 +0200
-+++ dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/admingraph.cgi	2009-07-19 18:09:29.000000000 +0200
+diff -urNad dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/admingraph.cgi dspam-3.9.0~beta1+git20090802/webui/cgi-bin/admingraph.cgi
+--- dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/admingraph.cgi	2009-07-20 18:25:15.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/webui/cgi-bin/admingraph.cgi	2009-08-02 15:45:34.000000000 +0200
 @@ -24,11 +24,11 @@
- use vars qw { %CONFIG %FORM @spam @nonspam @period @data @inoc @sm @fp @wh };
+ use vars qw { %CONFIG %FORM @spam @nonspam @period @data @inoc @sm @fp @wh @corpus @virus @black @block };
  
  # Read configuration parameters common to all CGI scripts
 -require "configure.pl";
@@ -70,13 +70,13 @@
  %FORM = &ReadParse();
  
 -GD::Graph::colour::read_rgb("rgb.txt"); 
-+GD::Graph::colour::read_rgb("/etc/dspam/htdocs/rgb.txt"); 
++GD::Graph::colour::read_rgb("/etc/dspam/rgb.txt"); 
  
  do {
-   my($spam, $nonspam, $sm, $fp, $inoc, $wh, $period) = split(/\_/, $FORM{'data'});
-diff -urNad dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/configure.pl.in dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/configure.pl.in
---- dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/configure.pl.in	2009-07-19 18:09:17.000000000 +0200
-+++ dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/configure.pl.in	2009-07-19 18:09:29.000000000 +0200
+   my($spam, $nonspam, $sm, $fp, $inoc, $wh, $corpus, $virus, $black, $block, $period) = split(/\_/, $FORM{'data'});
+diff -urNad dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/configure.pl.in dspam-3.9.0~beta1+git20090802/webui/cgi-bin/configure.pl.in
+--- dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/configure.pl.in	2009-07-20 18:25:15.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/webui/cgi-bin/configure.pl.in	2009-08-02 15:45:34.000000000 +0200
 @@ -29,11 +29,11 @@
  $CONFIG{'DSPAM_STATS'}	= $CONFIG{'DSPAM_BIN'} . "/dspam_stats";
  $CONFIG{'DSPAM_ARGS'}	= "--deliver=innocent --class=innocent " .
@@ -87,32 +87,34 @@
  $CONFIG{'MAIL_QUEUE'}   = "mailq | grep '^[0-9,A-F]\{10,12\}[\t ][\t ]*[1-9]' | wc -l";
  
 -$CONFIG{'WEB_ROOT'}     = ""; # URL location of included htdocs/ files
-+$CONFIG{'WEB_ROOT'}     = "/etc/dspam"; # URL location of included htdocs/ files
++$CONFIG{'WEB_ROOT'}     = "/usr/share/dspam/"; # URL location of included htdocs/ files
  
  # Default DSPAM display
  #$CONFIG{'DATE_FORMAT'}  = "%d.%m.%Y %H:%M"; # Date format in strftime style
-@@ -53,14 +53,14 @@
- $ENV{'PATH'} = "$ENV{'PATH'}:$CONFIG{'DSPAM_BIN'}";
- 
- # Autodetect filesystem layout and preference options
--$CONFIG{'AUTODETECT'} = 1;
-+$CONFIG{'AUTODETECT'} = 0;
+@@ -44,8 +44,7 @@
+ $CONFIG{'MAX_COL_LEN'}	= 50;		# Max chars in list columns
+ $CONFIG{'SORT_DEFAULT'}	= "Rating";	# Show quarantine by "Date" or "Rating"
+ $CONFIG{'3D_GRAPHS'}	= 1;
+-$CONFIG{'OPTMODE'}	= "NONE";	# OUT=OptOut IN=OptIn NONE=not selectable
+-$CONFIG{'LOCAL_DOMAIN'}	= "localhost";
++$CONFIG{'OPTMODE'}	= "IN";	# OUT=OptOut IN=OptIn NONE=not selectable
+ 
+ # Add customized settings below
+ $CONFIG{'LOCAL_DOMAIN'}	= "yourdomain.com";
+@@ -57,9 +56,8 @@
  
  # Or, if you're running dspam.cgi as untrusted, it won't be able to auto-detect
  # so you will need to specify some features manually:
 -#$CONFIG{'AUTODETECT'} = 0;
-+$CONFIG{'AUTODETECT'} = 0;
  #$CONFIG{'LARGE_SCALE'} = 0;
 -#$CONFIG{'DOMAIN_SCALE'} = 0;
--#$CONFIG{'PREFERENCES_EXTENSION'} = 0;
-+$CONFIG{'DOMAIN_SCALE'} = 1;
-+$CONFIG{'PREFERENCES_EXTENSION'} = 0;
++#$CONFIG{'DOMAIN_SCALE'} = 1;
+ #$CONFIG{'PREFERENCES_EXTENSION'} = 0;
  
  # Get DSPAM version
- $CONFIG{'DSPAM_VERSION'} = "Unknown Version";
-diff -urNad dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/dspam.cgi dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/dspam.cgi
---- dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/dspam.cgi	2009-06-27 14:11:57.000000000 +0200
-+++ dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/dspam.cgi	2009-07-19 18:09:29.000000000 +0200
+diff -urNad dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/dspam.cgi dspam-3.9.0~beta1+git20090802/webui/cgi-bin/dspam.cgi
+--- dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/dspam.cgi	2009-07-26 14:15:17.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/webui/cgi-bin/dspam.cgi	2009-08-02 15:45:34.000000000 +0200
 @@ -25,7 +25,7 @@
  require "ctime.pl";
  
@@ -131,7 +133,7 @@
    while(<FILE>) {
      chomp;
      if ($_ eq $ENV{'REMOTE_USER'}) {
-@@ -611,7 +611,7 @@
+@@ -626,7 +626,7 @@
  
  sub DisplayPreferences {
    my(%PREFS);
@@ -140,7 +142,7 @@
  
    my $username = $CURRENT_USER;
  
-@@ -1628,6 +1628,7 @@
+@@ -1643,6 +1643,7 @@
    my(%PREFS);
  
    my($FILE) = "$USER.prefs";
@@ -148,7 +150,7 @@
  
    if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
      open(PIPE, "$CONFIG{'DSPAM_BIN'}/dspam_admin agg pref " . quotemeta($CURRENT_USER) . "|");
-@@ -1641,10 +1642,10 @@
+@@ -1656,10 +1657,10 @@
  
    if (keys(%PREFS) eq "0" || $CONFIG{'PREFERENCES_EXTENSION'} != 1) {
  
@@ -161,9 +163,9 @@
      while(<FILE>) {
        chomp;
        my($directive, $value) = split(/\=/);
-diff -urNad dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/graph.cgi dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/graph.cgi
---- dspam-3.9.0~git+alpha2+git20090714~/webui/cgi-bin/graph.cgi	2009-06-27 12:13:57.000000000 +0200
-+++ dspam-3.9.0~git+alpha2+git20090714/webui/cgi-bin/graph.cgi	2009-07-19 18:09:29.000000000 +0200
+diff -urNad dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/graph.cgi dspam-3.9.0~beta1+git20090802/webui/cgi-bin/graph.cgi
+--- dspam-3.9.0~beta1+git20090802~/webui/cgi-bin/graph.cgi	2009-07-20 18:25:15.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/webui/cgi-bin/graph.cgi	2009-08-02 15:45:34.000000000 +0200
 @@ -25,11 +25,11 @@
  use vars qw { %CONFIG %FORM @spam_day @nonspam_day @period @data };
  
@@ -174,7 +176,7 @@
  %FORM = &ReadParse();
  
 -GD::Graph::colour::read_rgb("rgb.txt"); 
-+GD::Graph::colour::read_rgb("/etc/dspam/htdocs/rgb.txt"); 
++GD::Graph::colour::read_rgb("/etc/dspam/rgb.txt"); 
  
  do {
    my($spam, $nonspam, $period) = split(/\_/, $FORM{'data'});

Modified: branches/experimental/debian/patches/dspam_notify.dpatch
==============================================================================
--- branches/experimental/debian/patches/dspam_notify.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/dspam_notify.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -5,9 +5,9 @@
 ## DP: No description.
 
 @DPATCH@
-diff -urNad dspam-3.9.0~alpha2+git20090720~/src/tools/Makefile.am dspam-3.9.0~alpha2+git20090720/src/tools/Makefile.am
---- dspam-3.9.0~alpha2+git20090720~/src/tools/Makefile.am	2009-06-27 12:13:57.000000000 +0200
-+++ dspam-3.9.0~alpha2+git20090720/src/tools/Makefile.am	2009-07-20 21:12:59.000000000 +0200
+diff -urNad dspam-3.9.0~beta1+git20090802~/src/tools/Makefile.am dspam-3.9.0~beta1+git20090802/src/tools/Makefile.am
+--- dspam-3.9.0~beta1+git20090802~/src/tools/Makefile.am	2009-06-27 12:13:57.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/src/tools/Makefile.am	2009-08-02 15:53:55.000000000 +0200
 @@ -1,8 +1,8 @@
  # $Id: Makefile.am,v 1.8 2007/12/07 00:15:36 mjohnson Exp $
  # tools/Makefile.am
@@ -35,9 +35,9 @@
 +
 +dspam_notify: dspam_notify.pl
 +	cp dspam_notify.pl dspam_notify
-diff -urNad dspam-3.9.0~alpha2+git20090720~/src/tools/dspam_notify.pl dspam-3.9.0~alpha2+git20090720/src/tools/dspam_notify.pl
---- dspam-3.9.0~alpha2+git20090720~/src/tools/dspam_notify.pl	2009-07-20 18:25:15.000000000 +0200
-+++ dspam-3.9.0~alpha2+git20090720/src/tools/dspam_notify.pl	2009-07-20 21:12:59.000000000 +0200
+diff -urNad dspam-3.9.0~beta1+git20090802~/src/tools/dspam_notify.pl dspam-3.9.0~beta1+git20090802/src/tools/dspam_notify.pl
+--- dspam-3.9.0~beta1+git20090802~/src/tools/dspam_notify.pl	2009-07-20 18:25:15.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/src/tools/dspam_notify.pl	2009-08-02 15:54:14.000000000 +0200
 @@ -2,28 +2,7 @@
  
  use Net::SMTP;
@@ -64,7 +64,7 @@
 -# No need to config below this point.#
 -######################################
 -
-+require "/etc/dspam/dspam_notify.conf"
++require "/etc/dspam/dspam_notify.conf";
  
  #Build the Quarantine URL
  $QUARANTINE_URL = $DSPAM_URL . '/dspam.cgi?template=quarantine';

Modified: branches/experimental/debian/patches/path-to-dspam_for-training-script.dpatch
==============================================================================
--- branches/experimental/debian/patches/path-to-dspam_for-training-script.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/path-to-dspam_for-training-script.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -2,7 +2,7 @@
 ## path-to-dspam_for-training-script.dpatch by Julien Valroff <julien at kirya.net>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
+## DP: Fix path to dspam binary
 
 @DPATCH@
 diff -urNad dspam-3.9.0~git+alpha2+git20090714~/scripts/train.pl dspam-3.9.0~git+alpha2+git20090714/scripts/train.pl

Added: branches/experimental/debian/patches/remove-daily-quarantine-pref-from-webui.dpatch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/experimental/debian/patches/remove-daily-quarantine-pref-from-webui.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -0,0 +1,165 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## remove-daily-quarantine-pref-from-webui.dpatch by Julien Valroff <julien at kirya.net>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: dspam_notify script is not installed by default, hence removes possibility
+## DP: to use the dailyQuarantineSummary preference
+
+ at DPATCH@
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/admin.cgi dspam-3.9.0~beta2/webui/cgi-bin/admin.cgi
+--- dspam-3.9.0~beta2~/webui/cgi-bin/admin.cgi	2009-08-11 07:07:24.390855168 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/admin.cgi	2009-08-11 07:10:35.033286525 +0200
+@@ -161,9 +161,6 @@
+     if ($FORM{'showFactors'} ne "on") {
+       $FORM{'showFactors'} = "off";
+     }
+-    if ($FORM{'dailyQuarantineSummary'} ne "on") {
+-      $FORM{'dailyQuarantineSummary'} = "off";
+-    }
+ 
+     if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
+ 
+@@ -200,10 +197,6 @@
+       system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
+         "' enableWhitelist "
+         . quotemeta($FORM{'enableWhitelist'}) . "> /dev/null");
+-      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref '".quotemeta($USER).
+-        "' dailyQuarantineSummary "
+-        . quotemeta($FORM{'dailyQuarantineSummary'}) . "> /dev/null");
+-
+     } else {
+       open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
+       print FILE <<_END;
+@@ -215,7 +208,6 @@
+ enableWhitelist=$FORM{'enableWhitelist'}
+ signatureLocation=$FORM{'signatureLocation'}
+ showFactors=$FORM{'showFactors'}
+-dailyQuarantineSummary=$FORM{'dailyQuarantineSummary'}
+ _END
+       close(FILE);
+     }
+@@ -248,10 +240,6 @@
+   if ($PREFS{"enableWhitelist"} eq "on") {
+     $DATA{"C_WHITELIST"} = "CHECKED";
+   }
+-  if ($PREFS{"dailyQuarantineSummary"} eq "on") {
+-    $DATA{"C_SUMMARY"} = "CHECKED";
+-  }
+-
+ 
+   &output(%DATA);
+ }
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/dspam.cgi dspam-3.9.0~beta2/webui/cgi-bin/dspam.cgi
+--- dspam-3.9.0~beta2~/webui/cgi-bin/dspam.cgi	2009-08-11 07:07:24.374854638 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/dspam.cgi	2009-08-11 07:10:13.042855481 +0200
+@@ -651,9 +651,6 @@
+     if ($FORM{'enableWhitelist'} ne "on") {
+       $FORM{'enableWhitelist'} = "off";
+     }
+-    if ($FORM{'dailyQuarantineSummary'} ne "on") {
+-      $FORM{'dailyQuarantineSummary'} = "off";
+-    }
+ 
+     if ($CONFIG{'PREFERENCES_EXTENSION'} == 1) {
+ 
+@@ -690,10 +687,6 @@
+       system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
+         " enableWhitelist "
+         . quotemeta($FORM{'enableWhitelist'}) . "> /dev/null");
+-      system("$CONFIG{'DSPAM_BIN'}/dspam_admin ch pref ".quotemeta($CURRENT_USER).
+-        " dailyQuarantineSummary "
+-        . quotemeta($FORM{'dailyQuarantineSummary'}) . "> /dev/null");
+-
+ 
+     } else {
+       open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
+@@ -708,7 +701,6 @@
+ showFactors=$FORM{'showFactors'}
+ enableWhitelist=$FORM{'enableWhitelist'}
+ signatureLocation=$FORM{'signatureLocation'}
+-dailyQuarantineSummary=$FORM{'dailyQuarantineSummary'}
+ _END
+       close(FILE);
+     }
+@@ -737,9 +729,6 @@
+   if ($PREFS{"enableWhitelist"} eq "on") {
+     $DATA{"C_WHITELIST"} = "CHECKED";
+   }
+-  if ($PREFS{"dailyQuarantineSummary"} eq "on") {
+-    $DATA{"C_SUMMARY"} = "CHECKED";
+-  }
+ 
+   if ($CONFIG{'OPTMODE'} eq "OUT") {
+     $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optOut " . $DATA{'C_OPTOUT'} . ">Disable DSPAM filtering<br>";
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/he/nav_admin_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/he/nav_admin_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/he/nav_admin_preferences.html	2009-08-06 16:48:58.000000000 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/he/nav_admin_preferences.html	2009-08-11 07:08:54.948876808 +0200
+@@ -108,8 +108,6 @@
+ àôùø àéùåø àåèåîèé ùì îëåúáéí úëåôéí<BR>
+ <INPUT TYPE="CHECKBOX" NAME="showFactors" $C_FACTORS$>
+ äåñó àú ëì îàôééðé äñéðåï áëì äåãòä ìëåúøåú äîìàåú ùì ääåãòä<BR>
+-<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
+-<label for="dailyQuarantineSummary">àôùø ùìéçä éåîéú ùì úëåìú ääñâø</label>
+ </p>
+ 
+ </div>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/he/nav_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/he/nav_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/he/nav_preferences.html	2009-08-06 16:48:58.000000000 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/he/nav_preferences.html	2009-08-11 07:09:12.612272740 +0200
+@@ -102,8 +102,6 @@
+ àôùø çéñåï àåèåîèé ùì îëåúáéí úëåôéí<BR>
+ <INPUT TYPE="CHECKBOX" NAME="showFactors" $C_FACTORS$>
+ äåñó àú îàôééðé äñéðåï ùì ëì äåãòä ìëåúøåú ääåãòä<BR>
+-<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
+-<label for="dailyQuarantineSummary">àôùø ùìéçä éåîéú ùì úëåìú ääñâø</label>
+ </p>
+ 
+ </div>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/nav_admin_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/nav_admin_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/nav_admin_preferences.html	2009-08-06 16:48:58.000000000 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/nav_admin_preferences.html	2009-08-11 07:08:21.469986703 +0200
+@@ -106,8 +106,6 @@
+ Enable automatic whitelisting to record frequent correspondence<br>
+ <INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
+ Add the factoring tokens in each email into the message's full headers<br>
+-<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
+-<label for="dailyQuarantineSummary">Enable the sending of daily spam quarantine summary emails</label>
+ </p>
+ 
+ </div>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/nav_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/nav_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/nav_preferences.html	2009-08-06 16:48:58.000000000 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/nav_preferences.html	2009-08-11 07:08:02.742853716 +0200
+@@ -100,8 +100,6 @@
+ Enable automatic whitelisting to record frequent correspondence<BR>
+ <INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
+ Add the factoring tokens in each email into the message's full headers<br>
+-<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
+-<label for="dailyQuarantineSummary">Enable the sending of daily spam quarantine summary emails</label>
+ </p>
+ 
+ </div>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/ro/nav_admin_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/ro/nav_admin_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/ro/nav_admin_preferences.html	2009-08-06 16:48:58.000000000 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/ro/nav_admin_preferences.html	2009-08-11 07:09:20.340004208 +0200
+@@ -107,8 +107,6 @@
+ Activează adăugarea automată la lista albă a corespondenții frecvenți<br>
+ <INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
+ Adaugă factoring tokens in antetul (header) fiecărui mesaj<br>
+-<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
+-<label for="dailyQuarantineSummary">Activează trimiterea zilnică a unui sumar al mesajelor aflate in Carantină</label>
+ </p>
+ 
+ </div>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/ro/nav_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/ro/nav_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/ro/nav_preferences.html	2009-08-06 16:48:58.000000000 +0200
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/ro/nav_preferences.html	2009-08-11 07:09:25.458853100 +0200
+@@ -100,8 +100,6 @@
+ Activează automatic whitelisting pentru înregistrarea corespondeinților frecvenți<BR>
+ <INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
+ Add the factoring tokens din fiecare mail in antetele (headers) emailului<br>
+-<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
+-<label for="dailyQuarantineSummary">Activează trimiterea zilnică a unui sumar al emailului aflat în carantină</label>
+ </p>
+ 
+ </div>

Added: branches/experimental/debian/patches/templates_fr.dpatch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/experimental/debian/patches/templates_fr.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -0,0 +1,1116 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## templates_fr.dpatch by Julien Valroff <julien at kirya.net>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: French translation for WebUI
+
+ at DPATCH@
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_error.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_error.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_error.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_error.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,37 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Administrative Suite</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++		Centre de contr&ocirc;le DSPAM pour <strong>Administrateur ($REMOTE_USER$)</strong>
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=status">&Eacute;tat du syst&egrave;me</a></li>
++                <li><a href="$CGI$?$USER$template=user">Statistiques utilisateurs</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Administration</a></li>
++                <li><a href="dspam.cgi">Centre de contr&ocirc;le</a></li>
++	</ul>
++</div>
++
++<div id="panel">
++
++<H2>Une erreur s'est produite</H2>
++$MESSAGE$
++
++</div>
++
++
++
++</body>
++</html>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_preferences.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_preferences.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,129 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Administrative Suite</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++		Centre de contr&ocirc;le DSPAM pour <strong>Administrateur ($REMOTE_USER$)</strong>
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=status">&Eacute;tat du syst&egrave;me</a></li>
++                <li><a href="$CGI$?$USER$template=user">Statistiques utilisateurs</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=preferences">Administration</a></li>
++                <li><a href="dspam.cgi">Centre de contr&ocirc;le</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<FORM ACTION="$CGI$">
++
++<p>
++Cette page vous permet d'&eacute;diter les pr&eacute;f&eacute;rences de n'importe quel utilisateur. Vous avez &eacute;galement la possibilit&eacute;
++d'&eacute;diter les pr&eacute;f&eacute;rences par d&eacute;faut de DSPAM en laissant le champ de saisie vide.
++</p>
++
++<p>
++Nom d'utilisateur&nbsp;:
++<INPUT NAME=username VALUE=$USERNAME$> <INPUT TYPE=SUBMIT VALUE=&Eacute;diter>
++</p>
++
++<p>
++$ERROR$
++</p>
++
++<INPUT TYPE=HIDDEN NAME="template" VALUE="preferences">
++
++<div class="content">
++        <h3><strong>Apprentissage</strong> - Configure la fa&ccedil;don dont le filtre apprend lors de l'analyse des messages</h3>
++<p>
++<table class="hollow">
++<tr><td>
++DSPAM doit apprendre&nbsp;:<br><br>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TEFT" $S_TEFT$>
++&Agrave; chaque message analys&eacute; par le filtre<BR>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TOE" $S_TOE$>
++Seulement lorsque le filtre commet une erreur<BR>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TUM" $S_TUM$>
++Seulement lors de nouvelles donn&eacute;es ou lorsque le filtre commet une erreur
++</td><td width=20>
++ &nbsp;</td><td>
++Lorsque j'entraine DSPAM, je pr&eacute;f&egrave;re&nbsp;:<br><br>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="message" $S_LOC_MESSAGE$>
++<u>transf&eacute;rer</u> les pourriels re&ccedil;us (la signature appera&icirc;t dans le corps du message)<BR>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="headers" $S_LOC_HEADERS$>
++transf&eacute;rer les pourriels re&ccedil;us en tant que <u>pi&egrave;ce jointe</u> (la signature appara&icirc;t dans les en-t&ecirc;tes du messages)<BR>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="attachment" $S_LOC_ATTACHMENT$>
++laisser DSPAM joindre sa signature en tant que <u>pi&egrave;ce jointe</u><BR>
++</td></tr>
++</table>
++</p>
++
++<p>
++Sensibilit&eacute; du filtre <stron>pendant</strong> la p&eacute;riode d'apprentissage&nbsp;:<br>
++<span class="small">Haute sensibilit&eacute (plus de pourriels seront plac&eacute; en quarantaine)</span>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=0 $SEDATION_0$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=1 $SEDATION_1$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=2 $SEDATION_2$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=3 $SEDATION_3$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=4 $SEDATION_4$>
++    | <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=5 $SEDATION_5$> |
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=6 $SEDATION_6$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=7 $SEDATION_7$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=8 $SEDATION_8$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=9 $SEDATION_9$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=10 $SEDATION_10$>
++<span class="small">Faible sensibilit&eacute; (plus de messages seront consid&eacute;r&eacute;s comme l&eacute;gitimes et moins seront plac&eacute;s en quarantaine)</span>
++</p>
++
++</div>
++
++<div class="content">
++        <h3><strong>Gestion des messages</strong> - Configure la fa&ccedil;on dont sont g&eacute;r&eacute;s les pourriels</h3>
++<p>
++Lorsqu'un pourriel est identifi&eacute;&nbsp;:<br><br>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="quarantine" $S_ACTION_QUARANTINE$>Mettre le message en quarantaine<BR>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="tag" $S_ACTION_TAG$>Ajouter l'&eacute;tiquette <INPUT NAME=spamSubject VALUE="$SPAM_SUBJECT$" SIZE=8> &agrave; l'objet du message<BR>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="deliver" $S_ACTION_DELIVER$>Distribuer le message normalement en ajoutant une en-t&ecirc;te X-DSPAM-Result<BR>
++</p>
++
++</div>
++
++<div class="content">
++        <h3><strong>Fonctionnalit&eacute;s</strong> - Ajustement du filtrage</h3>
++<p>
++<INPUT TYPE=CHECKBOX NAME=enableBNR $C_BNR$>
++Activer la r&eacute;duction du bruit, qui am&eacute;liore g&eacute;n&eacute;ralement les performances de filtrage<br>
++<INPUT TYPE=CHECKBOX NAME=enableWhitelist $C_WHITELIST$>
++Activer la mise en liste blanche automatique des correspondants r&eacute;guliers<BR>
++<INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
++Ajouter les jetons de factorisation dans les en-t&ecirc;tes des messages<br>
++<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
++<label for="dailyQuarantineSummary">Activer l'envoi automatique de r&eacute;sum&eacute; journalier de la zone de quarantaine</label>
++</p>
++
++</div>
++
++<p>
++<INPUT TYPE=SUBMIT NAME=submit VALUE="Valider les modifications">
++</p>
++
++</FORM>
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_status.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_status.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_status.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_status.html	2009-08-06 15:05:41.000000000 +0200
+@@ -0,0 +1,140 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Administrative Suite</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++                Centre de contr&ocirc;le DSPAM pour <strong>Administrateur ($REMOTE_USER$)</strong>
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++		<li id="active"><a id="current" href="$CGI$?$USER$template=status">&Eacute;tat du syst&egrave;me</a></li>
++		<li><a href="$CGI$?$USER$template=user">Statistiques utilisateurs</a></li>
++		<li><a href="$CGI$?$USER$template=preferences">Administration</a></li>
++		<li><a href="dspam.cgi">Centre de contr&ocirc;le</a></li>
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Les graphiques et les tableaux ci-dessous r&eacute;sument les analyses effectu&eacute;es par le filtre.
++</p>
++
++<div class="content">
++	<h3><strong>Vue d'ensemble</strong></h3>
++			
++	<table border="0" cellspacing="0" cellpadding="4">
++		<tr>
++			<th>Messages</th>
++			<th>Aujourd'hui</th>
++			<th>Cette heure</th>
++		</tr>
++		<tr class="rowEven">
++			<td>Pourriels</td>
++			<td>$SPAM_TODAY$</td>
++			<td>$SPAM_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>Lessages l&eacute;gitimes</td>
++			<td>$NONSPAM_TODAY$</td>
++			<td>$NONSPAM_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowEven">
++			<td>Pourriels manqu&eacute;s</td>
++			<td>$SM_TODAY$</td>
++			<td>$SM_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>Faux positifs</td>
++			<td>$FP_TODAY$</td>
++			<td>$FP_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowEven">
++			<td>Inoculations</td>
++			<td>$INOC_TODAY$</td>
++			<td>$INOC_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>Depuis le corpus</td>
++			<td>$CORPUS_TODAY$</td>
++			<td>$CORPUS_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowEven">
++			<td>Mis en liste blanche</td>
++			<td>$WHITE_TODAY$</td>
++			<td>$WHITE_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>Messages infect&eacute;s</td>
++			<td>$VIRUS_TODAY$</td>
++			<td>$VIRUS_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowEven">
++			<td>Mis en liste noire</td>
++			<td>$BLACK_TODAY$</td>
++			<td>$BLACK_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>RBL</td>
++			<td>$BLOCK_TODAY$</td>
++			<td>$BLOCK_THIS_HOUR$</td>
++		</tr>
++		<tr class="rowHighlight">
++			<td>Total</td>
++			<td>$TOTAL_TODAY$</td>
++			<td>$TOTAL_THIS_HOUR$</td>
++		</tr>
++	</table>
++
++	<table border="0" cellspacing="0" cellpadding="4">
++		<tr>
++			<th>&Eacute;tat</th>
++			<th>Valeur actuelle</th>
++		</tr>
++		<tr class="rowEven">
++			<td>Temps moyen d'analyse par message</td>
++			<td>$AVG_PROCESSING_TIME$ sec.</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>D&eacute;bit moyen</td>
++			<td>$AVG_MSG_PER_SECOND$ messages/sec.</td>
++		</tr>
++		<tr class="rowEven">
++			<td>Nombre d'instances DSPAM</td>
++			<td>$DSPAM_PROCESSES$ processus</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>Uptime syst&egrave;me</td>
++			<td>$UPTIME$</td>
++		</tr>
++		<tr class="rowEven">
++			<td>Taille de la file d'attente</td>
++			<td>$MAIL_QUEUE$ message(s)</td>
++		</tr>
++	</table>
++</div>
++
++<div class="content">
++	<h3><strong>Activit&eacute; sur 24 heures</strong> - $TS_DAILY$ pourriel(s), $TI_DAILY$ message(s) l&eacute;gitime(s), $SM_DAILY$ pourriel(s) manqu&eacute;(s), $FP_DAILY$ faux positif(s), $INOC_DAILY$ inoculation(s), $CORPUS_DAILY$ depuis le corpus, $WHITE_DAILY$ mis en liste de blanche, $VIRUS_DAILY$ infect&eacute;(s), $BLACK_DAILY$ mis en liste noire, $BLOCK_DAILY$ RBL</h3>
++	<img src="./admingraph.cgi?data=$DATA_DAILY$&x_label=Heure+du+jour" />
++</div>
++
++<div class="content">
++	<h3><strong>Activit&eacute; journali&egrave;re</strong> - $TS_DAILY$ pourriel(s), $TI_DAILY$ message(s) l&eacute;gitime(s), $SM_DAILY$ pourriel(s) manqu&eacute;(s), $FP_DAILY$ faux positif(s), $INOC_DAILY$ inoculation(s), $CORPUS_DAILY$ depuis le corpus, $WHITE_DAILY$ mis en liste de blanche, $VIRUS_DAILY$ infect&eacute;(s), $BLACK_DAILY$ mis en liste noire, $BLOCK_DAILY$ RBL</h3>
++        <img src="./admingraph.cgi?data=$DATA_WEEKLY$&x_label=Date" />
++</div>
++
++
++
++</body>
++</html>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_user.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_user.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_admin_user.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_admin_user.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,58 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Administrative Suite</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++                Centre de contr&ocirc;le DSPAM pour <strong>Administrateur ($REMOTE_USER$)</strong>
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=status">&Eacute;tat du syst&egrave;me</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=user">Statistiques utilisateurs</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Administration</a></li>
++                <li><a href="dspam.cgi">Centre de contr&ocirc;le</a></li>
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Le tableau ci-dessous montre le nombre de messages analys&eacute;s pour chaque utilisateur, ainsi que leurs pr&eacute;f&eacute;rences acutelles.
++</p>
++
++<table border="0" cellspacing="0" cellpadding="4">
++	<tr>
++		<th>Nom d'utilisateur</th>
++		<th>Taille quarantaine</th>
++		<th>TP</th>
++                <th>TN</th>
++		<th>FP</th>
++		<th>FN</th>
++		<th>SC</th>
++		<th>IC</th>
++		<th>Mode</th>
++		<th>On Spam</th>
++		<th>BNR</th>
++		<th>Whitelist</th>
++                <th>Sed</th>
++                <th>Sig Loc</th>
++	</tr>
++$TABLE$
++</table>
++
++</div>
++
++
++
++</body>
++</html>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_alerts.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_alerts.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_alerts.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_alerts.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,52 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++                $FORM_USER$
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=performance">Performances</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=alerts">Alertes</a></li>
++                <li><a href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++                <li><a href="$CGI$?$USER$template=analysis">Analyses</a></li>
++                <li><a href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Les alertes vous aident &agrave; localiser les messages dans la zone de quarantaine. Si le texte d'une alerte est rep&eacute;r&eacute; dans un message, la ligne correspondante sera mise en valeur, vous aidant &agrave; identifier les messages qui pourraient ne pas &ecirc;tre des pourriels.
++</p>
++
++$ALERTS$
++<p>
++<FORM ACTION="$CGI$">
++<INPUT TYPE=HIDDEN NAME=command VALUE=addAlert>
++<INPUT TYPE=HIDDEN NAME=template VALUE=alerts>
++<INPUT TYPE=HIDDEN NAME=user VALUE="$REMOTE_USER$">
++<INPUT NAME=ALERT> &nbsp;<INPUT TYPE=SUBMIT VALUE="Ajouter l'alerte">
++</FORM>
++</p>
++
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_analysis.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_analysis.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_analysis.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_analysis.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,52 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++                $FORM_USER$
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=performance">Performances</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++                <li><a href="$CGI$?$USER$template=alerts">Alertes</a></li>
++                <li><a href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=analysis">Analyses</a></li>
++                <li><a href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Des graphiques montrant le nombre de messages analys&eacute; sont affich&eacute;s ci-dessous.
++</p>
++
++<div class="content">
++	<h3><strong>Activit&eacute; sur 24 heures</strong> - $TS_DAILY$ pourriels, $TI_DAILY$ l&eacute;gitimes</h3>
++
++	<img src="./graph.cgi?data=$DATA_DAILY$&x_label=Heure+du+jour" />
++</div>
++
++<div class="content">
++	<h3><strong>Activit&eacute; sur 14 jours</strong> - $TS_WEEKLY$ pourriels, $TI_WEEKLY$ l&eacute;gitimes</h3>
++	<img src="./graph.cgi?data=$DATA_WEEKLY$&graph=period&x_label=Date" />
++</div>
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_error.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_error.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_error.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_error.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,40 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++		Centre de contr&ocirc;le DSPAM pour <strong>$REMOTE_USER$</strong>
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=performance">Performances</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++                <li><a href="$CGI$?$USER$template=alerts">Alertes</a></li>
++                <li><a href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++                <li><a href="$CGI$?$USER$template=analysis">Analyses</a></li>
++                <li><a href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++                $NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<H2>Une erreur s'est produite</H2>
++$MESSAGE$
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_fragment.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_fragment.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_fragment.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_fragment.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,26 @@
++
++<HEAD><TITLE>DSPAM v3 Control Center: $SUBJECT$</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000 MARGINHEIGHT=0 MARGINWIDTH=0 TOPMARGIN=0 LEFTMARGIN=0 RIGHTMARGIN=0>
++<table border=0 cellspacing=0 cellpadding=0 width=100%>
++<tr>
++<td width=10 bgcolor=#686868> &nbsp;</td>
++<td bgcolor=#686868>
++<br>
++<font color=white><big>$SUBJECT$</big><br>
++$FROM$<br>
++<small>$TIME$ ($INFO$)</small></font><br>
++<br>
++</td></tr>
++
++<tr><td width=10> &nbsp;</td>
++<td>
++<PRE>
++$MESSAGE$
++</PRE>
++</td></tr></table>
++</body>
++</html>
++
++
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_history.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_history.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_history.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_history.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,85 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++<script type="text/javascript" src="$WEB_ROOT$/dspam.js"></script>
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++                $FORM_USER$
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=performance">Performances</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++                <li><a href="$CGI$?$USER$template=alerts">Alertes</a></li>
++                <li><a href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++                <li><a href="$CGI$?$USER$template=analysis">Analyses</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Les messages analys&eacute;s par le filtre sont affich&eacute;s ci-dessous. Les messages les plus r&eacute;cents sont affich&eacute;s en premier. Utilisez
++les options d'apprentissage pour corriger les erreurs et distribuer les faux positifs qui sont plac&eacute;s en zone de quarantaine.
++</p>
++
++<form name="history" action="dspam.cgi" method="POST">
++<input type="submit" value="R&eacute;-analyser les messages s&eacute;lectionn&eacute;s">
++<input type="hidden" name="template" value="history">
++<input type="hidden" name="command" value="retrainChecked">
++<input type="hidden" name="user" value="$REMOTE_USER$">
++<input type="hidden" name="show" value="$SHOW$" >
++
++&nbsp;&nbsp;$SHOW_SELECTOR$
++
++<table border="0" cellspacing="0" cellpadding="2" width="100%">
++<tr>
++	<th>Type</th>
++        <th>Apprentissage</th>
++	<th>Date/Heure</th>
++	<th<Exp&eacute;diteur</th>
++	<th>Objet</th>
++	<th>Informations compl&eacute;mentaires</th>
++</tr>
++$HISTORY$
++</table>
++
++$HISTORYPAGES$
++
++<input type="submit" value="R&eacute;-analyser les messages s&eacute;lectionn&eacute;s">
++</form>
++
++</div>
++
++
++
++<script language="javascript">
++<!--
++var remote = null;
++
++function openwin(width, height, scroll, url) {
++  remote = window.open('', 'SpecialIntro', 'width=' + width + ',height='
++                  + height + ',resizable=1,dependent,scrollbars=' + scroll +
++                  ',status=0');
++  if (remote != null) {
++    if (remote.opener == null) { remote.opener = self; }
++    remote.location.href = url;
++  }
++}
++//-->
++</script>
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_performance.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_performance.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_performance.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_performance.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,108 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++		$FORM_USER$
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++		<li id="active"><a id="current" href="$CGI$?$USER$template=performance">Performances</a></li>
++		<li><a href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++		<li><a href="$CGI$?$USER$template=alerts">Alertes</a></li>
++		<li><a href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++		<li><a href="$CGI$?$USER$template=analysis">Analyses</a></li>
++		<li><a href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Si vous recevez un message dans votre application de messagerie qui n'a pas &eacute;t&eacute;
++intercept&eacute; par le filtre, transf&eacute;rez le &agrave; <strong>spam-$REMOTE_USER$$LOCAL_DOMAIN$</strong>
++de fa&ccedil;on &agrave; ce que le filtre l'analyse. Cela am&eacute;liorera les performances du filtre dans le futur.
++</p>
++
++<div class="content">
++	<h3><strong>Statistiques des performances</strong> - $TIME$</h3>
++
++	<table border="0" cellspacing="0" cellpadding="4">
++		<tr>
++			<th>Donn&eacute;es</th>
++			<th>&nbsp;</th>
++			<th>M&eacute;thode de calcul</th>
++		</tr>
++		<tr class="rowEven">
++			<td>Performance g&eacute;n&eacute;rale (depuis la derni&egrave;re r&eacute;initialisation)</td>
++			<td><strong>$OVERALL_ACCURACY$%</strong></td>
++			<td class="rowDivider"><span class="small">(Nombre de pourriels filtr&eacute;s + Nombre de messages l&eacute;gitime distribu&eacute;s) / Nombre total de messages</span></td>
++		</tr>
++                <tr class="rowOdd">
++                        <td>Identification des pourriels (depuis la derni&egrave;re r&eacute;initialisation)</td>
++                        <td><strong>$SPAM_ACCURACY$%</strong></td>
++                        <td class="rowDivider"><span class="small">(Taux de filtrage des pourriels uniquement)</td>
++               </tr>
++		<tr class="rowEven">
++			<td>Ratio de pourriels (sur le total analys&eacute;)</td>
++			<td><strong>$SPAM_RATIO$%</strong></td>
++			<td class="rowDivider"><span class="small">Total de pourriels (attrap&eacute;s et manqu&eacute;s) / Nombre total de messages</span></td>
++		</tr>
++	</table>
++	<table border="0" cellspacing="0" cellpadding="4">
++		<tr>
++			<th>&nbsp;</th>
++			<th>Pourriels</th>
++			<th>Messages l&eacute;gitimes</th>
++		</tr>
++		<tr class="rowEven">
++			<td rowspan="3" valign="top" nowrap>Depuis la derni&egrave;re r&eacute;initialisation</td>
++			<td>$TOTAL_SPAM_MISSED$ manqu&eacute;s</td>
++			<td>$TOTAL_NONSPAM_MISSED$ manqu&eacute;s</td>
++		</tr>
++		<tr class="rowEven">
++			<td>$TOTAL_SPAM_CAUGHT$ attrap&eacute;s</td>
++			<td>$TOTAL_NONSPAM_CAUGHT$ distribu&eacute;s</td>
++		</tr>
++		<tr class="rowEven">
++			<td>$SPAM_ACCURACY$% attrap&eacute;s</td>
++			<td>$NONSPAM_ERROR_RATE$% manqu&eacute;s</td>
++		</tr>
++		<tr class="rowOdd">
++			<td rowspan="2" valign="top" nowrap>Total analys&eacute; par le filtre</td>
++			<td>$TOTAL_SPAM_LEARNED$ manqu&eacute;s</td>
++			<td>$TOTAL_NONSPAM_LEARNED$ manqu&eacute;s</td>
++		</tr>
++		<tr class="rowOdd">
++			<td>$TOTAL_SPAM_SCANNED$ attrap&eacute;s</td>
++			<td>$TOTAL_NONSPAM_SCANNED$ distribu&eacute;s</td>
++		</tr>
++		<tr class="rowEven">
++			<td valign="top" nowrap>Depuis le corpus</td>
++			<td>$TOTAL_SPAM_CORPUSFED$ envoy&eacute;s</td>
++			<td>$TOTAL_NONSPAM_CORPUSFED$ envoy&eacute;s</td>
++		</tr>
++	</table>
++
++	<p>
++		<a href="$CGI$?$USER$command=resetStats" title="Remettre les statistiques &agrave; z&eacute;ro">R&eacute;initalisation</a> | <a href="$CGI$?$USER$command=tweak" title="Ajustement des messages transf&aecute;r&eacute;s au filtre">Ajustement -1</a>
++	</p>
++</div>
++
++</div>
++
++
++
++</body>
++</html>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_preferences.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_preferences.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_preferences.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_preferences.html	2009-08-06 15:09:40.000000000 +0200
+@@ -0,0 +1,120 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++		$FORM_USER$
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=performance">Performances</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++                <li><a href="$CGI$?$USER$template=alerts">Alertes</a></li>
++                <li><a href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++                <li><a href="$CGI$?$USER$template=analysis">Analyses</a></li>
++                <li><a href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Cette page vous permet de configurer la fa&ccedil;on dont le filtre g&egrave;re vos messages.
++</p>
++
++<FORM ACTION="$CGI$">
++<INPUT TYPE=HIDDEN NAME="template" VALUE="preferences">
++<INPUT TYPE=HIDDEN NAME="user" VALUE="$REMOTE_USER$">
++
++<div class="content">
++	<h3><strong>Apprentissage</strong> - Configure la fa&ccedil;don dont le filtre apprend lors de l'analyse des messages</h3>
++<p>
++<table class="hollow">
++<tr><td>
++DSPAM doit apprendre&nbsp;:<br><br>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TEFT" $S_TEFT$>
++&Agrave; chaque message analys&eacute; par le filtre<BR>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TOE" $S_TOE$> 
++Seulement lorsque le filtre commet une erreur<BR>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TUM" $S_TUM$> 
++Seulement lors de nouvelles donn&eacute;es ou lorsque le filtre commet une erreur
++</td><td width=20>
++ &nbsp;</td><td>
++Lorsque j'entraine DSPAM, je pr&eacute;f&egrave;re&nbsp;:<br><br>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="message" $S_LOC_MESSAGE$>
++<u>transf&eacute;rer</u> les pourriels re&ccedil;us (la signature appera&icirc;t dans le corps du message)<BR>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="headers" $S_LOC_HEADERS$>
++transf&eacute;rer les pourriels re&ccedil;us en tant que <u>pi&egrave;ce jointe</u> (la signature appara&icirc;t dans les en-t&ecirc;tes du messages)<BR>
++</td></tr>
++</table>
++</p>
++
++<p>
++Sensibilit&eacute; du filtre <stron>pendant</strong> la p&eacute;riode d'apprentissage&nbsp;:<br>
++<span class="small">Haute sensibilit&eacute (plus de pourriels seront plac&eacute; en quarantaine)</span>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=0 $SEDATION_0$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=1 $SEDATION_1$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=2 $SEDATION_2$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=3 $SEDATION_3$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=4 $SEDATION_4$>
++    | <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=5 $SEDATION_5$> |
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=6 $SEDATION_6$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=7 $SEDATION_7$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=8 $SEDATION_8$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=9 $SEDATION_9$>
++    <INPUT TYPE=RADIO NAME=statisticalSedation VALUE=10 $SEDATION_10$> 
++<span class="small">Faible sensibilit&eacute; (plus de messages seront consid&eacute;r&eacute;s comme l&eacute;gitimes et moins seront plac&eacute;s en quarantaine)</span>
++</p>
++
++</div>
++
++<div class="content">
++	<h3><strong>Gestion des messages</strong> - Configure la fa&ccedil;on dont sont g&eacute;r&eacute;s les pourriels</h3>
++<p>
++Lorsqu'un pourriel est identifi&eacute;&nbsp;:<br><br>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="quarantine" $S_ACTION_QUARANTINE$>Mettre le message en quarantaine<BR>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="tag" $S_ACTION_TAG$>Ajouter l'&eacute;tiquette <INPUT NAME=spamSubject VALUE="$SPAM_SUBJECT$" SIZE=8> &agrave; l'objet du message<BR>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="deliver" $S_ACTION_DELIVER$>Distribuer le message normalement en ajoutant une en-t&ecirc;te X-DSPAM-Result<BR>
++</p>
++
++</div>
++
++<div class="content">
++	<h3><strong>Fonctionnalit&eacute;s</strong> - Ajustement du filtrage</h3>
++<p>
++$OPTION$
++<INPUT TYPE=CHECKBOX NAME=enableBNR $C_BNR$>
++Activer la r&eacute;duction du bruit, qui am&eacute;liore g&eacute;n&eacute;ralement les performances de filtrage<br>
++<INPUT TYPE=CHECKBOX NAME=enableWhitelist $C_WHITELIST$>
++Activer la mise en liste blanche automatique des correspondants r&eacute;guliers<BR>
++<INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
++Ajouter les jetons de factorisation dans les en-t&ecirc;tes des messages<br>
++<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
++<label for="dailyQuarantineSummary">Activer l'envoi automatique de r&eacute;sum&eacute; journalier de la zone de quarantaine</label>
++</p>
++
++</div>
++
++<p>
++<INPUT TYPE=SUBMIT NAME=submit VALUE="Valider les modifications">
++</p>
++
++</FORM>
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_quarantine.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_quarantine.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_quarantine.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_quarantine.html	2009-08-06 14:58:33.000000000 +0200
+@@ -0,0 +1,85 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++<script type="text/javascript" src="$WEB_ROOT$/dspam.js"></script>
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++                $FORM_USER$
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++                <li><a href="$CGI$?$USER$template=performance">Performances</a></li>
++                <li><a href="$CGI$?$USER$template=preferences">Pr&eacute;f&eacute;rences</a></li>
++                <li><a href="$CGI$?$USER$template=alerts">Alertes</a></li>
++                <li id="active"><a id="current" href="$CGI$?$USER$template=quarantine">Quarantaine ($TOTAL_QUARANTINED_MESSAGES$)</a></li>
++                <li><a href="$CGI$?$USER$template=analysis">Analyses</a></li>
++                <li><a href="$CGI$?$USER$template=history&history_page=1">Historique</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++Les messages ci-dessous n'ont pas &eacute;t&eacute; distribu&eacute;s version votre application de messagerie car ils ont
++&eacute;t&eacutes; consid&eacute;r&eacute;s comme pourriels probables.
++Cliquez sur l'object pour voir un message, ou choisissez une option de tri pour modifier la fa&ccedil;on sont sont tri&eacute;s les messages.
++Utilisez les case &agrave; cocher <strong>Distribuer les messages s&eacute;lectionn&eacute;s</strong> pour distribuer les messages que vous souhaitez lire,
++ou utilisez <strong>Supprimer tous les messages</strong> pour vider la zone de quarantaine.
++</p>
++
++<form action="$CGI$" method="post">
++<p>
++<input type="hidden" name="command" value="processQuarantine" >
++<input type="hidden" name="template" value="quarantine" >
++<input type="hidden" name="user" value="$REMOTE_USER$" >
++<input type="hidden" name="sortby" value="$SORTBY$" >
++<input type="submit" value="Distribuer les messages s&eacute;lectionn&eacute;s" NAME="manyNotSpam" >
++&nbsp;
++<input type="submit" value="Supprimer les messages s&eacute;lectionn&eacute;s" onClick="if (confirm('&Ecirc;tes-vous s&ucirc;r de vouloir supprimer les messages s&eacute;lectionn&eacute;s de la zone de quarantaine ?')==false) { return false; }" />
++<a href="#" onClick='for(j=0; j<200;j++) { if (document.forms[1].elements[j].type == "checkbox") { 
++	document.forms[1].elements[j].checked = true; } } return false'>S&eacute;lectionner 200 messages.</a>
++&nbsp;
++<input type="submit" value="Supprimer tous les messages" name="deleteAll" onClick="if (confirm('&Ecirc;tes-vous s&ucirc;r de vouloir supprimer TOUS les messages de la zone de quarantaine ?')==false) { return false; }" >
++
++</p>
++<table border="0" cellspacing="0" cellpadding="2" width="100%">
++	<tr>
++		<th>&nbsp;</th>
++		$SORT_QUARANTINE$
++	</tr>
++$QUARANTINE$
++</table>
++
++<p>
++<input type="submit" value="Distribuer les messages s&eacute;lectionn&eacute;s" NAME="manyNotSpam" >
++&nbsp;
++<input type="submit" value="Supprimer les messages s&eacute;lectionn&eacute;s" onClick="if (confirm('&Ecirc;tes-vous s&ucirc;r de vouloir supprimer les messages s&eacute;lectionn&eacute;s de la zone de quarantaine ?')==false) { return false; }" />
++<a href="#" onClick='for(j=0; j<200;j++) { if (document.forms[1].elements[j].type == "checkbox") { 
++	document.forms[1].elements[j].checked = true; } } return false'>S&eacute;lectionner 200 messages.</a>
++&nbsp;
++<input type="submit" value="Supprimer tous les messages" name="deleteAll" onClick="if (confirm('&Ecirc;tes-vous s&ucirc;r de vouloir supprimer TOUS les messages de la zone de quarantaine ?')==false) { return false; }" />
++</p>
++
++</form>
++
++<p>
++Code couleurs&nbsp;: <span class="low">Score faible</span>, <span class="medium">Score moyen, <span class="high">Score &eacute;lev&eacute;</span>
++</p>
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_viewmessage.html dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_viewmessage.html
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/nav_viewmessage.html	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/nav_viewmessage.html	2009-08-06 14:20:39.000000000 +0200
+@@ -0,0 +1,54 @@
++<HTML>
++<HEAD><TITLE>DSPAM v3 Control Center</TITLE>
++<LINK REL="STYLESHEET" HREF="$WEB_ROOT$/base.css">
++</HEAD>
++<BODY BGCOLOR=#FFFFFF TEXT=#000000 LINK=#000000 VLINK=#000000 ALINK=#000000>
++<div id="header">
++	<div id="logo">
++		<a href="$CGI$" title="Home"><img src="$WEB_ROOT$/dspam-logo-small.gif" alt="DSPAM Logo" /></a>
++		<p>$DSPAMVERSION$</p>
++	</div>
++	<div id="userinfo">
++		Statistical SPAM Protection for <strong>$REMOTE_USER$</strong>
++	</div>
++</div>
++
++<br clear="left" />
++
++<div id="navcontainer">
++	<ul id="navlist">
++		<li><a href="$CGI$?$USER$template=performance">Performance</a></li>
++		<li><a href="$CGI$?$USER$template=preferences">Preferences</a></li>
++		<li><a href="$CGI$?$USER$template=alerts">Alerts</a></li>
++		<li id="active"><a id="current" href="$CGI$?$USER$template=quarantine">Quarantine (View)</a></li>
++		<li><a href="$CGI$?$USER$template=analysis">Analysis</a></li>
++		<li><a href="$CGI$?$USER$template=history&history_page=1">History</a></li>
++		$NAV_ADMIN$
++	</ul>
++</div>
++
++<div id="panel">
++
++<p>
++The contents of the message in the quarantine is shown below.
++</p>
++
++<FORM ACTION="$CGI$">
++<INPUT TYPE=HIDDEN NAME=signatureID VALUE="$MESSAGE_ID$">
++<INPUT TYPE=HIDDEN NAME=command VALUE="processFalsePositive">
++<INPUT TYPE=HIDDEN NAME=template VALUE="quarantine">
++<INPUT TYPE=HIDDEN NAME=user VALUE="$REMOTE_USER$">
++<INPUT TYPE=SUBMIT VALUE="Deliver Message"> because it is <strong>not</strong> SPAM
++</FORM>
++<BR>
++<TEXTAREA ROWS=36 COLS=80 READONLY>
++$MESSAGE$
++</TEXTAREA>
++</FORM>
++
++</div>
++
++
++
++</BODY>
++</HTML>
+diff -urNad dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/strings.txt dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/strings.txt
+--- dspam-3.9.0~beta2~/webui/cgi-bin/templates/fr/strings.txt	1970-01-01 01:00:00.000000000 +0100
++++ dspam-3.9.0~beta2/webui/cgi-bin/templates/fr/strings.txt	2009-08-06 15:14:59.000000000 +0200
+@@ -0,0 +1,67 @@
++#!/usr/bin/perl
++
++$LANG{'empty'}				= "Vide";
++$LANG{'admin_suite'}			= "Administration";
++$LANG{'alert_name'}			= "Nom de l'alerte";
++$LANG{'remove_alert'}			= "Supprimer";
++$LANG{'user_form'}			= "Centre de contr&ocirc;le DSPAM pour";
++$LANG{'user_form_submit'}		= "Changer";
++
++$LANG{'option_disable_filtering'}       = "D&eacute;sactiver le filtre DSPAM";
++$LANG{'option_enable_filtering'}        = "Activer le filtre DSPAM";
++
++$LANG{'quarantine_rating'}		= "Score";
++$LANG{'quarantine_date'}		= "Date";
++$LANG{'quarantine_from'}		= "Exp&eacute;diteur";
++$LANG{'quarantine_subject'}		= "Objet";
++
++$LANG{'history_show'}			= "Afficher&nbsp;";
++$LANG{'history_show_all'}		= "tous";
++$LANG{'history_show_spam'}		= "pourriels";
++$LANG{'history_show_innocent'}		= "l&eacute;gitimes";
++$LANG{'history_show_virus'}		= "virus";
++$LANG{'history_show_whitelisted'}	= "mis en liste blanche";
++$LANG{'history_retrain_as_spam'}	= "pourriel";
++$LANG{'history_retrain_as_innocent'}	= "l&eacute;gitime";
++$LANG{'history_retrain_as'}		= "comme ";
++$LANG{'history_retrained'}		= "R&eacute;-analys&eacute;";
++$LANG{'history_retrain_undo'}		= "d&eacute;faire";
++$LANG{'history_label_resend'}		= "Renvoi";
++$LANG{'history_label_whitelist'}	= "Liste blanche";
++$LANG{'history_label_spam'}		= "Pourriel";
++$LANG{'history_label_innocent'}		= "L&eacute;gitime";
++$LANG{'history_label_miss'}		= "Manqu&eacute;";
++$LANG{'history_label_virus'}		= "Virus";
++$LANG{'history_label_RBL'}		= "RBL";
++$LANG{'history_label_block'}		= "Bloqu&eacute;";
++$LANG{'history_label_corpus'}		= "Corpus";
++$LANG{'history_label_unknown'}		= "Inconnu";
++$LANG{'history_label_error'}		= "Erreur";
++
++$LANG{'error_no_historic'}		= "Aucune donn&eacute;e d'historique n'est disponible.";
++$LANG{'error_cannot_open_log'}		= "Impossible d'ouvrir le journal";
++$LANG{'error_no_identity'}		= "Erreur syst&egrave;me. Impossible de d&eacute;terminer votre identit&eacute;.";
++$LANG{'error_invalid_command'}		= "Commande invalide";
++$LANG{'error_cannot_write_prefs'}	= "Impossible d'enregistrer les pr&eacute;f&eacute;rences";
++$LANG{'error_no_sigid'}			= "Aucun identifiant de message n'a &eacute;t&eacute; sp&eacute;cifi&eacute;";
++$LANG{'error_no_alert_specified'}	= "Aucune alerte sp&eacute;cifi&eacute;e.";
++$LANG{'error_message_part1'}		= "L'erreur suivante s'est produite pendant le traitement de votre requ&ecirc;te&nbsp;:";
++$LANG{'error_message_part2'}		= "Si le probl&egrave;me persiste, contactez votre administrateur.";
++$LANG{'error_filesystem_scale'}		= "Impossible de d&eacute;terminer l'organisation du syst&egrave;me de fichiers";
++$LANG{'error_load_default_prefs'}	= "Impossible de charger les pr&eacute;f&eacute;rences par d&eacute;faut.";
++$LANG{'error_access_denied'}		= "Acc&egrave;s interdit";
++
++$LANG{'graph_legend_nb_messages'}	= "Nombre de messages";
++$LANG{'graph_legend_spam'}		= "Pourriels";
++$LANG{'graph_legend_good'}		= "Messages legitimes";
++$LANG{'graph_legend_inoculations'}	= "Inoculations";
++$LANG{'graph_legend_corpusfeds'}	= "Depuis le corpus";
++$LANG{'graph_legend_virus'}		= "Virus";
++$LANG{'graph_legend_RBL'}		= "RBL";
++$LANG{'graph_legend_blocklisted'}	= "Mis en liste noire";
++$LANG{'graph_legend_whitelisted'}	= "Mis en liste blanche";
++$LANG{'graph_legend_nonspam'}		= "Messages legitimes";
++$LANG{'graph_legend_spam_misses'}	= "Pourriels manques";
++$LANG{'graph_legend_falsepositives'}	= "Faux positifs";
++
++1;

Modified: branches/experimental/debian/patches/update-dspam.conf.dpatch
==============================================================================
--- branches/experimental/debian/patches/update-dspam.conf.dpatch	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/patches/update-dspam.conf.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -2,21 +2,27 @@
 ## update-dspam.conf.dpatch by Julien Valroff <julien at kirya.net>
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
+## DP: Debian default configuration
 
 @DPATCH@
-diff -urNad dspam-3.9.0~git+alpha2+git20090714~/src/dspam.conf.in dspam-3.9.0~git+alpha2+git20090714/src/dspam.conf.in
---- dspam-3.9.0~git+alpha2+git20090714~/src/dspam.conf.in	2009-07-18 11:11:54.000000000 +0200
-+++ dspam-3.9.0~git+alpha2+git20090714/src/dspam.conf.in	2009-07-18 11:12:36.000000000 +0200
-@@ -134,6 +134,7 @@
- Trust mailnull 
- Trust smmsp
+diff -urNad dspam-3.9.0~beta1+git20090802~/src/dspam.conf.in dspam-3.9.0~beta1+git20090802/src/dspam.conf.in
+--- dspam-3.9.0~beta1+git20090802~/src/dspam.conf.in	2009-08-02 16:05:42.000000000 +0200
++++ dspam-3.9.0~beta1+git20090802/src/dspam.conf.in	2009-08-02 16:20:54.000000000 +0200
+@@ -129,11 +129,10 @@
+ #
+ Trust root
+ Trust dspam
+-Trust apache
++Trust www-data
+ Trust mail
+-Trust mailnull 
+-Trust smmsp
  Trust daemon
 +Trust amavis
  #Trust nobody
  #Trust majordomo
  
-@@ -271,11 +272,11 @@
+@@ -271,11 +270,11 @@
  # If user or default.prefs are found, the user's preferences will override any
  # defaults.
  #
@@ -31,7 +37,7 @@
  
  #
  # Overrides: Specifies the user preferences which may override configuration
-@@ -292,94 +293,6 @@
+@@ -292,94 +291,6 @@
  AllowOverride optIn optOut
  AllowOverride whitelistThreshold
  
@@ -126,7 +132,7 @@
  # --- SQLite ---
  
  #SQLitePragma   "synchronous = OFF"
-@@ -649,7 +562,7 @@
+@@ -649,7 +560,7 @@
  # users will be filtered unless a .nodspam file is dropped in 
  # /var/dspam/opt-out/user.nodspam
  #
@@ -135,7 +141,16 @@
  
  #
  # TrackSources: specify which (if any) source addresses to track and report
-@@ -736,7 +649,7 @@
+@@ -657,7 +568,7 @@
+ # blacklist and would like to use this information. Spam reporting also drops
+ # RABL blacklist files (see http://www.nuclearelephant.com/projects/rabl/). 
+ #
+-#TrackSources spam nonspam
++#TrackSources spam nonspam virus
+ 
+ #
+ # ParseToHeaders: In lieu of setting up individual aliases for each user,
+@@ -736,7 +647,7 @@
  #ServerHost		127.0.0.1
  #ServerPort		24
  #ServerQueueSize	32
@@ -144,7 +159,24 @@
  
  #
  # ServerMode specifies the type of LMTP server to start. This can be one of:
-@@ -826,4 +739,7 @@
+@@ -772,14 +683,14 @@
+ # you are running the client and server on the same machine, as it eliminates
+ # much of the bandwidth overhead.
+ #
+-#ServerDomainSocketPath  "/tmp/dspam.sock"
++#ServerDomainSocketPath  "/var/run/dspam/dspam.sock"
+ 
+ #
+ # Client Mode: If you are running DSPAM in client/server mode, uncomment and
+ # set these variables. A ClientHost beginning with a / will be treated as
+ # a domain socket.
+ #
+-#ClientHost	/tmp/dspam.sock
++#ClientHost	/var/run/dspam/dspam.sock
+ #ClientIdent	"secret at Relay1"
+ #
+ #ClientHost	127.0.0.1
+@@ -826,4 +737,7 @@
  #
  StripRcptDomain off
  

Added: branches/experimental/debian/patches/where-to-find-txt-files.dpatch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/experimental/debian/patches/where-to-find-txt-files.dpatch	Wed Aug 12 10:56:29 2009	(r200)
@@ -0,0 +1,19 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## where-to-find-txt-files.dpatch by Julien Valroff <julien at kirya.net>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: txt files are installed in /etc/dspam/txt
+
+ at DPATCH@
+diff -urNad dspam-3.9.0~beta2~/src/dspam.c dspam-3.9.0~beta2/src/dspam.c
+--- dspam-3.9.0~beta2~/src/dspam.c	2009-08-09 21:40:44.183588053 +0200
++++ dspam-3.9.0~beta2/src/dspam.c	2009-08-09 21:41:09.043585576 +0200
+@@ -1532,7 +1532,7 @@
+ 
+   time(&now);
+ 
+-  snprintf(msgfile, sizeof(msgfile), "%s/txt/%s", _ds_read_attribute(agent_config, "Home"), filename);
++  snprintf(msgfile, sizeof(msgfile), "/etc/dspam/txt/%s", filename);
+   f = fopen(msgfile, "r");
+   if (!f) {
+     LOG(LOG_ERR, ERR_IO_FILE_OPEN, filename, strerror(errno));

Modified: branches/experimental/debian/rules
==============================================================================
--- branches/experimental/debian/rules	Sun Aug  2 08:51:20 2009	(r199)
+++ branches/experimental/debian/rules	Wed Aug 12 10:56:29 2009	(r200)
@@ -86,13 +86,6 @@
 	cat src/tools.pgsql_drv/pgsql_objects.sql > debian/sqlfiles/pgsql
 	cat src/tools.pgsql_drv/virtual_users.sql >> debian/sqlfiles/pgsql
 
-	chmod 644 webui/cgi-bin/templates/*
-	chmod 644 webui/cgi-bin/admins
-	chmod 644 webui/cgi-bin/default.prefs
-	chmod 644 webui/cgi-bin/rgb.txt
-	chmod 644 webui/htdocs/base.css
-	chmod 644 webui/htdocs/dspam-logo-small.gif
-	chmod 644 src/tools.sqlite_drv/purge-3.sql
 	touch build-stamp
 
 clean: clean-patched unpatch



More information about the Pkg-dspam-commits mailing list