package apply;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(save_config apply_config compare_hashes);

#------------------------------------------------------------------------------
# /var/config/www/cgi-bin/apply.pm - save and apply configuration
#
# Creation:     07.07.2005
# Last Update:  $Id$
#
# Copyright (c) 2004-2005  eisfair webconf team
#
# 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.
#------------------------------------------------------------------------------

use strict;
use CGI::Carp qw(fatalsToBrowser);
use webconf_base;

use parse_checkfile;
use renderer_file;
use render_config;

our $VERBOSE;

no strict "subs";
do "conf.pl";
use strict "subs";


sub compare_hashes
{
    my ($old, $new) = @_;
    no warnings;  # silence spurious -w undef complaints
    return 0 if keys(%$old) > keys(%$new);
    while ( my ($key, $value) = each %$new)
    {
        if (! (($key =~ m/^UNDEFINED_/i) || (($new->{"UNDEFINED_$key"}) && ($value eq "")) ))
        {
            return 0  if ($old->{$key} ne $value);
        }
    }
    return 1;
}

sub save_config
{
    my ($package, $astruct, $newconfig) = @_;
    my %oldconfig = get_confvar("/etc/config.d/$package");
    my ($retval, $log) = (0, "");

    ### check if config has changed
    if (compare_hashes(\%oldconfig, $newconfig))
    {
         print "Configuration has not changed!\n";
         return 1;
    }
    else
    {
        print "Configuration has changed.\n" if ($VERBOSE eq "yes");
    }

    ### save config to file
    print "saving config ... " if ($VERBOSE eq "yes");

    my $renderer = create_renderer_file($package, "/var/config/tmp/$package");
    my $old_umask = umask(0077);
    render_config($renderer, $astruct, $newconfig);
    umask($old_umask);

    print "done\n" if ($VERBOSE eq "yes");

    ### syntax-check
    print "checking Options with eischk ...\n" if ($VERBOSE eq "yes");

    my @args = ("/usr/local/bin/eischk",
                "-c", "/var/config/tmp",
                "-x", "/etc/check.d",
                "-l", "/tmp/$package.log",
                "-p", "$package");
    $retval = system(@args);

    if ($retval == 0)
    {
        print "Successfully checked configuration.\n" if ($VERBOSE eq "yes");
    }
    else
    {
        print "\nPlease correct above errors or abort.\n";
        print "Configuration has <b class=\"servform\">not</b> been changed.\n";

        unlink("/var/config/tmp/$package");

        return 1;
    }

    print "Creating backup of old configuration ... " if ($VERBOSE eq "yes");
    $log = `/var/config/www/cgi-bin/config_shlib_wrapper.sh backup_config $package /etc/config.d/$package`;
    print "done\n" if ($VERBOSE eq "yes");

    print "Saving new configuration ... \n";
    $log = `cp -p /var/config/tmp/$package /etc/config.d/$package`;
    print "done\n" if ($VERBOSE eq "yes");

    unlink("/var/config/tmp/$package");

    return 0;
}


sub apply_script
{
    my ($package) = @_;

    if (-f "/var/install/config.d/$package.sh")
    {
        print "Call $package Apply-Script ...\n" if ($VERBOSE eq "yes");
        my $log = `/var/install/config.d/$package.sh`;
        print "$log\n";
        print ".done\n" if ($VERBOSE eq "yes");
    }
    else
    {
        print "no apply-skript found\n" if ($VERBOSE eq "yes");
    }

    return 1;
}

sub init_script
{
    my ($package, $task) = @_;

    if (-f "/etc/init.d/$package")
    {
        my $log = `/etc/init.d/$package $task`;
        print "$log\n";
        print ".done\n" if ($VERBOSE eq "yes");
    }
    else
    {
        print "no init-skript found\n" if ($VERBOSE eq "yes");
    }
}

sub can_start
{
    my ($package) = @_;
    my $startvar="START_" . uc($package);
    my $canstart="no";

    if ($package eq "base" || $package eq "environment")
    {
        $canstart="yes";
    }
    elsif ($package && -f "/etc/config.d/$package" && $startvar)
    {
        open(SOURCE, "</etc/config.d/$package");
        while (<SOURCE>) { $canstart = $2   if (/^$startvar=('|")(yes)('|")/); }
        close(SOURCE);
    }

    print "$startvar is set to \"$canstart\".\n" if ($VERBOSE eq "yes");

    return ($canstart eq "yes");
}

sub apply_config
{
    my ($package, $stopstart) = @_;
    my ($retval, $log) = (0, "");

    print "Applying configuration ... \n" if ($VERBOSE eq "yes");

    if ($stopstart eq "yes")
    {
        print "Stopping service ... \n" if ($VERBOSE eq "yes");
        init_script($package, "stop");

        if ( apply_script($package) && can_start($package) )
        {
            print "Starting service ... \n" if ($VERBOSE eq "yes");
            init_script($package, "start");
        }
    }
    else
    {
        if ( apply_script($package) && can_start($package) )
        {
            print "Restarting service ... \n" if ($VERBOSE eq "yes");
            init_script($package, "restart");
        }
        else
        {
            print "Stopping service ... \n" if ($VERBOSE eq "yes");
            init_script($package, "stop");
        }
    }
}

