From fec57c6d3971784dc87deea5df5d892d2c6b14a2 Mon Sep 17 00:00:00 2001 From: lars Date: Sat, 21 May 2005 00:48:36 +0000 Subject: [PATCH] ezmlm-web und web-splash ausgelagert --- ezmlm-web/README | 14 - ezmlm-web/contrib-patches/README | 27 - .../done/ezmlm-web-andrew-pam-20030520.txt | 422 ----- .../ignored/ezmlm-pm-jon-coulter-20040312.txt | 79 - .../ezmlm-pm-lars-braeuer-20040305.txt | 52 - .../ezmlm-pm-matt-simerson-20041115.txt | 54 - .../ignored/ezmlm-pm-scott-beck-20041009.txt | 193 -- .../ignored/ezmlm-web-andrew-pam-20040526.txt | 67 - .../ezmlm-web-gordon-rowell-20011024.txt | 67 - .../ezmlm-web-jose-celestino-20020208.txt | 1572 ----------------- ezmlm-web/tags/ezmlm-web-2.1.tar.gz | Bin 23315 -> 0 bytes ezmlm-web/tags/ezmlm-web-2.1/CHANGES | 84 - ezmlm-web/tags/ezmlm-web-2.1/README | 323 ---- ezmlm-web/tags/ezmlm-web-2.1/TODO | 8 - ezmlm-web/tags/ezmlm-web-2.1/UPGRADING | 18 - ezmlm-web/tags/ezmlm-web-2.1/ezmlm-web.cgi | 1084 ------------ ezmlm-web/tags/ezmlm-web-2.1/ezmlmwebrc | 268 --- ezmlm-web/tags/ezmlm-web-2.1/htaccess.sample | 9 - ezmlm-web/tags/ezmlm-web-2.1/index.c | 25 - ezmlm-web/tags/ezmlm-web-2.1/webusers.sample | 4 - ezmlm-web/tags/ezmlm-web-2.2.tar.gz | Bin 27494 -> 0 bytes ezmlm-web/tags/ezmlm-web-2.2/CHANGES | 91 - ezmlm-web/tags/ezmlm-web-2.2/INSTALL | 97 - ezmlm-web/tags/ezmlm-web-2.2/README | 270 --- ezmlm-web/tags/ezmlm-web-2.2/TODO | 8 - ezmlm-web/tags/ezmlm-web-2.2/UPGRADING | 39 - ezmlm-web/tags/ezmlm-web-2.2/ezmlm-web.cgi | 1131 ------------ ezmlm-web/tags/ezmlm-web-2.2/ezmlmwebrc | 85 - ezmlm-web/tags/ezmlm-web-2.2/htaccess.sample | 9 - ezmlm-web/tags/ezmlm-web-2.2/index.c | 25 - ezmlm-web/tags/ezmlm-web-2.2/lang/de.pm | 187 -- ezmlm-web/tags/ezmlm-web-2.2/lang/en.pm | 187 -- ezmlm-web/tags/ezmlm-web-2.2/webusers.sample | 5 - ezmlm-web/trunk/CHANGES | 99 -- ezmlm-web/trunk/INSTALL | 97 - ezmlm-web/trunk/README | 270 --- ezmlm-web/trunk/TODO | 27 - ezmlm-web/trunk/UPGRADING | 39 - ezmlm-web/trunk/css/default.css | 202 --- ezmlm-web/trunk/ezmlm-web.cgi | 1251 ------------- ezmlm-web/trunk/ezmlmwebrc | 80 - ezmlm-web/trunk/htaccess.sample | 9 - ezmlm-web/trunk/index.c | 25 - ezmlm-web/trunk/lang/de.pm | 187 -- ezmlm-web/trunk/lang/en.pm | 187 -- ezmlm-web/trunk/webusers.sample | 5 - ezmlm-web/website/ezmlm-web.css | 186 -- ezmlm-web/website/index.html | 197 --- web-splash/BUILDING | 31 - web-splash/CHANGELOG | 13 - web-splash/README | 118 -- web-splash/TODO | 2 - web-splash/ipkg/conffiles | 1 - web-splash/ipkg/control | 23 - web-splash/ipkg/postinst | 10 - web-splash/ipkg/postrm | 7 - web-splash/ipkg/preinst | 7 - web-splash/ipkg/prerm | 4 - web-splash/ipkg/rules | 37 - web-splash/splash-site/index.html | 21 - web-splash/splash-site/splash-info.html | 13 - web-splash/web-splash-functions.inc | 129 -- web-splash/web-splash.cgi | 16 - web-splash/web-splash.conf | 49 - web-splash/web-splash.sh | 56 - 65 files changed, 9902 deletions(-) delete mode 100644 ezmlm-web/README delete mode 100644 ezmlm-web/contrib-patches/README delete mode 100644 ezmlm-web/contrib-patches/done/ezmlm-web-andrew-pam-20030520.txt delete mode 100644 ezmlm-web/contrib-patches/ignored/ezmlm-pm-jon-coulter-20040312.txt delete mode 100644 ezmlm-web/contrib-patches/ignored/ezmlm-pm-lars-braeuer-20040305.txt delete mode 100644 ezmlm-web/contrib-patches/ignored/ezmlm-pm-matt-simerson-20041115.txt delete mode 100644 ezmlm-web/contrib-patches/ignored/ezmlm-pm-scott-beck-20041009.txt delete mode 100644 ezmlm-web/contrib-patches/ignored/ezmlm-web-andrew-pam-20040526.txt delete mode 100644 ezmlm-web/contrib-patches/ignored/ezmlm-web-gordon-rowell-20011024.txt delete mode 100644 ezmlm-web/contrib-patches/open/ezmlm-web-jose-celestino-20020208.txt delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1.tar.gz delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/CHANGES delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/README delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/TODO delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/UPGRADING delete mode 100755 ezmlm-web/tags/ezmlm-web-2.1/ezmlm-web.cgi delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/ezmlmwebrc delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/htaccess.sample delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/index.c delete mode 100644 ezmlm-web/tags/ezmlm-web-2.1/webusers.sample delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2.tar.gz delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/CHANGES delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/INSTALL delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/README delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/TODO delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/UPGRADING delete mode 100755 ezmlm-web/tags/ezmlm-web-2.2/ezmlm-web.cgi delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/ezmlmwebrc delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/htaccess.sample delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/index.c delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/lang/de.pm delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/lang/en.pm delete mode 100644 ezmlm-web/tags/ezmlm-web-2.2/webusers.sample delete mode 100644 ezmlm-web/trunk/CHANGES delete mode 100644 ezmlm-web/trunk/INSTALL delete mode 100644 ezmlm-web/trunk/README delete mode 100644 ezmlm-web/trunk/TODO delete mode 100644 ezmlm-web/trunk/UPGRADING delete mode 100644 ezmlm-web/trunk/css/default.css delete mode 100755 ezmlm-web/trunk/ezmlm-web.cgi delete mode 100644 ezmlm-web/trunk/ezmlmwebrc delete mode 100644 ezmlm-web/trunk/htaccess.sample delete mode 100644 ezmlm-web/trunk/index.c delete mode 100644 ezmlm-web/trunk/lang/de.pm delete mode 100644 ezmlm-web/trunk/lang/en.pm delete mode 100644 ezmlm-web/trunk/webusers.sample delete mode 100644 ezmlm-web/website/ezmlm-web.css delete mode 100644 ezmlm-web/website/index.html delete mode 100644 web-splash/BUILDING delete mode 100644 web-splash/CHANGELOG delete mode 100644 web-splash/README delete mode 100644 web-splash/TODO delete mode 100644 web-splash/ipkg/conffiles delete mode 100644 web-splash/ipkg/control delete mode 100755 web-splash/ipkg/postinst delete mode 100755 web-splash/ipkg/postrm delete mode 100755 web-splash/ipkg/preinst delete mode 100755 web-splash/ipkg/prerm delete mode 100755 web-splash/ipkg/rules delete mode 100644 web-splash/splash-site/index.html delete mode 100644 web-splash/splash-site/splash-info.html delete mode 100644 web-splash/web-splash-functions.inc delete mode 100755 web-splash/web-splash.cgi delete mode 100644 web-splash/web-splash.conf delete mode 100755 web-splash/web-splash.sh diff --git a/ezmlm-web/README b/ezmlm-web/README deleted file mode 100644 index 5642618..0000000 --- a/ezmlm-web/README +++ /dev/null @@ -1,14 +0,0 @@ -This repository contains the development code of ezmlm-web - -* trunk - the development area -* tags - released versions since 2.1 -* website - the website for https://systemausfall.org/toolforge/ezmlm-web -* contrib-patches - incoming patches from users (including the ones, that were sent to Guy) - -the website of ezmlm-web can be found at: -https://systemausfall.org/toolforge/ezmlm-web - -the original website of ezmlm-web's creator Guy Antony Halse is available at: -http://rucus.ru.ac.za/~guy/ezmlm/ - -send questions and recommondations to ezmlm-web@sumpfralle.de diff --git a/ezmlm-web/contrib-patches/README b/ezmlm-web/contrib-patches/README deleted file mode 100644 index 847a42f..0000000 --- a/ezmlm-web/contrib-patches/README +++ /dev/null @@ -1,27 +0,0 @@ -Source of most patches: -http://rucus.ru.ac.za/~guy/ezmlm/contrib/ - -all ezmlm-pm-patchs refer to Mail::Ezmlm -> ignored - -1) ezmlm-web-andrew-pam-20030520.txt - - tooltip texts -> this is already fixed - - xhtml-tags in lowercase -> fixed in rev 26 - -2) ezmlm-web-andrew-pam-20040526.txt - - untaint mail-adresses -> better suited for Mail::Ezmlm -> ignored - -3) ezmlm-web-gordon-rowell-20011024.txt - - delete only allowd, if user may create lists -> ignored - -4) ezmlm-web-jose-celestino-20020208.txt - - support for newsletters -> ignored (for now) - - domain-based acl -> ignored - - filtered subscribers list for huge lists -> ignored (for now) - - - ------------------------------------------------ -############ directory Policy ################# -* done - patches that were incorporated -* ignored - patches, that were ignored -* open - these patches are not yet implemented/examined diff --git a/ezmlm-web/contrib-patches/done/ezmlm-web-andrew-pam-20030520.txt b/ezmlm-web/contrib-patches/done/ezmlm-web-andrew-pam-20030520.txt deleted file mode 100644 index 164b42b..0000000 --- a/ezmlm-web/contrib-patches/done/ezmlm-web-andrew-pam-20030520.txt +++ /dev/null @@ -1,422 +0,0 @@ -From xanni@kira.glasswings.com.au Tue May 20 16:09:12 2003 -Return-Path: -Delivered-To: guy-ezmlm@rucus.ru.ac.za -Received: (qmail 98840 invoked from network); 20 May 2003 14:09:12 -0000 -Received: from mail011.syd.optusnet.com.au (210.49.20.139) - by server.rucus.ru.ac.za with SMTP; 20 May 2003 14:09:12 -0000 -Received: from kira.glasswings.com.au (c16443.eburwd3.vic.optusnet.com.au [210.49.192.62]) - by mail011.syd.optusnet.com.au (8.11.6p2/8.11.6) with ESMTP id h4KE93X08963 - for ; Wed, 21 May 2003 00:09:03 +1000 -Received: (from xanni@localhost) - by kira.glasswings.com.au (8.9.3/8.9.3) id AAA18521 - for guy-ezmlm@rucus.ru.ac.za; Wed, 21 May 2003 00:18:02 +1000 -Date: Wed, 21 May 2003 00:18:01 +1000 -From: Andrew Pam -To: guy-ezmlm@rucus.ru.ac.za -Subject: Bug fixes for ezmlm-web -Message-ID: <20030520141801.GM599@kira.glasswings.com.au> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.4i -Status: RO -Content-Length: 24092 - -I found the following problems when installing ezmlm-web v2.1: - -* Many browsers do not provide any visible display of alt tags, so the - help icons are not usable without some JavaScript - -* There were several HTML errors in the output of the script, such as - mismatched tags, misspelled attributes and missing quotes around attributes - -* The CGI module now outputs XHTML, which requires that all tags be lowercase - -Here is a patch which addresses all these issues: - - ---- ezmlm-web.cgi Tue Sep 26 06:58:08 2000 -+++ /usr/local/bin/ezmlm-web.cgi Wed May 21 00:07:32 2003 -@@ -1,6 +1,9 @@ --#!/usr/bin/perl -T -+#!/usr/bin/perl -Tw - #=========================================================================== - # ezmlm-web.cgi - version 2.1 - 25/09/2000 -+# 20/05/2003 Andrew Pam -+# Fixed HTML errors, changed all HTML to lowercase for XHTML -+# Added sub help_icon and sub help_option for non-tooltip browsers - # $Id: ezmlm-web.cgi,v 1.3 2000/09/25 19:58:07 guy Exp $ - # - # Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved. -@@ -239,7 +242,7 @@ - &list_text; - - } else { -- print "

$Q::action

$LANGUAGE{'nop'}


"; -+ print "

$Q::action

$LANGUAGE{'nop'}


"; - } - - # Print HTML footer and exit :) ... -@@ -280,15 +283,15 @@ - $q->delete_all; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'select'); -- print '
'; -+ print '
'; - print $q->scrolling_list(-name=>'list', -size=>$scrollsize, -values=>\@lists) if defined(@lists); - -- print '', $LANGUAGE{'chooselistinfo'}; -+ print '', $LANGUAGE{'chooselistinfo'}; - - print $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), ' ' if (!defined($opt_c)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), ' ' if(defined(@lists)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]") if(defined(@lists)); -- print '
'; -+ print '
'; - print $q->endform; - } - -@@ -302,9 +305,9 @@ - print $q->startform; - print $q->hidden(-name=>'state', -default=>'confirm_delete'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); -- print '

', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '


'; -+ print '

', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '


'; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'no'}]"), ' '; -- print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), '
'; -+ print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), '
'; - } - - # ------------------------------------------------------------------------ -@@ -327,28 +330,28 @@ - - # Print out a form of options ... - $q->delete('state'); -- print "

$LANGUAGE{'subscribersto'} $Q::list ($listaddress)


"; -+ print "

$LANGUAGE{'subscribersto'} $Q::list ($listaddress)


"; - print $q->start_multipart_form; -- print '
'; -+ print '
'; - print $q->hidden(-name=>'state', -default=>'edit'); - print $q->hidden(-name=>'list', -default=>$Q::list); - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -labels=>&pretty_names, -multiple=>'true') if defined(@subscribers); -- print ''; -- print ' ', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, '
' if defined(@subscribers); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); -- print $q->textfield(-name=>'addsubscriber', -size=>'40'), ' ', $HELPER{'addaddress'}, '
'; -- print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ', $HELPER{'addaddressfile'}, '
' if ($FILE_UPLOAD); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; -- print '', $LANGUAGE{'additionalparts'}, ':
' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), '', $HELPER{'moderator'}, ' ' if ($list->ismodpost || $list->ismodsub || $list->isremote); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), '', $HELPER{'deny'}, ' ' if ($list->isdeny); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), '', $HELPER{'allow'}, ' ' if ($list->isallow); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), '', $HELPER{'digest'}, ' ' if ($list->isdigest); -- print '

'; -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), '', $HELPER{'webarch'}, ' ' if(&ezmlmcgirc); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), '', $HELPER{'config'}, '   '; -+ print '

'; -+ print ' ', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, '
' if defined(@subscribers); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); -+ print $q->textfield(-name=>'addsubscriber', -size=>'40'), help_icon('addaddress'), '
'; -+ print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), help_icon('addaddressfile'), '
' if ($FILE_UPLOAD); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; -+ print '', $LANGUAGE{'additionalparts'}, ':
' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), help_icon('moderator'), ' ' if ($list->ismodpost || $list->ismodsub || $list->isremote); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), help_icon('deny'), ' ' if ($list->isdeny); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), help_icon('allow'), ' ' if ($list->isallow); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), help_icon('digest'), ' ' if ($list->isdigest); -+ print '

'; -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), help_icon('webarch'), ' ' if(&ezmlmcgirc); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), help_icon('config'), '   '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'selectlist'}]"); -- print '

'; -+ print '
'; - print $q->endform; - - } -@@ -534,15 +537,15 @@ - my($subpath) = $config =~ m{8\s*'([^']+)'}; - my($remotepath) = $config =~ m{9\s*'([^']+)'}; - -- $moderated = '' if ($postpath); -+ $moderated = '' if ($postpath); - $moderated .= "[$LANGUAGE{'posting'}]" if ($list->ismodpost); -- $moderated .= 'Posting Moderators are stored in a non-standard location (' . $postpath . '). You will have to edit them manually.' if ($postpath); -- $moderated .= '' if ($subpath); -+ $moderated .= 'Posting Moderators are stored in a non-standard location (' . $postpath . '). You will have to edit them manually.' if ($postpath); -+ $moderated .= '' if ($subpath); - $moderated .= " [$LANGUAGE{'subscription'}]" if($list->ismodsub); -- $moderated .= 'Subscriber Moderators are stored in a non-standard location (' . $subpath . '). You will have to edit them manually' if ($subpath); -- $moderated .= '' if ($remotepath); -+ $moderated .= 'Subscriber Moderators are stored in a non-standard location (' . $subpath . '). You will have to edit them manually' if ($subpath); -+ $moderated .= '' if ($remotepath); - $moderated .= " [$LANGUAGE{'remoteadmin'}]" if($list->isremote); -- $moderated .= 'Remote Administrators are stored in a non-standard location (' . $remotepath . '). You will have to edit them manually' if ($remotepath); -+ $moderated .= 'Remote Administrators are stored in a non-standard location (' . $remotepath . '). You will have to edit them manually' if ($remotepath); - - } - -@@ -557,20 +560,20 @@ - - # Print out a form of options ... - $q->delete('state'); -- print "

$type $LANGUAGE{'for'} $listaddress


"; -- print "
$moderated

" if(defined($moderated)); -+ print "

$type $LANGUAGE{'for'} $listaddress


"; -+ print "
$moderated

" if(defined($moderated)); - print $q->start_multipart_form; -- print '

'; -+ print '
'; - print $q->hidden(-name=>'state', -default=>$part); - print $q->hidden(-name=>'list', -default=>$Q::list), "\n"; - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -multiple=>'true', -labels=>&pretty_names) if defined(@subscribers); -- print '
'; -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); -- print $q->textfield(-name=>'addsubscriber', -size=>'40'), ' ', $HELPER{'addaddress'}, '
'; -- print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ', $HELPER{'addaddressfile'}, '
' if ($FILE_UPLOAD); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; -+ print '

'; -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); -+ print $q->textfield(-name=>'addsubscriber', -size=>'40'), help_icon('addaddreess'), '
'; -+ print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), help_icon('addaddressfile'), '
' if ($FILE_UPLOAD); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'subscribers'}]"); -- print '

'; -+ print '
'; - print $q->endform; - - } -@@ -598,27 +601,26 @@ - - # Print a form of options ... - $q->delete_all; -- print '

', $LANGUAGE{'createnew'}, '


'; -+ print '

', $LANGUAGE{'createnew'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'create'); -- print '', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), ' ', $HELPER{'listname'}, '

'; -- print '', $LANGUAGE{'listaddress'}, ': '; -+ print '', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), help_icon('listname'), '

'; -+ print '', $LANGUAGE{'listaddress'}, ': '; - print $q->textfield(-name=>'inlocal', -default=>$username, -size=>'10'); -- print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), ' ', $HELPER{'listadd'}, '

'; -+ print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), help_icon('listadd'), '

'; - -- print '

', $LANGUAGE{'listoptions'}, ':'; -+ print '

', $LANGUAGE{'listoptions'}, ':'; - &display_options($DEFAULT_OPTIONS); - - # Allow creation of mysql table if the module allows it - if($Mail::Ezmlm::MYSQL_BASE) { -- print '

', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1); -- print ' ', $HELPER{'mysqlcreate'}, ''; -+ print '

', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1), help_icon('mysqlcreate'); - - } - -- print '

', $LANGUAGE{'allowedtoedit'}, ': ', -- $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30'), ' ', $HELPER{'webusers'}, '', -- '
', $HELPER{'allowedit'}, '' -+ print '

', $LANGUAGE{'allowedtoedit'}, ': ', -+ $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30'), help_icon('webusers'), -+ '
', $HELPER{'allowedit'}, '' - if(-e "$LIST_DIR/webusers"); - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'createlist'}]"), ' '; -@@ -647,7 +649,7 @@ - # Sanity Checks ... - return 1 if ($listname eq '' || $qmail eq ''); - if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) { -- print "

List '$listname' already exists :(

"; -+ print "

List '$listname' already exists :(

"; - return 1; - } - -@@ -710,13 +712,13 @@ - - # Print a form of options ... - $q->delete_all; -- print '

', $LANGUAGE{'editconfiguration'}, '


'; -+ print '

', $LANGUAGE{'editconfiguration'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'configuration'); - print $q->hidden(-name=>'list', -value=>$listname); -- print '', $LANGUAGE{'listname'}, ": $listname
"; -- print "$LANGUAGE{'listaddress'}: $listaddress

"; -- print '', $LANGUAGE{'listoptions'}, ':
'; -+ print '', $LANGUAGE{'listname'}, ": $listname
"; -+ print "$LANGUAGE{'listaddress'}: $listaddress

"; -+ print '', $LANGUAGE{'listoptions'}, ':
'; - - # Print a list of options, selecting the ones that apply to this list ... - &display_options($list->getconfig); -@@ -727,10 +729,10 @@ - $mimeremove = $list->getpart('mimeremove'); - $prefix = $list->getpart('prefix'); - -- print '

', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), ' ', $HELPER{'prefix'}, '' if defined($prefix); -- print '

', $LANGUAGE{'headerremove'}, ': ', $HELPER{'headerremove'}, '
', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70); -- print '

', $LANGUAGE{'headeradd'}, ': ', $HELPER{'headeradd'}, '
', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70); -- print '

', $LANGUAGE{'mimeremove'}, ': ', $HELPER{'mimeremove'}, '
', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70) if defined($mimeremove); -+ print '

', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), help_icon('prefix') if defined($prefix); -+ print '

', $LANGUAGE{'headerremove'}, ': ', help_icon('headerremove'), '
', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70); -+ print '

', $LANGUAGE{'headeradd'}, ': ', help_icon('headeradd'), '
', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70); -+ print '

', $LANGUAGE{'mimeremove'}, ': ', help_icon('mimeremove'), '
', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70) if defined($mimeremove); - - if(open(WEBUSER, "<$LIST_DIR/webusers")) { - my($webusers); -@@ -740,13 +742,13 @@ - close WEBUSER; - $webusers ||= $ENV{'REMOTE_USER'} || 'ALL'; - -- print '

', $LANGUAGE{'allowedtoedit'}, ': ', -- $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30'), ' ', $HELPER{'webusers'}, '', -- '
', $HELPER{'allowedit'}, ''; -+ print '

', $LANGUAGE{'allowedtoedit'}, ': ', -+ $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30'), help_icon('webusers'), -+ '
', $HELPER{'allowedit'}, ''; - - } - -- print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ' '; -+ print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edittexts'}]"); -@@ -841,12 +843,12 @@ - print $q->startform; - print $q->hidden(-name=>'state', -default=>'list_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); -- print '

'; -+ print '
'; - print $q->scrolling_list(-name=>'file', -values=>\@files); -- print ''; -+ print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'editfile'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); -- print '

', $LANGUAGE{'edittextinfo'}, '

'; -+ print '

', $LANGUAGE{'edittextinfo'}, '

'; - print $q->endform; - - } -@@ -862,20 +864,20 @@ - - # Print a form ... - $q->delete('state'); -- print '

', $LANGUAGE{'editingfile'}, ': ', $Q::file, '

'; -- print '
'; -+ print '

', $LANGUAGE{'editingfile'}, ': ', $Q::file, '

'; -+ print '
'; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'edit_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print $q->hidden(-name=>'file', -default=>$q->param('file')); - print $q->textarea(-name=>'content', -default=>$content, -rows=>'25', -columns=>'72'); -- print ''; -+ print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'savefile'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); -- print '

', $LANGUAGE{'editfileinfo'}; -+ print '

', $LANGUAGE{'editfileinfo'}; - print $q->endform; -- print '

' -+ print '
' - - } - -@@ -915,37 +917,35 @@ - my($i, $j); - - print ""; -- print '
'; -+ print ''; $j++; -+ print help_option($i), ''; $j++; - if ($j >= 3) { -- $j = 0; print ''; -+ $j = 0; print ''; - } -- print '
'; - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if ($opts =~ /^\w*$i\w*\s*/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } -- print '', $EZMLM_LABELS{$i}[1] , ''; -- print '
'; -+ print ''; - } -- print '
'; -+ print '
'; - -- print ''; -+ print '
'; - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { -- print ''; -+ print ''; - - } -- print '
'; -+ print '
'; - if ($opts =~ /$i (?:'(.+?)')/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } -- print '', $EZMLM_LABELS{$i}[1] , ''; -- print ''; -+ print help_option($i), ''; - print $q->textfield(-name=>"$i-value", -value=>$1||$EZMLM_LABELS{$i}[2], -size=>30); -- print '
'; -+ print ''; - - } - -@@ -976,6 +976,7 @@ - } - - # ------------------------------------------------------------------------- -+ - sub rmtree { - # A subroutine to recursively delete a directory (like rm -f). - # Based on the one in the perl cookbook :) -@@ -995,6 +996,28 @@ - } - - # ------------------------------------------------------------------------ -+ -+sub help_icon($) { -+ # Generate HTML for help icons -+ # Written 20 May 2003 by Andrew Pam -+ -+ my $msg = $HELPER{$_[0]}; -+ return '' . $msg . 
-+          ''; -+} -+ -+# ------------------------------------------------------------------------ -+ -+sub help_option($) { -+ # Generate HTML for option help icons -+ # Written 20 May 2003 by Andrew Pam -+ -+ my $msg = $EZMLM_LABELS{$_[0]}[1]; -+ return '' . $msg .
-+          ''; -+} -+ -+# ------------------------------------------------------------------------ - - BEGIN { - sub handle_errors { - - -Hope that helps, - Andrew Pam --- -mailto:xanni@xanadu.net Andrew Pam -http://www.xanadu.com.au/ Chief Scientist, Xanadu -http://www.glasswings.com.au/ Technology Manager, Glass Wings -http://www.sericyb.com.au/ Manager, Serious Cybernetics - diff --git a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-jon-coulter-20040312.txt b/ezmlm-web/contrib-patches/ignored/ezmlm-pm-jon-coulter-20040312.txt deleted file mode 100644 index 9f3b6cd..0000000 --- a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-jon-coulter-20040312.txt +++ /dev/null @@ -1,79 +0,0 @@ -From ledjon@ledjon.com Fri Mar 12 00:03:27 2004 -Return-Path: -Delivered-To: guy-ezmlm@rucus.ru.ac.za -Received: (qmail 56152 invoked by uid 1025); 11 Mar 2004 22:03:27 -0000 -Received: (qmail-scanner-1.20rc3 56151 invoked by uid 82); 11 Mar 2004 22:03:27 -0000 -Received: from 69-56-199-178.theplanet.com (HELO wylde.ledhosting.com) (69.56.199.178) - by server.rucus.ru.ac.za with SMTP; 11 Mar 2004 22:03:24 -0000 -Received: (qmail 25788 invoked from network); 11 Mar 2004 17:03:18 -0500 -Received: from atlnga1-ar3-4-64-009-109.atlnga1.dsl-verizon.net (HELO page) (4.64.9.109) - by 69-56-199-178.theplanet.com with SMTP; 11 Mar 2004 17:03:18 -0500 -From: "Jon Coulter" -To: -Subject: Mail::Ezmlm Patch -Date: Thu, 11 Mar 2004 17:03:24 -0500 -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_NextPart_000_0000_01C4078A.C44C42F0" -X-Mailer: Microsoft Office Outlook, Build 11.0.5510 -Thread-Index: AcQHtKkecjFWE5llQ6aIAIPcXCJAog== -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 -X-Qmail-Scanner-Message-ID: <107904260763856141@server.rucus.ru.ac.za> -Status: RO -Content-Length: 1642 - -This is a multi-part message in MIME format. - -------=_NextPart_000_0000_01C4078A.C44C42F0 -Content-Type: text/plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit - -Your (quite wonderful) Mail::Ezmlm perl module has a bug in that I patched -some time ago for my own use, so I figured I'd go ahead and send it along to -you. - -Basically it does something to the effect of 'return @array || undef' which -forces a scalar return (making it return @array as the number of items in -the array, rather then the items themselves) - -This just replaces it with a trinary operator. - -Feel free to use or ignore it at your own will. Thanks. - -Jon Coulter -ledjon@ledjon.com - -------=_NextPart_000_0000_01C4078A.C44C42F0 -Content-Type: application/octet-stream; - name="Ezmlm.pm.patch" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; - filename="Ezmlm.pm.patch" - -*** /usr/lib/perl5/site_perl/5.8.0/Mail/Ezmlm.pm~ Wed Jul 16 00:44:01 = -2003=0A= ---- /usr/lib/perl5/site_perl/5.8.0/Mail/Ezmlm.pm Wed Jul 16 00:54:22 2003=0A= -***************=0A= -*** 245,251 ****=0A= - =0A= - if($?) {=0A= - $self->_seterror($?, 'error during ezmlm-list in = -subscribers()'); =0A= -! return @subscribers || undef;=0A= - } else {=0A= - $self->_seterror(undef);=0A= - return @subscribers; =0A= ---- 245,251 ----=0A= - =0A= - if($?) {=0A= - $self->_seterror($?, 'error during ezmlm-list in = -subscribers()'); =0A= -! return (scalar @subscribers ? @subscribers : undef);=0A= - } else {=0A= - $self->_seterror(undef);=0A= - return @subscribers; =0A= - -------=_NextPart_000_0000_01C4078A.C44C42F0-- - - diff --git a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-lars-braeuer-20040305.txt b/ezmlm-web/contrib-patches/ignored/ezmlm-pm-lars-braeuer-20040305.txt deleted file mode 100644 index 4bcc48a..0000000 --- a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-lars-braeuer-20040305.txt +++ /dev/null @@ -1,52 +0,0 @@ -From lbraeuer@mpex.net Fri Mar 5 17:03:07 2004 -Return-Path: -Delivered-To: guy-ezmlm@rucus.net -Received: (qmail 49433 invoked by uid 1025); 5 Mar 2004 15:03:07 -0000 -Received: (qmail-scanner-1.20rc3 49432 invoked by uid 82); 05 Mar 2004 15:03:07 -0000 -Received: from endo.mpex.net (80.190.108.11) - by server.rucus.ru.ac.za with SMTP; 5 Mar 2004 15:03:04 -0000 -Received: (qmail 21499 invoked by uid 509); 5 Mar 2004 15:02:59 -0000 -Received: from unknown (HELO mpex.net) (217.225.11.124) - by 0 with SMTP; 5 Mar 2004 15:02:59 -0000 -Message-ID: <404896A9.8030606@mpex.net> -Date: Fri, 05 Mar 2004 16:03:05 +0100 -From: Lars Braeuer -Organization: MPeX.net GmbH -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 -X-Accept-Language: de, en-us, en -MIME-Version: 1.0 -To: guy-ezmlm@rucus.net -Subject: Bug + fix in ezmlm.pm 0.04 -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Status: RO -Content-Length: 1010 - -Addition: Just found out, that there's the same bug on line 138! - ---------------- - -Hi Guy! - -I just posted this on cpan, but I also wanted to let you know: - ----------------- -http://rt.cpan.org/NoAuth/Bug.html?id=5571 ----------------- - -Subject: Problem with dash in owner or sender address - -In Ezmlm.pm 0.04 on line 85 the options are split at every dash ("-\w+"). So when trying to supply -an owner or sender address containing a dash i.e. someone@some-domain.com this domain is splitted in -two parts ("someone@some" and "-domain.com") causing this error: "ezmlm-make: fatal: dir and dot -must start with slash". This occurs because "-domain.com" is interpreted as an option which is of -course wrong. - -This problem can be solved by adding a \s right in front of the -\w+ on line 85 of the module: - ---- foreach (split(/["'](.+?)["']|(-\w+)/, $commandline)) { -+++ foreach (split(/["'](.+?)["']|(\s-\w+)/, $commandline)) { - -This assures, that an option is split and not every occurence of a dash, even in a domain. - - diff --git a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-matt-simerson-20041115.txt b/ezmlm-web/contrib-patches/ignored/ezmlm-pm-matt-simerson-20041115.txt deleted file mode 100644 index f0e3e0d..0000000 --- a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-matt-simerson-20041115.txt +++ /dev/null @@ -1,54 +0,0 @@ -From sbeck@gossamer-threads.com Sat Oct 9 00:36:20 2004 -Return-Path: -Delivered-To: guy-ezmlm@rucus.net -Received: (qmail 94672 invoked by uid 1025); 8 Oct 2004 22:36:20 -0000 -Received: from sbeck@gossamer-threads.com by server.rucus.ru.ac.za by uid 82 with qmail-scanner-1.22 - (clamdscan: 0.75.1. Clear:RC:0(64.69.64.21):. - Processed in 3.991777 secs); 08 Oct 2004 22:36:20 -0000 -Received: from gossamer.nmsrv.com (HELO gossamer-threads.com) (64.69.64.21) - by server.rucus.ru.ac.za with SMTP; 8 Oct 2004 22:36:16 -0000 -Received: (qmail 17647 invoked from network); 8 Oct 2004 22:36:00 -0000 -X-AntiVirus: Clean -Received: from unknown (HELO sbeck) (sbeck@64.180.111.209) - by gossamer.nmsrv.com with (RC4-MD5 encrypted) SMTP; 8 Oct 2004 22:36:00 -0000 -Subject: Mail::Ezmlm tainting -From: Scott Beck -To: Guy Antony Halse -Content-Type: text/plain -Organization: Gossamer Threads -Message-Id: <1097274969.15328.32.camel@sbeck.office.gossamer-threads.com> -Mime-Version: 1.0 -X-Mailer: Ximian Evolution 1.4.6 -Date: Fri, 08 Oct 2004 15:36:09 -0700 -Content-Transfer-Encoding: 7bit -Status: RO -Content-Length: 810 - -Hi, - -I just ran into a taint problem with Mail::Ezmlm on one of our servers. -In Mail/Ezmlm.pm you have a sub _checkaddress which validates an email -address that is passed off to system, however to just verify the address -is not enough for perl's -T tests. You must reassign it to a capture -from a regex. Here is a version of the function that fixes this (a -little hacky). - -sub _checkaddress { - my($self, $address) = @_; - return 1 unless defined($address); - return 0 unless($address =~ /^(\S+\@\S+\.\S+)$/); - $_[1] = $1; - return 1; -} - -Cheers, - -Scott --- --------------------- Gossamer Threads Inc. ---------------------- -Scott Beck Email: scott@gossamer-threads.com -Lead Software Developer Phone: (604) 687-5804 -http://www.gossamer-threads.com Fax: (604) 687-5806 - - - diff --git a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-scott-beck-20041009.txt b/ezmlm-web/contrib-patches/ignored/ezmlm-pm-scott-beck-20041009.txt deleted file mode 100644 index 9a2ca4a..0000000 --- a/ezmlm-web/contrib-patches/ignored/ezmlm-pm-scott-beck-20041009.txt +++ /dev/null @@ -1,193 +0,0 @@ -From matt@tnpi.biz Mon Nov 15 21:21:15 2004 -Return-Path: -Delivered-To: guy@rucus.ru.ac.za -Received: (qmail 48783 invoked by uid 1025); 15 Nov 2004 19:21:15 -0000 -Received: from matt@tnpi.biz by server.rucus.ru.ac.za by uid 82 with qmail-scanner-1.22 - (clamdscan: 0.75.1. Clear:RC:0(207.89.154.94):. - Processed in 2.727858 secs); 15 Nov 2004 19:21:15 -0000 -Received: from matt-serv2.cdlc.mi.core.com (HELO mail.cadillac.net) (207.89.154.94) - by server.rucus.ru.ac.za with SMTP; 15 Nov 2004 19:21:12 -0000 -Received: (qmail 5634 invoked by uid 89); 15 Nov 2004 19:21:06 -0000 -Received: from unknown (HELO ?10.0.1.218?) (matt@cadillac.net@10.0.1.218) - by matt-serv2.cdlc.mi.core.com with (RC4-SHA encrypted) SMTP; 15 Nov 2004 19:21:06 -0000 -Mime-Version: 1.0 (Apple Message framework v619) -To: guy@rucus.ru.ac.za -Message-Id: <7D5CC579-373B-11D9-A43C-000A95A797A8@tnpi.biz> -Content-Type: multipart/mixed; boundary=Apple-Mail-5--167304881 -From: Matt Simerson -Subject: Mail::Ezmlm patch submission -Date: Mon, 15 Nov 2004 14:21:02 -0500 -X-Mailer: Apple Mail (2.619) -Status: RO -Content-Length: 6582 - - ---Apple-Mail-5--167304881 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset=US-ASCII; - format=flowed - -Hey Guy, - -First, thanks a bunch for writing Mail::Ezmlm, it's quite useful. :-) - -I've used it to write a CGI interface to Ezmlm for a client. It's not a -very complex thing, it just creates a web page where the client logs in -and then has the choice to list the subscribers for a list, batch add a -list of subscribers, or mass delete a list. - -It's posted here if you're interested in seeing it: -https://mail.cadillac.net/ezmlm.cgi - -You can log in using the domain "example.com" and the password -"guyrucus". - -Anyhow, the only problem I've had with Mail::Ezmlm is that when I run -my script suid as the user that owns the mailing list, mod_perl whines -about the data because it's tainted. So, I've made a few minor -alterations to untaint the data. My approach is rather basic and could -be improved upon but it works quite well and is slightly more secure -than what's being used at present. I'd appreciate if you'd review the -patch and apply it or something similar which achieves the same result. - -The patch is against v 1.9 of Mail::Ezmlm. - - - ---Apple-Mail-5--167304881 -Content-Type: multipart/appledouble; - boundary=Apple-Mail-6--167304881 -Content-Disposition: attachment - - ---Apple-Mail-6--167304881 -Content-Transfer-Encoding: base64 -Content-Type: application/applefile; - name="Ezmlm.pm.patch" -Content-Disposition: attachment; - filename=Ezmlm.pm.patch - -AAUWBwACAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAJAAAAPgAAAAoAAAADAAAASAAAAA4AAAACAAAA -VgAABq5URVhUUipjaAAARXptbG0ucG0ucGF0Y2gAAAEAAAAGaAAABWgAAABGAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAASAAJTW9uYWNvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAEAEIACgR0AooAQgAKBHQC -ir2+Z3QAAAFTAAABUwAAAAABAAAABRhSKmNoAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQdDb3VyaWVyAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAACgAAAAQJSGVsdmV0aWNhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADENvbmZpZGVudGlhbAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAQAAAQAAAQAAAIAAAACAAAAAgAAAAIAAAAAAAAABAQABAAEAAAAAAwBQ -AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACW1hY2ludG9zaAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAQAAAAZoAAAFaAAAAEYAZdCMAlUAAAAcAEYAAU1QU1IAAAASQkJT -VAAAAB4D7f//AAAAAAB/K8AAgP//AAAATAB/K9A= - ---Apple-Mail-6--167304881 -Content-Transfer-Encoding: 7bit -Content-Type: application/text; - x-mac-type=54455854; - x-unix-mode=0644; - x-mac-creator=522A6368; - name="Ezmlm.pm.patch" -Content-Disposition: attachment; - filename=Ezmlm.pm.patch - ---- Ezmlm.pm.orig Sat Nov 13 13:38:59 2004 -+++ Ezmlm.pm Mon Nov 15 13:44:35 2004 -@@ -236,6 +236,16 @@ - my($self, $part) = @_; - my(@subscribers); - ($self->_seterror(-1, 'must setlist() before returning subscribers()') && return undef) unless(defined($self->{'LIST_NAME'})); -+ -+ # additions by matt simerson (matt@tnpi.biz) to pass mod_perl security (taint) checks -+ $ENV{"PATH"} = ""; -+ if ( $self->{'LIST_NAME'} =~ /([\w\-\/.]*)/ ) { -+ $self->{'LIST_NAME'} = $1; -+ } else { -+ warn "TAINTED DATA IN LIST_NAME: $self->{'LIST_NAME'}\n"; -+ }; -+ # end additions -+ - if(defined($part) && $part) { - ($self->_seterror(-1, "$part part of $self->{'LIST_NAME'} does not appear to exist in subscribers()") && return undef) unless(-e "$self->{'LIST_NAME'}/$part"); - @subscribers = map { s/[\r\n]// && $_ } sort `$EZMLM_BASE/ezmlm-list $self->{'LIST_NAME'}/$part`; -@@ -270,6 +280,19 @@ - } else { - foreach $address (@addresses) { - next unless $self->_checkaddress($address); -+ -+ # matt adds -+ $ENV{"PATH"} = ""; # taint checks -+ -+ if ( $self->{'LIST_NAME'} =~ /([\w\-\/.]*)/ ) { -+ $self->{'LIST_NAME'} = $1; -+ } else { -+ warn "TAINTED DATA IN LIST_NAME: $self->{'LIST_NAME'}\n"; -+ }; -+ -+ if ( $address =~ /(.*)/ ) { $address = $1 }; -+ # end matt adds -+ - system("$EZMLM_BASE/ezmlm-sub", $self->{'LIST_NAME'}, $address) == 0 || - ($self->_seterror($?) && return undef); - } -@@ -322,6 +345,16 @@ - } else { - foreach $address (@addresses) { - $ENV{'SENDER'} = $address; -+ -+ # matt adds -+ $ENV{"PATH"} = ""; # taint checks -+ if ( $self->{'LIST_NAME'} =~ /([\w\-\/.]*)/ ) { -+ $self->{'LIST_NAME'} = $1; -+ } else { -+ warn "TAINTED DATA IN LIST_NAME: $self->{'LIST_NAME'}\n"; -+ }; -+ # end matt adds -+ - undef($issub) if ((system("$EZMLM_BASE/ezmlm-issubn", $self->{'LIST_NAME'}) / 256) != 0) - } - } - ---Apple-Mail-6--167304881-- - ---Apple-Mail-5--167304881 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset=US-ASCII; - format=flowed - - - -Matt - -`````````````````````````````````````````````````````````````````` - Matt Simerson http://matt.simerson.net - The Network People Inc. http://www.tnpi.biz - - The chief danger in life is that you may take too many precautions. -- Alfred Adler -`````````````````````````````````````````````````````````````````` - ---Apple-Mail-5--167304881-- - - diff --git a/ezmlm-web/contrib-patches/ignored/ezmlm-web-andrew-pam-20040526.txt b/ezmlm-web/contrib-patches/ignored/ezmlm-web-andrew-pam-20040526.txt deleted file mode 100644 index 959e25a..0000000 --- a/ezmlm-web/contrib-patches/ignored/ezmlm-web-andrew-pam-20040526.txt +++ /dev/null @@ -1,67 +0,0 @@ -From xanni@urYod.glasswings.com.au Wed May 26 10:27:04 2004 -Return-Path: -Delivered-To: guy-ezmlm@rucus.ru.ac.za -Received: (qmail 95684 invoked by uid 1025); 26 May 2004 08:27:04 -0000 -Received: (qmail-scanner-1.22 95683 invoked by uid 82); 26 May 2004 08:27:04 -0000 -Received: from mail018.syd.optusnet.com.au (211.29.132.72) - by server.rucus.ru.ac.za with SMTP; 26 May 2004 08:26:58 -0000 -Received: from urYod.glasswings.com.au (c211-28-208-136.eburwd1.vic.optusnet.com.au [211.28.208.136]) - by mail018.syd.optusnet.com.au (8.11.6p2/8.11.6) with ESMTP id i4Q8QmD27299 - for ; Wed, 26 May 2004 18:26:49 +1000 -Received: from urYod.glasswings.com.au (localhost.localdomain [127.0.0.1]) - by urYod.glasswings.com.au (8.12.10/8.12.10) with ESMTP id i4Q8QlgD004619 - for ; Wed, 26 May 2004 18:26:47 +1000 -Received: (from xanni@localhost) - by urYod.glasswings.com.au (8.12.10/8.12.10/Submit) id i4Q8Qljs004617 - for guy-ezmlm@rucus.ru.ac.za; Wed, 26 May 2004 18:26:47 +1000 -Date: Wed, 26 May 2004 18:26:47 +1000 -From: Andrew Pam -To: guy-ezmlm@rucus.ru.ac.za -Subject: Another ezmlm-web patch -Message-ID: <20040526082647.GN1975@urYod.glasswings.com.au> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.4.1i -X-Face: ="NXL=B\E?60DRs]*]Mp-[@,"/\ESi&5s~&qMPLKzyWqo*<)SiE$IykXoakjYA62"oQT_.0I-i:nay>Pg]I{>J&dN(D<]F}+eaMSI=Kv]fr7.e;3u(e1ZlP^C>pRxW*sJEgdAevnn^/D{Eg[f -Status: RO -Content-Length: 1682 - -Hello! I recently upgraded my system from Red Hat Linux 7.3 to -Fedora Core 1 which in turn resulted in upgrading my perl to 5.8.3. -This revealed a nasty security bug in Mail::Ezmlm which of course affects -ezmlm-web.cgi and is detected by perl when running SUID. Mail::Ezmlm -passes email addresses to the ezmlm tools on the command line using the -"system" perl function, but doesn't check that the email addresses are -free of dangerous characters. Here's a patch to ezmlm-web.cgi to make -it check for valid characters before calling Mail::Ezmlm: - ---- ezmlm-web.cgi.orig 2000-09-26 06:58:08.000000000 +1100 -+++ ezmlm-web.cgi 2004-05-26 17:54:30.000000000 +1000 -@@ -477,7 +477,14 @@ - untie %pretty; - } - -- if ($list->sub($add->address(), $part) != 1) { -+# Modified 2004-05-26 by Andrew Pam -+# Untaint the address because $list->sub will pass it to ezmlm-sub -+# on the command line! -+# Note this may not handle some less common email address formats -+ my($addr) = $add->address() =~ /([\w\.\=]+\@[\w\.\=]+)/ -+ or die "Illegal character in address '" . $add->address() ."'"; -+# if ($list->sub($add->address(), $part) != 1) { -+ if ($list->sub($addr, $part) != 1) { - die "Unable to subscribe to list: $!"; - } - $count++; - -Of course arguably Mail::Ezmlm should really be doing this. - -Cheers, - Andrew --- -mailto:xanni@xanadu.net Andrew Pam -http://www.xanadu.com.au/ Chief Scientist, Xanadu -http://www.glasswings.com.au/ Technology Manager, Glass Wings -http://www.sericyb.com.au/ Manager, Serious Cybernetics - diff --git a/ezmlm-web/contrib-patches/ignored/ezmlm-web-gordon-rowell-20011024.txt b/ezmlm-web/contrib-patches/ignored/ezmlm-web-gordon-rowell-20011024.txt deleted file mode 100644 index bd161fb..0000000 --- a/ezmlm-web/contrib-patches/ignored/ezmlm-web-gordon-rowell-20011024.txt +++ /dev/null @@ -1,67 +0,0 @@ -From gordonr@e-smith.com Wed Oct 24 08:10:56 2001 -Return-Path: -Delivered-To: guy-ezmlm@rucus.ru.ac.za -Received: (qmail 18972 invoked from network); 24 Oct 2001 06:10:56 -0000 -Received: from terrapin.ru.ac.za (146.231.128.6) - by rucus.ru.ac.za with SMTP; 24 Oct 2001 06:10:56 -0000 -Received: from cpe-144-132-208-16.nsw.bigpond.net.au ([144.132.208.16] helo=icedvovo.sydney.e-smith.com) - by terrapin.ru.ac.za with smtp (Exim 3.32 #1) - id 15wHFE-000C6Z-00 - for guy-ezmlm@rucus.ru.ac.za; Wed, 24 Oct 2001 08:10:29 +0200 -Received: (qmail 19833 invoked by uid 500); 24 Oct 2001 06:10:53 -0000 -MBOX-Line: From gordonr@e-smith.com Wed Oct 24 16:10:53 2001 -Date: Wed, 24 Oct 2001 16:10:53 +1000 -From: Gordon Rowell -To: Guy Antony Halse -Subject: ezmlm-web 2.1 patch - if you can't create lists, you can't delete them -Message-ID: <20011024161053.U8219@e-smith.com> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -Organization: Mitel Networks Corporation -Status: RO -Content-Length: 1758 -Lines: 40 - -Hi Guy, - -I'm in process of integrating ezmlm-web with our SME Server V5 product - see -www.e-smith.{com,org}. I did a quick and dirty proof of concept contrib to -integrate ezmlm, and am now revising it around ezmlm-web - great stuff. - -It fits in very well with our manager. I have a small shim to create -and delete lists which ensures that the list is known to our account -namespace. I wanted to ensure that people couldn't delete lists without -our manager knowing about it. The patch below also disables list deletion -if you have disabled list creation. You may want another switch, but -overloading opt_c seemed right to me. - -BTW: I am also making use of Mail::Ezmlm, which is great, so you're not the -only one who thinks it's a good idea :-) - -Also, I'll be building an RPM out of ezmlm-web which I'll make available -once I've done it. - -Gordon --- - Gordon Rowell gordonr@e-smith.com - VP Engineering - Network Server Solutions Group http://www.e-smith.com - Mitel Networks Corporation http://www.mitel.com - ----CUT HERE------CUT HERE------CUT HERE------CUT HERE--- -[gordonr@sao]$ diff -u ezmlm-web.cgi.orig ezmlm-web.cgi ---- ezmlm-web.cgi.orig Tue Sep 26 06:58:08 2000 -+++ ezmlm-web.cgi Wed Oct 24 16:05:08 2001 -@@ -287,7 +287,7 @@ - - print $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), ' ' if (!defined($opt_c)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), ' ' if(defined(@lists)); -- print $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]") if(defined(@lists)); -+ print $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]") if ((!defined($opt_c)) && (defined(@lists))); - print '
'; - print $q->endform; - } - - diff --git a/ezmlm-web/contrib-patches/open/ezmlm-web-jose-celestino-20020208.txt b/ezmlm-web/contrib-patches/open/ezmlm-web-jose-celestino-20020208.txt deleted file mode 100644 index 674e90b..0000000 --- a/ezmlm-web/contrib-patches/open/ezmlm-web-jose-celestino-20020208.txt +++ /dev/null @@ -1,1572 +0,0 @@ -From japc@co.sapo.pt Fri Feb 8 20:01:34 2002 -Return-Path: -Delivered-To: guy-ezmlm@rucus.ru.ac.za -Received: (qmail 72201 invoked from network); 8 Feb 2002 18:01:34 -0000 -Received: from isengard.sl.pt (HELO morgoth.sl.pt) (212.55.140.11) - by server.rucus.ru.ac.za with SMTP; 8 Feb 2002 18:01:34 -0000 -Received: (qmail 4347 invoked by uid 500); 8 Feb 2002 17:56:07 -0000 -Date: Fri, 8 Feb 2002 17:56:07 +0000 -From: Jose Celestino -To: guy-ezmlm@rucus.ru.ac.za -Cc: japc@co.sapo.pt -Subject: Ezmlm-Web -Message-ID: <20020208175607.GB4210@co.sapo.pt> -Mime-Version: 1.0 -Content-Type: multipart/mixed; boundary="bg08WKrSYDhXBjb5" -Content-Disposition: inline -Content-Transfer-Encoding: 8bit -User-Agent: Mutt/1.3.27i -X-URL: http://xpto.org/~japc -X-System: Linux morgoth 2.4.18pre1 i686 -X-Subliminal: Exchange Microsoft -Status: RO -Content-Length: 63760 -Lines: 1546 - - ---bg08WKrSYDhXBjb5 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline - -Hello Guy, - -don't know if you still maintain Ezmlm-Web but I've done some minor -changes/improvements; - -- subscriber list can be filtered by the start character or by regexp - (we had lists of nearly 50000 subscribers and it was a pain for the page to open); - -- support for $LIST/domains (for submission acls per domain): - In $LIST/editor top you should add the following line (one line only): - - |export SENDER=`echo $SENDER | sed s/^.*@/@/g`; /servers/ezmlm/bin/ezmlm-issubn - '/servers/virtualdomains/lists.mydomain.com/list1/domains' || { echo - "Sorry, I'm reject mail from your domain ($SENDER). - Contact sysadmin@mydomain.com if you have any questions about it.(#5.7.2)"; exit 100 ; } - - ad an extra list directory similar to mod for instance, $LIST/domains. - -- and, finally, support for newsletter administration (we use ezmlm here - for newsletter sending - games, technology, health, etc.) for the - non-technical dudes to manage and send issues for all the mailing list - subscribers. - -I found the subscripter filter to be extremely useful :) - --- -Jose Celestino ---------------------------------- -Systems Administration - SAPO.pt - ---bg08WKrSYDhXBjb5 -Content-Type: text/plain; charset=iso-8859-1 -Content-Disposition: attachment; filename="ezmlm-web.cgi" -Content-Transfer-Encoding: 8bit - -#!/usr/bin/perl -#=========================================================================== -# ezmlm-web.cgi - version 2.1 - 25/09/2000 -# $Id: ezmlm-web.cgi,v 1.3 2000/09/25 19:58:07 guy Exp $ -# -# Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved. -# Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# Neither name Guy Antony Halse nor the names of any contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# ========================================================================== -# All user configuration happens in the config file ``ezmlmwebrc'' -# POD documentation is at the end of this file -# ========================================================================== - -# Modules to include -use strict; -use Getopt::Std; -use Mail::Ezmlm; -use Mail::Address; -use DB_File; -use CGI; -use CGI::Carp qw(fatalsToBrowser set_message); - -# These two are actually included later and are put here so we remember them. -#use File::Find if ($UNSAFE_RM == 1); -#use File::Copy if ($UNSAFE_RM == 0); - -my @searchable=("TODOS","0-9","A","B","C","D","E","F","G","H","I","J","K", - "L","M","N","O","P","Q","R","S","T","U","V","X","W","Y","Z","_"); - -my $q = new CGI; -$q->import_names('Q'); -use vars qw[$opt_c $opt_d $opt_C]; -getopts('cd:C:'); - -# Suid stuff requires a secure path. -$ENV{'PATH'} = '/bin'; - -# We run suid so we can't use $ENV{'HOME'} and $ENV{'USER'} to determine the -# user. :( Don't alter this line unless you are _sure_ you have to. -my @tmp = getpwuid($>); my $USER=$tmp[0]; - -# use strict is a good thing++ - -use vars qw[$HOME_DIR]; $HOME_DIR=$tmp[7]; -use vars qw[$DEFAULT_OPTIONS %EZMLM_LABELS $UNSAFE_RM $ALIAS_USER $LIST_DIR]; -use vars qw[$QMAIL_BASE $EZMLM_CGI_RC $EZMLM_CGI_URL $HTML_BGCOLOR $PRETTY_NAMES]; -use vars qw[%HELPER $HELP_ICON_URL $HTML_HEADER $HTML_FOOTER $HTML_TEXT $HTML_LINK]; -use vars qw[%BUTTON %LANGUAGE $HTML_VLINK $HTML_TITLE $FILE_UPLOAD]; - -# Get user configuration stuff -if(defined($opt_C)) { - require "$opt_C"; # Command Line -} elsif(-e "$HOME_DIR/.ezmlmwebrc") { - require "$HOME_DIR/.ezmlmwebrc"; # User -} elsif(-e "/etc/ezmlm/ezmlmwebrc") { - require "/etc/ezmlm/ezmlmwebrc"; # System -} elsif(-e "./ezmlmwebrc") { - require "./ezmlmwebrc"; # Install -} else { - die "Unable to read config file"; -} - -# Allow suid wrapper to over-ride default list directory ... -if(defined($opt_d)) { - $LIST_DIR = $1 if ($opt_d =~ /^([-\@\w.\/]+)$/); -} - -# Work out default domain name from qmail (for David Summers) -my($DEFAULT_HOST); -open (GETHOST, "<$QMAIL_BASE/me") || open (GETHOST, "<$QMAIL_BASE/defaultdomain") || die "Unable to read $QMAIL_BASE/me: $!"; -chomp($DEFAULT_HOST = ); -close GETHOST; - -# Untaint form input ... -&untaint; - -# redirect must come before headers are printed -if(defined($Q::action) && $Q::action eq '[Web Archive]') { - print $q->redirect(&ezmlmcgirc); - exit; -} - -# Print header on every page ... -print $q->header(-pragma=>'no-cache', '-cache-control'=>'no-cache', -expires=>'-1d'); -print $q->start_html(-title=>$HTML_TITLE, -author=>'guy-ezmlm@rucus.ru.ac.za', -BGCOLOR=>$HTML_BGCOLOR, -LINK=>$HTML_LINK, -VLINK=>$HTML_VLINK, -TEXT=>$HTML_TEXT, -expires=>'-1d'); -print $HTML_HEADER; - -# This is where we decide what to do, depending on the form state and the -# users chosen course of action ... -unless (defined($q->param('state'))) { - # Default action. Present a list of available lists to the user ... - &select_list; - -} elsif ($Q::state eq 'select') { - # User selects an action to perorm on a list ... - - if ($Q::action eq "[$BUTTON{'create'}]") { # Create a new list ... - &allow_create_list; - } elsif (defined($Q::list)) { - if ($Q::action eq "[$BUTTON{'edit'}]") { # Edit an existing list ... - &display_list("NONE"); -# open (ZBR,">>/tmp/123"); -# print ZBR "FILTER:" . $q->param('filt') ."\n"; -# while (defined($q->param('filt'))) { -# print ZBR "DONEEEEEEEE\n"; -# &display_list($q->param('filt')); -# } -# close ZBR; - } elsif ($Q::action eq "[$BUTTON{'delete'}]") { # Delete a list ... - &confirm_delete; - } - } else { - &select_list; # NOP - Blank input ... - } - -} elsif ($Q::state eq 'edit') { - # User chooses to edit a list - - my($list); $list = $LIST_DIR . '/' . $q->param('list'); - if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ... - &delete_address($list); - &display_list("NONE"); - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address($list); - &display_list("NONE"); - - } elsif ($Q::action eq "[$BUTTON{'edit_newsletter'}]") { # Send a newsletter issue... - &edit_newsletter($list); - - } elsif ($Q::action eq "[$BUTTON{'moderators'}]") { # Edit the moderators ... - &part_subscribers('mod'); - - } elsif ($Q::action eq "[$BUTTON{'domains'}]") { # Edit the domains ... - &part_subscribers('domains'); - - } elsif ($Q::action eq "[$BUTTON{'denylist'}]") { # Edit the deny list ... - &part_subscribers('deny'); - - } elsif ($Q::action eq "[$BUTTON{'allowlist'}]") { # edit the allow list ... - &part_subscribers('allow'); - - } elsif ($Q::action eq "[$BUTTON{'digestsubscribers'}]") { # Edit the digest subscribers ... - &part_subscribers('digest'); - - } elsif ($Q::action eq "[$BUTTON{'configuration'}]") { # Edit the config ... - &list_config; - - } elsif (defined($q->param('filt'))) { - &display_list($q->param('filt')); - - } elsif (defined($q->param('search')) && defined($q->param('searchfor'))) { - &display_list($q->param('searchfor')); - - } else { # Cancel - Return a screen ... - &select_list; - } - -} elsif ($Q::state eq 'allow' || $Q::state eq 'mod' || $Q::state eq 'deny' || $q->param('state') eq 'digest') { - # User edits moderators || deny || digest ... - - my($part); - # Which list directory are we using ... - if($Q::state eq 'mod') { - $part = 'mod'; - } elsif($Q::state eq 'deny' ) { - $part = 'deny'; - } elsif($Q::state eq 'allow') { - $part = 'allow'; - } else { - $part = 'digest'; - } - - if ($Q::action eq '[Delete Address]') { # Delete a subscriber ... - &delete_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } else { # Cancel - Return to the list ... - &display_list("NONE"); - } - -} elsif ($Q::state eq 'confirm_delete') { - # User wants to delete a list ... - - &delete_list if($q->param('confirm') eq "[$BUTTON{'yes'}]"); # Do it ... - $q->delete_all; - &select_list; - -} elsif ($Q::state eq 'create') { - # User wants to create a list ... - - if ($Q::action eq "[$BUTTON{'createlist'}]") { - if (&create_list) { # Return if list creation is unsuccessful ... - &allow_create_list; - } else { - &select_list; # Else choose a list ... - } - - } else { # Cancel ... - &select_list; - } - -} elsif ($Q::state eq 'configuration') { - # User updates configuration ... - - if ($Q::action eq "[$BUTTON{'updateconfiguration'}]") { # Save current settings ... - &update_config; - &display_list("NONE"); - - } elsif ($Q::action eq "[$BUTTON{'edittexts'}]") { # Edit DIR/text ... - &list_text; - - } else { # Cancel - Return to list editing screen ... - &display_list("NONE"); - } - -} elsif ($Q::state eq 'list_text') { - # User wants to edit texts associated with the list ... - - if ($Q::action eq "[$BUTTON{'editfile'}]") { - &edit_text; - } else { - &list_config; # Cancel ... - } - -} elsif ($Q::state eq 'edit_text') { - # User wants to save a new version of something in DIR/text ... - - &save_text if ($Q::action eq "[$BUTTON{'savefile'}]"); - &list_text; - -} elsif ($Q::state eq 'edit_newsletter') { - # User wants to do something related with the newsletter - - if ($Q::action eq "[$BUTTON{'updateconfiguration'}]") { - my $issue=$q->param('newsletterissue'); - $issue="0$issue" if (($issue < 10) && ($issue !~ m/^0/)); - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - # THOU SHALL NOT MESS $list->setpart("newsletter/localizacao", $q->param('newslettertree')); - $list->setpart("newsletter/ficheiro", $q->param('newsletterhtml')); - $list->setpart("newsletter/subject-da-edicao", $q->param('newslettersubject')); - # THOU SHALL NOT MESS $list->setpart("newsletter/sender", $q->param('newslettersender')); - $list->setpart("newsletter/edicao", $issue); - &edit_newsletter; - } - &edit_newsletter if ($Q::action eq "[$BUTTON{'resetform'}]"); - &sendnewsletter if ($Q::action eq "[$BUTTON{'sendnewsletter'}]"); - &display_list("NONE") if ($Q::action eq "[$BUTTON{'cancel'}]"); - -} else { - print "

$Q::action

$LANGUAGE{'nop'}


"; -} - -# Print HTML footer and exit :) ... -print $HTML_FOOTER, $q->end_html; -exit; - -# ========================================================================= - -sub select_list { - # List all mailing lists (sub directories) in the list directory. - # Allow the user to choose a course of action; either editing an existing - # list, creating a new one, or deleting an old one. - - my (@lists, @files, $i, $scrollsize); - - # Read the list directory for mailing lists. - opendir DIR, $LIST_DIR || die "Unable to read $LIST_DIR: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Check that they actually are lists ... - foreach $i (0 .. $#files) { - if (-e "$LIST_DIR/$files[$i]/lock") { - if (-e "$LIST_DIR/webusers") { - if (&webauth($files[$i]) == 0) { - $lists[$#lists + 1] = $files[$i]; - } - } else { - $lists[$#lists + 1] = $files[$i]; - } - } - } - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#lists + 1) > 25); - - # Print a form - $q->delete_all; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'select'); - print '
'; - print $q->scrolling_list(-name=>'list', -size=>$scrollsize, -values=>\@lists) if defined(@lists); - - print '', $LANGUAGE{'chooselistinfo'}; - - print $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), ' ' if (!defined($opt_c)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), ' ' if(defined(@lists)); - # JAPC // print $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]") if(defined(@lists)); - print '
'; - print $q->endform; -} - -# ------------------------------------------------------------------------ - -sub confirm_delete { - # Make sure that the user really does want to delete the list! - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'confirm_delete'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print '

', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '


'; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'no'}]"), ' '; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), '
'; -} - -# ------------------------------------------------------------------------ - -sub display_list { - # Show a list of subscribers to the user ... - - my ($i, $list, $listaddress, $moderated, @subscribers, $scrollsize); - my ($filt) = @_; - my @subscribersfilt; - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - # Get a list of subscribers from ezmlm ... - @subscribers = $list->subscribers; - - if ("$filt" ne "NONE") { - if ($filt eq "0-9") { $filt='\d' }; - if ($filt eq "TODOS") { $filt='.*$' }; - for (@subscribers) { - if (defined($q->param('search'))) { - push @subscribersfilt, $_ if (m/$filt/i); - } else { - push @subscribersfilt, $_ if (m/^$filt/i); - } - } - } - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - print "

$LANGUAGE{'subscribersto'} $Q::list ($listaddress)


"; - print $q->start_multipart_form; - print '
'; - print $q->hidden(-name=>'state', -default=>'edit'); - print $q->hidden(-name=>'list', -default=>$Q::list); - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribersfilt, -labels=>&pretty_names, -multiple=>'true');# if defined(@subscribersfilt) && ($#subscribers <= 50); - print ''; - print '
', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, ' || ', ($#subscribersfilt + 1), ' ', $LANGUAGE{'selected'},' (', $filt ,')

' if defined(@subscribers); - if (defined(@subscribers)) { - print "Filtrar:
"; - for (@searchable) { - print $q->submit(-name=>'filt', -value=>"$_"); - } - print "
[regexp]:" . $q->textfield(-name=>'searchfor', -size=>'40'); - print $q->submit(-name=>'search', -value=>"[$BUTTON{'search'}]"), '

'; - } - print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

'; # if (defined(@subscribers) && ($#subscribers >= 51)); - print $q->textfield(-name=>'addsubscriber', -size=>'40'), ' ', $HELPER{'addaddress'}, '
'; - print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ', $HELPER{'addaddressfile'}, '
' if ($FILE_UPLOAD); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print '', $LANGUAGE{'additionalparts'}, ':
' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest); - # JAPC // - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edit_newsletter'}]"), '', $HELPER{'edit_newsletter'}, ' '; - #if ($list->ismodpost || $list->ismodsub || $list->isremote); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), '', $HELPER{'moderator'}, ' ' if ($list->ismodpost || $list->ismodsub || $list->isremote); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'domains'}]"), '', $HELPER{'domains'}, ' ' if (-d "$LIST_DIR/domains"); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), '', $HELPER{'deny'}, ' ' if ($list->isdeny); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), '', $HELPER{'allow'}, ' ' if ($list->isallow); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), '', $HELPER{'digest'}, ' ' if ($list->isdigest); - print '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), '', $HELPER{'webarch'}, ' ' if(&ezmlmcgirc); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), '', $HELPER{'config'}, '   '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'selectlist'}]"); - print '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub delete_list { - # Delete a list ... - - # Fixes a bug from the previous version ... when the .qmail file has a - # different name to the list. We use outlocal to handle vhosts ... - my ($list, $listaddress, $listadd); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - if ($listadd = $list->getpart('outlocal')) { - chomp($listadd); - } else { - $listadd = $q->param('list'); - } - $listaddress = $1 if ($listadd =~ /-?(\w+)$/); - - if ($UNSAFE_RM == 0) { - # This doesn't actually delete anything ... It just moves them so that - # they don't show up. That way they can always be recovered by a helpful - # sysadmin should he be in the mood :) - - use File::Copy; - - my ($oldfile); $oldfile = "$LIST_DIR/$Q::list"; - my ($newfile); $newfile = "$LIST_DIR/.$Q::list"; - move($oldfile, $newfile) or die "Unable to rename list: $!"; - mkdir "$HOME_DIR/deleted.qmail", 0700 if(!-e "$HOME_DIR/deleted.qmail"); - - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - foreach (@files) { - unless (move($_, "$HOME_DIR/deleted.qmail/")) { - die "Unable to move .qmail files: $!"; - } - } - warn "List '$oldfile' moved (deleted)"; - } else { - # This, however, does DELETE the list. I don't like the idea, but I was - # asked to include support for it so ... - if (!rmtree("$LIST_DIR/$Q::list")) { - die "Unable to delete list: $!"; - } - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - if (unlink(@files) <= 0) { - die "Unable to delete .qmail files: $!"; - } - warn "List '$list->thislist()' deleted"; - } -} - -# ------------------------------------------------------------------------ -sub untaint { - - $DEFAULT_HOST = $1 if $DEFAULT_HOST =~ /^([\w\d\.-]+)$/; - - # 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 ... - - my (@params, $i, $param); - @params = $q->param; - - foreach $i (0 .. $#params) { - my(@values); - next if($params[$i] eq 'addfile'); - foreach $param ($q->param($params[$i])) { - next if $param eq ''; - if ($param =~ /^([#-\@\w\.\/\[\]\:\n\r\>\< ]+)$/) { - push @values, $1; - } else { - warn "Tainted input in '$params[$i]': " . $q->param($params[$i]); - } - $q->param(-name=>$params[$i], -values=>\@values); - } - } - $q->import_names('Q'); -} - -# ------------------------------------------------------------------------ - -sub add_address { - # Add an address to a list .. - - my ($address, $list, @addresses, $count); my ($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - - if($q->param('addfile')) { - - # Sanity check - die "File upload must be of type text/*" unless($q->uploadInfo($q->param('addfile'))->{'Content-Type'} =~ m{^text/}); - - # Handle file uploads of addresses - my($fh) = $q->upload('addfile'); - return unless (defined($fh)); - while (<$fh>) { - next if (/^\s*$/ or /^#/); # blank, comments - next unless (/\@/); # email address ... - chomp(); - push @addresses, $_; - } - - } else { - - # User typed in an address - return if ($q->param('addsubscriber') eq ''); - - $address = $q->param('addsubscriber'); - $address .= $DEFAULT_HOST if ($q->param('addsubscriber') =~ /\@$/); - push @addresses, $address; - - } - - foreach $address (@addresses) { - - my($add) = Mail::Address->parse($address); - if(defined($add->name()) && $PRETTY_NAMES) { - my(%pretty); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - $pretty{$add->address()} = $add->name(); - untie %pretty; - } - - if ($list->sub($add->address(), $part) != 1) { - die "Unable to subscribe to list: $!"; - } - $count++; - } - - $q->delete('addsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub delete_address { - # Delete an address from a list ... - - my ($list, @address); my($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - return if ($q->param('delsubscriber') eq ''); - - @address = $q->param('delsubscriber'); - - if ($list->unsub(@address, $part) != 1) { - die "Unable to unsubscribe from list $list: $!"; - } - - if($PRETTY_NAMES) { - my(%pretty, $add); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - foreach $add (@address) { - delete $pretty{$add}; - } - untie %pretty; - } - - $q->delete('delsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub part_subscribers { - my($part) = @_; - # Deal with list parts .... - - my ($i, $list, $listaddress, @subscribers, $moderated, $scrollsize, $type); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - if($part eq 'mod') { - # Lets know what is moderated :) - - # do we store things in different directories? - my $config = $list->getconfig; - my($postpath) = $config =~ m{7\s*'([^']+)'}; - my($subpath) = $config =~ m{8\s*'([^']+)'}; - my($remotepath) = $config =~ m{9\s*'([^']+)'}; - - $moderated = '' if ($postpath); - $moderated .= "[$LANGUAGE{'posting'}]" if ($list->ismodpost); - $moderated .= 'Posting Moderators are stored in a non-standard location (' . $postpath . '). You will have to edit them manually.' if ($postpath); - $moderated .= '' if ($subpath); - $moderated .= " [$LANGUAGE{'subscription'}]" if($list->ismodsub); - $moderated .= 'Subscriber Moderators are stored in a non-standard location (' . $subpath . '). You will have to edit them manually' if ($subpath); - $moderated .= '' if ($remotepath); - $moderated .= " [$LANGUAGE{'remoteadmin'}]" if($list->isremote); - $moderated .= 'Remote Administrators are stored in a non-standard location (' . $remotepath . '). You will have to edit them manually' if ($remotepath); - - } - - # What type of sublist is this? - ($type) = $Q::action =~ m/^\[(.+)\]$/; - - # Get a list of moderators from ezmlm ... - @subscribers = $list->subscribers($part); - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - print "

$type $LANGUAGE{'for'} $listaddress


"; - print "
$moderated

" if(defined($moderated)); - print $q->start_multipart_form; - print '

'; - print $q->hidden(-name=>'state', -default=>$part); - print $q->hidden(-name=>'list', -default=>$Q::list), "\n"; - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -multiple=>'true', -labels=>&pretty_names) if defined(@subscribers); - print '
'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); - print $q->textfield(-name=>'addsubscriber', -size=>'40'), ' ', $HELPER{'addaddress'}, '
'; - print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ', $HELPER{'addaddressfile'}, '
' if ($FILE_UPLOAD); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'subscribers'}]"); - print '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub allow_create_list { - # Let the user select options for list creation ... - - my($username, $hostname, %labels, $j); - - # 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; - } - - # Print a form of options ... - $q->delete_all; - print '

', $LANGUAGE{'createnew'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'create'); - print '', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), ' ', $HELPER{'listname'}, '

'; - print '', $LANGUAGE{'listaddress'}, ': '; - print $q->textfield(-name=>'inlocal', -default=>$username, -size=>'10'); - print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), ' ', $HELPER{'listadd'}, '

'; - - print '

', $LANGUAGE{'listoptions'}, ':'; - &display_options($DEFAULT_OPTIONS); - - # Allow creation of mysql table if the module allows it - if($Mail::Ezmlm::MYSQL_BASE) { - print '

', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1); - print ' ', $HELPER{'mysqlcreate'}, ''; - - } - - print '

', $LANGUAGE{'allowedtoedit'}, ': ', - $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30'), ' ', $HELPER{'webusers'}, '', - '
', $HELPER{'allowedit'}, '' - if(-e "$LIST_DIR/webusers"); - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'createlist'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub create_list { - # Create a list acording to user selections ... - - # Check the list directory exists and create if necessary ... - if(!-e $LIST_DIR) { - die "Unable to create directory ($LIST_DIR): $!" unless mkdir $LIST_DIR, 0700; - } - - my ($qmail, $listname, $options, $i); - - # Some taint checking ... - $qmail = $1 if $q->param('inlocal') =~ /(?:$USER-)?([^\<\>\\\/\s]+)$/; - $listname = $q->param('list'); $listname =~ s/ /_/g; # In case some git tries to put a space in the file name - - # Sanity Checks ... - return 1 if ($listname eq '' || $qmail eq ''); - if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) { - print "

List '$listname' already exists :(

"; - return 1; - } - - # Work out the command line options - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - my($list) = new Mail::Ezmlm; - - unless ($list->make(-dir=>"$LIST_DIR/$listname", - -qmail=>"$HOME_DIR/.qmail-$qmail", - -name=>$q->param('inlocal'), - -host=>$q->param('inhost'), - -switches=>$options, - -user=>$USER) - ) { - die 'List creation failed', $list->errmsg(); - } - - # handle MySQL stuff - if($q->param('sql') && $options =~ m/-6\s+/) { - unless($list->createsql()) { - die 'SQL table creation failed: ', $list->errmsg(); - } - } - - # Handle authentication stuff - if ($Q::webusers) { - open(WEBUSER, ">>$LIST_DIR/webusers") || die "Unable to open webusers: $!"; - print WEBUSER "$Q::list: $Q::webusers\n"; - close WEBUSER; - } - - return 0; -} - -# ------------------------------------------------------------------------ - -sub list_config { - # Allow user to alter the list configuration ... - - my ($list, $listaddress, $listname, $options); - my ($headeradd, $headerremove, $mimeremove, $prefix, $j); - - # Store some variables before we delete them ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listname = $q->param('list'); - $listaddress = &this_listaddress; - - # Print a form of options ... - $q->delete_all; - print '

', $LANGUAGE{'editconfiguration'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'configuration'); - print $q->hidden(-name=>'list', -value=>$listname); - print '', $LANGUAGE{'listname'}, ": $listname
"; - print "$LANGUAGE{'listaddress'}: $listaddress

"; - print '', $LANGUAGE{'listoptions'}, ':
'; - - # Print a list of options, selecting the ones that apply to this list ... - &display_options($list->getconfig); - - # Get the contents of the headeradd, headerremove, mimeremove and prefix files - $headeradd = $list->getpart('headeradd'); - $headerremove = $list->getpart('headerremove'); - $mimeremove = $list->getpart('mimeremove'); - $prefix = $list->getpart('prefix'); - - print '

', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), ' ', $HELPER{'prefix'}, '' if defined($prefix); - print '

', $LANGUAGE{'headerremove'}, ': ', $HELPER{'headerremove'}, '
', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70); - print '

', $LANGUAGE{'headeradd'}, ': ', $HELPER{'headeradd'}, '
', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70); - print '

', $LANGUAGE{'mimeremove'}, ': ', $HELPER{'mimeremove'}, '
', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70) if defined($mimeremove); - - if(open(WEBUSER, "<$LIST_DIR/webusers")) { - my($webusers); - while() { - last if (($webusers) = m{^$listname\s*\:\s*(.+)$}); - } - close WEBUSER; - $webusers ||= $ENV{'REMOTE_USER'} || 'ALL'; - - print '

', $LANGUAGE{'allowedtoedit'}, ': ', - $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30'), ' ', $HELPER{'webusers'}, '', - '
', $HELPER{'allowedit'}, ''; - - } - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edittexts'}]"); - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub update_config { - # Save the new user entered config ... - - my ($list, $options, $i, @inlocal, @inhost); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - - # Work out the command line options ... - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - # Actually update the list ... - unless($list->update($options)) { - die "List update failed"; - } - - # Update headeradd, headerremove, mimeremove and prefix ... - $list->setpart('headeradd', $q->param('headeradd')); - $list->setpart('headerremove', $q->param('headerremove')); - $list->setpart('mimeremove', $q->param('mimeremove')) if defined($q->param('mimeremove')); - $list->setpart('prefix', $q->param('prefix')) if defined($q->param('prefix')); - - if($Q::webusers) { - # Back up web users file - open(TMP, ">/tmp/ezmlm-web.$$"); - open(WU, "<$LIST_DIR/webusers"); - while() { print TMP; } - close TMP; close WU; - - open(TMP, "$LIST_DIR/webusers"); - while() { - if(/^$Q::list\s*:/) { - print WU "$Q::list\: $Q::webusers\n"; - } else { - print WU; - } - } - close TMP; close WU; - unlink "/tmp/ezmlm-web.$$"; - } - -} - -# ------------------------------------------------------------------------ - -sub this_listaddress { - # Work out the address of this list ... Used often so put in its own subroutine ... - - my ($list, $listaddress); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - chomp($listaddress = $list->getpart('outlocal')); - $listaddress .= '@'; - chomp($listaddress .= $list->getpart('outhost')); - return $listaddress; -} - -# ------------------------------------------------------------------------ - -sub list_text { - # Show a listing of what is in DIR/text ... - - my(@files, $list); - $list = $LIST_DIR . '/' . $q->param('list'); - - # Read the list directory for text ... - opendir DIR, "$list/text" || die "Unable to read DIR/text: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'list_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print '

'; - print $q->scrolling_list(-name=>'file', -values=>\@files); - print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'editfile'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print '

', $LANGUAGE{'edittextinfo'}, '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub edit_text { - # Allow user to edit the contents of DIR/text ... - - my ($content); - my($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $content = $list->getpart("text/$Q::file"); - - # Print a form ... - $q->delete('state'); - print '

', $LANGUAGE{'editingfile'}, ': ', $Q::file, '

'; - print '
'; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'edit_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print $q->hidden(-name=>'file', -default=>$q->param('file')); - print $q->textarea(-name=>'content', -default=>$content, -rows=>'25', -columns=>'72'); - print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'savefile'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print '

', $LANGUAGE{'editfileinfo'}; - print $q->endform; - print '

' - -} - -# ------------------------------------------------------------------------ - -sub save_text { - # Save new text in DIR/text ... - - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $list->setpart("text/$Q::file", $q->param('content')); - -} - -# ------------------------------------------------------------------------ - -sub webauth { - - # Read authentication level from webusers file. Format of this file is - # somewhat similar to the unix groups file - my($listname) = @_; - open (USERS, "<$LIST_DIR/webusers") || die "Unable to read webusers file: $!"; - while() { - if (/^($listname|ALL)\:/i) { - if (/(\:\s*|,\s+)((?:$ENV{'REMOTE_USER'})|(?:ALL))\s*(,|$)/) { - close USERS; return 0; - } - } - } - close USERS; - return 1; -} - -# --------------------------------------------------------------------------- - -sub display_options { - my($opts) = shift; - my($i, $j); - - print ""; - print ''; $j++; - if ($j >= 3) { - $j = 0; print ''; - } - print '
'; - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if ($opts =~ /^\w*$i\w*\s*/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print '', $EZMLM_LABELS{$i}[1] , ''; - print '
'; - } - print '
'; - - print ''; - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - print ''; - - } - print '
'; - if ($opts =~ /$i (?:'(.+?)')/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print '', $EZMLM_LABELS{$i}[1] , ''; - print ''; - print $q->textfield(-name=>"$i-value", -value=>$1||$EZMLM_LABELS{$i}[2], -size=>30); - print '
'; - -} - -# --------------------------------------------------------------------------- - -sub edit_newsletter { - # Edit a newsletter configuration - my ($file,$subject,$sender,$tree,$issue) = (); - my $listaddress = &this_listaddress; - - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - - $file="newsletter.html" unless ($file = $list->getpart("newsletter/ficheiro")); - $subject="Ediçao XX" unless ($subject = $list->getpart("newsletter/subject-da-edicao")); - $sender="$listaddress" unless ($sender = $list->getpart("newsletter/sender")); - $tree="/edicaoXX/" unless ($tree = $list->getpart("newsletter/localizacao")); - $issue="" unless ($issue = $list->getpart("newsletter/edicao")); - - $q->delete('state'); - print $q->start_multipart_form; - print $q->hidden(-name=>'state', -default=>'edit_newsletter'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print $q->hidden(-name=>'file', -default=>$q->param('file')); - print '
'; - print '

', $LANGUAGE{'newslettertree'}, ': ', $HELPER{'newslettertree'}, ''; - print '

', $LANGUAGE{'newsletterhtml'}, ': ', $HELPER{'newsletterhtml'}, ''; - print '

', $LANGUAGE{'newslettersubject'}, ': ', $HELPER{'newslettersubject'}, ''; - print '

', $LANGUAGE{'newslettersender'}, ': ', $HELPER{'newslettersender'}, ''; - print '

', $LANGUAGE{'newsletterissue'}, ': ', $HELPER{'newsletterissue'}, ''; - print '

'; - # THOU SHALL NOT MESS print '

', $q->textfield(-name=>'newslettertree', -size=>'50', -default=>"$tree"), ''; - print '

', "$tree/edicao$issue", ''; - print '

', $q->textfield(-name=>'newsletterhtml', -size=>'30', -default=>"$file"), ''; - print '

', $q->textfield(-name=>'newslettersubject', -size=>'50', -default=>"$subject"), ''; - # THOU SHALL NOT MESS print '

', $q->textbox(-name=>'newslettersender', -size=>'30', -default=>"$sender"), ''; - print '

', "$sender", ''; - print '

', $q->textfield(-name=>'newsletterissue', -size=>'10', -default=>"$issue"), ''; - print '

'; - - print $q->hidden(-name=>'newslettertree', -default=>$q->param("$tree")); - print $q->hidden(-name=>'newslettersender', -default=>$q->param("$sender")); - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'sendnewsletter'}]"); - - print $q->endform; -} - -# --------------------------------------------------------------------------- - -sub sendnewsletter { - # Send newsletter - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - my $listaddress = &this_listaddress; - my ($file,$subject,$sender,$tree,$issue) = (); - - $file="newsletter.html" unless ($file = $list->getpart("newsletter/ficheiro")); - $subject="Ediçao XX" unless ($subject = $list->getpart("newsletter/subject-da-edicao")); - $sender="$listaddress" unless ($sender = $list->getpart("newsletter/sender")); - $tree="/edicaoXX/" unless ($tree = $list->getpart("newsletter/localizacao")); - $issue="" unless ($issue = $list->getpart("newsletter/edicao")); - - print " COMING SOON "; -} - -# --------------------------------------------------------------------------- - -sub ezmlmcgirc { - my($listno); - if(open(WWW, "<$EZMLM_CGI_RC")) { - while() { - last if (($listno) = m{(\d+)(\D)\d+\2$LIST_DIR/$Q::list\2}); - } - close WWW; - return "$EZMLM_CGI_URL/$listno" if(defined($listno)); - } return undef; - -} - -# --------------------------------------------------------------------------- - -sub pretty_names { - return undef unless($PRETTY_NAMES); - my (%pretty, %prettymem); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - %prettymem = %pretty; - untie %pretty; - - return \%prettymem; -} - -# ------------------------------------------------------------------------- -sub rmtree { - # A subroutine to recursively delete a directory (like rm -f). - # Based on the one in the perl cookbook :) - - use File::Find qw(finddepth); - File::Find::finddepth sub { - # assume that File::Find::name is secure since it only uses data we pass it - my($name) = $File::Find::name =~ m{^(.+)$}; - - if (!-l && -d _) { - rmdir($name) or warn "couldn't rmdir $name: $!"; - } else { - unlink($name) or warn "couldn't unlink $name: $!"; - } - }, @_; - 1; -} - -# ------------------------------------------------------------------------ - -BEGIN { - sub handle_errors { - my $msg = shift; - print << "EOM"; - -
-

A fatal error has occoured

- Something you did caused this script to bail out. The error - message we got was

- $msg

- Please try what you were doing again, checking everything you entered.
- If you still find yourself getting this error, please - contact the site administrator - quoting the error message above. -

-EOM - - } - set_message(\&handle_errors); -} - -# ------------------------------------------------------------------------ -# End of ezmlm-web.cgi v2.1 -# ------------------------------------------------------------------------ -__END__ - -=head1 NAME - -ezmlm-web - A web configuration interface to ezmlm mailing lists - -=head1 SYNOPSIS - -ezmlm-web [B<-c>] [B<-C> EFE] [B<-d> EFE] - -=head1 DESCRIPTION - -=over 4 - -=item B<-c> Disable list configuration - -=item B<-C> Specify an alternate configuration file given as F -If not specified, ezmlm-web checks first in the users home directory, then in -F and then the current directory - -=item B<-d> Specify an alternate directory where lists live. This is now -depreciated in favour of using a custom ezmlmwebrc, but is left for backward -compatibility. - -=back - -=head1 SUID WRAPPER - -C<#include stdio.h> - -C - C - C -C<}> - - -=head1 DOCUMENTATION/CONFIGURATION - - Please refer to the example ezmlmwebrc which is well commented, and - to the README file in this distribution. - -=head1 FILES - -F<~/.ezmlmwebrc> -F -F<./ezmlmwebrc> - -=head1 AUTHOR - - Guy Antony Halse - -=head1 BUGS - - None known yet. Please report bugs to the author. - -=head1 S - - ezmlm(5), ezmlm-cgi(1), Mail::Ezmlm(3) - - http://rucus.ru.ac.za/~guy/ezmlm/ - http://www.ezmlm.org/ - http://www.qmail.org/ - ---bg08WKrSYDhXBjb5 -Content-Type: text/plain; charset=iso-8859-1 -Content-Disposition: attachment; filename="ezmlmwebrc.PT" -Content-Transfer-Encoding: 8bit - -# $Id: ezmlmwebrc,v 1.5 2000/09/25 18:25:26 guy Exp $ -# Configuration file for ezmlm-web 2.1 -# =========================================================================== - -# This file is not just an ordinary configuration file - it contains valid -# perl statements that are executed just like any other perl script. When -# editing this file, be careful that it is still valid perl when you have -# finished (perl -w ezmlmwebrc ;-) - -# It is divided into to logical parts. The first part configures the way -# ezmlm-web runs, and the second changes the language, etc of ezmlm-web. You -# can not arbitarilly exclude any statement, since the script doesn't define -# any defaults of its own. You could, however, always split this file up and -# include the parts with -# -# require('/path/to/other/part'); - -# --------------------------------------------------------------------------- - -# Where do we store lists on this server ... Try "$HOME_DIR/lists". -# This directory will automatically be created if needed. -$LIST_DIR = "/servers/virtualdomains/lists.mydomain.com"; - -# Safe list deletion? -# 0 = move list to .list and the .qmails to deleted.qmail/. Recoverable :) -# 1 = allow user to delete list completely. No backup, therefore no recovery. -$UNSAFE_RM = 0; - -# Who is the alias user on this system (usually alias ;) -$ALIAS_USER = 'alias'; - -# Where do the qmail control files live on this system ... -$QMAIL_BASE = $Mail::Ezmlm::QMAIL_BASE . '/control'; - -# The url to our web interface - so we can use ezmlm-cgi if necessary -$EZMLM_CGI_URL = 'http://listadmin.mydomain.com/'; - -# Where our ezcgirc file lives (probably /etc/ezmlm/ezcgirc -$EZMLM_CGI_RC = '/etc/ezmlm/ezcgirc'; - -# Do we want to allow ``pretty'' names - ie more human readable ones -# This will slow ezmlm-web down a bit for large lists -$PRETTY_NAMES = 1; - -# Do we want to allow the users to be allowed to upload a file containing -# lists of email addresses to subscribe? -$FILE_UPLOAD = 1; - -# What switches to we want ezmlm-web to have on as default. The ezmlm-make -# defaults are aBDFGHIJKLMNOpQRSTUWX (small means enabled, CAPITALS mean -# disabled). The defaults below should be reasonable - I use them ;) -$DEFAULT_OPTIONS = 'aBDFGHiJkLMNOpQRSTUWx'; - -# Where do we find the nice little help icon - by default HELP_ICON_URL -# points to resources on http://rucus.ru.ac.za/. This will work, but we -# would appreciate it if you changed this to a local site. -$HELP_ICON_URL = 'http://mail-int.sl.pt/images/q.gif'; - -# Header for every page (.= concatinates) -$HTML_HEADER = '

Lists Admin - mydomain.com

'; - -$HTML_HEADER .= '

'; - -# Footer for every page (.= concatinates) -$HTML_FOOTER = '
'; -$HTML_FOOTER .= '
'; -$HTML_FOOTER .= 'ezmlm-web (v2.1) -- Contactar mydomain.com
'; - -# What colour do we want the background to be? -$HTML_BGCOLOR = '#000000'; - -# What colour do we want text? -$HTML_TEXT = '#0f0f0f'; - -# What color do we want links? -$HTML_LINK = '#3333ff'; - -# What color to we want visited links? -$HTML_VLINK = '#8888ff'; - -# What is the title of this document? -$HTML_TITLE = 'mydomain.com - List Admin'; - -# --------------------------------------------------------------------------- - -# The meanings of the various ezmlm-make command line switches. The default -# ones match the ezmlm-idx 0.4 default ezmlmrc ... Alter them to suit your -# own ezmlmrc. Removing options from this list makes them unavailable -# through ezmlm-web - this could be useful for things like -w - -%EZMLM_LABELS = ( -# option => ['Short Name', -# 'Long Help Description'], - - a => ['Arquivadas', - 'O sistema arquivará mensagens novas'], - b => ['Arquivo Bloqueado', - 'Apenas aos moderadores é permitido aceder ao arquivo'], -# c => config. This is implicity called, so is not defined here - d => ['Digest', - 'Constituir uma lista de "digest" das mensagens da lista'], -# e => edit. Also implicity called, so not defined here - f => ['Prefixo', - 'O subject das mensagens sera alterado com este prefixo'], - g => ['Arquivo Guardado', - 'Pedidos de acesso ao arquivo originados de SENDERs desconhecidos são rejeitados'], - h => ['Ajuda na Subscrição', - 'As subscrições não precisam de confirmação'], - i => ['Indexada', - 'Indexada para arquivo acessível via WWW'], - j => ['Saída Rápida', - 'As dessubscrições não necessitam de confirmação'], - k => ['Kill', - 'As mensagens originárias de endereços listados em dir/deny/ são rejeitadas'], - l => ['Lista de Subscritos', - 'Os administradores remotos podem requerer uma lista dos subscritos'], - m => ['Moderação das Mensagens', - 'Todas as mensagens recebidas são moderadas'], - n => ['Edição de Textos', - 'É permitida aos administradores remotos a edição de ficheiros em dir/text/'], - o => ['Rejeição de Outros', - 'Mensagens de endereços que não os dos moderadores serão rejeitadas'], - p => ['Publica', - 'A lista responderá a pedidos administrativos e a pedidos do arquivo'], - q => ['Endereço de Pedidos e Serviços', - 'Processar comandos enviados no subject para local-request@host'], - r => ['Administração Remota', - 'Permitir a administração remota da lista'], - s => ['Subscrição Moderada', - 'Subscrições para a lista principal e para a digest são moderadas'], - t => ['Trailer', - 'Adicionar um trailer a todas as mensagens enviadas'], - u => ['Apenas de Subscritos', - 'Mensagens originárias de remetentes desconhecidos são rejeitadas'], -# v => version. I doubt you will really need this ;-) - w => ['Remover Warn', - 'Remover as invocações do ezmlm-warn(1) da configuração da lista. Parte-se do princípio que o ezmlm-warn(1) será invocado de outra forma'], - x => ['Extra', - 'Remover certos mimetypes, etc'], -# y => not used -# z => not used - -# These all take an extra argument, which is the default value to use - - 0 => ['Sublista', - 'Fazer a lista uma sublista da lista mainlist@host', - 'mainlist@host'], -# 1 => not used -# 2 => not used - 3 => ['Do Endereço', - 'Substituir o header "From:" da mensagem por "From: fromarg"', - 'fromarg'], - 4 => ['Opções de Digest', - 'Switches para o ezmlm-tstdig(1)', - '-t24 -m30 -k64'], - 5 => ['Dono da Lista', - 'Endereço e-mail do dono da lista', - ''], - 6 => ['Base de dados SQL', - 'Dados para ligação á base de dados SQL. Necessita de suporte para SQL', - 'host:port:user:password:datab:table'], - 7 => ['Caminho para a Moderação de Mensagens', - 'Caminho para a base de dados dos moderadores das mensagens, se a lista tiver sido configurada para moderação de mensagens', - '/some/full/path'], - 8 => ['Caminho para a Moderação de Subscrições', - 'Caminho para a base de dados dos moderadores das subscrições, se a lista tiver sido configurada para moderação de subscrições', - '/some/full/path'], - 9 => ['Caminho para a Administração Remota', - 'Caminho para a base de dados dos administradores, se a lista tiver sido configurada para administração remota', - '/some/full/path'] - -); - -# This list defines most of the context sensitive help in ezmlm-web. What -# isn't defined here is the options, which are defined above ... You can -# alter these if you feel something else would make more sense to your users -# Just be careful of what can fit on a screen! - -%HELPER = ( - - # These should be self explainitory - addaddress => 'Poderá introduzir um endereço conforme o RFC822, incluindo a parte de comentário. Por exemplo Zacarias Albertino ', - addaddressfile => 'ou poderá introduzir o nome de um ficheiro de texto contendo múltiplos endereços RFC822, um por linha', - moderator => 'Moderadores: Controlam quem se pode subscrever ou enviar mail para uma lista', - deny => 'Deny: Uma lista de endereços que estão explicitamente impedidos de enviar mail para a lista', - allow => 'Allow: A list of address that are allowed to mail the list even if the configuration otherwise restricts it', - digest => 'Digest: Endereços que recebem o digest de todas as mensagens da lista', - webarch => 'Ver o arquivo web desta lista', - config => 'Alterar as configurações desta lista', - listname => 'Nome da lista. É também o nome do subdirectório que contém a lista', - listadd => 'Endereço de e-mail da lista. Por defeito vem da configuração do qmail. Apenas deverá ser alterada a parte local (antes da @)', - webusers => 'NB! Por enquanto quaisquer utilizadores especificados deverão existir. A criação de utilizadores será adicionada numa versão futura', - prefix => 'Texto a adicionar ao subject de todas as mensagens enviadas', - headerremove => 'Lista de headers a remover de todas as mensagens enviadas', - headeradd => 'Lista de headers a adicionar a todas as mensagens enviadas', - mimeremove => 'Qualquer mensagem cujo "Content-Type" coincida com um destes mime types será devolvida ao remetente', - allowedit => 'Lista (separada por vírgulas) dos utilizadores, ou ALL (todos os utilizadores válidos)', - domains => 'Aos dominios nesta lista é permitido enviar mail para a mailing list', - mysqlcreate => 'Isto permite criar as tabelas de MySQL necessárias se a configuração da lista acima assim o exigir', - edit_newsletter => 'Clique para editar e enviar a newsletter associada a esta lista', - newsletterhtml => 'Nome do ficheiro html que contém a newsletter', - newslettersubject => 'Subject da newsletter', - newslettersender => 'Sender da newsletter', - newslettertree => 'Localização em disco (ou ftp) do ficheiro que contém a newsletter', - newsletterissue => 'Número desta edição da newsletter', -); - -# This defines the captions of each of the buttons in ezmlm-web, and allows -# you to configure them for your own language or taste. Since these are used -# by the switching algorithm it is important that every button has a unique -# caption - ie we can't have two 'Edit' buttons doing different things. - -%BUTTON = ( - - # These MUST all be unique! - create => 'Criar', - createlist => 'Criar Lista', - edit => 'Editar', - delete => 'Remover', - deleteaddress => 'Remover Endereço', - addaddress => 'Adicionar Endereço', - moderators => 'Moderadores', - denylist => 'Lista "Deny"', - allowlist => 'Lista "Allow"', - digestsubscribers => 'Subscritores do "Digest"', - configuration => 'Configuração', - yes => 'Sim', - no => 'Não', - updateconfiguration => 'Actualizar a Configuração', - edittexts => 'Editar Textos', - editfile => 'Editar Ficheiro', - savefile => 'Guardar Ficheiro', - webarchive => 'Arquivo Web', - selectlist => 'Seleccionar Lista', - subscribers => 'Subscritos', - search => 'Procurar', - domains => 'Dominios', - cancel => 'Cancelar', - resetform => 'Reset do Form', - edit_newsletter => 'Editar Newsletter', - sendnewsletter => 'Enviar Newsletter' - -); - -# This defines the fixed text strings that are used in ezmlm-web. By editing -# these along with the button labels and help texts, you can convert ezmlm-web -# to another language :-) If anyone gets arround to doing complete templates -# for other languages I would appreciate a copy so that I can include it in -# future releases of ezmlm-web. - -%LANGUAGE = ( - nop => 'Acção por implementar', - chooselistinfo => "

  • Escolha a Lista da caixa à esquerda ou clique em [$BUTTON{'create'}].
  • Clique em [$BUTTON{'edit'}] para editar a Lista seleccionada.
  • Clique em [$BUTTON{'delete'}] para remover a Lista seleccionada.
", - confirmdelete => 'Confirme a remoção de', # list name - subscribersto => 'Subscritos na', # list name - subscribers => 'subscritos', - selected => 'seleccionados', - additionalparts => 'Configuração da Lista', - posting => 'Posting', - subscription => 'Subscrição', - remoteadmin => 'Administração Remota', - for => 'de', # as in; moderators for blahlist - createnew => 'Criar uma nova Lista', - listname => 'Nome da Lista', - listaddress => 'Endereço da Lista', - listoptions => 'Opções da Lista', - allowedtoedit => 'Utilizadores com acesso para edição desta Lista', - editconfiguration => 'Editar a configuração da Lista', - prefix => 'Prefixo para os subjects das mensagens', - headerremove => 'Headers a excluir de todas as mensagens enviadas', - headeradd => 'Headers a incluir em todas as mensagens enviadas', - mimeremove => 'Mime types a excluir de todas as mensagens enviadas', - edittextinfo => "A caixa à esquerda contém uma lista dos ficheiros disponíveis no directório
DIR/text. Estes ficheiros são enviados nas respostas a certos pedidos (via e-mail) dos utilizadores, ou como parte de todas as mensagens enviadas.

Para editar um ficheiro seleccione o seu nome na caixa, de seguida clique em [$BUTTON{'editfile'}].

Clique em [$BUTTON{'cancel'}] quando tiver terminado a edição.", - editingfile => 'A editar o ficheiro', - editfileinfo => 'ezmlm-manage
<#l#> O nome da Lista
<#A#> O endereço de subscrição
<#R#> O endereço de resposta para os subscritores

ezmlm-store
<#l#> O nome da Lista
<#A#> O endereço de aceitação
<#R#> O endereço de rejeição', - mysqlcreate => 'Criar as tabelas para a base de dados MySQL se necessário', - newsletterhtml => 'Conteúdo', - newslettersubject => 'Subject', - newslettersender => 'Sender', - newslettertree => 'Localização', - newsletterissue => 'Edição', - -); - -# === Configuration file ends === - ---bg08WKrSYDhXBjb5-- - diff --git a/ezmlm-web/tags/ezmlm-web-2.1.tar.gz b/ezmlm-web/tags/ezmlm-web-2.1.tar.gz deleted file mode 100644 index 3b220b3816004ea4298dc21667d76eabe7edffe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23315 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 Y%%1-K|6}0P?^mS71=F}UR!DFD2RHan0RR91 diff --git a/ezmlm-web/tags/ezmlm-web-2.1/CHANGES b/ezmlm-web/tags/ezmlm-web-2.1/CHANGES deleted file mode 100644 index 58b2a08..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/CHANGES +++ /dev/null @@ -1,84 +0,0 @@ -$Id: CHANGES,v 1.2 2000/09/25 17:54:06 guy Exp $ - -REVISION HISTORY - ezmlm-web.cgi -================================ - -Version 0.1 - 10/04/98 (Not Released) -* University Vac - I was bored and started to play. The first version just - let people play with the subscribers list. No moderators, no nothing. - -Version 0.2 - 13/04/98 (Not Released) -* Allow list creation -* Allowed users to edit moderators - -Version 0.3 - 15/04/98 -* Allow list deletion (for balin@moria.org) -* Made changes to allow it to run on RedHat 4.2 as well as FreeBSD 3.0 -* Fixed some minor bugs (cosmetic irritaions really) that people noticed -* Sorted subscribers list into alphabetical order. -* Added command line switch to change list directory (for nxsy@moria.org) -* Wrote some documentation ... - -Version 0.4 - 28/04/98 -* Fixed up virtual domain (inlocal) stuff as spotted by bryan@rucus -* Allowed the list directory to be automatically created if necessary. - -Version 0.5 - 12/05/98 (Not Released) -* More bug fixes. Mainly for mathew@graham. - -Version 1.0 - 01/08/98 -* Complete re-write to convert to perl5 and CGI.pm -* Removed a lot of dependancy on the OS. Use builtin functions instead :) -* Added support for ezmlm-idx -* Added a lot more command line option support (-adfgiklmnpqsrstux5) -* Added support for digests and digest subscribers -* Added support for blacklists -* Allowed users to edit the config of existing lists -* Allowed the user to edit headeradd and headerremove as well as mimeremove -* Allowed user to edit any of the files in DIR/text -* Revised interface to make it more user-friendly and ergonomic. -* Changed the background colour for Kether (clb@rucus) *gryn* -* Removed a big bug in the delete_list function that had gone unnoticed. - -Version 1.0.1 - 10/08/98 -* Fixed a bug in the way 1.0 re-configured virtual hosts (bryan@rucus) -* Made the script read the /var/qmail/control files instead of explicitly - setting variables (for david@summersoft) - -Version 1.0.2 - 28/08/98 -* Fixed the bug introduced in v1.0.1 :( (keith@rucus) -* Fixed the way we recreate config files (noticed by Glen Stewart) -* Made the script check return values of system calls properly -* Fixed some of the taint checking stuff ... reports less in the logs now. - -Version 1.0.3 - 03/10/98 -* Fixed the alias-alias-alias-list bug in inlocal (bryan@rucus) -* Added a bit of online help -* Fixed the & in list owner (bryan@rucus) -* Added multi-level access to lists (based on idea by Glen Stewart) - -Version 2.0 - 01/01/00 -* Rewrote most of the code to take advantage of Mail::Ezmlm -* Made the webuser file more functional (users can alter it) -* Now handles all current, and future command line options -* Changed the colours :) -* Added support for ezmlm-cgi web archives -* Made it -w and use strict clean -* Moved all user config to a separate file -* Fixed the way we worked out list config - now complete -* Allowed a user specific config over-ride ``ezmlmwebrc'' -* Allowed the printing of `nice' usernames (for Rhodes CS Dept) -* Took account of non-standard paths for moderators -* Removed all system() and `` calls from ezmlm-web.cgi -* Made `look and feel' virtually all user configurable -* Added a lot more context sensitive help -* Made ezmlm-web 99% language configurable - but no other templates yet :( -* Added support for creating databases - -Version 2.1 - 25/09/00 -* Fixed the multiple delete thing - finally! -* Fixed the '-' in username problem - The '-' in hostnames problem is fixed - in the new version of Mail::Ezmlm -* Fixed the '_' in list names problem -* Added support for file uploads of email addresses (multiple subscribe) -* Made error handling more friendly diff --git a/ezmlm-web/tags/ezmlm-web-2.1/README b/ezmlm-web/tags/ezmlm-web-2.1/README deleted file mode 100644 index 3ec4b1b..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/README +++ /dev/null @@ -1,323 +0,0 @@ -$Id: README,v 1.2 2000/09/25 17:57:21 guy Exp $ - -================= -| ezmlm-web-2.1 | -================= - -Contents -======== - I. Copyright Stuff - II. Some Background - III. Requirements - IV. Files - V. Installation - VI. Notes - VII. Multi-level list access -VIII. Language Portability - IX. Bugs && Bug Reports - X. Acknowledgements - XI. Availability - - -I. Copyright Stuff - essentially the FreeBSD licence ... -================== -ezmlm-web - version 2.1 - 25/09/2000 - -Copyright (C) 1998, Guy Antony Halse, All Rights Reserved. -Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -Neither name Guy Antony Halse nor the names of any contributors may be used -to endorse or promote products derived from this software without specific -prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -II. Some Background -=================== -The need for ezmlm-web arose from the fact that we host many student -societies on our system. These societies usually have a virtual host for web -and email, which is administered by a computer rep from the society. These -computer reps often have little or no knowledge of Unix and so we needed a -user friendly system that would let the create and maintain mailing lists -(such as members@foo.soc.ru.ac.za, committee@foo.soc.ru.ac.za, etc). - -Since I am never keen to re-invent the wheel, I had a look at Steve Peterson's -script (http://virtation.com/qmail/ml-sub), which allows people to subscribe -and unsubscribe from mailing lists using a form->email gateway. This is fine -for putting on a web page saying "here come and join our mailing list", but -doesn't really allow you to administrate a list. - -Security of mailing lists was a concern, as we really didn't want -unauthorised people to be able to alter some users list. Ezmlm-web itself -implements no security checks (apart from un-tainting input) and so relies -on the web server to do this (re-inventing the wheel again :). We use an -Apache webserver, so one can control access to a directory using a .htaccess -file or in the access.conf file. ApacheWeek have a good article on doing -this at http://www.apacheweek.com/features/userauth. I also give examples -later in this document. - -This version of ezmlm-web (2.0) is based to a large extent on previous -versions that I have developed. It has however been totally re-written to -make use of the Mail::Ezmlm perl module I wrote. At the same time it was -updated and extended to include the new features of ezmlm-idx. It includes -many new features that have been suggested to me over the last few months, -and hopefully is now useful to a much larger group of people. - -III. Requirements -================= -This version of ezmlm-web requires the following; - -* qmail v1.03 -* ezmlm v0.53 (idx v0.40) -* Perl v5.004 and the following modules; - + Mail::Ezmlm v0.03 - + Mail::Address v1.15 - + CGI v2.6 - + CGI::Carp v1.06 - + DB_File v1.65 - + Getopt::Std v4.1 - + File::Find v? - + File::Copy v2.02 - -The version number indicates the version of the module that ezmlm-web was -developed with. Earlier versions may work, but then they haven't been -tested. Have a look on http://www.CPAN.org/, http://www.qmail.org/, and -http://www.ezmlm.org/ for anything you are missing. - -IV. Files -========= -In this distribution you should find 8 files; - -README This file. Provides some background information, notes on - installation, etc. Not needed to run ezmlm-web. - -CHANGES The change history. Not needed to run ezmlm-web - -TODO This file is a list of things I intend doing in future - versions of ezmlm-web. That is if there are any future - versions :) Not needed to run ezmlm-web. - -ezmlm-web.cgi The ezmlm-web script proper. This program requires that - you have perl5 installed on your machine and that your web - server is capable of running CGI scripts. - -index.c A C wrapper to allow ezmlm-web.cgi to run suid. Not - strictly necessary if your setup allows perl scripts to - run suid, but I prefer using wrappers anyway. It needs to - be edited and compiled to suit your system. Not needed to - run ezmlm-web. - -htaccess.sample A sample Apache .htaccess file for controlling access to - the mailing lists. If you use another web server, you will - have to work this bit out for yourself. - -webusers.sample A sample webusers file for multi-level access control. - -V. Installation -=============== -1. Copy ezmlm-web.cgi to some publically readable directory. It does not - have to be in a path accessible to your web server, but any user with a - mailing list must be able to run it (Check the read and execute rights - on both the file and directory). We put our copy in - /usr/local/bin ... - -3. Edit the ezmlmwebrc file and alter the variables at the top to suit - your particular system. In particular, you will probably have to change - the $ENV{'PATH'} variable. Be particularly careful about what you set - as the path. Too much is a security risk and too little will cause the - script to malfunction. Version 2.0 requires that the following programs - be accessible in your path; mv, rm - - Also be careful about the $LIST_DIR variable. This script assumes that - all users store their mailing lists in the same sub directory of the - home directory (eg ~/lists). You can override this for an individual - user by recompiling the C wrapper to call ezmlm-web.cgi with a -d - option. - - Other configurable options are documented in the ezmlmwebrc file - itself. I have tried to keep the amount of information that you need to - supply to a minimum and also make reasonable guesses about default - values. - -4. Edit the index.c file and change the path to the path of your copy - of ezmlm-web.cgi. Then compile this file. You can do this by issuing - the command; gcc -o index.cgi index.c - -5. For every user/virtual host that needs to manage mailing lists, you - need to create a SUID (user not root!!) copy of index.cgi (see - chmod(1) for details). These need to reside somewhere accessible by - the web server. I suggest that you put them in a sub directory (see - about security) of each user/virtual host's home directory (eg - /home/luser/public_html/ezmlm for Apache on Redhat). - - The copies don't actually have to be called index.cgi, but it is nice - for web servers that can resolve a cgi script as an index page (see the - srm.conf file in Apache). It is important to make sure that whichever - directory you choose to put them can i: Execute CGI Scripts and ii: Be - access controlled (here I mean both web and user access) by some method - (eg .htaccess, access.conf for Apache). - -6. Install some method of securing access to the page. The following - information is applicable to Apache web servers ... Detailed - information on user authentication can be obtained from the Apache - documentation (http://www.apache.org) and ApacheWeek - (http://www.apacheweek.com/features/userauth) - -6.1 Ensure that your Apache setup will allow .htaccess file to control - access in the directory that contains. This is controlled by the - AllowOverride tag in access.conf. (Also ensure you have the - necessary Apache modules installed) - -6.2 Create a htpasswd file. This is done using the htpasswd command that - comes with Apache. Its command line syntax is; - htpasswd [-c] passwordfile username - - You need to put the passwordfile somewhere that is not accessible by - people through the web, and create an entry for each user you want - to have access ... See the ApacheWeek article for more details. - -6.3 Create a .htaccess file in the directory that contains index.cgi. - Note that using Apache's built in access control, you can only control - access to directories, not individual files, hence the need for a - sub-directory in step 5. - - The format of the .htaccess file should be along the lines of this; - - AuthName EZ Mailing List Manager - AuthType Basic - AuthUserFile /path/to/passwordfile - require valid-user # or require user username - - Again, see the ApacheWeek article for details. - -7. Test the installation through the web. You should be asked for a - username and password (supplied in 6.2) and then be presented with a - screen entitled EZ Mailing List Manger. You can then try to create and - edit mailing lists ... Have Fun :) - -VI. Notes -========= -* There is a function to delete mailing lists, but I really don't like the - idea. The only reason I put it in is that bvi@rucus asked for it. - If you set $UNSAFE_RD = 0 (the default) in the config section, the - ezmlm-web won't actually delete the list. In this case it moves the - to . and all the associated .qmail files to a sub-directory called - deleted.qmail/ (In the users home directory. This is by far a safer way - (since you can restore lists) and therefore I recommend it. - -* The HTML interface has been tested using Nutscrape, Internet Exploder, and - Lynx. If anyone uses anything else and has problems, please let me know. - -* I suggest that you make use of custom ezmlmwebrc files rather than using - the -d command line switches - it makes fault diagnosis easier ... - -* Please see the section on languages below. - -VII. Multi-Level Access -======================= -Ezmlm-web has a multi-level access system. This depends on a file called -webusers being present in $LIST_DIR. If the file is not present, then any -valid user has access to all lists. If, however, this file exists a number -of constraints come into place. - -- The webusers file is scanned for either the list name (case insensitive) or - an ALL (case sensitive) entry. -- The list entry (or ALL) is scanned for the current user (as set in - $REMOTE_USER) or an ALL entry. -- If any valid match is made, then the user is allowed to edit the list. - Otherwise the user is politely told to go away ;-) - -If list creation is allowed and the webusers file exists, then the person who -creates the list is the default owner. As of yet there is no way to add users -through the web interface, but I intend to do this eventually. - -The format of a webusers file is as follows; - -list1: user1, user2, user3 -ALL: user1, user2 -list2: ALL - -ie; listname colon (:) and a comma (,) separated list of users. Spaces are -ignored but each list must appear on a new line. - -Once this file exists, the ezmlm-web script will allow the list users to -configure their access lists along with any other options. - -Oh, and BTW, list creation through the web can now be disabled. The way to do -this is to compile the wrapper calling ezmlm-web.cgi with a -c switch. See the -example index.c file for more details. - -VIII. Language Portablity -========================= -One of the great new features of version 2.0 is that it is essentially -language independant (okay, not quite, but is 99% of the way there). Most of -the fixed strings, help, etc is defined in the RC file and thus can be -altered to suite a particular locale, language or even your own taste. - -If anyone gets round to writing full templates for languages I would -appreciate it if you would do two things; - -Firstly, make them public and announce them on the ezmlm@lists.cr.yp.to -mailing list so that others may benefit. - -Secondly, please mail me a copy (guy-ezmlm@rucus.ru.ac.za) so that I may use -them in any future releases of ezmlm-web. - - -IX. Bugs && Bug Reports -======================= -I don't know of any bugs, but then this is a rewrite and a first release. It -has been tested reasonably well, but not exhaustively. I know it works on -FreeBSD 4.0-STABLE, FreeBSD 3.4-RELEASE, RedHat 5.1 and Redhat 6.0 all using -an Apache web server, but I would be interested to know whether it works on -other OSs and with other web servers. This version is far less dependent on -the OS than previous versions so I don't see any reason why it shouldn't. - -Please mail bug reports and comments to guy-ezmlm@rucus.ru.ac.za - -X. Acknowledgements -=================== -* Keith Burdis (keith@rucus.ru.ac.za) - For constantly bugging me and - ensuring that I actually got round to writing some code :) -* Bryan Kilian (bryan@rucus.ru.ac.za) and the administrators of the - Litestep mailing list - For helping beta test and putting up with me - pestering them. -* Several societies at Rhodes. For switching to my web interface and so - unknowingly helping to beta test it. -* Barry Irwin (bvi@moria.org) - For trusting me and moving the Grahamstown - Foundation over to qmail and ezmlm - yet another beta tester :-) -* David Summers (david@summersoft.fay.ar.us) - For some ideas. And for - offering to make up an RPM version. I hope the offer still exists for - version 2.0 :-) -* Glen Stewart (glen_stewart@associate.com) - For a multitude of ideas. -* Fred Lindberg (lindberg@id.wustl.edu) for his useful posts to the - mailing list, suggestions, help, etc -* Galen Johnson (gjohnson@totalsports.net) - For some ideas on bugfixes. - -XI. Availability -================= -The latest version of ezmlm-web will always be available on; -ftp://rucus.ru.ac.za/pub/mail/ezmlm/ - -More information on ezmlm-web and developments to ezmlm-web can be found at; -http://rucus.ru.ac.za/~guy/ezmlm/ diff --git a/ezmlm-web/tags/ezmlm-web-2.1/TODO b/ezmlm-web/tags/ezmlm-web-2.1/TODO deleted file mode 100644 index 75d3540..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/TODO +++ /dev/null @@ -1,8 +0,0 @@ -$Id: TODO,v 1.3 2000/09/25 19:58:02 guy Exp $ - -TODO - ezmlm-web 2.1 - -- More Documentation -- Maybe allowing user specific overides on the -c option. -- Some nice install method. But then I use FreeBSD and ported it - so that might just count as my nice install method :) diff --git a/ezmlm-web/tags/ezmlm-web-2.1/UPGRADING b/ezmlm-web/tags/ezmlm-web-2.1/UPGRADING deleted file mode 100644 index 03e20fc..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/UPGRADING +++ /dev/null @@ -1,18 +0,0 @@ -$Id: UPGRADING,v 1.1 2000/09/25 19:24:20 guy Exp $ - -UPGRADING ezmlm-web 2.0 to ezmlm-web 2.1 - -There are no major changes that need to be made in order to upgrade. All -that is necessary is to add two new lines to your ezmlmwebrc ... In the top -section of the file add - -$FILE_UPLOAD = 1; - -and in the %HELPER section, you need to add - -addaddressfile => 'or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line', - -(or just copy the new ezmlmwebrc :) - -Have a look for these two lines in the new ezmlmwebrc included in this -distribution if you are unsure of how/where to put these. diff --git a/ezmlm-web/tags/ezmlm-web-2.1/ezmlm-web.cgi b/ezmlm-web/tags/ezmlm-web-2.1/ezmlm-web.cgi deleted file mode 100755 index 0072489..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/ezmlm-web.cgi +++ /dev/null @@ -1,1084 +0,0 @@ -#!/usr/bin/perl -T -#=========================================================================== -# ezmlm-web.cgi - version 2.1 - 25/09/2000 -# $Id: ezmlm-web.cgi,v 1.3 2000/09/25 19:58:07 guy Exp $ -# -# Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved. -# Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# Neither name Guy Antony Halse nor the names of any contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# ========================================================================== -# All user configuration happens in the config file ``ezmlmwebrc'' -# POD documentation is at the end of this file -# ========================================================================== - -# Modules to include -use strict; -use Getopt::Std; -use Mail::Ezmlm; -use Mail::Address; -use DB_File; -use CGI; -use CGI::Carp qw(fatalsToBrowser set_message); - -# These two are actually included later and are put here so we remember them. -#use File::Find if ($UNSAFE_RM == 1); -#use File::Copy if ($UNSAFE_RM == 0); - -my $q = new CGI; -$q->import_names('Q'); -use vars qw[$opt_c $opt_d $opt_C]; -getopts('cd:C:'); - -# Suid stuff requires a secure path. -$ENV{'PATH'} = '/bin'; - -# We run suid so we can't use $ENV{'HOME'} and $ENV{'USER'} to determine the -# user. :( Don't alter this line unless you are _sure_ you have to. -my @tmp = getpwuid($>); my $USER=$tmp[0]; - -# use strict is a good thing++ - -use vars qw[$HOME_DIR]; $HOME_DIR=$tmp[7]; -use vars qw[$DEFAULT_OPTIONS %EZMLM_LABELS $UNSAFE_RM $ALIAS_USER $LIST_DIR]; -use vars qw[$QMAIL_BASE $EZMLM_CGI_RC $EZMLM_CGI_URL $HTML_BGCOLOR $PRETTY_NAMES]; -use vars qw[%HELPER $HELP_ICON_URL $HTML_HEADER $HTML_FOOTER $HTML_TEXT $HTML_LINK]; -use vars qw[%BUTTON %LANGUAGE $HTML_VLINK $HTML_TITLE $FILE_UPLOAD]; - -# Get user configuration stuff -if(defined($opt_C)) { - require "$opt_C"; # Command Line -} elsif(-e "$HOME_DIR/.ezmlmwebrc") { - require "$HOME_DIR/.ezmlmwebrc"; # User -} elsif(-e "/etc/ezmlm/ezmlmwebrc") { - require "/etc/ezmlm/ezmlmwebrc"; # System -} elsif(-e "./ezmlmwebrc") { - require "./ezmlmwebrc"; # Install -} else { - die "Unable to read config file"; -} - -# Allow suid wrapper to over-ride default list directory ... -if(defined($opt_d)) { - $LIST_DIR = $1 if ($opt_d =~ /^([-\@\w.\/]+)$/); -} - -# Work out default domain name from qmail (for David Summers) -my($DEFAULT_HOST); -open (GETHOST, "<$QMAIL_BASE/me") || open (GETHOST, "<$QMAIL_BASE/defaultdomain") || die "Unable to read $QMAIL_BASE/me: $!"; -chomp($DEFAULT_HOST = ); -close GETHOST; - -# Untaint form input ... -&untaint; - -# redirect must come before headers are printed -if(defined($Q::action) && $Q::action eq '[Web Archive]') { - print $q->redirect(&ezmlmcgirc); - exit; -} - -# Print header on every page ... -print $q->header(-pragma=>'no-cache', '-cache-control'=>'no-cache', -expires=>'-1d'); -print $q->start_html(-title=>$HTML_TITLE, -author=>'guy-ezmlm@rucus.ru.ac.za', -BGCOLOR=>$HTML_BGCOLOR, -LINK=>$HTML_LINK, -VLINK=>$HTML_VLINK, -TEXT=>$HTML_TEXT, -expires=>'-1d'); -print $HTML_HEADER; - -# This is where we decide what to do, depending on the form state and the -# users chosen course of action ... -unless (defined($q->param('state'))) { - # Default action. Present a list of available lists to the user ... - &select_list; - -} elsif ($Q::state eq 'select') { - # User selects an action to perorm on a list ... - - if ($Q::action eq "[$BUTTON{'create'}]") { # Create a new list ... - &allow_create_list; - } elsif (defined($Q::list)) { - if ($Q::action eq "[$BUTTON{'edit'}]") { # Edit an existing list ... - &display_list; - } elsif ($Q::action eq "[$BUTTON{'delete'}]") { # Delete a list ... - &confirm_delete; - } - } else { - &select_list; # NOP - Blank input ... - } - -} elsif ($Q::state eq 'edit') { - # User chooses to edit a list - - my($list); $list = $LIST_DIR . '/' . $q->param('list'); - if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ... - &delete_address($list); - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address($list); - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'moderators'}]") { # Edit the moderators ... - &part_subscribers('mod'); - - } elsif ($Q::action eq "[$BUTTON{'denylist'}]") { # Edit the deny list ... - &part_subscribers('deny'); - - } elsif ($Q::action eq "[$BUTTON{'allowlist'}]") { # edit the allow list ... - &part_subscribers('allow'); - - } elsif ($Q::action eq "[$BUTTON{'digestsubscribers'}]") { # Edit the digest subscribers ... - &part_subscribers('digest'); - - } elsif ($Q::action eq "[$BUTTON{'configuration'}]") { # Edit the config ... - &list_config; - - } else { # Cancel - Return a screen ... - &select_list; - } - -} elsif ($Q::state eq 'allow' || $Q::state eq 'mod' || $Q::state eq 'deny' || $q->param('state') eq 'digest') { - # User edits moderators || deny || digest ... - - my($part); - # Which list directory are we using ... - if($Q::state eq 'mod') { - $part = 'mod'; - } elsif($Q::state eq 'deny' ) { - $part = 'deny'; - } elsif($Q::state eq 'allow') { - $part = 'allow'; - } else { - $part = 'digest'; - } - - if ($Q::action eq '[Delete Address]') { # Delete a subscriber ... - &delete_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } else { # Cancel - Return to the list ... - &display_list; - } - -} elsif ($Q::state eq 'confirm_delete') { - # User wants to delete a list ... - - &delete_list if($q->param('confirm') eq "[$BUTTON{'yes'}]"); # Do it ... - $q->delete_all; - &select_list; - -} elsif ($Q::state eq 'create') { - # User wants to create a list ... - - if ($Q::action eq "[$BUTTON{'createlist'}]") { - if (&create_list) { # Return if list creation is unsuccessful ... - &allow_create_list; - } else { - &select_list; # Else choose a list ... - } - - } else { # Cancel ... - &select_list; - } - -} elsif ($Q::state eq 'configuration') { - # User updates configuration ... - - if ($Q::action eq "[$BUTTON{'updateconfiguration'}]") { # Save current settings ... - &update_config; - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'edittexts'}]") { # Edit DIR/text ... - &list_text; - - } else { # Cancel - Return to list editing screen ... - &display_list; - } - -} elsif ($Q::state eq 'list_text') { - # User wants to edit texts associated with the list ... - - if ($Q::action eq "[$BUTTON{'editfile'}]") { - &edit_text; - } else { - &list_config; # Cancel ... - } - -} elsif ($Q::state eq 'edit_text') { - # User wants to save a new version of something in DIR/text ... - - &save_text if ($Q::action eq "[$BUTTON{'savefile'}]"); - &list_text; - -} else { - print "

$Q::action

$LANGUAGE{'nop'}


"; -} - -# Print HTML footer and exit :) ... -print $HTML_FOOTER, $q->end_html; -exit; - -# ========================================================================= - -sub select_list { - # List all mailing lists (sub directories) in the list directory. - # Allow the user to choose a course of action; either editing an existing - # list, creating a new one, or deleting an old one. - - my (@lists, @files, $i, $scrollsize); - - # Read the list directory for mailing lists. - opendir DIR, $LIST_DIR || die "Unable to read $LIST_DIR: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Check that they actually are lists ... - foreach $i (0 .. $#files) { - if (-e "$LIST_DIR/$files[$i]/lock") { - if (-e "$LIST_DIR/webusers") { - if (&webauth($files[$i]) == 0) { - $lists[$#lists + 1] = $files[$i]; - } - } else { - $lists[$#lists + 1] = $files[$i]; - } - } - } - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#lists + 1) > 25); - - # Print a form - $q->delete_all; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'select'); - print '
'; - print $q->scrolling_list(-name=>'list', -size=>$scrollsize, -values=>\@lists) if defined(@lists); - - print '', $LANGUAGE{'chooselistinfo'}; - - print $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), ' ' if (!defined($opt_c)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), ' ' if(defined(@lists)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]") if(defined(@lists)); - print '
'; - print $q->endform; -} - -# ------------------------------------------------------------------------ - -sub confirm_delete { - # Make sure that the user really does want to delete the list! - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'confirm_delete'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print '

', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '


'; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'no'}]"), ' '; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), '
'; -} - -# ------------------------------------------------------------------------ - -sub display_list { - # Show a list of subscribers to the user ... - - my ($i, $list, $listaddress, $moderated, @subscribers, $scrollsize); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - - # Get a list of subscribers from ezmlm ... - @subscribers = $list->subscribers; - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - print "

$LANGUAGE{'subscribersto'} $Q::list ($listaddress)


"; - print $q->start_multipart_form; - print '
'; - print $q->hidden(-name=>'state', -default=>'edit'); - print $q->hidden(-name=>'list', -default=>$Q::list); - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -labels=>&pretty_names, -multiple=>'true') if defined(@subscribers); - print ''; - print ' ', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, '
' if defined(@subscribers); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); - print $q->textfield(-name=>'addsubscriber', -size=>'40'), ' ', $HELPER{'addaddress'}, '
'; - print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ', $HELPER{'addaddressfile'}, '
' if ($FILE_UPLOAD); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print '', $LANGUAGE{'additionalparts'}, ':
' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), '', $HELPER{'moderator'}, ' ' if ($list->ismodpost || $list->ismodsub || $list->isremote); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), '', $HELPER{'deny'}, ' ' if ($list->isdeny); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), '', $HELPER{'allow'}, ' ' if ($list->isallow); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), '', $HELPER{'digest'}, ' ' if ($list->isdigest); - print '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), '', $HELPER{'webarch'}, ' ' if(&ezmlmcgirc); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), '', $HELPER{'config'}, '   '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'selectlist'}]"); - print '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub delete_list { - # Delete a list ... - - # Fixes a bug from the previous version ... when the .qmail file has a - # different name to the list. We use outlocal to handle vhosts ... - my ($list, $listaddress, $listadd); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - if ($listadd = $list->getpart('outlocal')) { - chomp($listadd); - } else { - $listadd = $q->param('list'); - } - $listaddress = $1 if ($listadd =~ /-?(\w+)$/); - - if ($UNSAFE_RM == 0) { - # This doesn't actually delete anything ... It just moves them so that - # they don't show up. That way they can always be recovered by a helpful - # sysadmin should he be in the mood :) - - use File::Copy; - - my ($oldfile); $oldfile = "$LIST_DIR/$Q::list"; - my ($newfile); $newfile = "$LIST_DIR/.$Q::list"; - move($oldfile, $newfile) or die "Unable to rename list: $!"; - mkdir "$HOME_DIR/deleted.qmail", 0700 if(!-e "$HOME_DIR/deleted.qmail"); - - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - foreach (@files) { - unless (move($_, "$HOME_DIR/deleted.qmail/")) { - die "Unable to move .qmail files: $!"; - } - } - warn "List '$oldfile' moved (deleted)"; - } else { - # This, however, does DELETE the list. I don't like the idea, but I was - # asked to include support for it so ... - if (!rmtree("$LIST_DIR/$Q::list")) { - die "Unable to delete list: $!"; - } - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - if (unlink(@files) <= 0) { - die "Unable to delete .qmail files: $!"; - } - warn "List '$list->thislist()' deleted"; - } -} - -# ------------------------------------------------------------------------ -sub untaint { - - $DEFAULT_HOST = $1 if $DEFAULT_HOST =~ /^([\w\d\.-]+)$/; - - # 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 ... - - my (@params, $i, $param); - @params = $q->param; - - foreach $i (0 .. $#params) { - my(@values); - next if($params[$i] eq 'addfile'); - foreach $param ($q->param($params[$i])) { - next if $param eq ''; - if ($param =~ /^([#-\@\w\.\/\[\]\:\n\r\>\< ]+)$/) { - push @values, $1; - } else { - warn "Tainted input in '$params[$i]': " . $q->param($params[$i]); - } - $q->param(-name=>$params[$i], -values=>\@values); - } - } - $q->import_names('Q'); -} - -# ------------------------------------------------------------------------ - -sub add_address { - # Add an address to a list .. - - my ($address, $list, @addresses, $count); my ($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - - if($q->param('addfile')) { - - # Sanity check - die "File upload must be of type text/*" unless($q->uploadInfo($q->param('addfile'))->{'Content-Type'} =~ m{^text/}); - - # Handle file uploads of addresses - my($fh) = $q->upload('addfile'); - return unless (defined($fh)); - while (<$fh>) { - next if (/^\s*$/ or /^#/); # blank, comments - next unless (/\@/); # email address ... - chomp(); - push @addresses, $_; - } - - } else { - - # User typed in an address - return if ($q->param('addsubscriber') eq ''); - - $address = $q->param('addsubscriber'); - $address .= $DEFAULT_HOST if ($q->param('addsubscriber') =~ /\@$/); - push @addresses, $address; - - } - - foreach $address (@addresses) { - - my($add) = Mail::Address->parse($address); - if(defined($add->name()) && $PRETTY_NAMES) { - my(%pretty); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - $pretty{$add->address()} = $add->name(); - untie %pretty; - } - - if ($list->sub($add->address(), $part) != 1) { - die "Unable to subscribe to list: $!"; - } - $count++; - } - - $q->delete('addsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub delete_address { - # Delete an address from a list ... - - my ($list, @address); my($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - return if ($q->param('delsubscriber') eq ''); - - @address = $q->param('delsubscriber'); - - if ($list->unsub(@address, $part) != 1) { - die "Unable to unsubscribe from list $list: $!"; - } - - if($PRETTY_NAMES) { - my(%pretty, $add); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - foreach $add (@address) { - delete $pretty{$add}; - } - untie %pretty; - } - - $q->delete('delsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub part_subscribers { - my($part) = @_; - # Deal with list parts .... - - my ($i, $list, $listaddress, @subscribers, $moderated, $scrollsize, $type); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - if($part eq 'mod') { - # Lets know what is moderated :) - - # do we store things in different directories? - my $config = $list->getconfig; - my($postpath) = $config =~ m{7\s*'([^']+)'}; - my($subpath) = $config =~ m{8\s*'([^']+)'}; - my($remotepath) = $config =~ m{9\s*'([^']+)'}; - - $moderated = '' if ($postpath); - $moderated .= "[$LANGUAGE{'posting'}]" if ($list->ismodpost); - $moderated .= 'Posting Moderators are stored in a non-standard location (' . $postpath . '). You will have to edit them manually.' if ($postpath); - $moderated .= '' if ($subpath); - $moderated .= " [$LANGUAGE{'subscription'}]" if($list->ismodsub); - $moderated .= 'Subscriber Moderators are stored in a non-standard location (' . $subpath . '). You will have to edit them manually' if ($subpath); - $moderated .= '' if ($remotepath); - $moderated .= " [$LANGUAGE{'remoteadmin'}]" if($list->isremote); - $moderated .= 'Remote Administrators are stored in a non-standard location (' . $remotepath . '). You will have to edit them manually' if ($remotepath); - - } - - # What type of sublist is this? - ($type) = $Q::action =~ m/^\[(.+)\]$/; - - # Get a list of moderators from ezmlm ... - @subscribers = $list->subscribers($part); - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - print "

$type $LANGUAGE{'for'} $listaddress


"; - print "
$moderated

" if(defined($moderated)); - print $q->start_multipart_form; - print '

'; - print $q->hidden(-name=>'state', -default=>$part); - print $q->hidden(-name=>'list', -default=>$Q::list), "\n"; - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -multiple=>'true', -labels=>&pretty_names) if defined(@subscribers); - print '
'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); - print $q->textfield(-name=>'addsubscriber', -size=>'40'), ' ', $HELPER{'addaddress'}, '
'; - print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ', $HELPER{'addaddressfile'}, '
' if ($FILE_UPLOAD); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'subscribers'}]"); - print '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub allow_create_list { - # Let the user select options for list creation ... - - my($username, $hostname, %labels, $j); - - # 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; - } - - # Print a form of options ... - $q->delete_all; - print '

', $LANGUAGE{'createnew'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'create'); - print '', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), ' ', $HELPER{'listname'}, '

'; - print '', $LANGUAGE{'listaddress'}, ': '; - print $q->textfield(-name=>'inlocal', -default=>$username, -size=>'10'); - print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), ' ', $HELPER{'listadd'}, '

'; - - print '

', $LANGUAGE{'listoptions'}, ':'; - &display_options($DEFAULT_OPTIONS); - - # Allow creation of mysql table if the module allows it - if($Mail::Ezmlm::MYSQL_BASE) { - print '

', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1); - print ' ', $HELPER{'mysqlcreate'}, ''; - - } - - print '

', $LANGUAGE{'allowedtoedit'}, ': ', - $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30'), ' ', $HELPER{'webusers'}, '', - '
', $HELPER{'allowedit'}, '' - if(-e "$LIST_DIR/webusers"); - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'createlist'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub create_list { - # Create a list acording to user selections ... - - # Check the list directory exists and create if necessary ... - if(!-e $LIST_DIR) { - die "Unable to create directory ($LIST_DIR): $!" unless mkdir $LIST_DIR, 0700; - } - - my ($qmail, $listname, $options, $i); - - # Some taint checking ... - $qmail = $1 if $q->param('inlocal') =~ /(?:$USER-)?([^\<\>\\\/\s]+)$/; - $listname = $q->param('list'); $listname =~ s/ /_/g; # In case some git tries to put a space in the file name - - # Sanity Checks ... - return 1 if ($listname eq '' || $qmail eq ''); - if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) { - print "

List '$listname' already exists :(

"; - return 1; - } - - # Work out the command line options - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - my($list) = new Mail::Ezmlm; - - unless ($list->make(-dir=>"$LIST_DIR/$listname", - -qmail=>"$HOME_DIR/.qmail-$qmail", - -name=>$q->param('inlocal'), - -host=>$q->param('inhost'), - -switches=>$options, - -user=>$USER) - ) { - die 'List creation failed', $list->errmsg(); - } - - # handle MySQL stuff - if($q->param('sql') && $options =~ m/-6\s+/) { - unless($list->createsql()) { - die 'SQL table creation failed: ', $list->errmsg(); - } - } - - # Handle authentication stuff - if ($Q::webusers) { - open(WEBUSER, ">>$LIST_DIR/webusers") || die "Unable to open webusers: $!"; - print WEBUSER "$Q::list: $Q::webusers\n"; - close WEBUSER; - } - - return 0; -} - -# ------------------------------------------------------------------------ - -sub list_config { - # Allow user to alter the list configuration ... - - my ($list, $listaddress, $listname, $options); - my ($headeradd, $headerremove, $mimeremove, $prefix, $j); - - # Store some variables before we delete them ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listname = $q->param('list'); - $listaddress = &this_listaddress; - - # Print a form of options ... - $q->delete_all; - print '

', $LANGUAGE{'editconfiguration'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'configuration'); - print $q->hidden(-name=>'list', -value=>$listname); - print '', $LANGUAGE{'listname'}, ": $listname
"; - print "$LANGUAGE{'listaddress'}: $listaddress

"; - print '', $LANGUAGE{'listoptions'}, ':
'; - - # Print a list of options, selecting the ones that apply to this list ... - &display_options($list->getconfig); - - # Get the contents of the headeradd, headerremove, mimeremove and prefix files - $headeradd = $list->getpart('headeradd'); - $headerremove = $list->getpart('headerremove'); - $mimeremove = $list->getpart('mimeremove'); - $prefix = $list->getpart('prefix'); - - print '

', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), ' ', $HELPER{'prefix'}, '' if defined($prefix); - print '

', $LANGUAGE{'headerremove'}, ': ', $HELPER{'headerremove'}, '
', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70); - print '

', $LANGUAGE{'headeradd'}, ': ', $HELPER{'headeradd'}, '
', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70); - print '

', $LANGUAGE{'mimeremove'}, ': ', $HELPER{'mimeremove'}, '
', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70) if defined($mimeremove); - - if(open(WEBUSER, "<$LIST_DIR/webusers")) { - my($webusers); - while() { - last if (($webusers) = m{^$listname\s*\:\s*(.+)$}); - } - close WEBUSER; - $webusers ||= $ENV{'REMOTE_USER'} || 'ALL'; - - print '

', $LANGUAGE{'allowedtoedit'}, ': ', - $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30'), ' ', $HELPER{'webusers'}, '', - '
', $HELPER{'allowedit'}, ''; - - } - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edittexts'}]"); - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub update_config { - # Save the new user entered config ... - - my ($list, $options, $i, @inlocal, @inhost); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - - # Work out the command line options ... - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - # Actually update the list ... - unless($list->update($options)) { - die "List update failed"; - } - - # Update headeradd, headerremove, mimeremove and prefix ... - $list->setpart('headeradd', $q->param('headeradd')); - $list->setpart('headerremove', $q->param('headerremove')); - $list->setpart('mimeremove', $q->param('mimeremove')) if defined($q->param('mimeremove')); - $list->setpart('prefix', $q->param('prefix')) if defined($q->param('prefix')); - - if($Q::webusers) { - # Back up web users file - open(TMP, ">/tmp/ezmlm-web.$$"); - open(WU, "<$LIST_DIR/webusers"); - while() { print TMP; } - close TMP; close WU; - - open(TMP, "$LIST_DIR/webusers"); - while() { - if(/^$Q::list\s*:/) { - print WU "$Q::list\: $Q::webusers\n"; - } else { - print WU; - } - } - close TMP; close WU; - unlink "/tmp/ezmlm-web.$$"; - } - -} - -# ------------------------------------------------------------------------ - -sub this_listaddress { - # Work out the address of this list ... Used often so put in its own subroutine ... - - my ($list, $listaddress); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - chomp($listaddress = $list->getpart('outlocal')); - $listaddress .= '@'; - chomp($listaddress .= $list->getpart('outhost')); - return $listaddress; -} - -# ------------------------------------------------------------------------ - -sub list_text { - # Show a listing of what is in DIR/text ... - - my(@files, $list); - $list = $LIST_DIR . '/' . $q->param('list'); - - # Read the list directory for text ... - opendir DIR, "$list/text" || die "Unable to read DIR/text: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'list_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print '

'; - print $q->scrolling_list(-name=>'file', -values=>\@files); - print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'editfile'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print '

', $LANGUAGE{'edittextinfo'}, '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub edit_text { - # Allow user to edit the contents of DIR/text ... - - my ($content); - my($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $content = $list->getpart("text/$Q::file"); - - # Print a form ... - $q->delete('state'); - print '

', $LANGUAGE{'editingfile'}, ': ', $Q::file, '

'; - print '
'; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'edit_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print $q->hidden(-name=>'file', -default=>$q->param('file')); - print $q->textarea(-name=>'content', -default=>$content, -rows=>'25', -columns=>'72'); - print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'savefile'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print '

', $LANGUAGE{'editfileinfo'}; - print $q->endform; - print '

' - -} - -# ------------------------------------------------------------------------ - -sub save_text { - # Save new text in DIR/text ... - - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $list->setpart("text/$Q::file", $q->param('content')); - -} - -# ------------------------------------------------------------------------ - -sub webauth { - - # Read authentication level from webusers file. Format of this file is - # somewhat similar to the unix groups file - my($listname) = @_; - open (USERS, "<$LIST_DIR/webusers") || die "Unable to read webusers file: $!"; - while() { - if (/^($listname|ALL)\:/i) { - if (/(\:\s*|,\s+)((?:$ENV{'REMOTE_USER'})|(?:ALL))\s*(,|$)/) { - close USERS; return 0; - } - } - } - close USERS; - return 1; -} - -# --------------------------------------------------------------------------- - -sub display_options { - my($opts) = shift; - my($i, $j); - - print ""; - print ''; $j++; - if ($j >= 3) { - $j = 0; print ''; - } - print '
'; - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if ($opts =~ /^\w*$i\w*\s*/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print '', $EZMLM_LABELS{$i}[1] , ''; - print '
'; - } - print '
'; - - print ''; - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - print ''; - - } - print '
'; - if ($opts =~ /$i (?:'(.+?)')/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print '', $EZMLM_LABELS{$i}[1] , ''; - print ''; - print $q->textfield(-name=>"$i-value", -value=>$1||$EZMLM_LABELS{$i}[2], -size=>30); - print '
'; - -} - -# --------------------------------------------------------------------------- - -sub ezmlmcgirc { - my($listno); - if(open(WWW, "<$EZMLM_CGI_RC")) { - while() { - last if (($listno) = m{(\d+)(\D)\d+\2$LIST_DIR/$Q::list\2}); - } - close WWW; - return "$EZMLM_CGI_URL/$listno" if(defined($listno)); - } return undef; - -} - -# --------------------------------------------------------------------------- - -sub pretty_names { - return undef unless($PRETTY_NAMES); - my (%pretty, %prettymem); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - %prettymem = %pretty; - untie %pretty; - - return \%prettymem; -} - -# ------------------------------------------------------------------------- -sub rmtree { - # A subroutine to recursively delete a directory (like rm -f). - # Based on the one in the perl cookbook :) - - use File::Find qw(finddepth); - File::Find::finddepth sub { - # assume that File::Find::name is secure since it only uses data we pass it - my($name) = $File::Find::name =~ m{^(.+)$}; - - if (!-l && -d _) { - rmdir($name) or warn "couldn't rmdir $name: $!"; - } else { - unlink($name) or warn "couldn't unlink $name: $!"; - } - }, @_; - 1; -} - -# ------------------------------------------------------------------------ - -BEGIN { - sub handle_errors { - my $msg = shift; - print << "EOM"; - -
-

A fatal error has occoured

- Something you did caused this script to bail out. The error - message we got was

- $msg

- Please try what you were doing again, checking everything you entered.
- If you still find yourself getting this error, please - contact the site administrator - quoting the error message above. -

-EOM - - } - set_message(\&handle_errors); -} - -# ------------------------------------------------------------------------ -# End of ezmlm-web.cgi v2.1 -# ------------------------------------------------------------------------ -__END__ - -=head1 NAME - -ezmlm-web - A web configuration interface to ezmlm mailing lists - -=head1 SYNOPSIS - -ezmlm-web [B<-c>] [B<-C> EFE] [B<-d> EFE] - -=head1 DESCRIPTION - -=over 4 - -=item B<-c> Disable list configuration - -=item B<-C> Specify an alternate configuration file given as F -If not specified, ezmlm-web checks first in the users home directory, then in -F and then the current directory - -=item B<-d> Specify an alternate directory where lists live. This is now -depreciated in favour of using a custom ezmlmwebrc, but is left for backward -compatibility. - -=back - -=head1 SUID WRAPPER - -C<#include stdio.h> - -C - C - C -C<}> - - -=head1 DOCUMENTATION/CONFIGURATION - - Please refer to the example ezmlmwebrc which is well commented, and - to the README file in this distribution. - -=head1 FILES - -F<~/.ezmlmwebrc> -F -F<./ezmlmwebrc> - -=head1 AUTHOR - - Guy Antony Halse - -=head1 BUGS - - None known yet. Please report bugs to the author. - -=head1 S - - ezmlm(5), ezmlm-cgi(1), Mail::Ezmlm(3) - - http://rucus.ru.ac.za/~guy/ezmlm/ - http://www.ezmlm.org/ - http://www.qmail.org/ diff --git a/ezmlm-web/tags/ezmlm-web-2.1/ezmlmwebrc b/ezmlm-web/tags/ezmlm-web-2.1/ezmlmwebrc deleted file mode 100644 index 7c37330..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/ezmlmwebrc +++ /dev/null @@ -1,268 +0,0 @@ -# $Id: ezmlmwebrc,v 1.5 2000/09/25 18:25:26 guy Exp $ -# Configuration file for ezmlm-web 2.1 -# =========================================================================== - -# This file is not just an ordinary configuration file - it contains valid -# perl statements that are executed just like any other perl script. When -# editing this file, be careful that it is still valid perl when you have -# finished (perl -w ezmlmwebrc ;-) - -# It is divided into to logical parts. The first part configures the way -# ezmlm-web runs, and the second changes the language, etc of ezmlm-web. You -# can not arbitarilly exclude any statement, since the script doesn't define -# any defaults of its own. You could, however, always split this file up and -# include the parts with -# -# require('/path/to/other/part'); - -# --------------------------------------------------------------------------- - -# Where do we store lists on this server ... Try "$HOME_DIR/lists". -# This directory will automatically be created if needed. -$LIST_DIR = "$HOME_DIR/lists"; - -# Safe list deletion? -# 0 = move list to .list and the .qmails to deleted.qmail/. Recoverable :) -# 1 = allow user to delete list completely. No backup, therefore no recovery. -$UNSAFE_RM = 0; - -# Who is the alias user on this system (usually alias ;) -$ALIAS_USER = 'alias'; - -# Where do the qmail control files live on this system ... -$QMAIL_BASE = $Mail::Ezmlm::QMAIL_BASE . '/control'; - -# The url to our web interface - so we can use ezmlm-cgi if necessary -$EZMLM_CGI_URL = 'http://some.server.that.has/cgi-bin/ezmlm-cgi'; - -# Where our ezcgirc file lives (probably /etc/ezmlm/ezcgirc) -$EZMLM_CGI_RC = '/etc/ezmlm/ezcgirc'; - -# Do we want to allow ``pretty'' names - ie more human readable ones -# This will slow ezmlm-web down a bit for large lists -$PRETTY_NAMES = 1; - -# Do we want to allow the users to be allowed to upload a file containing -# lists of email addresses to subscribe? -$FILE_UPLOAD = 1; - -# What switches to we want ezmlm-web to have on as default. The ezmlm-make -# defaults are aBDFGHIJKLMNOpQRSTUWX (small means enabled, CAPITALS mean -# disabled). The defaults below should be reasonable - I use them ;) -$DEFAULT_OPTIONS = 'aBDFGHiJkLMNOpQRSTUWx'; - -# Where do we find the nice little help icon - by default HELP_ICON_URL -# points to resources on http://rucus.ru.ac.za/. This will work, but we -# would appreciate it if you changed this to a local site. -$HELP_ICON_URL = 'http://rucus.ru.ac.za/icons/small/unknown.gif'; - -# Header for every page (.= concatinates) -$HTML_HEADER = '
E Z Mailing List Manager

'; -$HTML_HEADER .= '
'; - -# Footer for every page (.= concatinates) -$HTML_FOOTER = '
'; -$HTML_FOOTER .= '
'; -$HTML_FOOTER .= 'ezmlm-web (v2.1) A web interface to ezmlm
'; - -# What colour do we want the background to be? -$HTML_BGCOLOR = '#000080'; - -# What colour do we want text? -$HTML_TEXT = '#000000'; - -# What color do we want links? -$HTML_LINK = '#3333ff'; - -# What color to we want visited links? -$HTML_VLINK = '#8888ff'; - -# What is the title of this document? -$HTML_TITLE = 'E Z Mailing List Manager'; - -# --------------------------------------------------------------------------- - -# The meanings of the various ezmlm-make command line switches. The default -# ones match the ezmlm-idx 0.4 default ezmlmrc ... Alter them to suit your -# own ezmlmrc. Removing options from this list makes them unavailable -# through ezmlm-web - this could be useful for things like -w - -%EZMLM_LABELS = ( -# option => ['Short Name', -# 'Long Help Description'], - - a => ['Archived', - 'Ezmlm will archive new messages'], - b => ['Block archive', - 'Only moderators are allowed to access the archive'], -# c => config. This is implicity called, so is not defined here - d => ['Digest', - 'Set up a digest list to disseminate digest of the list messages'], -# e => edit. Also implicity called, so not defined here - f => ['Prefix', - 'Outgoing subject will be prefixed with the list name'], - g => ['Guard Archive', - 'Archive access requests from unrecognized SENDERs will be rejected'], - h => ['Help subscription', - 'Subscriptions do not require confirmation'], - i => ['Indexed', - 'Indexed for WWW archive access'], - j => ['Jump off', - 'Unsubscribe does not require confirmation'], - k => ['Kill', - 'Posts from addresses in dir/deny/ are rejected'], - l => ['Subscriber List', - 'Remote administrators can request a subscriber list'], - m => ['Message Moderation', - 'All incoming messages are moderated'], - n => ['Text Editing', - 'Allow remote administrators to edit files in dir/text/'], - o => ['Others rejected', - 'Posts from addresses other than moderators are rejected'], - p => ['Public', - 'List will respond to administrative requests and archive retrieval'], - q => ['Service Request Address', - 'Process commands sent in the subject to local-request@host'], - r => ['Remote Admin', - 'Enable remote adminstration of the list'], - s => ['Subscription Moderation', - 'Subscriptions to the main list and digest will be moderated'], - t => ['Trailer', - 'Add a trailer to outgoing messages'], - u => ['User Posts Only', - 'Posts from unrecognized SENDER addresses will be rejected'], -# v => version. I doubt you will really need this ;-) - w => ['Remove Warn', - 'Remove the ezmlm-warn(1) invocations from the list setup. It is assumed that ezmlm-warn(1) is run by other means'], - x => ['Extra', - 'Strip certain mimetypes, etc'], -# y => not used -# z => not used - -# These all take an extra argument, which is the default value to use - - 0 => ['Sublist', - 'Make the list a sublist of list mainlist@host', - 'mainlist@host'], -# 1 => not used -# 2 => not used - 3 => ['From Address', - 'Replace the "From:" header of the message with "From: fromarg"', - 'fromarg'], - 4 => ['Digest Options', - 'Switches for ezmlm-tstdig(1)', - '-t24 -m30 -k64'], - 5 => ['List Owner', - 'The email address of the list owner', - ''], - 6 => ['SQL Database', - 'SQL database connect information. Requires SQL support', - 'host:port:user:password:datab:table'], - 7 => ['Message Moderation Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'], - 8 => ['Subscription Moderation Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'], - 9 => ['Remote Admin Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'] - -); - -# This list defines most of the context sensitive help in ezmlm-web. What -# isn't defined here is the options, which are defined above ... You can -# alter these if you feel something else would make more sense to your users -# Just be careful of what can fit on a screen! - -%HELPER = ( - - # These should be self explainitory - addaddress => 'You may enter any RFC822 compliant email address here, including the comment part. For example; J Random User ', - addaddressfile => 'or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line', - moderator => 'Moderators: people who control who may subscribe or post to a list', - deny => 'Deny: A list of addresses that are _never_ allowed to mail the list', - allow => 'Allow: A list of address that are allowed to mail the list even if the configuration otherwise restricts it', - digest => 'Digest: People who will recieve a digest of all messages on the list', - webarch => 'View the web based archive of this list', - config => 'This lets you alter the way the list is set up', - listname => 'This is the name of the list as displayed on the Select Lists screen. It is also the name of the subdirectory that contains the list', - listadd => 'This is the email address of the list. Note that the defaults come from your qmail config. You should just update the local part (before the @)', - webusers => 'NB! At this stage, any users specified here must exist. User creation may be added in future versions', - prefix => 'Text to add to the subject line of all outgoing messages', - headerremove => 'This is a list of headers to remove from all outgoing mail', - headeradd => 'This is a list of headers to add to all outging mail', - mimeremove => 'All messages whose Content-Type matches these mime types will be bounced back to sender', - allowedit => 'Comma separated list of usernames, or ALL (all valid users)', - mysqlcreate => 'This will create the necessary MySQL tables if the list configuration above requires it' - -); - -# This defines the captions of each of the buttons in ezmlm-web, and allows -# you to configure them for your own language or taste. Since these are used -# by the switching algorithm it is important that every button has a unique -# caption - ie we can't have two 'Edit' buttons doing different things. - -%BUTTON = ( - - # These MUST all be unique! - create => 'Create', - createlist => 'Create List', - edit => 'Edit', - delete => 'Delete', - deleteaddress => 'Delete Address', - addaddress => 'Add Address', - moderators => 'Moderators', - denylist => 'Deny List', - allowlist => 'Allow List', - digestsubscribers => 'Digest Subscribers', - configuration => 'Configuration', - yes => 'Yes', - no => 'No', - updateconfiguration => 'Update Configuration', - edittexts => 'Edit Texts', - editfile => 'Edit File', - savefile => 'Save File', - webarchive => 'Web Archive', - selectlist => 'Select List', - subscribers => 'Subscribers', - cancel => 'Cancel', - resetform => 'Reset Form', - -); - -# This defines the fixed text strings that are used in ezmlm-web. By editing -# these along with the button labels and help texts, you can convert ezmlm-web -# to another language :-) If anyone gets arround to doing complete templates -# for other languages I would appreciate a copy so that I can include it in -# future releases of ezmlm-web. - -%LANGUAGE = ( - nop => 'Action not yet implemented', - chooselistinfo => "

  • Choose a mailing list from the selection box or click on [$BUTTON{'create'}].
  • Click on the [$BUTTON{'edit'}] button if you want to edit the selected list.
  • Click on the [$BUTTON{'delete'}] button if you want to delete the selected list.
", - confirmdelete => 'Confirm deletion of', # list name - subscribersto => 'Subscribers to', # list name - subscribers => 'subscribers', - additionalparts => 'Additional list parts', - posting => 'Posting', - subscription => 'Subscription', - remoteadmin => 'Remote Admin', - for => 'for', # as in; moderators for blahlist - createnew => 'Create a New List', - listname => 'List Name', - listaddress => 'List Address', - listoptions => 'List Options', - allowedtoedit => 'Users allowed to edit this list', - editconfiguration => 'Edit the List Configuration', - prefix => 'Subject prefex for outgoing messages', - headerremove => 'Headers to strip from all outgoing mail', - headeradd => 'Headers to add to all outgoing mail', - mimeremove => 'Mime types to strip from all outgoing mail', - edittextinfo => "The box on the left contains a list of files available in the
DIR/text directory. These files are sent out in response to specfic user request, or as part of all outgoing messages

To edit a file, select its name from the box. Then click on the [$BUTTON{'editfile'}] button.

Press [$BUTTON{'cancel'}] when you have finished editing.", - editingfile => 'Editing File', - editfileinfo => 'ezmlm-manage
<#l#> The list name
<#A#> The subscription address
<#R#> The address a subscriber must reply to

ezmlm-store
<#l#> The list name
<#A#> The acceptance address
<#R#> The rejection address', - mysqlcreate => 'Create the MySQL database tables if necessary', - -); - -# === Configuration file ends === diff --git a/ezmlm-web/tags/ezmlm-web-2.1/htaccess.sample b/ezmlm-web/tags/ezmlm-web-2.1/htaccess.sample deleted file mode 100644 index b381a14..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/htaccess.sample +++ /dev/null @@ -1,9 +0,0 @@ -#$Id: htaccess.sample,v 1.1 2000/01/29 11:35:40 guy Exp $ -# -#order deny,allow -#deny from all -#allow from .ru.ac.za -AuthName "EZ Mailing List Manager -AuthType Basic -AuthUserFile /etc/ezmlm/.htusers -require valid-user diff --git a/ezmlm-web/tags/ezmlm-web-2.1/index.c b/ezmlm-web/tags/ezmlm-web-2.1/index.c deleted file mode 100644 index 3ba9cc1..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/index.c +++ /dev/null @@ -1,25 +0,0 @@ -/* $Id: index.c,v 1.2 2000/09/25 18:14:12 guy Exp $ */ - -#include - -/* C wrapper to allow ezmlm-web.cgi to run suid */ -/* Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved */ -/* See the README file in this distribution for copyright information */ - -int main(void) { - /* Change this path to wherever you decided to put ezmlm-web.cgi */ - execv("/usr/local/bin/ezmlm-web.cgi"); - - /* Note that you could also use the following to allow a specific user - to store their mailing lists in a different directory defined by - /tmp/ezmlm-web-demo ... This over-rides the default . */ - - /* Look at the exec(3) man page if you don't understand how the arguments - list below works */ - - /* - char *switches[] = { "ezmlm-web.cgi", "-d", "/tmp/ezmlm-web-demo", NULL }; - execv("/usr/local/bin/ezmlm-web.cgi", switches); - */ - -} diff --git a/ezmlm-web/tags/ezmlm-web-2.1/webusers.sample b/ezmlm-web/tags/ezmlm-web-2.1/webusers.sample deleted file mode 100644 index f383eb2..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.1/webusers.sample +++ /dev/null @@ -1,4 +0,0 @@ -comm: guy, arb -users: arb -members: ALL -ALL: root diff --git a/ezmlm-web/tags/ezmlm-web-2.2.tar.gz b/ezmlm-web/tags/ezmlm-web-2.2.tar.gz deleted file mode 100644 index 24341b92745be86bd3dbe3d5a8e883b024a30992..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27494 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 BWN-ig diff --git a/ezmlm-web/tags/ezmlm-web-2.2/CHANGES b/ezmlm-web/tags/ezmlm-web-2.2/CHANGES deleted file mode 100644 index 5de2a93..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/CHANGES +++ /dev/null @@ -1,91 +0,0 @@ -$Id: CHANGES,v 1.2 2000/09/25 17:54:06 guy Exp $ - -REVISION HISTORY - ezmlm-web.cgi -================================ - -Version 0.1 - 10/04/98 (Not Released) -* University Vac - I was bored and started to play. The first version just - let people play with the subscribers list. No moderators, no nothing. - -Version 0.2 - 13/04/98 (Not Released) -* Allow list creation -* Allowed users to edit moderators - -Version 0.3 - 15/04/98 -* Allow list deletion (for balin@moria.org) -* Made changes to allow it to run on RedHat 4.2 as well as FreeBSD 3.0 -* Fixed some minor bugs (cosmetic irritaions really) that people noticed -* Sorted subscribers list into alphabetical order. -* Added command line switch to change list directory (for nxsy@moria.org) -* Wrote some documentation ... - -Version 0.4 - 28/04/98 -* Fixed up virtual domain (inlocal) stuff as spotted by bryan@rucus -* Allowed the list directory to be automatically created if necessary. - -Version 0.5 - 12/05/98 (Not Released) -* More bug fixes. Mainly for mathew@graham. - -Version 1.0 - 01/08/98 -* Complete re-write to convert to perl5 and CGI.pm -* Removed a lot of dependancy on the OS. Use builtin functions instead :) -* Added support for ezmlm-idx -* Added a lot more command line option support (-adfgiklmnpqsrstux5) -* Added support for digests and digest subscribers -* Added support for blacklists -* Allowed users to edit the config of existing lists -* Allowed the user to edit headeradd and headerremove as well as mimeremove -* Allowed user to edit any of the files in DIR/text -* Revised interface to make it more user-friendly and ergonomic. -* Changed the background colour for Kether (clb@rucus) *gryn* -* Removed a big bug in the delete_list function that had gone unnoticed. - -Version 1.0.1 - 10/08/98 -* Fixed a bug in the way 1.0 re-configured virtual hosts (bryan@rucus) -* Made the script read the /var/qmail/control files instead of explicitly - setting variables (for david@summersoft) - -Version 1.0.2 - 28/08/98 -* Fixed the bug introduced in v1.0.1 :( (keith@rucus) -* Fixed the way we recreate config files (noticed by Glen Stewart) -* Made the script check return values of system calls properly -* Fixed some of the taint checking stuff ... reports less in the logs now. - -Version 1.0.3 - 03/10/98 -* Fixed the alias-alias-alias-list bug in inlocal (bryan@rucus) -* Added a bit of online help -* Fixed the & in list owner (bryan@rucus) -* Added multi-level access to lists (based on idea by Glen Stewart) - -Version 2.0 - 01/01/00 -* Rewrote most of the code to take advantage of Mail::Ezmlm -* Made the webuser file more functional (users can alter it) -* Now handles all current, and future command line options -* Changed the colours :) -* Added support for ezmlm-cgi web archives -* Made it -w and use strict clean -* Moved all user config to a separate file -* Fixed the way we worked out list config - now complete -* Allowed a user specific config over-ride ``ezmlmwebrc'' -* Allowed the printing of `nice' usernames (for Rhodes CS Dept) -* Took account of non-standard paths for moderators -* Removed all system() and `` calls from ezmlm-web.cgi -* Made `look and feel' virtually all user configurable -* Added a lot more context sensitive help -* Made ezmlm-web 99% language configurable - but no other templates yet :( -* Added support for creating databases - -Version 2.1 - 25/09/00 -* Fixed the multiple delete thing - finally! -* Fixed the '-' in username problem - The '-' in hostnames problem is fixed - in the new version of Mail::Ezmlm -* Fixed the '_' in list names problem -* Added support for file uploads of email addresses (multiple subscribe) -* Made error handling more friendly - -Version 2.2 - 26/01/02005 -* German translation of the web interface - more translations can be added easily -* changed "ALT"-tags to "TITLE" - most browsers will display the tooltip texts now -* fixed security problems (permissions were not thoroughly check) -* user-based permission for creating lists (can be set in webusersrc) -* the location of the webusers file is now an option in ezmlmwebrc diff --git a/ezmlm-web/tags/ezmlm-web-2.2/INSTALL b/ezmlm-web/tags/ezmlm-web-2.2/INSTALL deleted file mode 100644 index 11f2651..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/INSTALL +++ /dev/null @@ -1,97 +0,0 @@ -The following notes will guide you through the installation of ezmlm-web: - -0. IMPORTANT: you need the perl module Mail::Ezmlm and others to use - ezmlm-web! The file README contains the list of necessary modules. - -1. Get ezmlm-web and extract the archive: - tar xzf ezmlm-web-2.2.tar.gz - -2. Copy ezmlm-web.cgi to some publically readable directory. It does not - have to be in a path accessible to your web server, but any user with a - mailing list must be able to run it (Check the read and execute rights - on both the file and directory). We put our copy in "/usr/local/bin". - - At the top of ezmlm-web.gi you can will probably have to change the - $ENV{'PATH'} variable. Be careful about what you set as the path. Too - much is a security risk and too little will cause the script to - malfunction. Version 2.0 requires that the following programs be - accessible in your path: mv, rm - -3. Edit the ezmlmwebrc file and alter the variables to suit your - particular system. - - Be careful about the $LIST_DIR variable. This script assumes that all - users store their mailing lists in the same sub directory of the home - directory (eg ~/lists). You can override this for an individual user - by recompiling the C wrapper to call ezmlm-web.cgi with a -d option. - - Other configurable options are documented in the ezmlmwebrc file - itself. I have tried to keep the amount of information that you need to - supply to a minimum and also make reasonable guesses about default - values. - - Finally, copy the ezmlmwebrc file and the "lang" directory to one of - the following places: - - /etc/ezmlm - - the home directory of the user that runs ezmlm-web.cgi - - the directory, that contains your ezmlm-web.cgi file - -4. Edit the index.c file and change the path to the path of your copy - of ezmlm-web.cgi. Then compile this file. You can do this by issuing - the command; gcc -o index.cgi index.c - -5. For every user/virtual host that needs to manage mailing lists, you - need to create a SUID (user not root!!) copy of index.cgi (see - chmod(1) for details). These need to reside somewhere accessible by - the web server. I suggest that you put them in a sub directory (see - about security) of each user/virtual host's home directory (eg - /home/luser/public_html/ezmlm for Apache on Redhat). - - The copies don't actually have to be called index.cgi, but it is nice - for web servers that can resolve a cgi script as an index page (see the - srm.conf file in Apache). It is important to make sure that whichever - directory you choose to put them can i: Execute CGI Scripts and ii: Be - access controlled (here I mean both web and user access) by some method - (eg .htaccess, access.conf for Apache). - -6. Install some method of securing access to the page. The following - information is applicable to Apache web servers ... Detailed - information on user authentication can be obtained from the Apache - documentation (http://www.apache.org) and ApacheWeek - (http://www.apacheweek.com/features/userauth) - -6.1 Ensure that your Apache setup will allow .htaccess file to control - access in the directory that contains. This is controlled by the - AllowOverride tag in access.conf. (Also ensure you have the - necessary Apache modules installed) - -6.2 Create a htpasswd file. This is done using the htpasswd command that - comes with Apache. Its command line syntax is; - htpasswd [-c] passwordfile username - - You need to put the passwordfile somewhere that is not accessible by - people through the web, and create an entry for each user you want - to have access ... See the ApacheWeek article for more details. - -6.3 Create a .htaccess file in the directory that contains index.cgi. - Note that using Apache's built in access control, you can only control - access to directories, not individual files, hence the need for a - sub-directory in step 5. - - The format of the .htaccess file should be along the lines of this; - - AuthName EZ Mailing List Manager - AuthType Basic - AuthUserFile /path/to/passwordfile - require valid-user # or require user username - - Again, see the ApacheWeek article for details. - -7. Test the installation through the web. You should be asked for a - username and password (supplied in 6.2) and then be presented with a - screen entitled EZ Mailing List Manger. You can then try to create and - edit mailing lists ... Have Fun :) - -If you have any problems, then you can: -- take a look at https://systemausfall.org/toolforge/ezmlm-web -- send me an email: ezmlm-web@sumpfralle.de diff --git a/ezmlm-web/tags/ezmlm-web-2.2/README b/ezmlm-web/tags/ezmlm-web-2.2/README deleted file mode 100644 index 89fbfa7..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/README +++ /dev/null @@ -1,270 +0,0 @@ -$Id: README,v 1.2 2000/09/25 17:57:21 guy Exp $ - -================= -| ezmlm-web-2.2 | -================= - -If you only want to know how to install ezmlm-web, then you should -read INSTALL. - -Contents -======== - I. Copyright Stuff - II. Some Background - III. Requirements - IV. Files - V. Notes - VI. Multi-level list access - VII. Language Portability -VIII. Bugs && Bug Reports - XI. Acknowledgements - X. Availability - - -I. Copyright Stuff - essentially the FreeBSD licence ... -================== -ezmlm-web - version 2.2 - 26/01/02005 - -Copyright (C) 1998, Guy Antony Halse, All Rights Reserved. -Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -Neither name Guy Antony Halse nor the names of any contributors may be used -to endorse or promote products derived from this software without specific -prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -II. Some Background -=================== -The need for ezmlm-web arose from the fact that we host many student -societies on our system. These societies usually have a virtual host for web -and email, which is administered by a computer rep from the society. These -computer reps often have little or no knowledge of Unix and so we needed a -user friendly system that would let the create and maintain mailing lists -(such as members@foo.soc.ru.ac.za, committee@foo.soc.ru.ac.za, etc). - -Since I am never keen to re-invent the wheel, I had a look at Steve Peterson's -script (http://virtation.com/qmail/ml-sub), which allows people to subscribe -and unsubscribe from mailing lists using a form->email gateway. This is fine -for putting on a web page saying "here come and join our mailing list", but -doesn't really allow you to administrate a list. - -Security of mailing lists was a concern, as we really didn't want -unauthorised people to be able to alter some users list. Ezmlm-web itself -implements no security checks (apart from un-tainting input) and so relies -on the web server to do this (re-inventing the wheel again :). We use an -Apache webserver, so one can control access to a directory using a .htaccess -file or in the access.conf file. ApacheWeek have a good article on doing -this at http://www.apacheweek.com/features/userauth. I also give examples -later in this document. - -This version of ezmlm-web is based to a large extent on previous -versions that I have developed. It has however been totally re-written to -make use of the Mail::Ezmlm perl module I wrote. At the same time it was -updated and extended to include the new features of ezmlm-idx. It includes -many new features that have been suggested to me over the last few months, -and hopefully is now useful to a much larger group of people. - -Since 02005 ezmlm-web is maintained by Lars Kruse (ezmlm-web@sumpfralle.de). -Only minor improvements had to be implemented to keep the already fully -functional ezmlm-web up to date. - -III. Requirements -================= -This version of ezmlm-web requires the following; - -* qmail v1.03 -* ezmlm v0.53 (idx v0.40) -* Perl v5.004 and the following modules; - + Mail::Ezmlm v0.03 - + Mail::Address v1.15 - + CGI v2.6 - + CGI::Carp v1.06 - + DB_File v1.65 - + Getopt::Std v4.1 - + File::Find v? - + File::Copy v2.02 - -The version number indicates the version of the module that ezmlm-web was -developed with. Earlier versions may work, but then they haven't been -tested. Have a look on http://www.CPAN.org/, http://www.qmail.org/, and -http://www.ezmlm.org/ for anything you are missing. - -IV. Files -========= -In this distribution you should find 8 files; - -README This file. Provides some background information. - Not needed to run ezmlm-web. - -INSTALL Notes on installation. Not needed to run ezmlm-web. - -CHANGES The change history. Not needed to run ezmlm-web - -TODO This file is a list of things I intend doing in future - versions of ezmlm-web. Not needed to run ezmlm-web. - -ezmlm-web.cgi The ezmlm-web script proper. This program requires that - you have perl5 installed on your machine and that your web - server is capable of running CGI scripts. - -index.c A C wrapper to allow ezmlm-web.cgi to run suid. Not - strictly necessary if your setup allows perl scripts to - run suid, but I prefer using wrappers anyway. It needs to - be edited and compiled to suit your system. Not needed to - run ezmlm-web. - -ezmlmwebrc This is the configuration file for ezmlm-web. All options - are explained in this example file. You will need this - file to run ezmlm-web. - -htaccess.sample A sample Apache .htaccess file for controlling access to - the mailing lists. If you use another web server, you will - have to work this bit out for yourself. - -webusers.sample A sample webusers file for multi-level access control. - -The directory "lang" contains the language files. You will need at least the -one, that you have choosen in "ezmlmwebrc" by the option "HTML_LANGUAGE". - -V. Notes -========= -* There is a function to delete mailing lists, but I really don't like the - idea. The only reason I put it in is that bvi@rucus asked for it. - If you set $UNSAFE_RD = 0 (the default) in the config section, the - ezmlm-web won't actually delete the list. In this case it moves the - to . and all the associated .qmail files to a sub-directory called - deleted.qmail/ (In the users home directory. This is by far a safer way - (since you can restore lists) and therefore I recommend it. - -* The HTML interface has been tested using Nutscrape, Internet Exploder, and - Lynx. If anyone uses anything else and has problems, please let me know. - -* I suggest that you make use of custom ezmlmwebrc files rather than using - the -d command line switches - it makes fault diagnosis easier ... - -* Please see the section on languages below. - -VI. Multi-Level Access -======================= -Ezmlm-web has a multi-level access system. This depends on a file called -webusers being present in $LIST_DIR. If the file is not present, then any -valid user has access to all lists. If, however, this file exists a number -of constraints come into place. - -- The webusers file is scanned for either the list name (case insensitive) or - an ALL (case sensitive) entry. -- The list entry (or ALL) is scanned for the current user (as set in - $REMOTE_USER) or an ALL entry. -- If any valid match is made, then the user is allowed to edit the list. - Otherwise the user is politely told to go away ;-) - -If list creation is allowed and the webusers file exists, then the person who -creates the list is the default owner. As of yet there is no way to create users -through the web interface, but I intend to do this eventually. - -The format of a webusers file is as follows; - -list1: user1, user2, user3 -ALL: user1, user2 -list2: ALL - -ie; listname colon (:) and a comma (,) separated list of users. Spaces are -ignored but each list must appear on a new line. - -Once this file exists, the ezmlm-web script will allow the list users to -configure their access lists along with any other options. - -You can permit some users to create lists by adding a line similar to the -following to your webusers file: - -ALLOW_CREATE: user2, user3 - -If there is no line starting with "ALLOW_CREATE:" in the webusers file, then -no one will be allowed to create lists. This behaviour is new for ezmlm-web -since version 2.2. To stay compatible to old installations, the commandline -option "-c" for ezmlm-web.cgi will still allow everyone to create lists. The -use of this option is deprecated, since the line "ALLOW_CREATE: ALL" provides -the same effect in a cleaner way. - -VII. Language Portablity -========================= -One of the great new features of version 2.0 is that it is essentially -language independant (okay, not quite, but is 99% of the way there). Most of -the fixed strings, help, etc is defined in the files of lang directory. -Of course you can change them or create a new translation. - -The language can be selected in ezmlmwebrc with the "HTML_LANGUAGE" option. - -If anyone gets round to writing full templates for languages I would -appreciate it if you would do two things; - -Firstly, make them public and announce them on the ezmlm@lists.cr.yp.to -mailing list so that others may benefit. - -Secondly, please mail me a copy (ezmlm-web@sumpfralle.de) so that I may use -them in any future releases of ezmlm-web. - - -VIII. Bugs && Bug Reports -======================= -I don't know of any bugs, but then this is a rewrite and a first release. It -has been tested reasonably well, but not exhaustively. I know it works on -FreeBSD 4.0-STABLE, FreeBSD 3.4-RELEASE, RedHat 5.1 and Redhat 6.0 all using -an Apache web server, but I would be interested to know whether it works on -other OSs and with other web servers. This version is far less dependent on -the OS than previous versions so I don't see any reason why it shouldn't. - -Please mail bug reports and comments to ezmlm-web@sumpfralle.de. - -IX. Acknowledgements -=================== -* Guy Antony Halse (guy-ezmlm@rucus.ru.ac.za) - He created ezmlm-web, - maintained it till 02005 and wrote nearly every line of code! -* Keith Burdis (keith@rucus.ru.ac.za) - For constantly bugging me and - ensuring that I actually got round to writing some code :) -* Bryan Kilian (bryan@rucus.ru.ac.za) and the administrators of the - Litestep mailing list - For helping beta test and putting up with me - pestering them. -* Several societies at Rhodes. For switching to my web interface and so - unknowingly helping to beta test it. -* Barry Irwin (bvi@moria.org) - For trusting me and moving the Grahamstown - Foundation over to qmail and ezmlm - yet another beta tester :-) -* David Summers (david@summersoft.fay.ar.us) - For some ideas. And for - offering to make up an RPM version. I hope the offer still exists for - version 2.0 :-) -* Glen Stewart (glen_stewart@associate.com) - For a multitude of ideas. -* Fred Lindberg (lindberg@id.wustl.edu) for his useful posts to the - mailing list, suggestions, help, etc -* Galen Johnson (gjohnson@totalsports.net) - For some ideas on bugfixes. - -X. Availability -================= -More information on ezmlm-web and developments to ezmlm-web can be found at: -https://systemausfall.org/toolforge/ezmlm-web - -The website of Guy Antony Halse (the author of ezmlm-web) is still at: -http://rucus.ru.ac.za/~guy/ezmlm/ - -The old ftp-archive of ezmlm-web is still available on: -ftp://rucus.ru.ac.za/pub/mail/ezmlm/ diff --git a/ezmlm-web/tags/ezmlm-web-2.2/TODO b/ezmlm-web/tags/ezmlm-web-2.2/TODO deleted file mode 100644 index a09d11f..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/TODO +++ /dev/null @@ -1,8 +0,0 @@ -$Id: TODO,v 1.3 2000/09/25 19:58:02 guy Exp $ - -TODO - ezmlm-web 2.2 - -- More Documentation -- Some nice install method. But then I use FreeBSD and ported it - so that might just count as my nice install method :) -- Option for a css-stylesheet diff --git a/ezmlm-web/tags/ezmlm-web-2.2/UPGRADING b/ezmlm-web/tags/ezmlm-web-2.2/UPGRADING deleted file mode 100644 index 7abe744..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/UPGRADING +++ /dev/null @@ -1,39 +0,0 @@ -$Id: UPGRADING,v 1.1 2000/09/25 19:24:20 guy Exp $ - -UPGRADING ezmlm-web 2.1 to ezmlm-web 2.2 - -1) Creating of new lists is now controlled by a line in the webusers file instead -of a commandline switch for ezmlm-web.cgi. - -necessary changes: - - optional: remove switch "-c" when calling ezmlm-web.cgi (take a look at index.c) - - optional: add a line like "ALLOW_CREATE: john, myra" to the webusers file - -2) The location of the webusers file is now defined in ezmlmwebrc. (default: $LIST_DIR/webusers) - -necessary changes: - - optional: add a line like "$WEBUSERS_FILE = /home/ml/webusers" to ezmlmwebrc - -3) A german translation is available. - - - optional: include "lang/de.pm" in ezmlmwebrc (there you can also remove the english definitions) - or copy the new ezmlmwebrc :) - ------------------------------------------------------------------------------- - -UPGRADING ezmlm-web 2.0 to ezmlm-web 2.1 - -There are no major changes that need to be made in order to upgrade. All -that is necessary is to add two new lines to your ezmlmwebrc ... In the top -section of the file add - -$FILE_UPLOAD = 1; - -and in the %HELPER section, you need to add - -addaddressfile => 'or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line', - -(or just copy the new ezmlmwebrc :) - -Have a look for these two lines in the new ezmlmwebrc included in this -distribution if you are unsure of how/where to put these. diff --git a/ezmlm-web/tags/ezmlm-web-2.2/ezmlm-web.cgi b/ezmlm-web/tags/ezmlm-web-2.2/ezmlm-web.cgi deleted file mode 100755 index aaf1a8f..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/ezmlm-web.cgi +++ /dev/null @@ -1,1131 +0,0 @@ -#!/usr/bin/perl -T -#=========================================================================== -# ezmlm-web.cgi - version 2.2 - 26/01/02005 -# $Id: ezmlm-web.cgi,v 1.3 2000/09/25 19:58:07 guy Exp $ -# -# Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved. -# Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# Neither name Guy Antony Halse nor the names of any contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# ========================================================================== -# All user configuration happens in the config file ``ezmlmwebrc'' -# POD documentation is at the end of this file -# ========================================================================== - -# Modules to include -use strict; -use Getopt::Std; -use Mail::Ezmlm; -use Mail::Address; -use DB_File; -use CGI; -use CGI::Carp qw(fatalsToBrowser set_message); - -# These two are actually included later and are put here so we remember them. -#use File::Find if ($UNSAFE_RM == 1); -#use File::Copy if ($UNSAFE_RM == 0); - -my $q = new CGI; -$q->import_names('Q'); -use vars qw[$opt_c $opt_d $opt_C]; -getopts('cd:C:'); - -# Suid stuff requires a secure path. -$ENV{'PATH'} = '/bin'; - -# We run suid so we can't use $ENV{'HOME'} and $ENV{'USER'} to determine the -# user. :( Don't alter this line unless you are _sure_ you have to. -my @tmp = getpwuid($>); my $USER=$tmp[0]; - -# use strict is a good thing++ - -use vars qw[$HOME_DIR]; $HOME_DIR=$tmp[7]; -use vars qw[$DEFAULT_OPTIONS %EZMLM_LABELS $UNSAFE_RM $ALIAS_USER $LIST_DIR]; -use vars qw[$QMAIL_BASE $EZMLM_CGI_RC $EZMLM_CGI_URL $HTML_BGCOLOR $PRETTY_NAMES]; -use vars qw[%HELPER $HELP_ICON_URL $HTML_HEADER $HTML_FOOTER $HTML_TEXT $HTML_LINK]; -use vars qw[%BUTTON %LANGUAGE $HTML_VLINK $HTML_TITLE $FILE_UPLOAD $WEBUSERS_FILE]; - -# Get user configuration stuff -if(defined($opt_C)) { - require "$opt_C"; # Command Line -} elsif(-e "$HOME_DIR/.ezmlmwebrc") { - require "$HOME_DIR/.ezmlmwebrc"; # User -} elsif(-e "/etc/ezmlm/ezmlmwebrc") { - require "/etc/ezmlm/ezmlmwebrc"; # System -} elsif(-e "./ezmlmwebrc") { - require "./ezmlmwebrc"; # Install -} else { - die "Unable to read config file"; -} - -# Allow suid wrapper to over-ride default list directory ... -if(defined($opt_d)) { - $LIST_DIR = $1 if ($opt_d =~ /^([-\@\w.\/]+)$/); -} - -# If WEBUSERS_FILE is not defined in ezmlmwebrc (as before version 2.2), then use former default value for compatibility -if (!defined($WEBUSERS_FILE)) { - $WEBUSERS_FILE = $LIST_DIR . '/webusers' -} - -# Work out default domain name from qmail (for David Summers) -my($DEFAULT_HOST); -open (GETHOST, "<$QMAIL_BASE/me") || open (GETHOST, "<$QMAIL_BASE/defaultdomain") || die "Unable to read $QMAIL_BASE/me: $!"; -chomp($DEFAULT_HOST = ); -close GETHOST; - -# Untaint form input ... -&untaint; - -# redirect must come before headers are printed -if(defined($Q::action) && $Q::action eq '[Web Archive]') { - print $q->redirect(&ezmlmcgirc); - exit; -} - -# Print header on every page ... -print $q->header(-pragma=>'no-cache', '-cache-control'=>'no-cache', -expires=>'-1d', '-Content-Type'=>'text/html; charset=utf-8'); -print $q->start_html(-title=>$HTML_TITLE, -author=>'guy-ezmlm@rucus.ru.ac.za', -BGCOLOR=>$HTML_BGCOLOR, -LINK=>$HTML_LINK, -VLINK=>$HTML_VLINK, -TEXT=>$HTML_TEXT, -expires=>'-1d'); -print $HTML_HEADER; - -# check permissions -&check_permission_for_action == 0 || die 'Error: you are not allowed to do this!'; - -# This is where we decide what to do, depending on the form state and the -# users chosen course of action ... -unless (defined($q->param('state'))) { - # Default action. Present a list of available lists to the user ... - &select_list; - -} elsif ($Q::state eq 'select') { - # User selects an action to perform on a list ... - - if ($Q::action eq "[$BUTTON{'create'}]") { # Create a new list ... - &allow_create_list; - } elsif (defined($Q::list)) { - if ($Q::action eq "[$BUTTON{'edit'}]") { # Edit an existing list ... - &display_list; - } elsif ($Q::action eq "[$BUTTON{'delete'}]") { # Delete a list ... - &confirm_delete; - } - } else { - &select_list; # NOP - Blank input ... - } - -} elsif ($Q::state eq 'edit') { - # User chooses to edit a list - - my($list); $list = $LIST_DIR . '/' . $q->param('list'); - if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ... - &delete_address($list); - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address($list); - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'moderators'}]") { # Edit the moderators ... - &part_subscribers('mod'); - - } elsif ($Q::action eq "[$BUTTON{'denylist'}]") { # Edit the deny list ... - &part_subscribers('deny'); - - } elsif ($Q::action eq "[$BUTTON{'allowlist'}]") { # edit the allow list ... - &part_subscribers('allow'); - - } elsif ($Q::action eq "[$BUTTON{'digestsubscribers'}]") { # Edit the digest subscribers ... - &part_subscribers('digest'); - - } elsif ($Q::action eq "[$BUTTON{'configuration'}]") { # Edit the config ... - &list_config; - - } else { # Cancel - Return a screen ... - &select_list; - } - -} elsif ($Q::state eq 'allow' || $Q::state eq 'mod' || $Q::state eq 'deny' || $q->param('state') eq 'digest') { - # User edits moderators || deny || digest ... - - my($part); - # Which list directory are we using ... - if($Q::state eq 'mod') { - $part = 'mod'; - } elsif($Q::state eq 'deny' ) { - $part = 'deny'; - } elsif($Q::state eq 'allow') { - $part = 'allow'; - } else { - $part = 'digest'; - } - - if ($Q::action eq '[Delete Address]') { # Delete a subscriber ... - &delete_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } else { # Cancel - Return to the list ... - &display_list; - } - -} elsif ($Q::state eq 'confirm_delete') { - # User wants to delete a list ... - - &delete_list if($q->param('confirm') eq "[$BUTTON{'yes'}]"); # Do it ... - $q->delete_all; - &select_list; - -} elsif ($Q::state eq 'create') { - # User wants to create a list ... - - if ($Q::action eq "[$BUTTON{'createlist'}]") { - if (&create_list) { # Return if list creation is unsuccessful ... - &allow_create_list; - } else { - &select_list; # Else choose a list ... - } - - } else { # Cancel ... - &select_list; - } - -} elsif ($Q::state eq 'configuration') { - # User updates configuration ... - - if ($Q::action eq "[$BUTTON{'updateconfiguration'}]") { # Save current settings ... - &update_config; - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'edittexts'}]") { # Edit DIR/text ... - &list_text; - - } else { # Cancel - Return to list editing screen ... - &display_list; - } - -} elsif ($Q::state eq 'list_text') { - # User wants to edit texts associated with the list ... - - if ($Q::action eq "[$BUTTON{'editfile'}]") { - &edit_text; - } else { - &list_config; # Cancel ... - } - -} elsif ($Q::state eq 'edit_text') { - # User wants to save a new version of something in DIR/text ... - - &save_text if ($Q::action eq "[$BUTTON{'savefile'}]"); - &list_text; - -} else { - print "

$Q::action

$LANGUAGE{'nop'}


"; -} - -# Print HTML footer and exit :) ... -print $HTML_FOOTER, $q->end_html; -exit; - -# ========================================================================= - -sub select_list { - # List all mailing lists (sub directories) in the list directory. - # Allow the user to choose a course of action; either editing an existing - # list, creating a new one, or deleting an old one. - - my (@lists, @files, $i, $scrollsize); - - # Read the list directory for mailing lists. - opendir DIR, $LIST_DIR || die "Unable to read $LIST_DIR: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Check that they actually are lists ... - foreach $i (0 .. $#files) { - if (-e "$LIST_DIR/$files[$i]/lock") { - $lists[$#lists + 1] = $files[$i] if (&webauth($files[$i]) == 0); - } - } - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#lists + 1) > 25); - - # Print a form - $q->delete_all; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'select'); - print '
'; - print $q->scrolling_list(-name=>'list', -size=>$scrollsize, -values=>\@lists) if defined(@lists); - - print '', $LANGUAGE{'chooselistinfo'}; - - print $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), ' ' if ((&webauth_create_allowed == 0) || (!defined($opt_c))); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), ' ' if(defined(@lists)); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]") if(defined(@lists)); - print '
'; - print $q->endform; -} - -# ------------------------------------------------------------------------ - -sub confirm_delete { - # Make sure that the user really does want to delete the list! - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'confirm_delete'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print '

', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '


'; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'no'}]"), ' '; - print $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), '
'; -} - -# ------------------------------------------------------------------------ - -sub display_list { - # Show a list of subscribers to the user ... - - my ($i, $list, $listaddress, $moderated, @subscribers, $scrollsize); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - - # Get a list of subscribers from ezmlm ... - @subscribers = $list->subscribers; - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - print "

$LANGUAGE{'subscribersto'} $Q::list ($listaddress)


"; - print $q->start_multipart_form; - print '
'; - print $q->hidden(-name=>'state', -default=>'edit'); - print $q->hidden(-name=>'list', -default=>$Q::list); - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -labels=>&pretty_names, -multiple=>'true') if defined(@subscribers); - print ''; - print ' ', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, '
' if defined(@subscribers); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); - print $q->textfield(-name=>'addsubscriber', -size=>'40'), '
'; - print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), '
' if ($FILE_UPLOAD); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print '', $LANGUAGE{'additionalparts'}, ':
' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), ' ' if ($list->ismodpost || $list->ismodsub || $list->isremote); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), ' ' if ($list->isdeny); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), ' ' if ($list->isallow); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), ' ' if ($list->isdigest); - print '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), ' ' if(&ezmlmcgirc); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), '   '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'selectlist'}]"); - print '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub delete_list { - # Delete a list ... - - # Fixes a bug from the previous version ... when the .qmail file has a - # different name to the list. We use outlocal to handle vhosts ... - my ($list, $listaddress, $listadd); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - if ($listadd = $list->getpart('outlocal')) { - chomp($listadd); - } else { - $listadd = $q->param('list'); - } - $listaddress = $1 if ($listadd =~ /-?(\w+)$/); - - if ($UNSAFE_RM == 0) { - # This doesn't actually delete anything ... It just moves them so that - # they don't show up. That way they can always be recovered by a helpful - # sysadmin should he be in the mood :) - - use File::Copy; - - my ($oldfile); $oldfile = "$LIST_DIR/$Q::list"; - my ($newfile); $newfile = "$LIST_DIR/.$Q::list"; - move($oldfile, $newfile) or die "Unable to rename list: $!"; - mkdir "$HOME_DIR/deleted.qmail", 0700 if(!-e "$HOME_DIR/deleted.qmail"); - - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - foreach (@files) { - unless (move($_, "$HOME_DIR/deleted.qmail/")) { - die "Unable to move .qmail files: $!"; - } - } - warn "List '$oldfile' moved (deleted)"; - } else { - # This, however, does DELETE the list. I don't like the idea, but I was - # asked to include support for it so ... - if (!rmtree("$LIST_DIR/$Q::list")) { - die "Unable to delete list: $!"; - } - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - if (unlink(@files) <= 0) { - die "Unable to delete .qmail files: $!"; - } - warn "List '$list->thislist()' deleted"; - } -} - -# ------------------------------------------------------------------------ -sub untaint { - - $DEFAULT_HOST = $1 if $DEFAULT_HOST =~ /^([\w\d\.-]+)$/; - - # 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 ... - - my (@params, $i, $param); - @params = $q->param; - - foreach $i (0 .. $#params) { - my(@values); - next if($params[$i] eq 'addfile'); - foreach $param ($q->param($params[$i])) { - next if $param eq ''; - if ($param =~ /^([#-\@\w\.\/\[\]\:\n\r\>\< ]+)$/) { - push @values, $1; - } else { - warn "Tainted input in '$params[$i]': " . $q->param($params[$i]); - } - $q->param(-name=>$params[$i], -values=>\@values); - } - } - $q->import_names('Q'); -} - -# ------------------------------------------------------------------------ - -sub check_permission_for_action { - # test if the user is allowed to modify the choosen list or to create an new one - # the user would still be allowed to fill out the create-form (however he got there), - # but the final creation is omitted - - my $ret; - if ($Q::state eq 'create') { - $ret = &webauth_create_allowed(); - } elsif (defined($Q::list)) { - $ret = &webauth($Q::list); - } else { - $ret = 0; - } - return $ret; - -} - -# ------------------------------------------------------------------------ - -sub add_address { - # Add an address to a list .. - - my ($address, $list, @addresses, $count); my ($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - - if($q->param('addfile')) { - - # Sanity check - die "File upload must be of type text/*" unless($q->uploadInfo($q->param('addfile'))->{'Content-Type'} =~ m{^text/}); - - # Handle file uploads of addresses - my($fh) = $q->upload('addfile'); - return unless (defined($fh)); - while (<$fh>) { - next if (/^\s*$/ or /^#/); # blank, comments - next unless (/\@/); # email address ... - chomp(); - push @addresses, $_; - } - - } else { - - # User typed in an address - return if ($q->param('addsubscriber') eq ''); - - $address = $q->param('addsubscriber'); - $address .= $DEFAULT_HOST if ($q->param('addsubscriber') =~ /\@$/); - push @addresses, $address; - - } - - foreach $address (@addresses) { - - my($add) = Mail::Address->parse($address); - if(defined($add->name()) && $PRETTY_NAMES) { - my(%pretty); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - $pretty{$add->address()} = $add->name(); - untie %pretty; - } - - if ($list->sub($add->address(), $part) != 1) { - die "Unable to subscribe to list: $!"; - } - $count++; - } - - $q->delete('addsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub delete_address { - # Delete an address from a list ... - - my ($list, @address); my($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - return if ($q->param('delsubscriber') eq ''); - - @address = $q->param('delsubscriber'); - - if ($list->unsub(@address, $part) != 1) { - die "Unable to unsubscribe from list $list: $!"; - } - - if($PRETTY_NAMES) { - my(%pretty, $add); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - foreach $add (@address) { - delete $pretty{$add}; - } - untie %pretty; - } - - $q->delete('delsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub part_subscribers { - my($part) = @_; - # Deal with list parts .... - - my ($i, $list, $listaddress, @subscribers, $moderated, $scrollsize, $type); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - if($part eq 'mod') { - # Lets know what is moderated :) - - # do we store things in different directories? - my $config = $list->getconfig; - my($postpath) = $config =~ m{7\s*'([^']+)'}; - my($subpath) = $config =~ m{8\s*'([^']+)'}; - my($remotepath) = $config =~ m{9\s*'([^']+)'}; - - $moderated = '' if ($postpath); - $moderated .= "[$LANGUAGE{'posting'}]" if ($list->ismodpost); - $moderated .= '' if ($postpath); - $moderated .= '' if ($subpath); - $moderated .= " [$LANGUAGE{'subscription'}]" if($list->ismodsub); - $moderated .= '' if ($subpath); - $moderated .= '' if ($remotepath); - $moderated .= " [$LANGUAGE{'remoteadmin'}]" if($list->isremote); - $moderated .= '' if ($remotepath); - - } - - # What type of sublist is this? - ($type) = $Q::action =~ m/^\[(.+)\]$/; - - # Get a list of moderators from ezmlm ... - @subscribers = $list->subscribers($part); - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - print "

$type $LANGUAGE{'for'} $listaddress


"; - print "
$moderated

" if(defined($moderated)); - print $q->start_multipart_form; - print '

'; - print $q->hidden(-name=>'state', -default=>$part); - print $q->hidden(-name=>'list', -default=>$Q::list), "\n"; - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -multiple=>'true', -labels=>&pretty_names) if defined(@subscribers); - print '
'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '

' if defined(@subscribers); - print $q->textfield(-name=>'addsubscriber', -size=>'40'), '
'; - print $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), '
' if ($FILE_UPLOAD); - print $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), '

'; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'subscribers'}]"); - print '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub allow_create_list { - # Let the user select options for list creation ... - - my($username, $hostname, %labels, $j); - - # 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; - } - - # Print a form of options ... - $q->delete_all; - print '

', $LANGUAGE{'createnew'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'create'); - print '', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), '

'; - print '', $LANGUAGE{'listaddress'}, ': '; - print $q->textfield(-name=>'inlocal', -default=>$username, -size=>'10'); - print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), '

'; - - print '

', $LANGUAGE{'listoptions'}, ':'; - &display_options($DEFAULT_OPTIONS); - - # Allow creation of mysql table if the module allows it - if($Mail::Ezmlm::MYSQL_BASE) { - print '

', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1); - print ' '; - - } - - print '

', $LANGUAGE{'allowedtoedit'}, ': ', - $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30'), ' ', - '
', $HELPER{'allowedit'}, '' - if(-e "$WEBUSERS_FILE"); - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'createlist'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub create_list { - # Create a list acording to user selections ... - - # Check the list directory exists and create if necessary ... - if(!-e $LIST_DIR) { - die "Unable to create directory ($LIST_DIR): $!" unless mkdir $LIST_DIR, 0700; - } - - my ($qmail, $listname, $options, $i); - - # Some taint checking ... - $qmail = $1 if $q->param('inlocal') =~ /(?:$USER-)?([^\<\>\\\/\s]+)$/; - $listname = $q->param('list'); $listname =~ s/ /_/g; # In case some git tries to put a space in the file name - - # Sanity Checks ... - return 1 if ($listname eq '' || $qmail eq ''); - if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) { - print "

List '$listname' already exists :(

"; - return 1; - } - - # Work out the command line options - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - my($list) = new Mail::Ezmlm; - - unless ($list->make(-dir=>"$LIST_DIR/$listname", - -qmail=>"$HOME_DIR/.qmail-$qmail", - -name=>$q->param('inlocal'), - -host=>$q->param('inhost'), - -switches=>$options, - -user=>$USER) - ) { - die 'List creation failed', $list->errmsg(); - } - - # handle MySQL stuff - if($q->param('sql') && $options =~ m/-6\s+/) { - unless($list->createsql()) { - die 'SQL table creation failed: ', $list->errmsg(); - } - } - - &update_webusers(); - - return 0; -} - -# ------------------------------------------------------------------------ - -sub list_config { - # Allow user to alter the list configuration ... - - my ($list, $listaddress, $listname, $options); - my ($headeradd, $headerremove, $mimeremove, $prefix, $j); - - # Store some variables before we delete them ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listname = $q->param('list'); - $listaddress = &this_listaddress; - - # Print a form of options ... - $q->delete_all; - print '

', $LANGUAGE{'editconfiguration'}, '


'; - print $q->startform; - print $q->hidden(-name=>'state', -value=>'configuration'); - print $q->hidden(-name=>'list', -value=>$listname); - print '', $LANGUAGE{'listname'}, ": $listname
"; - print "$LANGUAGE{'listaddress'}: $listaddress

"; - print '', $LANGUAGE{'listoptions'}, ':
'; - - # Print a list of options, selecting the ones that apply to this list ... - &display_options($list->getconfig); - - # Get the contents of the headeradd, headerremove, mimeremove and prefix files - $headeradd = $list->getpart('headeradd'); - $headerremove = $list->getpart('headerremove'); - $mimeremove = $list->getpart('mimeremove'); - $prefix = $list->getpart('prefix'); - - print '

', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), ' ' if defined($prefix); - print '

', $LANGUAGE{'headerremove'}, ':
', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70); - print '

', $LANGUAGE{'headeradd'}, ':
', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70); - print '

', $LANGUAGE{'mimeremove'}, ':
', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70) if defined($mimeremove); - - if(open(WEBUSER, "<$WEBUSERS_FILE")) { - my($webusers); - while() { - last if (($webusers) = m{^$listname\s*\:\s*(.+)$}); - } - close WEBUSER; - $webusers ||= $ENV{'REMOTE_USER'} || 'ALL'; - - print '

', $LANGUAGE{'allowedtoedit'}, ': ', - $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30'), ' ', - '
', $HELPER{'allowedit'}, ''; - - } - - print '

', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'edittexts'}]"); - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub update_config { - # Save the new user entered config ... - - my ($list, $options, $i, @inlocal, @inhost); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - - # Work out the command line options ... - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - # Actually update the list ... - unless($list->update($options)) { - die "List update failed"; - } - - # Update headeradd, headerremove, mimeremove and prefix ... - $list->setpart('headeradd', $q->param('headeradd')); - $list->setpart('headerremove', $q->param('headerremove')); - $list->setpart('mimeremove', $q->param('mimeremove')) if defined($q->param('mimeremove')); - $list->setpart('prefix', $q->param('prefix')) if defined($q->param('prefix')); - - &update_webusers(); -} - -# ------------------------------------------------------------------------ - -sub update_webusers { - # replace existing webusers-line or add a new one - - if($Q::webusers) { - # Back up web users file - open(TMP, ">/tmp/ezmlm-web.$$"); - open(WU, "<$WEBUSERS_FILE"); - while() { print TMP; } - close TMP; close WU; - - open(TMP, "$WEBUSERS_FILE"); - while() { - if(/^$Q::list\s*:/) { - print WU "$Q::list\: $Q::webusers\n"; - } else { - print WU; - } - } - close TMP; close WU; - unlink "/tmp/ezmlm-web.$$"; - } - -} - -# ------------------------------------------------------------------------ - -sub this_listaddress { - # Work out the address of this list ... Used often so put in its own subroutine ... - - my ($list, $listaddress); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - chomp($listaddress = $list->getpart('outlocal')); - $listaddress .= '@'; - chomp($listaddress .= $list->getpart('outhost')); - return $listaddress; -} - -# ------------------------------------------------------------------------ - -sub list_text { - # Show a listing of what is in DIR/text ... - - my(@files, $list); - $list = $LIST_DIR . '/' . $q->param('list'); - - # Read the list directory for text ... - opendir DIR, "$list/text" || die "Unable to read DIR/text: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'list_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print '

'; - print $q->scrolling_list(-name=>'file', -values=>\@files); - print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'editfile'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print '

', $LANGUAGE{'edittextinfo'}, '

'; - print $q->endform; - -} - -# ------------------------------------------------------------------------ - -sub edit_text { - # Allow user to edit the contents of DIR/text ... - - my ($content); - my($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $content = $list->getpart("text/$Q::file"); - - # Print a form ... - $q->delete('state'); - print '

', $LANGUAGE{'editingfile'}, ': ', $Q::file, '

'; - print '
'; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'edit_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print $q->hidden(-name=>'file', -default=>$q->param('file')); - print $q->textarea(-name=>'content', -default=>$content, -rows=>'25', -columns=>'72'); - print ''; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'savefile'}]"), ' '; - print $q->reset(-value=>"[$BUTTON{'resetform'}]"), ' '; - print $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"); - print '

', $LANGUAGE{'editfileinfo'}; - print $q->endform; - print '

' - -} - -# ------------------------------------------------------------------------ - -sub save_text { - # Save new text in DIR/text ... - - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $list->setpart("text/$Q::file", $q->param('content')); - -} - -# ------------------------------------------------------------------------ - -sub webauth { - - # Check if webusers file exists - if not, then access is granted - return 0 if (! -e "$WEBUSERS_FILE"); - - # Read authentication level from webusers file. Format of this file is - # somewhat similar to the unix groups file - my($listname) = @_; - open (USERS, "<$WEBUSERS_FILE") || die "Unable to read webusers file ($WEBUSERS_FILE): $!"; - while() { - if (/^($listname|ALL)\:/i) { - if (/(\:\s*|,\s+)((?:$ENV{'REMOTE_USER'})|(?:ALL))\s*(,|$)/) { - close USERS; return 0; - } - } - } - close USERS; - return 1; -} - -# --------------------------------------------------------------------------- - -sub webauth_create_allowed { - - # Check if webusers file exists - if not, then access is granted - return 0 if (! -e "$WEBUSERS_FILE"); - - # Read create-permission from webusers file. - # the special listname "ALLOW_CREATE" controls, who is allowed to do it - open (USERS, "<$WEBUSERS_FILE") || die "Unable to read webusers file ($WEBUSERS_FILE): $!"; - while() { - if (/^ALLOW_CREATE:/i) { - if (/(\:\s*|,\s+)((?:$ENV{'REMOTE_USER'})|(?:ALL))\s*(,|$)/) { - close USERS; return 0; - } - } - } - close USERS; - return 1; -} - -# --------------------------------------------------------------------------- - -sub display_options { - my($opts) = shift; - my($i, $j); - - print ""; - print ''; $j++; - if ($j >= 3) { - $j = 0; print ''; - } - print '
'; - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if ($opts =~ /^\w*$i\w*\s*/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print ''; - print '
'; - } - print '
'; - - print ''; - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - print ''; - - } - print '
'; - if ($opts =~ /$i (?:'(.+?)')/) { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print ''; - print ''; - print $q->textfield(-name=>"$i-value", -value=>$1||$EZMLM_LABELS{$i}[2], -size=>30); - print '
'; - -} - -# --------------------------------------------------------------------------- - -sub ezmlmcgirc { - my($listno); - if(open(WWW, "<$EZMLM_CGI_RC")) { - while() { - last if (($listno) = m{(\d+)(\D)\d+\2$LIST_DIR/$Q::list\2}); - } - close WWW; - return "$EZMLM_CGI_URL/$listno" if(defined($listno)); - } return undef; - -} - -# --------------------------------------------------------------------------- - -sub pretty_names { - return undef unless($PRETTY_NAMES); - my (%pretty, %prettymem); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - %prettymem = %pretty; - untie %pretty; - - return \%prettymem; -} - -# ------------------------------------------------------------------------- -sub rmtree { - # A subroutine to recursively delete a directory (like rm -f). - # Based on the one in the perl cookbook :) - - use File::Find qw(finddepth); - File::Find::finddepth sub { - # assume that File::Find::name is secure since it only uses data we pass it - my($name) = $File::Find::name =~ m{^(.+)$}; - - if (!-l && -d _) { - rmdir($name) or warn "couldn't rmdir $name: $!"; - } else { - unlink($name) or warn "couldn't unlink $name: $!"; - } - }, @_; - 1; -} - -# ------------------------------------------------------------------------ - -BEGIN { - sub handle_errors { - my $msg = shift; - print << "EOM"; - -
-

A fatal error has occoured

- Something you did caused this script to bail out. The error - message we got was

- $msg

- Please try what you were doing again, checking everything you entered.
- If you still find yourself getting this error, please - contact the site administrator - quoting the error message above. -

-EOM - - } - set_message(\&handle_errors); -} - -# ------------------------------------------------------------------------ -# End of ezmlm-web.cgi v2.2 -# ------------------------------------------------------------------------ -__END__ - -=head1 NAME - -ezmlm-web - A web configuration interface to ezmlm mailing lists - -=head1 SYNOPSIS - -ezmlm-web [B<-c>] [B<-C> EFE] [B<-d> EFE] - -=head1 DESCRIPTION - -=over 4 - -=item B<-C> Specify an alternate configuration file given as F -If not specified, ezmlm-web checks first in the users home directory, then in -F and then the current directory - -=item B<-d> Specify an alternate directory where lists live. This is now -depreciated in favour of using a custom ezmlmwebrc, but is left for backward -compatibility. - -=back - -=head1 SUID WRAPPER - -C<#include stdio.h> - -C - C - C -C<}> - - -=head1 DOCUMENTATION/CONFIGURATION - - Please refer to the example ezmlmwebrc which is well commented, and - to the README file in this distribution. - -=head1 FILES - -F<~/.ezmlmwebrc> -F -F<./ezmlmwebrc> - -=head1 AUTHOR - - Guy Antony Halse - -=head1 BUGS - - None known yet. Please report bugs to the author. - -=head1 S - - ezmlm(5), ezmlm-cgi(1), Mail::Ezmlm(3) - - https://systemausfall.org/toolforge/ezmlm-web - http://rucus.ru.ac.za/~guy/ezmlm/ - http://www.ezmlm.org/ - http://www.qmail.org/ diff --git a/ezmlm-web/tags/ezmlm-web-2.2/ezmlmwebrc b/ezmlm-web/tags/ezmlm-web-2.2/ezmlmwebrc deleted file mode 100644 index 301394f..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/ezmlmwebrc +++ /dev/null @@ -1,85 +0,0 @@ -# $Id: ezmlmwebrc,v 1.5 2000/09/25 18:25:26 guy Exp $ -# Configuration file for ezmlm-web 2.2 -# =========================================================================== - -# This file is not just an ordinary configuration file - it contains valid -# perl statements that are executed just like any other perl script. When -# editing this file, be careful that it is still valid perl when you have -# finished (perl -w ezmlmwebrc ;-) - -# --------------------------------------------------------------------------- - -# Where do we store lists on this server ... Try "$HOME_DIR/lists". -# This directory will automatically be created if needed. -$LIST_DIR = "$HOME_DIR/lists"; - -# Where is the webusers file for access-permissions -# defaults to "$LIST_DIR/webusers" -$WEBUSERS_FILE = "$LIST_DIR/webusers"; - -# Safe list deletion? -# 0 = move list to .list and the .qmails to deleted.qmail/. Recoverable :) -# 1 = allow user to delete list completely. No backup, therefore no recovery. -$UNSAFE_RM = 0; - -# Who is the alias user on this system (usually alias ;) -$ALIAS_USER = 'alias'; - -# Where do the qmail control files live on this system ... -$QMAIL_BASE = $Mail::Ezmlm::QMAIL_BASE . '/control'; - -# The url to our web interface - so we can use ezmlm-cgi if necessary -$EZMLM_CGI_URL = 'http://some.server.that.has/cgi-bin/ezmlm-cgi'; - -# Where our ezcgirc file lives (probably /etc/ezmlm/ezcgirc) -$EZMLM_CGI_RC = '/etc/ezmlm/ezcgirc'; - -# Do we want to allow ``pretty'' names - ie more human readable ones -# This will slow ezmlm-web down a bit for large lists -$PRETTY_NAMES = 1; - -# Do we want to allow the users to be allowed to upload a file containing -# lists of email addresses to subscribe? -$FILE_UPLOAD = 1; - -# What switches to we want ezmlm-web to have on as default. The ezmlm-make -# defaults are aBDFGHIJKLMNOpQRSTUWX (small means enabled, CAPITALS mean -# disabled). The defaults below should be reasonable - I use them ;) -$DEFAULT_OPTIONS = 'aBDFGHiJkLMNOpQRSTUWx'; - -# Where do we find the nice little help icon - by default HELP_ICON_URL -# points to resources on http://rucus.ru.ac.za/. This will work, but we -# would appreciate it if you changed this to a local site. -$HELP_ICON_URL = 'http://rucus.ru.ac.za/icons/small/unknown.gif'; - -# Header for every page (.= concatinates) -$HTML_HEADER = '
E Z Mailing List Manager

'; -$HTML_HEADER .= '
'; - -# Footer for every page (.= concatinates) -$HTML_FOOTER = '
'; -$HTML_FOOTER .= '
'; -$HTML_FOOTER .= 'ezmlm-web (v2.2) A web interface to ezmlm
'; - -# What colour do we want the background to be? -$HTML_BGCOLOR = '#000080'; - -# What colour do we want text? -$HTML_TEXT = '#000000'; - -# What color do we want links? -$HTML_LINK = '#3333ff'; - -# What color to we want visited links? -$HTML_VLINK = '#8888ff'; - -# What is the title of this document? -$HTML_TITLE = 'E Z Mailing List Manager'; - -# choose a language (en|de) -$HTML_LANGUAGE = 'en'; - -# --------------------------------------------------------------------------- -# include language-specific definitions -require('./lang/' . $HTML_LANGUAGE . '.pm'); - diff --git a/ezmlm-web/tags/ezmlm-web-2.2/htaccess.sample b/ezmlm-web/tags/ezmlm-web-2.2/htaccess.sample deleted file mode 100644 index b381a14..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/htaccess.sample +++ /dev/null @@ -1,9 +0,0 @@ -#$Id: htaccess.sample,v 1.1 2000/01/29 11:35:40 guy Exp $ -# -#order deny,allow -#deny from all -#allow from .ru.ac.za -AuthName "EZ Mailing List Manager -AuthType Basic -AuthUserFile /etc/ezmlm/.htusers -require valid-user diff --git a/ezmlm-web/tags/ezmlm-web-2.2/index.c b/ezmlm-web/tags/ezmlm-web-2.2/index.c deleted file mode 100644 index 3ba9cc1..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/index.c +++ /dev/null @@ -1,25 +0,0 @@ -/* $Id: index.c,v 1.2 2000/09/25 18:14:12 guy Exp $ */ - -#include - -/* C wrapper to allow ezmlm-web.cgi to run suid */ -/* Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved */ -/* See the README file in this distribution for copyright information */ - -int main(void) { - /* Change this path to wherever you decided to put ezmlm-web.cgi */ - execv("/usr/local/bin/ezmlm-web.cgi"); - - /* Note that you could also use the following to allow a specific user - to store their mailing lists in a different directory defined by - /tmp/ezmlm-web-demo ... This over-rides the default . */ - - /* Look at the exec(3) man page if you don't understand how the arguments - list below works */ - - /* - char *switches[] = { "ezmlm-web.cgi", "-d", "/tmp/ezmlm-web-demo", NULL }; - execv("/usr/local/bin/ezmlm-web.cgi", switches); - */ - -} diff --git a/ezmlm-web/tags/ezmlm-web-2.2/lang/de.pm b/ezmlm-web/tags/ezmlm-web-2.2/lang/de.pm deleted file mode 100644 index 468900f..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/lang/de.pm +++ /dev/null @@ -1,187 +0,0 @@ -# language-specific definitions for ezmlm-web -# in english - -# The meanings of the various ezmlm-make command line switches. The default -# ones match the ezmlm-idx 0.4 default ezmlmrc ... Alter them to suit your -# own ezmlmrc. Removing options from this list makes them unavailable -# through ezmlm-web - this could be useful for things like -w - -%EZMLM_LABELS = ( -# option => ['Short Name', -# 'Long Help Description'], - - a => ['archivieren', - 'Ezmlm wird neue Nachrichten zum Archiv hinzufügen'], - b => ['Archiv nur für ModeratorInnen', - 'Nur ModeratorInnen haben Zugriff zum Archiv'], -# c => config. This is implicity called, so is not defined here - d => ['Zusammenfassungen', - 'Erstelle eine Mailing-Liste, an die regelmäßige Zusammenfassungen versandt werden'], -# e => edit. Also implicity called, so not defined here - f => ['Listenname als Präfix in Betreff einfügen', - 'In die versandten Mails wird in der Betreff-Zeile ein Präfix eingefügt'], - g => ['Archiv nur für Mitglieder', - 'Nur TeilnehmerInnen der Liste erhalten Zugriff zum Archiv'], - h => ['abonnieren ohne Bestätigung', - 'Das Abonnieren der Liste erfordert keine Bestätigung durch die neue AbonnentIn'], - i => ['Web-Index erstellen', - 'Den Zugriff auf das Archiv per Webinterface erlauben'], - j => ['abmelden ohne Bestätigung', - 'Das Abbestellen der Liste erfordert keine Bestätigung durch die ehemalige AbonnentIn'], - k => ['Beachte Ausschlussliste', - 'Einsendungen von Abonnenten, die inm deny-Verzeichnis enthalten sind, werden abgelehnt'], - l => ['Abonnenten-Auflistung für AdministratorInnen', - 'Die AdministratorInnen können eine Liste aller AbonnentInnen anfordern'], - m => ['Moderation aktivieren', - 'Alle eingehenden Nachrichten müssen durch eine ModeratorIn bestätigt werden'], - n => ['Anpassung der Textbausteine erlauben', - 'Administratoren dürfen die Standard-Textbausteine im Unterverzeichnis text/ verändern'], - o => ['Nur ModeratorInnen dürfen einsenden', - 'Nur eingehende Nachrichten von den ModeratorInnen werden akzeptiert'], - p => ['Öffentlich', - 'Die öffentliche Einschreibung und Archiv-Anforderung ist erlaubt'], - q => ['Verarbeite Anforderungen', - 'Mails an liste-request@domain werden verarbeitet'], - r => ['Administration per Mail erlauben', - 'Die Verwaltung der Liste durch Mails der AdministratorInnen ist erlaubt'], - s => ['Abonnierung durch ModeratorIn bestätigen', - 'Die Einschreibungen in die Liste und die Zusammenfassungs-Liste werden moderiert'], - t => ['Infotext an Mails anhängen', - 'An alle ausgehenden Mails wird ein Anhang angefügt'], - u => ['Nur Abonnenten dürfen einsenden', - 'Einsendungen von nicht-eingeschriebenen Mail-Adressen werden abgewiesen'], -# v => version. I doubt you will really need this ;-) - w => ['Warnung deaktivieren', - 'Entferne den Aufruf von ezmlm-warn aus der Listen-Konfiguration - es wird angenommen, dass ezmlm-warn auf einem anderem Wege gestartet wird'], - x => ['Filtere Anhänge und Kopfzeilen', - 'Mails mit den angegebenen Anhangs-Typen werden abgewiesen - die angegebenen Kopfzeilen werden aus den ausgehenden Mails entfernt'], -# y => not used -# z => not used - -# These all take an extra argument, which is the default value to use - - 0 => ['Unterlisten', - 'Diese Liste soll eine Unterliste einer anderen Hauptliste sein', - 'hauptliste@domain'], -# 1 => not used -# 2 => not used - 3 => ['Absender', - 'Ersetze den Absender der ausgehenden Mails durch diese Adresse', - 'Absender'], - 4 => ['Zusammenfassungseinstellungen', - 'Einstellungen for ezmlm-tstdig (nach "t" Stunden oder "m" Nachrichten oder "k" Kilobyte', - '-t24 -m30 -k64'], - 5 => ['Adresse des Verantwortlichen der Liste', - 'Mail-Adresse des Listen-Eigentümers', - 'name@domain.org'], - 6 => ['SQL-Datenbank', - 'SQL-Datenbank-Zugangsinformationen (erfordert SQL-Unterstützung)', - 'host:port:user:password:datab:table'], - 7 => ['Listen-Moderations-Verzeichnis', - 'Falls die Liste moderiert wird, ist der vollständige Verzeichnispfad zur Moderationsdatenbank erforderlich', - '/absoluter/pfad/zur/moderations/datenbank'], - 8 => ['Einschreibungs-Moderations-Verzeichnis', - 'Falls die Einschreibung in die Liste moderiert wird, ist der vollständige Verzeichnispfad zur Einschreibungs-Moderationsdatenbank erforderlich', - '/absoluter/pfad/zur/abonnenten/moderations/datenbank'], - 9 => ['Administrations-Verzeichnis', - 'Falls die Liste per Mail administriert wird, ist der vollständige Verzeichnispfad zur Administrationsdatenbank erforderlich', - '/absoluter/pfad/zur/administrations/datenbank'], - -); - -# This list defines most of the context sensitive help in ezmlm-web. What -# isn't defined here is the options, which are defined above ... You can -# alter these if you feel something else would make more sense to your users -# Just be careful of what can fit on a screen! - -%HELPER = ( - - # These should be self explainitory - addaddress => 'Eine Mail-Adresse - auch in der Form \'Max Meier \'', - addaddressfile => 'alternativ ist auch eine Datei mit je einer Adresse pro Zeile möglich', - moderator => 'ModeratorInnen kontrollen, welche Mails weitegeleitet und welche AbonnentInnen akzeptiert werden', - deny => 'Ausschluss: die Mail-Adressen, die NIE an die Liste schreiben dürfen', - allow => 'Zulassung: die Mail-Adressen, die immer an die Liste schreiben dürfen', - digest => 'Zusammenfassung: diese Leute werden regeläßige Zusammenfassungen der Mailingliste erhalten', - webarch => 'Gehe zum Web-Archiv der Mailingliste', - config => 'Einstellungen zur Mailingliste', - listname => 'Dies ist der eindeutige Name der Mailingliste', - listadd => 'Die Adresse der Mailingliste - nur der lokale Teil kann geändert werden', - webusers => 'unfertig: derzeit können Listen-Administratoren nur manuell festgelegt werden', - prefix => 'Präfix der Betreffzeile', - headerremove => 'Diese Kopfzeilen werden aus den ausgehenden Mails entfernt', - headeradd => 'Diese Kopfzeilen werden zu jeder ausgehenden Mail hinzugefügt', - mimeremove => 'Alle Mails, die die genannten Anhangs-Typen beinhalten, werden abgewiesen', - allowedit => 'Komma-getrennte Liste von (existierenden) Nutzern oder ALL', - mysqlcreate => 'Anlegen der konfigurierten MySQL-Datenbank' - -); - -# This defines the captions of each of the buttons in ezmlm-web, and allows -# you to configure them for your own language or taste. Since these are used -# by the switching algorithm it is important that every button has a unique -# caption - ie we can't have two 'Edit' buttons doing different things. - -%BUTTON = ( - - # These MUST all be unique! - create => 'Anlegen', - createlist => 'Liste anlegen', - edit => 'Bearbeiten', - delete => 'Entfernen', - deleteaddress => 'Entferne Adresse', - addaddress => 'Füge Adresse hinzu', - moderators => 'ModeratorInnen', - denylist => 'Ausschlussliste', - allowlist => 'Zulassungsliste', - digestsubscribers => 'Abonnenten der Zusammenfassungen', - configuration => 'Konfiguration', - yes => 'Ja', - no => 'Nein', - updateconfiguration => 'Speichere Konfiguration', - edittexts => 'Bearbeite Texte', - editfile => 'Bearbeite Datei', - savefile => 'Speichere Datei', - webarchive => 'Web-Archiv', - selectlist => 'Listenauswahl', - subscribers => 'AbonnentInnen', - cancel => 'Abbruch', - resetform => 'Reset', - -); - -# This defines the fixed text strings that are used in ezmlm-web. By editing -# these along with the button labels and help texts, you can convert ezmlm-web -# to another language :-) If anyone gets arround to doing complete templates -# for other languages I would appreciate a copy so that I can include it in -# future releases of ezmlm-web. - -%LANGUAGE = ( - nop => 'Diese Funktionalität ist noch nicht umgesetzt worden', - chooselistinfo => "

  • Markiere eine Liste in der Auswahlbox oder klicke auf [$BUTTON{'create'}].
  • Klicke auf den [$BUTTON{'edit'}]-Schalter, falls du die markierte Liste bearbeiten möchtest.
  • Klicke auf den [$BUTTON{'delete'}]-Schalter, falls du die markierte Liste löschen möchtest.
", - confirmdelete => 'Bestätige die Löschung von ', # list name - subscribersto => 'Abonnenten von', # list name - subscribers => 'Abonnenten', - additionalparts => 'Weitere Listen-Bestandteile', - posting => 'Einsendungen', - subscription => 'Einschreibung', - remoteadmin => 'Entfernte AdministratorIn', - for => 'für', # as in; moderators for blahlist - createnew => 'Lege eine neue Liste an', - listname => 'Name der Liste', - listaddress => 'Adresse der Liste', - listoptions => 'Einstellungen der Liste', - allowedtoedit => 'Nutzer, die diese Liste bearbeiten dürfen', - editconfiguration => 'Einstellungen ändern', - prefix => 'Präfix der Betreff-Zeile ausgehender Nachrichten', - headerremove => 'zu entfernende Kopfzeilen', - headeradd => 'einzufügende Kopfzeilen', - mimeremove => 'abzuweisende Anhangs-Typen', - edittextinfo => "Das Auswahlfeld links enthält die Dateien des
Verzeichnisses DIR/text/. Diese Dateien werden als Antwort auf spezifische Nutzer-Anfragen oder als Teil aller ausgehenden Nachrichten versandt.

Um diese Dateien zu verändern, wähle ihren Namen im Auswahlfeld an. Anschlißend klicke auf den [$BUTTON{'editfile'}] Schalter.

Betätige [$BUTTON{'cancel'}] um die Veränderung abzubrechen.", - editingfile => 'Bearbeite Datei', - editfileinfo => 'ezmlm-manage
<#l#> Der Name der Liste
<#A#> Die Anmeldungs-Adresse
<#R#> Die Bestätigungs-Adresse

ezmlm-store
<#l#> Der Name der Liste
<#A#> Die Zusage-Adresse
<#R#> Die Ablehungs-Adresse', - mysqlcreate => 'Lege die MySQL-Datenbank an, falls erforderlich', - -); - -# === Configuration file ends === diff --git a/ezmlm-web/tags/ezmlm-web-2.2/lang/en.pm b/ezmlm-web/tags/ezmlm-web-2.2/lang/en.pm deleted file mode 100644 index 25bd2b1..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/lang/en.pm +++ /dev/null @@ -1,187 +0,0 @@ -# language-specific definitions for ezmlm-web -# in english - -# The meanings of the various ezmlm-make command line switches. The default -# ones match the ezmlm-idx 0.4 default ezmlmrc ... Alter them to suit your -# own ezmlmrc. Removing options from this list makes them unavailable -# through ezmlm-web - this could be useful for things like -w - -%EZMLM_LABELS = ( -# option => ['Short Name', -# 'Long Help Description'], - - a => ['Archived', - 'Ezmlm will archive new messages'], - b => ['Block archive', - 'Only moderators are allowed to access the archive'], -# c => config. This is implicity called, so is not defined here - d => ['Digest', - 'Set up a digest list to disseminate digest of the list messages'], -# e => edit. Also implicity called, so not defined here - f => ['Prefix', - 'Outgoing subject will be prefixed with the list name'], - g => ['Guard Archive', - 'Archive access requests from unrecognized SENDERs will be rejected'], - h => ['Help subscription', - 'Subscriptions do not require confirmation'], - i => ['Indexed', - 'Indexed for WWW archive access'], - j => ['Jump off', - 'Unsubscribe does not require confirmation'], - k => ['Kill', - 'Posts from addresses in dir/deny/ are rejected'], - l => ['Subscriber List', - 'Remote administrators can request a subscriber list'], - m => ['Message Moderation', - 'All incoming messages are moderated'], - n => ['Text Editing', - 'Allow remote administrators to edit files in dir/text/'], - o => ['Others rejected', - 'Posts from addresses other than moderators are rejected'], - p => ['Public', - 'List will respond to administrative requests and archive retrieval'], - q => ['Service Request Address', - 'Process commands sent in the subject to local-request@host'], - r => ['Remote Admin', - 'Enable remote adminstration of the list'], - s => ['Subscription Moderation', - 'Subscriptions to the main list and digest will be moderated'], - t => ['Trailer', - 'Add a trailer to outgoing messages'], - u => ['User Posts Only', - 'Posts from unrecognized SENDER addresses will be rejected'], -# v => version. I doubt you will really need this ;-) - w => ['Remove Warn', - 'Remove the ezmlm-warn(1) invocations from the list setup. It is assumed that ezmlm-warn(1) is run by other means'], - x => ['Extra', - 'Strip certain mimetypes, etc'], -# y => not used -# z => not used - -# These all take an extra argument, which is the default value to use - - 0 => ['Sublist', - 'Make the list a sublist of list mainlist@host', - 'mainlist@host'], -# 1 => not used -# 2 => not used - 3 => ['From Address', - 'Replace the "From:" header of the message with "From: fromarg"', - 'fromarg'], - 4 => ['Digest Options', - 'Switches for ezmlm-tstdig(1)', - '-t24 -m30 -k64'], - 5 => ['List Owner', - 'The email address of the list owner', - ''], - 6 => ['SQL Database', - 'SQL database connect information. Requires SQL support', - 'host:port:user:password:datab:table'], - 7 => ['Message Moderation Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'], - 8 => ['Subscription Moderation Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'], - 9 => ['Remote Admin Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'] - -); - -# This list defines most of the context sensitive help in ezmlm-web. What -# isn't defined here is the options, which are defined above ... You can -# alter these if you feel something else would make more sense to your users -# Just be careful of what can fit on a screen! - -%HELPER = ( - - # These should be self explainitory - addaddress => 'You may enter any RFC822 compliant email address here, including the comment part. For example; J Random User ', - addaddressfile => 'or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line', - moderator => 'Moderators: people who control who may subscribe or post to a list', - deny => 'Deny: A list of addresses that are _never_ allowed to mail the list', - allow => 'Allow: A list of address that are allowed to mail the list even if the configuration otherwise restricts it', - digest => 'Digest: People who will recieve a digest of all messages on the list', - webarch => 'View the web based archive of this list', - config => 'This lets you alter the way the list is set up', - listname => 'This is the name of the list as displayed on the Select Lists screen. It is also the name of the subdirectory that contains the list', - listadd => 'This is the email address of the list. Note that the defaults come from your qmail config. You should just update the local part (before the @)', - webusers => 'NB! At this stage, any users specified here must exist. User creation may be added in future versions', - prefix => 'Text to add to the subject line of all outgoing messages', - headerremove => 'This is a list of headers to remove from all outgoing mail', - headeradd => 'This is a list of headers to add to all outging mail', - mimeremove => 'All messages whose Content-Type matches these mime types will be bounced back to sender', - allowedit => 'Comma separated list of usernames, or ALL (all valid users)', - mysqlcreate => 'This will create the necessary MySQL tables if the list configuration above requires it' - -); - -# This defines the captions of each of the buttons in ezmlm-web, and allows -# you to configure them for your own language or taste. Since these are used -# by the switching algorithm it is important that every button has a unique -# caption - ie we can't have two 'Edit' buttons doing different things. - -%BUTTON = ( - - # These MUST all be unique! - create => 'Create', - createlist => 'Create List', - edit => 'Edit', - delete => 'Delete', - deleteaddress => 'Delete Address', - addaddress => 'Add Address', - moderators => 'Moderators', - denylist => 'Deny List', - allowlist => 'Allow List', - digestsubscribers => 'Digest Subscribers', - configuration => 'Configuration', - yes => 'Yes', - no => 'No', - updateconfiguration => 'Update Configuration', - edittexts => 'Edit Texts', - editfile => 'Edit File', - savefile => 'Save File', - webarchive => 'Web Archive', - selectlist => 'Select List', - subscribers => 'Subscribers', - cancel => 'Cancel', - resetform => 'Reset Form', - -); - -# This defines the fixed text strings that are used in ezmlm-web. By editing -# these along with the button labels and help texts, you can convert ezmlm-web -# to another language :-) If anyone gets arround to doing complete templates -# for other languages I would appreciate a copy so that I can include it in -# future releases of ezmlm-web. - -%LANGUAGE = ( - nop => 'Action not yet implemented', - chooselistinfo => "

  • Choose a mailing list from the selection box or click on [$BUTTON{'create'}].
  • Click on the [$BUTTON{'edit'}] button if you want to edit the selected list.
  • Click on the [$BUTTON{'delete'}] button if you want to delete the selected list.
", - confirmdelete => 'Confirm deletion of', # list name - subscribersto => 'Subscribers to', # list name - subscribers => 'subscribers', - additionalparts => 'Additional list parts', - posting => 'Posting', - subscription => 'Subscription', - remoteadmin => 'Remote Admin', - for => 'for', # as in; moderators for blahlist - createnew => 'Create a New List', - listname => 'List Name', - listaddress => 'List Address', - listoptions => 'List Options', - allowedtoedit => 'Users allowed to edit this list', - editconfiguration => 'Edit the List Configuration', - prefix => 'Subject prefex for outgoing messages', - headerremove => 'Headers to strip from all outgoing mail', - headeradd => 'Headers to add to all outgoing mail', - mimeremove => 'Mime types to strip from all outgoing mail', - edittextinfo => "The box on the left contains a list of files available in the
DIR/text directory. These files are sent out in response to specfic user request, or as part of all outgoing messages

To edit a file, select its name from the box. Then click on the [$BUTTON{'editfile'}] button.

Press [$BUTTON{'cancel'}] when you have finished editing.", - editingfile => 'Editing File', - editfileinfo => 'ezmlm-manage
<#l#> The list name
<#A#> The subscription address
<#R#> The address a subscriber must reply to

ezmlm-store
<#l#> The list name
<#A#> The acceptance address
<#R#> The rejection address', - mysqlcreate => 'Create the MySQL database tables if necessary', - -); - -# === Configuration file ends === diff --git a/ezmlm-web/tags/ezmlm-web-2.2/webusers.sample b/ezmlm-web/tags/ezmlm-web-2.2/webusers.sample deleted file mode 100644 index b89278f..0000000 --- a/ezmlm-web/tags/ezmlm-web-2.2/webusers.sample +++ /dev/null @@ -1,5 +0,0 @@ -comm: guy, arb -users: arb -members: ALL -ALL: root -ALLOW_CREATE: root, guy diff --git a/ezmlm-web/trunk/CHANGES b/ezmlm-web/trunk/CHANGES deleted file mode 100644 index ad52401..0000000 --- a/ezmlm-web/trunk/CHANGES +++ /dev/null @@ -1,99 +0,0 @@ -$Id: CHANGES,v 1.2 2000/09/25 17:54:06 guy Exp $ - -REVISION HISTORY - ezmlm-web.cgi -================================ - -Version 0.1 - 10/04/98 (Not Released) -* University Vac - I was bored and started to play. The first version just - let people play with the subscribers list. No moderators, no nothing. - -Version 0.2 - 13/04/98 (Not Released) -* Allow list creation -* Allowed users to edit moderators - -Version 0.3 - 15/04/98 -* Allow list deletion (for balin@moria.org) -* Made changes to allow it to run on RedHat 4.2 as well as FreeBSD 3.0 -* Fixed some minor bugs (cosmetic irritaions really) that people noticed -* Sorted subscribers list into alphabetical order. -* Added command line switch to change list directory (for nxsy@moria.org) -* Wrote some documentation ... - -Version 0.4 - 28/04/98 -* Fixed up virtual domain (inlocal) stuff as spotted by bryan@rucus -* Allowed the list directory to be automatically created if necessary. - -Version 0.5 - 12/05/98 (Not Released) -* More bug fixes. Mainly for mathew@graham. - -Version 1.0 - 01/08/98 -* Complete re-write to convert to perl5 and CGI.pm -* Removed a lot of dependancy on the OS. Use builtin functions instead :) -* Added support for ezmlm-idx -* Added a lot more command line option support (-adfgiklmnpqsrstux5) -* Added support for digests and digest subscribers -* Added support for blacklists -* Allowed users to edit the config of existing lists -* Allowed the user to edit headeradd and headerremove as well as mimeremove -* Allowed user to edit any of the files in DIR/text -* Revised interface to make it more user-friendly and ergonomic. -* Changed the background colour for Kether (clb@rucus) *gryn* -* Removed a big bug in the delete_list function that had gone unnoticed. - -Version 1.0.1 - 10/08/98 -* Fixed a bug in the way 1.0 re-configured virtual hosts (bryan@rucus) -* Made the script read the /var/qmail/control files instead of explicitly - setting variables (for david@summersoft) - -Version 1.0.2 - 28/08/98 -* Fixed the bug introduced in v1.0.1 :( (keith@rucus) -* Fixed the way we recreate config files (noticed by Glen Stewart) -* Made the script check return values of system calls properly -* Fixed some of the taint checking stuff ... reports less in the logs now. - -Version 1.0.3 - 03/10/98 -* Fixed the alias-alias-alias-list bug in inlocal (bryan@rucus) -* Added a bit of online help -* Fixed the & in list owner (bryan@rucus) -* Added multi-level access to lists (based on idea by Glen Stewart) - -Version 2.0 - 01/01/00 -* Rewrote most of the code to take advantage of Mail::Ezmlm -* Made the webuser file more functional (users can alter it) -* Now handles all current, and future command line options -* Changed the colours :) -* Added support for ezmlm-cgi web archives -* Made it -w and use strict clean -* Moved all user config to a separate file -* Fixed the way we worked out list config - now complete -* Allowed a user specific config over-ride ``ezmlmwebrc'' -* Allowed the printing of `nice' usernames (for Rhodes CS Dept) -* Took account of non-standard paths for moderators -* Removed all system() and `` calls from ezmlm-web.cgi -* Made `look and feel' virtually all user configurable -* Added a lot more context sensitive help -* Made ezmlm-web 99% language configurable - but no other templates yet :( -* Added support for creating databases - -Version 2.1 - 25/09/00 -* Fixed the multiple delete thing - finally! -* Fixed the '-' in username problem - The '-' in hostnames problem is fixed - in the new version of Mail::Ezmlm -* Fixed the '_' in list names problem -* Added support for file uploads of email addresses (multiple subscribe) -* Made error handling more friendly - -Version 2.2 - 26/01/02005 -* German translation of the web interface - more translations can be added easily -* changed "ALT"-tags to "TITLE" - most browsers will display the tooltip texts now -* fixed security problems (permissions were not thoroughly checked) -* user-based permission for creating lists (can be set in webusersrc) -* the location of the webusers file is now an option in ezmlmwebrc - -Version 2.3 - ??/04/02005 -* css styles are used instead of tables -* permission check for upload of files fixed -* removed some taint errors -* file upload typo fixed -* update of webusers file fixed -* moderator unsubscribe fixed diff --git a/ezmlm-web/trunk/INSTALL b/ezmlm-web/trunk/INSTALL deleted file mode 100644 index 11f2651..0000000 --- a/ezmlm-web/trunk/INSTALL +++ /dev/null @@ -1,97 +0,0 @@ -The following notes will guide you through the installation of ezmlm-web: - -0. IMPORTANT: you need the perl module Mail::Ezmlm and others to use - ezmlm-web! The file README contains the list of necessary modules. - -1. Get ezmlm-web and extract the archive: - tar xzf ezmlm-web-2.2.tar.gz - -2. Copy ezmlm-web.cgi to some publically readable directory. It does not - have to be in a path accessible to your web server, but any user with a - mailing list must be able to run it (Check the read and execute rights - on both the file and directory). We put our copy in "/usr/local/bin". - - At the top of ezmlm-web.gi you can will probably have to change the - $ENV{'PATH'} variable. Be careful about what you set as the path. Too - much is a security risk and too little will cause the script to - malfunction. Version 2.0 requires that the following programs be - accessible in your path: mv, rm - -3. Edit the ezmlmwebrc file and alter the variables to suit your - particular system. - - Be careful about the $LIST_DIR variable. This script assumes that all - users store their mailing lists in the same sub directory of the home - directory (eg ~/lists). You can override this for an individual user - by recompiling the C wrapper to call ezmlm-web.cgi with a -d option. - - Other configurable options are documented in the ezmlmwebrc file - itself. I have tried to keep the amount of information that you need to - supply to a minimum and also make reasonable guesses about default - values. - - Finally, copy the ezmlmwebrc file and the "lang" directory to one of - the following places: - - /etc/ezmlm - - the home directory of the user that runs ezmlm-web.cgi - - the directory, that contains your ezmlm-web.cgi file - -4. Edit the index.c file and change the path to the path of your copy - of ezmlm-web.cgi. Then compile this file. You can do this by issuing - the command; gcc -o index.cgi index.c - -5. For every user/virtual host that needs to manage mailing lists, you - need to create a SUID (user not root!!) copy of index.cgi (see - chmod(1) for details). These need to reside somewhere accessible by - the web server. I suggest that you put them in a sub directory (see - about security) of each user/virtual host's home directory (eg - /home/luser/public_html/ezmlm for Apache on Redhat). - - The copies don't actually have to be called index.cgi, but it is nice - for web servers that can resolve a cgi script as an index page (see the - srm.conf file in Apache). It is important to make sure that whichever - directory you choose to put them can i: Execute CGI Scripts and ii: Be - access controlled (here I mean both web and user access) by some method - (eg .htaccess, access.conf for Apache). - -6. Install some method of securing access to the page. The following - information is applicable to Apache web servers ... Detailed - information on user authentication can be obtained from the Apache - documentation (http://www.apache.org) and ApacheWeek - (http://www.apacheweek.com/features/userauth) - -6.1 Ensure that your Apache setup will allow .htaccess file to control - access in the directory that contains. This is controlled by the - AllowOverride tag in access.conf. (Also ensure you have the - necessary Apache modules installed) - -6.2 Create a htpasswd file. This is done using the htpasswd command that - comes with Apache. Its command line syntax is; - htpasswd [-c] passwordfile username - - You need to put the passwordfile somewhere that is not accessible by - people through the web, and create an entry for each user you want - to have access ... See the ApacheWeek article for more details. - -6.3 Create a .htaccess file in the directory that contains index.cgi. - Note that using Apache's built in access control, you can only control - access to directories, not individual files, hence the need for a - sub-directory in step 5. - - The format of the .htaccess file should be along the lines of this; - - AuthName EZ Mailing List Manager - AuthType Basic - AuthUserFile /path/to/passwordfile - require valid-user # or require user username - - Again, see the ApacheWeek article for details. - -7. Test the installation through the web. You should be asked for a - username and password (supplied in 6.2) and then be presented with a - screen entitled EZ Mailing List Manger. You can then try to create and - edit mailing lists ... Have Fun :) - -If you have any problems, then you can: -- take a look at https://systemausfall.org/toolforge/ezmlm-web -- send me an email: ezmlm-web@sumpfralle.de diff --git a/ezmlm-web/trunk/README b/ezmlm-web/trunk/README deleted file mode 100644 index 89fbfa7..0000000 --- a/ezmlm-web/trunk/README +++ /dev/null @@ -1,270 +0,0 @@ -$Id: README,v 1.2 2000/09/25 17:57:21 guy Exp $ - -================= -| ezmlm-web-2.2 | -================= - -If you only want to know how to install ezmlm-web, then you should -read INSTALL. - -Contents -======== - I. Copyright Stuff - II. Some Background - III. Requirements - IV. Files - V. Notes - VI. Multi-level list access - VII. Language Portability -VIII. Bugs && Bug Reports - XI. Acknowledgements - X. Availability - - -I. Copyright Stuff - essentially the FreeBSD licence ... -================== -ezmlm-web - version 2.2 - 26/01/02005 - -Copyright (C) 1998, Guy Antony Halse, All Rights Reserved. -Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -Neither name Guy Antony Halse nor the names of any contributors may be used -to endorse or promote products derived from this software without specific -prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -II. Some Background -=================== -The need for ezmlm-web arose from the fact that we host many student -societies on our system. These societies usually have a virtual host for web -and email, which is administered by a computer rep from the society. These -computer reps often have little or no knowledge of Unix and so we needed a -user friendly system that would let the create and maintain mailing lists -(such as members@foo.soc.ru.ac.za, committee@foo.soc.ru.ac.za, etc). - -Since I am never keen to re-invent the wheel, I had a look at Steve Peterson's -script (http://virtation.com/qmail/ml-sub), which allows people to subscribe -and unsubscribe from mailing lists using a form->email gateway. This is fine -for putting on a web page saying "here come and join our mailing list", but -doesn't really allow you to administrate a list. - -Security of mailing lists was a concern, as we really didn't want -unauthorised people to be able to alter some users list. Ezmlm-web itself -implements no security checks (apart from un-tainting input) and so relies -on the web server to do this (re-inventing the wheel again :). We use an -Apache webserver, so one can control access to a directory using a .htaccess -file or in the access.conf file. ApacheWeek have a good article on doing -this at http://www.apacheweek.com/features/userauth. I also give examples -later in this document. - -This version of ezmlm-web is based to a large extent on previous -versions that I have developed. It has however been totally re-written to -make use of the Mail::Ezmlm perl module I wrote. At the same time it was -updated and extended to include the new features of ezmlm-idx. It includes -many new features that have been suggested to me over the last few months, -and hopefully is now useful to a much larger group of people. - -Since 02005 ezmlm-web is maintained by Lars Kruse (ezmlm-web@sumpfralle.de). -Only minor improvements had to be implemented to keep the already fully -functional ezmlm-web up to date. - -III. Requirements -================= -This version of ezmlm-web requires the following; - -* qmail v1.03 -* ezmlm v0.53 (idx v0.40) -* Perl v5.004 and the following modules; - + Mail::Ezmlm v0.03 - + Mail::Address v1.15 - + CGI v2.6 - + CGI::Carp v1.06 - + DB_File v1.65 - + Getopt::Std v4.1 - + File::Find v? - + File::Copy v2.02 - -The version number indicates the version of the module that ezmlm-web was -developed with. Earlier versions may work, but then they haven't been -tested. Have a look on http://www.CPAN.org/, http://www.qmail.org/, and -http://www.ezmlm.org/ for anything you are missing. - -IV. Files -========= -In this distribution you should find 8 files; - -README This file. Provides some background information. - Not needed to run ezmlm-web. - -INSTALL Notes on installation. Not needed to run ezmlm-web. - -CHANGES The change history. Not needed to run ezmlm-web - -TODO This file is a list of things I intend doing in future - versions of ezmlm-web. Not needed to run ezmlm-web. - -ezmlm-web.cgi The ezmlm-web script proper. This program requires that - you have perl5 installed on your machine and that your web - server is capable of running CGI scripts. - -index.c A C wrapper to allow ezmlm-web.cgi to run suid. Not - strictly necessary if your setup allows perl scripts to - run suid, but I prefer using wrappers anyway. It needs to - be edited and compiled to suit your system. Not needed to - run ezmlm-web. - -ezmlmwebrc This is the configuration file for ezmlm-web. All options - are explained in this example file. You will need this - file to run ezmlm-web. - -htaccess.sample A sample Apache .htaccess file for controlling access to - the mailing lists. If you use another web server, you will - have to work this bit out for yourself. - -webusers.sample A sample webusers file for multi-level access control. - -The directory "lang" contains the language files. You will need at least the -one, that you have choosen in "ezmlmwebrc" by the option "HTML_LANGUAGE". - -V. Notes -========= -* There is a function to delete mailing lists, but I really don't like the - idea. The only reason I put it in is that bvi@rucus asked for it. - If you set $UNSAFE_RD = 0 (the default) in the config section, the - ezmlm-web won't actually delete the list. In this case it moves the - to . and all the associated .qmail files to a sub-directory called - deleted.qmail/ (In the users home directory. This is by far a safer way - (since you can restore lists) and therefore I recommend it. - -* The HTML interface has been tested using Nutscrape, Internet Exploder, and - Lynx. If anyone uses anything else and has problems, please let me know. - -* I suggest that you make use of custom ezmlmwebrc files rather than using - the -d command line switches - it makes fault diagnosis easier ... - -* Please see the section on languages below. - -VI. Multi-Level Access -======================= -Ezmlm-web has a multi-level access system. This depends on a file called -webusers being present in $LIST_DIR. If the file is not present, then any -valid user has access to all lists. If, however, this file exists a number -of constraints come into place. - -- The webusers file is scanned for either the list name (case insensitive) or - an ALL (case sensitive) entry. -- The list entry (or ALL) is scanned for the current user (as set in - $REMOTE_USER) or an ALL entry. -- If any valid match is made, then the user is allowed to edit the list. - Otherwise the user is politely told to go away ;-) - -If list creation is allowed and the webusers file exists, then the person who -creates the list is the default owner. As of yet there is no way to create users -through the web interface, but I intend to do this eventually. - -The format of a webusers file is as follows; - -list1: user1, user2, user3 -ALL: user1, user2 -list2: ALL - -ie; listname colon (:) and a comma (,) separated list of users. Spaces are -ignored but each list must appear on a new line. - -Once this file exists, the ezmlm-web script will allow the list users to -configure their access lists along with any other options. - -You can permit some users to create lists by adding a line similar to the -following to your webusers file: - -ALLOW_CREATE: user2, user3 - -If there is no line starting with "ALLOW_CREATE:" in the webusers file, then -no one will be allowed to create lists. This behaviour is new for ezmlm-web -since version 2.2. To stay compatible to old installations, the commandline -option "-c" for ezmlm-web.cgi will still allow everyone to create lists. The -use of this option is deprecated, since the line "ALLOW_CREATE: ALL" provides -the same effect in a cleaner way. - -VII. Language Portablity -========================= -One of the great new features of version 2.0 is that it is essentially -language independant (okay, not quite, but is 99% of the way there). Most of -the fixed strings, help, etc is defined in the files of lang directory. -Of course you can change them or create a new translation. - -The language can be selected in ezmlmwebrc with the "HTML_LANGUAGE" option. - -If anyone gets round to writing full templates for languages I would -appreciate it if you would do two things; - -Firstly, make them public and announce them on the ezmlm@lists.cr.yp.to -mailing list so that others may benefit. - -Secondly, please mail me a copy (ezmlm-web@sumpfralle.de) so that I may use -them in any future releases of ezmlm-web. - - -VIII. Bugs && Bug Reports -======================= -I don't know of any bugs, but then this is a rewrite and a first release. It -has been tested reasonably well, but not exhaustively. I know it works on -FreeBSD 4.0-STABLE, FreeBSD 3.4-RELEASE, RedHat 5.1 and Redhat 6.0 all using -an Apache web server, but I would be interested to know whether it works on -other OSs and with other web servers. This version is far less dependent on -the OS than previous versions so I don't see any reason why it shouldn't. - -Please mail bug reports and comments to ezmlm-web@sumpfralle.de. - -IX. Acknowledgements -=================== -* Guy Antony Halse (guy-ezmlm@rucus.ru.ac.za) - He created ezmlm-web, - maintained it till 02005 and wrote nearly every line of code! -* Keith Burdis (keith@rucus.ru.ac.za) - For constantly bugging me and - ensuring that I actually got round to writing some code :) -* Bryan Kilian (bryan@rucus.ru.ac.za) and the administrators of the - Litestep mailing list - For helping beta test and putting up with me - pestering them. -* Several societies at Rhodes. For switching to my web interface and so - unknowingly helping to beta test it. -* Barry Irwin (bvi@moria.org) - For trusting me and moving the Grahamstown - Foundation over to qmail and ezmlm - yet another beta tester :-) -* David Summers (david@summersoft.fay.ar.us) - For some ideas. And for - offering to make up an RPM version. I hope the offer still exists for - version 2.0 :-) -* Glen Stewart (glen_stewart@associate.com) - For a multitude of ideas. -* Fred Lindberg (lindberg@id.wustl.edu) for his useful posts to the - mailing list, suggestions, help, etc -* Galen Johnson (gjohnson@totalsports.net) - For some ideas on bugfixes. - -X. Availability -================= -More information on ezmlm-web and developments to ezmlm-web can be found at: -https://systemausfall.org/toolforge/ezmlm-web - -The website of Guy Antony Halse (the author of ezmlm-web) is still at: -http://rucus.ru.ac.za/~guy/ezmlm/ - -The old ftp-archive of ezmlm-web is still available on: -ftp://rucus.ru.ac.za/pub/mail/ezmlm/ diff --git a/ezmlm-web/trunk/TODO b/ezmlm-web/trunk/TODO deleted file mode 100644 index cc2a4ab..0000000 --- a/ezmlm-web/trunk/TODO +++ /dev/null @@ -1,27 +0,0 @@ -$Id: TODO,v 1.3 2000/09/25 19:58:02 guy Exp $ - -TODO - ezmlm-web 2.3 - -DOKU: -- mention in INSTALL, that a missing webusers-file deactivates access control -- more documentation -- webusers is not mentioned in INSTALL - -ORG: -- change ./lang/ to /usr/local/share/ezmlm-web/lang -- move unknown.gif to systemausfall.org -- some nice install method -- easy-mode? - maybe with typical profiles - or: separation basic / expert - -CODE: -- check and improve DEFAULT_HOST -- check virtual user testing -- implement ldap authorisation -- check: the textfields for paths are filled with the first set value -- line 472 - replace "return" by "if"-construct - -LAYOUT: -- option for a css-stylesheet -- migrate header and footer in ezmlmwebrc to css -- improve css-design -- "prefix"-option should be next to its text field (as with all paths) diff --git a/ezmlm-web/trunk/UPGRADING b/ezmlm-web/trunk/UPGRADING deleted file mode 100644 index 7abe744..0000000 --- a/ezmlm-web/trunk/UPGRADING +++ /dev/null @@ -1,39 +0,0 @@ -$Id: UPGRADING,v 1.1 2000/09/25 19:24:20 guy Exp $ - -UPGRADING ezmlm-web 2.1 to ezmlm-web 2.2 - -1) Creating of new lists is now controlled by a line in the webusers file instead -of a commandline switch for ezmlm-web.cgi. - -necessary changes: - - optional: remove switch "-c" when calling ezmlm-web.cgi (take a look at index.c) - - optional: add a line like "ALLOW_CREATE: john, myra" to the webusers file - -2) The location of the webusers file is now defined in ezmlmwebrc. (default: $LIST_DIR/webusers) - -necessary changes: - - optional: add a line like "$WEBUSERS_FILE = /home/ml/webusers" to ezmlmwebrc - -3) A german translation is available. - - - optional: include "lang/de.pm" in ezmlmwebrc (there you can also remove the english definitions) - or copy the new ezmlmwebrc :) - ------------------------------------------------------------------------------- - -UPGRADING ezmlm-web 2.0 to ezmlm-web 2.1 - -There are no major changes that need to be made in order to upgrade. All -that is necessary is to add two new lines to your ezmlmwebrc ... In the top -section of the file add - -$FILE_UPLOAD = 1; - -and in the %HELPER section, you need to add - -addaddressfile => 'or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line', - -(or just copy the new ezmlmwebrc :) - -Have a look for these two lines in the new ezmlmwebrc included in this -distribution if you are unsure of how/where to put these. diff --git a/ezmlm-web/trunk/css/default.css b/ezmlm-web/trunk/css/default.css deleted file mode 100644 index 2311365..0000000 --- a/ezmlm-web/trunk/css/default.css +++ /dev/null @@ -1,202 +0,0 @@ -body { - background-color: #000080; - color: #000000; - } - -h1 { - text-align: center; - } - -h2 { - text-align: center; - } - -a { - color: #3333ff; - } - -a:visited { - color: #8888ff; - } - - -/*********************** general ************************** - -used classes for containers: - title - heading of most pages (except main) - list - list of subscribers/mailinglists/moderators/... - add_remove - buttons and fields to manipulate such lists - info - explanations - question - buttons to answer a question - options - various possibilities (buttons) - input - group of form fields - container - includes all other containers on a page - -low-level classes (for "span"): - button - formfield - checkbox - help - -and a special div: - error - -************************************************************/ - -div.container { - margin-left: auto; - margin-right: auto; - } - -div.add_remove span.button { - width: auto; - margin-top: 0px; - margin-right: auto; - } - -div.add_remove span.formfield { - width: auto; - margin: 0px; - margin-right: auto; - padding: 0px; - } - -div.add_remove span.formfield:before { - content: attr("
"); - } - -div.list { - margin: 1%; - margin-right: 3%; - text-align: center; - float: left; - margin-bottom: auto; - } - -div.question { - text-align: center; - } - -p.warning { - text-decoration: blink; - color: #ff0000; - text-align: center; - } - -span.help { - font-size: small; - } - -span.button { - margin-left: 3px; - margin-right: 3px; - } - -span.formfield { - margin-right: auto; - } - -/************************ main page *********************** -name of container: main -available classes: list info add_remove -**********************************************************/ - - - - - -/******************* confirm delete page ******************* -name of container: delete -available classes: title button -***********************************************************/ - - - - - -/************************* edit page *********************** -name of container: edit -availbale classes: title list add_remove options -***********************************************************/ - - - - - -/********* allow/deny/moderators/digests page ************** -name of container: parts -available classes: title info list add_remove -***********************************************************/ - - - - - -/******************* create list page ********************** -name of container: create -available classes: title input question -***********************************************************/ - -#create div.input span.formfield { - font-weight: bold; - font-size: large; - margin-left: 0px; - margin-right: auto; - } - - - -/********************* config page ************************* -name of container: config -available classes: title info input question -***********************************************************/ - -#config div.info { - font-size: large; - font-weight: bold; - } - -#config div.input span.formfield { - font-weight: bold; - margin-left: 0px; - margin-right: auto; - } - - -/******************** textfiles **************************** -name of container: textfiles -available classes: list info question -***********************************************************/ - - - - - -/******************** edittext ***************************** -name of container: edittext -available classes: title input info question -***********************************************************/ - -#edittext div.input { - float:left; - } - - - -/**************** error messages **************************/ - -div.error { - width: 99%; - padding: 5px; - text-align: center; - background-color: #e0e0ff; - } - -div.error h2 { - color: #ff0000; - } - -div.error p.msg { - font-weight: bold; - } - diff --git a/ezmlm-web/trunk/ezmlm-web.cgi b/ezmlm-web/trunk/ezmlm-web.cgi deleted file mode 100755 index 5fda9a8..0000000 --- a/ezmlm-web/trunk/ezmlm-web.cgi +++ /dev/null @@ -1,1251 +0,0 @@ -#!/usr/bin/perl -#=========================================================================== -# ezmlm-web.cgi - version 2.2 - 26/01/02005 -# $Id: ezmlm-web.cgi,v 1.3 2000/09/25 19:58:07 guy Exp $ -# -# Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved. -# Please send bug reports and comments to guy-ezmlm@rucus.ru.ac.za -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# Neither name Guy Antony Halse nor the names of any contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS -# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# ========================================================================== -# All user configuration happens in the config file ``ezmlmwebrc'' -# POD documentation is at the end of this file -# ========================================================================== - -# Modules to include -use strict; -use Getopt::Std; -use Mail::Ezmlm; -use Mail::Address; -use DB_File; -use CGI; -use CGI::Carp qw(fatalsToBrowser set_message); - -# These two are actually included later and are put here so we remember them. -#use File::Find if ($UNSAFE_RM == 1); -#use File::Copy if ($UNSAFE_RM == 0); - -my $q = new CGI; -$q->import_names('Q'); -use vars qw[$opt_c $opt_d $opt_C]; -getopts('cd:C:'); - -# Suid stuff requires a secure path. -$ENV{'PATH'} = '/bin'; - -# We run suid so we can't use $ENV{'HOME'} and $ENV{'USER'} to determine the -# user. :( Don't alter this line unless you are _sure_ you have to. -my @tmp = getpwuid($>); my $USER=$tmp[0]; - -# use strict is a good thing++ - -use vars qw[$HOME_DIR]; $HOME_DIR=$tmp[7]; -use vars qw[$DEFAULT_OPTIONS %EZMLM_LABELS $UNSAFE_RM $ALIAS_USER $LIST_DIR]; -use vars qw[$QMAIL_BASE $EZMLM_CGI_RC $EZMLM_CGI_URL $HTML_BGCOLOR $PRETTY_NAMES]; -use vars qw[%HELPER $HELP_ICON_URL $HTML_HEADER $HTML_FOOTER $HTML_TEXT $HTML_LINK]; -use vars qw[%BUTTON %LANGUAGE $HTML_VLINK $HTML_TITLE $FILE_UPLOAD $WEBUSERS_FILE]; -use vars qw[$HTML_CSS_FILE]; - -# Get user configuration stuff -if(defined($opt_C)) { - require "$opt_C"; # Command Line -} elsif(-e "$HOME_DIR/.ezmlmwebrc") { - require "$HOME_DIR/.ezmlmwebrc"; # User -} elsif(-e "/etc/ezmlm/ezmlmwebrc") { - require "/etc/ezmlm/ezmlmwebrc"; # System -} elsif(-e "./ezmlmwebrc") { - require "./ezmlmwebrc"; # Install -} else { - die "Unable to read config file"; -} - -# Allow suid wrapper to over-ride default list directory ... -if(defined($opt_d)) { - $LIST_DIR = $1 if ($opt_d =~ /^([-\@\w.\/]+)$/); -} - -# If WEBUSERS_FILE is not defined in ezmlmwebrc (as before version 2.2), then use former default value for compatibility -if (!defined($WEBUSERS_FILE)) { - $WEBUSERS_FILE = $LIST_DIR . '/webusers' -} - -# Work out default domain name from qmail (for David Summers) -my($DEFAULT_HOST); -open (GETHOST, "<$QMAIL_BASE/me") || open (GETHOST, "<$QMAIL_BASE/defaultdomain") || die "Unable to read $QMAIL_BASE/me: $!"; -chomp($DEFAULT_HOST = ); -close GETHOST; - -# Untaint form input ... -&untaint; - -# redirect must come before headers are printed -if(defined($Q::action) && $Q::action eq '[Web Archive]') { - print $q->redirect(&ezmlmcgirc); - exit; -} - -# Print header on every page ... -print $q->header(-pragma=>'no-cache', '-cache-control'=>'no-cache', -expires=>'-1d', '-Content-Type'=>'text/html; charset=utf-8'); -print $q->start_html(-style=>{'src'=>"$HTML_CSS_FILE"},-title=>$HTML_TITLE, -author=>'guy-ezmlm@rucus.ru.ac.za', -expires=>'-1d'); -print $HTML_HEADER; - -# check permissions -&check_permission_for_action == 0 || die 'Error: you are not allowed to do this!'; - -# This is where we decide what to do, depending on the form state and the -# users chosen course of action ... -unless (defined($q->param('state'))) { - # Default action. Present a list of available lists to the user ... - &select_list; - -} elsif ($Q::state eq 'select') { - # User selects an action to perform on a list ... - - if ($Q::action eq "[$BUTTON{'create'}]") { # Create a new list ... - &allow_create_list; - } elsif (defined($Q::list)) { - if ($Q::action eq "[$BUTTON{'edit'}]") { # Edit an existing list ... - &display_list; - } elsif ($Q::action eq "[$BUTTON{'delete'}]") { # Delete a list ... - &confirm_delete; - } - } else { - &select_list; # NOP - Blank input ... - } - -} elsif ($Q::state eq 'edit') { - # User chooses to edit a list - - my($list); $list = $LIST_DIR . '/' . $q->param('list'); - if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ... - &delete_address($list); - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address($list); - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'moderators'}]") { # Edit the moderators ... - &part_subscribers('mod'); - - } elsif ($Q::action eq "[$BUTTON{'denylist'}]") { # Edit the deny list ... - &part_subscribers('deny'); - - } elsif ($Q::action eq "[$BUTTON{'allowlist'}]") { # edit the allow list ... - &part_subscribers('allow'); - - } elsif ($Q::action eq "[$BUTTON{'digestsubscribers'}]") { # Edit the digest subscribers ... - &part_subscribers('digest'); - - } elsif ($Q::action eq "[$BUTTON{'configuration'}]") { # Edit the config ... - &list_config; - - } else { # Cancel - Return a screen ... - &select_list; - } - -} elsif ($Q::state eq 'allow' || $Q::state eq 'mod' || $Q::state eq 'deny' || $q->param('state') eq 'digest') { - # User edits moderators || deny || digest ... - - my($part); - # Which list directory are we using ... - if($Q::state eq 'mod') { - $part = 'mod'; - } elsif($Q::state eq 'deny' ) { - $part = 'deny'; - } elsif($Q::state eq 'allow') { - $part = 'allow'; - } else { - $part = 'digest'; - } - - if ($Q::action eq "[$BUTTON{'deleteaddress'}]") { # Delete a subscriber ... - &delete_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } elsif ($Q::action eq "[$BUTTON{'addaddress'}]") { # Add a subscriber ... - &add_address("$LIST_DIR/$Q::list", $part); - &part_subscribers($part); - - } else { # Cancel - Return to the list ... - &display_list; - } - -} elsif ($Q::state eq 'confirm_delete') { - # User wants to delete a list ... - - &delete_list if($q->param('confirm') eq "[$BUTTON{'yes'}]"); # Do it ... - $q->delete_all; - &select_list; - -} elsif ($Q::state eq 'create') { - # User wants to create a list ... - - if ($Q::action eq "[$BUTTON{'createlist'}]") { - if (&create_list) { # Return if list creation is unsuccessful ... - &allow_create_list; - } else { - &select_list; # Else choose a list ... - } - - } else { # Cancel ... - &select_list; - } - -} elsif ($Q::state eq 'configuration') { - # User updates configuration ... - - if ($Q::action eq "[$BUTTON{'updateconfiguration'}]") { # Save current settings ... - &update_config; - &display_list; - - } elsif ($Q::action eq "[$BUTTON{'edittexts'}]") { # Edit DIR/text ... - &list_text; - - } else { # Cancel - Return to list editing screen ... - &display_list; - } - -} elsif ($Q::state eq 'list_text') { - # User wants to edit texts associated with the list ... - - if ($Q::action eq "[$BUTTON{'editfile'}]") { - &edit_text; - } else { - &list_config; # Cancel ... - } - -} elsif ($Q::state eq 'edit_text') { - # User wants to save a new version of something in DIR/text ... - - &save_text if ($Q::action eq "[$BUTTON{'savefile'}]"); - &list_text; - -} else { - print "

$Q::action

$LANGUAGE{'nop'}


"; -} - -# Print HTML footer and exit :) ... -print $HTML_FOOTER, $q->end_html; -exit; - -# ========================================================================= - -sub select_list { - # List all mailing lists (sub directories) in the list directory. - # Allow the user to choose a course of action; either editing an existing - # list, creating a new one, or deleting an old one. - - my (@lists, @files, $i, $scrollsize); - - # Read the list directory for mailing lists. - opendir DIR, $LIST_DIR || die "Unable to read $LIST_DIR: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Check that they actually are lists ... - foreach $i (0 .. $#files) { - if (-e "$LIST_DIR/$files[$i]/lock") { - $lists[$#lists + 1] = $files[$i] if (&webauth($files[$i]) == 0); - } - } - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#lists + 1) > 25); - - # Begin of content - print '
'; - - # Print a form - $q->delete_all; - print $q->startform; - print $q->hidden(-name=>'state', -default=>'select'); - - print '
'; - print $q->scrolling_list(-name=>'list', -size=>$scrollsize, -values=>\@lists) if defined(@lists); - print '
'; # end of main_mainlinglists_list - - print '
', $LANGUAGE{'chooselistinfo'}, '
'; # explanation of options - - print '
'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'create'}]"), '' if (&webauth_create_allowed == 0); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'edit'}]"), '' if(defined(@lists)); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'delete'}]"), '' if(defined(@lists)); - print '
'; # end of main_buttons - print $q->endform; - - print '
'; # end of content -} - -# ------------------------------------------------------------------------ - -sub confirm_delete { - # Make sure that the user really does want to delete the list! - - # Begin of content - print '
'; - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'confirm_delete'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - - print '
'; - print '

', $LANGUAGE{'confirmdelete'}, ' ', $q->param('list'), '

'; - print '
'; # end of delete->title - - print '
'; - print '', $q->submit(-name=>'confirm', -value=>"[$BUTTON{'no'}]"), ''; - print '', $q->submit(-name=>'confirm', -value=>"[$BUTTON{'yes'}]"), ''; - print '
'; # end of delete->question - - print '
'; # enf of delete -} - -# ------------------------------------------------------------------------ - -sub display_list { - # Show a list of subscribers to the user ... - - my ($i, $list, $listaddress, $moderated, @subscribers, $scrollsize); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - - # Get a list of subscribers from ezmlm ... - @subscribers = $list->subscribers; - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Print out a form of options ... - $q->delete('state'); - - # Begin of content - print '
'; - - print '
'; - print "

$LANGUAGE{'subscribersto'} $Q::list

"; - print "

($listaddress)

"; - print '
'; - print '
'; # end of edit->title - - print $q->start_multipart_form; - print $q->hidden(-name=>'state', -default=>'edit'); - print $q->hidden(-name=>'list', -default=>$Q::list); - - print '
'; - print $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -labels=>&pretty_names, -multiple=>'true') if defined(@subscribers); - print '
'; # end of edit->list - - print '
'; - print '

', ($#subscribers + 1), ' ', $LANGUAGE{'subscribers'}, '

' if defined(@subscribers); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '' if defined(@subscribers); - print '', $q->textfield(-name=>'addsubscriber', -size=>'40'), ' '; - print '', $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ' if ($FILE_UPLOAD); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), ''; - print '
'; # end of edit->add_remove - - print '
'; - print '

', $LANGUAGE{'additionalparts'}, ':

' if($list->ismodpost || $list->ismodsub || $list->isremote || $list->isdeny || $list->isallow || $list->isdigest); - print '

'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'moderators'}]"), ' ' if ($list->ismodpost || $list->ismodsub || $list->isremote); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'denylist'}]"), ' ' if ($list->isdeny); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'allowlist'}]"), ' ' if ($list->isallow); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'digestsubscribers'}]"), ' ' if ($list->isdigest); - print '

'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'webarchive'}]"), ' ' if(&ezmlmcgirc); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'configuration'}]"), ' '; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'selectlist'}]"), ''; - print '

'; - print '
'; # end of edit->options - print $q->endform; - - print '
'; # end of edit - -} - -# ------------------------------------------------------------------------ - -sub delete_list { - # Delete a list ... - - # Fixes a bug from the previous version ... when the .qmail file has a - # different name to the list. We use outlocal to handle vhosts ... - my ($list, $listaddress, $listadd); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - if ($listadd = $list->getpart('outlocal')) { - chomp($listadd); - } else { - $listadd = $q->param('list'); - } - $listaddress = $1 if ($listadd =~ /-?(\w+)$/); - - if ($UNSAFE_RM == 0) { - # This doesn't actually delete anything ... It just moves them so that - # they don't show up. That way they can always be recovered by a helpful - # sysadmin should he be in the mood :) - - use File::Copy; - - my ($oldfile); $oldfile = "$LIST_DIR/$Q::list"; - my ($newfile); $newfile = "$LIST_DIR/.$Q::list"; - move($oldfile, $newfile) or die "Unable to rename list: $!"; - mkdir "$HOME_DIR/deleted.qmail", 0700 if(!-e "$HOME_DIR/deleted.qmail"); - - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - foreach (@files) { - unless (move($_, "$HOME_DIR/deleted.qmail/")) { - die "Unable to move .qmail files: $!"; - } - } - warn "List '$oldfile' moved (deleted)"; - } else { - # This, however, does DELETE the list. I don't like the idea, but I was - # asked to include support for it so ... - if (!rmtree("$LIST_DIR/$Q::list")) { - die "Unable to delete list: $!"; - } - opendir(DIR, "$HOME_DIR") or die "Unable to get directory listing: $!"; - my @files = map { "$HOME_DIR/$1" if m{^(\.qmail.+)$} } grep { /^\.qmail-$listaddress/ } readdir DIR; - closedir DIR; - if (unlink(@files) <= 0) { - die "Unable to delete .qmail files: $!"; - } - warn "List '$list->thislist()' deleted"; - } -} - -# ------------------------------------------------------------------------ -sub untaint { - - $DEFAULT_HOST = $1 if $DEFAULT_HOST =~ /^([\w\d\.-]+)$/; - - # 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 ... - - my (@params, $i, $param); - @params = $q->param; - - foreach $i (0 .. $#params) { - my(@values); - next if($params[$i] eq 'addfile'); - foreach $param ($q->param($params[$i])) { - next if $param eq ''; - if ($param =~ /^([#-\@\w\.\/\[\]\:\n\r\>\< ]+)$/) { - push @values, $1; - } else { - warn "Tainted input in '$params[$i]': " . $q->param($params[$i]); - } - $q->param(-name=>$params[$i], -values=>\@values); - } - } - $q->import_names('Q'); -} - -# ------------------------------------------------------------------------ - -sub check_permission_for_action { - # test if the user is allowed to modify the choosen list or to create an new one - # the user would still be allowed to fill out the create-form (however he got there), - # but the final creation is omitted - - my $ret; - if ($Q::state eq 'create') { - $ret = &webauth_create_allowed(); - } elsif (defined($Q::list)) { - $ret = &webauth($Q::list); - } else { - $ret = 0; - } - return $ret; - -} - -# ------------------------------------------------------------------------ - -sub add_address { - # Add an address to a list .. - - my ($address, $list, @addresses, $count); my ($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - - if (($q->param('addfile')) && ($FILE_UPLOAD)) { - - # Sanity check - die "File upload must be of type text/*" unless($q->uploadInfo($q->param('addfile'))->{'Content-Type'} =~ m{^text/}); - - # Handle file uploads of addresses - my($fh) = $q->param('addfile'); - return unless (defined($fh)); - while (<$fh>) { - next if (/^\s*$/ or /^#/); # blank, comments - next unless ( /(\w[\-\w_\.]*)@(\w[\-\w_\.]+)/ ); # email address ... - chomp(); - push @addresses, "$_"; - } - - } - - # User typed in an address - if ($q->param('addsubscriber') ne '') { - - $address = $q->param('addsubscriber'); - $address .= $DEFAULT_HOST if ($q->param('addsubscriber') =~ /\@$/); - - # untaint - if ($address =~ /(\w[\-\w_\.]*)@(\w[\-\w_\.]+)/) { - push @addresses, "$1\@$2"; - } else { - warn "this address ($address) is not valid!"; - } - - } - - foreach $address (@addresses) { - - my($add) = Mail::Address->parse($address); - if(defined($add->name()) && $PRETTY_NAMES) { - my(%pretty); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - $pretty{$add->address()} = $add->name(); - untie %pretty; - } - - if ($list->sub($add->address(), $part) != 1) { - die "Unable to subscribe to list: $!"; - } - $count++; - } - - $q->delete('addsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub delete_address { - # Delete an address from a list ... - - my ($list, @address); my($listname, $part) = @_; - $list = new Mail::Ezmlm($listname); - return if ($q->param('delsubscriber') eq ''); - - @address = $q->param('delsubscriber'); - - if ($list->unsub(@address, $part) != 1) { - die "Unable to unsubscribe from list $list: $!"; - } - - if($PRETTY_NAMES) { - my(%pretty, $add); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - foreach $add (@address) { - delete $pretty{$add}; - } - untie %pretty; - } - - $q->delete('delsubscriber'); -} - -# ------------------------------------------------------------------------ - -sub part_subscribers { - my($part) = @_; - # Deal with list parts .... - - my ($i, $list, $listaddress, @subscribers, $moderated, $scrollsize, $type); - - # Work out the address of this list ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listaddress = &this_listaddress; - - if($part eq 'mod') { - # Lets know what is moderated :) - - # do we store things in different directories? - my $config = $list->getconfig; - my($postpath) = $config =~ m{7\s*'([^']+)'}; - my($subpath) = $config =~ m{8\s*'([^']+)'}; - my($remotepath) = $config =~ m{9\s*'([^']+)'}; - - my($divclass); - - $divclass = ($postpath)? 'warning' : 'ok'; - $moderated .= "

[$LANGUAGE{'posting'}]" if ($list->ismodpost); - $moderated .= '' if ($postpath); - $moderated .= '

' if ($list->ismodpost); - - $divclass = ($subpath)? 'warning' : 'ok'; - $moderated .= "

[$LANGUAGE{'subscription'}]" if($list->ismodsub); - $moderated .= '' if ($subpath); - $moderated .= '

' if ($list->ismodsub); - - $divclass = ($remotepath)? 'warning' : 'ok'; - $moderated .= "

[$LANGUAGE{'remoteadmin'}]" if($list->isremote); - $moderated .= '' if ($remotepath); - $moderated .= '

if ($list->isremote)'; - - } - - # What type of sublist is this? - ($type) = $Q::action =~ m/^\[(.+)\]$/; - - # Get a list of moderators from ezmlm ... - @subscribers = $list->subscribers($part); - - # Keep selection box a resonable size - suggested by Sebastian Andersson - $scrollsize = 25 if(($scrollsize = $#subscribers + 1) > 25); - - # Begin of content - print '
'; - - # Print out a form of options ... - $q->delete('state'); - - print '
'; - print "

$type $LANGUAGE{'for'} $listaddress

"; - print '
'; - print '
'; # end of parts_title - - print '
', "$moderated", '
' if(defined($moderated)); - - print $q->start_multipart_form; - print $q->hidden(-name=>'state', -default=>$part); - print $q->hidden(-name=>'list', -default=>$Q::list), "\n"; - - print '
', $q->scrolling_list(-name=>'delsubscriber', -size=>$scrollsize, -values=>\@subscribers, -multiple=>'true', -labels=>&pretty_names), '
' if defined(@subscribers); - - print '
'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'deleteaddress'}]"), '' if defined(@subscribers); - print '', $q->textfield(-name=>'addsubscriber', -size=>'40'), ' '; - print '', $q->filefield(-name=>'addfile', -size=>20, -maxlength=>100), ' ' if ($FILE_UPLOAD); - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'addaddress'}]"), ''; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'subscribers'}]"), ''; - print '
'; # end of parts_subscribers_actions - - print $q->endform; - - print '
'; # end of parts - -} - -# ------------------------------------------------------------------------ - -sub allow_create_list { - # Let the user select options for list creation ... - - my($username, $hostname, %labels, $j); - - # 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; - } - - print '
'; - - # Print a form of options ... - $q->delete_all; - - print '
'; - print '

', $LANGUAGE{'createnew'}, '

'; - print '
'; - print '
'; # end of create->title - - print $q->startform; - print $q->hidden(-name=>'state', -value=>'create'); - - print '
'; - print '', $LANGUAGE{'listname'}, ': ', $q->textfield(-name=>'list', -size=>'20'), ' '; - print '', $LANGUAGE{'listaddress'}, ': ', $q->textfield(-name=>'inlocal', -default=>$username, -size=>'10'); - print ' @ ', $q->textfield(-name=>'inhost', -default=>$hostname, -size=>'30'), ' '; - - print '', $LANGUAGE{'listoptions'}, ':'; - &display_options($DEFAULT_OPTIONS); - - # Allow creation of mysql table if the module allows it - if($Mail::Ezmlm::MYSQL_BASE) { - print '', $q->checkbox(-name=>'sql', -label=>$LANGUAGE{'mysqlcreate'}, -on=>1); - print ' '; - } - - if(-e "$WEBUSERS_FILE") { - print '', $LANGUAGE{'allowedtoedit'}, ': '; - print $q->textfield(-name=>'webusers', -value=>$ENV{'REMOTE_USER'}||'ALL', -size=>'30'); - print ' '; - print '', $HELPER{'allowedit'}, ''; - } - print '
'; # end of create->input - - print '
'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'createlist'}]"), ''; - print '', $q->reset(-value=>"[$BUTTON{'resetform'}]"), ''; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ''; - print '
'; # end of create->question - print $q->endform; - - print '
'; # end of create - -} - -# ------------------------------------------------------------------------ - -sub create_list { - # Create a list acording to user selections ... - - # Check the list directory exists and create if necessary ... - if(!-e $LIST_DIR) { - die "Unable to create directory ($LIST_DIR): $!" unless mkdir $LIST_DIR, 0700; - } - - my ($qmail, $listname, $options, $i); - - # Some taint checking ... - $qmail = $1 if $q->param('inlocal') =~ /(?:$USER-)?([^\<\>\\\/\s]+)$/; - $listname = $q->param('list'); $listname =~ s/ /_/g; # In case some git tries to put a space in the file name - - # Sanity Checks ... - return 1 if ($listname eq '' || $qmail eq ''); - if(-e ("$LIST_DIR/$listname/lock") || -e ("$HOME_DIR/.qmail-$qmail")) { - print '

', "List '$listname' already exists :(

"; - return 1; - } - - # Work out the command line options - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - my($list) = new Mail::Ezmlm; - - unless ($list->make(-dir=>"$LIST_DIR/$listname", - -qmail=>"$HOME_DIR/.qmail-$qmail", - -name=>$q->param('inlocal'), - -host=>$q->param('inhost'), - -switches=>$options, - -user=>$USER) - ) { - die 'List creation failed', $list->errmsg(); - } - - # handle MySQL stuff - if($q->param('sql') && $options =~ m/-6\s+/) { - unless($list->createsql()) { - die 'SQL table creation failed: ', $list->errmsg(); - } - } - - &update_webusers(); - - return 0; -} - -# ------------------------------------------------------------------------ - -sub list_config { - # Allow user to alter the list configuration ... - - my ($list, $listaddress, $listname, $options); - my ($headeradd, $headerremove, $mimeremove, $prefix, $j); - - # Store some variables before we delete them ... - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $listname = $q->param('list'); - $listaddress = &this_listaddress; - - # Begin of content - print '
'; - - # Print a form of options ... - $q->delete_all; - - print '
'; - print '

', $LANGUAGE{'editconfiguration'}, '

'; - print '
'; - print '
'; # end of config->title - - print $q->startform; - print $q->hidden(-name=>'state', -value=>'configuration'); - print $q->hidden(-name=>'list', -value=>$listname); - - print '
'; - print '

', $LANGUAGE{'listname'}, ": $listname

"; - print '

', "$LANGUAGE{'listaddress'}: $listaddress

"; - print '
'; # end of config->info - - print '
'; - print '

', $LANGUAGE{'listoptions'}, ':

'; - - # Print a list of options, selecting the ones that apply to this list ... - &display_options($list->getconfig); - - # Get the contents of the headeradd, headerremove, mimeremove and prefix files - $headeradd = $list->getpart('headeradd'); - $headerremove = $list->getpart('headerremove'); - $mimeremove = $list->getpart('mimeremove'); - $prefix = $list->getpart('prefix'); - - print '', $LANGUAGE{'prefix'}, ': ', $q->textfield(-name=>'prefix', -default=>$prefix, -size=>12), ' ' if defined($prefix); - print '

', $LANGUAGE{'headerremove'}, ':
', $q->textarea(-name=>'headerremove', -default=>$headerremove, -rows=>5, -columns=>70), ''; - print '', $LANGUAGE{'headeradd'}, ':
', $q->textarea(-name=>'headeradd', -default=>$headeradd, -rows=>5, -columns=>70), '

'; - print '', $LANGUAGE{'mimeremove'}, ':
', $q->textarea(-name=>'mimeremove', -default=>$mimeremove, -rows=>5, -columns=>70), '
' if defined($mimeremove); - - if(open(WEBUSER, "<$WEBUSERS_FILE")) { - my($webusers); - while() { - last if (($webusers) = m{^$listname\s*\:\s*(.+)$}); - } - close WEBUSER; - $webusers ||= $ENV{'REMOTE_USER'} || 'ALL'; - - print '', $LANGUAGE{'allowedtoedit'}, ': '; - print $q->textfield(-name=>'webusers', -value=>$webusers, -size=>'30'); - print ' ', - print '', $HELPER{'allowedit'}, ''; - - } - print '
'; # end of config->input - - print '
'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'updateconfiguration'}]"), ''; - print '', $q->reset(-value=>"[$BUTTON{'resetform'}]"), ''; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ''; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'edittexts'}]"), ''; - print '
'; # end of config->question - - print $q->endform; - - print ''; # end of config -} - -# ------------------------------------------------------------------------ - -sub update_config { - # Save the new user entered config ... - - my ($list, $options, $i, @inlocal, @inhost); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - - # Work out the command line options ... - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= $i; - } else { - $options .= uc($i); - } - } - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - if (defined($q->param($i))) { - $options .= " -$i '" . $q->param("$i-value") . "'"; - } - } - - # Actually update the list ... - unless($list->update($options)) { - die "List update failed"; - } - - # Update headeradd, headerremove, mimeremove and prefix ... - $list->setpart('headeradd', $q->param('headeradd')); - $list->setpart('headerremove', $q->param('headerremove')); - $list->setpart('mimeremove', $q->param('mimeremove')) if defined($q->param('mimeremove')); - $list->setpart('prefix', $q->param('prefix')) if defined($q->param('prefix')); - - &update_webusers(); -} - -# ------------------------------------------------------------------------ - -sub update_webusers { - # replace existing webusers-line or add a new one - - if($Q::webusers) { - # Back up web users file - open(TMP, ">/tmp/ezmlm-web.$$"); - open(WU, "<$WEBUSERS_FILE"); - while() { print TMP; } - close TMP; close WU; - - open(TMP, "$WEBUSERS_FILE"); - while() { - print WU unless (/^$Q::list\s*:/); - } - print WU "$Q::list\: $Q::webusers\n"; - close TMP; close WU; - unlink "/tmp/ezmlm-web.$$"; - } - -} - -# ------------------------------------------------------------------------ - -sub this_listaddress { - # Work out the address of this list ... Used often so put in its own subroutine ... - - my ($list, $listaddress); - $list = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - chomp($listaddress = $list->getpart('outlocal')); - $listaddress .= '@'; - chomp($listaddress .= $list->getpart('outhost')); - return $listaddress; -} - -# ------------------------------------------------------------------------ - -sub list_text { - # Show a listing of what is in DIR/text ... - - my(@files, $list); - $list = $LIST_DIR . '/' . $q->param('list'); - - # Read the list directory for text ... - opendir DIR, "$list/text" || die "Unable to read DIR/text: $!"; - @files = grep !/^\./, readdir DIR; - closedir DIR; - - # Begin of content - print '
'; - - # Print a form ... - $q->delete('state'); - print $q->startform; - print $q->hidden(-name=>'state', -default=>'list_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - - print '
'; - print $q->scrolling_list(-name=>'file', -values=>\@files); - print '
'; # end of textfiles->list - - print '
'; - print $LANGUAGE{'edittextinfo'}; - print '
'; # end of textfiles->info - - print '
'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'editfile'}]"), ''; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ''; - print '
'; # end of textfiles->question - - print $q->endform; - - print '
'; - -} - -# ------------------------------------------------------------------------ - -sub edit_text { - # Allow user to edit the contents of DIR/text ... - - my ($content); - my($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $content = $list->getpart("text/$Q::file"); - - # Begin of content - print '
'; - - # Print a form ... - $q->delete('state'); - - print '
'; - print '

', $LANGUAGE{'editingfile'}, ': ', $Q::file, '

'; - print '
'; # end of edittext->title - - print $q->startform; - print $q->hidden(-name=>'state', -default=>'edit_text'); - print $q->hidden(-name=>'list', -default=>$q->param('list')); - print $q->hidden(-name=>'file', -default=>$q->param('file')); - - print '
'; - print '', $q->textarea(-name=>'content', -default=>$content, -rows=>'25', -columns=>'72'), ''; - print '
'; # end of edittext->input - - print ''; - print $LANGUAGE{'editfileinfo'}; - print '
'; # end of edittext->info - - print '
'; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'savefile'}]"), ''; - print '', $q->reset(-value=>"[$BUTTON{'resetform'}]"), ''; - print '', $q->submit(-name=>'action', -value=>"[$BUTTON{'cancel'}]"), ''; - print '
'; # end of edittext->question - - print $q->endform; - - print ''; # end of edittext -} - -# ------------------------------------------------------------------------ - -sub save_text { - # Save new text in DIR/text ... - - my ($list) = new Mail::Ezmlm("$LIST_DIR/$Q::list"); - $list->setpart("text/$Q::file", $q->param('content')); - -} - -# ------------------------------------------------------------------------ - -sub webauth { - - # Check if webusers file exists - if not, then access is granted - return 0 if (! -e "$WEBUSERS_FILE"); - - # Read authentication level from webusers file. Format of this file is - # somewhat similar to the unix groups file - my($listname) = @_; - open (USERS, "<$WEBUSERS_FILE") || die "Unable to read webusers file ($WEBUSERS_FILE): $!"; - while() { - if (/^($listname|ALL)\:/i) { - if (/(\:\s*|,\s+)((?:$ENV{'REMOTE_USER'})|(?:ALL))\s*(,|$)/) { - close USERS; return 0; - } - } - } - close USERS; - return 1; -} - -# --------------------------------------------------------------------------- - -sub webauth_create_allowed { - - # Check if we were called with the deprecated argument "-c" (allow to create lists) - return 0 if (defined($opt_c)); - - # Check if webusers file exists - if not, then access is granted - return 0 if (! -e "$WEBUSERS_FILE"); - - # Read create-permission from webusers file. - # the special listname "ALLOW_CREATE" controls, who is allowed to do it - open (USERS, "<$WEBUSERS_FILE") || die "Unable to read webusers file ($WEBUSERS_FILE): $!"; - while() { - if (/^ALLOW_CREATE:/i) { - if (/(\:\s*|,\s+)((?:$ENV{'REMOTE_USER'})|(?:ALL))\s*(,|$)/) { - close USERS; return 0; - } - } - } - close USERS; - return 1; -} - -# --------------------------------------------------------------------------- - -sub display_options { - my($opts) = shift; - my($i, $j); - - print ""; - print '

'; - foreach $i (grep {/\D/} keys %EZMLM_LABELS) { - if ($opts =~ /^\w*$i\w*\s*/) { - print '', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print '', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print ''; - print ''; $j++; - if ($j >= 3) { - $j = 0; print '

'; - } - } - print '

'; - - foreach $i (grep {/\d/} keys %EZMLM_LABELS) { - print '

'; - if ($opts =~ /$i (?:'(.+?)')/) { - print '', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0], -on=>'1'); - } else { - print '', $q->checkbox(-name=>$i, -value=>$i, -label=>$EZMLM_LABELS{$i}[0]); - } - print ''; - print '', $q->textfield(-name=>"$i-value", -value=>$1||$EZMLM_LABELS{$i}[2], -size=>30), ''; - print '

'; - } - -} - -# --------------------------------------------------------------------------- - -sub ezmlmcgirc { - my($listno); - if(open(WWW, "<$EZMLM_CGI_RC")) { - while() { - last if (($listno) = m{(\d+)(\D)\d+\2$LIST_DIR/$Q::list\2}); - } - close WWW; - return "$EZMLM_CGI_URL/$listno" if(defined($listno)); - } return undef; - -} - -# --------------------------------------------------------------------------- - -sub pretty_names { - return undef unless($PRETTY_NAMES); - my (%pretty, %prettymem); - tie %pretty, "DB_File", "$LIST_DIR/$Q::list/webnames"; - %prettymem = %pretty; - untie %pretty; - - return \%prettymem; -} - -# ------------------------------------------------------------------------- -sub rmtree { - # A subroutine to recursively delete a directory (like rm -f). - # Based on the one in the perl cookbook :) - - use File::Find qw(finddepth); - File::Find::finddepth sub { - # assume that File::Find::name is secure since it only uses data we pass it - my($name) = $File::Find::name =~ m{^(.+)$}; - - if (!-l && -d _) { - rmdir($name) or warn "couldn't rmdir $name: $!"; - } else { - unlink($name) or warn "couldn't unlink $name: $!"; - } - }, @_; - 1; -} - -# ------------------------------------------------------------------------ - -BEGIN { - sub handle_errors { - my $msg = shift; - print << "EOM"; -
-

A fatal error has occoured

-

Something you did caused this script to bail out. The error - message we got was

-

$msg

-

Please try what you were doing again, checking everything you entered.
- If you still find yourself getting this error, please - contact the site administrator - quoting the error message above.

- -EOM - - } - set_message(\&handle_errors); -} - -# ------------------------------------------------------------------------ -# End of ezmlm-web.cgi v2.2 -# ------------------------------------------------------------------------ -__END__ - -=head1 NAME - -ezmlm-web - A web configuration interface to ezmlm mailing lists - -=head1 SYNOPSIS - -ezmlm-web [B<-c>] [B<-C> EFE] [B<-d> EFE] - -=head1 DESCRIPTION - -=over 4 - -=item B<-C> Specify an alternate configuration file given as F -If not specified, ezmlm-web checks first in the users home directory, then in -F and then the current directory - -=item B<-d> Specify an alternate directory where lists live. This is now -depreciated in favour of using a custom ezmlmwebrc, but is left for backward -compatibility. - -=back - -=head1 SUID WRAPPER - -C<#include stdio.h> - -C - C - C -C<}> - - -=head1 DOCUMENTATION/CONFIGURATION - - Please refer to the example ezmlmwebrc which is well commented, and - to the README file in this distribution. - -=head1 FILES - -F<~/.ezmlmwebrc> -F -F<./ezmlmwebrc> - -=head1 AUTHOR - - Guy Antony Halse - -=head1 BUGS - - None known yet. Please report bugs to the author. - -=head1 S - - ezmlm(5), ezmlm-cgi(1), Mail::Ezmlm(3) - - https://systemausfall.org/toolforge/ezmlm-web - http://rucus.ru.ac.za/~guy/ezmlm/ - http://www.ezmlm.org/ - http://www.qmail.org/ diff --git a/ezmlm-web/trunk/ezmlmwebrc b/ezmlm-web/trunk/ezmlmwebrc deleted file mode 100644 index c1c5113..0000000 --- a/ezmlm-web/trunk/ezmlmwebrc +++ /dev/null @@ -1,80 +0,0 @@ -# $Id: ezmlmwebrc,v 1.5 2000/09/25 18:25:26 guy Exp $ -# Configuration file for ezmlm-web 2.2 -# =========================================================================== - -# This file is not just an ordinary configuration file - it contains valid -# perl statements that are executed just like any other perl script. When -# editing this file, be careful that it is still valid perl when you have -# finished (perl -w ezmlmwebrc ;-) - -# --------------------------------------------------------------------------- - -# Where do we store lists on this server ... Try "$HOME_DIR/lists". -# This directory will automatically be created if needed. -$LIST_DIR = "$HOME_DIR/lists"; - -# Where is the webusers file for access-permissions -# defaults to "$LIST_DIR/webusers" -$WEBUSERS_FILE = "$LIST_DIR/webusers"; - -# Safe list deletion? -# 0 = move list to .list and the .qmails to deleted.qmail/. Recoverable :) -# 1 = allow user to delete list completely. No backup, therefore no recovery. -$UNSAFE_RM = 0; - -# Who is the alias user on this system (usually alias ;) -$ALIAS_USER = 'alias'; - -# Where do the qmail control files live on this system ... -$QMAIL_BASE = $Mail::Ezmlm::QMAIL_BASE . '/control'; - -# The url to our web interface - so we can use ezmlm-cgi if necessary -$EZMLM_CGI_URL = 'http://some.server.that.has/cgi-bin/ezmlm-cgi'; - -# Where our ezcgirc file lives (probably /etc/ezmlm/ezcgirc) -$EZMLM_CGI_RC = '/etc/ezmlm/ezcgirc'; - -# Do we want to allow ``pretty'' names - ie more human readable ones -# This will slow ezmlm-web down a bit for large lists -$PRETTY_NAMES = 1; - -# Do we want to allow the users to be allowed to upload a file containing -# lists of email addresses to subscribe? -$FILE_UPLOAD = 1; - -# What switches to we want ezmlm-web to have on as default. The ezmlm-make -# defaults are aBDFGHIJKLMNOpQRSTUWX (small means enabled, CAPITALS mean -# disabled). The defaults below should be reasonable - I use them ;) -$DEFAULT_OPTIONS = 'aBDFGHiJkLMNOpQRSTUWx'; - -# Where do we find the nice little help icon - by default HELP_ICON_URL -# points to resources on http://rucus.ru.ac.za/. This will work, but we -# would appreciate it if you changed this to a local site. -$HELP_ICON_URL = 'http://rucus.ru.ac.za/icons/small/unknown.gif'; - -# Header for every page (.= concatinates) -$HTML_HEADER = '
E Z Mailing List Manager

'; -$HTML_HEADER .= '
'; - -# Footer for every page (.= concatinates) -$HTML_FOOTER = '
'; -$HTML_FOOTER .= '
'; -$HTML_FOOTER .= 'ezmlm-web (v2.2) A web interface to ezmlm
'; - -# NEW: -# html properties (e.g. color, background-color) can be defined in a -# stylesheet (see HTML_CSS_FILE) since version 2.3 - -# What is the title of this document? -$HTML_TITLE = 'E Z Mailing List Manager'; - -# Optional: use a cascading style sheet (css) -$HTML_CSS_FILE = "css/default.css"; - -# choose a language (en|de) -$HTML_LANGUAGE = 'en'; - -# --------------------------------------------------------------------------- -# include language-specific definitions -require('./lang/' . $HTML_LANGUAGE . '.pm'); - diff --git a/ezmlm-web/trunk/htaccess.sample b/ezmlm-web/trunk/htaccess.sample deleted file mode 100644 index b381a14..0000000 --- a/ezmlm-web/trunk/htaccess.sample +++ /dev/null @@ -1,9 +0,0 @@ -#$Id: htaccess.sample,v 1.1 2000/01/29 11:35:40 guy Exp $ -# -#order deny,allow -#deny from all -#allow from .ru.ac.za -AuthName "EZ Mailing List Manager -AuthType Basic -AuthUserFile /etc/ezmlm/.htusers -require valid-user diff --git a/ezmlm-web/trunk/index.c b/ezmlm-web/trunk/index.c deleted file mode 100644 index 3ba9cc1..0000000 --- a/ezmlm-web/trunk/index.c +++ /dev/null @@ -1,25 +0,0 @@ -/* $Id: index.c,v 1.2 2000/09/25 18:14:12 guy Exp $ */ - -#include - -/* C wrapper to allow ezmlm-web.cgi to run suid */ -/* Copyright (C) 1999/2000, Guy Antony Halse, All Rights Reserved */ -/* See the README file in this distribution for copyright information */ - -int main(void) { - /* Change this path to wherever you decided to put ezmlm-web.cgi */ - execv("/usr/local/bin/ezmlm-web.cgi"); - - /* Note that you could also use the following to allow a specific user - to store their mailing lists in a different directory defined by - /tmp/ezmlm-web-demo ... This over-rides the default . */ - - /* Look at the exec(3) man page if you don't understand how the arguments - list below works */ - - /* - char *switches[] = { "ezmlm-web.cgi", "-d", "/tmp/ezmlm-web-demo", NULL }; - execv("/usr/local/bin/ezmlm-web.cgi", switches); - */ - -} diff --git a/ezmlm-web/trunk/lang/de.pm b/ezmlm-web/trunk/lang/de.pm deleted file mode 100644 index ddcd8c3..0000000 --- a/ezmlm-web/trunk/lang/de.pm +++ /dev/null @@ -1,187 +0,0 @@ -# language-specific definitions for ezmlm-web -# in english - -# The meanings of the various ezmlm-make command line switches. The default -# ones match the ezmlm-idx 0.4 default ezmlmrc ... Alter them to suit your -# own ezmlmrc. Removing options from this list makes them unavailable -# through ezmlm-web - this could be useful for things like -w - -%EZMLM_LABELS = ( -# option => ['Short Name', -# 'Long Help Description'], - - a => ['archivieren', - 'Ezmlm wird neue Nachrichten zum Archiv hinzufuegen'], - b => ['Archiv nur fuer ModeratorInnen', - 'Nur ModeratorInnen haben Zugriff zum Archiv'], -# c => config. This is implicity called, so is not defined here - d => ['Zusammenfassungen', - 'Erstelle eine Mailing-Liste, an die regelmaessige Zusammenfassungen versandt werden'], -# e => edit. Also implicity called, so not defined here - f => ['Listenname als Praefix in Betreff einfuegen', - 'In die versandten Mails wird in der Betreff-Zeile ein Praefix eingefuegt'], - g => ['Archiv nur fuer Mitglieder', - 'Nur TeilnehmerInnen der Liste erhalten Zugriff zum Archiv'], - h => ['einschreiben ohne Bestaetigung', - 'Das Abonnieren der Liste erfordert keine Bestaetigung durch die neue AbonnentIn'], - i => ['Web-Index erstellen', - 'Den Zugriff auf das Archiv per Webinterface erlauben'], - j => ['abmelden ohne Bestaetigung', - 'Das Abbestellen der Liste erfordert keine Bestaetigung durch die ehemalige AbonnentIn'], - k => ['Beachte Ausschlussliste', - 'Einsendungen von Abonnenten, die inm deny-Verzeichnis enthalten sind, werden abgelehnt'], - l => ['Abonnenten-Auflistung fuer AdministratorInnen', - 'Die AdministratorInnen koennen eine Liste aller AbonnentInnen anfordern'], - m => ['Moderation aktivieren', - 'Alle eingehenden Nachrichten muessen durch eine ModeratorIn bestaetigt werden'], - n => ['Anpassung der Textbausteine erlauben', - 'Administratoren duerfen die Standard-Textbausteine per Mail veraendern'], - o => ['Nur ModeratorInnen duerfen einsenden', - 'Nur eingehende Nachrichten von den ModeratorInnen werden akzeptiert'], - p => ['oeffentlich', - 'Die oeffentliche Einschreibung und Archiv-Anforderung ist erlaubt'], - q => ['Verarbeite Anforderungen', - 'Mails an liste-request@domain werden verarbeitet'], - r => ['Administration per Mail erlauben', - 'Die Verwaltung der Liste durch Mails der AdministratorInnen ist erlaubt'], - s => ['Einschreibung durch ModeratorIn bestaetigen', - 'Die Einschreibungen in die Liste und die Zusammenfassungs-Liste werden moderiert'], - t => ['Infotext an Mails anhaengen', - 'An alle ausgehenden Mails wird ein Anhang angefuegt (siehe Datei "text/trailer")'], - u => ['Nur Abonnenten duerfen einsenden', - 'Einsendungen von nicht-eingeschriebenen Mail-Adressen werden abgewiesen'], -# v => version. I doubt you will really need this ;-) - w => ['Warnung deaktivieren', - 'Entferne den Aufruf von ezmlm-warn aus der Listen-Konfiguration - es wird angenommen, dass ezmlm-warn auf einem anderem Wege gestartet wird'], - x => ['Filtere Anhaenge und Kopfzeilen', - 'Mails mit den angegebenen Anhangs-Typen werden abgewiesen - die angegebenen Kopfzeilen werden aus den ausgehenden Mails entfernt'], -# y => not used -# z => not used - -# These all take an extra argument, which is the default value to use - - 0 => ['Unterlisten', - 'Diese Liste soll eine Unterliste einer anderen Hauptliste sein', - 'hauptliste@domain'], -# 1 => not used -# 2 => not used - 3 => ['Absender', - 'Ersetze den Absender der ausgehenden Mails durch diese Adresse', - 'Absender'], - 4 => ['Zusammenfassungseinstellungen', - 'Einstellungen for ezmlm-tstdig (nach "t" Stunden oder "m" Nachrichten oder "k" Kilobyte', - '-t24 -m30 -k64'], - 5 => ['Adresse des Verantwortlichen der Liste', - 'Mail-Adresse des Listen-Eigentuemers', - 'name@domain.org'], - 6 => ['SQL-Datenbank', - 'SQL-Datenbank-Zugangsinformationen (erfordert SQL-Unterstuetzung)', - 'host:port:user:password:datab:table'], - 7 => ['Listen-Moderations-Verzeichnis', - 'alternatives Verzeichnis zur Moderationsdatenbank', - '/absoluter/pfad/zur/moderations/datenbank'], - 8 => ['Einschreibungs-Moderations-Verzeichnis', - 'alternatives Verzeichnis zur Einschreibungs-Moderationsdatenbank', - '/absoluter/pfad/zur/abonnenten/moderations/datenbank'], - 9 => ['Administrations-Verzeichnis', - 'alternatives Verzeichnis zur Administrationsdatenbank', - '/absoluter/pfad/zur/administrations/datenbank'], - -); - -# This list defines most of the context sensitive help in ezmlm-web. What -# isn't defined here is the options, which are defined above ... You can -# alter these if you feel something else would make more sense to your users -# Just be careful of what can fit on a screen! - -%HELPER = ( - - # These should be self explainitory - addaddress => 'Eine Mail-Adresse - auch in der Form \'Max Meier \'', - addaddressfile => 'alternativ ist auch eine Datei mit je einer Adresse pro Zeile moeglich', - moderator => 'ModeratorInnen kontrollen, welche Mails weitegeleitet und welche AbonnentInnen akzeptiert werden', - deny => 'Ausschluss: die Mail-Adressen, die NIE an die Liste schreiben duerfen', - allow => 'Zulassung: die Mail-Adressen, die immer an die Liste schreiben duerfen', - digest => 'Zusammenfassung: diese Leute werden regelaessge Zusammenfassungen der Mailingliste erhalten', - webarch => 'Gehe zum Web-Archiv der Mailingliste', - config => 'Einstellungen zur Mailingliste', - listname => 'Dies ist der eindeutige Name der Mailingliste', - listadd => 'Die Adresse der Mailingliste - nur der lokale Teil kann geaendert werden', - webusers => 'unfertig: derzeit koennen Listen-Administratoren nur manuell festgelegt werden', - prefix => 'Praefix der Betreffzeile', - headerremove => 'Diese Kopfzeilen werden aus den ausgehenden Mails entfernt', - headeradd => 'Diese Kopfzeilen werden zu jeder ausgehenden Mail hinzugefuegt', - mimeremove => 'Alle Mails, die die genannten Anhangs-Typen beinhalten, werden abgewiesen', - allowedit => 'Komma-getrennte Liste von (existierenden) Nutzern oder ALL', - mysqlcreate => 'Anlegen der konfigurierten MySQL-Datenbank' - -); - -# This defines the captions of each of the buttons in ezmlm-web, and allows -# you to configure them for your own language or taste. Since these are used -# by the switching algorithm it is important that every button has a unique -# caption - ie we can't have two 'Edit' buttons doing different things. - -%BUTTON = ( - - # These MUST all be unique! - create => 'Anlegen', - createlist => 'Liste anlegen', - edit => 'Bearbeiten', - delete => 'Entfernen', - deleteaddress => 'Entferne Adresse', - addaddress => 'Fuege Adresse hinzu', - moderators => 'ModeratorInnen', - denylist => 'Ausschlussliste', - allowlist => 'Zulassungsliste', - digestsubscribers => 'Abonnenten der Zusammenfassungen', - configuration => 'Konfiguration', - yes => 'Ja', - no => 'Nein', - updateconfiguration => 'Speichere Konfiguration', - edittexts => 'Bearbeite Texte', - editfile => 'Bearbeite Datei', - savefile => 'Speichere Datei', - webarchive => 'Web-Archiv', - selectlist => 'Listenauswahl', - subscribers => 'AbonnentInnen', - cancel => 'Abbruch', - resetform => 'Reset', - -); - -# This defines the fixed text strings that are used in ezmlm-web. By editing -# these along with the button labels and help texts, you can convert ezmlm-web -# to another language :-) If anyone gets arround to doing complete templates -# for other languages I would appreciate a copy so that I can include it in -# future releases of ezmlm-web. - -%LANGUAGE = ( - nop => 'Diese Funktionalitaet ist noch nicht umgesetzt worden', - chooselistinfo => "

  • Markiere eine Liste in der Auswahlbox oder klicke auf [$BUTTON{'create'}].
  • Klicke auf den [$BUTTON{'edit'}]-Schalter, falls du die markierte Liste bearbeiten moechtest.
  • Klicke auf den [$BUTTON{'delete'}]-Schalter, falls du die markierte Liste loeschen moechtest.
", - confirmdelete => 'Bestaetige die Loeschung von ', # list name - subscribersto => 'Abonnenten von', # list name - subscribers => 'Abonnenten', - additionalparts => 'Weitere Optionen', - posting => 'Einsendungen', - subscription => 'Einschreibung', - remoteadmin => 'Entfernte AdministratorIn', - for => 'fuer', # as in; moderators for blahlist - createnew => 'Lege eine neue Liste an', - listname => 'Name der Liste', - listaddress => 'Adresse der Liste', - listoptions => 'Einstellungen der Liste', - allowedtoedit => 'Nutzer, die diese Liste bearbeiten duerfen', - editconfiguration => 'Einstellungen aendern', - prefix => 'Praefix der Betreff-Zeile ausgehender Nachrichten', - headerremove => 'zu entfernende Kopfzeilen', - headeradd => 'einzufuegende Kopfzeilen', - mimeremove => 'abzuweisende Anhangs-Typen', - edittextinfo => "Das Auswahlfeld links enthaelt die Dateien des
Verzeichnisses DIR/text/. Diese Dateien werden als Antwort auf spezifische Nutzer-Anfragen oder als Teil aller ausgehenden Nachrichten versandt.

Um diese Dateien zu veraendern, waehle ihren Namen im Auswahlfeld an. Anschliessend klicke auf den [$BUTTON{'editfile'}] Schalter.

BetäAege [$BUTTON{'cancel'}] um die Veraenderung zu beenden.", - editingfile => 'Bearbeite Datei', - editfileinfo => 'ezmlm-manage
<#l#> Der Name der Liste
<#A#> Die Anmeldungs-Adresse
<#R#> Die Bestaetigungs-Adresse

ezmlm-store
<#l#> Der Name der Liste
<#A#> Die Zusage-Adresse
<#R#> Die Ablehungs-Adresse', - mysqlcreate => 'Lege die MySQL-Datenbank an, falls erforderlich', - -); - -# === Configuration file ends === diff --git a/ezmlm-web/trunk/lang/en.pm b/ezmlm-web/trunk/lang/en.pm deleted file mode 100644 index 25bd2b1..0000000 --- a/ezmlm-web/trunk/lang/en.pm +++ /dev/null @@ -1,187 +0,0 @@ -# language-specific definitions for ezmlm-web -# in english - -# The meanings of the various ezmlm-make command line switches. The default -# ones match the ezmlm-idx 0.4 default ezmlmrc ... Alter them to suit your -# own ezmlmrc. Removing options from this list makes them unavailable -# through ezmlm-web - this could be useful for things like -w - -%EZMLM_LABELS = ( -# option => ['Short Name', -# 'Long Help Description'], - - a => ['Archived', - 'Ezmlm will archive new messages'], - b => ['Block archive', - 'Only moderators are allowed to access the archive'], -# c => config. This is implicity called, so is not defined here - d => ['Digest', - 'Set up a digest list to disseminate digest of the list messages'], -# e => edit. Also implicity called, so not defined here - f => ['Prefix', - 'Outgoing subject will be prefixed with the list name'], - g => ['Guard Archive', - 'Archive access requests from unrecognized SENDERs will be rejected'], - h => ['Help subscription', - 'Subscriptions do not require confirmation'], - i => ['Indexed', - 'Indexed for WWW archive access'], - j => ['Jump off', - 'Unsubscribe does not require confirmation'], - k => ['Kill', - 'Posts from addresses in dir/deny/ are rejected'], - l => ['Subscriber List', - 'Remote administrators can request a subscriber list'], - m => ['Message Moderation', - 'All incoming messages are moderated'], - n => ['Text Editing', - 'Allow remote administrators to edit files in dir/text/'], - o => ['Others rejected', - 'Posts from addresses other than moderators are rejected'], - p => ['Public', - 'List will respond to administrative requests and archive retrieval'], - q => ['Service Request Address', - 'Process commands sent in the subject to local-request@host'], - r => ['Remote Admin', - 'Enable remote adminstration of the list'], - s => ['Subscription Moderation', - 'Subscriptions to the main list and digest will be moderated'], - t => ['Trailer', - 'Add a trailer to outgoing messages'], - u => ['User Posts Only', - 'Posts from unrecognized SENDER addresses will be rejected'], -# v => version. I doubt you will really need this ;-) - w => ['Remove Warn', - 'Remove the ezmlm-warn(1) invocations from the list setup. It is assumed that ezmlm-warn(1) is run by other means'], - x => ['Extra', - 'Strip certain mimetypes, etc'], -# y => not used -# z => not used - -# These all take an extra argument, which is the default value to use - - 0 => ['Sublist', - 'Make the list a sublist of list mainlist@host', - 'mainlist@host'], -# 1 => not used -# 2 => not used - 3 => ['From Address', - 'Replace the "From:" header of the message with "From: fromarg"', - 'fromarg'], - 4 => ['Digest Options', - 'Switches for ezmlm-tstdig(1)', - '-t24 -m30 -k64'], - 5 => ['List Owner', - 'The email address of the list owner', - ''], - 6 => ['SQL Database', - 'SQL database connect information. Requires SQL support', - 'host:port:user:password:datab:table'], - 7 => ['Message Moderation Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'], - 8 => ['Subscription Moderation Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'], - 9 => ['Remote Admin Path', - 'Make /path the path to the database for message moderators, if the list is set up for message moderation', - '/some/full/path'] - -); - -# This list defines most of the context sensitive help in ezmlm-web. What -# isn't defined here is the options, which are defined above ... You can -# alter these if you feel something else would make more sense to your users -# Just be careful of what can fit on a screen! - -%HELPER = ( - - # These should be self explainitory - addaddress => 'You may enter any RFC822 compliant email address here, including the comment part. For example; J Random User ', - addaddressfile => 'or you may enter the filename of a plain text file containing multiple RFC822 email addresses, one per line', - moderator => 'Moderators: people who control who may subscribe or post to a list', - deny => 'Deny: A list of addresses that are _never_ allowed to mail the list', - allow => 'Allow: A list of address that are allowed to mail the list even if the configuration otherwise restricts it', - digest => 'Digest: People who will recieve a digest of all messages on the list', - webarch => 'View the web based archive of this list', - config => 'This lets you alter the way the list is set up', - listname => 'This is the name of the list as displayed on the Select Lists screen. It is also the name of the subdirectory that contains the list', - listadd => 'This is the email address of the list. Note that the defaults come from your qmail config. You should just update the local part (before the @)', - webusers => 'NB! At this stage, any users specified here must exist. User creation may be added in future versions', - prefix => 'Text to add to the subject line of all outgoing messages', - headerremove => 'This is a list of headers to remove from all outgoing mail', - headeradd => 'This is a list of headers to add to all outging mail', - mimeremove => 'All messages whose Content-Type matches these mime types will be bounced back to sender', - allowedit => 'Comma separated list of usernames, or ALL (all valid users)', - mysqlcreate => 'This will create the necessary MySQL tables if the list configuration above requires it' - -); - -# This defines the captions of each of the buttons in ezmlm-web, and allows -# you to configure them for your own language or taste. Since these are used -# by the switching algorithm it is important that every button has a unique -# caption - ie we can't have two 'Edit' buttons doing different things. - -%BUTTON = ( - - # These MUST all be unique! - create => 'Create', - createlist => 'Create List', - edit => 'Edit', - delete => 'Delete', - deleteaddress => 'Delete Address', - addaddress => 'Add Address', - moderators => 'Moderators', - denylist => 'Deny List', - allowlist => 'Allow List', - digestsubscribers => 'Digest Subscribers', - configuration => 'Configuration', - yes => 'Yes', - no => 'No', - updateconfiguration => 'Update Configuration', - edittexts => 'Edit Texts', - editfile => 'Edit File', - savefile => 'Save File', - webarchive => 'Web Archive', - selectlist => 'Select List', - subscribers => 'Subscribers', - cancel => 'Cancel', - resetform => 'Reset Form', - -); - -# This defines the fixed text strings that are used in ezmlm-web. By editing -# these along with the button labels and help texts, you can convert ezmlm-web -# to another language :-) If anyone gets arround to doing complete templates -# for other languages I would appreciate a copy so that I can include it in -# future releases of ezmlm-web. - -%LANGUAGE = ( - nop => 'Action not yet implemented', - chooselistinfo => "

  • Choose a mailing list from the selection box or click on [$BUTTON{'create'}].
  • Click on the [$BUTTON{'edit'}] button if you want to edit the selected list.
  • Click on the [$BUTTON{'delete'}] button if you want to delete the selected list.
", - confirmdelete => 'Confirm deletion of', # list name - subscribersto => 'Subscribers to', # list name - subscribers => 'subscribers', - additionalparts => 'Additional list parts', - posting => 'Posting', - subscription => 'Subscription', - remoteadmin => 'Remote Admin', - for => 'for', # as in; moderators for blahlist - createnew => 'Create a New List', - listname => 'List Name', - listaddress => 'List Address', - listoptions => 'List Options', - allowedtoedit => 'Users allowed to edit this list', - editconfiguration => 'Edit the List Configuration', - prefix => 'Subject prefex for outgoing messages', - headerremove => 'Headers to strip from all outgoing mail', - headeradd => 'Headers to add to all outgoing mail', - mimeremove => 'Mime types to strip from all outgoing mail', - edittextinfo => "The box on the left contains a list of files available in the
DIR/text directory. These files are sent out in response to specfic user request, or as part of all outgoing messages

To edit a file, select its name from the box. Then click on the [$BUTTON{'editfile'}] button.

Press [$BUTTON{'cancel'}] when you have finished editing.", - editingfile => 'Editing File', - editfileinfo => 'ezmlm-manage
<#l#> The list name
<#A#> The subscription address
<#R#> The address a subscriber must reply to

ezmlm-store
<#l#> The list name
<#A#> The acceptance address
<#R#> The rejection address', - mysqlcreate => 'Create the MySQL database tables if necessary', - -); - -# === Configuration file ends === diff --git a/ezmlm-web/trunk/webusers.sample b/ezmlm-web/trunk/webusers.sample deleted file mode 100644 index b89278f..0000000 --- a/ezmlm-web/trunk/webusers.sample +++ /dev/null @@ -1,5 +0,0 @@ -comm: guy, arb -users: arb -members: ALL -ALL: root -ALLOW_CREATE: root, guy diff --git a/ezmlm-web/website/ezmlm-web.css b/ezmlm-web/website/ezmlm-web.css deleted file mode 100644 index 649c520..0000000 --- a/ezmlm-web/website/ezmlm-web.css +++ /dev/null @@ -1,186 +0,0 @@ -body { - margin: 0; - padding: 0; - font: normal 100% sans-serif; - color: #606760; - } - -font.ez { - font-style: italic; - color: #505050; - } - -font.hint { - font-size: 85%; - } - -font.feature { - #font-size: 110%; - font-weight: bold; - } - -#nav-bar { - float: left; - width: 14%; - margin: 0.5%; - padding-bottom: 1%; - background-color: #c0c0b0; -} - -.nav-group { - margin-top: 1%; - padding-bottom: 1%; - } - -#nav-bar ul { - list-style: square; - color: #af8060; - margin: 0; - padding-left: 20px; - } - -#nav-bar li { - margin-top: 0; - border-bottom: solid 1px #606070; - } - -#nav-bar a { - font: bold 85% sans-serif; - color: #2f4860; - text-decoration: none; - } - -#nav-bar a:hover { - background-color: #d8d8d8; - color: #2f4860; - } - -#news { - background: #e8947c; - color: #000000; - margin: 1%; - padding: 5px; - width: 30%; - float: right; - font-size: 80%; - } - -#news font.title { - font-style: italic; - font-size: 110%; - } - -#news ul.changes { - font-size: 90%; - margin-top: 0px; - } - -a:visited { - color: #005040; - } - -#oben { - background-color: #2f4860; - } - -h1.oben { - text-align: left; - border-bottom: solid 2px #ffffff; - padding: 5px; - font-weight: bold; - letter-spacing: -1px; - color: #ffffff; - margin: 0; - } - -#perm-nav { - float: right; - padding-right: 5px; - font-size: 100%; - color: #006760; - background-color: inherit; - } - -#perm-nav a { - font-weight: bold; - color: #ffffff; - padding-left: 2px; - padding-right: 2px; - text-decoration: none; - } - -#perm-nav a:hover { - color: #ffcc00; - } - - -.lid { - margin: 0; - padding: 3px; - padding-left: 10px; - border-bottom: solid 1px #606070; - background-color: #c0c0b0; - font: bold 100% sans-serif; - letter-spacing: -1px; - color: #ffffff; - } - -#content { -# position: absolute; -# right: 0px; -# width: 85%; - font: normal 82% sans-serif; - background-color: #ffffff; - padding: 2px; - } - -#content h2 { - margin: 5px; - margin-top: 10px; - margin-left: 0; - font-weight: normal; - letter-spacing: -1px; - color: #2f4860; - } - -.push { - margin: 5px; - padding: 0; - } - -.push p { - text-align: justify; - } - -#info-title { - text-align: center; - background-color: #c0c0b0; - margin: 0.5%; - color: #ffffff; - font-size: 105%; - #font-weight: bold; - } - -#header { - text-align: right; - background-color: #2f4860; - font-size: 90%; - color: #ffffff; - margin: 0; - } - -#footer { - text-align: right; - background-color: #2f4860; - font-size: 90%; - color: #ffffff; - margin: 0; - } -#footer a:visited { - color: #a0d0b0; - } - -.mail { - font-style: italic; - color: #2f4860; - } diff --git a/ezmlm-web/website/index.html b/ezmlm-web/website/index.html deleted file mode 100644 index 273ecf0..0000000 --- a/ezmlm-web/website/index.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - - - - ezmlm-web - administration interface for ezmlm - - - - - -

- -
- -

ezmlm-web

-
- - - - -
a web interface for mailing lists' administration
- -
- -
- -02005/01/26 - ezmlm-web Version 2.2 released -
    -
  • german translation
  • -
  • security fixes
  • -
  • create-permissions per user
  • -
- -02005/01/24 - the work of Guy Antony Halse will be continued ... here - -
- -
-

Overview

- -

ezmlm-web is a web interface for the administration of ezmlm mailing lists. It allows complete control over their configuration by using a web browser. User-based access control relieves administrators from the burden of managing all their mailing lists on their own.

-
- -
-

History

-

The original author of ezmlm-web is Guy Antony Halse. He maintained it up to -version 2.1. By then it was functionally complete and convenient.

-

Since September 02000 no new releases were published.

-

In January 02005 Guy allowed me to continue the project. I will try to incorporate the suggestions -that were sent to Guy so far. Additional security improvements and translations will be integrated.

-

Your suggestions are welcome and will improve ezmlm-web whenever possible.

-
- - -
-

How can ezmlm-web help you?

-

ezmlm uses a mainly -command line interface for the creation and maintainence -of mailing lists. While this is very convenient for the average systems -administrator who is used to such interfaces, it restrains him from transferring -administrative work to users who want to manage a community on their own.

- -

ezmlm-web is an attempt to hide the complexities of managing a mailing list -behind and intuative, easy to use web based interface. The idea behind this -is threefold. Firstly just about everyone these days can use a web browser, -or can learn very quickly. Secondly it provides almost complete platform -independence on the client side - there are GUI web browsers available for -every major modern operating system. Thirdly, and perhaps more importantly, -it makes easy remote administration a real possibility.

- -

ezmlm-web allows the user to easily add and remove -mailing list subscribers, create and delete mailing lists as well as alter -the configuration of existing mailing lists. Almost every aspect of the -mailing list is controlable through the web front end, allowing the list -user to do most things without the assistance of the systems administrators.

-
- - -
-

Features

-Some of the important features that ezmlm-web offers are; -
    -
  • Full Virtual Host Support -- ezmlm-web hides the complexities of setting up virtually hosted mailing lists from your users.
  • - -
  • Multi-Level Access -- You can control who has access to different mailing lists.
  • - -
  • Name Association -- You can enter any RFC 822 email address, and it will display the nice name while refering to the email address.
  • - -
  • Configurable Interface -- Most of the "look & feel" of ezmlm-web is configured through templates, allowing you to easily co-ordinate it with your existing website.
  • - -
  • Language Independence -- ezmlm-web can be easily reconfigured for different locales and languages. For now you can only choose between english and german - your contribution for other languages is welcome.
  • - -
  • Context Sensitive Help -- Context sensitive help is provided throughout ezmlm-web in the form of image TITLE tags, which serve as tooltips.
  • - -
  • Full support for all command line options -- ezmlm-web has been updated to take advantage of all the command line features of ezmlm-idx 0.40. And should be compatible with any further releases :-)
  • - -
  • Browser Independence -- ezmlm-web has been tested with Mozilla 1.73, Firefox 1.0, Netscape Navigator 4.7, Lynx 2.8.3, w3m 0.1.11-pre and Internet Explorer 5.0
  • - -
  • Platform Independence -- ezmlm-web should run on any platform that can run ezmlm and Perl
  • - -
  • Multiple Subscribes/Unsubscribes -- ezmlm-web supports file uploads for bulk subscription of email addresses, and multiple selects for bulk deletes.
  • - -
-
- - -
-

Requirements

-

A full list of requirements is available in the README -file in the distribution.

- -

Basically, however, you require the following on your -system:

- -
- -
-

How you can contribute

-

You can help to improve ezmlm-web in many ways. Some of them are:

-
    -
  • translate it to another language (this takes about an hour) - for now english and german are available
  • -
  • create a nice stylesheet to improve its appearance
  • -
  • send me patches you would like to see incorporated
  • -
  • tell me if you find evidences of my poor english tongue on this page
  • -
-

If you are interested in the development code of ezmlm-web, then you may -anonymously checkout the subversion repository at - -https://svn.systemausfall.org/svn/admin-tools/ezmlm-web.

-
- -
-

Some final words ...

-

As I am no native english speaker, I will gladly accept every hint to improve the appearance of this website.

-

Nearly every line of ezmlm-web was written by Guy Antony Halse - thanks a lot for this work!

-

If you have any suggestions regarding ezmlm-web, please send a mail to ezmlm-web[AT]sumpfralle.de.

-
- -
- - - - -
- - - diff --git a/web-splash/BUILDING b/web-splash/BUILDING deleted file mode 100644 index 528608a..0000000 --- a/web-splash/BUILDING +++ /dev/null @@ -1,31 +0,0 @@ -1. creating the ipkg package - -1.1 install ipkg-utils - -- get it: ftp://ftp.handhelds.org/packages/ipkg-utils/ -- unpack it -- make -- make install - -Strangely the script ipkg-buildpackage does not get installed. You have to copy it manually -to /usr/local/bin/. - -There is a problem with the choice of the archiver: -- tar -- ar -ipkg-build (which is called by ipkg-buildpackage) uses "ar" by default, but most busybox -installations do not include this archiver. -To change the default archiver for ipkg-build you could pass the option "-c" to it. -As it is called by ipkg-buildpackage you have to change this by hand: -- look for a line that starts with "ipkg-build " near to the end of ipkg-buildpackage -- insert "-c" after "ipkg-build" - - -1.2 create control files for the package -for detailed instructions see "http://handhelds.org/moin/moin.cgi/BuildingIpkgs" -(note: the directory "CONTROL" can be "ipkg" too) - - -1.3 package the software -fakeroot SOURCE_DIR ipkg-buildpackage - diff --git a/web-splash/CHANGELOG b/web-splash/CHANGELOG deleted file mode 100644 index 0bbc0e7..0000000 --- a/web-splash/CHANGELOG +++ /dev/null @@ -1,13 +0,0 @@ -Version 0.2.1 - * traffic counter added - --- 18. May 02005 - Lars Kruse --- - -Version 0.2 - * counter for returned packets added - * enhanced installation and removal - * DEBUG mode - --- 18. May 02005 - Lars Kruse --- - -Version 0.1 - * basic functionality provided - --- 17. May 02005 - Lars Kruse --- diff --git a/web-splash/README b/web-splash/README deleted file mode 100644 index 2402f6c..0000000 --- a/web-splash/README +++ /dev/null @@ -1,118 +0,0 @@ -1. Licence -These shell scripts are licenced under the GPL Version 2.0 -(or higher at your option). Details can be found in the file -COPYING or at http://www.fsf.org/licensing/licenses/gpl.html. - - -2. Overview -web-splash manipulates some iptables rules to redirect the -first web access of a client to a page you choose. This can -be used for open wireless networks that want to inform -anonymous users about the policy of the net. -Further http (and other) requests will be forwarded. You may -also restrict access to some services, if you want. - -web-splash does also give you information about the traffic -consumption of every user. This can be used to limit the -traffic volume or speed with packages like "fairspeed" -(https://systemausfall.org/toolforge/fairspeed). - - -3. How does it work? - - clients retrieve an IP by your dhcp server - - of course, your router should be their default gateway - - the clients are allowed to use nameservice - - only DNS requests get forwarded while the client is not - registered - - the first request on port 80 (http) will get redirected - to the router itself - - each the index.html of the webserver's root and the - error-404-document should contain an http-refresh tag - leading to /www/cgi-bin/web-splash.cgi - - this cgi will register the client (that means: add a - iptable rule to allow forwarding for this client) and - show the page, that is set by the "SPLASH_DOCUMENT" - variable in /etc/web-splash.conf - - FUTURE: there will be a script that unregisters clients - after a specified idle time (so they will get redirected - to the login page again) - - -4. Installation -You may install web-splash with the ipkg package manager or -manually. - -4.1 with ipkg -The package can be installed with the ipkg package management -(it was developd for embeded devices). -With ipkg you may just type: - ipkg install web-splash_???.ipk - -Now you should take a look at /etc/web-splash.conf. -If you use thttpd as your webserver, then you should restart -it. Otherwise it will not see the new default page for a -404-error. This will be explained later in this document ... - -4.2 manuallly -If you do use a distribution that does not include ipkg, then -you may install it manually. - - 1.) unpack the sources - tar xzf web-splash_???.tar.gz - - 2.) config file - cp web-splash.conf /etc - - 3.) functions "library" - cp web-splash-function.sh /usr/lib - - 4.) main script - cp web-splash.sh /usr/bin - - 5.) cgi script - cp web-splash.cgi /www/cgi-bin - - 6.) default web site - cp -r splash-site /www/web-splash - -If you used different locations for these files, then -you need to change the settings in /etc/web-splash.conf too. - - -5. webserver configuration -It is necessary, that your webserver redirects all request to -the cgi of web-splash. This can be done by using an alias -directive (if your webserver supports this) or defining a -custom error-404-document in your webserver (thttpd can do this). - -For thttpd your configuration is already complete if you -installed web-splash as described before. - - -6. splash page -Surely you want to replace the default page that was installed -with your own text (or change the SPLASH_DOCUMENT setting in -/etc/web-splash.conf). -This page could show some information that your users should -get before using the internet. - - -7. support open networks! -web-splash was designed for open (wireless) networks. -I hope that this software ease the work of their administrator's -to spread the word ... -(see http://freenetworks.org) - - -8. contact -Send me an email if you have questions or suggestions: -devel@sumpfralle.de - -the project's homepage: -https://systemausfall.org/toolforge/web-splash - -the subversion repository: -https://svn.systemausfall.org/svn/openwrt-packages - -the bug tracker: -https://systemausfall.org/trac/openwrt-packages diff --git a/web-splash/TODO b/web-splash/TODO deleted file mode 100644 index 142b5a2..0000000 --- a/web-splash/TODO +++ /dev/null @@ -1,2 +0,0 @@ -- add some useful links to the splash-site -- add some information (aka documentation) to the splash-site diff --git a/web-splash/ipkg/conffiles b/web-splash/ipkg/conffiles deleted file mode 100644 index 0a9b07c..0000000 --- a/web-splash/ipkg/conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/web-splash.conf diff --git a/web-splash/ipkg/control b/web-splash/ipkg/control deleted file mode 100644 index 7391e07..0000000 --- a/web-splash/ipkg/control +++ /dev/null @@ -1,23 +0,0 @@ -Package: web-splash -Priority: optional -Version: 0.2.1 -Architecture: mipsel -Maintainer: Lars Kruse -Section: net -Source: https://systemausfall.org/toolforge/web-splash -Depends: grep, sed, iptables -Description: web-splash helps you administering an open access point - Users who want to access the internet with your access point will - at first retrieve a webpage that informs them about the net. - After viewing this page they are allowed to use the net for as long - as you define. - This allows you (the administrator) to inform the users about the free - service they use. - . - It is recommended to use this package with thttpd or any other webserver - that allows you to define a custom error-404-page or a webserver that - supports aliases with regular expression matching. - . - The package web-limit can be used with web-splash to define a traffic - limitation and decrease the available bandwith depending on the remaining - volume. diff --git a/web-splash/ipkg/postinst b/web-splash/ipkg/postinst deleted file mode 100755 index dbb2809..0000000 --- a/web-splash/ipkg/postinst +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -echo -echo "Starting web-splash ..." -/etc/init.d/S89web-splash start -echo -echo "Maybe you should:" -echo " 1) restart your webserver (thttpd needs this to see the new error-404-document)" -echo " 2) change the hostname in /www/index.html to the IP or name of the router" -echo diff --git a/web-splash/ipkg/postrm b/web-splash/ipkg/postrm deleted file mode 100755 index 187eaf4..0000000 --- a/web-splash/ipkg/postrm +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ -e /www/index.html.orig ] - then echo - echo "Restoring original /www/index.html.orig to /www/index.html" - mv /www/index.html.orig /www/index.html - fi diff --git a/web-splash/ipkg/preinst b/web-splash/ipkg/preinst deleted file mode 100755 index 8027088..0000000 --- a/web-splash/ipkg/preinst +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ -e /www/index.html ] - then echo - echo "Renaming /www/index.html to /www/index.html.orig" - mv /www/index.html /www/index.html.orig - fi diff --git a/web-splash/ipkg/prerm b/web-splash/ipkg/prerm deleted file mode 100755 index df3d0ee..0000000 --- a/web-splash/ipkg/prerm +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "Stopping web-splash ..." -/etc/init.d/S89web-splash stop || true diff --git a/web-splash/ipkg/rules b/web-splash/ipkg/rules deleted file mode 100755 index 1bfaac2..0000000 --- a/web-splash/ipkg/rules +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/make -f - -# DESTDIR should be defined -DESTDIR ?= /tmp/web-splash - - -build: - @echo "done" - - -install: - @# config files - @mkdir -p $(DESTDIR)/etc - @cp web-splash.conf $(DESTDIR)/etc - - @# web site - @mkdir -p $(DESTDIR)/www/web-splash - @cp splash-site/* $(DESTDIR)/www/web-splash/ - @mkdir -p $(DESTDIR)/www/cgi-bin - @cp web-splash.cgi $(DESTDIR)/www/cgi-bin/ - @ln -s web-splash/index.html $(DESTDIR)/www/index.html - @mkdir -p $(DESTDIR)/www/errors - @ln -s ../index.html $(DESTDIR)/www/errors/err404.html - - @# install binaries - @mkdir -p $(DESTDIR)/usr/lib - @cp web-splash-functions.inc $(DESTDIR)/usr/lib - @mkdir -p $(DESTDIR)/usr/bin - @cp web-splash.sh $(DESTDIR)/usr/bin - - @# startup script - @mkdir -p $(DESTDIR)/etc/init.d - @echo -e "#!/bin/sh\n/usr/bin/web-splash.sh start" >$(DESTDIR)/etc/init.d/S89web-splash - @chmod +x $(DESTDIR)/etc/init.d/S89web-splash - -clean: - @echo "done" diff --git a/web-splash/splash-site/index.html b/web-splash/splash-site/index.html deleted file mode 100644 index 6f5c25e..0000000 --- a/web-splash/splash-site/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Umleitung des offenen Netzes - - - - -

-

If you do not get redirected, then please follow this link to enable internet access.

- -
- -

Falls du nicht automatisch weitergeleitet wurdest, dann folge diesem Link, um deine Internetverbindung freizuschalten.

- - - diff --git a/web-splash/splash-site/splash-info.html b/web-splash/splash-site/splash-info.html deleted file mode 100644 index 2432f5e..0000000 --- a/web-splash/splash-site/splash-info.html +++ /dev/null @@ -1,13 +0,0 @@ - - - Willkommen im Offenen Netz - - - - -



- -

Deine Verbindung ins Internet wurde freigeschaltet ...

- - - diff --git a/web-splash/web-splash-functions.inc b/web-splash/web-splash-functions.inc deleted file mode 100644 index 4aea67b..0000000 --- a/web-splash/web-splash-functions.inc +++ /dev/null @@ -1,129 +0,0 @@ -# this skript is GPL software (http://www.fsf.org/licensing/licenses/gpl.html) -# suggestions and questions to: devel@sumpfralle.de -# homepage: https://systemausfall.org/toolforge/web-splash -# -# this file will be sourced by web-splash.sh -# - -remove_old() -{ - # remove the rules from PREROUTING - $IPT -t nat -F $CHAIN_FORWARD_CHECK 2>/dev/null && $IPT -t nat -D PREROUTING -i $IF_SRC -j $CHAIN_FORWARD_CHECK - $IPT -t nat -F $CHAIN_REDIRECT 2>/dev/null && $IPT -t nat -D PREROUTING -i $IF_SRC -j $CHAIN_REDIRECT - $IPT -t nat -F $CHAIN_SERVICES 2>/dev/null && $IPT -t nat -D PREROUTING -i $IF_SRC -j $CHAIN_SERVICES - - # remove the rule from FORWARD - $IPT -F $CHAIN_RETURN 2>/dev/null && $IPT -D FORWARD -o $IF_SRC -j $CHAIN_RETURN - - # empty and remove chains if they exist (from POSTROUTING) - for a in $CHAIN_FORWARD_ACTION $CHAIN_FORWARD_CHECK $CHAIN_REDIRECT $CHAIN_SERVICES - do $IPT -t nat -F $a 2>/dev/null && $IPT -t nat -X $a - true - done - - # empty and remove chains if they exist (from FORWARD) - for a in $CHAIN_RETURN - do $IPT -F $a 2>/dev/null && $IPT -X $a - true - done -} - - -init_chains() -{ - # create chains (in nat table) - for a in $CHAIN_FORWARD_ACTION $CHAIN_FORWARD_CHECK $CHAIN_REDIRECT $CHAIN_SERVICES - do $IPT -t nat -N $a - done - - # create chains (in filter table) - for a in $CHAIN_RETURN - do $IPT -N $a - done - - # all packets from the specified interface go to the web-splash-chains first - # "-I" means insert before every other chain -> inserting reverse ordered - $IPT -t nat -I PREROUTING -i $IF_SRC -j $CHAIN_REDIRECT - $IPT -t nat -I PREROUTING -i $IF_SRC -j $CHAIN_FORWARD_CHECK - $IPT -t nat -I PREROUTING -i $IF_SRC -j $CHAIN_SERVICES - - # add a "counting" chain for return packets - # it does nothing - except providing a counter for returned bytes - $IPT -I FORWARD -o $IF_SRC -j $CHAIN_RETURN - - # rules for CHAIN_REDIRECT - $IPT -t nat -A $CHAIN_REDIRECT -p tcp --dport 80 -j DNAT --to-destination $INTERN_IP - $IPT -t nat -A $CHAIN_REDIRECT -p tcp --dport 80 -j ACCEPT - $IPT -t nat -A $CHAIN_REDIRECT -j $REJECT_ACTION - - # all registered senders are simply accepted - $IPT -t nat -A $CHAIN_FORWARD_ACTION -j ACCEPT - - # allowed packets (services like dns, dhcp and ssh (to the router only)) - $IPT -t nat -A $CHAIN_SERVICES -p udp --dport 53 -j ACCEPT - $IPT -t nat -A $CHAIN_SERVICES -p udp --dport 67 -j ACCEPT - $IPT -t nat -A $CHAIN_SERVICES -p tcp --dport 67 -j ACCEPT - $IPT -t nat -A $CHAIN_SERVICES -p tcp -d $INTERN_IP --dport 22 -j ACCEPT - - # user defined "privileged" source IPs - for a in $ALLOW_IP_LIST - do $IPT -t nat -A $CHAIN_SERVICES -s $a -j ACCEPT - done - - # user defined forbidden source IPs - for a in $DENY_IP_LIST - do $IPT -t nat -I $CHAIN_SERVICES -s $a -j $REJECT_ACTION - done -} - - -get_IP_list() -# prints out all active forwarding IPs -{ - $IPT -t nat -L "$CHAIN_FORWARD_CHECK" -vnx | sed "1,2d; s/ */ /g" | cut -d " " -f 9 - # get all active forward chains - # remove the first two lines - # remove multiple spaces - # take only the IP -} - - -register_IP() -# add a new allowed IP -{ - if get_IP_list | grep -q "^$1$" - then echo "die IP $1 war bereits freigeschaltet!" - else eval `echo "$RULE_ADD" | sed "s/_IP_/$1/g"` - fi -} - - -unregister_IP() -# remove the specified IP -{ - if get_IP_list | grep -q "^$1$" - then eval `echo "$RULE_DEL" | sed "s/_IP_/$1/g"` - else echo "die IP $1 war nicht freigeschaltet!" - fi -} - - -update_IP_list() -# remove inactive IPs from the forwarding list -{ - local IP - get_IPs | while read IP - do [ `get_IP_traffic $IP` -gt 0 ] && unregister_IP "$IP" - done -} - -get_IP_traffic() -{ - local IP="$1" - local out_traffic="`$IPT -t nat -L \"$CHAIN_FORWARD_CHECK\" -vnx | sed '1,2d; s/ */ /g' | cut -d ' ' -f 3,9 | grep \" $IP$\" | cut -d ' ' -f 1`" - local in_traffic="`$IPT -L \"$CHAIN_RETURN\" -vnx | sed '1,2d; s/ */ /g' | cut -d ' ' -f 3,9 | grep \" $IP$\" | cut -d ' ' -f 1`" - if [ -n "$in_traffic" -a -n "$out_traffic" ] - then echo $((in_traffic+out_traffic)) - else echo 0 - fi -} diff --git a/web-splash/web-splash.cgi b/web-splash/web-splash.cgi deleted file mode 100755 index 8323538..0000000 --- a/web-splash/web-splash.cgi +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# this skript is GPL software (http://www.fsf.org/licensing/licenses/gpl.html) -# suggestions and questions to: devel@sumpfralle.de -# homepage: https://systemausfall.org/toolforge/web-splash -# - - -. /etc/web-splash.conf - -echo "Content-type: text/html" -echo - -cat "$SPLASH_DOCUMENT" - -"$SPLASH_BIN/web-splash.sh" register "$REMOTE_ADDR" diff --git a/web-splash/web-splash.conf b/web-splash/web-splash.conf deleted file mode 100644 index 407a296..0000000 --- a/web-splash/web-splash.conf +++ /dev/null @@ -1,49 +0,0 @@ -# this file is not parsed, but simply sourced -# -# web-splash is GPL software (http://www.fsf.org/licensing/licenses/gpl.html) -# suggestions and questions to: devel@sumpfralle.de -# homepage: https://systemausfall.org/toolforge/web-splash -# - - -# the source interface (only these packets will be filtered) -IF_SRC=eth1 - -# intern IP address auf the network, where web-splash will be used -INTERN_IP=192.168.1.1 - -# name of the local file that should be displayed by the cgi -SPLASH_DOCUMENT=/www/web-splash/splash-info.html - -# allowed and denied IPs - separated by spaces -ALLOW_IP_LIST="" -DENY_IP_LIST="" - -# templates for the rules to manage forwarding rules (_IP_ will be substituted by the host's IP) -# the first line adds the PREROUTING-ACCEPT rule -# the second line adds the counter rule -RULE_ADD='$IPT -t nat -I $CHAIN_FORWARD_CHECK -s _IP_ -j $CHAIN_FORWARD_ACTION; - $IPT -I $CHAIN_RETURN -d _IP_' -RULE_DEL='$IPT -t nat -D $CHAIN_FORWARD_CHECK -s _IP_ -j $CHAIN_FORWARD_ACTION; - $IPT -D $CHAIN_RETURN -d _IP_' - -# the iptables chain, that contains all forwarded ips -CHAIN_FORWARD_CHECK=web_splash_forward_check -CHAIN_FORWARD_ACTION=web_splash_forward_action -CHAIN_REDIRECT=web_splash_redirect -CHAIN_SERVICES=web_splash_services -CHAIN_RETURN=web_splash_return - -# the iptables action for bad packets (e.g. DROP or REJECT) -REJECT_ACTION=DROP - -# the location of the iptables program -IPT=/sbin/iptables -[ ! -x "$IPT" ] && IPT=/usr/sbin/iptables - -# path to the web-splash scripts -SPLASH_LIB=/usr/lib -SPLASH_BIN=/usr/bin - -# activate DEBUG mode 0/1 (only for testing - it produces ugly output) -SPLASH_DEBUG=0 diff --git a/web-splash/web-splash.sh b/web-splash/web-splash.sh deleted file mode 100755 index 8f16a37..0000000 --- a/web-splash/web-splash.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh -# -# this skript is GPL software (http://www.fsf.org/licensing/licenses/gpl.html) -# suggestions and questions to: devel@sumpfralle.de -# homepage: https://systemausfall.org/toolforge/web-splash -# - - -set -ue - -. /etc/web-splash.conf -. "$SPLASH_LIB/web-splash-functions.inc" - - -# check for DEBUG mode -[ "$SPLASH_DEBUG" -eq 1 ] && set -x - - -ACTION="--help" -[ $# -gt 0 ] && ACTION="$1" - -case "$ACTION" in - start|restart ) - remove_old - init_chains - ;; - stop ) - remove_old - ;; - register ) - [ $# -gt 2 ] && echo "[WEB_SPLASH] too many parameters: only one IP address is allowed" && exit 1 - [ $# -lt 2 ] && echo "[WEB_SPLASH] you have to specify an IP address" && exit 2 - register_IP "$2" - ;; - unregister ) - [ $# -gt 2 ] && echo "[WEB_SPLASH] too many parameters: only one IP address is allowed" && exit 1 - [ $# -lt 2 ] && echo "[WEB_SPLASH] you have to specify an IP address" && exit 2 - unregister_IP "$2" - ;; - update ) - update_IP_list - ;; - traffic ) - if [ $# -eq 1 ] - then get_IP_list | while read IP - do echo "$IP `get_IP_traffic \"$IP\"`" - done - else IP="$2" - get_IP_traffic "$IP" - fi - ;; - * ) - echo "Syntax: $0 {start|stop|restart|register|unregister|update|traffic}" - echo - ;; - esac