QMAIL_BASE now defaults to /var/qmail/control (before: it was mandatory)

replaced DEFAULT_HOST by MAIL_DOMAIN
clarified MAIL_DOMAIN and MAIL_ADDRESS_PREFIX retrieval
clarified 'mimeremove' handling (Closes: #32)
added support for ezmlm-idx v5 features 'headerkeep', 'mimekeep' and 'copylines'
added 'easy' and 'expert' interface settings
fixed tagging of active menue items
cleaned version-specific visibility of some options (charset, language, ...)
This commit is contained in:
lars 2007-04-03 15:49:24 +00:00
parent dbad72d853
commit 9d0e8730e0
27 changed files with 776 additions and 213 deletions

8
TODO
View file

@ -1,11 +1,7 @@
add basic/normal/expert to web interface
Reply-To-Option
multi-domain-Support?
charset support for idx <= 5.0
Listen-Auswahl fuer Einsende/Mod/...-Modi (moderiert & offen / newsletter / ...)
Infos fuer Massen-Hosting:
http://www.fbis.ch/index-de.php?page=14&frameset=4
support for 'mailinglist' (maybe)

View file

@ -1,11 +1,13 @@
Version 3.2 - 04/14/02006
* support for encrypted mailing lists
(https://systemausfall.org/toolforge/gpgpy-ezmlm/)
* support for multi-domain setups
* support for multi-domain setups (multiple list directories)
* detect preferred interface language
* user-specific interface language selection
* support for listing of subscription log
* a prefix for the local part of mailing list addresses is now configurable
* user-specific interface selection (easy/default/expert)
* support for more ezmlm-idx: 'headerkeep', 'mimekeep' and 'copylines'
* script for creating binary suid wrappers added
* handling of empty settings for ezmlm-idx 5.0 fixed (closes #21)
* bug in MySQL support fixed

View file

@ -52,6 +52,7 @@ $UNSAFE_RM = 0;
$ALIAS_USER = "alias";
# Where do the qmail control files live on this system ...
# defaults to /var/qmail/control
$QMAIL_BASE = $Mail::Ezmlm::QMAIL_BASE . '/control';
# default mailing list domain name (optional)

View file

@ -76,7 +76,7 @@ use vars qw[$DEFAULT_OPTIONS $UNSAFE_RM $ALIAS_USER $LIST_DIR];
use vars qw[$QMAIL_BASE $PRETTY_NAMES $DOTQMAIL_DIR];
use vars qw[$FILE_UPLOAD $WEBUSERS_FILE $MAIL_DOMAIN $HTML_TITLE];
use vars qw[$HTML_CSS_FILE $TEMPLATE_DIR $LANGUAGE_DIR $HTML_LANGUAGE];
use vars qw[$DEFAULT_HOST $MAIL_ADDRESS_PREFIX];
use vars qw[$MAIL_ADDRESS_PREFIX];
# some settings for encrypted mailing lists
use vars qw[$GPG_SUPPORT];
# settings for multi-domain setups
@ -151,13 +151,40 @@ $HTML_CSS_FILE = '' unless defined($HTML_CSS_FILE);
# check template directory
$TEMPLATE_DIR = 'template' unless defined($TEMPLATE_DIR);
if (defined($MAIL_DOMAIN) && ($MAIL_DOMAIN ne '')) {
$DEFAULT_HOST = $MAIL_DOMAIN;
} else {
# Work out default domain name from qmail (for David Summers)
open (GETHOST, "<$QMAIL_BASE/defaultdomain") || open (GETHOST, "<$QMAIL_BASE/me") || &fatal_error("Unable to read $QMAIL_BASE/me: $!");
chomp($DEFAULT_HOST = <GETHOST>);
close GETHOST;
# check QMAIL_BASE
$QMAIL_BASE = '/var/qmail/control' unless defined($QMAIL_BASE);
# determine MAIL_DOMAIN
unless (defined($MAIL_DOMAIN) && ($MAIL_DOMAIN ne '')) {
if ((-e "$QMAIL_BASE/virtualdomains") && open(VD, "<$QMAIL_BASE/virtualdomains")) {
# Work out if this user has a virtual host and set input accordingly ...
while(<VD>) {
last if (($MAIL_DOMAIN) = /(.+?):$USER/);
}
close VD;
}
# use 'defaultdomain' or 'me' if no matching virtualdomain was found
if (defined($MAIL_DOMAIN) && ($MAIL_DOMAIN ne '')) {
# the prefix is empty for virtual domains
$MAIL_ADDRESS_PREFIX = "" unless (defined($MAIL_ADDRESS_PREFIX));
} else {
# Work out default domain name from qmail (for David Summers)
if (open (GETHOST, "<$QMAIL_BASE/defaultdomain") || open (GETHOST, "<$QMAIL_BASE/me")) {
chomp($MAIL_DOMAIN = <GETHOST>);
close GETHOST;
} else {
&fatal_error("Unable to read $QMAIL_BASE/me: $!");
}
}
}
# check MAIL_ADDRESS_PREFIX
unless (defined($MAIL_ADDRESS_PREFIX)) {
if ($USER eq $ALIAS_USER) {
$MAIL_ADDRESS_PREFIX = "";
} else {
$MAIL_ADDRESS_PREFIX = "$USER-"
}
}
@ -172,7 +199,10 @@ my $action = $q->param('action');
# This is where we decide what to do, depending on the form state and the
# users chosen course of action ...
# TODO: unify all these "is list param set?" checks ...
if (%DOMAINS && (!defined($CURRENT_DOMAIN) || ($CURRENT_DOMAIN eq '')
if ($action eq 'show_mime_examples') {
&output_mime_examples();
exit 0;
} elsif (%DOMAINS && (!defined($CURRENT_DOMAIN) || ($CURRENT_DOMAIN eq '')
|| ($action eq 'domain_select'))) {
# domain support is enabled, but no domain is selected
$pagename = 'domain_select';
@ -465,11 +495,27 @@ sub init_hdf {
unless (-e $TEMPLATE_DIR);
$hdf->setValue("TemplateDir", "$TEMPLATE_DIR/");
# "normal", "basic" and "expert" should be supported soon
# TODO: should be selected via web interface
$ui_template = "normal";
# easy/normal/expert
my $one_template;
my @all_templates = &get_available_interfaces();
if (defined($q->param('template'))) {
foreach $one_template (@all_templates) {
$ui_template = $q->param('template')
if ($q->param('template') eq $one_template);
}
}
$ui_template = 'normal' unless defined($ui_template);
$hdf->setValue("Config.UI.LinkAttrs.template", $ui_template);
# retrieve available interface sets and add them to the dataset
my %interfaces = &get_available_interfaces();
my $interface;
foreach $interface (keys %interfaces) {
$hdf->setValue("Config.UI.Interfaces.$interface",
$interfaces{$interface});
}
# retrieve available languages and add them to the dataset
my %languages = &get_available_interface_languages();
my $lang;
@ -486,6 +532,17 @@ sub init_hdf {
# support for encrypted mailing lists?
$hdf->setValue("Config.Features.Crypto", 1) if ($GPG_SUPPORT);
# enable some features that are only available for specific versions
# of ezmlm-idx
if (Mail::Ezmlm->get_version() >= 5.1) {
$hdf->setValue("Config.Features.KeepFiles", 1);
}
if (Mail::Ezmlm->get_version() >= 5) {
$hdf->setValue("Config.Features.LanguageSelect", 1);
$hdf->setValue("Config.Features.CharsetSelect", 1);
$hdf->setValue("Config.Features.CopyLines", 1);
}
return $hdf;
}
@ -652,34 +709,14 @@ sub set_pagedata_list_of_lists {
sub set_pagedata {
my ($hostname, $username);
# read available list of lists
&set_pagedata_list_of_lists();
# multi domain support?
&set_pagedata_domains() if (%DOMAINS);
# username and hostname
# Work out if this user has a virtual host and set input accordingly ...
if (-e "$QMAIL_BASE/virtualdomains") {
open(VD, "<$QMAIL_BASE/virtualdomains") || warn "Can't read virtual domains file: $!";
while(<VD>) {
last if (($hostname) = /(.+?):$USER/);
}
close VD;
}
if (!defined($hostname)) {
$username = "$USER-" if ($USER ne $ALIAS_USER);
$hostname = $DEFAULT_HOST;
}
# maybe a local prefix was configured?
if (defined($MAIL_ADDRESS_PREFIX)) {
$username = $MAIL_ADDRESS_PREFIX;
}
$pagedata->setValue("Data.UserName", "$username");
$pagedata->setValue("Data.HostName", "$hostname");
$pagedata->setValue("Data.LocalPrefix", $MAIL_ADDRESS_PREFIX);
$pagedata->setValue("Data.HostName", $MAIL_DOMAIN);
# modules
@ -807,10 +844,30 @@ sub set_pagedata_misc_configfiles {
$pagedata->setValue("Data.List.Prefix", "$item");
$item = $list->getpart('headeradd');
$pagedata->setValue("Data.List.HeaderAdd", "$item");
$item = $list->getpart('headerremove');
$pagedata->setValue("Data.List.HeaderRemove", "$item");
$item = $list->getpart('mimeremove');
$pagedata->setValue("Data.List.MimeRemove", "$item");
# 'headerremove' is ignored if 'headerkeep' exists (since ezmlm-idx v5)
if ((Mail::Ezmlm->get_version() >= 5.1) &&(-e $list->thislist() . "/headerkeep")) {
$item = $list->getpart('headerkeep');
$pagedata->setValue("Data.List.HeaderKeep", "$item");
} else {
$item = $list->getpart('headerremove');
$pagedata->setValue("Data.List.HeaderRemove", "$item");
}
# 'mimeremove' is ignored if 'mimekeep' exists (since ezmlm-idx v5)
if ((Mail::Ezmlm->get_version() >= 5.1) && (-e $list->thislist() . "/mimekeep")) {
$item = $list->getpart('mimekeep');
$pagedata->setValue("Data.List.MimeKeep", "$item");
} else {
$item = $list->getpart('mimeremove');
$pagedata->setValue("Data.List.MimeRemove", "$item");
}
if (Mail::Ezmlm->get_version() >= 5) {
$item = $list->getpart('copylines');
$pagedata->setValue("Data.List.CopyLines", "$item");
}
$item = $list->getpart('mimereject');
$pagedata->setValue("Data.List.MimeReject", "$item");
$item = $list->get_text_content('trailer');
@ -958,7 +1015,7 @@ sub set_pagedata4options {
unless ($state) {
# set default values
if ($i eq 0) {
$value = 'mainlist@' . $DEFAULT_HOST;
$value = 'mainlist@' . $MAIL_DOMAIN;
} elsif ($i eq 3) {
$value = 'from_address@domain.org';
} elsif ($i eq 4) {
@ -1000,14 +1057,15 @@ sub set_pagedata4options {
if (-e "$dir_of_list/trailer");
$pagedata->setValue("Data.List.Options.f" , 1)
if (-e "$dir_of_list/prefix");
$pagedata->setValue("Data.List.Options.x" , 1)
if ((-e "$dir_of_list/mimeremove") || (-e "$dir_of_list/mimereject"));
$pagedata->setValue("Data.List.Options.m" , 1)
if (-e "$dir_of_list/modpost");
$pagedata->setValue("Data.List.Options.s" , 1)
if (-e "$dir_of_list/modsub");
$pagedata->setValue("Data.List.Options.r" , 1)
if (-e "$dir_of_list/remote");
# the option 'x' is always off, as we use it for resetting - this
# should be easier to understand for users
$pagedata->setValue("Data.List.Options.x" , 0);
}
# ---------------------------------------------------------------------------
@ -1251,7 +1309,8 @@ sub untaint {
# Go through all the CGI input and make sure it is not tainted. Log any
# tainted data that we come accross ... See the perlsec(1) man page ...
$DEFAULT_HOST = $1 if $DEFAULT_HOST =~ /^([\w\d\.-]+)$/;
# maybe it was read from a file - so we should untaint it
$MAIL_DOMAIN = $1 if $MAIL_DOMAIN =~ /^([\w\d\.-]+)$/;
my (@params, $i, $param);
@params = $q->param;
@ -1343,7 +1402,7 @@ sub add_address {
if ($q->param('mailaddress_add') ne '') {
$address = $q->param('mailaddress_add');
$address .= $DEFAULT_HOST if ($q->param('mailaddress_add') =~ /\@$/);
$address .= $MAIL_DOMAIN if ($q->param('mailaddress_add') =~ /\@$/);
# untaint
if ($address =~ m/(\w[\w\.\!\#\$\%\&\'\`\*\+\-\/\=\?\^\{\|\}\~]*)@(\w[\-\w_\.]+)/) {
@ -1431,7 +1490,7 @@ sub set_pagedata4part_list {
if ($part eq 'mod') {
# do we store things in different directories?
my $config = $list->getconfig;
my $config = $list->getconfig();
# empty values represent default settings - everything else is considered as evil :)
my($postpath) = $config =~ m{-7\s*'([^']+)'};
my($subpath) = $config =~ m{-8\s*'([^']+)'};
@ -1552,7 +1611,19 @@ sub extract_options_from_params {
# parse the first part of the options string
while ($old_key =~ m/\w/) {
# scan the first part of the options string for lower case letters
if (defined($q->param('available_option_' . lc($old_key)))) {
if (lc($old_key) eq 'x') {
# the 'x' setting does not really represent the mimeremove
# ezmlm-idx is ugly: 'X' -> remove file / 'x' -> reset file to default
if (-e "$LIST_DIR/$listname/mimeremove") {
$options .= 'x';
# we have to delete 'mimeremove' if the 'x' checkbox was activated
# as ezmlm-make will only reset it, if the file does not exist
unlink("$LIST_DIR/$listname/mimeremove")
if (defined($q->param('option_x')));
} else {
$options .= 'X';
}
} elsif (defined($q->param('available_option_' . lc($old_key)))) {
my $form_var_name = "option_" . lc($old_key);
# this option was visible for the user
if (defined($q->param($form_var_name))) {
@ -1637,7 +1708,7 @@ sub gnupg_export_key {
my @all_keys = $list->get_public_keys();
my ($i, $key, $name);
for ($i = 0; $i < @all_keys; $i++) {
$name = $all_keys[$i]{name} if ($keyid == $all_keys[$i]{id});
$name = $all_keys[$i]{name} if ($keyid eq $all_keys[$i]{id});
}
if ($name) {
$name =~ s/\W+/_/g;
@ -1857,30 +1928,53 @@ sub update_config {
}
}
# update mimeremove
if (defined($q->param('mimeremove'))) {
if (defined($q->param('option_x'))) {
$list->setpart('mimeremove', $q->param('mimeremove'))
} else {
# ezmlm-make automatically removes this file
}
# update mimeremove/keep
if ($q->param('mimefilter_action') eq "remove") {
# the checkbox 'x' is only used for reset - so we may not write,
# if a reset was requested
$list->setpart('mimeremove', $q->param('mimefilter'))
unless (defined($q->param('option_x')));
# remove 'mimekeep' as it is dominating
my $keep_file = "$LIST_DIR/" . $q->param('list') . "/mimekeep";
unlink ($keep_file) if (-e $keep_file);
} elsif ($q->param('mimefilter_action') eq "keep") {
$list->setpart('mimekeep', $q->param('mimefilter'))
# it is not necessary to remove 'mimeremove' - see above
}
# update mimereject
if (defined($q->param('mimereject'))) {
if (defined($q->param('option_x'))) {
$list->setpart('mimereject', $q->param('mimereject'))
} else {
# ezmlm-make automatically removes this file
}
}
# update mimereject - we do not care for 'x'
$list->setpart('mimereject', $q->param('mimereject'))
if (defined($q->param('mimereject')));
# Update headeradd and headerremove if these options were visible
# Update headeradd if this option is visible
$list->setpart('headeradd', $q->param('headeradd'))
if (defined($q->param('headeradd')));
$list->setpart('headerremove', $q->param('headerremove'))
if (defined($q->param('headerremove')));
# update headerremove/keep
if ($q->param('headerfilter_action') eq "remove") {
$list->setpart('headerremove', $q->param('headerfilter'));
# remove 'headerkeep' as it is dominating
my $keep_file = "$LIST_DIR/" . $q->param('list') . "/headerkeep";
unlink ($keep_file) if (-e $keep_file);
} elsif ($q->param('headerfilter_action') eq "keep") {
$list->setpart('headerkeep', $q->param('headerfilter'))
# it is not necessary to remove 'headerremove' - see above
}
# 'copylines' setting (since ezmlm-idx v5)
if (defined($q->param('copylines'))) {
my $copylines;
$copylines = (defined($q->param('copylines'))) ?
$q->param('copylines') : 0;
if (defined($q->param('copylines_enabled')) && ($copylines)) {
$list->setpart('copylines', "$copylines");
} else {
my $copyfile = "$LIST_DIR/" . $q->param('list') . "/copylines";
unlink ($copyfile) if (-e $copyfile);
}
}
# 'msgsize' setting
if (defined($q->param('msgsize_max_value')) && defined($q->param('msgsize_min_value'))) {
my ($minsize, $maxsize);
$maxsize = (defined($q->param('msgsize_max_state'))) ?
@ -1978,6 +2072,24 @@ sub update_webusers {
# ------------------------------------------------------------------------
sub output_mime_examples {
# print an incomplete list of possible mime types (taken from ezmlm-idx 6.0)
my $example_file = "$TEMPLATE_DIR/mime_type_examples.txt";
print "Content-Type: text/plain\n\n";
if (open(MTF, "<$example_file")) {
while (<MTF>) {
print $_;
}
close MTF;
} else {
warn "Failed to open the example file ($example_file): $!\n";
print "Failed to open the example file ($example_file): $!\n";
}
}
# ------------------------------------------------------------------------
sub this_listaddress {
# Work out the address of this list ... Used often so put in its own subroutine ...
@ -2097,7 +2209,7 @@ sub get_available_interface_languages {
my (%languages, @files, $file);
opendir(DIR, $LANGUAGE_DIR)
or &fatal_error ("Language directory ($LANGUAGE_DIR) not accessible!");
or &fatal_error ("Language directory ($LANGUAGE_DIR) is not accessible!");
@files = sort grep { /.*\.hdf$/ } readdir(DIR);
close(DIR);
@ -2113,6 +2225,24 @@ sub get_available_interface_languages {
# ---------------------------------------------------------------------------
sub get_available_interfaces {
my (%interfaces, @files, $file);
opendir(DIR, "$TEMPLATE_DIR/ui")
or &fatal_error ("Interface directory ($TEMPLATE_DIR/ui) is not accessible!");
@files = sort grep { /.*\.hdf$/ } readdir(DIR);
close(DIR);
foreach $file (@files) {
substr($file, -4) = "";
$interfaces{$file} = $file;
}
return %interfaces;
}
# ---------------------------------------------------------------------------
sub check_interface_language {
my ($language) = @_;

View file

@ -25,6 +25,7 @@ Lang {
ListSelect = Auswahl einer Liste
Properties = Eigenschaften von
Language = Sprache
Interface = Interface
Help = Hilfe (extern)
SubscribeLog = Einschreibungen
DomainSelect = Choose a domain
@ -67,6 +68,7 @@ Lang {
SaveFile = Datei speichern
ResetFile = Angepassten Textbaustein verwerfen
LanguageSet = wählen
InterfaceSet = wählen
GnupgConvertToEncrypted = Wandle in eine verschlüsselte Liste um
GnupgConvertToPlain = Wandle in eine unverschlüsselte Liste um
DeletePublicKey = Öffentliche(n) Schlüssel löschen
@ -161,7 +163,7 @@ Lang {
t = Hänge eine Signatur an jede versandte Nachricht
u = Nur Einsendungen von AbonnentInnen werden akzeptiert (für moderierte Listen: akzeptiere alle Einsendungen von AbonnentInnen)
w = Entferne den Aufruf von ezmlm-warn aus den Verarbeitungsregeln (für sehr spezielle Konfigurationen)
x = Prüfe die MIME-Typen der Anhänge eingehender Nachrichten
x = Reset the list of to be stripped mime types to its default value
y = Fordere eine Bestätigung für jede eingesandte Nachricht an
gnupg_plain_without_key = Sende Nachrichten im Klartext an Empfänger ohne Schlüssel
gnupg_sign_messages = Signiere ausgehende Nachrichten mit dem Listenschlüssel
@ -184,10 +186,15 @@ Lang {
ListName = Name der Liste
ListAddress = Addresse der Liste
ListOptions = Grundlegende Einstellungen
AllowedToEdit = Nutzer, die diese Liste per Web-Interface konfigurieren dürfen:
HeaderRemove = zu entfernende Kopfzeilen
AllowedToEdit = Users allowed to edit this list via web interface
HeaderFiltering = Header filtering
HeaderRemove = strip these header lines
HeaderKeep = keep only these header lines
HeaderAdd = hinzuzufügende Kopfzeilen
MimeRemove = Nachrichtenbestandteile dieses Typs werden entfernt
MimeTypeExamples = Show some example mime types
MimeFiltering = Mime type filtering (for multipart mails)
MimeRemove = strip these from all messages
MimeKeep = keep only these in messages
MimeReject = Nachrichten, die einen der folgenden Datentypen enthalten, werden abgewiesen
EditFileInfo {
CommonTags = allgemeine Platzhalter
@ -228,6 +235,13 @@ Lang {
GnupgKeyExpires = Verfallsdatum (in Jahren)
Never = nie
NoDomainsAvailable = No domains are available.
CopyLinesEnabled = Add some lines of every original message to automatic replies
CopyLinesNumber = number of lines
Interfaces {
easy = basic
normal = default
expert = expert
}
}
Introduction {
ConfigAdmin = Fern-AdministratorInnen sind (per Voreinstellung) auch ModeratorInnen für die Einschreibung und für eingesandte Mails. Sie können berechtigt sein, per Mail Nutzer ein- und auszutragen, sowie Textbausteine zu verändern.

View file

@ -27,6 +27,7 @@ Lang {
ListSelect = Choose a list
Properties = Properties of
Language = Language
Interface = Interface
Help = Help (external)
SubscribeLog = Subscriber's log
DomainSelect = Choose a domain
@ -73,6 +74,7 @@ Lang {
SaveFile = Save file
ResetFile = Remove customized file
LanguageSet = select
InterfaceSet = select
GnupgConvertToEncrypted = Convert to an encrypted mailinglist
GnupgConvertToPlain = Convert to a plaintext mainlinglist
DeletePublicKey = Delete public key(s)
@ -175,7 +177,7 @@ Lang {
t = Add a trailing text to every message
u = Only subscribed users may post messages (for moderated lists: always accept subscribers' postings)
w = Remove the ezmlm-warn invocations from the list setup (rarely useful)
x = Remove or reject specific mime types in messages
x = Reset the list of to be stripped mime types to its default value
y = Request a confirmation mail for every posted message
gnupg_plain_without_key = Send plaintext to the subscribers which have no key
gnupg_sign_messages = Sign outgoing messages with the list's key
@ -202,10 +204,15 @@ Lang {
ListName = List Name
ListAddress = List Address
ListOptions = Basic List Options
AllowedToEdit = Users allowed to edit this list via web interface:
HeaderRemove = Headers to strip from every outgoing mail
AllowedToEdit = Users allowed to edit this list via web interface
HeaderFiltering = Header filtering
HeaderRemove = strip these header lines
HeaderKeep = keep only these header lines
HeaderAdd = Headers to add to all outgoing mail
MimeRemove = Mime types to strip from all outgoing mail
MimeTypeExamples = Show some example mime types
MimeFiltering = Mime type filtering (for multipart mails)
MimeRemove = strip these from all messages
MimeKeep = keep only these in messages
MimeReject = Messages containing any of these mime type will be rejected
EditFileInfo {
CommonTags = common tags
@ -245,6 +252,13 @@ Lang {
GnupgKeyExpires = Expiration time (years)
Never = never
NoDomainsAvailable = No domains are available.
CopyLinesEnabled = Add some lines of every original message to automatic replies
CopyLinesNumber = number of lines
Interfaces {
easy = basic
normal = default
expert = expert
}
}

View file

@ -7,6 +7,11 @@ Config.Title
Config.UI.Languages.[names]
Config.UI.LinkAttrs.web_lang
Config.UI.LinkAttrs.template
Config.Features.Crypto
Config.Features.KeepFiles
Config.Features.LanguageSelect
Config.Features.CharsetSelect
Config.Features.CopyLines
Data.Action
Data.areDefaultTextsAvailable

View file

@ -1,7 +1,9 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- charset -->
<?cs if:Data.List.CharSet ?>
<label for="list_charset"><?cs var:html_escape(Lang.Misc.ListCharset)
?>:</label>
<input type="text" name="list_charset" id="list_charset" size="30"
value="<?cs var:Data.List.CharSet ?>" /><?cs /if ?>
<?cs if:Config.Features.CharsetSelect ?>
<?cs if:Data.List.CharSet ?>
<label for="list_charset"><?cs var:html_escape(Lang.Misc.ListCharset)
?>:</label>
<input type="text" name="list_charset" id="list_charset" size="30"
value="<?cs var:Data.List.CharSet ?>" /><?cs /if ?>
<?cs /if ?>

View file

@ -0,0 +1,13 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- 'copylines' setting -->
<?cs if:Config.Features.CopyLines ?>
<input type="checkbox" name="copylines_enabled"
value="selected" id="copylines_enabled" <?cs
if:Data.List.CopyLines>0 ?>checked="checked"<?cs /if ?> />
<label for="copylines_enabled"><?cs
var:html_escape(Lang.Misc.CopyLinesEnabled) ?></label>
<ul><li><input type="text" name="copylines" size="10"
style="text-align:right" value="<?cs
alt:Data.List.CopyLines ?>0<?cs /alt ?>" /> <?cs
var:html_escape(Lang.Misc.CopyLinesNumber) ?></li></ul>
<?cs /if ?>

View file

@ -1,5 +1,5 @@
<label for="listaddress"><?cs var:html_escape(Lang.Misc.ListAddress) ?>:</label>
<input type="text" id="listaddress" name="inlocal" size="20"
value="<?cs var:html_escape(Data.UserName)
value="<?cs var:html_escape(Data.LocalPrefix)
?>"> @ <input type="text" name="inhost" size="30" value="<?cs
var:html_escape(Data.HostName) ?>"></li>

View file

@ -0,0 +1,31 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- headerfilter -->
<?cs if:Config.Features.KeepFiles ?>
<?cs var:html_escape(Lang.Misc.HeaderFiltering) ?>:
<ul>
<li><input type="radio" name="headerfilter_action" value="remove"
id="hf_remove"<?cs if:Data.List.HeaderRemove
?> checked="checked"<?cs /if ?> /><label for="hf_remove"><?cs
var:html_escape(Lang.Misc.HeaderRemove) ?></label></li>
<li><input type="radio" name="headerfilter_action" value="keep"
id="hf_keep"<?cs if:Data.List.HeaderKeep
?> checked="checked"<?cs /if ?> /><label for="hf_keep"><?cs
var:html_escape(Lang.Misc.HeaderKeep) ?></label></li>
<li>
<textarea name="headerfilter" rows="5" cols="70"><?cs
if Data.List.HeaderRemove ?><?cs
var:html_escape(Data.List.HeaderRemove) ?><?cs else ?><?cs
var:html_escape(Data.List.HeaderKeep) ?><?cs /if ?></textarea></li>
</ul>
<?cs else ?>
<?cs var:html_escape(Lang.Misc.HeaderFiltering) ?>:
<?cs var:html_escape(Lang.Misc.HeaderRemove) ?>
<input type="hidden" name="headerfilter_action" value="remove" />
<ul>
<li>
<textarea name="headerfilter" rows="5" cols="70"><?cs
if Data.List.HeaderRemove ?><?cs
var:html_escape(Data.List.HeaderRemove) ?><?cs else ?><?cs
var:html_escape(Data.List.HeaderKeep) ?><?cs /if ?></textarea></li>
</ul>
<?cs /if ?>

View file

@ -1,5 +0,0 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- headerremove -->
<?cs var:html_escape(Lang.Misc.HeaderRemove) ?>:<br/>
<ul><li><textarea name="headerremove" rows="5" cols="70"><?cs
var:html_escape(Data.List.HeaderRemove) ?></textarea></li></ul>

View file

@ -1,24 +1,25 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- list language -->
<?cs if:Data.Action != "list_create" ?>
<?cs if:subcount(Data.List.AvailableLanguages) > 0 ?>
<label for="list_language"><?cs var:html_escape(Lang.Misc.ListLanguage)
?>:</label>
<select name="list_language" id="list_language">
<?cs each:item = Data.List.AvailableLanguages ?>
<option <?cs if:(item == Data.List.Language)
?>selected="selected"<?cs /if ?>><?cs var:item ?></option>
<?cs /each ?>
</select><?cs /if ?>
<?cs else ?>
<?cs if:subcount(Data.AvailableLanguages) > 0 ?>
<label for="list_language"><?cs var:html_escape(Lang.Misc.ListLanguage)
?>:</label>
<select name="list_language" id="list_language">
<?cs each:item = Data.AvailableLanguages ?>
<option <?cs if:item == "default"
?>selected="selected"<?cs /if ?>><?cs var:item ?></option>
<?cs /each ?>
</select><?cs /if ?>
<?cs if:Config.Features.LanguageSelect ?>
<?cs if:Data.Action != "list_create" ?>
<?cs if:subcount(Data.List.AvailableLanguages) > 0 ?>
<label for="list_language"><?cs var:html_escape(Lang.Misc.ListLanguage)
?>:</label>
<select name="list_language" id="list_language">
<?cs each:item = Data.List.AvailableLanguages ?>
<option <?cs if:(item == Data.List.Language)
?>selected="selected"<?cs /if ?>><?cs var:item ?></option>
<?cs /each ?>
</select><?cs /if ?>
<?cs else ?>
<?cs if:subcount(Data.AvailableLanguages) > 0 ?>
<label for="list_language"><?cs var:html_escape(Lang.Misc.ListLanguage)
?>:</label>
<select name="list_language" id="list_language">
<?cs each:item = Data.AvailableLanguages ?>
<option <?cs if:item == "default"
?>selected="selected"<?cs /if ?>><?cs var:item ?></option>
<?cs /each ?>
</select><?cs /if ?>
<?cs /if ?>
<?cs /if ?>

View file

@ -1,9 +0,0 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- mimeremove and mimereject -->
<?cs call:checkbox("x") ?>
<?cs if:(Data.List.Options.x == 1) ?><ul>
<!-- turn off mimermove, if "-x" is not activated, as it will be
removed during the next config_update -->
<?cs call:display_option('mimereject') ?>
<?cs call:display_option('mimeremove') ?>
</ul><?cs /if ?>

View file

@ -1,3 +0,0 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- care for mime(reject|remove) -->
<?cs call:checkbox("x") ?>

View file

@ -0,0 +1,35 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<?cs if:Config.Features.KeepFiles ?>
<?cs var:html_escape(Lang.Misc.MimeFiltering) ?>:
<ul>
<li><input type="radio" name="mimefilter_action" value="remove"
id="mf_remove"<?cs if:Data.List.MimeRemove
?> checked="checked"<?cs /if ?> /><label for="mf_remove"><?cs
var:html_escape(Lang.Misc.MimeRemove) ?></label></li>
<li><input type="radio" name="mimefilter_action" value="keep"
id="mf_keep"<?cs if:Data.List.MimeKeep
?> checked="checked"<?cs /if ?> /><label for="mf_keep"><?cs
var:html_escape(Lang.Misc.MimeKeep) ?></label></li>
<li>
<textarea name="mimefilter" rows="5" cols="70"><?cs
if Data.List.MimeRemove ?><?cs var:html_escape(Data.List.MimeRemove)
?><?cs else ?><?cs var:html_escape(Data.List.MimeKeep)
?><?cs /if ?></textarea></li>
<li>(<a href="<?cs call:link('action','show_mime_examples','','','','')
?>" target="_blank"><?cs var:html_escape(Lang.Misc.MimeTypeExamples)
?></a>)</li>
</ul>
<?cs else ?>
<?cs var:html_escape(Lang.Misc.MimeFiltering) ?>:
<?cs var:html_escape(Lang.Misc.MimeRemove) ?>
<input type="hidden" name="mimefilter_action" value="remove" />
<ul><li>
<textarea name="mimefilter" rows="5" cols="70"><?cs
if Data.List.MimeRemove ?><?cs var:html_escape(Data.List.MimeRemove)
?><?cs else ?><?cs var:html_escape(Data.List.MimeKeep)
?><?cs /if ?></textarea></li>
</ul>
<?cs /if ?>
<?cs # uncomment the following to enable the 'reset' feature
but that would mess up the interface, right? ?>
<?cs # call:checkbox("x") ?>

View file

@ -1,8 +1,7 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<?cs if:Data.List.Options.x == 1 ?>
<!-- turn off mimermove, if "-x" is not activated, as it will be
removed during the next config_update -->
<?cs var:html_escape(Lang.Misc.MimeReject) ?>:<br/>
<textarea name="mimereject" rows="4" cols="70"><?cs
<?cs var:html_escape(Lang.Misc.MimeReject) ?>:
<ul>
<li><textarea name="mimereject" rows="4" cols="70"><?cs
var:html_escape(Data.List.MimeReject) ?></textarea>
<?cs /if ?>
</li>
</ul>

View file

@ -1,8 +0,0 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<?cs if:Data.List.Options.x == 1 ?>
<!-- turn off mimermove, if "-x" is not activated, as it will be
removed during the next config_update -->
<?cs var:html_escape(Lang.Misc.MimeRemove) ?>:<br/>
<textarea name="mimeremove" rows="4" cols="70"><?cs
var:html_escape(Data.List.MimeRemove) ?></textarea>
<?cs /if ?>

View file

@ -1,6 +1,6 @@
<!-- REMOVE --><?cs include:TemplateDir + '/macros.cs' ?>
<!-- ezmlm-web administators -->
<?cs var:html_escape(Lang.Misc.AllowedToEdit) ?>
<?cs var:html_escape(Lang.Misc.AllowedToEdit) ?>:
<ul><li><input type="text"
name="webusers" value="<?cs if:Data.List.WebUsers
?><?cs var:html_escape(Data.List.WebUsers) ?><?cs

View file

@ -0,0 +1,21 @@
<!-- allows the user to change the interface language (not of the list!) -->
<?cs if:subcount(Config.UI.Interfaces) > 0 ?>
<?cs call:form_header("select_interface", "template") ?>
<?cs if:Data.List.Name ?><input type="hidden" name="action"
value="subscribers" /><?cs /if ?>
<font class="no_link"><?cs
var:html_escape(Lang.Menue.Interface) ?>:</font><br/>
<select name="template" size="0">
<?cs each: ttemp = Config.UI.Interfaces
?><option value="<?cs var:name(ttemp) ?>"<?cs
if:name(ttemp) == Config.UI.LinkAttrs.template
?> selected="selected"<?cs /if?>><?cs
var:html_escape(Lang.Misc.Interfaces[ttemp]) ?></option>
<?cs /each ?>
</select>&nbsp;<button type="submit" name="send" value="do"><?cs var:html_escape(Lang.Buttons.InterfaceSet) ?></button>
</form>
<?cs /if ?>

View file

@ -22,7 +22,7 @@ def:setting(setting)
?>" id="setting_value_<?cs var:setting ?>" value="<?cs
var:html_escape(Data.List.Settings[setting].value) ?>" size="30" /></li></ul>
<input type="hidden" name="available_setting_<?cs
var:setting ?>" value="true"><?cs
var:setting ?>" value="true" /><?cs
else ?>unknown setting (<?cs var:setting ?>)<?cs /if ?><?cs
/def ?><?cs

View file

@ -0,0 +1,83 @@
application/excel
application/rtf
application/msword
application/ms-tnef
text/html
text/rtf
text/enriched
text/x-vcard
application/activemessage
application/andrew-inset
application/applefile
application/atomicmail
application/dca-rft
application/dec-dx
application/mac-binhex40
application/mac-compactpro
application/macwriteii
application/news-message-id
application/news-transmission
application/octet-stream
application/oda
application/pdf
application/postscript
application/powerpoint
application/remote-printing
application/slate
application/wita
application/wordperfect5.1
application/x-bcpio
application/x-cdlink
application/x-compress
application/x-cpio
application/x-csh
application/x-director
application/x-dvi
application/x-hdf
application/x-httpd-cgi
application/x-koan
application/x-latex
application/x-mif
application/x-netcdf
application/x-stuffit
application/x-sv4cpio
application/x-sv4crc
application/x-tar
application/x-tcl
application/x-tex
application/x-texinfo
application/x-troff
application/x-troff-man
application/x-troff-me
application/x-troff-ms
application/x-ustar
application/x-wais-source
audio/basic
audio/mpeg
audio/x-aiff
audio/x-pn-realaudio
audio/x-pn-realaudio
audio/x-pn-realaudio-plugin
audio/x-realaudio
audio/x-wav
image/gif
image/ief
image/jpeg
image/png
image/tiff
image/x-cmu-raster
image/x-portable-anymap
image/x-portable-bitmap
image/x-portable-graymap
image/x-portable-pixmap
image/x-rgb
image/x-xbitmap
image/x-xpixmap
image/x-xwindowdump
text/x-sgml
video/mpeg
video/quicktime
video/x-msvideo
video/x-sgi-movie
x-conference/x-cooltalk
x-world/x-vrml

View file

@ -166,14 +166,15 @@
var:html_escape(Lang.Menue.TextFiles) ?></a></li><?cs /if ?>
<?cs if:(UI.Navigation.GnupgConvert == 1) && Config.Features.Crypto
?><li><a <?cs if:(Data.Action == "gnupg_convert_ask") ||
(Data.Action == "gnupg_convert_do") ?> class="nav_active"<?cs /if ?>
?><li><a <?cs if:(Data.Action == "gnupg_convert")
?> class="nav_active"<?cs /if ?>
href="<?cs call:link("list",Data.List.Name,"action","gnupg_convert_ask","","") ?>"
title="<?cs var:html_escape(Lang.Menue.GnupgConvert) ?>"><?cs
var:html_escape(Lang.Menue.GnupgConvert) ?></a></li><?cs /if ?>
<?cs if:UI.Navigation.SubscribeLog == 1
?><li><a <?cs if:(Data.Action == "subscribe_log") ?> class="nav_active"<?cs /if ?>
?><li><a <?cs if:(Data.Action == "show_subscription_log")
?> class="nav_active"<?cs /if ?>
href="<?cs call:link("list",Data.List.Name,"action","subscribe_log","","") ?>"
title="<?cs var:html_escape(Lang.Menue.SubscribeLog) ?>"><?cs
var:html_escape(Lang.Menue.SubscribeLog) ?></a></li><?cs /if ?>
@ -188,8 +189,13 @@
<li><hr/></li>
<?cs /if ?>
<?cs if:UI.Navigation.Language
?><li><?cs include:TemplateDir + '/language_select.cs' ?></li>
<?cs if:UI.Navigation.Language || UI.Navigation.Interface ?>
<?cs if:UI.Navigation.Language ?>
<li><?cs include:TemplateDir + '/language_select.cs' ?></li>
<?cs /if ?>
<?cs if:UI.Navigation.Interface ?>
<li><?cs include:TemplateDir + '/interface_select.cs' ?></li>
<?cs /if ?>
<li><hr/></li>

83
template/ui/easy.hdf Normal file
View file

@ -0,0 +1,83 @@
UI {
Navigation {
DomainSelect = 1
ListSelect = 1
ListCreate = 1
Subscribers {
Subscribers = 1
Allow = 1
}
Config {
Main = 1
Subscription = 1
Posting = 1
Processing = 1
}
Gnupg {
PublicKeys = 1
SecretKeys = 1
GenerateKey = 1
}
TextEdit = 1
ListDelete = 1
SubscribeLog = 1
GnupgConvert = 1
Language = 1
Interface = 1
Help = 1
}
Options {
Create {
Listname = create_listname
Listaddress = create_listaddress
Listlanguage = lang_select
Webuser = webusers
}
Subscribers {
Subscribers = {}
}
GenerateKey {
KeyName = gnupg_keyname
KeyComment = gnupg_keycomment
}
Config {
Main {
Language = lang_select
Owner = owner_address
WebUsers = webusers
}
Subscription {
Public = public
ConfirmSub = confirm_sub
ConfirmUnsub = confirm_unsub
}
Posting {
BlockOthers = block_others_post
SizeMax = msgsize_max
}
Processing {
Prefix = prefix
Trailer = trailer
From = from_address
}
}
}
}

204
template/ui/expert.hdf Normal file
View file

@ -0,0 +1,204 @@
UI {
Navigation {
DomainSelect = 1
ListSelect = 1
ListCreate = 1
Subscribers {
Subscribers = 1
Digest = 1
Allow = 1
Deny = 1
Moderators = 1
}
Config {
Main = 1
Subscription = 1
Posting = 1
Processing = 1
GnupgOptions = 1
Archive = 1
Admin = 1
All = 1
}
Gnupg {
PublicKeys = 1
SecretKeys = 1
GenerateKey = 1
}
TextEdit = 1
ListDelete = 1
SubscribeLog = 1
GnupgConvert = 1
Language = 1
Interface = 1
Help = 1
}
Options {
Create {
Listname = create_listname
Listaddress = create_listaddress
Listlanguage = lang_select
Mysql = mysql
Webuser = webusers
}
Subscribers {
Subscribers = {}
Digest {
Enabled = digest_enabled
Settings = digest_settings
}
Deny {
Enabled = block_deny
}
Moderators {
Posting {
Self = mod_post
Path = mod_post_path
}
Subscription {
Self = mod_sub
Path = mod_sub_path
}
Administration {
Self = admin_enabled
Path = admin_path
}
}
}
GenerateKey {
KeyName = gnupg_keyname
KeyComment = gnupg_keycomment
KeySize = gnupg_keysize
KeyExpiration = gnupg_keyexpires
}
Config {
Main {
Language = lang_select
Charset = charset_select
Owner = owner_address
MainList = mainlist
MailmanRequests = mailman_requests
RemoveWarn = warn_remove
SQL = mysql
WebUsers = webusers
}
Archive {
Enabled {
Self = archive_enabled
Public = public
ModOnly = archive_mod_only
Guard = archive_deny_unknown
}
RemovePrivateHeader = archive_remove_private_header
}
Subscription {
Public = public
ConfirmSub = confirm_sub
ConfirmUnsub = confirm_unsub
ModSub {
Self = mod_sub
Path = mod_sub_path
}
}
Admin {
Enabled {
Self = admin_enabled
RequestSubscribers = admin_get_subscribers
EditText = admin_edit_text
Path = admin_path
}
}
Posting {
UseDeny = block_deny
BlockOthers = block_others_post
Confirm = confirm_post
Moderate {
Self = mod_post
NonMod = block_nonmod_post
Path = mod_post_path
}
SizeMax = msgsize_max
SizeMin = msgsize_min
MimeReject = mimereject
}
GnupgOptions {
SignMessages = gnupg_sign_messages
PlainWithoutKey = gnupg_plain_without_key
}
Processing {
Prefix = prefix
Trailer = trailer
From = from_address
MimeFilter = mimefilter
HeaderFilter = headerfilter
HeaderAdd = headeradd
CopyLines = copylines
}
Overview {
Public = public
ConfirmSub = confirm_sub
ConfirmUnsub = confirm_unsub
ModSubEnable = mod_sub
UseDeny = block_deny
BlockOthers = block_others_post
ConfirmPosting = confirm_post
ModPosting = mod_post
NonModPosting = block_nonmod_post
MailmanRequests = mailman_requests
RemoveWarn = warn_remove
DigestEnabled = digest_enabled
DigestSettings = digest_settings
ArchiveEnabled = archive_enabled
ArchiveModOnly = archive_mod_only
ArchiveGuard = archive_deny_unknown
RemovePrivateHeader = archive_remove_private_header
AdminEnabled = admin_enabled
AdminRequestSubscribers = admin_get_subscribers
AdminEditText = admin_edit_text
FromAddress = from_address
Owner = owner_address
SQL = mysql
MainList = mainlist
ModPostPath = mod_post_path
ModSubPath = mod_sub_path
AdminPath = admin_path
Prefix = prefix
Trailer = trailer
SizeMax = msgsize_max
SizeMin = msgsize_min
MimeFilter = mimefilter
MimeReject = mimereject
HeaderFilter = headerfilter
HeaderAdd = headeradd
CopyLines = copylines
Language = lang_select
Charset = charset_select
WebUsers = webusers
}
}
}
}

View file

@ -20,7 +20,6 @@ UI {
GnupgOptions = 1
Archive = 1
Admin = 1
All = 1
}
Gnupg {
@ -45,7 +44,6 @@ UI {
Listname = create_listname
Listaddress = create_listaddress
Listlanguage = lang_select
Mysql = mysql
Webuser = webusers
}
@ -54,7 +52,6 @@ UI {
Subscribers = {}
Digest {
Enabled = digest_enabled
Settings = digest_settings
}
Deny {
@ -64,15 +61,12 @@ UI {
Moderators {
Posting {
Self = mod_post
Path = mod_post_path
}
Subscription {
Self = mod_sub
Path = mod_sub_path
}
Administration {
Self = admin_enabled
Path = admin_path
}
}
}
@ -90,9 +84,6 @@ UI {
Charset = charset_select
Owner = owner_address
MainList = mainlist
MailmanRequests = mailman_requests
RemoveWarn = warn_remove
SQL = mysql
WebUsers = webusers
}
@ -112,7 +103,6 @@ UI {
ConfirmUnsub = confirm_unsub
ModSub {
Self = mod_sub
Path = mod_sub_path
}
}
@ -121,7 +111,6 @@ UI {
Self = admin_enabled
RequestSubscribers = admin_get_subscribers
EditText = admin_edit_text
Path = admin_path
}
}
@ -132,14 +121,10 @@ UI {
Moderate {
Self = mod_post
NonMod = block_nonmod_post
Path = mod_post_path
}
SizeMax = msgsize_max
SizeMin = msgsize_min
MimeCheck {
Self = mimecheck
MimeReject = mimereject
}
MimeReject = mimereject
}
GnupgOptions {
@ -151,58 +136,11 @@ UI {
Prefix = prefix
Trailer = trailer
From = from_address
MimeCheck {
Self = mimecheck
MimeRemove = mimeremove
}
HeaderRemove = headerremove
MimeFilter = mimefilter
HeaderFilter = headerfilter
HeaderAdd = headeradd
}
Overview {
Public = public
ConfirmSub = confirm_sub
ConfirmUnsub = confirm_unsub
ModSubEnable = mod_sub
UseDeny = block_deny
BlockOthers = block_others_post
ConfirmPosting = confirm_post
ModPosting = mod_post
NonModPosting = block_nonmod_post
MailmanRequests = mailman_requests
RemoveWarn = warn_remove
DigestEnabled = digest_enabled
DigestSettings = digest_settings
ArchiveEnabled = archive_enabled
ArchiveModOnly = archive_mod_only
ArchiveGuard = archive_deny_unknown
RemovePrivateHeader = archive_remove_private_header
AdminEnabled = admin_enabled
AdminRequestSubscribers = admin_get_subscribers
AdminEditText = admin_edit_text
FromAddress = from_address
Owner = owner_address
SQL = mysql
MainList = mainlist
ModPostPath = mod_post_path
ModSubPath = mod_sub_path
AdminPath = admin_path
Prefix = prefix
Trailer = trailer
SizeMax = msgsize_max
SizeMin = msgsize_min
MimeCheck {
Self = mimecheck
MimeRemove = mimeremove
MimeReject = mimereject
}
HeaderRemove = headerremove
HeaderAdd = headeradd
Language = lang_select
Charset = charset_select
WebUsers = webusers
}
}
}

View file

@ -56,12 +56,12 @@ font.feature {
}
#nav_bar ul li {
margin-top: 0;
margin-top: 0px;
/* small space between highest level entries */
margin-bottom: 5px;
}
v_bar ul li ul {
#nav_bar ul li ul {
/* small space between middle level entries */
margin-bottom: 4px;
}
@ -138,10 +138,20 @@ v_bar ul li ul {
list-style: none;
}
#main_content ul li {
padding-top: 2px;
padding-bottom: 2px;
}
#main_content ul li ul {
font-size: 85%;
}
#main_content ul li ul li {
padding-top: 0px;
padding-bottom: 0px;
}
#main_content fieldset {
margin-top: 0.5%;
margin-bottom: 1%;