#!/usr/bin/perl -w
#
# Zymonic Business Process and Information Management System
# Copyright Zednax Limited 2008 -
# For Authors and Changelog see the subversion history

use strict;

package main;

# Library path
BEGIN
{
    use vars qw($location $script_name $script_location $utils);
    use Zymonic::Utils qw(get_dh_config);
}

# Modules
use Zymonic::Utils;
use IO::Socket;
use Algorithm::FloodControl qw(flood_check);
use Storable qw(thaw nfreeze);
use Data::Dumper;

my $debug = 1;    # Set to 1 for debugging

# Read our error configuration file
Zymonic::Utils::get_dh_config("");

# Incoming clients
my $client;

# Hash will be filled with clients sent data
my %error_msg_hash;

# Our read buffer for the socket
my $read_buf;

# Create socket on the server
my $server = new IO::Socket::INET(
    LocalHost => $Zymonic::Utils::dh_config{'serverhost'},
    LocalPort => $Zymonic::Utils::dh_config{'serverport'},
    Proto     => 'tcp',
    Listen    => 1,
    Reuse     => 1,
);

die "Can't starts server!" unless $server;

#Enter our loop and wait for connections...
while ( $client = $server->accept() )
{

    # A client as connected. Attempt to determin the full length
    if ( read( $client, $read_buf, 4 ) ne 4 )
    {
        error_debug("Can't read packet to determine full read length!");
        next;
    }

    # Unpack our data to determine full read length
    my $length = unpack( "N", $read_buf );

    if ( read( $client, $read_buf, $length ) ne $length )
    {

        error_debug("Can't whole packet length!");
        next;
    }

    # Thaw our received data into a hash - should now
    # be identical to the sent hash.
    %error_msg_hash = %{ thaw($read_buf) };

    # Check we can email/syslog this error via Floodcontrol
    my $rate_type;

    if ( !$error_msg_hash{error} )
    {
        error_debug("Incorrect error event received");
        next;
    }

    my $flood_event = $error_msg_hash{error} . ":" . $error_msg_hash{flag};
    if ( $error_msg_hash{flag} eq 'syslog' )
    {
        $rate_type = $Zymonic::Utils::dh_config{'sysloglimit'};
    }
    elsif ( $error_msg_hash{flag} eq 'email' )
    {
        $rate_type = $Zymonic::Utils::dh_config{'emaillimit'};
    }
    else
    {
        error_debug("Received incorrect type flag");
        next;
    }

    my $flood_result = flood_check( 1, $rate_type, $flood_event );

    if ($flood_result)
    {
        error_debug("Disallowed");
        send_response( "Disallowed", $client );
    }
    else
    {
        error_debug("Allowed");
        send_response( "Allowed", $client );
    }

    # Close the socket
    close($client);
}

sub send_response
{
    my $response      = shift;
    my $client_socket = shift;

    # Response hash
    my %send_response_hash = ( status => '', );

    $send_response_hash{status} = $response;

    my $packet = nfreeze( \%send_response_hash );
    $packet = pack( "N/a*", $packet );
    print $client_socket $packet;
}

sub error_debug
{
    my $message = shift;

    if ($debug)
    {
        print $message . "\n";
    }
}
