#!/usr/bin/perl
$|=1;
# Copyright (C) 1999 Brent A. Fulgham
# Copyright (C) 1997-1998 Johnie Ingram .
# aolsrvconf
# Program to configure the AOLserver
#
# Note: This program is a shameless theft of Johnie Ingram's
# excellent set-up script. I have modified it for use with
# AOLserver.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# The following are the standard Debian locations for various
# files and utilities. You should be able to port this script to
# other file schemes by only modifying these fields. However,
# it hasn't been tested so use caution.
#
$NSD_CONFDIR="/etc/aolserver";
$NSD_CONF="$NSD_CONFDIR/nsd.tcl";
$NSD_EX="/usr/share/doc/aolserver/examples/nsd.tcl";
$NSD_INIT="/usr/lib/aolserver/bin/init";
$INIT_DIR="/etc/init.d";
$CRON_CONF="/etc/aolserver/cron.conf";
$CRON_EX="/usr/share/doc/aolserver/examples/cron.conf";
$MIME_CONF="/etc/mime.types";
$MAILNAME_CONF="/etc/mailname";
$ALIASES_CONF="/etc/aliases";
$HOME_EX="/usr/share/doc/aolserver/examples/intro.html";
$GROUP="www-data";
$USER="www-data";
$PAGE_ROOT="/var/www";
$AOLSRV_ROOT="/usr/lib/aolserver";
$PID_DIR="/var/run/aolserver";
$PID_FILE="$PID_DIR/aolserver.pid";
$LOG_DIR="/var/log/aolserver";
$LOG_FILE="$LOG_DIR/server.log";
#
# You shouldn't need to modify beyond this point
#
$write_nsdconf = 0;
$write_aliasesconf = 0;
$changed = 0;
$q = 1;
use Getopt::Long;
$opt_assert_perl = 0;
$opt_force = 0;
$opt_update = 0;
$opt_remove = 0;
$opt_noninteract = 0;
chomp ($arch = `dpkg --print-installation-architecture`);
chomp ($mailname = (-e $MAILNAME_CONF)
? `cat $MAILNAME_CONF` : "localhost");
###########################################################################
sub load_config_files ()
{
if (! -e $NSD_EX)
{
system("gzip -d $NSD_EX.gz") && die "Couldn't unzip $NSD_EX.gz\n";
}
$main::nsdconf = `cat $NSD_EX` || die "No $NSD_EX on this system.\n";
$main::servername = loadsetting ("servername", "localhost");
$main::serveradmin = loadconf ("ServerAdmin", "www-data");
$main::serveruser = loadconf ("User", "www-data");
$main::servergroup = loadconf ("Group", "www-data");
chomp (my $tmproot = `egrep "^www-data" /etc/passwd | cut -f 6 -d :`);
$tmproot = "/var/www" if ($tmproot eq "");
$main::pageroot = loadsetting ("pageroot", $tmproot, $NSD_CONF);
$main::serverport = loadsetting ("httpport", "80");
$main::version = "3.0";
$main::servergroup = "www-data" if $main::servergroup =~ m/-/;
}
###########################################################################
sub yorn ($;$)
{
$main::changed = 0;
my $result = $_[0];
my $morearg = "";
print $_[1] if defined $_[1];
($result) ? print " [Y/n] " : print " [y/N] ";
$arg = ;
$result = 1 if ($arg =~ /^y/i);
$result = 0 if ($arg =~ /^n/i);
$q = 0 if ($arg =~ /q/i);
$main::changed = 1 unless ($result == $_[0]);
return $result;
}
###########################################################################
sub remove_files()
{
print "\n";
print "Removing entries for the domain $main::domain.\n";
print "\n";
print "This will completely delete any configuration information,\n";
print "HTML files, and anything else under $main::pageroot.\n";
print "\n";
if (! $opt_noninteract)
{
if (! yorn (0, "Are you sure you wish to delete domain $main::domain? "))
{
print "Great! Nothing has been changed.\n";
exit 0;
}
}
my($NSD_DOMAIN_INIT);
# Must remove a few things.
# 1. Remove the init.d entries
$NSD_DOMAIN_INIT="$INIT_DIR/aolserver.$main::domain";
system ("$NSD_DOMAIN_INIT stop");
unlink ($NSD_DOMAIN_INIT);
system ("update-rc.d aolserver.$main::domain remove") && die "Unable to remove init.d links.\n";
# 2. Remove the configuration file
print "Deleting configuration file $NSD_CONFDIR/$main::domain.tcl\n";
unlink ("$NSD_CONFDIR/$main::domain.tcl");
# 3. Remove the entries in PageRoot
#my($pageroot);
#$pageroot = loadconf ("pageroot", "/var/www/$main::domain", $NSD_CONF);
#print "Deleting the $pageroot directory.\n";
#system ("rm -r $pageroot");
# 4. Remove the server includes in BinRoot
print "Deleting the $AOLSRV_ROOT/servers/$main::domain directory.\n";
system ("rm -r $AOLSRV_ROOT/servers/$main::domain");
print "Finished.\n";
}
###########################################################################
sub add_initd_entry()
{
# In this case, must add an entry to init.d to start the
# separate process up.
print "Adding an entry for domain $main::domain to init.d ...\n";
# Create the init file
$initfile = `cat $NSD_INIT`;
$initfile =~ s/^NAME=.*$/NAME=$main::domain/m;
$initfile =~ s/^USER=.*$/USER=$main::serveruser/m;
$initfile =~ s/^GROUP=.*$/GROUP=$main::servergroup/m;
$NSD_CONF="$NSD_CONFDIR/$main::domain.tcl";
$initfile =~ s/^CONF=.*$/CONF=$NSD_CONF/m;
$NSD_DOMAIN_INIT="$INIT_DIR/aolserver.$main::domain";
open (CONF, ">$NSD_DOMAIN_INIT") || die ("couldn't open $NSD_DOMAIN_INIT");
print CONF $initfile;
close (CONF);
# Create the symlinks
chmod 0755, $NSD_DOMAIN_INIT || die "Unable to set correct permissions for $main::domain.\n";
system ("update-rc.d aolserver.$main::domain defaults") && die "Unable to create init.d links.\n";
# Done!
print "done.\n";
}
###########################################################################
sub answer ($;$)
{
$main::changed = 0;
my $arg;
my $default = $_[0];
print $_[1] if defined $_[1];
print " [$default] " if (defined ($default) && $default ne "");
chomp ($arg = `read REPLY; echo \$REPLY`);
if ($arg ne "")
{
$main::changed = 1;
return $arg;
}
return $default;
}
###########################################################################
sub loadconf ($$;$)
{
my $parameter = $_[0];
my $default = $_[1];
my $file = (defined ($_[2]) ? $_[2] : "$NSD_CONF");
my $in = `egrep "^ns_param.*$parameter " $file 2> /dev/null| head -1`;
$in =~ s/ns_param\s*$parameter //;
$in =~ s/"//g;
$in =~ s/ //g;
chomp ($in);
return $in if ($in ne "");
return $default;
}
###########################################################################
sub loadsetting ($$;$)
{
my $parameter = $_[0];
my $default = $_[1];
my $file = (defined ($_[2]) ? $_[2] : "$NSD_CONF");
my $in = `egrep "^set.*$parameter " $file 2> /dev/null| head -1`;
$in =~ s/set\s*$parameter //;
$in =~ s/"//g;
$in =~ s/ //g;
chomp ($in);
return $in if ($in ne "");
return $default;
}
###########################################################################
sub ensure_files ()
{
system ("mkdir -m 755 --parents /etc/aolserver");
if (! -e $NSD_CONF)
{
print "Installing new configuration file $NSD_CONF ...\n";
if (system ("cp $NSD_EX $NSD_CONF"))
{
# Failed to copy the file!
# The nsd.tcl file might be compressed
system("cp $NSD_EX.gz $NSD_CONF.gz") && exit 1;
system("gzip -d $NSD_CONF.gz") && exit 1;
}
}
if (! -e $CRON_CONF)
{
print "Installing new configuration file $CRON_CONF ...\n";
system ("cp $CRON_EX $CRON_CONF") && exit 1;
}
if (! -e $MIME_CONF)
{
print "\nError: $MIME_CONF not found.\n";
print "Install the mime-support package, or copy the mime.types ";
print "from\n/usr/share/doc/aolserver/conf/mime.types.\n\n";
exit 1;
}
if (! -x "/usr/bin/savelog")
{
print "\nError: /usr/bin/savelog not found.\n";
print "Are you sure you're running a Debian system? :-)\n\n";
exit 1;
}
if (! -w $NSD_CONF)
{
print "\nError: $NSD_CONF not writable by userid.\n";
print "Who do you think you are, root? :-)\n\n";
exit 1;
}
}
###########################################################################
sub make_corrections ()
{
my $doc = "/usr/share/doc/";
if (! ($main::nsdconf =~ m/^\s*Home\s+$AOLSRV_ROOT/m))
{
print "Correcting Home to $AOLSRV_ROOT in nsd.tcl.\n";
$main::nsdconf =~ s/^ns_param.*Home.*/ns_param Home \"$AOLSRV_ROOT\"/m;
$main::nsdconf =~ s/^set.*home.*/set home \"$AOLSRV_ROOT\"/m;
$write_nsdconf++;
}
if (! ($main::nsdconf =~ m/^\s*PageRoot\s+$PAGE_ROOT/m))
{
print "Correcting PageRoot to $PAGE_ROOT in nsd.tcl.\n";
$main::nsdconf =~ s/^ns_param.*PageRoot.*/ns_param PageRoot \"$PAGE_ROOT\"/mg;
$main::nsdconf =~ s/^set.*pageroot.*/set pageroot \"$PAGE_ROOT\"/mg;
$write_nsdconf++;
}
if (! ($main::nsdconf =~ m/^\s*ServerLog\s+$LOG_FILE/m))
{
print "Correcting ServerLog to $LOG_FILE in nsd.tcl.\n";
$main::nsdconf =~ s/^ns_param.*ServerLog.*/ns_param ServerLog \"$LOG_FILE\"/m;
$write_nsdconf++;
}
if (! ($main::nsdconf =~ m/^\s*ns_param.*PidFile\s+$PID_FILE/m))
{
print "Correcting PidFile to $PID_FILE in nsd.tcl.\n";
$main::nsdconf =~ s/^ns_param.*PidFile.*/ns_param PidFile $PID_FILE/m;
$write_nsdconf++;
}
if (! ($main::nsdconf =~ m/^\s*User\s+$USER/m))
{
print "Correcting User to $USER in nsd.tcl.\n";
$main::nsdconf =~ s/^ns_param.*User.*/ns_param User $USER/m;
$write_nsdconf++;
}
print "Correcting Server Name to $main::domain.\n";
if (! ($main::nsdconf =~ m/^\s*set\s+server.*$/m))
{
$main::nsdconf =~ s/^ns_section\s+\"ns\/parameters\"/set server \"$main::domain\"\n\nns_section \"ns\/parameters\"/m;
}
else
{
$main::nsdconf =~ s/^\s*set\s+server.*$/set server \"$main::domain\"/m;
}
$write_nsdconf++
}
###########################################################################
sub make_directory ($)
{
if (! -d $_[0])
{
system ("mkdir --parents --mode=755 $_[0]")
|| print "Created directory $_[0].\n";
}
print "Fixing: ";
system ("chown --verbose $main::serveradmin.$main::servergroup $_[0]");
}
###########################################################################
sub config_domain ()
{
my($documentroot);
#
# Get the root directory where all WWW domains are kept.
#
if (! defined ($opt_documentroot))
{
my($temproot);
$temproot = "$PAGE_ROOT";
print "\n";
print "The AOLserver server will serve documents from a directory called the document\n";
print "root or PageRoot. You must specify such a directory for the server to work.\n";
print "It is recommended that you use the default: $temproot\n";
print "\n\n";
do {
$documentroot = answer ($temproot, "What should the page root be?");
} until ($documentroot);
}
else
{
$documentroot = $opt_documentroot;
}
make_directory ($documentroot) if (! -x $documentroot);
$documentroot .= "/$domain";
make_directory("$documentroot") if (! -x "$documentroot");
$documentroot .= "/www";
make_directory ("$documentroot") if (! -x "$documentroot");
unless($opt_noninteract)
{
do {
$title = answer($title, "What is a short title for the domain $main::domain? ");
} until ($title);
}
#
# Update the PageRoot in the configuration file
#
$main::nsdconf =~ s/^ns_param.*PageRoot.*/ns_param PageRoot \"$documentroot\"/m;
$main::nsdconf =~ s/^set.*pageroot.*/set pageroot \"$documentroot\"/m;
print "The PageRoot is set to $documentroot.\n";
#
# Everyplace that refers to the server must use this domain
#
print "Adjusting server references to domain $domain.\n";
$main::nsdconf =~ s/^ns_section\s+\"ns\/server\/\w+\"/ns_section \"ns\/server\/\${server}\"/mg;
$main::nsdconf =~ s/^ns_section\s+\"ns\/server\/\w+\/(.+)\"/ns_section \"ns\/server\/\${server}\/$1\"/mgo;
$main::nsdconf =~ s/^set\s+servername\s.*/set servername \"$title\"/m;
#
# Create a server instance in the aolserver directory
#
system ("cp -ar $AOLSRV_ROOT/servers/server1 $AOLSRV_ROOT/servers/$domain");
#
# Set the logfile and pidfile
#
$main::nsdconf =~ s/^ns_param.*ServerLog.*/ns_param ServerLog \"$LOG_DIR\/aolserver.\${server}.log\"/m;
$main::nsdconf =~ s/^ns_param.*PidFile.*/ns_param PidFile \"$PID_DIR\/aolserver.\${server}.pid\"/m;
$main::nsdconf =~ s/^ns_section\s+\"ns\/server\/\w+\/module\/nslog\"\n^ns_param\s+File.*/ns_section \"ns\/server\/$domain\/module\/nslog\"\nns_param File \"$LOG_DIR\/aolserver.\${server}.access.log\"/m;
$write_nsdconf++;
#
# Set up some introductory documents in the pageroot
#
chomp ($indexfile = `ls $documentroot/index.* 2> /dev/null | head -1`);
if ($indexfile eq "")
{
print "Installing your new homepage in $documentroot.\n";
system ("cp -p -i $HOME_EX $documentroot/index.html");
system ("chmod 644 $documentroot/index.html");
system ("cp -p -i /usr/share/aolserver/icons/aolserver.png $documentroot/aolserver.png");
system ("chmod 644 $documentroot/aolserver.png");
system ("cp -p -i /usr/share/aolserver/icons/openlogo-50.jpg $documentroot/openlogo-50.jpg");
system ("chmod 644 $documentroot/openlogo-50.jpg");
}
else
{
print "Leaving existing site $indexfile untouched.\n";
}
#
# Some debian-specific depends
#
symlink ("/usr/share/doc", "$documentroot/doc");
symlink ("/var/lib/dwww/html", "$documentroot/dwww");
}
###########################################################################
sub config_serveradmin ()
{
if (! defined ($opt_serveradmin))
{
print "\n";
print "Enter the user ID of your server administrator. This login\n";
print "will be used for the nscp web control port for AOLserver.\n";
print "The password information from the /etc/passwd file will be\n";
print "used for your login.\n\n";
print "It is recommended that you use the default user: www-data\n\n";
$main::serveradmin = answer ($main::serveradmin,
"Who should the ServerAdmin be? ");
# Find the passwd file entry
$passwd = `grep $main::serveradmin /etc/passwd`;
@chunks = split (/:/, $passwd);
$passwd = $chunks[1].":";
# If the "ns/server/[servername]/module/nscp/users" stanza is present
if ($main::nsdconf =~ /^ns_section\s+\"ns\/server\/\w+\/module\/nscp\/users\"/m)
{
print "Correcting $main::serveradmin password entry in nsd.tcl.\n";
$main::nsdconf =~ s/ns_param.+user.+\".+:.*:\"/ns_param user \"$main::serveradmin:$passwd\"/m;
$write_nsdconf++;
}
$change++;
}
else
{
$main::serveradmin = $opt_serveradmin;
print "The ServerAdmin is set to $main::serveradmin.\n";
$changed++;
}
$main::serveruser=$main::serveradmin;
$write_nsdconf++ if $changed;
}
###########################################################################
sub config_serverport ()
{
if (! defined ($opt_port))
{
print "\n";
print "Please choose a port number on which the AOLserver will listen\n";
print "for incoming connections. This port number is usually 80, but you\n";
print "may want to choose another one if you have another server already\n";
print "listening on that port, or if you want to listen on an unprivileged\n";
print "port. In this case, the port 8080 might be a good choice.\n\n";
$serverport = answer ($serverport, "What port should AOLserver listen on? ");
$changed++;
}
else
{
$serverport = $opt_port;
print "The Port is set to $serverport.\n";
$changed++;
}
$main::nsdconf =~ s/^ns_param.*Port.*/ns_param Port $serverport/m;
$write_nsdconf++ if $changed;
}
###########################################################################
sub get_description ($)
{
chomp (my $desc = `egrep "^Description: " $_[0]`);
$desc =~ s/Description: //;
return $desc;
}
###########################################################################
sub offer_early_exit ()
{
return if ($opt_force);
if (! $write_nsdconf )
{
if (yorn (1, "A valid AOLserver configuration exists. Use it?"))
{
if (yorn (1, "Restart AOLserver now?"))
{
system ("/etc/init.d/aolserver restart");
}
print "\n";
exit 0;
}
$opt_update = 0;
}
print "An AOLserver configuration exists, but needs some tweaking.\n"
if ($write_nsdconf);
}
###########################################################################
#
# Main entry
#
###########################################################################
GetOptions ("force!",
"assert-perl!",
"update!",
"serveradmin=s",
"servername=s",
"serveradmin=s",
"documentroot=s",
"domain=s",
"remove!",
"noninteract!",
"port=i");
exit 0 if $opt_assert_perl;
if ($opt_domain)
{
print "Configuring for domain $opt_domain\n";
$main::domain = $opt_domain;
$NSD_CONF="$NSD_CONFDIR/$main::domain.tcl";
}
else
{
my($temp_domain);
#
# Now determine the particular domain being configured in this run
#
print "\n";
print "The AOLserver can serve pages for multiple domains. However, each\n";
print "run of this configuratio script is only concerned with a single domain.\n";
print "\n\n";
do {
$temp_domain = answer($temp_domain, "What should the domain name be? ");
} until ($temp_domain);
$main::domain=$temp_domain;
}
ensure_files ();
load_config_files ();
if ($opt_remove)
{
remove_files();
exit 0;
}
make_corrections ();
offer_early_exit () if ($opt_update);
print "\nYour config files will not be modified until you select Y at \"save changes.\"\n";
config_serveradmin ();
config_domain () unless ($write_nsdconf == 0);
config_serverport () unless ($opt_update);
unless ($opt_noninteract)
{
if (! yorn (1, "\nSave these changes to the configuration files?"))
{
print "\nWhew! No changes were made.\n\n";
exit 0;
}
print "\n";
}
if ($write_nsdconf)
{
$NSD_CONF="$NSD_CONFDIR/$main::domain.tcl";
if (-x $NSD_CONF)
{
system ("savelog -c 100 $NSD_CONF")
&& die ("couldn't rotate $NSD_CONF");
}
open (CONF, ">$NSD_CONF") || die ("couldn't open $NSD_CONF");
print CONF $main::nsdconf;
close (CONF);
}
add_initd_entry();
if ($opt_noninteract ||
(yorn (1, "Restart AOLserver now?")))
{
system ("/etc/init.d/aolserver.$main::domain stop");
system ("/etc/init.d/aolserver.$main::domain start");
}
print "\n";
exit 0;