#!/usr/bin/perl

# agent polls db for changed attribute values
# pending values are written to wp by WPsetVal.pl
# (c) 2009 alexander.philipp.lintenhofer
#

use strict;
use DBI;
use Proc::Daemon;
use Proc::PID::File;

#####################################################################################################

my @arrACLWrite = ('system','philipp','franziska');

my %MySQLParams = ( 'databasehost' => 'gorm.flake',
                    'database'     => 'wp_monitor',
                    'databaseuser' => 'user',
                    'databasepwd'  => 'password' );

my $logfile      = 'logs/wp_setvald.log';
my $setValScript = 'WPsetVal.pl';

#####################################################################################################

require('WPmemaddr.inc.pl');
require('WPhelperfunctions.inc.pl');

#####################################################################################################
#####################################################################################################
# main
#

MAIN:
{
    Proc::Daemon::Init();
    if (Proc::PID::File->running(dir => '/tmp')) { exit(0); }

    ################################################################################
    open(STDOUT, ">>$logfile")
        || die "failed to re-open STDOUT to $logfile";
    open(STDERR, ">&STDOUT")
        || die "failed to re-open STDERR to STDOUT";

    ################################################################################
    $SIG{INT} = $SIG{TERM} = sub
                {
                    print "stopped at ".localtime().
                          "\n=================================================\n";
                    $::exit = 1
                };

    ################################################################################
    ################################################################################
    print STDOUT "started at ".localtime()." with PID ".$$."\n";
    while (1)
    {
        if (my $dbh = DBI->connect("DBI:mysql:".$MySQLParams{'database'}.":".$MySQLParams{'databasehost'},$MySQLParams{'databaseuser'},$MySQLParams{'databasepwd'}))
        {
            my (%newVals,$outdated);
            my $sth = $dbh->prepare("SELECT id,user,attribute,newval FROM wp_setdata WHERE datetime > 0 AND datetime <= now() AND status='pending' ORDER BY datetime DESC");
            if (!$sth->execute) { print STDERR (localtime().": ".DBI->errstr."\n"); }

            while (my @arrQuery = $sth->fetchrow_array())
            {
                my $currID   = $arrQuery[0];
                my $currUser = $arrQuery[1];
                my $currAttr = $arrQuery[2];
                my $currVal  = $arrQuery[3];

                if (!exists($newVals{$currAttr})) { $newVals{$currAttr} = [$currID,$currVal,$currUser]; }
                else { $outdated .= $currID.','; }
            }

            foreach (sort keys %newVals)
            {
                my $currID   = $newVals{$_}[0];
                my $currAttr = $_;
                my $currVal  = $newVals{$_}[1];
                my $currUser = $newVals{$_}[2];
                my $newStat  = 'success';
                my $cmd_output;

                if(grep $_ eq $currUser, @arrACLWrite)
                {
                    $cmd_output = `$setValScript $currAttr $currVal 2>&1`;
                    my $cmd_retval = ${^CHILD_ERROR_NATIVE}/256;

                    if ($cmd_retval!=0)
                    {
                        print STDERR (localtime().": error setting value $currAttr to $currVal: $cmd_output\n");
                        $newStat = 'fail';
                    }
                    else { print STDOUT (localtime().": successfully set $currAttr to $currVal\n"); }
                }
                else
                {
                    $cmd_output = 'no permission';
                    $newStat    = 'fail';
                }

                $sth = $dbh->prepare("UPDATE wp_setdata SET datetime=now(), status='".$newStat."', WPsetVal_output='".$cmd_output."' WHERE ID=".$currID);
                if (!$sth->execute) { print STDERR (localtime().": ".DBI->errstr."\n"); }
            }

            if (length($outdated)>0)
            {
                chop($outdated);
                $sth = $dbh->prepare("UPDATE wp_setdata SET status='outdated' WHERE ID IN (".$outdated.")");
                if (!$sth->execute) { print STDERR (localtime().": ".DBI->errstr."\n"); }
            }

            $sth->finish;
            $dbh->disconnect;
        }
        else { print STDERR (localtime().": error connecting to database\n"); }

        if ($::exit) { exit;  }
        else         { sleep 67; } # WPpolld sleeps 60'' - avoids interferences
    }
    ################################################################################
    ################################################################################
}

