[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\"> </td>".
++ " <td class=\"$b\"> </td>".
++ " <td class=\"$b\"> </td>".
++ " <td class=\"$b\"> </td>".
++ " <td class=\"$b\"> </td>".
++ " <td class=\"$b\"> </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> </th>
+ </tr>
+ _end
+@@ -1448,7 +1459,7 @@
+ while(<FILE>) {
+ s/</</g;
+ s/>/>/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/</<\;/g;
++ s/>/>\;/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/</</g;
++ $from =~ s/>/>/g;
++ $subject =~ s/</</g;
++ $subject =~ s/>/>/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! </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\"> < </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> $i </strong></big></a>";
++ } else {
++ $DATA{'HISTORYPAGES'} .= "<a href=\"$MYURL&show=$show&history_page=$i\"> $i </a>";
++ }
++ }
++ if (($history_pages > 1) && ($history_page < $history_pages)) {
++ my $i = $history_page+1;
++ $DATA{'HISTORYPAGES'} .= "<a href=\"$MYURL&show=$show&history_page=$i\"> > </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/</\<\;/g;
++ s/>/\>\;/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/</\<\;/g;
++ $new->{$_} =~ s/>/\>\;/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> </th>
++ </tr>
++_end
++
++ my($rowclass);
++ $rowclass = "rowEven";
++
++ do {
++ my($line) = 0;
++ open(FILE, "<$USER.alerts");
++ while(<FILE>) {
++ s/</</g;
++ s/>/>/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 ";
++$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ô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">État du systè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ô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ô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">État du systè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ôle</a></li>
++ $NAV_ADMIN$
++ </ul>
++</div>
++
++<div id="panel">
++
++<FORM ACTION="$CGI$">
++
++<p>
++Cette page vous permet d'éditer les préférences de n'importe quel utilisateur. Vous avez également la possibilité
++d'éditer les préférences par défaut de DSPAM en laissant le champ de saisie vide.
++</p>
++
++<p>
++Nom d'utilisateur :
++<INPUT NAME=username VALUE=$USERNAME$> <INPUT TYPE=SUBMIT VALUE=Éditer>
++</p>
++
++<p>
++$ERROR$
++</p>
++
++<INPUT TYPE=HIDDEN NAME="template" VALUE="preferences">
++
++<div class="content">
++ <h3><strong>Apprentissage</strong> - Configure la façdon dont le filtre apprend lors de l'analyse des messages</h3>
++<p>
++<table class="hollow">
++<tr><td>
++DSPAM doit apprendre :<br><br>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TEFT" $S_TEFT$>
++À chaque message analysé 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ées ou lorsque le filtre commet une erreur
++</td><td width=20>
++ </td><td>
++Lorsque j'entraine DSPAM, je préfère :<br><br>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="message" $S_LOC_MESSAGE$>
++<u>transférer</u> les pourriels reçus (la signature apperaît dans le corps du message)<BR>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="headers" $S_LOC_HEADERS$>
++transférer les pourriels reçus en tant que <u>pièce jointe</u> (la signature apparaît dans les en-têtes du messages)<BR>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="attachment" $S_LOC_ATTACHMENT$>
++laisser DSPAM joindre sa signature en tant que <u>pièce jointe</u><BR>
++</td></tr>
++</table>
++</p>
++
++<p>
++Sensibilité du filtre <stron>pendant</strong> la période d'apprentissage :<br>
++<span class="small">Haute sensibilité (plus de pourriels seront placé 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é (plus de messages seront considérés comme légitimes et moins seront placés en quarantaine)</span>
++</p>
++
++</div>
++
++<div class="content">
++ <h3><strong>Gestion des messages</strong> - Configure la façon dont sont gérés les pourriels</h3>
++<p>
++Lorsqu'un pourriel est identifié :<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'étiquette <INPUT NAME=spamSubject VALUE="$SPAM_SUBJECT$" SIZE=8> à l'objet du message<BR>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="deliver" $S_ACTION_DELIVER$>Distribuer le message normalement en ajoutant une en-tête X-DSPAM-Result<BR>
++</p>
++
++</div>
++
++<div class="content">
++ <h3><strong>Fonctionnalités</strong> - Ajustement du filtrage</h3>
++<p>
++<INPUT TYPE=CHECKBOX NAME=enableBNR $C_BNR$>
++Activer la réduction du bruit, qui améliore généralement les performances de filtrage<br>
++<INPUT TYPE=CHECKBOX NAME=enableWhitelist $C_WHITELIST$>
++Activer la mise en liste blanche automatique des correspondants réguliers<BR>
++<INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
++Ajouter les jetons de factorisation dans les en-têtes des messages<br>
++<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
++<label for="dailyQuarantineSummary">Activer l'envoi automatique de résumé 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ô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">État du systè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ôle</a></li>
++ </ul>
++</div>
++
++<div id="panel">
++
++<p>
++Les graphiques et les tableaux ci-dessous résument les analyses effectué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égitimes</td>
++ <td>$NONSPAM_TODAY$</td>
++ <td>$NONSPAM_THIS_HOUR$</td>
++ </tr>
++ <tr class="rowEven">
++ <td>Pourriels manqué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é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>É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é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è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é sur 24 heures</strong> - $TS_DAILY$ pourriel(s), $TI_DAILY$ message(s) légitime(s), $SM_DAILY$ pourriel(s) manqué(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é(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é journalière</strong> - $TS_DAILY$ pourriel(s), $TI_DAILY$ message(s) légitime(s), $SM_DAILY$ pourriel(s) manqué(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é(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ô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">État du systè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ôle</a></li>
++ </ul>
++</div>
++
++<div id="panel">
++
++<p>
++Le tableau ci-dessous montre le nombre de messages analysés pour chaque utilisateur, ainsi que leurs préfé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éfé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 à localiser les messages dans la zone de quarantaine. Si le texte d'une alerte est repéré dans un message, la ligne correspondante sera mise en valeur, vous aidant à identifier les messages qui pourraient ne pas ê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> <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éfé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é sont affichés ci-dessous.
++</p>
++
++<div class="content">
++ <h3><strong>Activité sur 24 heures</strong> - $TS_DAILY$ pourriels, $TI_DAILY$ légitimes</h3>
++
++ <img src="./graph.cgi?data=$DATA_DAILY$&x_label=Heure+du+jour" />
++</div>
++
++<div class="content">
++ <h3><strong>Activité sur 14 jours</strong> - $TS_WEEKLY$ pourriels, $TI_WEEKLY$ lé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ô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éfé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> </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> </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éfé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és par le filtre sont affichés ci-dessous. Les messages les plus récents sont affichés en premier. Utilisez
++les options d'apprentissage pour corriger les erreurs et distribuer les faux positifs qui sont placés en zone de quarantaine.
++</p>
++
++<form name="history" action="dspam.cgi" method="POST">
++<input type="submit" value="Ré-analyser les messages sélectionné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$" >
++
++ $SHOW_SELECTOR$
++
++<table border="0" cellspacing="0" cellpadding="2" width="100%">
++<tr>
++ <th>Type</th>
++ <th>Apprentissage</th>
++ <th>Date/Heure</th>
++ <th<Expéditeur</th>
++ <th>Objet</th>
++ <th>Informations complémentaires</th>
++</tr>
++$HISTORY$
++</table>
++
++$HISTORYPAGES$
++
++<input type="submit" value="Ré-analyser les messages sélectionné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éfé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 été
++intercepté par le filtre, transférez le à <strong>spam-$REMOTE_USER$$LOCAL_DOMAIN$</strong>
++de façon à ce que le filtre l'analyse. Cela amé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ées</th>
++ <th> </th>
++ <th>Méthode de calcul</th>
++ </tr>
++ <tr class="rowEven">
++ <td>Performance générale (depuis la dernière réinitialisation)</td>
++ <td><strong>$OVERALL_ACCURACY$%</strong></td>
++ <td class="rowDivider"><span class="small">(Nombre de pourriels filtrés + Nombre de messages légitime distribués) / Nombre total de messages</span></td>
++ </tr>
++ <tr class="rowOdd">
++ <td>Identification des pourriels (depuis la dernière ré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é)</td>
++ <td><strong>$SPAM_RATIO$%</strong></td>
++ <td class="rowDivider"><span class="small">Total de pourriels (attrapés et manqués) / Nombre total de messages</span></td>
++ </tr>
++ </table>
++ <table border="0" cellspacing="0" cellpadding="4">
++ <tr>
++ <th> </th>
++ <th>Pourriels</th>
++ <th>Messages légitimes</th>
++ </tr>
++ <tr class="rowEven">
++ <td rowspan="3" valign="top" nowrap>Depuis la dernière réinitialisation</td>
++ <td>$TOTAL_SPAM_MISSED$ manqués</td>
++ <td>$TOTAL_NONSPAM_MISSED$ manqués</td>
++ </tr>
++ <tr class="rowEven">
++ <td>$TOTAL_SPAM_CAUGHT$ attrapés</td>
++ <td>$TOTAL_NONSPAM_CAUGHT$ distribués</td>
++ </tr>
++ <tr class="rowEven">
++ <td>$SPAM_ACCURACY$% attrapés</td>
++ <td>$NONSPAM_ERROR_RATE$% manqués</td>
++ </tr>
++ <tr class="rowOdd">
++ <td rowspan="2" valign="top" nowrap>Total analysé par le filtre</td>
++ <td>$TOTAL_SPAM_LEARNED$ manqués</td>
++ <td>$TOTAL_NONSPAM_LEARNED$ manqués</td>
++ </tr>
++ <tr class="rowOdd">
++ <td>$TOTAL_SPAM_SCANNED$ attrapés</td>
++ <td>$TOTAL_NONSPAM_SCANNED$ distribués</td>
++ </tr>
++ <tr class="rowEven">
++ <td valign="top" nowrap>Depuis le corpus</td>
++ <td>$TOTAL_SPAM_CORPUSFED$ envoyés</td>
++ <td>$TOTAL_NONSPAM_CORPUSFED$ envoyés</td>
++ </tr>
++ </table>
++
++ <p>
++ <a href="$CGI$?$USER$command=resetStats" title="Remettre les statistiques à zéro">Réinitalisation</a> | <a href="$CGI$?$USER$command=tweak" title="Ajustement des messages transf&aecute;ré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éfé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çon dont le filtre gè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çdon dont le filtre apprend lors de l'analyse des messages</h3>
++<p>
++<table class="hollow">
++<tr><td>
++DSPAM doit apprendre :<br><br>
++<INPUT TYPE=RADIO NAME=trainingMode VALUE="TEFT" $S_TEFT$>
++À chaque message analysé 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ées ou lorsque le filtre commet une erreur
++</td><td width=20>
++ </td><td>
++Lorsque j'entraine DSPAM, je préfère :<br><br>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="message" $S_LOC_MESSAGE$>
++<u>transférer</u> les pourriels reçus (la signature apperaît dans le corps du message)<BR>
++<INPUT TYPE=RADIO NAME=signatureLocation VALUE="headers" $S_LOC_HEADERS$>
++transférer les pourriels reçus en tant que <u>pièce jointe</u> (la signature apparaît dans les en-têtes du messages)<BR>
++</td></tr>
++</table>
++</p>
++
++<p>
++Sensibilité du filtre <stron>pendant</strong> la période d'apprentissage :<br>
++<span class="small">Haute sensibilité (plus de pourriels seront placé 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é (plus de messages seront considérés comme légitimes et moins seront placés en quarantaine)</span>
++</p>
++
++</div>
++
++<div class="content">
++ <h3><strong>Gestion des messages</strong> - Configure la façon dont sont gérés les pourriels</h3>
++<p>
++Lorsqu'un pourriel est identifié :<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'étiquette <INPUT NAME=spamSubject VALUE="$SPAM_SUBJECT$" SIZE=8> à l'objet du message<BR>
++<INPUT TYPE=RADIO NAME=spamAction VALUE="deliver" $S_ACTION_DELIVER$>Distribuer le message normalement en ajoutant une en-tête X-DSPAM-Result<BR>
++</p>
++
++</div>
++
++<div class="content">
++ <h3><strong>Fonctionnalités</strong> - Ajustement du filtrage</h3>
++<p>
++$OPTION$
++<INPUT TYPE=CHECKBOX NAME=enableBNR $C_BNR$>
++Activer la réduction du bruit, qui améliore généralement les performances de filtrage<br>
++<INPUT TYPE=CHECKBOX NAME=enableWhitelist $C_WHITELIST$>
++Activer la mise en liste blanche automatique des correspondants réguliers<BR>
++<INPUT TYPE=CHECKBOX NAME=showFactors $C_FACTORS$>
++Ajouter les jetons de factorisation dans les en-têtes des messages<br>
++<input type="checkbox" name="dailyQuarantineSummary" id="dailyQuarantineSummary" $C_SUMMARY$>
++<label for="dailyQuarantineSummary">Activer l'envoi automatique de résumé 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éfé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 été distribués version votre application de messagerie car ils ont
++étés; considérés comme pourriels probables.
++Cliquez sur l'object pour voir un message, ou choisissez une option de tri pour modifier la façon sont sont triés les messages.
++Utilisez les case à cocher <strong>Distribuer les messages sélectionné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électionnés" NAME="manyNotSpam" >
++
++<input type="submit" value="Supprimer les messages sélectionnés" onClick="if (confirm('Êtes-vous sûr de vouloir supprimer les messages sélectionné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électionner 200 messages.</a>
++
++<input type="submit" value="Supprimer tous les messages" name="deleteAll" onClick="if (confirm('Êtes-vous sû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> </th>
++ $SORT_QUARANTINE$
++ </tr>
++$QUARANTINE$
++</table>
++
++<p>
++<input type="submit" value="Distribuer les messages sélectionnés" NAME="manyNotSpam" >
++
++<input type="submit" value="Supprimer les messages sélectionnés" onClick="if (confirm('Êtes-vous sûr de vouloir supprimer les messages sélectionné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électionner 200 messages.</a>
++
++<input type="submit" value="Supprimer tous les messages" name="deleteAll" onClick="if (confirm('Êtes-vous sûr de vouloir supprimer TOUS les messages de la zone de quarantaine ?')==false) { return false; }" />
++</p>
++
++</form>
++
++<p>
++Code couleurs : <span class="low">Score faible</span>, <span class="medium">Score moyen, <span class="high">Score élevé</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ôle DSPAM pour";
++$LANG{'user_form_submit'} = "Changer";
++
++$LANG{'option_disable_filtering'} = "Désactiver le filtre DSPAM";
++$LANG{'option_enable_filtering'} = "Activer le filtre DSPAM";
++
++$LANG{'quarantine_rating'} = "Score";
++$LANG{'quarantine_date'} = "Date";
++$LANG{'quarantine_from'} = "Expéditeur";
++$LANG{'quarantine_subject'} = "Objet";
++
++$LANG{'history_show'} = "Afficher ";
++$LANG{'history_show_all'} = "tous";
++$LANG{'history_show_spam'} = "pourriels";
++$LANG{'history_show_innocent'} = "lé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égitime";
++$LANG{'history_retrain_as'} = "comme ";
++$LANG{'history_retrained'} = "Ré-analysé";
++$LANG{'history_retrain_undo'} = "défaire";
++$LANG{'history_label_resend'} = "Renvoi";
++$LANG{'history_label_whitelist'} = "Liste blanche";
++$LANG{'history_label_spam'} = "Pourriel";
++$LANG{'history_label_innocent'} = "Légitime";
++$LANG{'history_label_miss'} = "Manqué";
++$LANG{'history_label_virus'} = "Virus";
++$LANG{'history_label_RBL'} = "RBL";
++$LANG{'history_label_block'} = "Bloqué";
++$LANG{'history_label_corpus'} = "Corpus";
++$LANG{'history_label_unknown'} = "Inconnu";
++$LANG{'history_label_error'} = "Erreur";
++
++$LANG{'error_no_historic'} = "Aucune donnée d'historique n'est disponible.";
++$LANG{'error_cannot_open_log'} = "Impossible d'ouvrir le journal";
++$LANG{'error_no_identity'} = "Erreur système. Impossible de déterminer votre identité.";
++$LANG{'error_invalid_command'} = "Commande invalide";
++$LANG{'error_cannot_write_prefs'} = "Impossible d'enregistrer les préférences";
++$LANG{'error_no_sigid'} = "Aucun identifiant de message n'a été spécifié";
++$LANG{'error_no_alert_specified'} = "Aucune alerte spécifiée.";
++$LANG{'error_message_part1'} = "L'erreur suivante s'est produite pendant le traitement de votre requête :";
++$LANG{'error_message_part2'} = "Si le problème persiste, contactez votre administrateur.";
++$LANG{'error_filesystem_scale'} = "Impossible de déterminer l'organisation du système de fichiers";
++$LANG{'error_load_default_prefs'} = "Impossible de charger les préférences par défaut.";
++$LANG{'error_access_denied'} = "Accè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