#!/usr/local/bin/perl 
#
# Name		: libipfc.pl
# 
# Version	: $Header: /cvsroot/ipfc/ipfc/src/lib/libipfc.pl,v 1.8 2002/02/14 10:49:12 adulau Exp $
#
# Purpose	: Library in use for wrapper and other program around the ipfc framework
#      
# Author	: Alexandre Dulaunoy <alex@thinkingsecure.com>

# Copyright (C) 2000,2001 Alexandre Dulaunoy <adulau@thinkingsecure.com>
# Copyright (C) 2001 Conostix S.A. Luxembourg - Alexandre Dulaunoy <adulau@conostix.com>

# 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
#
# 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.
#

## Everybody use somebody...
use POSIX;
use Net::SMTP;
use XML::Simple;
use LWP;
use File::Find;
use MIME::Base64;
$| = 303;
if ( $ENV{IPFCDEBUG} eq "enable" ) { use Data::Dumper; }

### Global declaration 
$ipfc_lib_version     = "cvs ver";
$ipfc_dir             = $ENV{IPFCDIR};
$ipfc_dir_state       = $ipfc_dir . "/state/";
$ipfc_dir_log         = $ipfc_dir . "/logs/";
$ipfc_dir_run         = $ipfc_dir . "/run/";
$ipfc_dir_transac     = $ipfc_dir_run . "/transac/";
$ipfc_dir_transac_out = $ipfc_dir_transac . "/out/";
$ipfc_dir_transac_in  = $ipfc_dir_transac . "/in/";
$ipfc_dir_transac_bad = $ipfc_dir_transac . "/bad/";
$ipfc_dir_cfg         = $ipfc_dir . "/cfg/";
$ipfc_dir_lib         = $ipfc_dir . "/lib/";
$ipfc_path_logfile    = $ipfc_dir_log . "ipfc.logs";
$ipfc_path_state      = $ipfc_dir_state . "state";
$ipfc_path_run        = $ipfc_dir_run . "$0.pid";
$ipfc_path_cfg        = $ipfc_dir_cfg . "ipfc.cfg";
$ipfc_path_cfgsig     = $ipfc_dir_cfg . "sign-keys.xml";
$ipfc_seqid           = 0;
$ipfc_genid           = &ipfc_new_generationid;
my $config;

### IPFC lib use 
if ( $ENV{IPFCDIR} eq "" ) {
    die "No IPFCDIR defined ! please read documentation.";
}
$ipfcsignlib       = $ipfc_dir_lib . "ipfcsign.pm";
$ipfcsignlibconfig = $ipfc_dir_lib . "./ipfcsign-xmlconfig.pm";
require $ipfcsignlibconfig;
require $ipfcsignlib;

sub ipfc_init {
    if ( !($ipfc_dir) ) { &ipfc_going_bad("No ROOT path defined !") }

    if ( !( -e $ipfc_dir_log ) ) {
        mkdir( $ipfc_dir_log, 0700 );
        print "$ipfc_dir_log not existing so I create one";
    }
    if ( !( -e $ipfc_dir_state ) ) {
        mkdir( $ipfc_dir_state, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_state");
    }

    if ( !( -e $ipfc_dir_cfg ) ) {
        mkdir( $ipfc_dir_cfg, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_cfg");
    }
    if ( !( -e $ipfc_dir_run ) ) {
        mkdir( $ipfc_dir_run, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_run");
    }

    if ( !( -e $ipfc_dir_transac ) ) {
        mkdir( $ipfc_dir_transac, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_transac");
    }
    if ( !( -e $ipfc_dir_transac_in ) ) {
        mkdir( $ipfc_dir_transac_in, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_transac_in");
    }
    if ( !( -e $ipfc_dir_transac_out ) ) {
        mkdir( $ipfc_dir_transac_out, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_transac_out");
    }
    if ( !( -e $ipfc_dir_transac_bad ) ) {
        mkdir( $ipfc_dir_transac_bad, 0700 );
        &ipfc_call_log("Creating directory $ipfc_dir_transac_bad");
    }
    if ( -e $ipfc_path_run ) {
        &ipfc_going_bad(
            "PID files exist (another process running ? or pid files to be
	removed in $ipfc_path_run )"
        );
    }
    else {
        open( IPFCPIDFILE, ">$ipfc_path_run" );
        print IPFCPIDFILE $$;
        close(IPFCPIDFILE);
    }

    if ( !( -e $ipfc_path_cfg ) ) {
        &ipfc_going_bad("No configuration file was found in $ipfc_path_cfg");
    }
    if ( !( -e $ipfc_path_cfgsig ) ) {
        &ipfc_going_bad(
            "No signature configuration file was found in $ipfc_path_cfgsig");
    }
    my $ipfc_xml_cfgtree = XMLin($ipfc_path_cfg);

    ## Set global from configuration files
    $ipfc_conf_drserver_ip       = $ipfc_xml_cfgtree->{'drserver'}->{'ip'};
    $ipfc_conf_drserver_root     = $ipfc_xml_cfgtree->{'drserver'}->{'root'};
    $ipfc_conf_drserver_port     = $ipfc_xml_cfgtree->{'drserver'}->{'port'};
    $ipfc_conf_drserver_user     = $ipfc_xml_cfgtree->{'drserver'}->{'user'};
    $ipfc_conf_drserver_password =
      $ipfc_xml_cfgtree->{'drserver'}->{'password'};
    $ipfc_conf_modulename       = $ipfc_xml_cfgtree->{'agent'}->{'name'};
    $ipfc_conf_moduleip         = $ipfc_xml_cfgtree->{'agent'}->{'ip'};
    $ipfc_conf_smtpserver       = $ipfc_xml_cfgtree->{'agent'}->{'smtpserver'};
    $ipfc_conf_sensorid         = $ipfc_xml_cfgtree->{'agent'}->{'id'};
    $ipfc_conf_status_retrytime =
      $ipfc_xml_cfgtree->{'agent'}->{'status'}->{'retrytime'};
    &ipfc_call_log("Retry time is     $ipfc_conf_status_retrytime ");
    $ipfc_conf_encryption =
      $ipfc_xml_cfgtree->{'agent'}->{'encryption'}->{'enable'};

    if ( $ipfc_xml_cfgtree->{'agent'}->{'encryption'}->{'enable'} eq "on" ) {
        &ipfc_call_log("Encryption enable");

        if ( $ipfc_xml_cfgtree->{'agent'}->{'encryption'}->{'type'} eq
            "symmetric" )
        {

            #use Crypt::Rijndael;
            &ipfc_call_log("encryption type : symmetric");

#print length($ipfc_xml_cfgtree->{'agent'}->{'encryption'}->{'key'});
            $cipher =
              new Crypt::Rijndael $ipfc_xml_cfgtree->{'agent'}->{'encryption'}
              ->{'key'}, Crypt::Rijndael::MODE_ECB;
        }
        elsif ( $ipfc_xml_cfgtree->{'agent'}->{'encryption'}->{'type'} eq
            "asymmetric" )
        {
            &ipfc_call_log(
                "encryption type : asymmetric (not yet implemented)");
        }
        else {
            &ipfc_call_log("encryption type : UNKNOW");
        }
    }
    else {
        &ipfc_call_log(
"encryption disable, data will not be encrypted. but will be encrypted in the TLS connection"
        );
    }
}

sub ipfc_going_bad {
    my $ipfcc_text = shift;
    $ipfc_time_to_die = 1;
    die "$ipfcc_text";
}

sub ipfc_going_daemon {
    my $pid;
    $pid = fork;
    exit if $pid;
    die "ipfc_going_daemon : Couldn't fork : $!" unless defined($pid);
    POSIX::setsid() or die "ipfc_going_daemon : Can't start a new session: $!";
    $ipfc_time_to_die = 0;
    $SIG{INT}  = \&ipfc_catch_signal_term;
    $SIG{TERM} = \&ipfc_catch_signal_term;
    $SIG{HUP}  = \&ipfc_catch_signal_hup;
    &ipfc_call_log("Going Daemon with PID $$");

    ## Update PID files (needed for the controller)
    open( IPFCPIDFILE, ">$ipfc_path_run" );
    print IPFCPIDFILE $$;
    close(IPFCPIDFILE);

    return $$;

}

sub ipfc_catch_signal_term {
    $ipfc_time_to_die = 1;
    if ( -e $ipfc_path_run ) { unlink($ipfc_path_run); }
    &ipfc_call_log("Going down by SIG TERM/INT ");
}

sub ipfc_catch_signal_hup {
    &ipfc_call_log("Going reload by SIG HUP ");
}

sub ipfc_gen_transacid {
    my $transacid, $day, $month, $year, $hour, $minute, $second;
    if ( defined($ipfc_current_transacid) ) {
        $ipfc_last_transacid = $ipfc_current_transacid;
    }
    open( IPFCCSTATE, "$ipfc_path_state" );
    $state = <IPFCCSTATE>;
    close(IPFCCSTATE);
    $state = $state + 1;
    if ( $state eq "32000" ) { $state = "1"; }
    open( IPFCCSTATE, ">$ipfc_path_state" );
    print IPFCCSTATE $state;
    close(IPFCCSTATE);
    if    ( $state < 10 )    { $state = "0000" . $state; }
    elsif ( $state < 100 )   { $state = "000" . $state; }
    elsif ( $state < 1000 )  { $state = "00" . $state; }
    elsif ( $state < 10000 ) { $state = "0" . $state; }
    ( $second, $minute, $hour, $day, $month, $year ) =
      (localtime)[ 0, 1, 2, 3, 4, 5 ];
    $month = $month + 1;
    $year  = $year + 1900;
    if ( $day < 10 )    { $day    = "0" . $day; }
    if ( $minute < 10 ) { $minute = "0" . $minute; }
    if ( $hour < 10 )   { $hour   = "0" . $hour; }
    if ( $second < 10 ) { $second = "0" . $second; }
    if ( $month < 10 )  { $month  = "0" . $month; }
    $transacid = $year . $month . $day . $hour . $minute . $second . $state;
    $ipfc_current_transacid = $transacid;
    return $transacid;
}

sub ipfc_get_date {
    my $date, $day, $month, $year, $hour, $minute, $second;
    ( $second, $minute, $hour, $day, $month, $year ) =
      (localtime)[ 0, 1, 2, 3, 4, 5 ];
    $year  = $year + 1900;
    $month = $month + 1;
    if ( $minute < 10 ) { $minute = "0" . $minute; }
    if ( $hour < 10 )   { $hour   = "0" . $hour; }
    if ( $second < 10 ) { $second = "0" . $second; }
    $date =
      $year . "-" . $month . "-" . $day . " " . $hour . ":" . $minute . ":"
      . "$second";
    return $date;
}

sub ipfc_call_log {
    my $ipfcc_text = shift;
    open( RUNFL, ">>$ipfc_path_logfile" );
    print RUNFL $0 . "[" . $$. "] : " . $ipfcc_text . "\n";
    close(RUNFL);

}

sub ipfc_send_mail {

    ## Based upon lstein@lsjs.org mail function

    my ( $msg, $server ) = @_;

    if ( $server eq "" ) { $server = $ipfc_conf_smtpserver; }

    # parse the message to get sender and recipient
    my ( $header, $body ) = split /\n\n/, $msg, 2;
    return &ipfc_call_log("ipfc_send_mail: no header") unless $header && $body;

    # fold continuation lines
    $header =~ s/\n\s+/ /gm;

    # parse fields
    my (%fields) = $header =~ /([\w-]+):\s+(.+)$/mg;
    my $from = $fields{From} or return &ipfc_call_log( "ipfc_send_mail:
	no From field"
    );
    my @to = split /\s*,\s*/, $fields{To} or return &ipfc_call_log(
        "ipfc_send_mail:
	To field"
    );
    push @to, split /\s*,\s*/, $fields{Cc} if $fields{Cc};

    # open server
    my $smtp = Net::SMTP->new($server)
      or return &ipfc_call_log( "ipfc_send_mail:
	couldn't smtp server"
    );
    $smtp->mail($from) or return warn $smtp->message;
    my @ok = $smtp->recipient( @to, { SkipBad => 1 } )
      or return warn $smtp->message;
    &ipfc_call_log( $smtp->message ) unless @ok == @to;
    $smtp->data($msg) or return warn $smtp->message;
    $smtp->quit;

}

sub ipfc_gen_xml {
    my (
        $ipfc_type,     $ipfc_data,             $ipfc_transacid,
        $ipfc_category, $ipfc_category_version, $ipfc_agentid,
        $ipfc_type2
      )
      = @_;

    my ( $ipfc_xml_generated, $ipfc_xml, @entry, $cpt, $entry_line );

    ## Setting default value if not defined 	
    if ( !( defined($ipfc_type) ) ) { $ipfc_type = "status"; }
    if ( !( defined($ipfc_transacid) ) ) {
        $ipfc_transacid = $ipfc_current_transacid;
    }
    if ( !( defined($ipfc_category) ) ) { $ipfc_category = "syslog-line"; }
    if ( !( defined($ipfc_category_version) ) ) { $ipfc_category_version = 1; }

    ## Building document
    $ipfc_xml->{'version'}      = "1";
    $ipfc_xml->{'type'}         = $ipfc_type;
    $ipfc_xml->{'transacid'}    = $ipfc_transacid;
    $ipfc_xml->{'sequenceid'}   = &ipfc_new_sequenceid;
    $ipfc_xml->{'generationid'} = $ipfc_genid;
    $ipfc_xml->{'drserver'};
    $ipfc_xml->{'drserver'}->{'ip'}  = $ipfc_conf_drserver_ip;
    $ipfc_xml->{'drserver'}->{'uri'} =
      $ipfc_conf_drserver_root . "/" . $ipfc_conf_modulename . "/" . $ipfc_type
      . "/";

    $ipfc_xml->{'agent'};
    $ipfc_xml->{'agent'}->{'name'} = $ipfc_conf_modulename;
    $ipfc_xml->{'agent'}->{'ip'}   = $ipfc_conf_moduleip;
    if ( $ipfc_agentid eq "" ) {
        $ipfc_xml->{'agent'}->{'id'} = $ipfc_conf_sensorid;
    }
    else {
        $ipfc_xml->{'agent'}->{'id'} = $ipfc_agentid;
    }
    $ipfc_xml->{'agent'}->{'date'} = &ipfc_get_date;
    if ( $ipfc_type2 eq "events" ) {

        $ipfc_xml->{'data'};
        $ipfc_xml->{'data'}->{'entry'}[0];
        $ipfc_xml->{'data'}->{'entry'}[0]->{'type'}     = $ipfc_type2;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'category'} = $ipfc_category;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'version'} = $ipfc_category_version;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'content'};

        if ( $ipfc_category eq "syslog-line" ) {
            @entry = split ( /\n/, $ipfc_data );
            foreach $entry_line (@entry) {
                $ipfc_xml->{'data'}->{'entry'}[0]
                  ->{'content'}->{$ipfc_category}[$cpt] = $entry_line;
                $cpt++;
            }

        }
    }
    elsif ( $ipfc_type2 eq "log" ) {
        $ipfc_xml->{'data'};
        $ipfc_xml->{'data'}->{'entry'}[0];
        $ipfc_xml->{'data'}->{'entry'}[0]->{'type'}     = $ipfc_type2;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'category'} = $ipfc_category;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'version'} = $ipfc_category_version;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'content'};

        if ( $ipfc_category eq "common-log" ) {
            @entry = split ( /\n/, $ipfc_data );
            foreach $entry_line (@entry) {
                $ipfc_xml->{'data'}->{'entry'}[0]
                  ->{'content'}->{'apache-line'}[$cpt] = $entry_line;
                $cpt++;
            }
        }

        if ( $ipfc_category eq "error-log" ) {
            @entry = split ( /\n/, $ipfc_data );

            foreach $entry_line (@entry) {
                $eentry_line = encode_base64($entry_line);
                $ipfc_xml->{'data'}->{'entry'}[0]
                  ->{'content'}->{'apache-line'}[$cpt]->{'attr'}->{'format'} =
                  "base64";
                $ipfc_xml->{'data'}->{'entry'}[0]
                  ->{'content'}->{'apache-line'}[$cpt] = $eentry_line;

                $cpt++;

            }
        }
    }

    elsif ( $ipfc_type eq "status" ) {
        $ipfc_xml->{'data'};
        $ipfc_xml->{'data'}->{'entry'}[0];
        $ipfc_xml->{'data'}->{'entry'}[0]->{'type'}    = $ipfc_type;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'version'} = $ipfc_category_version;
        $ipfc_xml->{'data'}->{'entry'}[0]->{'category'}  = "availability";
        $ipfc_xml->{'data'}->{'entry'}[0]->{'retrytime'} =
          $ipfc_conf_status_retrytime;
    }

    $ipfc_xml_generated =
      XMLout( $ipfc_xml, rootname => "ipfc", xmldecl => 1, noattr => 1 );

    $ipfc_path_transac =
      $ipfc_dir_transac_out . $ipfc_xml->{'transacid'} . ".xml";
    open( IPFCTRANSAC, ">$ipfc_path_transac" );
    print IPFCTRANSAC $ipfc_xml_generated;
    close(IPFCTRANSAC);
    $ipfc_path_transacok = $ipfc_path_transac . ".ok";
    open( IPFCTRANSACOK, ">$ipfc_path_transacok" );
    print IPFCTRANSACOK "ok";
    close(IPFCTRANSACOK);
    return $ipfc_xml_generated;
}

sub IpfcGenMessage {

    my (
        $IpfcData,          $IpfcAgentID,  $IpfcWrapperID,
        $IpfcType,          $IpfcDataType, $IpfcDataSubType,
        $IpfcDataTransport, $IpfcKeyID
      )
      = @_;

    my ( $IpfcXMLStream, $IpfcTransacid );
    $IpfcTransacid = &ipfc_gen_transacid;
    $IpfcXMLStream = "<?xml version='1' standalone='yes'?>\n";
    $IpfcXMLStream .= "<ipfc version=\"1\" type=";
    if ( $IpfcType eq "" ) { $IpfcType = "status"; }
    $IpfcXMLStream .= "\"" . $IpfcType . "\">\n";

    ### XML Document Start Data part
    $IpfcXMLStream .= "<data";
    $IpfcXMLStream .= " version=\"1\"";
    if ( $IpfcDataType eq "" ) { $IpfcDataType = "status"; }
    $IpfcXMLStream .= " type=\"$IpfcDataType\"";
    if ( $IpfcDataSubType eq "" ) { $IpfcDataSubType = "availability"; }
    $IpfcXMLStream .= " subtype=\"$IpfcDataSubType\"";
    if ( $IpfcDataTransport eq "" ) { $IpfcDataTransport = "null"; }
    $IpfcXMLStream .= " transport=\"$IpfcDataTransport\"";
    $IpfcXMLStream .= ">\n";

    if ( !( $IpfcDataType eq "status" ) ) {

        if ( !( $IpfcDataTransport eq "null" ) ) {
            @entry = split ( /\n/, $IpfcData );
            foreach $entry_line (@entry) {
                $IpfcXMLStream .= "<$IpfcDataTransport format=\"base64\">";
                $IpfcXMLStream .= encode_base64($entry_line);
                $IpfcXMLStream .= "</$IpfcDataTransport>\n";
            }
        }
        else {
            $IpfcXMLStream .= $IpfcData . "\n";
        }
    }
    elsif ( $IpfcDataType eq "status" ) {
        if ( $IpfcDataSubType eq "availability" ) {
            $IpfcXMLStream .=
              "<retrytime>$ipfc_conf_status_retrytime</retrytime>\n";
        }

### We assume that the data is xml format for a special non-defined datasubtype.
        else {

            $IpfcXMLStream .= $IpfcData . "\n";
        }

### TODO Must put a method add additional parameter to status (like disk free, memory used...)
    }

    $IpfcXMLStream .= "</data>\n";

    ### XML Document End Data part

    ### XML Document Start Agent part 

    $IpfcGetDateReturn = &ipfc_get_date;
    $IpfcXMLStream .= "<agent date=\"" . $IpfcGetDateReturn . "\"";
    if ( $IpfcAgentID eq "" )   { $IpfcAgentID   = $ipfc_conf_sensorid; }
    if ( $IpfcWrapperID eq "" ) { $IpfcWrapperID = "0"; }

    $IpfcXMLStream .= " id=\"$IpfcAgentID\"";
    $IpfcXMLStream .= " wrapperid=\"" . $IpfcWrapperID . "\"";
    $IpfcXMLStream .= " generationid=\"$ipfc_genid\"";
    $IpfcGetSeqReturn = &ipfc_new_sequenceid;
    $IpfcXMLStream .= " sequenceid=\"$IpfcGetSeqReturn\"";
    $IpfcXMLStream .= " transacid=\"$IpfcTransacid\" />\n";

    ### End Agent Part
    $IpfcXMLStream .= "</ipfc>\n";

    if ( $IpfcKeyID eq "" ) { $IpfcKeyID = "none"; }

    IPFC::Sign::set_config(
        IPFC::Sign::Xmlconfig::read_config($ipfc_path_cfgsig) );

    $IpfcXMLStreamSigned =
      IPFC::Sign::sign_message( $IpfcXMLStream, $IpfcKeyID );

    $IpfcPathTransac = $ipfc_dir_transac_out . $IpfcTransacid . ".xml";
    open( IPFCTRANSAC, ">$IpfcPathTransac" );
    print IPFCTRANSAC $IpfcXMLStreamSigned;
    close(IPFCTRANSAC);
    $IpfcPathTransacOk = $IpfcPathTransac . ".ok";
    open( IPFCTRANSACOK, ">$IpfcPathTransacOk" );
    print IPFCTRANSACOK "ok";
    close(IPFCTRANSACOK);
    return $IpfcXMLStream;

}

sub IpfcPutDrserver {

    my $IpfcTransacidToPut = shift;
    my (
        $XmlFile,      $XmlFileOk, $xml_content, $ipfc_ua,
        $ipfc_request, $url,       $ipfc_res
    );
    $XmlFile = $ipfc_dir_transac_out . $IpfcTransacidToPut . ".xml";
    $XmlFile =~ s/\/\//\//g;
    open( FILETOPUT, "$XmlFile" );
    while (<FILETOPUT>) {
        if (/^<ipfc version=/) {
            if (/status/) { $XmlTypeIs = "status"; }
            if (/events/) { $XmlTypeIs = "events"; }
            if (/logs/)   { $XmlTypeIs = "logs"; }
        }
    }
    close(FILETOPUT);
    my $url =
      "http://" . $ipfc_conf_drserver_ip . ":" . $ipfc_conf_drserver_port . "/"
      . $ipfc_conf_drserver_root . "/" . $ipfc_conf_modulename . "/"
      . $XmlTypeIs . "/" . $IpfcTransacidToPut . "." . $XmlTypeIs;
    &ipfc_call_log("IpfcPutDrserver::URL is $url");

    $ipfc_ua = new LWP::UserAgent( keep_alive => 1 );
    $ipfc_ua->agent( "IPFC genwarp " . $ipfc_lib_version );
    $ipfc_ua->from("ipfc-test\@perycles.unix.be.EU.org");
    $ipfc_request = new HTTP::Request PUT => $url;
    $ipfc_request->authorization_basic( $ipfc_conf_drserver_user,
        $ipfc_conf_drserver_password );
    open( LOCALCURRENT, "$XmlFile" );
    while (<LOCALCURRENT>) { $xml_content = $xml_content . $_; }
    close(LOCALCURRENT);
    $ipfc_request->content($xml_content);

    my $ipfc_res = $ipfc_ua->request($ipfc_request);

    if ( $ipfc_res->is_success ) {

        $url = $url . ".ok";
        my $ipfc_request = new HTTP::Request PUT => $url;
        $ipfc_request->authorization_basic( $ipfc_conf_drserver_user,
            $ipfc_conf_drserver_password );
        $ipfc_request->content("");
        my $ipfc_res = $ipfc_ua->request($ipfc_request);
        $ipfc_put_status = 1;
        unlink($XmlFile);
        $XmlFileOk = $XmlFile . ".ok";
        unlink($XmlFileOk);
        &ipfc_call_log(
            "PutDrserver: Success for Transacid : $ipfc_transac_toput");
    }
    else {

        $ipfc_put_status = 0;
        &ipfc_call_log(
"PutDrserver: Error for Transacid : $ipfc_transac_toput because of $ipfc_res->message"
        );
    }

    return $ipfc_put_status;

}

sub IpfcFlushQueue {

    opendir( LDIR, $ipfc_dir_transac_out )
      or &ipfc_call_log("put_drserver_all : can't go to dir transac");
    while ( defined( $ipfc_file = readdir(LDIR) ) ) {
        if ( !( $ipfc_file =~ m/ok/ ) ) {

            #&ipfc_call_log("DEBUG : $ipfc_file_ok -- $ipfc_file");
            $ipfc_file_ok = $ipfc_file . ".ok";
            $ipfc_file =~ s/.xml//g;
            $ipfc_file_ok = $ipfc_dir_transac_out . $ipfc_file_ok;

            $transacid = $ipfc_file;
            if ( ( $transacid > 1 ) && ( -e $ipfc_file_ok ) ) {
                &IpfcPutDrserver($transacid);

            }
        }
    }
    closedir(LDIR);
}

sub ipfc_put_drserver {
    my $ipfc_transac_toput = shift;

    my (
        $ipfc_request, $ipfc_ua,       $ipfc_put_status,
        $xs,           $ipfc_xml_tree, $xml_content
    );
    if ( $ipfc_transac_toput == 0 ) {
        $ipfc_transac_toput = $ipfc_current_transacid;
    }
    $xml_file = $ipfc_dir_transac_out . $ipfc_transac_toput . ".xml";
    $xml_file =~ s/\/\//\//g;

    $ip = XMLin($xml_file);

    $ipfc_ua = new LWP::UserAgent( keep_alive => 1 );
    $ipfc_ua->agent( "IPFC genwarp " . $ipfc_lib_version );
    $ipfc_ua->from("Wrapper name:");

    my $temp_url =
      "http://" . $ip->{'drserver'}->{'ip'} . ":" . $ipfc_conf_drserver_port
      . "/" . $ip->{'drserver'}->{'uri'} . $ipfc_transac_toput . "."
      . $ip->{'type'};

    &ipfc_call_log("PutDrserver: URL -> $temp_url");

    $ipfc_request = new HTTP::Request PUT => $temp_url;
    $ipfc_request->authorization_basic( $ipfc_conf_drserver_user,
        $ipfc_conf_drserver_password );

    open( LOCALCURRENT, "$xml_file" );
    while (<LOCALCURRENT>) { $xml_content = $xml_content . $_; }
    close(LOCALCURRENT);

    if ( $ipfc_conf_encryption eq "on" ) {
        my $lengthvar = length($xml_content);

        ## padding with null bytes.
        while ( $lengthvar % 16 != 0 ) {
            $xml_content .= "\0";
            $lengthvar++;

        }
        $xml_content_local = $cipher->encrypt($xml_content);

        #print      $cipher->decrypt($xml_content_local);

    }
    else {
        $xml_content_local = $xml_content;
    }
    $ipfc_request->content($xml_content_local);

    my $ipfc_res = $ipfc_ua->request($ipfc_request);

    if ( $ipfc_res->is_success ) {

        $temp_url = $temp_url . ".ok";
        my $ipfc_request = new HTTP::Request PUT => $temp_url;
        $ipfc_request->authorization_basic( $ipfc_conf_drserver_user,
            $ipfc_conf_drserver_password );
        $ipfc_request->content("");
        my $ipfc_res = $ipfc_ua->request($ipfc_request);
        $ipfc_put_status = 1;
        unlink($xml_file);
        $xml_file_ok = $xml_file . ".ok";
        unlink($xml_file_ok);
        &ipfc_call_log(
            "PutDrserver: Success for Transacid : $ipfc_transac_toput");
    }
    else {

        $ipfc_put_status = 0;
        &ipfc_call_log(
"PutDrserver: Error for Transacid : $ipfc_transac_toput because of $ipfc_res->message"
        );
    }

    return $ipfc_put_status;

}

sub ipfc_put_drserver_waiting {

    opendir( LDIR, $ipfc_dir_transac_out )
      or &ipfc_call_log("put_drserver_all : can't go to dir transac");
    while ( defined( $ipfc_file = readdir(LDIR) ) ) {
        if ( !( $ipfc_file =~ m/ok/ ) ) {

            #&ipfc_call_log("DEBUG : $ipfc_file_ok -- $ipfc_file");
            $ipfc_file_ok = $ipfc_file . ".ok";
            $ipfc_file =~ s/.xml//g;
            $ipfc_file_ok = $ipfc_dir_transac_out . $ipfc_file_ok;

            $transacid = $ipfc_file;
            if ( ( $transacid > 1 ) && ( -e $ipfc_file_ok ) ) {
                &ipfc_put_drserver($transacid);

            }
        }
    }
    closedir(LDIR);
}

## Generation is only generated at the startup of the wrapper 

sub ipfc_new_generationid {
    my $GeneratedID;
    my $date, $day, $month, $year, $hour, $minute, $second;
    ( $second, $minute, $hour, $day, $month, $year ) =
      (localtime)[ 0, 1, 2, 3, 4, 5 ];
    $year        = $year + 1900;
    $month       = $month + 1;
    $GeneratedID =
      $year . "-" . $month . "-" . $day . " " . $hour . ":" . $minute . ":"
      . "$second";

    return $GeneratedID;
}

## Generation is generated for each transaction from 0 (startup of the script)  
sub ipfc_new_sequenceid {
    my $sequenceID;
    $sequenceID = $ipfc_seqid;
    $sequenceID = $sequenceID + 1;
    $ipfc_seqid = $sequenceID;
    return $sequenceID;
}

sub ipfc_get_drserver {

}

sub ipfc_send_smtpalert {

    my ( $msg_body, $server ) = @_;

    if ( $server eq "" ) { $server = $ipfc_conf_smtpserver; }

    my $msg = "From: ipfc@" . $ipfc_conf_modulename . "\n";
    my $msg .= "\n" . $msg_body;

    my $state;

    return $state;
}

## From char to ascii code

sub ipfc_ctoa {
    my ($char) = @_;
    my $ConvTmp = unpack( "C*", $char );
    return $ConvTmp;
}

## From ascii code to char

sub ipfc_atoc {
    my ($char) = @_;
    my $ConvTmp2 = pack( "C*", $char );
    return $ConvTmp2;
}

1;

