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

# Copyright (C) 1999 Brent A. Fulgham <bfulgham@debian.org>

# aolpgconfig
# Program to configure the postgres module of the 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";
$GROUP="www-data";
$DRIVER="postgres";
$DRIVER_BIN="nspostgres.so";

#
#  You shouldn't need to modify beyond this point
#

$write_nsdconf = 0;
$changed = 0;
$q = 1;

use Getopt::Long;
use Sys::Hostname;

$opt_domain = "server1";
$opt_assert_perl = 0;

###########################################################################
sub load_config_files ()
{
    $main::nsdconf = `cat $NSD_CONF`;
    $main::servername = loadconf ("ServerName", "localhost");
    $main::serveradmin = loadconf ("ServerAdmin", "www-data");
    $main::serveruser = loadconf ("User", "www-data");
    $main::servergroup = loadconf ("Group", "www-data");
    chomp (my $tmproot = `egrep "^aolserver:" /etc/passwd | cut -f 6 -d :`);
    $tmproot = "/var/www" if ($tmproot eq "");

    $main::servergroup = "www-data" if $main::servergroup =~ m/-/;
    $main::db = "test1";
}

###########################################################################
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 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 make_corrections ()
{
    if (! ($main::nsdconf =~ m/^ns_section\s+\"ns\/db\/drivers\"/m))
    {
        print "It doesn't seem that you have a database driver section.\n";
	print "I'll correct that now...";

	$main::nsdconf .= "ns_section \"ns/db/drivers\"\n";
	$main::nsdconf .= "ns_param $DRIVER    $DRIVER_BIN\n";
	$main::nsdconf .= "\n";
        $write_nsdconf++;
    }
    
    if (! ($main::nsdconf =~ m/^ns_param\s+$DRIVER\s+$DRIVER_BIN/m))
    {
	print "It doesn't seem that you have a $DRIVER driver entry.\n";
	print "I'll correct that now...";
	
	$main::nsdconf =~ s/^\s*ns_section\s+\"ns\/db\/drivers\"/ns_section "ns\/db\/drivers"\nns_param $DRIVER    $DRIVER_BIN/m; 

	$write_nsdconf++;
	print "done.\n";
    }
    
    if (! ($main::nsdconf =~ m/^\s*ns_section\s+"ns\/db\/driver\/$DRIVER"/m))
    {
	print "It doesn't seem that you have a $DRIVER configuration.\n";
	print "I'll correct that now...";

	$main::nsdconf .= "ns_section \"ns/db/driver/$DRIVER\"\n";
	$main::nsdconf .= "ns_param datestyle    iso\n";
	$main::nsdconf .= "\n";
	
	$write_nsdconf++;
	print "done.\n";
    }

    #
    #  Check the Database Pools Section
    #
    if (! ($main::nsdconf =~ m/^\s*ns_section\s+"ns\/db\/pools"/m))
    {
	print "It doesn't seem that you have a database pool configuration.\n";
	print "I'll correct that now...";

	$main::nsdconf .= "ns_section \"ns/db/pools\"\n";
	$main::nsdconf .= "ns_param main         \"The main database pool\"\n";
	$main::nsdconf .= "\n";
	
	$write_nsdconf++;
	print "done.\n";
    }
    else
    {
        print "Verifying that the \"pools\" section is correct.";

        if (! ($main::nsdconf =~ m/^\s*ns_param\s+main/m))
	{
	    $main::nsdconf =~ s/^.*ns_param\s+main/ns_param main    "The main database pool"/m;
	    $write_nsdconf++;
	}
	print "... done\n";
    }

    #
    #  Check for a Main Database Pool
    #
    if (! ($main::nsdconf =~ m/^\s*ns_section\s+"ns\/db\/pool\/main"/m))
    {
        print "\n\n";
	print "No main database pool entry set.  I'll add it now.\n\n";
	print "Enter the name of the PostgreSQL database you wish\n";
	print "to use.\n";
	
	$main::db = answer ($main::db, "Which database should I use? ");
	
	print "Updating...";

	$main::nsdconf .= "ns_section \"ns/db/pool/main\"\n";
	$main::nsdconf .= "ns_param Driver       $DRIVER\n";
	$main::nsdconf .= "ns_param Connections	 4\n";
	$main::nsdconf .= "ns_param MaxOpen      1000000000\n";
	$main::nsdconf .= "ns_param MaxIdle      1000000000\n";
	$main::nsdconf .= "ns_param DataSource   $main::hostname\:\:$main::db\n";
	$main::nsdconf .= "ns_param User         $main::serveruser\n";
	
	# Find the passwd file entry
	my ($passwd);
	$passwd = `grep $main::serveruser /etc/passwd`;
	@chunks = split (/:/, $passwd);
	$passwd = $chunks[1];
	$main::nsdconf .= "ns_param Password     $passwd\n";
	$main::nsdconf .= "ns_param Verbose      off\n";
	$main::nsdconf .= "ns_param LogSQLErrors  off\n";
	$main::nsdconf .= "ns_param ExtendedTableInfo   on\n";
	$main::nsdconf .= "\n";
	
	$write_nsdconf++;
	print "done.\n";
    }
    else
    {
        # Just make sure the driver is correct
        $main::nsdconf =~ s/(^\s*ns_parm\s+Driver)\s+\w+.*$/ns_param Driver         $DRIVER/m
	    ||  $main::nsdconf =~ s/^\s*ns_section\s+\"ns\/db\/pool\/main\"/ns_section "ns\/db\/pool\/main\"\nns_param Driver      $DRIVER/m; 
    }


    #
    #  List the pools for our server
    #
    # If the "ns/server/[servername]/db" stanza is present
    if ( !($main::nsdconf =~ /^ns_section\s+\"ns\/server\/\w+\/db\"/m))
    {
        $main::nsdconf .= "ns_section \"ns/server/\${server}/db\"\n";
	$main::nsdconf .= "ns_param Pools  *\n";
	$main::nsdconf .= "ns_param DefaultPool   \"main\"\n";
	$main::nsdconf .= "\n";
    }
}

###########################################################################
sub remove_entries()
{
    print "\n";
    print "Removing $DRIVER entries for the $opt_domain domain.\n";
    print "\n";
    print "This will remove the load command for the $DRIVER db driver,\n";
    print "as well as specific configuration information.\n";
    print "This will not touch the database pool entries.\n";

    if (! $opt_noninteract)
    {
        if (! yorn(0, "Are you sure you wish to modify domain $opt_domain? "))
	{
	    print "Great!  Nothing has been changed.\n";
	    exit 0;
	}
    }

    my($NS_DOMAIN_INIT);
    # First, stop the server
    $NS_DOMAIN_INIT="$INIT_DIR/$main::domain";
    system ("$NS_DOMAIN_INIT stop");

    # Next, modify the entries
    print "Removing the $DRIVER load command.\n";
    $main::nsdconf =~ s/\s*ns_param\s+$DRIVER\s+$DRIVER_BIN.*$//m; 

    print "Removing the $DRIVER configuration data.\n";
    $main::nsdconf =~ s/^ns_section\s+\"ns\/db\/drivers\".*$//m;
    $main::nsdconf =~ s/^ns_section\s+\"ns\/db\/drivers\/$DRIVER\".*$//m;
    $main::nsdconf =~ s/^ns_param\s+datestyle\s+iso.*$//m;
    $main::nsdconf =~ s/^ns_param\s+Driver\s+$DRIVER.*$//m;
    
    $write_nsdconf++;
    print "done.\n";
}
    
###########################################################################
GetOptions ("assert-perl!",
            "remove!",
	    "noninteract!",
	    "update!",
	    "domain=s");

$main::hostname = hostname;

exit 0 if $opt_assert_perl;

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

print "\n";
print "Your config files will not be modified until you select Y at \"save changes.\"\n";

load_config_files ();
if ($opt_remove)
{
    remove_entries();
}
else
{
    make_corrections ();
}

if (! $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)
{
    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);
}

if ( (! $opt_remove) && ($main::db != "test1") )
{
    # Note:  We will be adding the "test1" database in the postinst script, so
    # this note should only be displayed for user-defined names
    print "You requested that the database $main::db be used.  If this database\n";
    print "does not already exist, you should make sure it does before attempting.\n";
    print "queries on it.  Please refer to the documentation that came with your\n";
    print "postgres package for details.\n";
    print "\n";
}

if ( ($opt_noninteract) || (yorn (1, "Restart AOLserver now? ")) )
{
    system ("/etc/init.d/aolserver.$main::domain stop");
    system ("/etc/init.d/aolserver.$main::domain start");
}

exit 0;


