diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/conf/config.pl /var/www/cgi-bin/perl-admin/conf/config.pl
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/conf/config.pl	2004-08-20 13:01:50.000000000 +0200
+++ /var/www/cgi-bin/perl-admin/conf/config.pl	2007-07-19 09:40:14.000000000 +0200
@@ -1,2 +1,2 @@
 $topdir = "/var/spool/mlmmj";
-$templatedir = "/home/mlmmj/templates";
+$templatedir = "/var/www/cgi-bin/perl-admin/templates";
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/htdocs/edit_text.cgi /var/www/cgi-bin/perl-admin/htdocs/edit_text.cgi
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/htdocs/edit_text.cgi	1970-01-01 01:00:00.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/htdocs/edit_text.cgi	2007-07-19 14:07:53.000000000 +0200
@@ -0,0 +1,88 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2004 Morten K. Poulsen <morten at afdelingp.dk>
+# Copyright (C) 2004 Christian Laursen <christian@pil.dk>
+#
+# $Id: edit.cgi,v 1.2 2004/11/09 15:19:02 mmj Exp $
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+use strict;
+use CGI;
+use CGI::FastTemplate;
+use HTML::Entities;
+
+use vars qw($topdir $templatedir $list);
+
+if (exists $ENV{CONFIG_PATH}) {
+	require $ENV{CONFIG_PATH};
+} else {
+	require "../conf/config.pl";
+}
+
+my $tpl = new CGI::FastTemplate($templatedir);
+
+my $q = new CGI;
+$list = $q->param("list");
+
+die "no list specified" unless $list;
+die "non-existent list" unless -d("$topdir/$list");
+
+$tpl->define(main => "edit_text.html",
+             list => "edit_textstring.html");
+
+$tpl->assign(LIST => encode_entities($list));
+
+my $textdir = "$topdir/$list/text";
+my @files;
+opendir(DIR, $textdir ) || die "can't opendir $textdir: $!";
+@files = grep { !/^\./ && -f "$textdir/$_" } readdir(DIR);
+closedir DIR;
+
+for my $textfile (sort @files) {
+   mlmmj_text($textfile);
+}
+
+print "Content-type: text/html\n\n";
+$tpl->parse(CONTENT => "main");
+$tpl->print;
+
+sub mlmmj_text {
+	my ($name, $nicename, $text) = @_;
+    my $file = "$textdir/$name";
+    my $value;
+
+    if (! -f $file) {
+        $value = "";
+    } else {
+        open(F, $file) or die("can't open $file");
+        while (<F>) {
+            $value .= $_;
+        }
+        close(F);
+        chomp($value);
+    }
+
+	$tpl->assign(NAME => encode_entities($name));
+	$tpl->assign(NICENAME => encode_entities($nicename));
+	$tpl->assign(TEXT => encode_entities($text));
+	$tpl->assign(VALUE => encode_entities($value));
+
+	$tpl->parse(ROWS => ".list");
+}
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/htdocs/save_text.cgi /var/www/cgi-bin/perl-admin/htdocs/save_text.cgi
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/htdocs/save_text.cgi	1970-01-01 01:00:00.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/htdocs/save_text.cgi	2007-07-19 14:08:46.000000000 +0200
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2004 Morten K. Poulsen <morten at afdelingp.dk>
+# Copyright (C) 2004 Christian Laursen <christian@pil.dk>
+#
+# $Id: save.cgi,v 1.3 2005/03/14 12:44:56 mmj Exp $
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+# We might want some kind of validation of the values we are about to save,
+# but that would require save.cgi to know about all kind of options that mlmmj
+# accepts. I am not sure we want that.  -- mortenp 20040709
+
+use strict;
+use CGI;
+use CGI::FastTemplate;
+use HTML::Entities;
+
+use vars qw($topdir $templatedir $list);
+
+if (exists $ENV{CONFIG_PATH}) {
+	require $ENV{CONFIG_PATH};
+} else {
+	require "../conf/config.pl";
+}
+
+my $tpl = new CGI::FastTemplate($templatedir);
+
+my $q = new CGI;
+$list = $q->param("list");
+
+die "no list specified" unless $list;
+die "non-existent list" unless -d("$topdir/$list");
+
+$tpl->define(main => "save_text.html");
+$tpl->assign(LIST => encode_entities($list));
+
+my $textdir = "$topdir/$list/text";
+my @files;
+opendir(DIR, $textdir ) || die "can't opendir $textdir: $!";
+@files = grep { !/^\./ && -f "$textdir/$_" } readdir(DIR);
+closedir DIR;
+
+for my $textfile (sort @files) {
+   mlmmj_text($textfile);
+}
+
+print "Content-type: text/html\n\n";
+$tpl->parse(CONTENT => "main");
+$tpl->print;
+
+sub mlmmj_text {
+	my ($name, $nicename, $text) = @_;
+
+	my $file = "$textdir/$name";
+
+	my $value = $q->param($name);
+
+	open (FILE, ">$file") or die "Couldn't open $file for writing: $!";
+	print FILE $value;
+	close FILE;
+}
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/htdocs/subscribers.cgi /var/www/cgi-bin/perl-admin/htdocs/subscribers.cgi
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/htdocs/subscribers.cgi	2006-07-14 10:04:56.000000000 +0200
+++ /var/www/cgi-bin/perl-admin/htdocs/subscribers.cgi	2007-07-19 15:42:53.000000000 +0200
@@ -47,6 +47,8 @@
 my $update = $q->param("update");
 my $search = $q->param("search");
 my $email = $q->param("email");
+my $file = $q->param("file");
+my $removeall = $q->param("removeall");
 
 # Everything is submitted from the same form so a little hackery is needed
 # to pick the right action to perform. When doing subscribe and search we
@@ -72,21 +74,55 @@
 my $subscribers;
 my $subcount;
 
-if (defined $email) {
+if (defined $removeall) {
+	my $removeall_check = $q->param("removeall_check");
+	if ($removeall_check) {
+	   unlink <$topdir/$list/subscribers.d/*>;
+	   unlink <$topdir/$list/nomailsubs.d/*>;
+	   unlink <$topdir/$list/digesters.d/*>;
+	   $action = "All subscribers have been removed.";
+	} else {
+	   $action = "Safety check not clicked, nothing done.";
+	}
+} elsif (defined $file) {
+	my $subscriber = $q->param("subscriber");
+	my $digester = $q->param("digester");
+	my $nomailsub = $q->param("nomailsub");
+	my $upload_handle = $q->upload("file");
+	binmode $upload_handle;
+	while (<$upload_handle>) {
+	   chomp;
+	   my $email=$_;
+	   if ($email =~ /^[a-z0-9\.\-_\@]+$/i) {
+		if ($subscriber) {
+			system "$mlmmjsub -L $topdir/$list -a $email -U -s";
+		}
+		if ($digester) {
+			system "$mlmmjsub -L $topdir/$list -a $email -Ud -s";
+		}
+		if ($nomailsub) {
+			system "$mlmmjsub -L $topdir/$list -a $email -Un -s";
+		}
+		$action .= "$email has been subscribed.<br>\n";
+	   } else {
+		$action .= '"'.encode_entities($email).'" is not a valid email address.<br>';
+	   }
+	}
+} elsif (defined $email) {
 	my $subscriber = $q->param("subscriber");
 	my $digester = $q->param("digester");
 	my $nomailsub = $q->param("nomailsub");
 	if ($email =~ /^[a-z0-9\.\-_\@]+$/i) {
 		if ($subscriber) {
-			system "$mlmmjsub -L $topdir/$list -a $email -U";
+			system "$mlmmjsub -L $topdir/$list -a $email -U -s";
 		}
 		if ($digester) {
-			system "$mlmmjsub -L $topdir/$list -a $email -Ud";
+			system "$mlmmjsub -L $topdir/$list -a $email -Ud -s";
 		}
 		if ($nomailsub) {
-			system "$mlmmjsub -L $topdir/$list -a $email -Un";
+			system "$mlmmjsub -L $topdir/$list -a $email -Un -s";
 		}
-		$action = "$email has been subscribed.";
+		$action = "error adding $email (code $?)";
 	} else {
 		$action = '"'.encode_entities($email).'" is not a valid email address.';
 	}
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/README /var/www/cgi-bin/perl-admin/README
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/README	2004-11-09 16:19:00.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/README	2007-07-19 13:56:49.000000000 +0200
@@ -27,8 +27,14 @@
    you need to create a group (eg. mlmmj) and add both users to it. The
    subscribers.d directory then needs to be writable by that group:
 
-     # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/subscribers.d/
-     # chmod -R g+w /var/spool/mlmmj/mlmmj-test/subscribers.d/
+     # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/subscribers.d
+     # chmod -R g+w /var/spool/mlmmj/mlmmj-test/subscribers.d
+     # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/digesters.d
+     # chmod -R g+w /var/spool/mlmmj/mlmmj-test/digesters.d
+     # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/nomailsubs.d
+     # chmod -R g+w /var/spool/mlmmj/mlmmj-test/nomailsubs.d
+     # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/text
+     # chmod -R g+w /var/spool/mlmmj/mlmmj-test/text
 
 To enable access control on Apache you have to:
 
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/edit.html /var/www/cgi-bin/perl-admin/templates/edit.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/edit.html	2006-07-14 10:04:56.000000000 +0200
+++ /var/www/cgi-bin/perl-admin/templates/edit.html	2007-07-19 13:54:54.000000000 +0200
@@ -1,7 +1,7 @@
 <html><head><title>mlmmj config</title></head><body>
 <h1>mlmmj config</h1>
 <p>
-<a href="index.cgi">Index</a> | <a href="subscribers.cgi?list=$LIST">Subscribers</a>
+<a href="index.cgi">Index</a> | <a href="edit.cgi?list=$LIST">Configuration</a> | <a href="edit_text.cgi?list=$LIST">Edit texts</a></td>
 </p>
 <p>
 List: $LIST
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/edit_text.html /var/www/cgi-bin/perl-admin/templates/edit_text.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/edit_text.html	1970-01-01 01:00:00.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/templates/edit_text.html	2007-07-19 13:55:09.000000000 +0200
@@ -0,0 +1,16 @@
+<html><head><title>mlmmj config</title></head><body>
+<h1>mlmmj config</h1>
+<p>
+<a href="index.cgi">Index</a> | <a href="edit.cgi?list=$LIST">Configuration</a> | <a href="edit_text.cgi?list=$LIST">Edit texts</a></td>
+</p>
+<p>
+List: $LIST
+</p>
+<form method="post" action="save_text.cgi">
+<input type="hidden" name="list" value="$LIST">
+<table border="1">
+$ROWS
+</table>
+<input type="submit" name="submit" value="Update texts" />
+</form>
+</body></html>
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/edit_textstring.html /var/www/cgi-bin/perl-admin/templates/edit_textstring.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/edit_textstring.html	1970-01-01 01:00:00.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/templates/edit_textstring.html	2007-07-19 13:44:31.000000000 +0200
@@ -0,0 +1 @@
+<tr><td>$NAME</td><td><textarea name="$NAME" rows="10" cols="70">$VALUE</textarea></td></tr>
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/index_row.html /var/www/cgi-bin/perl-admin/templates/index_row.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/index_row.html	2004-11-11 14:10:51.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/templates/index_row.html	2007-07-19 13:13:03.000000000 +0200
@@ -1 +1 @@
-<tr><td>$LIST</td><td><a href="edit.cgi?list=$ULIST">Configure</a></td><td><a href="subscribers.cgi?list=$ULIST">Subscribers</a></td></tr>
+<tr><td>$LIST</td><td><a href="edit.cgi?list=$ULIST">Configure</a></td><td><a href="subscribers.cgi?list=$ULIST">Subscribers</a></td><td><a href="edit_text.cgi?list=$ULIST">Edit texts</a></td></tr>
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/save.html /var/www/cgi-bin/perl-admin/templates/save.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/save.html	2004-11-26 15:36:27.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/templates/save.html	2007-07-19 13:54:40.000000000 +0200
@@ -4,6 +4,6 @@
 $LIST control values saved!
 </p>
 <p>
-<a href="index.cgi">Index</a> | <a href="edit.cgi?list=$LIST">Back to configuration</a>
+<a href="index.cgi">Index</a> | <a href="edit.cgi?list=$LIST">Configuration</a> | <a href="edit_text.cgi?list=$LIST">Edit texts</a></td>
 </p>
 </body></html>
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/save_text.html /var/www/cgi-bin/perl-admin/templates/save_text.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/save_text.html	1970-01-01 01:00:00.000000000 +0100
+++ /var/www/cgi-bin/perl-admin/templates/save_text.html	2007-07-19 13:54:00.000000000 +0200
@@ -0,0 +1,9 @@
+<html><head><title>mlmmj config</title></head><body>
+<h1>mlmmj config</h1>
+<p>
+$LIST text values saved!
+</p>
+<p>
+<a href="index.cgi">Index</a> | <a href="edit.cgi?list=$LIST">Configuration</a> | <a href="edit_text.cgi?list=$LIST">Edit texts</a></td>
+</p>
+</body></html>
diff -ubr --new-file mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/subscribers.html /var/www/cgi-bin/perl-admin/templates/subscribers.html
--- mlmmj-1.2.15-RC1/contrib/web/perl-admin/templates/subscribers.html	2006-07-14 10:04:56.000000000 +0200
+++ /var/www/cgi-bin/perl-admin/templates/subscribers.html	2007-07-19 13:55:40.000000000 +0200
@@ -1,11 +1,35 @@
 <html><head><title>mlmmj subscribers</title></head><body>
 <h1>mlmmj subscribers</h1>
 <p>
-<a href="index.cgi">Index</a> | <a href="subscribers.cgi?list=$LIST">Reload subscriber list</a> | <a href="edit.cgi?list=$LIST">Configure</a>
+<a href="index.cgi">Index</a> | <a href="subscribers.cgi?list=$LIST">Reload subscriber list</a> | <a href="edit.cgi?list=$LIST">Configuration</a> | <a href="edit_text.cgi?list=$LIST">Edit texts</a></td>
 </p>
 <p>
 $ACTION
 </p>
+<hr>
+<form action="subscribers.cgi" method="post" onSubmit="if (window.confirm('Are you sure you want to do this?')) this.submit(); else return false;">
+<input type="hidden" name="list" value="$LIST">
+<input type="hidden" name="maxid" value="$MAXID">
+<input type="hidden" name="removeall" value="1">
+<table><tr><td rowspan="5" valign="top">Remove all subscribers:&nbsp;&nbsp;</td>
+<td><input type="submit" name="remove" value="Remove all"></td></tr>
+<tr><td>Click this as extra safety check: <input type="checkbox" name="removeall_check" value="1" unchecked></td></tr>
+</table>
+</form>
+<hr>
+<form action="subscribers.cgi" method="post" enctype="multipart/form-data">
+<input type="hidden" name="list" value="$LIST">
+<input type="hidden" name="maxid" value="$MAXID">
+<input type="hidden" name="page" value="$PAGE">
+<table><tr><td rowspan="5" valign="top">Bulk add subscribers:&nbsp;&nbsp;</td>
+<td>File: <input type="FILE" name="file"></td></tr>
+<tr><td>Normal subscribers: <input type="checkbox" name="subscriber" value="1" checked></td></tr>
+<tr><td>Digest subscribers: <input type="checkbox" name="digester" value="1"></td></tr>
+<tr><td>No-mail subscribers: <input type="checkbox" name="nomailsub" value="1"></td></tr>
+<tr><td><input type="submit" name="subscribe" value="Subscribe"></td></tr>
+</table>
+</form>
+
 <form action="subscribers.cgi" method="post">
 <input type="hidden" name="list" value="$LIST">
 <input type="hidden" name="maxid" value="$MAXID">

