#!/usr/bin/perl 
$|=1;

# Copyright (C) 1999 Brent A. Fulgham <bfulgham@debian.org>
# Copyright (C) 1997-1998 Johnie Ingram <johnie@debian.org>.

# 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="aolserver";

$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_domain = "server1";
$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 ()
{
    $main::nsdconf = `cat $NSD_EX`;
    $main::servername = loadconf ("ServerName", "localhost");
    $main::serveradmin = loadconf ("ServerAdmin", "aolserver");
    $main::serveruser = loadconf ("User", "aolserver");
    $main::servergroup = loadconf ("Group", "www-data");
    chomp (my $tmproot = `egrep "^aolserver:" /etc/passwd | cut -f 6 -d :`);
    $tmproot = "/var/www" if ($tmproot eq "");
    $main::pageroot = loadconf ("PageRoot", $tmproot, $NSD_CONF);
    $main::serverport = loadconf ("Port", "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 = <STDIN>;
    $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 $opt_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 $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 $opt_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 ensure_files ()
{
    system ("mkdir -m 755 --parents /etc/aolserver");
    if (! -e $NSD_CONF)
    {
	print "Installing new configuration file $NSD_CONF ...\n";
	system ("cp $NSD_EX $NSD_CONF") && 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;
	$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;
	$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);

    #
    #  Now determine the particular domain being configured in this run
    #
    if (! defined($opt_domain))
    {
        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);
    }
    else
    {
       $temp_domain = $opt_domain;
    }
    $main::domain=$opt_domain;
    $documentroot .= "/$domain";
    make_directory("$documentroot") if (! -x "$documentroot");
    $documentroot .= "/www";
    make_directory ("$documentroot") if (! -x "$documentroot");
    
    do {
       $title = answer($title, "What is a short title for this domain? ");
    } until ($title);
    
    #
    #  Update the PageRoot in the configuration file
    #
    $main::nsdconf =~ s/^ns_param.*PageRoot.*/ns_param 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/^ns_section\s+\"ns\/servers\"\n^ns_param\s.*/ns_section \"ns\/servers\"\nns_param $domain      \"$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 ("/var/www/doc", "$documentroot/doc");
    symlink ("/var/www/dwww", "$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: aolserver\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",
	    "documentroot=s",
	    "domain=s",
	    "remove!",
	    "noninteract!",
	    "port=i");

exit 0 if $opt_assert_perl;
if ($opt_domain)
{
    $main::domain = $opt_domain;
    $NSD_CONF="$NSD_CONFDIR/$main::domain.tcl";
}

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);

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/$opt_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 (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;


