>At 03:54 PM 06-02-97 -0800, you wrote:
>> Anyone happen to have a nice CGI that would allow users to subscribe and
>> unsubscribe to Majordomo lists froma WWW page. Perhaps several lists at
>> once? I would hate to re-create what someone alread did. ;-)
>>
>> Dave
>>
>> Dave A. Flanigan, Systems Administrator, NewReach Communications Inc.
>
>
>I use MailServ. Have a look at : http://iquest.com/~fitz/www/mailserv/
>
>Damien.
>
>Damien Malczewski
>Information Technology Division
>Central Queensland University, Australia
>Email : d.malczewski@cqu.edu.au
First, I am not a member of the majordomo-users mailing list. The
question above was sent to me by the manager of the ISP Peak, who
suggested I send out what I wrote as a hack for here. Feel free
to send mail to me at regan@peak.org.
You can sample this program by looking at:
http://www.peak.org/peak_info/mlists/
or more specifically:
http://www.peak.org/cgi-bin/majordomo?lug:peak.org
The first page is an index into the mailing lists supported at Peak,
and the second puts you into the CGI program.
There are two programs. The first one, majordomo, is called with
?mailing-list-name:site-offering-mailing-list
So you can set up a subscribe button which has some of the fields
preset.
The second program, majordomo2, parses the form, and sends email
to the appropriate server to request subscription.
This allows access to the major functions of majordomo.
Note that this is a CGI program. I used to think the problems of
security with user written CGI programs was overstated. After looking
at a few other CGI programs I understand why administrators get worried.
So, please do not trust this or any other CGI program unless you have
a disposable machine or have one of *your* people look it over for
stupid errors. Now I don't expect that you will find any in these
programs, but you shouldn't trust my word. Note that if you
do find some problem, please let me know so that I can fix it.
Both of these programs are intended to be added to your cgi-bin
directory.
I hadn't written these programs for external consumption, so there
isn't much in the way of external documentation. The basic idea
is that you have something like:
<a href="/cgi-bin/majordomo?dvd-www:peak.org">Subscribe</a>
in your web page, and the rest goes from there.
Note that the first line of each program must be changed to
reflect the location of perl on your web server.
Dave Regan
regan@peak.org
==================== majordomo ==========================
#!/usr/ucb/perl5
#
# majordomo
#
# Build a form with some fields preset. The generated form will
# allow most of the options which majordomo allows.
#
#
# 24 Jun 1996 Dave Regan regan@peak.org
# Initial hack
#
# 12 Jul 1996 Dave Regan regan@peak.org
# Changed background color
#
###
### Configuration
###
###
### Main program
###
HTMLhead("Marjordomo meets the web");
# print "<body background=\"/images/wheat.gif\">\n";
print "<body bgcolor=\"#FFFFFF\">\n";
$| = 1;
# printenv();
$query = untaint($ENV{'QUERY_STRING'});
$mlist = $query;
$mlist =~ s/:.*//;
$host = $query;
$host =~ s/.*://;
DisplayForm($mlist, $host);
HTMLterm();
exit 0;
###
### DisplayForm
###
### Build a form for the user to fill in.
###
sub DisplayForm
{
local($mlist, $host) = @_;
print "<p>This form will let you control any majordomo mailing list server.\n";
if ($mlist ne "")
{
$host = "peak.org" if ($host eq "");
print "The current mailing list ($mlist on host $host)\n";
print "is selected as a default, but you\n";
print "can alter the mailing list name or host if you want.\n";
}
# print "You must enter your email address and your full name.\n";
print "You must enter your email address.\n";
print "<p>\n";
print "You can select any of the majordomo commands, and you can choose to select\n";
print "several of them.\n";
print "<p>\n";
print "<form action=\"http://www.peak.org/cgi-bin/majordomo2\" method=\"POST\">\n";
print "<table width=100% border=2>\n";
print "<tr><td>\n";
print "<pre>\n";
print "Email address: <input NAME=\"email\" TYPE=\"text\" SIZE=\"40\"><p>\n";
# print "Real Name: <input NAME=\"name\" TYPE=\"text\" SIZE=\"40\"><p>\n";
print "Mailing List: <input NAME=\"mlist\" TYPE=\"text\" SIZE=\"40\" VALUE=\"$mlist\"><p>\n";
print "Host: <input NAME=\"host\" TYPE=\"text\" SIZE=\"40\" VALUE=\"$host\"><p>\n";
print "Filename: <input NAME=\"fname\" TYPE=\"text\" SIZE=\"40\">(for get command)<p>\n";
print "<p>\n";
print "</pre>\n";
print "<input TYPE=\"checkbox\" NAME=\"subscribe\" checked> ";
print "Subscribe -- Subscribe to the specified mailing list.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"unsubscribe\">";
print "Unsubscribe -- Unsubscribe from the specified mailing list.<br> ";
print "<input TYPE=\"checkbox\" NAME=\"help\"> ";
print "Help -- Get a help message from Majordomo.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"info\"> ";
print "Info -- Get information on the specified mailing list.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"index\"> ";
print "Index -- Return an index of files you can \"get\" for the specified list.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"which\"> ";
print "Which -- Find out which lists you are on for the specified host.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"who\"> ";
print "Who -- Find out who is on the specified list.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"lists\"> ";
print "Lists -- Get an index of the mailing lists available on the specified host.<br>\n";
print "<input TYPE=\"checkbox\" NAME=\"get\"> ";
print "Get -- Get a file from the archive associated with the specified mailing list.<br>\n";
print "<center>\n";
print "<input NAME=\"Submit\" TYPE=\"submit\" VALUE=\"Submit\">\n";
print "<input NAME=\"Reset\" TYPE=\"reset\" VALUE=\"Reset\">\n";
print "</center>\n";
print "</td></tr>\n";
print "</table>\n";
}
###
### HTMLhead
###
### Put out a HTML header
###
sub HTMLhead
{
local($title) = @_;
print "Content-type: text/html\n\n";
print "<html><head><title>$title</title></head>\n";
print "<body>\n";
}
###
### HTMLterm
###
### Put out the end of an HTML body.
###
sub HTMLterm
{
print "</body></html>\n";
}
###
### printenv
###
### Display the environment.
### This assumes that we can write on stdout. This may not
### be true if we haven't written the header line yet.
###
sub printenv
{
local(@env, $var);
@env = `printenv`;
for $var (@env)
{
print "$var<br>\n";
}
}
###
### untaint
###
### Pass over a string.
### This is somewhat cheating.
###
sub untaint
{
local($var) = @_;
$var =~ m#^(.*)$#;
return $1;
}
===================== majordomo2 ========================
#!/usr/ucb/perl5
#
# majordomo2
#
# This is the completion routine for signing up for a majordomo list.
# Check the variables for sanity, and then send e-mail to sign up for
# a list.
#
#
# 24 Jun 1996 Dave Regan regan@peak.org
# Initial hack.
#
# 12 Jul 1996 Dave Regan regan@peak.org
# Changed background color.
#
###
### Configuration
###
$LocalHost = "peak.org";
$Mail = "/usr/lib/sendmail";
###
### Main program
###
CheckSanePost();
HTMLhead("Account Validation");
# print "<body background=\"/images/wheat.gif\">\n";
print "<body bgcolor=\"#FFFFFF\">\n";
$| = 1;
# printenv();
ParseFormVariables();
# printvars();
if (CheckData() == 0)
{
print "<p><h2>Please use the <b>back</b> button of your browser and correct the form.\n";
print "Once the data is corrected, resubmit the data.</h2>\n";
}
else
{
print "Your request has been sent. Expect to see results in your e-mail soon.\n";
SendMail();
}
HTMLterm();
exit 0;
###
### CheckData
###
### See if the data looks reasonable.
###
sub CheckData
{
local($retval);
$retval = 1;
# We need an e-mail address to do anything
if ($Vars{'email'} eq "")
{
print "You must specify a valid e-mail address to do much of anything ";
print "with majordomo.<br>\n";
$retval = 0;
}
$Vars{'email'} = "$Vars{'email'}\@$LocalHost" if ($Vars{'email'} !~ /\@/);
# # subscribe and unsubscribe really want a real name
# if ( ($Vars{'subscribe'} ne "" || $Vars{'unsubscribe'} ne "") && $Vars{'name'} eq "")
# {
# print "Subscriptions and unsubscriptions require your name.<br>\n";
# $retval = 0;
# }
# For some of the operations, a mailing list and host must be specified
if ( ($Vars{'mlist'} eq "" || $Vars{'host'} eq "") &&
($Vars{'subscribe'} ne "" ||
$Vars{'unsubscribe'} ne "" ||
$Vars{'info'} ne "" ||
$Vars{'index'} ne "" ||
$Vars{'who'} ne "" ||
$Vars{'get'} ne ""))
{
print "The options you have selected require that you specify a mailing list name\n";
print "as well as a host name.<br>\n";
$retval = 0;
}
# Cannot both subscribe and unsubscribe
if ($Vars{'subscribe'} ne "" && $Vars{'unsubscribe'} ne "")
{
print "Cannot subscribe and unsubscribe at the same time.<br>\n";
$retval = 0;
}
# Cannot specify "get" unless there is a filename
if ($Vars{'get'} ne "" && $Vars{'fname'} eq "")
{
print "Please specify a filename when using the \"GET\" option.<br>\n";
$retval = 0;
}
return $retval;
}
###
### CheckSanePost
###
### See that this is a legitimate POST request. Die if not.
### This assumes that the initial Content-type message has *not*
### been sent.
###
sub CheckSanePost
{
###
### Ensure that the form of the request looks valid.
###
if ($ENV{'REQUEST_METHOD'} ne "POST")
{
HTMLhead("Bad method");
print "This script should be referenced with a METHOD of POST.\n";
print "If you don't understand this, see this:\n";
print "<A HREF=\"http://www.ncsa.uiuc.edu/SDG/Software/Mosaic/Docs/fill-out-forms/overview.html\">forms overview</A>.\n";
HTMLterm();
exit 0;
}
if ($ENV{'CONTENT_TYPE'} ne "application/x-www-form-urlencoded")
{
HTMLhead("Bad encoding");
print "This script can only be used to decode form results.\n";
HTMLterm();
exit 1;
}
}
###
### HTMLhead
###
### Put out a HTML header
###
sub HTMLhead
{
local($title) = @_;
print "Content-type: text/html\n\n";
print "<html><head><title>$title</title></head>\n";
print "<body>\n";
}
###
### HTMLterm
###
### Put out the end of an HTML body.
###
sub HTMLterm
{
print "</body></html>\n";
}
###
### ParseFormVariables
###
### The variables from a CGI FORM come in on standard input.
### Read this string, and break it up into the Vars associative
### array.
###
sub ParseFormVariables
{
local($data, @tbl, $val, $var);
$data = <>;
# print "The raw data is $data<br>\n";
$data =~ s/query..=//g;
$data =~ s/&*\s*$//;
@tbl = split(/&/, $data); # Vars separated by &
for ($[ .. $#tbl)
{
# Process the variables. Be careful to avoid removing needed characters.
$tbl[$_] = unquote($tbl[$_]);
# print "$tbl[$_]<br>\n" if ($tbl[$_] !~ /^$/);
# Set up an associative array of name/value pairs.
$var = $tbl[$_];
$val = $tbl[$_];
$* = 1;
$var =~ s/\n//g;
$var =~ s/=.*//;
$val =~ s/^[^=]*=//;
$Vars{$var} = $val;
}
}
###
### printvars
###
### Print the contents of the Vars variable.
###
sub printvars
{
local($key, $value);
print "Variables:<br>\n";
while (($key, $value) = each %Vars)
{
print "$key = $value<br>\n";
}
}
###
### printenv
###
### Display the environment.
### This assumes that we can write on stdout. This may not
### be true if we haven't written the header line yet.
###
sub printenv
{
local(@env, $var);
@env = `printenv`;
for $var (@env)
{
print "$var<br>\n";
}
}
###
### SendMail
###
### Send mail to the majordomo server.
###
### The mail needs to appear as if it is from the specified user.
### This is not as needed for the subscribe/unsubscribe, but is
### absolutely required for most commands to get information back
### to the user.
###
sub SendMail
{
local($email, $host, $mlist);
$email = $Vars{'email'};
$host = $Vars{'host'};
$mlist = $Vars{'mlist'};
if (open(MAIL, "|$Mail majordomo\@$host") == 0)
{
print "Cannot start mailer\n";
return;
}
print MAIL "From: $email\n";
print MAIL "To: majordomo\@$host\n";
print MAIL "\n";
print MAIL "subscribe $mlist $email\n" if ($Vars{'subscribe'} ne "");
print MAIL "unsubscribe $mlist $email\n" if ($Vars{'unsubscribe'} ne "");
print MAIL "help\n" if ($Vars{'help'} ne "");
print MAIL "info $mlist\n" if ($Vars{'info'} ne "");
print MAIL "index $mlist\n" if ($Vars{'index'} ne "");
print MAIL "which $email\n" if ($Vars{'which'} ne "");
print MAIL "who $mlist\n" if ($Vars{'who'} ne "");
print MAIL "lists\n" if ($Vars{'lists'} ne "");
print MAIL "get $mlist $Vars{'fname'}\n" if ($Vars{'get'} ne "");
print MAIL ".\n";
close MAIL;
}
###
### unquote
###
### Unescape a CGI form variable.
###
sub unquote
{
local($raw) = @_;
local($code, @pieces, $piece);
$* = 1;
$raw =~ s/\+/ /g;
$raw =~ s/%0D//g;
@pieces = split(/%/, $raw);
for ($piece = 1; $piece <= $#pieces; $piece++)
{
$pieces[$piece] =~ s/^%//;
$code = substr($pieces[$piece], 0, 2);
$code = hex($code);
$pieces[$piece] = sprintf("%c%s", $code, substr($pieces[$piece], 2));
}
return join("", @pieces);
}
|
|