#!/usr/bin/perl
# Author: Maik Ernst
# History:
# 2013-09-26 - initial script
#
# LICENSE
# Hitachi, Ltd. All rights reserved
# Hitachi Data Systems products and services can be ordered only under the terms and conditions
# of the applicable Hitachi Data Systems agreements.
#
# NAME
# pptransfer.pl
# Hitachi Confoederatio Helvetica performance package transfer tool
# Part of HiCHperfpkg
# 
#
# SYNOPSIS
# see usage function below
#
# DESCRIPTION
#
# OPTIONS 
# see "usage" function below.
#
# NOTES
#
# AUTHOR
#   Maik Ernst (maik.ernst@hds.com) - September,2013 
#
# MODIFICATIONS
#  2013-09-26 - v1.0	- initial script
#  2013-10-02 - v1.1	- Adding spool directory equal to transfer directory
#						- Adding -e entry
# 2014-01-06 - v1.2		- Changing die-function to be logged in file
#						- Changing ADD_SPOOLLIST_NEW function.
#						NEW: Adding file to spool list txt file AFTER sucessful scp
# 2014-01-06 - v1.3		- Adding -r entry (rotate option)
#						With this entry the data in directory defined with -d will be deleted after specified days.
# 2014-02-20 - v1.4		- Change default ioportal target to ftp.hdsioportal.com
#						- Adding plink.exe command at the beginning of every transfter to make sure not to have keyprint issue
#						This could be the case if different users are starting the transfer
#						- Fixing file to spool list will only be added if exit code of scp is 0 which means sucessful
# 2014-06-17 - v1.5		- Adding multiple suffix support (=> 7zip support)
# 2014-12-26 - v1.6		- Adding log file output
# 2015-04-05 - v1.7		- Adding "log" to suffix list that "scriptlog" dir can be transfered
#						- Adding Sys::Hostname to get hostname of script
# 2015-04-20 - v1.8		- Changing default  $REMOTE_HOST to "ftp.hdsioportal.com"
# 2015-05-01 - v2.0		- Change from parameter to config file => pm file config::tiny needed
#						Adding https via curl as transfer method
#						Changing script name from HDSperftransfer.pl to HCHpptransfer.pl to meet swiss script standard
# 2015-05-01 - v2.1.0	- Reorganize folder structure for HiCHperfpkg according to Swiss development group
#						Log format changed (LOG_MSG)
#						Debuglevel, CURL parameter change
# 2016-03-25 - v2.2.0	- adding LOG->autoflush(1)
# 						- adding pptransfer_proxyoptions
#						- changing CURL syntax to pptransfer_proxyoptions
#						- addicng check HTTPS_PROXYUSER / HTTPS_PROXYPWD (@ and & not allowed)
#						- adding DELETE_OLD_LOGS / log file rotation pptransfer_logkeepdays
# 2016-04-02 - v2.2.1	- Change log output CURL RUN USER PWD  = ***
# 2016-11-19 - v2.3.0	- adding logging module HiCH_LOG, change logging call to have more parameters (e.g. verbose)
#						- update of curl version 7.42 to 7.51
#						  old:
#						  curl 7.42.0 (i386-pc-win32) libcurl/7.42.0 OpenSSL/1.0.2a zlib/1.2.8
#						  Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
#						  Features: AsynchDNS IPv6 Largefile NTLM SSL libz
#						  new:
#						  curl 7.51.0 (i386-pc-win32) libcurl/7.51.0 OpenSSL/1.1.0c zlib/1.2.8 WinIDN libssh2/1.8.0 nghttp2/1.16.1
#						  Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
#						  Features: AsynchDNS IDN IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL libz TLS-SRP HTTP2

use strict;
use warnings;
use POSIX qw(strftime);
use Time::Local;
use File::Find;
use File::Path;
use File::Spec;
use File::Basename;
use Getopt::Long qw(:config no_ignore_case bundling); # Get options /  qw(:config bundling no_ignore_case) makes getopt case sensitive 
use Config;
use Cwd 'abs_path';
use File::Copy qw(copy);
use Sys::Hostname; # To get hostname
use IO::Handle; # required for autoflush

# Use custom/local perl modules lib. FindBin is needed to find the module when running the script from relativ/absolute paths.
use FindBin qw($Bin);
use lib $Bin;
use lib "$Bin\\..\\lib\\modules";
use Config::Tiny;
use HiCH_LOG;

### main ### DO NOT CHANGE ANYTHING IF DO NOT KNOW WHAT YOU ARE DOING!
my $VERSION = "2.3.0";

my $vbse;
my $lglvl = "normal";
my $log_fh;

# Error handling. Change function that a message gets written to log file before dieing.
INIT {$SIG{__DIE__}=sub {LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Script died: $_[0]") and LOG_MSG_CLOSE($log_fh);}}
INIT {$SIG{__WARN__}=sub {LOG_MSG($log_fh,$vbse,"n",$lglvl,4,"GENERAL","Script warning: $_[0]")}}

# Change to directory of the running script
# abs_path for $0 or __FILE__
my ( $script_name, $script_path, $script_suffix ) = fileparse( abs_path($0), qr{\.[^.]*$} );
my $script_dirname = dirname(abs_path($0));
# Change slashes to backslashes
$script_dirname =~ s/\//\\/g;
chdir ($script_dirname);
my $script_rootdir =  dirname ($script_dirname);
my $time_scriptstart = strftime("%Y-%m-%d_%H-%M-%S", localtime);
my $HOST = hostname;

# Check Flags
my $flag_config;
my $flag_help;
my $flag_version;
GetOptions (
	'h|help' => \$flag_help,
	'V|VER' => \$flag_version,
	'v|verbose' => \$vbse,
	'c|config=s' => \$flag_config,
           ) or die USAGE();


# Check flags and print usage
if ($flag_version)
{
	print "$0 Version: $VERSION\n";
	exit;
}

if ($flag_help)
{
	USAGE();
	exit;
}

if (!$flag_config)
{
	print "\n!!! You must define -c <config file>. Example: pptransfer.pl -c pp_54068.conf !!!\n";
    USAGE();
    exit;
}

unless (-e "${script_rootdir}\\etc\\${flag_config}")
{
	print "\n!!! Your with -c defined config file \"${script_rootdir}\\etc\\${flag_config}\" does not exist. !!!\n";
    USAGE();
    exit;
}
$flag_config = "${script_rootdir}\\etc\\${flag_config}";

# Get config
my $conf_file = Config::Tiny->new;
$conf_file = Config::Tiny->read($flag_config);

# Check & set variables for log

if (!$conf_file->{maindir}->{pp_log})
{
	print "\n!!! Variable \"[maindir] pp_log\" is not defined correctly in $flag_config !!!\n";
	exit;
}

my $flag_transfer;
if (!$conf_file->{main}->{pptransfer_sourcedir})
{
	print "\n!!! Variable \"[main] pptransfer_sourcedir\" is not defined correctly in $flag_config !!!\n";
	exit;
}

# If set to default<raid|log|vmio>, then create automatically sourcedir path
if (lc $conf_file->{main}->{pptransfer_sourcedir} eq "defaultraid")
{
	if (!$conf_file->{main}->{ppcollect_serial})
	{
		print "\n!!! \"[main] ppcollect_serial\" is not defined correctly in $flag_config!!!";
		print "\n!!! Therefore \"[main] pptransfer_sourcedir\" can not be set to \"defaultraid\"\n";
		exit;
	} 
	
	elsif (!$conf_file->{zip}->{ppcollect_archivedir})
	{
		print "\n!!! \"[zip] ppcollect_archivedir\" is not defined correctly in $flag_config!!!";
		print "\n!!! Therefore \"[main] pptransfer_sourcedir\" can not be set to \"defaultraid\"\n";
		exit;
	}
	
	elsif (!$conf_file->{maindir}->{pp_data})
	{
		print "\n!!! \"[maindir] pp_data\" is not defined correctly in $flag_config!!!";
		print "\n!!! Therefore \"[main] pptransfer_sourcedir\" can not be set to \"defaultraid\"\n";
		exit;
	}
	
	else
	{
		$flag_transfer = "${script_rootdir}\\$conf_file->{maindir}->{pp_data}\\$conf_file->{zip}->{ppcollect_archivedir}$conf_file->{main}->{ppcollect_serial}";
		unless (-d $flag_transfer)
		{
			print "\n!!! \"[main] pptransfer_sourcedir\" is set to \"defaultraid\" in $flag_config but the default directory does not exist !!!\n";
			print "!!! Directory: $flag_transfer does not exist !!!\n";
			exit;
		}
	}
}
elsif (lc $conf_file->{main}->{pptransfer_sourcedir} eq "defaultlog")
{
	if (!$conf_file->{maindir}->{pp_log})
	{
		print "\n!!! \"[maindir] pp_log\" is not defined correctly in $flag_config!!!";
		print "\n!!! Therefore \"[main] pptransfer_sourcedir\" can not be set to \"defaultlog\"\n";
		exit;
	}
	else
	{
		$flag_transfer = "${script_rootdir}\\$conf_file->{maindir}->{pp_log}";
		unless (-d $flag_transfer)
		{
			print "\n!!! \"[main] pptransfer_sourcedir\" is set to \"defaultlog\" in $flag_config but the default directory does not exist !!!\n";
			print "!!! Directory: $flag_transfer does not exist !!!\n";
			exit;
		}
	}
}
elsif (lc $conf_file->{main}->{pptransfer_sourcedir} eq "defaultvmio")
{
	if (!$conf_file->{maindir}->{pp_data})
	{
		print "\n!!! \"[maindir] pp_data\" is not defined correctly in $flag_config!!!";
		print "\n!!! Therefore \"[main] pptransfer_sourcedir\" can not be set to \"defaultvmio\"\n";
		exit;
	}
	else
	{
		$flag_transfer = "${script_rootdir}\\$conf_file->{maindir}->{pp_data}\\vmiooutput";
		unless (-d $flag_transfer)
		{
			print "\n!!! \"[main] pptransfer_sourcedir\" is set to \"defaultvmio\" in $flag_config but the default directory does not exist !!!\n";
			print "!!! Directory: $flag_transfer does not exist !!!\n";
			exit;
		}
	}
	
}
else
{
	unless (-d $conf_file->{main}->{pptransfer_sourcedir})
	{
		print "\n!!! Source directory defined as \"[main] pptransfer_sourcedir\" in $flag_config does not exist !!!\n";
		print "!!! Directory: $conf_file->{main}->{pptransfer_sourcedir} !!!\n";
		exit;
	}
	$flag_transfer = $conf_file->{main}->{pptransfer_sourcedir};
}

my $scriptdir_log = "${script_rootdir}\\$conf_file->{maindir}->{pp_log}";
my $flag_transfer_base = basename($flag_transfer);
my $SCRIPTLOG_FILE = "${scriptdir_log}\\${script_name}_${flag_transfer_base}_${time_scriptstart}.log";
my $SCRIPTLOG_DEL_PATH = "${scriptdir_log}\\${script_name}_${flag_transfer_base}_*.log";

# Create directories/files
unless (-d $scriptdir_log) { mkpath($scriptdir_log) or die ("Can't create dir $scriptdir_log: $!\n"); }

# Open script logfile
$log_fh = LOG_MSG_OPEN($SCRIPTLOG_FILE);
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Starting Script: \"$0\"");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Version: ${VERSION}");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Logfile: \"$SCRIPTLOG_FILE\"");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Operating system: \"$Config{osname}\"");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Hostname: \"$HOST\"");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Config file: \"$flag_config\"");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Parameters (not checked yet) ..."); 

foreach my $conf_section (sort keys %{$conf_file}) 
{
   LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","[$conf_section]");
    foreach my $conf_parameter (sort keys %{$conf_file->{$conf_section}}) 
	{
		if ($conf_parameter =~ m/pwd/)
		{
			if ($conf_file->{$conf_section}->{$conf_parameter})
			{
				LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\t$conf_parameter = ***");
			}
			else
			{
				LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\t$conf_parameter = $conf_file->{$conf_section}->{$conf_parameter}");
			}
		}	
		else
		{
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\t$conf_parameter = $conf_file->{$conf_section}->{$conf_parameter}");
		}    
	}
}

### Check & set variables for the rest
my $flag_win;
my $flag_method;
# ssh vars
my $PUTTY_PSCP_PATH;
my $PUTTY_PLINK_PATH;
my $REMOTE_HOST;
my $REMOTE_DIR;
my $flag_user;
my $flag_key;
# https vars
my $HTTPS_CURL_PATH;
my $HTTPS_TOKEN;
my $HTTPS_REMOTESERVER;
my $HTTPS_REMOTEPATH;
my $HTTPS_PROXYSERVER;
my $HTTPS_PROXYPORT;
my $HTTPS_PROXYPROTOCOL;
my $HTTPS_PROXYUSER;
my $HTTPS_PROXYPWD;
my $HTTPS_PROXYOPTIONS;
# feature vars
my $flag_entries;
my $flag_rotatedays;
my $flag_logkeepdays;


LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Checking parameter now");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Logdir: $scriptdir_log");
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Sourcedir: $flag_transfer");

if (lc $conf_file->{log}->{pptransfer_loglevel} eq "normal")
{
	$lglvl = lc $conf_file->{log}->{pptransfer_loglevel};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Loglevel: normal");
}

elsif (lc $conf_file->{log}->{pptransfer_loglevel} eq "debug")
{
	$lglvl = lc $conf_file->{log}->{pptransfer_loglevel};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Loglevel: debug");
}

else
{
	LOG_MSG("normal",3,"PARAM","\"[log] pptransfer_loglevel\" is not valid."); 
	LOG_MSG("normal",3,"PARAM","See \"$flag_config\" and check if it is set to \"normal\" or \"debug\".");
	LOG_MSG("normal",3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
	exit;
}

if (!$conf_file->{maindir}->{pp_bin})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[maindir] pp_bin\" is not defined correctly.");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
my $scriptdir_bin = "${script_rootdir}\\$conf_file->{maindir}->{pp_bin}";

if (!$conf_file->{maindir}->{pp_data})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[maindir] pp_data\" is not defined correctly.");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
my $scriptdir_data = "${script_rootdir}\\$conf_file->{maindir}->{pp_data}";

if (!$conf_file->{maindir}->{pp_etc})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[maindir] pp_etc\" is not defined correctly.");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
my $scriptdir_etc = "${script_rootdir}\\$conf_file->{maindir}->{pp_etc}";

if (!$conf_file->{maindir}->{pp_doc})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[maindir] pp_doc\" is not defined correctly.");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
my $scriptdir_doc = "${script_rootdir}\\$conf_file->{maindir}->{pp_doc}";

if (!$conf_file->{maindir}->{pp_lib})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[maindir] pp_lib\" is not defined correctly.");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
my $scriptdir_lib = "${script_rootdir}\\$conf_file->{maindir}->{pp_lib}";

if (!$conf_file->{maindir}->{pp_spool})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[maindir] pp_spool\" is not defined correctly.");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
my $scriptdir_spool = "${script_rootdir}\\$conf_file->{maindir}->{pp_spool}";

unless ((-d $scriptdir_bin) and (-d $scriptdir_data) and (-d $scriptdir_etc) and (-d $scriptdir_doc) and (-d $scriptdir_lib) and (-d $scriptdir_spool) and (-d $scriptdir_log))
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Any of the following directories does not exist...");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_bin");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_data");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_etc");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_doc");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_lib");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_log");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\t$scriptdir_spool");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\tPlease check your directories and/or [maindir] section in config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}


if (lc $conf_file->{main}->{pp_mode} ne "windows")
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[main] pp_mode\" is not supported. Only windows."); 
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
else
{
	if ($Config{osname}=~/Win/)
	{
		$flag_win = 1;
		LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Mode: $conf_file->{main}->{pp_mode}");
	}
	else
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","It looks like your OS it not Windows \"$Config{osname}\". Only windows is not supported."); 
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}
}

# required for log file deletion

if ($conf_file->{main}->{pptransfer_logkeepdays} !~ /^\d+$/)
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[main] pptransfer_logkeepdays\" must be set, a whole number and bigger or equal 0"); 
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","Please check your config \"$flag_config\".");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
    exit;
}
$flag_logkeepdays = $conf_file->{main}->{pptransfer_logkeepdays};
LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Logfile keepdays: $flag_logkeepdays");

## config file ssh

if (lc $conf_file->{main}->{pptransfer_method} eq "ssh")
{
	$flag_method = $conf_file->{main}->{pptransfer_method};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","Method: $flag_method");
	
	unless (-e "${scriptdir_etc}\\$conf_file->{ssh}->{pptransfer_keyfile}")
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","\"[ssh] pptransfer_keyfile\" does not exist. !!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
        exit;
	}
	$flag_key = "${scriptdir_etc}\\$conf_file->{ssh}->{pptransfer_keyfile}";
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","Keyfile: $flag_key");
	
	unless (-e "${scriptdir_bin}\\$conf_file->{ssh}->{pptransfer_pscppath}")
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","\"[ssh] pptransfer_pscppath\" does not exist. !!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
        exit;
	}	
	$PUTTY_PSCP_PATH = "${scriptdir_bin}\\$conf_file->{ssh}->{pptransfer_pscppath}";
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","SSH pscp path: $PUTTY_PSCP_PATH");
	
	unless (-e "${scriptdir_bin}\\$conf_file->{ssh}->{pptransfer_plinkpath}")
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","\"[ssh] pptransfer_plinkpath\" does not exist. !!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
        exit;
	}	
	$PUTTY_PLINK_PATH = "${scriptdir_bin}\\$conf_file->{ssh}->{pptransfer_plinkpath}";
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","SSH plink path: $PUTTY_PLINK_PATH");
	
	if (!$conf_file->{ssh}->{pptransfer_remotehost})
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","\"[ssh] pptransfer_remotehost\" is not defined correctly in $flag_config!!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}
	$REMOTE_HOST = $conf_file->{ssh}->{pptransfer_remotehost};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","Remote host: $REMOTE_HOST");
	
	if (!$conf_file->{ssh}->{pptransfer_remotedir})
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","\"[ssh] pptransfer_remotedir\" is not defined correctly in $flag_config!!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}	
	$REMOTE_DIR = $conf_file->{ssh}->{pptransfer_remotedir};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","Remote dir: $REMOTE_DIR");
	
	if (!$conf_file->{ssh}->{pptransfer_username})
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","\"[ssh] pptransfer_username\" is not defined correctly in $flag_config!!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_SSH","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}	
	$flag_user = $conf_file->{ssh}->{pptransfer_username};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_SSH","SSH username: $flag_user");
	
}

## config file https

elsif (lc $conf_file->{main}->{pptransfer_method} eq "https")
{
	$flag_method = $conf_file->{main}->{pptransfer_method};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","Method: $flag_method");
	
	unless (-e "${scriptdir_bin}\\$conf_file->{https}->{pptransfer_curlpath}")
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","\"[https] pptransfer_curlpath\" does not exist. !!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
        exit;
	}	
	$HTTPS_CURL_PATH = "${scriptdir_bin}\\$conf_file->{https}->{pptransfer_curlpath}";
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","CURL path: $HTTPS_CURL_PATH");
	
	if (!$conf_file->{https}->{pptransfer_token})
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","\"[https] pptransfer_token\" is not defined correctly in $flag_config!!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}	
	$HTTPS_TOKEN = $conf_file->{https}->{pptransfer_token};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","CURL token: $HTTPS_TOKEN");
	
	if (!$conf_file->{https}->{pptransfer_remotepath})
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","\"[https] pptransfer_remotepath\" is not defined correctly in $flag_config!!!");		
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}	
	$HTTPS_REMOTEPATH = $conf_file->{https}->{pptransfer_remotepath};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","CURL remote path: $HTTPS_REMOTEPATH");
	
	if (!$conf_file->{https}->{pptransfer_remoteserver})
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","\"[https] pptransfer_remoteserver\" is not defined correctly in $flag_config!!!");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","Please check your config \"$flag_config\".");
		LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
		LOG_MSG_CLOSE($log_fh);
		exit;
	}	
	$HTTPS_REMOTESERVER = $conf_file->{https}->{pptransfer_remoteserver};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","CURL remote server: $HTTPS_REMOTESERVER");

	if ($conf_file->{https}->{pptransfer_proxyserver})
	{
		$HTTPS_PROXYSERVER = $conf_file->{https}->{pptransfer_proxyserver};
		LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","HTTPS proxyserver: $HTTPS_PROXYSERVER");
		
		if (($conf_file->{https}->{pptransfer_proxyuser}) and ($conf_file->{https}->{pptransfer_proxypwd}))
		{
			$HTTPS_PROXYUSER = $conf_file->{https}->{pptransfer_proxyuser};
			$HTTPS_PROXYPWD = $conf_file->{https}->{pptransfer_proxypwd};
			
			if ($HTTPS_PROXYUSER =~ m/@|&/)
			{
				LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","HTTPS proxyuser: $HTTPS_PROXYUSER. Characters \"@\" and \"&\" are not allowed. Please change.");
				LOG_MSG_CLOSE($log_fh);
				exit;
			}
			elsif ($HTTPS_PROXYPWD =~ m/@|&/)
			{
				LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","HTTPS proxypwd: $HTTPS_PROXYPWD. Characters \"@\" and \"&\" are not allowed. Please change.");
				LOG_MSG_CLOSE($log_fh);
				exit;
			}
			else
			{
				LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","HTTPS proxyuser: $HTTPS_PROXYUSER");
				LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","HTTPS proxypwd: ******");
			}
		}
		elsif ((!$conf_file->{https}->{pptransfer_proxyuser}) and (!$conf_file->{https}->{pptransfer_proxypwd}))
		{
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","\"[https] pptransfer_proxyuser\" is not definied (maybe needed, maybe not)");
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","\"[https] pptransfer_proxypwd\" is not definied (maybe needed, maybe not)");

		}
		else
		{
			LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","Only \"[https] pptransfer_proxypuser\" or \"[https] pptransfer_proxypwd\" is definied. Either none or both must be definied!");
			LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","\"[https] proyxpuser\" = \"$conf_file->{https}->{pptransfer_proxyuser}\"");
			LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM_CURL","\"[https] proxpwd\" = \"$conf_file->{https}->{pptransfer_proxypwd}\"");
			LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
			LOG_MSG_CLOSE($log_fh);
			exit;
		}
		
		if ($conf_file->{https}->{pptransfer_proxyprotocol})
		{
			$HTTPS_PROXYPROTOCOL = $conf_file->{https}->{pptransfer_proxyprotocol};
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","HTTPS proxyprotocol: $HTTPS_PROXYPROTOCOL");
		}
		else
		{
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","\"[https] pptransfer_proxyprotocol\" is not definied (maybe needed, maybe not)");
		}
	
		if ($conf_file->{https}->{pptransfer_proxyport})
		{
			$HTTPS_PROXYPORT = $conf_file->{https}->{pptransfer_proxyport};
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","HTTPS proxy port: $HTTPS_PROXYPORT");
		}
		else
		{
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","\"[https] pptransfer_proxyport\" is not definied (maybe needed, maybe not)");
		}
		
		if ($conf_file->{https}->{pptransfer_proxyoptions})
		{
			$HTTPS_PROXYOPTIONS = $conf_file->{https}->{pptransfer_proxyoptions};
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","HTTPS proxy options: $HTTPS_PROXYOPTIONS");
		}
		else
		{
			LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","\"[https] pptransfer_proxyoptions\" is not definied (maybe needed, maybe not)");
		}
	}
	else
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM_CURL","\"[https] pptransfer_proxyserver\" is not definied (maybe needed, maybe not)");
	}
	
	
}

elsif (lc $conf_file->{main}->{pptransfer_method} eq "off")
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[main] pptransfer_method\" = \"$conf_file->{main}->{pptransfer_method}\". As is set to \"off\" the scripts stops now."); 
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
	exit;
}

else
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[main] pptransfer_method\" is not supported. Only ssh and https."); 
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
	USAGE();
	exit;
}

## config file features

if ($conf_file->{features}->{pptransfer_maxentries})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"[features] pptransfer_maxentries\" is set to \"$conf_file->{features}->{pptransfer_maxentries}\"");
	$flag_entries = $conf_file->{features}->{pptransfer_maxentries};
}
else
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"[features] pptransfer_maxentries\" is set to default \"360\"");
	$flag_entries = 360;
}

if ($conf_file->{features}->{pptransfer_deletefiles})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"[features] pptransfer_deletefiles\" is set to \"$conf_file->{features}->{pptransfer_deletefiles}\". I hope you know what you are doing.");
	$flag_rotatedays = $conf_file->{features}->{pptransfer_deletefiles};
}
else
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"[features] pptransfer_deletefiles\" is set to default \"0\"");
	$flag_rotatedays = 0;
}

## config file spooling

my $SPOOLING_DIR_PREFIX;
my $SPOOLING_DIR;
my $SPOOLING_LIST;
my $SPOOLING_SUFFIX;

if (!$conf_file->{spooling}->{pptransfer_spoolingprefix})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[spooling] pptransfer_spoolingprefix\" is not defined correctly in $flag_config!!!");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
	exit;
}
else
{
	$SPOOLING_DIR_PREFIX = $conf_file->{spooling}->{pptransfer_spoolingprefix};
	$SPOOLING_DIR = "${scriptdir_spool}\\${SPOOLING_DIR_PREFIX}_${flag_transfer_base}";
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"[spooling] spoolingprefix\" is set to \"$conf_file->{spooling}->{pptransfer_spoolingprefix}\"");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"spooling directory\" is set to \"$SPOOLING_DIR\"");
}

if (!$conf_file->{spooling}->{pptransfer_spoolinglistfile})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[spooling] pptransfer_spoolinglistfile\" is not defined correctly in $flag_config!!!");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
	exit;
}
else
{
	$SPOOLING_LIST = "${SPOOLING_DIR}\\$conf_file->{spooling}->{pptransfer_spoolinglistfile}";
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"spooling list path\" is set to \"$SPOOLING_LIST\"");
}

if (!$conf_file->{spooling}->{pptransfer_spoolingsuffix})
{
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"PARAM","\"[spooling] pptransfer_spoolingsuffix\" is not defined correctly in $flag_config!!!");
	LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Finishing Script $0");
	LOG_MSG_CLOSE($log_fh);
	exit;
}
else
{
	$SPOOLING_SUFFIX = $conf_file->{spooling}->{pptransfer_spoolingsuffix};
	LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","\"spooling suffix\" is set to \"$SPOOLING_SUFFIX\"");
}

LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"PARAM","Checking parameter finished");


# Create directories/files
unless (-d $SPOOLING_DIR) { mkpath($SPOOLING_DIR) or die LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Can't create dir $SPOOLING_DIR: $!\n"); }
unless (-e $SPOOLING_LIST) { open(FH,">${SPOOLING_LIST}") or die LOG_MSG($log_fh,$vbse,"n",$lglvl,3,"GENERAL","Can't create $SPOOLING_LIST: $!");close(FH)}


if ($flag_win)
{
	if ($flag_method eq "ssh")
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Transfer method is set to \"$flag_method\"");
		COPY_TO_SPOOL($flag_transfer,$SPOOLING_DIR,$SPOOLING_SUFFIX,$log_fh,$vbse,$lglvl);
		RUN_PLINK($PUTTY_PLINK_PATH,$flag_user,$flag_key,$REMOTE_HOST,$log_fh,$vbse,$lglvl);
		RUN_PSCP($PUTTY_PSCP_PATH,$SPOOLING_DIR,$flag_user,$flag_key,$REMOTE_HOST,$REMOTE_DIR,$SPOOLING_SUFFIX,$SPOOLING_LIST,$log_fh,$vbse,$lglvl);
		CLEAN_SPOOL($SPOOLING_DIR,$SPOOLING_SUFFIX,$log_fh,$vbse,$lglvl);
		CLEAN_SPOOLFILE($SPOOLING_LIST,$flag_entries,$log_fh,$vbse,$lglvl);
	}
	
	if ($flag_method eq "https")
	{
		LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Transfer method is set to \"$flag_method\"");
		COPY_TO_SPOOL($flag_transfer,$SPOOLING_DIR,$SPOOLING_SUFFIX,$log_fh,$vbse,$lglvl);
		RUN_CURL($HTTPS_CURL_PATH,$HTTPS_TOKEN,$HTTPS_REMOTESERVER,$HTTPS_REMOTEPATH,
		$HTTPS_PROXYSERVER,$HTTPS_PROXYPROTOCOL,$HTTPS_PROXYPORT,$HTTPS_PROXYUSER,
		$HTTPS_PROXYPWD,$HTTPS_PROXYOPTIONS,$SPOOLING_SUFFIX,$SPOOLING_LIST,$SPOOLING_DIR,$log_fh,$vbse,$lglvl);
		CLEAN_SPOOL($SPOOLING_DIR,$SPOOLING_SUFFIX,$log_fh,$vbse,$lglvl);
		CLEAN_SPOOLFILE($SPOOLING_LIST,$flag_entries,$log_fh,$vbse,$lglvl);
	} 
	
	unless ($flag_rotatedays == 0)
	{
		DELETE_OLD_SAVES($flag_transfer,$SPOOLING_SUFFIX,$flag_rotatedays,$log_fh,$vbse,$lglvl)
	}
	
	
	unless ($flag_logkeepdays == 0)
	{
		DELETE_OLD_LOGS($flag_logkeepdays,$SCRIPTLOG_DEL_PATH,$log_fh,$vbse,$lglvl);
	}
}


LOG_MSG($log_fh,$vbse,"n",$lglvl,5,"GENERAL","Finishing Script $0");
LOG_MSG_CLOSE($log_fh);


### sub routines ###

sub DELETE_OLD_LOGS
{
	my $par_logkeepdays = $_[0];
	my $par_SCRIPTLOG_DEL_PATH = $_[1];
	my $par_log_fh = $_[2];
	my $par_vbse = $_[3];
	my $par_lglvl = $_[4];
	
	my $now = time();       # get current time
	my $AGE = 60*60*24*$par_logkeepdays;  # convert $par_logkeepdays days into seconds
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLDLOGS","Start deleting log files older than $par_logkeepdays days");
	
	my @fileliste_logs = <${par_SCRIPTLOG_DEL_PATH}>;
	
	foreach my $filename (@fileliste_logs) 
	{
		# If modified time of the file is older then $AGE = days in seconds
		if ($now-(stat $filename)[9] > $AGE)
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLDLOGS","Found the following log file to delete: $filename");
			unlink $filename or warn LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"DELOLDLOGS","Could not delete $filename: $!");
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLDLOGS","Deleted $filename");
		}
	}
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLDLOGS","Deleting log files finished");

}

sub RUN_PLINK
{

	my $par_PUTTY_PLINK_PATH = $_[0];
	my $par_USER = $_[1];
	my $par_KEY = $_[2];
	my $par_REMOTE_HOST = $_[3];
	my $par_log_fh = $_[4];
	my $par_vbse = $_[5];
	my $par_lglvl = $_[6];
	
	my $plink_command;
	if ($par_lglvl eq "debug")
	{
		# This will make sure to update the key if required
		$plink_command ="echo y | $par_PUTTY_PLINK_PATH -v -ssh -i $par_KEY $par_REMOTE_HOST -l $par_USER exit";
	}
	else
	{
		# This will make sure to update the key if required
		$plink_command ="echo y | $par_PUTTY_PLINK_PATH -ssh -i $par_KEY $par_REMOTE_HOST -l $par_USER exit";
	}
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PLINK","Start runing plink to update key fingerprint");
	
	open (CMD_PLINK, "$plink_command 2>&1 |") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"PLINK","Can't run program: $!\n");
	while (my $line = <CMD_PLINK>)
	{
		if ($par_lglvl eq "debug")
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,7,"PLINK","$line");
		}
		else
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PLINK","$line");
		}
	}
	close CMD_PLINK;
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PLINK","Finished updating plink key fingerprint");
}


sub DELETE_OLD_SAVES
{

	my $par_TRANSFER = $_[0];
	my $par_SPOOLING_SUFFIX = $_[1];
	my $par_rotatedays = $_[2];
	my $par_log_fh = $_[3];
	my $par_vbse = $_[4];
	my $par_lglvl = $_[5];
	
	my $now = time();       # get current time
	my $AGE = 60*60*24*$par_rotatedays;  # convert $par_rotatedays days into seconds

	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLD","Start deleting files older than $par_rotatedays days");
	
	# Split suffixes and get files
	my @suffixsplit = split(',', $par_SPOOLING_SUFFIX);
    my @fileliste;
	foreach my $suffix (@suffixsplit)
	{
		# delete white space on the beginning and the end
		$suffix =~ s/\s+|\s+$//g;
		push (@fileliste, <$par_TRANSFER\\*.${suffix}>);
	}

	foreach my $filename (@fileliste) 
	{
		# If modified time of the file is older then $AGE = days in seconds
		if ($now-(stat $filename)[9] > $AGE)
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLD","Found the following file to delete: $filename");
			unlink $filename or warn LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"DELOLD","Could not delete $filename: $!");
		}
	}
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"DELOLD","Finished deleting files older than $par_rotatedays days");
}

sub CLEAN_SPOOLFILE
{
	my $par_SPOOLING_LIST = $_[0];
	my $par_flag_entries = $_[1];
	my $par_log_fh = $_[2];
	my $par_vbse = $_[3];
	my $par_lglvl = $_[4];
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CLNSPOOLFILE","Cleanup spool list (delete old entries): $par_SPOOLING_LIST");
	
	my @spoollist = (); 
	open(SPOOL_LIST,"< $par_SPOOLING_LIST") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"CLNSPOOLFILE","Can't open $par_SPOOLING_LIST: $!\n");
	while (<SPOOL_LIST>) 
	{ 
		chomp $_; 
		push @spoollist, $_;
	} 	
	close SPOOL_LIST;
	
	# Get amount of files listed in $par_SPOOLING_LIST
	my $arraysize_spoollist = @spoollist;
	
	# Check if there are more files in $par_SPOOLING_LIST than entries defined. If yes delete the oldest entry in the array.
	while ($arraysize_spoollist > $par_flag_entries) 
	{
		$arraysize_spoollist--;
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CLNSPOOLFILE","Delete entry: $spoollist[0]");
		shift(@spoollist); 
	}
	
	# Add the remaining entries in the file
	open(SPOOL_LIST,"> $par_SPOOLING_LIST") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"CLNSPOOLFILE","Can't open $par_SPOOLING_LIST: $!\n");
	for my $entry (@spoollist)
	{
		print SPOOL_LIST "$entry\n";
	}
	close SPOOL_LIST;
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CLNSPOOLFILE","Finished cleanup spool list (delete old entries): $par_SPOOLING_LIST");
}

sub CLEAN_SPOOL
{
	my $par_SPOOLING = $_[0];
	my $par_SPOOLING_SUFFIX = $_[1];
	my $par_log_fh = $_[2];
	my $par_vbse = $_[3];
	my $par_lglvl = $_[4];
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CLNSPOOL","Start CLEANUP $par_SPOOLING");
	# Split suffixes and get files
	my @suffixsplit = split(',', $par_SPOOLING_SUFFIX);
    my @spooling_list;
	foreach my $suffix (@suffixsplit)
	{
		# delete white space on the beginning and the end
		$suffix =~ s/\s+|\s+$//g;
		push (@spooling_list, <${par_SPOOLING}\\*.${suffix}>);
	}	
	
	foreach my $file_to_delete (@spooling_list)
	{
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CLNSPOOL","Delete: $file_to_delete");
		unlink $file_to_delete or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"CLNSPOOL","Could not unlink $file_to_delete : $!\n");
	}
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CLNSPOOL","CLEANUP $par_SPOOLING finished");
}

sub ADD_SPOOLLIST_NEW
{
	my $par_SPOOLING_LIST = $_[0];
	my $par_TRANSFER = $_[1];
	my $par_log_fh = $_[2];
	my $par_vbse = $_[3];
	my $par_lglvl = $_[4];
	
	open(SPOOL_LIST,">> $par_SPOOLING_LIST") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"ADDSPOOL","Can't open $par_SPOOLING_LIST: $!\n");
	my $filename = basename($par_TRANSFER);
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"ADDSPOOL","Add entry $filename to $par_SPOOLING_LIST");
	print SPOOL_LIST "$filename\n";
	close SPOOL_LIST;
}

sub CHECK_SPOOLLIST
{
	my $par_SPOOLING_LIST = $_[0];
	my $par_ref_TRANSFER = $_[1];
	my $par_log_fh = $_[2];
	my $par_vbse = $_[3];
	my $par_lglvl = $_[4];
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CHKSPOOL","Check spool list: $par_SPOOLING_LIST");
	
	my @spoollist = (); 
	open(SPOOL_LIST,"< $par_SPOOLING_LIST") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"CHKSPOOL","Can't open $par_SPOOLING_LIST: $!\n");
	while (<SPOOL_LIST>) 
	{ 
		chomp $_; 
		push @spoollist, $_;
	} 	
	close SPOOL_LIST;
	
	# figure out which file already in $par_SPOOLING_LIST comparing with $par_ref_TRANSFER
	my %seen = ();                  # lookup table to test membership of B
	my @transferonly = ();                 # answer
	# build lookup table
	foreach my $file (@spoollist) { $seen{$file} = 1; }
	# find only elements in @$par_ref_TRANSFER and not in @spoollist
	foreach my $file (@$par_ref_TRANSFER) 
	{
		my $file_original = $file;
		my $file = basename($file);
		unless ($seen{$file}) 
		{
			# it's not in %seen, so add to @transferonly
			push(@transferonly, $file_original);
		}
	} 
	
	# overwrite TRANSFER array with files which are only in transfer but not in the $par_SPOOLING_LIST
	@$par_ref_TRANSFER = @transferonly;
	
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CHKSPOOL","Array [\@transferonly] is empty after comparing with $par_SPOOLING_LIST - nothing to transfer") unless grep {defined($_)} @$par_ref_TRANSFER;
	LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CHKSPOOL","Finished check spool list: $par_SPOOLING_LIST");
}

sub COPY_TO_SPOOL
{
	my $par_TRANSFER = $_[0];
	my $par_SPOOLING_DIR = $_[1];
	my $par_SPOOLING_SUFFIX = $_[2];
	my $par_log_fh = $_[3];
	my $par_vbse = $_[4];
	my $par_lglvl = $_[5];
		
	my @suffixsplit = split(',', $par_SPOOLING_SUFFIX);
    my @transfer_list;
	foreach my $suffix (@suffixsplit)
	{
		# delete white space on the beginning and the end
		$suffix =~ s/\s+|\s+$//g;
		push (@transfer_list, <${par_TRANSFER}\\*.${suffix}>);
	}	
	
	CHECK_SPOOLLIST($SPOOLING_LIST,\@transfer_list,$par_log_fh,$par_vbse,$par_lglvl);
	foreach my $file (@transfer_list)
	{
	    my $filename = basename($file);
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CPYSPOOL","Copy $file to $par_SPOOLING_DIR");
		copy ($file, $par_SPOOLING_DIR) or die "Copy failed: $!";
	}
}

sub RUN_PSCP
{
	my $par_PSCP = $_[0];
	my $par_SPOOLING = $_[1];
	my $par_USER = $_[2];
	my $par_KEY = $_[3];
	my $par_REMOTE_HOST = $_[4];
	my $par_REMOTE_DIR = $_[5];
	my $par_SPOOLING_SUFFIX = $_[6];
	my $par_SPOOLING_LIST = $_[7];
	my $par_log_fh = $_[8];
	my $par_vbse = $_[9];
	my $par_lglvl = $_[10];
	
	my @suffixsplit = split(',', $par_SPOOLING_SUFFIX);
    my @spooling_list;
	foreach my $suffix (@suffixsplit)
	{
		# delete white space on the beginning and the end
		$suffix =~ s/\s+|\s+$//g;
		push (@spooling_list, <${par_SPOOLING}\\*.${suffix}>);
	}	
	
	
	foreach my $file_to_transfer (@spooling_list)
	{
		my $PSCP_RUN_1;
		if ($par_lglvl eq "debug")
		{
			$PSCP_RUN_1 = "${par_PSCP} -v -batch -i ${par_KEY} ${file_to_transfer}";
		}
		else
		{
			$PSCP_RUN_1 = "${par_PSCP} -batch -i ${par_KEY} ${file_to_transfer}";
		}
		my $PSCP_RUN_2 = "${par_USER}\@${par_REMOTE_HOST}:${par_REMOTE_DIR}";
		my $PSCP_RUN = "$PSCP_RUN_1 $PSCP_RUN_2";
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PSCP","PSCP command: $PSCP_RUN");
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PSCP","Transfer start");
		open (CMD, "$PSCP_RUN 2>&1|") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"PSCP","Can't run program: $!\n");
			while (my $line = <CMD>)
			{
				if ($par_lglvl eq "debug")
				{
					LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,7,"PSCP","$line");
				}
				else
				{
					LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PSCP","$line");
				}	
			}
		 	close CMD;
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PSCP","Transfer finished");
		my $exit_CMD_PSCP = $?;
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"PSCP","Exit code of pscp: $exit_CMD_PSCP");
		if ($exit_CMD_PSCP == 0)
		{
			ADD_SPOOLLIST_NEW ($par_SPOOLING_LIST,$file_to_transfer,$par_log_fh,$par_vbse,$par_lglvl);
		}
		else 
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"PSCP","Exit code of pscp not 0!");
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"PSCP","Not adding $file_to_transfer to spool_list.");
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"PSCP","That means it will be tried to transfer this file the next time again.");
		}
	}
}

sub RUN_CURL
{
	my $par_HTTPS_CURL_PATH = $_[0];
	my $par_HTTPS_TOKEN = $_[1];
	my $par_HTTPS_REMOTESERVER = $_[2];
	my $par_HTTPS_REMOTEPATH = $_[3];
	my $par_HTTPS_PROXYSERVER = $_[4];
	my $par_HTTPS_PROXYPROTOCOL = $_[5];
	my $par_HTTPS_PROXYPORT = $_[6];
	my $par_HTTPS_PROXYUSER = $_[7];
	my $par_HTTPS_PROXYPWD = $_[8];
	my $par_HTTPS_PROXYOPTIONS = $_[9];
	my $par_SPOOLING_SUFFIX = $_[10];
	my $par_SPOOLING_LIST = $_[11];
	my $par_SPOOLING = $_[12];
	my $par_log_fh = $_[13];
	my $par_vbse = $_[14];
	my $par_lglvl = $_[15];

	my @suffixsplit = split(',', $par_SPOOLING_SUFFIX);
    my @spooling_list;
	foreach my $suffix (@suffixsplit)
	{
		# delete white space on the beginning and the end
		$suffix =~ s/\s+|\s+$//g;
		push (@spooling_list, <${par_SPOOLING}\\*.${suffix}>);
	}	
	
	
	foreach my $file_to_transfer (@spooling_list)
	{
		my $CURL_RUN;
		my $CURL_PROXY_CMD;
		
		# build proxy command for curl
		if ($par_HTTPS_PROXYSERVER)
		{
			if ($par_HTTPS_PROXYPROTOCOL)
			{
				$CURL_PROXY_CMD =  "${par_HTTPS_PROXYPROTOCOL}://";
			}
			
			$CURL_PROXY_CMD =  $CURL_PROXY_CMD . "$par_HTTPS_PROXYSERVER";
			
			if ($par_HTTPS_PROXYPORT)
			{
				$CURL_PROXY_CMD =  $CURL_PROXY_CMD . ":${par_HTTPS_PROXYPORT}";
			}
			
			if (($par_HTTPS_PROXYUSER) and ($par_HTTPS_PROXYPWD))
			{
				$CURL_PROXY_CMD =  $CURL_PROXY_CMD . " --proxy-user \"${par_HTTPS_PROXYUSER}\":\"${par_HTTPS_PROXYPWD}\"";
			}
			
			# OLD # proxy ... -x, --proxy <[protocol://][user:password@]proxyhost[:port]>
			# NEW:    ${par_HTTPS_CURL_PATH} --proxy ${par_HTTPS_PROXYSERVER}:${par_HTTPS_PROXYPORT} --proxy-user \"${par_HTTPS_PROXYUSER}\":\"${par_HTTPS_PROXYPWD}\"";
			my $CURL_RUN_1 = "${par_HTTPS_CURL_PATH} --proxy ${CURL_PROXY_CMD}";
			
			if ($par_HTTPS_PROXYOPTIONS)
			{
				$CURL_RUN_1 = "${par_HTTPS_CURL_PATH} ${par_HTTPS_PROXYOPTIONS} --proxy ${CURL_PROXY_CMD}";
			}
			
			my $CURL_RUN_2;
			if ($par_lglvl eq "debug")
			{
				$CURL_RUN_2 = "-v -k -F file=\@${file_to_transfer} -F id=${par_HTTPS_TOKEN}";
			}
			else 
			{
				$CURL_RUN_2 = "-k -F file=\@${file_to_transfer} -F id=${par_HTTPS_TOKEN}";
			}
			my $CURL_RUN_3 = "https://${par_HTTPS_REMOTESERVER}/${par_HTTPS_REMOTEPATH}";
			$CURL_RUN = "$CURL_RUN_1 $CURL_RUN_2 $CURL_RUN_3";
		
		}
		else
		{
			my $CURL_RUN_1;
			if ($par_lglvl eq "debug")
			{
				$CURL_RUN_1 = "${par_HTTPS_CURL_PATH} -v -k -F file=\@${file_to_transfer} -F id=${par_HTTPS_TOKEN}";
			}
			else 
			{
				$CURL_RUN_1 = "${par_HTTPS_CURL_PATH} -k -F file=\@${file_to_transfer} -F id=${par_HTTPS_TOKEN}";
			}
			my $CURL_RUN_2 = "https://${par_HTTPS_REMOTESERVER}/${par_HTTPS_REMOTEPATH}";
			$CURL_RUN = "$CURL_RUN_1 $CURL_RUN_2";
		}
		
		if ($par_HTTPS_PROXYPWD)
		{
			if ($par_lglvl eq "debug")
			{
				LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","CURL command: $CURL_RUN");
			}
			else 
			{
				my $CURL_RUN_NOPWD = $CURL_RUN;
				$CURL_RUN_NOPWD =~ s/":".*"/":"***"/g;
				LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","CURL command: $CURL_RUN_NOPWD");			
			}
		}
		else
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","CURL command: $CURL_RUN");
		}
		
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","Transfer start");
		open (CMD, "$CURL_RUN 2>&1|") or die LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,3,"CURL","Can't run program: $!\n");
		while (my $line = <CMD>)
		{
			if ($par_lglvl eq "debug")
			{
				LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,7,"CURL","$line");
			}
			else
			{
				LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","$line");
			}
		}
		close CMD;
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","Transfer finished");
		my $exit_CMD_CURL = $?;
		LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,5,"CURL","Exit code of CURL: $exit_CMD_CURL");
		if ($exit_CMD_CURL == 0)
		{
			ADD_SPOOLLIST_NEW ($par_SPOOLING_LIST,$file_to_transfer,$par_log_fh,$par_vbse,$par_lglvl);
		}
		else 
		{
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"CURL","Exit code of CURL not 0!");
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"CURL","Not adding $file_to_transfer to spool_list.");
			LOG_MSG($par_log_fh,$par_vbse,"n",$par_lglvl,4,"CURL","That means it will be tried to transfer this file the next time again.");
		}
	}
}

sub USAGE
{
    	my ($message)=<<'MESSAGE';

NAME HCHpptransfer.pl

SYNOPSIS
     HCHpptransfer.pl -c <configuration file>
     HCHpptransfer.pl [-h] [-v]

DESCRIPTION
     This script transfers the collected export tool data to the HDS ioportal (or any definded location)
	 via ssh or http[s]

REQUIREMENT
     > Install perl (tested with 5.10 and above)
     > Run this script with appropriate privileges! If you are not sure use root or administrator.

OPTIONS
	 
	-c <configuration file>
		Path to configuration file
		Please see the manual (http://loop.hds.com/docs/DOC-45708) for detailed information about configuration settings.
	
	-h
		Show help message.
		
	-v
		Displays the version of the script


FILES
	 $SCRIPT_HOME/HCHpptransfer.pl
	 $SCRIPT_HOME/modules/*
	 $SCRIPT_HOME/putty/*
	 $SCRIPT_HOME/key/*
	 $SCRIPT_HOME/curl/*

EXAMPLES
	HCHpptransfer.pl -h
	HCHpptransfer.pl -v
	HCHpptransfer.pl -c pp_123456.conf
	 
MESSAGE

    	print "Version:${VERSION}\n$message";
}
