From 9d0e8730e0480b765e3dec6ce5c15b938b44f485 Mon Sep 17 00:00:00 2001 From: lars Date: Tue, 3 Apr 2007 15:49:24 +0000 Subject: [PATCH] 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, ...) --- TODO | 8 +- changelog | 4 +- examples/ezmlmwebrc.dist | 1 + ezmlm-web.cgi | 262 +++++++++++++----- lang/de.hdf | 22 +- lang/en.hdf | 22 +- spec/hdf-spec.txt | 5 + template/config_options/charset_select.cs | 12 +- template/config_options/copylines.cs | 13 + template/config_options/create_listaddress.cs | 2 +- template/config_options/headerfilter.cs | 31 +++ template/config_options/headerremove.cs | 5 - template/config_options/lang_select.cs | 43 +-- template/config_options/mime_both.cs | 9 - template/config_options/mimecheck.cs | 3 - template/config_options/mimefilter.cs | 35 +++ template/config_options/mimereject.cs | 11 +- template/config_options/mimeremove.cs | 8 - template/config_options/webusers.cs | 2 +- template/interface_select.cs | 21 ++ template/macros.cs | 2 +- template/mime_type_examples.txt | 83 ++++++ template/nav.cs | 16 +- template/ui/easy.hdf | 83 ++++++ template/ui/expert.hdf | 204 ++++++++++++++ template/ui/normal.hdf | 68 +---- www-data/default.css | 14 +- 27 files changed, 776 insertions(+), 213 deletions(-) create mode 100644 template/config_options/copylines.cs create mode 100644 template/config_options/headerfilter.cs delete mode 100644 template/config_options/headerremove.cs delete mode 100644 template/config_options/mime_both.cs delete mode 100644 template/config_options/mimecheck.cs create mode 100644 template/config_options/mimefilter.cs delete mode 100644 template/config_options/mimeremove.cs create mode 100644 template/interface_select.cs create mode 100644 template/mime_type_examples.txt create mode 100644 template/ui/easy.hdf create mode 100644 template/ui/expert.hdf diff --git a/TODO b/TODO index 95d68b3..f342e42 100644 --- a/TODO +++ b/TODO @@ -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) - diff --git a/changelog b/changelog index 4b07433..228f4cf 100644 --- a/changelog +++ b/changelog @@ -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 diff --git a/examples/ezmlmwebrc.dist b/examples/ezmlmwebrc.dist index 702066e..09c64b3 100644 --- a/examples/ezmlmwebrc.dist +++ b/examples/ezmlmwebrc.dist @@ -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) diff --git a/ezmlm-web.cgi b/ezmlm-web.cgi index 47df7fb..1025a1c 100755 --- a/ezmlm-web.cgi +++ b/ezmlm-web.cgi @@ -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 = ); - 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() { + 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 = ); + 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() { - 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 () { + 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) = @_; diff --git a/lang/de.hdf b/lang/de.hdf index b109418..62251a5 100644 --- a/lang/de.hdf +++ b/lang/de.hdf @@ -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. diff --git a/lang/en.hdf b/lang/en.hdf index 01bfb25..d4e2816 100644 --- a/lang/en.hdf +++ b/lang/en.hdf @@ -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 + } } diff --git a/spec/hdf-spec.txt b/spec/hdf-spec.txt index 977f069..8dad364 100644 --- a/spec/hdf-spec.txt +++ b/spec/hdf-spec.txt @@ -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 diff --git a/template/config_options/charset_select.cs b/template/config_options/charset_select.cs index 3343a13..1d0a1ce 100644 --- a/template/config_options/charset_select.cs +++ b/template/config_options/charset_select.cs @@ -1,7 +1,9 @@ - - - + + + + + diff --git a/template/config_options/copylines.cs b/template/config_options/copylines.cs new file mode 100644 index 0000000..08d93f5 --- /dev/null +++ b/template/config_options/copylines.cs @@ -0,0 +1,13 @@ + + + + 0 ?>checked="checked" /> + +
+ diff --git a/template/config_options/create_listaddress.cs b/template/config_options/create_listaddress.cs index eee4b84..8f87e90 100644 --- a/template/config_options/create_listaddress.cs +++ b/template/config_options/create_listaddress.cs @@ -1,5 +1,5 @@ "> @ diff --git a/template/config_options/headerfilter.cs b/template/config_options/headerfilter.cs new file mode 100644 index 0000000..3d0d0da --- /dev/null +++ b/template/config_options/headerfilter.cs @@ -0,0 +1,31 @@ + + + + : +
    +
  • checked="checked" />
  • +
  • checked="checked" />
  • +
  • +
  • +
+ + : + + +
    +
  • +
  • +
+ diff --git a/template/config_options/headerremove.cs b/template/config_options/headerremove.cs deleted file mode 100644 index 9673ddc..0000000 --- a/template/config_options/headerremove.cs +++ /dev/null @@ -1,5 +0,0 @@ - - -:
-
diff --git a/template/config_options/lang_select.cs b/template/config_options/lang_select.cs index 5f5ea15..eec83d1 100644 --- a/template/config_options/lang_select.cs +++ b/template/config_options/lang_select.cs @@ -1,24 +1,25 @@ - - 0 ?> - - - - 0 ?> - - + + + 0 ?> + + + + 0 ?> + + + - diff --git a/template/config_options/mime_both.cs b/template/config_options/mime_both.cs deleted file mode 100644 index 5446b3c..0000000 --- a/template/config_options/mime_both.cs +++ /dev/null @@ -1,9 +0,0 @@ - - - -
    - - - -
diff --git a/template/config_options/mimecheck.cs b/template/config_options/mimecheck.cs deleted file mode 100644 index 614750c..0000000 --- a/template/config_options/mimecheck.cs +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/template/config_options/mimefilter.cs b/template/config_options/mimefilter.cs new file mode 100644 index 0000000..6875175 --- /dev/null +++ b/template/config_options/mimefilter.cs @@ -0,0 +1,35 @@ + + + : +
    +
  • checked="checked" />
  • +
  • checked="checked" />
  • +
  • +
  • +
  • ()
  • +
+ + : + + +
  • +
  • +
+ + + diff --git a/template/config_options/mimereject.cs b/template/config_options/mimereject.cs index 0c51ff4..2172c1a 100644 --- a/template/config_options/mimereject.cs +++ b/template/config_options/mimereject.cs @@ -1,8 +1,7 @@ - - - :
- - + + diff --git a/template/config_options/mimeremove.cs b/template/config_options/mimeremove.cs deleted file mode 100644 index 3ff2ce0..0000000 --- a/template/config_options/mimeremove.cs +++ /dev/null @@ -1,8 +0,0 @@ - - - - :
- - diff --git a/template/config_options/webusers.cs b/template/config_options/webusers.cs index 38ebdb6..826f388 100644 --- a/template/config_options/webusers.cs +++ b/template/config_options/webusers.cs @@ -1,6 +1,6 @@ - +:
  • + + + + :
    +   + + + diff --git a/template/macros.cs b/template/macros.cs index 92604e8..4f961af 100644 --- a/template/macros.cs +++ b/template/macros.cs @@ -22,7 +22,7 @@ def:setting(setting) ?>" id="setting_value_" value="" size="30" />
" value="true" />unknown setting ()
  • class="nav_active" + ?>
  • class="nav_active" href="" title="">
  • class="nav_active" + ?>
  • class="nav_active" href="" title="">
  • @@ -188,8 +189,13 @@

  • -
  • + + +
  • + + +
  • +

  • diff --git a/template/ui/easy.hdf b/template/ui/easy.hdf new file mode 100644 index 0000000..3cc28ea --- /dev/null +++ b/template/ui/easy.hdf @@ -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 + } + + } + + } + + } + diff --git a/template/ui/expert.hdf b/template/ui/expert.hdf new file mode 100644 index 0000000..3ed7e8e --- /dev/null +++ b/template/ui/expert.hdf @@ -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 + + } + } + + } + + } + diff --git a/template/ui/normal.hdf b/template/ui/normal.hdf index 8cbfadf..8083a50 100644 --- a/template/ui/normal.hdf +++ b/template/ui/normal.hdf @@ -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 - - } } } diff --git a/www-data/default.css b/www-data/default.css index 0cd8c64..9e87ceb 100644 --- a/www-data/default.css +++ b/www-data/default.css @@ -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%;