Przeglądaj źródła

First Commit Windows Agent

Andre 12 lat temu
commit
2ebe78f96e

+ 22 - 0
.gitattributes

@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs     diff=csharp
+*.sln    merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc	 diff=astextplain
+*.DOC	 diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot  diff=astextplain
+*.DOT  diff=astextplain
+*.pdf  diff=astextplain
+*.PDF	 diff=astextplain
+*.rtf	 diff=astextplain
+*.RTF	 diff=astextplain

+ 215 - 0
.gitignore

@@ -0,0 +1,215 @@
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+#############
+## Windows detritus
+#############
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac crap
+.DS_Store
+
+
+#############
+## Python
+#############
+
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist/
+build/
+eggs/
+parts/
+var/
+sdist/
+develop-eggs/
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg

+ 2190 - 0
OGP/ogp_agent.pl

@@ -0,0 +1,2190 @@
+#!/usr/bin/perl
+#
+# OGP - Open Game Panel
+# Copyright (C) Copyright (C) 2008 - 2013 The OGP Development Team
+#
+# http://www.opengamepanel.org/
+#
+# 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 any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+use warnings;
+use strict;
+
+use Frontier::Daemon::Forking;	# Forking XML-RPC server
+use File::Copy;				   # Simple file copy functions
+use File::Copy::Recursive
+  qw(fcopy rcopy dircopy fmove rmove dirmove pathempty pathrmdir)
+  ;							   # Used to copy whole directories
+use Crypt::XXTEA;	# Encryption between webpages and agent.
+use Cfg::Config;	 # Config file
+use Cfg::Preferences;   # Preferences file
+use Fcntl ':flock';  # Import LOCK_* constants for file locking
+use Cwd;			 # Fast way to get the current directory
+use LWP::Simple;	 # Used for fetching URLs
+use MIME::Base64;	# Used to ensure data travelling right through the network.
+use Getopt::Long;	# Used for command line params.
+use Path::Class::File;	# Used to handle files and directories.
+use File::Path qw(mkpath);
+use Archive::Extract;	 # Used to handle archived files.
+use File::Find;
+
+# Current location of the agent.
+use constant AGENT_RUN_DIR => getcwd();
+
+# Load our config file values
+use constant AGENT_KEY	  => $Cfg::Config{key};
+use constant AGENT_IP	   => $Cfg::Config{listen_ip};
+use constant AGENT_LOG_FILE => $Cfg::Config{logfile};
+use constant AGENT_PORT	 => $Cfg::Config{listen_port};
+use constant AGENT_VERSION  => $Cfg::Config{version};
+use constant SCREEN_LOG_LOCAL  => $Cfg::Preferences{screen_log_local};
+use constant DELETE_LOGS_AFTER  => $Cfg::Preferences{delete_logs_after};
+use constant AGENT_PID_FILE =>
+  Path::Class::File->new(AGENT_RUN_DIR, 'ogp_agent.pid');
+
+use constant GAME_AGENT_STARTUP_PID => 'ogp_game_agent_startup.pid';
+
+use constant STEAM_LICENSE_OK => "Accept";
+use constant STEAM_LICENSE	=> $Cfg::Config{steam_license};
+use constant MANUAL_TMP_DIR   => Path::Class::Dir->new(AGENT_RUN_DIR, 'tmp');
+use constant STEAM_CLIENT_DIR => Path::Class::Dir->new(AGENT_RUN_DIR, 'steamc');
+use constant STEAM_CLIENT_BIN =>
+  Path::Class::File->new(STEAM_CLIENT_DIR, 'HldsUpdateTool.exe');
+use constant STEAMCMD_CLIENT_DIR => Path::Class::Dir->new(AGENT_RUN_DIR, 'steamcmd');
+use constant STEAMCMD_CLIENT_BIN =>
+  Path::Class::File->new(STEAMCMD_CLIENT_DIR, 'steamcmd.exe');
+use constant SCREEN_LOGS_DIR =>
+  Path::Class::Dir->new(AGENT_RUN_DIR, 'screenlogs');
+use constant GAME_STARTUP_DIR =>
+  Path::Class::Dir->new(AGENT_RUN_DIR, 'startups');
+
+use constant SCREENRC_FILE =>
+  Path::Class::File->new(AGENT_RUN_DIR, 'ogp_screenrc');
+
+use constant SCREEN_TYPE_HOME   => "HOME";
+use constant SCREEN_TYPE_UPDATE => "UPDATE";
+
+my $no_startups	= 0;
+my $clear_startups = 0;
+our $log_std_out = 0;
+
+GetOptions(
+		   'no-startups'	=> \$no_startups,
+		   'clear-startups' => \$clear_startups,
+		   'log-stdout'	 => \$log_std_out
+		  );
+
+# Starting the agent as root user is not supported anymore.
+if ($< == 0)
+{
+	print "ERROR: You are trying to start the agent as root user.";
+	print "This is not currently supported. If you wish to start the";
+	print "you need to create a normal user account for it.";
+	exit 1;
+}
+
+### Logger function.
+### @param line the line that is put to the log file.
+sub logger
+{
+	my $logcmd	 = $_[0];
+	my $also_print = 0;
+
+	if (@_ == 2)
+	{
+		($also_print) = $_[1];
+	}
+
+	$logcmd = localtime() . " $logcmd\n";
+
+	if ($log_std_out == 1)
+	{
+		print "$logcmd";
+		return;
+	}
+	if ($also_print == 1)
+	{
+		print "$logcmd";
+	}
+
+	open(LOGFILE, '>>', AGENT_LOG_FILE)
+	  or die("Can't open " . AGENT_LOG_FILE . " - $!");
+	flock(LOGFILE, LOCK_EX) or die("Failed to lock log file.");
+	seek(LOGFILE, 0, 2) or die("Failed to seek to end of file.");
+	print LOGFILE "$logcmd" or die("Failed to write to log file.");
+	flock(LOGFILE, LOCK_UN) or die("Failed to unlock log file.");
+	close(LOGFILE) or die("Failed to close log file.");
+}
+
+# Check the screen logs folder
+if (!-d SCREEN_LOGS_DIR && !mkdir SCREEN_LOGS_DIR)
+{
+	logger "Could not create " . SCREEN_LOGS_DIR . " directory $!.", 1;
+	exit -1;
+}
+
+# Rotate the log file
+if (-e AGENT_LOG_FILE)
+{
+	if (-e AGENT_LOG_FILE . ".bak")
+	{
+		unlink(AGENT_LOG_FILE . ".bak");
+	}
+	logger "Rotating log file";
+	move(AGENT_LOG_FILE, AGENT_LOG_FILE . ".bak");
+	logger "New log file created";
+}
+
+sub backup_home_log
+{
+	my ($home_id, $log_file) = @_;
+	
+	my $home_backup_dir = SCREEN_LOGS_DIR . "/home_id_" . $home_id;
+		
+	if( ! -e $home_backup_dir )
+	{
+		if( ! mkdir $home_backup_dir )
+		{
+			logger "Can not create a backup directory at $home_backup_dir.";
+			return 1;
+		}
+	}
+	
+	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+	
+	my $backup_file_name =  $mday . $mon . $year . '_' . $hour . 'h' . $min . 'm' . $sec . "s.log";
+	
+	my $output_path = $home_backup_dir . "/" . $backup_file_name;
+	
+	# Used for deleting log files older than DELETE_LOGS_AFTER
+	my @file_list;
+	my @find_dirs; # directories to search
+	my $now = time(); # get current time
+	my $days;
+	if((DELETE_LOGS_AFTER =~ /^[+-]?\d+$/) && (DELETE_LOGS_AFTER > 0)){
+		$days = DELETE_LOGS_AFTER; # how many days old
+	}else{
+		$days = 30; # how many days old
+	}
+	my $seconds_per_day = 60*60*24; # seconds in a day
+	my $AGE = $days*$seconds_per_day; # age in seconds
+	push (@find_dirs, $home_backup_dir);
+	
+	# Create local copy of log file backup in the log_backups folder and current user home directory if SCREEN_LOG_LOCAL = 1 
+	if(SCREEN_LOG_LOCAL == 1)
+	{
+		# Create local backups folder
+		my $local_log_folder = Path::Class::Dir->new("logs_backup");
+		
+		if(!-e $local_log_folder){
+			mkdir($local_log_folder);
+		}
+		
+		# Add full path to @find_dirs so that log files older than DELETE_LOGS_AFTER are deleted
+		my $fullpath_to_local_logs = Path::Class::Dir->new(getcwd(), "logs_backup");
+		push (@find_dirs, $fullpath_to_local_logs);
+		
+		my $log_local = $local_log_folder . "/" . $backup_file_name;
+		
+		# Delete the local log file if it already exists
+		if(-e $log_local){
+			unlink $log_local;
+		}
+		
+		# If the log file contains UPDATE in the filename, do not allow users to see it since it will contain steam credentials
+		# Will return -1 for not existing
+		my $isUpdate = index($log_file,SCREEN_TYPE_UPDATE);
+		
+		if($isUpdate == -1){
+			copy($log_file,$log_local);
+		}
+	}
+	
+	# Delete all files in @find_dirs older than DELETE_LOGS_AFTER days
+	find ( sub {
+		my $file = $File::Find::name;
+		if ( -f $file ) {
+			push (@file_list, $file);
+		}
+	}, @find_dirs);
+ 
+	for my $file (@file_list) {
+		my @stats = stat($file);
+		if ($now-$stats[9] > $AGE) {
+			unlink $file;
+		}
+	}
+	
+	move($log_file,$output_path);
+	
+	return 0;
+}
+
+sub create_screen_id
+{
+	my ($screen_type, $home_id) = @_;
+	return sprintf("OGP_%s_%09d", $screen_type, $home_id);
+}
+
+sub create_screen_cmd
+{
+	my ($screen_id, $exec_cmd) = @_;
+	$exec_cmd = replace_OGP_Vars($screen_id, $exec_cmd);
+	return
+	  sprintf('screen -d -m -t "%1$s" -c ' . SCREENRC_FILE . ' -S %1$s %2$s',
+			  $screen_id, $exec_cmd);
+
+}
+
+sub create_screen_cmd_loop
+{
+	my ($screen_id, $exec_cmd, $priority, $affinity) = @_;
+	my $server_start_batfile = $screen_id . "_startup_scr.bat";
+	
+	$exec_cmd = replace_OGP_Vars($screen_id, $exec_cmd);
+	
+	# Create batch file that will launch the process and store PID which will be used for killing later
+	open (SERV_START_BAT_SCRIPT, '>', $server_start_batfile);
+	
+	my $batch_server_command = ":TOP" . "\r\n"
+	. "set starttime=%time%" . "\r\n"
+	. "start " . $priority . " " . $affinity . " /wait " . $exec_cmd . "\r\n"
+	. "set endtime=%time%" . "\r\n" 
+	. "set /a secs=%endtime:~6,2%" . "\r\n" 
+	. "set /a secs=%secs%-%starttime:~6,2%" . "\r\n"
+	. "if exist SERVER_STOPPED exit" . "\r\n"
+	. "if %secs% lss 15 exit" . "\r\n"
+	. "goto TOP" . "\r\n";
+	
+	print SERV_START_BAT_SCRIPT $batch_server_command;
+	close (SERV_START_BAT_SCRIPT);
+	
+	my $screen_exec_script = "cmd /Q /C " . $server_start_batfile;
+	
+	return
+	  sprintf('screen -d -m -t "%1$s" -c ' . SCREENRC_FILE . ' -S %1$s %2$s',
+			  $screen_id, $screen_exec_script);
+
+}
+
+sub replace_OGP_Vars{
+	# This function replaces constants from game server XML Configs with OGP paths for Steam Auto Updates for example
+	my ($screen_id, $exec_cmd) = @_;
+	my $screen_id_for_txt_update = substr ($screen_id, rindex($screen_id, '_') + 1);
+	my $steamInsFile = $screen_id_for_txt_update . "_install.txt";
+	my $steamCMDPath = STEAMCMD_CLIENT_DIR;
+	my $fullPath = Path::Class::File->new($steamCMDPath, $steamInsFile);
+	
+	my $windows_steamCMDPath= `cygpath -wa $steamCMDPath`;
+	chop $windows_steamCMDPath;
+	$windows_steamCMDPath =~ s#/#\\#g;
+	
+	# If the install file exists, the game can be auto updated, else it will be ignored by the game for improper syntax
+	# To generate the install file, the "Install/Update via Steam" button must be clicked on at least once!
+	if(-e $fullPath){
+		$exec_cmd =~ s/{OGP_STEAM_CMD_DIR}/$windows_steamCMDPath/g;
+		$exec_cmd =~ s/{STEAMCMD_INSTALL_FILE}/$steamInsFile/g;
+	}
+	
+	return $exec_cmd;
+}
+
+
+sub is_screen_running_without_decrypt
+{
+	my ($screen_type, $home_id) = @_;
+
+	my $screen_id = create_screen_id($screen_type, $home_id);
+
+	my $is_running = `screen -list | grep $screen_id`;
+
+	if ($is_running =~ /^\s*$/)
+	{
+		logger "Home with id $screen_id is not running.";
+		return 0;
+	}
+	else
+	{
+		logger "Home with id $screen_id is running.";
+		return 1;
+	}
+}
+
+sub encode_list
+{
+	my $encoded_content = '';
+	foreach (@_)
+	{
+		$encoded_content .= encode_base64($_, '\n');
+	}
+	return $encoded_content;
+}
+
+sub decrypt_param
+{
+	my ($param) = @_;
+	$param = decode_base64($param);
+	$param = Crypt::XXTEA::decrypt($param, AGENT_KEY);
+	$param = decode_base64($param);
+	return $param;
+}
+
+sub decrypt_params
+{
+	my @params;
+	foreach my $param (@_)
+	{
+		$param = &decrypt_param($param);
+		push(@params, $param);
+	}
+	return @params;
+}
+
+sub check_steam_cmd_client
+{
+	if (STEAM_LICENSE ne STEAM_LICENSE_OK)
+	{
+		logger "Steam license not accepted, stopping steam client check.";
+		return 0;
+	}
+
+	# TODO: This does not work on windows because the binary is not extracted as in Linux.
+
+	if (-f STEAMCMD_CLIENT_BIN)
+	{
+		logger "steamcmd client ok.";
+		my $update = system(STEAMCMD_CLIENT_BIN." +exit");
+		return 1;
+	}
+	
+	logger "steamcmd client does not exist, installing...";
+
+	if (!-d STEAMCMD_CLIENT_DIR && !mkdir STEAMCMD_CLIENT_DIR)
+	{
+		logger "Could not create " . STEAMCMD_CLIENT_DIR . " directory $!.", 1;
+		exit -1;
+	}
+	if (!-w STEAMCMD_CLIENT_DIR)
+	{
+		logger "Steam client dir '"
+		  . STEAMCMD_CLIENT_DIR
+		  . "' not writable. Unable to get steam client.";
+		return -1;
+	}
+
+	chdir STEAMCMD_CLIENT_DIR;
+
+	# These two commands needs to be variables changed depending the platform.
+	my $steam_client_file		  = 'steamcmd.zip';
+	my $steam_installation_command = 'unzip ' . $steam_client_file;
+
+	if (!-f Path::Class::File->new(STEAMCMD_CLIENT_DIR, $steam_client_file))
+	{
+		my $steam_client_url =
+		  "http://media.steampowered.com/installer/" . $steam_client_file;
+		logger "Downloading the steam client from $steam_client_url to '"
+		  . getcwd() . "'.";
+		my $steam_client_val = getstore($steam_client_url, $steam_client_file);
+		if ($steam_client_val != 200)
+		{
+			logger "Failed to download steam binary from "
+			  . $steam_client_url
+			  . ". Error code: "
+			  . $steam_client_val
+			  . "", 1;
+			return -1;
+		}
+	}
+	
+	my $steam_installation = system($steam_installation_command);
+	if ($steam_installation == -1)
+	{
+		logger "Failed to execute '"
+		  . $steam_installation_command
+		  . "' in dir "
+		  . STEAMCMD_CLIENT_DIR . ".";
+		return -1;
+	}
+	chmod 0755, STEAMCMD_CLIENT_BIN;
+	my $update = system(STEAMCMD_CLIENT_BIN." +exit");
+	
+	unlink($steam_client_file);
+	chdir AGENT_RUN_DIR;
+	return 1;
+}
+
+if (check_steam_cmd_client() == -1)
+{
+	print "ERROR: You must download and uncompress the new steamcmd package.";
+	print "ENSURE TO INSTALL IT IN /OGP/steamcmd directory,";
+	print "so it can be managed by the agent to install servers.";
+	exit 1;
+}
+sleep 5;
+logger "Open Game Panel - Agent started - "
+  . AGENT_VERSION
+  . " - port "
+  . AGENT_PORT
+  . " - PID $$", 1;
+# create the directory for startup flags
+if (!-e GAME_STARTUP_DIR)
+{
+	logger "Creating the startups directory " . GAME_STARTUP_DIR . "";
+	if (!mkdir GAME_STARTUP_DIR)
+	{
+		my $message =
+			"Failed to create the "
+		  . GAME_STARTUP_DIR
+		  . " directory - check permissions. Errno: $!";
+		logger $message, 1;
+		exit 1;
+	}
+}
+
+elsif ($clear_startups)
+{
+	opendir(STARTUPDIR, GAME_STARTUP_DIR);
+	while (my $startup_file = readdir(STARTUPDIR))
+	{
+
+		# Skip . and ..
+		next if $startup_file =~ /^\./;
+		$startup_file = Path::Class::File->new(GAME_STARTUP_DIR, $startup_file);
+		logger "Removing " . $startup_file . ".";
+		unlink($startup_file);
+	}
+	closedir(STARTUPDIR);
+}
+
+# If the directory already existed check if we need to start some games.
+elsif ($no_startups != 1)
+{
+	my $screenwipe = `/usr/bin/screen -wipe > /dev/null`;
+	# Loop through all the startup flags, and call universal startup
+	opendir(STARTUPDIR, GAME_STARTUP_DIR);
+	logger "Reading startup flags from " . GAME_STARTUP_DIR . "";
+	while (my $dirlist = readdir(STARTUPDIR))
+	{
+
+		# Skip . and ..
+		next if $dirlist =~ /^\./;
+		logger "Found $dirlist";
+		open(STARTFILE, '<', Path::Class::Dir->new(GAME_STARTUP_DIR, $dirlist))
+		  || logger "Error opening start flag $!";
+		while (<STARTFILE>)
+		{
+			my (
+				$home_id,   $home_path,   $server_exe,
+				$run_dir,   $startup_cmd, $server_port,
+				$server_ip, $cpu,		 $nice
+			   ) = split(',', $_);
+			
+			if (is_screen_running_without_decrypt(SCREEN_TYPE_HOME, $home_id) ==
+				1)
+			{
+				logger
+				  "This server ($server_exe on $server_ip : $server_port) is already running (ID: $home_id).";
+				next;
+			}
+
+			logger "Starting server_exe $server_exe from home $home_path.";
+			universal_start_without_decrypt(
+										 $home_id,   $home_path,   $server_exe,
+										 $run_dir,   $startup_cmd, $server_port,
+										 $server_ip, $cpu,		 $nice
+										   );
+		}
+		close(STARTFILE);
+	}
+	closedir(STARTUPDIR);
+}
+
+# Create the pid file
+open(PID, '>', AGENT_PID_FILE)
+  or die("Can't write to pid file - " . AGENT_PID_FILE . "\n");
+print PID "$$\n";
+close(PID);
+
+my $d = Frontier::Daemon::Forking->new(
+			 methods => {
+				 is_screen_running				=> \&is_screen_running,
+				 universal_start				=> \&universal_start, 
+				 cpu_count						=> \&cpu_count,
+				 rfile_exists					=> \&rfile_exists,
+				 quick_chk						=> \&quick_chk,
+				 steam							=> \&steam,
+				 steam_cmd						=> \&steam_cmd,
+				 get_log						=> \&get_log,
+				 stop_server					=> \&stop_server,
+				 send_rcon_command				=> \&send_rcon_command,
+				 dirlist						=> \&dirlist,
+				 dirlistfm						=> \&dirlistfm,
+				 readfile						=> \&readfile,
+				 writefile						=> \&writefile,
+				 what_os						=> \&what_os,
+				 start_file_download			=> \&start_file_download,
+				 is_file_download_in_progress	=> \&is_file_download_in_progress,
+				 uncompress_file				=> \&uncompress_file,
+				 discover_ips					=> \&discover_ips,
+				 mon_stats						=> \&mon_stats,
+				 exec							=> \&exec,
+				 clone_home						=> \&clone_home,
+				 remove_home					=> \&remove_home,
+				 start_rsync_install			=> \&start_rsync_install,
+				 rsync_progress					=> \&rsync_progress,
+				 restart_server					=> \&restart_server,
+				 sudo_exec						=> \&sudo_exec,
+				 master_server_update			=> \&master_server_update,
+				 secure_path					=> \&secure_path,
+				 get_chattr						=> \&get_chattr,
+				 ftp_mgr						=> \&ftp_mgr,
+			 },
+			 debug	 => 4,
+			 LocalPort => AGENT_PORT,
+			 LocalAddr => AGENT_IP,
+			 ReuseAddr => '1'
+) or die "Couldn't start OGP Agent: $!";
+
+sub is_screen_running
+{
+	my ($screen_type, $home_id) = decrypt_params(@_);
+	return is_screen_running_without_decrypt($screen_type, $home_id);
+}
+
+# Delete Server Stopped Status File:
+
+sub deleteStoppedStatFile{
+	my $server_stop_status_file = "SERVER_STOPPED";
+		
+	if(-e $server_stop_status_file){
+		unlink $server_stop_status_file;
+	}
+}
+
+# Universal startup function
+sub universal_start
+{
+	chomp(@_);
+	return universal_start_without_decrypt(decrypt_params(@_));
+}
+
+# Split to two parts because of internal calls.
+sub universal_start_without_decrypt
+{
+	my (
+		$home_id,	 $home_path, $server_exe, $run_dir, $startup_cmd,
+		$server_port, $server_ip, $cpu,		$nice
+	   ) = @_;
+	   
+	if (is_screen_running_without_decrypt(SCREEN_TYPE_HOME, $home_id) == 1)
+	{
+		logger "This server is already running (ID: $home_id).";
+		return -14;
+	}
+
+	if (!-e $home_path)
+	{
+		logger "Can't find server's install path [ $home_path ].";
+		return -10;
+	}
+
+	# Some game require that we are in the directory where the binary is.
+	my $game_binary_dir = Path::Class::Dir->new($home_path, $run_dir);
+	if (!chdir $game_binary_dir)
+	{
+		logger "Could not change to server binary directory $game_binary_dir.";
+		return -12;
+	}
+
+	if (!-x $server_exe)
+	{
+		my $chmod_exe = chmod 0755, $server_exe;
+		if (!$chmod_exe)
+		{
+			logger "The $server_exe file is not executable.";
+			return -13;
+		}
+	}
+
+	my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
+
+	# Create affinity and priority strings
+	my $priority;
+	my $affinity;
+	
+	if($nice ne "NA")
+	{
+		if( $nice <= 19 and $nice >= 11 )
+		{
+			$priority = "/low";
+		}		
+		elsif( $nice <= 10 and $nice >= 1 )
+		{
+			$priority = "/belownormal";
+		}
+		elsif( $nice == 0 )
+		{
+			$priority = "/normal";
+		}
+		elsif( $nice <= -1 and $nice >= -8  )
+		{
+			$priority = "/abovenormal";
+		}
+		elsif( $nice <= -9 and $nice >= -18 )
+		{
+			$priority = "/high";
+		}
+		elsif( $nice == -19 )
+		{
+			$priority = "/realtime";
+		}
+	}
+	else
+	{
+		$priority = "";
+	}
+	
+	if($cpu ne "NA" and $cpu ne "" )
+	{
+		
+		$affinity = "/affinity $cpu";
+	}
+	else
+	{
+		$affinity = "";
+	}
+	
+	
+	my $cygwin_path = `cygpath -wa /`;
+	chomp $cygwin_path;
+	
+	$home_path =~ s/\//\\/g;
+	
+	if ( $run_dir ne "" )
+	{
+		$run_dir = $run_dir."\\";
+	}
+	
+	my $windows_path = $cygwin_path.$home_path."\\".$run_dir;
+	
+	$windows_path =~ s/\\/\\\\/g;
+	
+	# Create the startup string.
+	my ($file_extension) = $server_exe =~ /(\.[^.]+)$/;
+		
+	my $cli_bin;
+	
+	# Create bash file to respawn process if it crashes or exits without user interaction
+	# If a user stops the server, the process will not respawn
+	
+	if($file_extension eq ".jar")
+	{
+		if(defined($Cfg::Preferences{ogp_autorestart_server}) &&  $Cfg::Preferences{ogp_autorestart_server} eq "1"){
+			deleteStoppedStatFile();
+			$cli_bin = create_screen_cmd_loop($screen_id, "$startup_cmd", $priority, $affinity);
+		}else{
+			# $startup_cmd =~ s/java //g;
+			# $cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT wscript.exe \"$invisible\" \"java\" \"$startup_cmd\"");
+			$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT $startup_cmd");
+		}
+	}
+	elsif(($file_extension eq ".sh")||($file_extension eq ".bash"))
+	{
+		# There is no software made for windows that uses bash by default,
+		# but it can be a good way to improve the server startup. To be able to use
+		# sh/bash scripts as server executable I added this piece to the agent:	
+		if(defined($Cfg::Preferences{ogp_autorestart_server}) &&  $Cfg::Preferences{ogp_autorestart_server} eq "1"){
+			deleteStoppedStatFile();
+			$cli_bin = create_screen_cmd_loop($screen_id, "bash $server_exe $startup_cmd", $priority, $affinity);
+		}else{
+			$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT bash $server_exe $startup_cmd");
+		}
+	}
+	else
+	{
+		if(defined($Cfg::Preferences{ogp_autorestart_server}) &&  $Cfg::Preferences{ogp_autorestart_server} eq "1"){
+			deleteStoppedStatFile();
+			
+			$cli_bin = create_screen_cmd_loop($screen_id, "$windows_path$server_exe $startup_cmd", $priority, $affinity);
+		}else{
+			# $cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT wscript.exe \"$invisible\" \"$server_exe\" \"$startup_cmd\"");
+			$cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT $windows_path$server_exe $startup_cmd");
+		}
+	}
+	
+	$home_path =~ s/\\/\//g;
+	
+	my $log_file = Path::Class::File->new(SCREEN_LOGS_DIR, "screenlog.$screen_id");
+	backup_home_log( $home_id, $log_file );
+	
+	my $clean_cli_bin = $cli_bin;
+	$clean_cli_bin =~ s/\\\\/\\/g;
+	logger
+	  "Startup command [ $clean_cli_bin ] will be executed in dir $game_binary_dir.";
+
+	system($cli_bin);
+
+	# Create startup file for the server.
+	my $startup_file =
+	  Path::Class::File->new(GAME_STARTUP_DIR, "$server_ip-$server_port");
+
+	if (open(STARTUP, '>', $startup_file))
+	{
+		print STARTUP
+		  "$home_id,$home_path,$server_exe,$run_dir,$startup_cmd,$server_port,$server_ip,$cpu,$nice";
+		logger "Created startup flag for $server_ip-$server_port";
+		close(STARTUP);
+	}
+	else
+	{
+		logger "Cannot create file in " . $startup_file . " : $!";
+	}
+	return 1;
+}
+
+# Returns the number of CPUs available.
+sub cpu_count
+{
+	if (!-e "/proc/cpuinfo")
+	{
+		return "ERROR - Missing /proc/cpuinfo";
+	}
+
+	open(CPUINFO, '<', "/proc/cpuinfo")
+	  or return "ERROR - Cannot open /proc/cpuinfo";
+
+	my $cpu_count = 0;
+
+	while (<CPUINFO>)
+	{
+		chomp;
+		next if $_ !~ /^processor/;
+		$cpu_count++;
+	}
+	close(CPUINFO);
+	return "$cpu_count";
+}
+
+### File exists check ####
+# Simple a way to check if a file exists using the remote agent
+#
+# @return 0 when file exists.
+# @return 1 when file does not exist.
+sub rfile_exists
+{
+	chdir AGENT_RUN_DIR;
+	my $checkFile = decrypt_param(@_);
+
+	if (-e $checkFile)
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
+##### Quick check to verify agent is up and running
+# Used to quickly see if the agent is online, and if the keys match.
+# The message that is sent to the agent must be hello, if not then
+# it is intrepret as encryption key missmatch.
+#
+# @return 1 when encrypted message is not 'hello'
+# @return 0 when check is ok.
+sub quick_chk
+{
+	my $dec_check = &decrypt_param(@_);
+	if ($dec_check ne 'hello')
+	{
+		logger "ERROR - Encryption key mismatch! Returning 1 to asker.";
+		return 1;
+	}
+	return 0;
+}
+
+sub rcon_quit_postback_handler
+{
+	my ($type, $ip, $port, $command, $identifier, $response) = @_;
+	logger "Rcon command of $command to a $type server";
+	logger " at $ip:$port";
+	logger " had a identifier of $identifier" if defined $identifier;
+	logger " returned from the server with:\n$response\n";
+}
+
+### Return -10 If home path is not found.
+### Return -9  If log type was invalid.
+### Return -8  If log file was not found.
+### 0 reserved for connection problems.
+### Return 1;content If log found and screen running.
+### Return 2;content If log found but screen is not running.
+sub get_log
+{
+	my ($screen_type, $home_id, $home_path, $nb_of_lines) = decrypt_params(@_);
+
+	if (!chdir $home_path)
+	{
+		logger "Can't change to server's install path [ $home_path ].";
+		return -10;
+	}
+
+	if (   ($screen_type eq SCREEN_TYPE_UPDATE)
+		&& ($screen_type eq SCREEN_TYPE_HOME))
+	{
+		logger "Invalid screen type '$screen_type'.";
+		return -9;
+	}
+
+	my $screen_id = create_screen_id($screen_type, $home_id);
+		
+	my $log_file = Path::Class::File->new(SCREEN_LOGS_DIR, "screenlog.$screen_id");
+	
+	chmod 0644, $log_file;	
+	
+	# Create local copy of current log file if SCREEN_LOG_LOCAL = 1
+	if(SCREEN_LOG_LOCAL == 1)
+	{
+		my $log_local = Path::Class::File->new($home_path, "LOG_$screen_type.txt");
+		if ( -e $log_local )
+		{
+			unlink $log_local;
+		}
+		
+		# Copy log file only if it's not an UPDATE type as it may contain steam credentials
+		if($screen_type eq SCREEN_TYPE_HOME){
+			copy($log_file, $log_local);
+		}
+	}
+	
+	# Regenerate the log file if it doesn't exist
+	unless ( -e $log_file )
+	{
+		if (open(NEWLOG, '>', $log_file))
+		{
+			logger "Log file missing, regenerating: " . $log_file;
+			print NEWLOG "Log file missing, started new log\n";
+			close(NEWLOG);
+		}
+		else
+		{
+			logger "Cannot regenerate log file in " . $log_file . " : $!";
+			return -8;
+		}
+	}
+	
+	# Return a few lines of output to the web browser
+	my(@modedlines) = `tail -n $nb_of_lines $log_file`;
+	
+	my $linecount = 0;
+	
+	foreach my $line (@modedlines) {
+		#Text replacements to remove the Steam user login from steamcmd logs for security reasons.
+		$line =~ s/login .*//g;
+		$line =~ s/Logging .*//g;
+		$line =~ s/set_steam_guard_code.*//g;
+		$line =~ s/force_install_dir.*//g;
+		#Text replacements to remove empty lines.
+		$line =~ s/^ +//g;
+		$line =~ s/^\t+//g;
+		$line =~ s/^\e+//g;
+		#Remove � from console output when master server update is running.
+		$line =~ s/�//g;
+		$modedlines[$linecount]=$line;
+		$linecount++;
+	} 
+	
+	my $encoded_content = encode_list(@modedlines);
+	chdir AGENT_RUN_DIR;
+	if(is_screen_running_without_decrypt($screen_type, $home_id) == 1)
+	{
+		return "1;" . $encoded_content;
+	}
+	else
+	{
+		return "2;" . $encoded_content;
+	}
+}
+
+# stop server function
+sub stop_server
+{
+	chomp(@_);
+	my ($home_id, $server_ip, $server_port, $control_protocol,
+		$control_password, $control_type, $home_path) = decrypt_params(@_);
+		
+	my $startup_file =
+	Path::Class::File->new(GAME_STARTUP_DIR, "$server_ip-$server_port");
+	
+	if (-e $startup_file)
+	{
+		logger "Removing startup flag " . $startup_file . "";
+		unlink($startup_file)
+		  or logger "Cannot remove the startup flag file $startup_file $!";
+	}
+	
+	# Create file indicator that the game server has been stopped if defined
+	if(defined($Cfg::Preferences{ogp_autorestart_server}) &&  $Cfg::Preferences{ogp_autorestart_server} eq "1"){
+		
+		# Get current directory and chdir into the game's home dir
+		my $curDir = getcwd();
+		chdir $home_path;
+
+		# Create stopped indicator file used by autorestart of OGP if server crashes
+		open(STOPFILE, '>', "SERVER_STOPPED");
+		close(STOPFILE);
+		
+		# Return to original directory
+		chdir $curDir;
+	}
+	
+	return stop_server_without_decrypt($home_id, $server_ip,
+									   $server_port, $control_protocol,
+									   $control_password, $control_type);
+}
+##### Stop server without decrypt
+### Return 1 when error occurred on decryption.
+### Return 0 on success
+sub stop_server_without_decrypt
+{
+	my ($home_id, $server_ip, $server_port, $control_protocol,
+		$control_password, $control_type) = @_;
+	
+	my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
+	my $get_screen_pid = "screen -list | grep $screen_id | cut -f1 -d'.' | sed '".'s/\W//g'."'";
+	my $screen_pid = `$get_screen_pid`; 
+	chomp $screen_pid;
+	# Some validation checks for the variables.
+	if ($server_ip =~ /^\s*$/ || $server_port < 0 || $server_port > 65535)
+	{
+		logger("Invalid IP:Port given $server_ip:$server_port.");
+		return 1;
+	}
+
+	if ($control_password !~ /^\s*$/ and $control_protocol ne "")
+	{
+		if ($control_protocol eq "rcon")
+		{
+			use KKrcon::KKrcon;
+			my $rcon = new KKrcon(
+								  Password => $control_password,
+								  Host	 => $server_ip,
+								  Port	 => $server_port,
+								  Type	 => $control_type
+								 );
+
+			my $rconCommand = "quit";
+			$rcon->execute($rconCommand);
+		}
+		elsif ($control_protocol eq "rcon2")
+		{
+			use KKrcon::HL2;
+			my $rcon2 = new HL2(
+								  hostname => $server_ip,
+								  port	 => $server_port,
+								  password => $control_password,
+								  timeout  => 2
+								 );
+
+			my $rconCommand = "quit";
+			$rcon2->run($rconCommand);
+		}
+		system("screen -wipe");	
+	}
+	else
+	{
+		logger "Control protocol not supported. Using kill signal to stop the server.";
+		my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
+		system("cmd /C taskkill /f /fi 'PID eq $screen_pid' /T");
+		system("screen -wipe");
+	}
+	
+	if (is_screen_running_without_decrypt(SCREEN_TYPE_HOME, $home_id) == 1)
+	{
+		logger "Control protocol not responding. Using kill signal.";
+		system("cmd /C taskkill /f /fi 'PID eq $screen_pid' /T");
+		system("screen -wipe");
+		logger "Server ID $home_id:Stopped server running on $server_ip:$server_port.";
+		return 0;
+	}
+	else
+	{
+		logger "Server ID $home_id:Stopped server running on $server_ip:$server_port.";
+		return 0;
+	}
+}
+
+##### Send RCON command 
+### Return 0 when error occurred on decryption.
+### Return 1 on success
+sub send_rcon_command
+{
+	my ($home_id, $server_ip, $server_port, $control_protocol,
+		$control_password, $control_type, $rconCommand) = decrypt_params(@_);
+	
+	# legacy console
+	if ($control_protocol eq "lcon")
+	{
+		my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id);
+		system('screen -S '.$screen_id.' -p 0 -X stuff "'.$rconCommand.'$(printf \\\\r)"');
+		logger "Sending legacy console command to ".$screen_id.": \n$rconCommand \n .";
+		if ($? == 0)
+		{
+			my(@modedlines) = "$rconCommand";
+			my $encoded_content = encode_list(@modedlines);
+			return "1;" . $encoded_content;
+		}
+		return 0;
+	}
+	
+	# Some validation checks for the variables.
+	if ($server_ip =~ /^\s*$/ || $server_port < 0 || $server_port > 65535)
+	{
+		logger("Invalid IP:Port given $server_ip:$server_port.");
+		return 0;
+	}
+	
+	if ($control_password !~ /^\s*$/)
+	{
+		if ($control_protocol eq "rcon")
+		{
+			use KKrcon::KKrcon;
+			my $rcon = new KKrcon(
+								  Password => $control_password,
+								  Host	 => $server_ip,
+								  Port	 => $server_port,
+								  Type	 => $control_type
+								 );
+
+			logger "Sending RCON command to $server_ip:$server_port: \n$rconCommand \n  .";
+						
+			my(@modedlines) = $rcon->execute($rconCommand);
+			my $encoded_content = encode_list(@modedlines);
+			return "1;" . $encoded_content;
+		}
+		else
+		{		
+			if ($control_protocol eq "rcon2")
+			{
+				use KKrcon::HL2;
+				my $rcon2 = new HL2(
+									  hostname => $server_ip,
+									  port	 => $server_port,
+									  password => $control_password,
+									  timeout  => 2
+									 );
+				
+				logger "Sending RCON command to $server_ip:$server_port: \n $rconCommand \n  .";
+						
+				my(@modedlines) = $rcon2->run($rconCommand);
+				my $encoded_content = encode_list(@modedlines);
+				return "1;" . $encoded_content;
+			}
+		}
+	}
+	else
+	{
+		logger "Control protocol PASSWORD NOT SET.";
+		return -10;
+	}
+}
+
+##### Returns a directory listing
+### @return List of directories if everything OK.
+### @return 0 If the directory is not found.
+### @return -1 If cannot open the directory.
+sub dirlist
+{
+	my ($datadir) = &decrypt_param(@_);
+	logger "Asked for dirlist of $datadir directory.";
+	if (!-d $datadir)
+	{
+		logger "ERROR - Directory [ $datadir ] not found!";
+		return -1;
+	}
+	if (!opendir(DIR, $datadir))
+	{
+		logger "ERROR - Can't open $datadir: $!";
+		return -2;
+	}
+	my @dirlist = readdir(DIR);
+	closedir(DIR);
+	return join(";", @dirlist);
+}
+
+##### Returns a directory listing with extra info the filemanager
+### @return List of directories if everything OK.
+### @return 0 If the directory is empty.
+### @return -1 If the directory is not found.
+### @return -2 If cannot open the directory.
+sub dirlistfm
+{
+	my $datadir = &decrypt_param(@_);
+	logger "Asked for dirlist of $datadir directory.";
+	if (!-d $datadir)
+	{
+		logger "ERROR - Directory [ $datadir ] not found!";
+		return -1;
+	}
+	if (!opendir(DIR, $datadir))
+	{
+		logger "ERROR - Can't open $datadir: $!";
+		return -2;
+	}
+	chdir($datadir);
+	my @dirlist = readdir(DIR);
+
+	if (@dirlist eq 0)
+	{
+		logger "Empty directory $datadir.";
+		return 0;
+	}
+
+	@dirlist = sort @dirlist;
+
+	my $dirlist;
+	my @dl;
+	my (
+		$dev,  $ino,   $mode,  $nlink, $uid,	 $gid, $rdev,
+		$size, $atime, $mtime, $ctime, $blksize, $blocks
+	   );
+	foreach $dirlist (@dirlist)
+	{
+
+		#skip the . and .. special dirs
+		next if $dirlist eq '.';
+		next if $dirlist eq '..';
+
+		#print "Dir list is" . $dirlist."\n";
+		#Stat the file to get ownership and size
+		(
+		 $dev,  $ino,   $mode,  $nlink, $uid,	 $gid, $rdev,
+		 $size, $atime, $mtime, $ctime, $blksize, $blocks
+		) = stat($dirlist);
+		$uid = getpwuid($uid);
+		$gid = getgrgid($gid);
+
+		#This if else logic determines what it is, File, Directory, other
+		#We modify the @dl array by adding file info to each element
+		if (-T $dirlist)
+		{
+
+			# print "File\n";
+			push(@dl,
+				 $dirlist . "|" . "$size" . "|" . "$uid" . "|" . "$gid" . "|"
+				   . "F");
+		}
+		elsif (-d $dirlist)
+		{
+
+			# print "Dir\n";
+			push(@dl,
+				 $dirlist . "|" . "$size" . "|" . "$uid" . "|" . "$gid" . "|"
+				   . "D");
+		}
+		elsif (-B $dirlist)
+		{
+
+			#print "File\n";
+			push(@dl,
+				 $dirlist . "|" . "$size" . "|" . "$uid" . "|" . "$gid" . "|"
+				   . "B");
+		}
+		else
+		{
+
+			#print "Unknown\n";
+			push(@dl,
+				 $dirlist . "|" . "$size" . "|" . "$uid" . "|" . "$gid" . "|"
+				   . "U");
+		}
+
+	}
+	closedir(DIR);
+
+	#Now we return it to the webpage, which then can parse it further
+	return join(";", @dl);
+}
+
+###### Returns the contents of a text file
+sub readfile
+{
+	chdir AGENT_RUN_DIR;
+	my $userfile = &decrypt_param(@_);
+
+	unless ( -e $userfile )
+	{
+		if (open(BLANK, '>', $userfile))
+		{
+			close(BLANK);
+		}
+	}
+	
+	if (!open(USERFILE, '<', $userfile))
+	{
+		logger "ERROR - Can't open file $userfile for reading.";
+		return -1;
+	}
+
+	my ($wholefile, $buf);
+
+	while (read(USERFILE, $buf, 60 * 57))
+	{
+		$wholefile .= encode_base64($buf);
+	}
+	close(USERFILE);
+	
+	if(!defined $wholefile)
+	{
+		return "1; ";
+	}
+	
+	return "1;" . $wholefile;
+}
+
+###### Backs up file, then writes data to new file
+### @return 1 On success
+### @return 0 In case of a failure
+sub writefile
+{
+	chdir AGENT_RUN_DIR;
+	# $writefile = file we're editing, $filedata = the contents were writing to it
+	my ($writefile, $filedata) = &decrypt_params(@_);
+	if (!-e $writefile)
+	{
+		open FILE, ">", $writefile;
+	}
+	else
+	{
+		# backup the existing file
+		logger
+		  "Backing up file $writefile to $writefile.bak before writing new data.";
+		if (!copy("$writefile", "$writefile.bak"))
+		{
+			logger
+			  "ERROR - Failed to backup $writefile to $writefile.bak. Error: $!";
+			return 0;
+		}
+	}
+	if (!-w $writefile)
+	{
+		logger "ERROR - File [ $writefile ] is not writeable!";
+		return 0;
+	}
+	if (!open(WRITER, '>', $writefile))
+	{
+		logger "ERROR - Failed to open $writefile for writing.";
+		return 0;
+	}
+	$filedata = decode_base64($filedata);
+	$filedata =~ s/\r//g;
+	print WRITER "$filedata";
+	close(WRITER);
+	logger "Wrote $writefile successfully!";
+	return 1;
+}
+
+# Determine the os of the agent machine.
+sub what_os
+{
+	my $os;
+	logger "Asking for OS type";
+	if (-e "/usr/bin/uname")
+	{
+		$os = `/usr/bin/uname`;
+		chomp $os;
+		logger "OS is $os";
+		return "$os";
+	}
+	elsif (-e "/bin/uname")
+	{
+		$os = `/bin/uname`;
+		chomp $os;
+		logger "OS is $os";
+		return "$os";
+	}
+	elsif (-e 'c:\\')
+	{
+		logger "OS is Windows";
+		return "Windows";
+	}
+	else
+	{
+		logger "Cannot determine OS..that is odd";
+		return "Unknown";
+	}
+}
+
+### @return PID of the download process if started succesfully.
+### @return -1 If could not create temporary download directory.
+### @return -2 If could not create destination directory.
+### @return -3 If resources unavailable.
+sub start_file_download
+{
+	my ($url, $destination, $filename, $action, $post_script) = &decrypt_params(@_);
+	logger
+	  "Starting to download URL $url. Destination: $destination - Filename: $filename";
+
+	if (!-e $destination)
+	{
+		logger "Creating destination directory.";
+		if (!mkpath $destination )
+		{
+			logger "Could not create destination '$destination' directory : $!";
+			return -2;
+		}
+	}
+	
+	my $download_file_path = Path::Class::File->new($destination, "$filename");
+
+	my $pid = fork();
+	if (not defined $pid)
+	{
+		logger "Could not allocate resources for download.";
+		return -3;
+	}
+
+	# Only the forked child goes here.
+	elsif ($pid == 0)
+	{
+		my $get_retval = getstore($url, "$download_file_path");
+
+		if (!is_success($get_retval))
+		{
+			logger
+			  "Unable to fetch $url, or save to $download_file_path. Retval: $get_retval";
+			exit(0);
+		}
+
+		logger
+		  "Successfully fetched $url and stored it to $download_file_path. Retval: $get_retval.";
+
+		if (!-e $download_file_path)
+		{
+			logger "File $download_file_path does not exist.";
+			exit(0);
+		}
+
+		if ($action eq "uncompress")
+		{
+			logger "Starting file uncompress as ordered.";
+			uncompress_file_without_decrypt($download_file_path,
+											$destination);
+		}
+
+		# Child process must exit.
+		exit(0);
+	}
+	else
+	{
+		if ($post_script ne "")
+		{
+			logger "Running postscript commands.";
+			my @postcmdlines = split /[\r\n]+/, $post_script;
+			my $postcmdfile = $destination."/".'postinstall.sh';
+			open  FILE, '>', $postcmdfile;
+			print FILE "cd $destination\n";
+			print FILE "while kill -0 $pid >/dev/null 2>&1\n";
+			print FILE "do\n";
+			print FILE "	sleep 1\n";
+			print FILE "done\n";
+			foreach my $line (@postcmdlines) {
+				print FILE "$line\n";
+			}
+			print FILE "rm -f $destination/postinstall.sh\n";
+			close FILE;
+			chmod 0755, $postcmdfile;
+			my $screen_id = create_screen_id("post_script", $pid);
+			my $cli_bin = create_screen_cmd($screen_id, "bash $postcmdfile");
+			system($cli_bin);
+		}
+		logger "Download process for $download_file_path has pid number $pid.";
+		return "$pid";
+	}
+}
+
+sub check_b4_chdir
+{
+	my ( $path ) = @_;
+		
+	if (!-e $path)
+	{
+		logger "$path does not exist yet. Trying to create it...";
+
+		if (!mkpath($path))
+		{
+			logger "Error creating $path . Errno: $!";
+			return -1;
+		}
+	}
+	
+	if (!chdir $path)
+	{
+		logger "Unable to change dir to '$path'.";
+		return -1;
+	}
+	
+	return 0;
+}
+
+sub create_bash_scripts
+{
+	my ( $home_path, $bash_scripts_path, $precmd, $postcmd, @installcmds ) = @_;
+	
+	my @precmdlines = split /[\r\n]+/, $precmd;
+	my $precmdfile = 'preinstall.sh';
+	open  FILE, '>', $precmdfile;
+	print FILE "cd $home_path\n";
+	foreach my $line (@precmdlines) {
+		print FILE "$line\n";
+	}
+	close FILE;
+	chmod 0755, $precmdfile;
+	
+	my @postcmdlines = split /[\r\n]+/, $postcmd;
+	my $postcmdfile = 'postinstall.sh';
+	open  FILE, '>', $postcmdfile;
+	print FILE "cd $home_path\n";
+	foreach my $line (@postcmdlines) {
+		print FILE "$line\n";
+	}
+	print FILE "cd $bash_scripts_path\n";
+	print FILE "rm -f preinstall.sh\n";
+	print FILE "rm -f postinstall.sh\n";
+	print FILE "rm -f runinstall.sh\n";
+	close FILE;
+	chmod 0755, $postcmdfile;
+	
+	my $installfile = 'runinstall.sh';
+	open  FILE, '>', $installfile;
+	print FILE "#!/bin/bash\n";
+	print FILE "cd $bash_scripts_path\n";
+	print FILE "./$precmdfile\n";
+	foreach my $installcmd (@installcmds)
+	{
+		print FILE "$installcmd\n";
+	}
+	print FILE "wait ".'${!}'."\n";
+	print FILE "cd $bash_scripts_path\n";
+	print FILE "./$postcmdfile\n";
+	close FILE;
+	chmod 0755, $installfile;
+	
+	return $installfile;
+}
+
+#### Run the rsync update ####
+### @return 1 If update started
+### @return 0 In error case.
+sub start_rsync_install
+{
+	my ($home_id, $home_path, $url, $exec_folder_path, $exec_path, $precmd, $postcmd) = decrypt_params(@_);
+
+	if ( check_b4_chdir($home_path) != 0)
+	{
+		return 0;
+	}
+
+	my $bash_scripts_path = MANUAL_TMP_DIR . "/home_id_" . $home_id;
+	
+	if ( check_b4_chdir($bash_scripts_path) != 0)
+	{
+		return 0;
+	}
+	
+	# Rsync install require the rsync binary to exist in the system
+	# to enable this functionality.
+	my $rsync_binary = Path::Class::File->new("/usr/bin", "rsync");
+	
+	if (!-f $rsync_binary)
+	{
+		logger "Failed to start rsync update from "
+		  . $url
+		  . " to $home_path. Error: Rsync client not installed.";
+		return 0;
+	}
+
+	my $screen_id = create_screen_id(SCREEN_TYPE_UPDATE, $home_id);
+	
+	my $log_file = Path::Class::File->new(SCREEN_LOGS_DIR, "screenlog.$screen_id");
+	
+	backup_home_log( $home_id, $log_file );
+	
+	my @installcmds = ("/usr/bin/rsync --archive --compress --copy-links --update --verbose rsync://$url $home_path", 
+					   "cd $home_path",
+					   "chmod -Rf 755 $home_path",
+					   "find -iname \\\*.exe -exec chmod -f +x {} \\\;", 
+					   "find -iname \\\*.bat -exec chmod -f +x {} \\\;");
+	my $installfile = create_bash_scripts( $home_path, $bash_scripts_path, $precmd, $postcmd, @installcmds );
+
+	my $screen_cmd = create_screen_cmd($screen_id, "./$installfile");
+	logger "Running rsync update: /usr/bin/rsync --archive --compress --copy-links --update --verbose rsync://$url $home_path";
+	system($screen_cmd);
+	
+	chdir AGENT_RUN_DIR;
+	return 1;
+}
+
+### @return PID of the download process if started succesfully.
+### @return -1 If could not create temporary download directory.
+### @return -2 If could not create destination directory.
+### @return -3 If resources unavailable.
+sub master_server_update
+{
+	my ($home_id,$home_path,$ms_home_id,$ms_home_path,$exec_folder_path,$exec_path,$precmd,$postcmd) = decrypt_params(@_);
+	
+	if ( check_b4_chdir($home_path) != 0)
+	{
+		return 0;
+	}
+			
+	my $bash_scripts_path = MANUAL_TMP_DIR . "/home_id_" . $home_id;
+	
+	if ( check_b4_chdir($bash_scripts_path) != 0)
+	{
+		return 0;
+	}
+
+	my $screen_id = create_screen_id(SCREEN_TYPE_UPDATE, $home_id);
+	
+	my $log_file = Path::Class::File->new(SCREEN_LOGS_DIR, "screenlog.$screen_id");
+	
+	backup_home_log( $home_id, $log_file );
+	
+	my @installcmds = ("cp -vuRf  $ms_home_path/* $home_path");
+	my $installfile = create_bash_scripts( $home_path, $bash_scripts_path, $precmd, $postcmd, @installcmds );
+
+	my $screen_cmd = create_screen_cmd($screen_id, "./$installfile");
+	logger "Running master server update: cp -vuRf  $ms_home_path/* $home_path";
+	system($screen_cmd);
+	
+	chdir AGENT_RUN_DIR;
+	return 1;
+}
+
+#### Run the steam client ####
+### @return 1 If update started
+### @return 0 In error case.
+sub steam_cmd
+{
+	my ($home_id, $home_path, $mod, $modname, $betaname, $betapwd, $user, $pass, $guard, $exec_folder_path, $exec_path, $precmd, $postcmd) = decrypt_params(@_);
+	
+	# Creates home path if it doesn't exist
+	if ( check_b4_chdir($home_path) != 0)
+	{
+		return 0;
+	}
+  
+    # Changes into root steamcmd OGP directory
+	if ( check_b4_chdir(STEAMCMD_CLIENT_DIR) != 0)
+	{
+		return 0;
+	}
+	
+	my $screen_id = create_screen_id(SCREEN_TYPE_UPDATE, $home_id);
+	my $screen_id_for_txt_update = substr ($screen_id, rindex($screen_id, '_') + 1);
+	my $steam_binary = Path::Class::File->new(STEAMCMD_CLIENT_DIR, "steamcmd.exe");
+	my $installSteamFile = $screen_id_for_txt_update . "_install.txt";
+	
+	my $windows_home_path = `cygpath -wa $home_path`;
+	chop $windows_home_path;
+	
+	my $installtxt = Path::Class::File->new($installSteamFile);
+	
+	open  FILE, '>', $installtxt;
+	print FILE "\@ShutdownOnFailedCommand 1\n";
+	print FILE "\@NoPromptForPassword 1\n";
+	if($guard ne '')
+	{	
+		print FILE "set_steam_guard_code $guard\n";
+	}
+	if($user ne '' && $user ne 'anonymous')
+	{
+		print FILE "login $user $pass\n";
+	}
+	else
+	{
+		print FILE "login anonymous\n";
+	}
+	
+	print FILE "force_install_dir $windows_home_path\n";
+	
+	if($modname ne "")
+	{
+		print FILE "app_set_config $mod mod $modname\n"
+	}
+
+	if($betaname ne "" && $betapwd ne "")
+	{
+		print FILE "app_update $mod -beta $betaname -betapassword $betapwd validate\n";
+	}
+	elsif($betaname ne "" && $betapwd eq "")
+	{
+		print FILE "app_update $mod -beta $betaname validate\n";
+	}
+	else
+	{
+		print FILE "app_update $mod validate\n";
+	}
+	
+	print FILE "exit\n";
+	close FILE;
+  
+    my $bash_scripts_path = MANUAL_TMP_DIR . "/home_id_" . $home_id;
+	
+	if ( check_b4_chdir($bash_scripts_path) != 0)
+	{
+		return 0;
+	}
+	
+	my $log_file = Path::Class::File->new(SCREEN_LOGS_DIR, "screenlog.$screen_id");
+	backup_home_log( $home_id, $log_file );
+	
+	my $postcmd_mod = $postcmd;
+	my @installcmds = ("$steam_binary +runscript $installtxt +exit");
+	my $installfile = create_bash_scripts( $home_path, $bash_scripts_path, $precmd, $postcmd_mod, @installcmds );
+	
+	my $screen_cmd = create_screen_cmd($screen_id, "./$installfile");
+	logger "Running steam update: $steam_binary +runscript $installtxt +exit";
+	system($screen_cmd);
+
+	return 1;
+}
+
+sub rsync_progress
+{
+	my ($running_home) = &decrypt_param(@_);
+	logger "User requested progress on rsync job on home $running_home.";
+	if (-r $running_home)
+	{
+		$running_home =~ s/\s/\\ /g;
+		my $progress = `du -sk $running_home`;
+		chomp($progress);
+		my ($bytes, $junk) = split(/\s+/, $progress);
+		logger("Found $bytes and $junk");
+		return $bytes;
+	}
+	return "0";
+}
+
+sub is_file_download_in_progress
+{
+	my ($pid) = &decrypt_param(@_);
+	logger "User requested if download is in progress with pid $pid.";
+	my @pids = `ps -ef`;
+	@pids = grep(/$pid/, @pids);
+	logger "Number of pids for file download: @pids";
+	if (@pids > '0')
+	{
+		return 1;
+	}
+	return 0;
+}
+
+### \return 1 If file is uncompressed succesfully.
+### \return 0 If file does not exist.
+### \return -1 If file could not be uncompressed.
+sub uncompress_file
+{
+	return uncompress_file_without_decrypt(decrypt_params(@_));
+}
+
+sub uncompress_file_without_decrypt
+{
+
+	# File must include full path.
+	my ($file, $destination) = @_;
+
+	logger "Uncompression called for file $file to dir $destination.";
+
+	if (!-e $file)
+	{
+		logger "File $file could not be found for uncompression.";
+		return 0;
+	}
+
+	if (!-e $destination)
+	{
+		mkpath($destination, {error => \my $err});
+		if (@$err)
+		{
+			logger "Failed to create destination dir $destination.";
+			return 0;
+		}
+	}
+
+	my $ae = Archive::Extract->new(archive => $file);
+
+	if (!$ae)
+	{
+		logger "Could not create archive instance for file $file.";
+		return -1;
+	}
+
+	my $ok = $ae->extract(to => $destination);
+
+	if (!$ok)
+	{
+		logger "File $file could not be uncompressed.";
+		return -1;
+	}
+
+	system("chmod -Rf 755 $destination");
+	system("cd $destination && find -iname \\\*.exe -exec chmod -f +x {} \\\;");
+	system("cd $destination && find -iname \\\*.bat -exec chmod -f +x {} \\\;");
+
+	logger "File uncompressed/extracted successfully.";
+	return 1;
+
+	# TODO: This is still WIP. Remove lines above to continue.
+
+	my $common_path = '';
+
+	# TODO: These might not work on all systems if dir separator isn't /
+	if ($ae->files->[0] =~ /^.*\/$/)
+	{
+		$common_path = $ae->files->[0];
+	}
+	else
+	{
+		my @file_path_tmp = split('/', $ae->files->[0]);
+
+		if (@file_path_tmp > 1)
+		{
+			$common_path = $file_path_tmp[0] . '/';
+		}
+	}
+
+	if ($common_path ne '')
+	{
+		my $match = 1;
+
+		my $file_list = $ae->files;
+
+		# Check that every file contains the common path.
+		foreach (@$file_list)
+		{
+			next if (s!$common_path!$_!);
+
+			logger "File mismatch: $_ to $common_path";
+			$match = 0;
+			last;
+		}
+
+		# If all files did not include the common path we should extract
+		# the file to the home. Reset path.
+		if ($match != 1)
+		{
+			$common_path = '';
+		}
+
+		logger "Common path is: $common_path";
+	}
+
+	#local $File::Copy::Recursive::SkipFlop = 1;
+	#my ($num_of_f_and_d,$nb_of_d,$depth_traversed) = dircopy("teamspeak3-server_linux-x86/", "copy/");
+	#logger "$num_of_f_and_d,$nb_of_d,$depth_traversed";
+
+	logger "File uncompressed/extracted successfully.";
+	return 1;
+}
+
+sub discover_ips
+{
+	my ($check) = decrypt_params(@_);
+
+	if ($check ne "chk")
+	{
+		logger "Invalid parameter '$check' given for discover_ips function.";
+		return "";
+	}
+	
+	my $iplist = "";
+	
+	my @data = `ipconfig /all`;
+
+	foreach my $temp (@data)
+	{
+		if ($temp =~ /ip.+: (\d+\.\d+\.\d+\.\d+)/si)
+		{
+			chomp $1;
+			logger "Found an IP $1";
+			$iplist .= "$1,";
+		}
+	}
+	logger "IPlist is $iplist";
+	chop $iplist;
+	return "$iplist";
+}
+
+### Return -1 In case of invalid param
+### Return 1;content in case of success
+sub mon_stats
+{
+	my ($mon_stats) = decrypt_params(@_);
+	if ($mon_stats ne "mon_stats")
+	{
+		logger "Invalid parameter '$mon_stats' given for $mon_stats function.";
+		return -1;
+	}
+
+	my @disk			= `df -hP -x tmpfs`;
+	my $encoded_content = encode_list(@disk);
+	my @uptime		  = `net stats srv`;
+	$encoded_content .= encode_list(@uptime);
+	return "1;$encoded_content";
+}
+
+sub exec
+{
+	my ($command) = decrypt_params(@_);
+	my @cmdret		   = `$command`;
+	my $encoded_content = encode_list(@cmdret);
+	logger "$command sent.";
+	return "1;$encoded_content";
+}
+
+# used in conjunction with the clone_home feature in the web panel
+# this actually does the file copies
+sub clone_home
+{
+	my ($source_home, $dest_home, $owner) = decrypt_params(@_);
+	my ($time_start, $time_stop, $time_diff);
+	logger "Copying from $source_home to $dest_home...";
+
+	# check size of source_home, make sure we have space to copy
+	if (!-e $source_home)
+	{
+		logger "ERROR - $source_home does not exist";
+		return 0;
+	}
+	logger "Game home $source_home exists...copy will proceed";
+
+	# start the copy, and a timer
+	$time_start = time();
+	if (!dircopy("$source_home", "$dest_home"))
+	{
+		$time_stop = time();
+		$time_diff = $time_stop - $time_start;
+		logger
+		  "Error occured after $time_diff seconds during copy of $source_home to $dest_home - $!";
+		return 0;
+	}
+	else
+	{
+		$time_stop = time();
+		$time_diff = $time_stop - $time_start;
+		logger
+		  "Home clone completed successfully to $dest_home in $time_diff seconds";
+		logger "Using chown -R $owner $dest_home to set home ownership";
+		`chown -R $owner $dest_home`;
+		return 1;
+	}
+
+	# caputre copy return code, stop timer
+
+	# return to success/fail
+}
+
+# used to delete the game home from the file system when it's removed from the panel
+sub remove_home
+{
+	my ($home_path_del) = decrypt_params(@_);
+
+	if (!-e $home_path_del)
+	{
+		logger "ERROR - $home_path_del does not exist...nothing to do";
+		return 0;
+	}
+
+	sleep 1 while ( !pathrmdir("$home_path_del") );
+
+	logger "Deletetion of $home_path_del successful!";
+	return 1;
+}
+
+### Restart the server
+## return -2 CANT STOP
+## return -1  CANT START (no startup file found that mach the home_id, port and ip)
+## return 1 Restart OK
+sub restart_server
+{
+	my ($home_id, $server_ip, $server_port, $control_protocol,
+		$control_password, $control_type, $home_path, $server_exe, $run_dir,
+		$cmd, $cpu, $nice) = decrypt_params(@_);
+
+	if (stop_server_without_decrypt($home_id, $server_ip, 
+									$server_port, $control_protocol,
+									$control_password, $control_type) == 0)
+	{
+		if (universal_start_without_decrypt($home_id, $home_path, $server_exe, $run_dir,
+											$cmd, $server_port, $server_ip, $cpu, $nice) == 1)
+		{
+			return 1;
+		}
+		else
+		{
+			return -1;
+		}
+	}
+	else
+	{
+		return -2;
+	}
+}
+
+sub sudo_exec
+{
+	my $sudo_exec = &decrypt_param(@_);
+	return sudo_exec_without_decrypt($sudo_exec);
+}
+
+sub sudo_exec_without_decrypt
+{
+	my ($command) = @_;
+	my @cmdret = `$command`;
+	logger "Executed: $command";
+	my $encoded_content = encode_list(@cmdret);
+	if ($? == 0)
+	{
+		return "1;$encoded_content";
+	}
+	return 0;
+}
+
+sub secure_path
+{   
+	my ($action, $file_path) = decrypt_params(@_);
+
+	if($action eq "chattr+i")
+	{
+		return "1;";
+	}
+	elsif($action eq "chattr-i")
+	{
+		return "1;";
+	}
+}
+
+sub get_chattr
+{   
+	my ($file_path) = decrypt_params(@_);
+	return "1;";
+}
+
+sub ftp_mgr
+{
+	my ($action, $login, $password, $home_path) = decrypt_params(@_);
+	my $ogp_user = `echo \$USERNAME`;
+	chomp $ogp_user;
+	
+	if(!defined($Cfg::Preferences{ogp_manages_ftp}) || (defined($Cfg::Preferences{ogp_manages_ftp}) &&  $Cfg::Preferences{ogp_manages_ftp} eq "1")){
+	
+		if($action eq "list")
+		{
+			return sudo_exec_without_decrypt("pure-pw list");
+		}
+		elsif($action eq "userdel")
+		{
+			return sudo_exec_without_decrypt("pure-pw userdel ".$login." && pure-pw mkdb");
+		}
+		elsif($action eq "useradd")
+		{
+			return sudo_exec_without_decrypt("(echo ".$password."; echo ".$password.") | pure-pw useradd ".$login." -u ".$ogp_user." -d ".$home_path." && pure-pw mkdb");
+		}
+		elsif($action eq "passwd")
+		{
+			return sudo_exec_without_decrypt("(echo ".$password."; echo ".$password.") | pure-pw passwd ".$login." && pure-pw mkdb");
+		}
+		elsif($action eq "show")
+		{
+			return sudo_exec_without_decrypt("pure-pw show ".$login);
+		}
+		elsif($action eq "usermod")
+		{
+			my $update_account = "pure-pw usermod " . $login . " -u " . $ogp_user;
+			
+			my @account_settings = split /[\n]+/, $password;
+			
+			foreach my $setting (@account_settings) {
+				my ($key, $value) = split /[\t]+/, $setting;
+				
+				if( $key eq 'Directory' )
+				{
+					$update_account .= " -d " . $value;
+				}
+					
+				if( $key eq 'Full_name' )
+				{
+					if(  $value ne "" )
+					{
+						$update_account .= " -c " . $value;
+					}
+					else
+					{
+						$update_account .= ' -c ""';
+					}
+				}
+				
+				if( $key eq 'Download_bandwidth' && $value ne ""  )
+				{
+					my $Download_bandwidth;
+					if($value eq 0)
+					{
+						$Download_bandwidth = "\"\"";
+					}
+					else
+					{
+						$Download_bandwidth = $value;
+					}
+					$update_account .= " -t " . $Download_bandwidth;
+				}
+				
+				if( $key eq 'Upload___bandwidth' && $value ne "" )
+				{
+					my $Upload___bandwidth;
+					if($value eq 0)
+					{
+						$Upload___bandwidth = "\"\"";
+					}
+					else
+					{
+						$Upload___bandwidth = $value;
+					}
+					$update_account .= " -T " . $Upload___bandwidth;
+				}
+				
+				if( $key eq 'Max_files' )
+				{
+					if( $value eq "0" )
+					{
+						$update_account .= ' -n ""';
+					}
+					elsif( $value ne "" )
+					{
+						$update_account .= " -n " . $value;
+					}
+					else
+					{
+						$update_account .= ' -n ""';
+					}
+				}
+									
+				if( $key eq 'Max_size' )
+				{
+					if( $value ne "" )
+					{
+						$update_account .= " -N " . $value;
+					}
+					else
+					{
+						$update_account .= ' -N ""';
+					}
+				}
+									
+				if( $key eq 'Ratio' && $value ne ""  )
+				{
+					my($upload_ratio,$download_ratio) = split/:/,$value;
+					
+					if($upload_ratio eq "0")
+					{
+						$upload_ratio = "\"\"";
+					}
+					$update_account .= " -q " . $upload_ratio;
+					
+					if($download_ratio eq "0")
+					{
+						$download_ratio = "\"\"";
+					}
+					$update_account .= " -Q " . $download_ratio;
+				}
+				
+				if( $key eq 'Allowed_client_IPs' )
+				{
+					if( $value ne "" )
+					{
+						$update_account .= " -r " . $value;
+					}
+					else
+					{
+						$update_account .= ' -r ""';
+					}
+				}
+									
+				if( $key eq 'Denied__client_IPs' )
+				{
+					if( $value ne "" )
+					{
+						$update_account .= " -R " . $value;
+					}
+					else
+					{
+						$update_account .= ' -R ""';
+					}
+				}
+				
+				if( $key eq 'Allowed_local__IPs' )
+				{
+					if( $value ne "" )
+					{
+						$update_account .= " -i " . $value;
+					}
+					else
+					{
+						$update_account .= ' -i ""';
+					}
+				}
+									
+				if( $key eq 'Denied__local__IPs' )
+				{
+					if( $value ne "" )
+					{
+						$update_account .= " -I " . $value;
+					}
+					else
+					{
+						$update_account .= ' -I ""';
+					}
+				}
+				
+					
+				if( $key eq 'Max_sim_sessions' && $value ne "" )
+				{
+					$update_account .= " -y " . $value;
+				}
+				
+				if ( $key eq 'Time_restrictions'  )
+				{
+					if( $value eq "0000-0000")
+					{
+						$update_account .= ' -z ""';
+					}
+					elsif( $value ne "" )
+					{
+						$update_account .= " -z " . $value;
+					}
+					else
+					{
+						$update_account .= ' -z ""';
+					}
+				}
+			}
+			$update_account .=" && pure-pw mkdb";
+			# print $update_account;
+			return sudo_exec_without_decrypt($update_account);
+		}
+	}
+	return 0;
+}

+ 8 - 0
OGP/ogp_screenrc

@@ -0,0 +1,8 @@
+startup_message off
+hardstatus on
+hardstatus alwayslastline '%{gk}[ %{G}%H %{g}][%= %{wk}%?%-Lw%?%{=b kR}[%{W}%n%f %t%?(%u)%?%{=b kR}]%{= kw}%?%+Lw%?%?%= %{g}][%{Y}%l%{g}]%{=b C}[ %D %m/%d %C%a ]%{W}'
+# Default scroll back 100
+defscrollback 100
+deflog on
+logfile /OGP/screenlogs/screenlog.%t
+

+ 5 - 0
README.md

@@ -0,0 +1,5 @@
+Open Game Panel Windows Agent
+===============
+This is the Windows agent of the Open Game Panel project
+
+Check the install instructions at www.opengamepanel.org

+ 19 - 0
win_script/README.txt

@@ -0,0 +1,19 @@
+BOTH SCRIPTS:
+Both installers must be run as administrator.
+This script will install all in the folder where it is executed.
+CygWin and all the scripts must be installed in the same folder.
+Do not change any option in the cygwin setup but the main mirror. 
+Cygports mirror ( mirros.kernel.org ) must be checked as well.
+After the first Cygwin installation you should use the commands
+mkpasswd and mkgroup to generate the file /etc/passwd:
+
+mkpasswd -l > /etc/passwd
+mkgroup -l > /etc/group
+
+This is usefull to prevent the error:
+"Unable to open the passwd file: No such file or directory"
+
+PANEL SCRIPT:
+Stop the agent and pure-ftpd before running the panel installer, 
+because apache2 needs to use 'rebaseall -v' from the dash shell to get it working properly,
+and this action requieres all processes stopped before running it.

+ 91 - 0
win_script/agent_installer-x86_64.bat

@@ -0,0 +1,91 @@
+@echo off
+net session >nul 2>&1
+if NOT %errorLevel% == 0 (
+	echo Failure: Current permissions inadequate.
+	echo[
+	echo Run this script by using "Run as administrator" in the context menu.
+	pause >nul
+	exit
+)
+set WD=%~dp0
+pushd %WD%
+REM Create a vbs file that downloads the setup binary for Cygwin
+echo strFileURL = "http://cygwin.com/setup-x86_64.exe" > dwl_setup.vbs
+echo Dim strSavePath >> dwl_setup.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\setup-x86_64.exe" >> dwl_setup.vbs
+echo Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") >> dwl_setup.vbs
+echo objXMLHTTP.open "GET", strFileURL, false >> dwl_setup.vbs
+echo objXMLHTTP.send() >> dwl_setup.vbs
+echo If objXMLHTTP.Status = 200 Then >> dwl_setup.vbs
+echo     Set objADOStream = CreateObject("ADODB.Stream") >> dwl_setup.vbs
+echo     objADOStream.Open >> dwl_setup.vbs
+echo     objADOStream.Type = 1 'adTypeBinary >> dwl_setup.vbs
+echo     objADOStream.Write objXMLHTTP.ResponseBody >> dwl_setup.vbs
+echo     objADOStream.Position = 0 >> dwl_setup.vbs
+echo     Set objFso = Createobject("Scripting.FileSystemObject") >> dwl_setup.vbs
+echo     If objFso.Fileexists(strSavePath) Then objFSO.DeleteFile strSavePath >> dwl_setup.vbs
+echo     Set objFso = Nothing >> dwl_setup.vbs
+echo     objADOStream.SaveToFile strSavePath >> dwl_setup.vbs
+echo     objADOStream.Close >> dwl_setup.vbs
+echo     Set objADOStream = Nothing >> dwl_setup.vbs
+echo End if >> dwl_setup.vbs
+echo Set objXMLHTTP = Nothing >> dwl_setup.vbs
+REM Advice 
+echo DO NOT CLOSE THIS WINDOW YET.
+echo The setup process will continue once cygwin installation ends.
+echo WARNING, the ftp server is not available in 64bit. Even if the 64bit environment is highly recommendable, there is no suitable package for pure-ftpd.
+REM start the download for Cygwin setup.exe 
+dwl_setup.vbs
+REM start the setup for cygwin with the requiered repositories, paths and packages
+setup-x86_64.exe -K http://cygwinports.org/ports.gpg -s ftp://mirrors.kernel.org/sources.redhat.com/cygwinports -s ftp://ftp.gwdg.de/pub/linux/sources.redhat.com/cygwin --quiet-mode --packages pure-ftpd --packages libssp0 --packages screen --packages subversion --packages perl --packages perl-XML-Parser --packages perl-HTTP-Daemon --packages wget --packages unzip --packages tar --packages gawk --packages pure-ftpd --packages screen --packages bzip2 --packages wget --packages zip --packages unzip --packages nano --packages rsync --root %WD% --local-package-dir %WD%cygTemp  -P crypt -P csih -P diffutils -P gettext -P groff -P less -P libapr1 -P libaprutil1 -P libasn1_8 -P libattr1 -P libbz2_1 -P libcom_err2 -P libdb4.5 -P libdb4.8 -P libexpat1 -P libffi6 -P libgcc1 -P libgcrypt11 -P libgdbm4 -P libgmp10	-P libgmp3	-P libgnutls26 -P libgpg-error0 -P libgssapi3 -P libheimbase1 -P libheimntlm0 -P libhx509_5 -P libiconv2 -P libidn11 -P libintl8 -P libiodbc2 -P libkrb5_26 -P liblzma5 -P liblzo2_2 -P libmpfr4 -P libmysqlclient18 -P libncurses10 -P libncursesw10 -P libneon27 -P libopenldap2_4_2 -P libopenssl098 -P libopenssl100 -P libp11-kit0 -P libpcre0 -P libpopt0 -P libpq5 -P libproxy1 -P libroken18 -P libsasl2_3 -P libserf1_0 -P libsqlite3_0 -P libssp0 -P libstdc++6 -P libtasn1_3 -P libuuid1 -P libwind0 -P libxml2 -P openssl -P perl_vendor -P texinfo -P xz -P _autorebase -P _update-info-dir -P perl-Path-Class -P libasprintf0 -P libcrypt0 -P libdb5.3 -P libpcre1 -P libreadline7 -P perl-Encode-Locale -P perl-File-Listing -P perl-HTML-Parser -P perl-HTML-Tagset -P perl-HTTP-Cookies -P perl-HTTP-Date -P perl-HTTP-Message -P perl-HTTP-Negotiate -P perl-LWP -P perl-LWP-MediaTypes -P perl-Net-HTTP -P perl-URI -P perl-WWW-RobotRules -P terminfo -P perl-YAML -P make > cygwin64_setup.log
+REM Set the needed enviroment variables to run Cygwin executables without writing the full path
+set path=%WD%\bin;%WD%\usr\sbin;%path%
+set SHELL=/bin/bash
+mkpasswd -l > /etc/passwd
+mkgroup -l > /etc/group
+REM Create batch files to start and stop the agent
+echo @echo off> agent_start.bat
+echo set WD=%%~dp0>> agent_start.bat
+echo pushd %%WD%%>> agent_start.bat
+echo set path=%%WD%%bin;%%WD%%usr\sbin;%%path%%>> agent_start.bat
+echo set CYGWIN=server ntsec>> agent_start.bat
+echo set SHELL=/bin/bash>> agent_start.bat
+cp -f agent_start.bat agent_stop.bat
+echo set /p PID1=^<%%WD%%OGP\ogp_agent.pid>> agent_stop.bat
+echo kill -15 %%PID1%%>> agent_stop.bat
+echo set /p PID2=^<%%WD%%var\run\pure-ftpd.pid>> agent_stop.bat
+echo kill -15 %%PID2%%>> agent_stop.bat
+echo set /p PID3=^<%%WD%%OGP\ogp_agent_run.pid>> agent_stop.bat
+echo kill -15 %%PID3%%>> agent_stop.bat
+echo rm -Rf /OGP/.svn>> agent_start.bat
+echo rm -Rf /usr/bin/.svn>> agent_start.bat
+echo bash ogp_agent -pidfile /OGP/ogp_agent_run.pid>> agent_start.bat
+REM Create a vbs to run agent_start.bat hidden
+echo Dim strSavePath> agent_start_background.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\agent_start.bat">> agent_start_background.vbs
+echo CreateObject("Wscript.Shell").Run "" ^& strSavePath ^& "" , 0, false>> agent_start_background.vbs
+REM download the bash script that starts the agent setup 
+echo Downloading the agent setup bash script from SVN ...
+svn co svn://svn.code.sf.net/p/hldstart/code/trunk/agent_win/bin bin
+chmod +x bin/ogp_install
+REM Asks for adding OGP agent to the system startup 
+set /p ONBOOT= Start OGP agent at system boot[Y/n]:
+IF "X%ONBOOT%" == "X" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "Xy" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "XN" (
+set ONBOOT=n
+)
+IF "X%ONBOOT%" == "XY" (
+set /p PASS=please enter the password for user '%USERNAME%':
+schtasks /create /tn "OGP agent start on boot" /rl highest /ru %USERDOMAIN%\%USERNAME% /rp "%PASS%" /tr %WD%agent_start.bat /sc onstart
+) ELSE (
+IF "X%ONBOOT%" == "Xn" (
+schtasks /delete /tn "OGP agent start on boot"
+)
+)
+REM run the agent setup
+bash -i ogp_install

+ 89 - 0
win_script/agent_installer.bat

@@ -0,0 +1,89 @@
+@echo off
+net session >nul 2>&1
+if NOT %errorLevel% == 0 (
+	echo Failure: Current permissions inadequate.
+	echo[
+	echo Run this script by using "Run as administrator" in the context menu.
+	pause >nul
+	exit
+)
+set WD=%~dp0
+pushd %WD%
+REM Create a vbs file that downloads the setup binary for Cygwin
+echo strFileURL = "http://cygwin.com/setup-x86.exe" > dwl_setup.vbs
+echo Dim strSavePath >> dwl_setup.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\setup-x86.exe" >> dwl_setup.vbs
+echo Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") >> dwl_setup.vbs
+echo objXMLHTTP.open "GET", strFileURL, false >> dwl_setup.vbs
+echo objXMLHTTP.send() >> dwl_setup.vbs
+echo If objXMLHTTP.Status = 200 Then >> dwl_setup.vbs
+echo     Set objADOStream = CreateObject("ADODB.Stream") >> dwl_setup.vbs
+echo     objADOStream.Open >> dwl_setup.vbs
+echo     objADOStream.Type = 1 'adTypeBinary >> dwl_setup.vbs
+echo     objADOStream.Write objXMLHTTP.ResponseBody >> dwl_setup.vbs
+echo     objADOStream.Position = 0 >> dwl_setup.vbs
+echo     Set objFso = Createobject("Scripting.FileSystemObject") >> dwl_setup.vbs
+echo     If objFso.Fileexists(strSavePath) Then objFSO.DeleteFile strSavePath >> dwl_setup.vbs
+echo     Set objFso = Nothing >> dwl_setup.vbs
+echo     objADOStream.SaveToFile strSavePath >> dwl_setup.vbs
+echo     objADOStream.Close >> dwl_setup.vbs
+echo     Set objADOStream = Nothing >> dwl_setup.vbs
+echo End if >> dwl_setup.vbs
+echo Set objXMLHTTP = Nothing >> dwl_setup.vbs
+REM Advice 
+echo DO NOT CLOSE THIS WINDOW YET.
+echo The setup process will continue once cygwin installation ends.
+REM start the download for Cygwin setup.exe 
+dwl_setup.vbs
+REM start the setup for cygwin with the requiered repositories, paths and packages
+setup-x86.exe -K http://cygwinports.org/ports.gpg -s ftp://mirrors.kernel.org/sources.redhat.com/cygwinports -s ftp://ftp.gwdg.de/pub/linux/sources.redhat.com/cygwin --quiet-mode --packages screen --packages subversion --packages perl --packages wget --packages unzip --packages tar --packages gawk --packages pure-ftpd --packages screen --packages bzip2 --packages wget --packages zip --packages unzip --packages nano --packages rsync --root %WD% --local-package-dir %WD%cygTemp -P crypt -P csih -P diffutils -P gettext -P groff -P less -P libapr1 -P libaprutil1 -P libasn1_8 -P libattr1 -P libbz2_1 -P libcom_err2 -P libdb4.5 -P libdb4.8 -P libexpat1 -P libffi6 -P libgcc1 -P libgcrypt11 -P libgdbm4 -P libgmp10	-P libgmp3	-P libgnutls26 -P libgpg-error0 -P libgssapi3 -P libheimbase1 -P libheimntlm0 -P libhx509_5 -P libiconv2 -P libidn11 -P libintl8 -P libiodbc2 -P libkrb5_26 -P liblzma5 -P liblzo2_2 -P libmpfr4 -P libmysqlclient18 -P libncurses10 -P libncursesw10 -P libneon27 -P libopenldap2_4_2 -P libopenssl098 -P libopenssl100 -P libp11-kit0 -P libpcre0 -P libpopt0 -P libpq5 -P libproxy1 -P libroken18 -P libsasl2_3 -P libserf1_0 -P libsqlite3_0 -P libssp0 -P libstdc++6 -P libtasn1_3 -P libuuid1 -P libwind0 -P libxml2 -P openssl -P perl_vendor -P texinfo -P xz -P _autorebase -P _update-info-dir -P perl-Path-Class -P perl-YAML -P make -P libpcre1> cygwin_setup.log
+REM Set the needed enviroment variables to run Cygwin executables without writing the full path
+set path=%WD%\bin;%WD%\usr\sbin;%path%
+set SHELL=/bin/bash
+REM Create batch files to start and stop the agent
+echo @echo off> agent_start.bat
+echo set WD=%%~dp0>> agent_start.bat
+echo pushd %%WD%%>> agent_start.bat
+echo set path=%%WD%%bin;%%WD%%usr\sbin;%%path%%>> agent_start.bat
+echo set CYGWIN=server ntsec>> agent_start.bat
+echo set SHELL=/bin/bash>> agent_start.bat
+cp -f agent_start.bat agent_stop.bat
+echo set /p PID1=^<%%WD%%OGP\ogp_agent.pid>> agent_stop.bat
+echo kill -15 %%PID1%%>> agent_stop.bat
+echo set /p PID2=^<%%WD%%var\run\pure-ftpd.pid>> agent_stop.bat
+echo kill -15 %%PID2%%>> agent_stop.bat
+echo set /p PID3=^<%%WD%%OGP\ogp_agent_run.pid>> agent_stop.bat
+echo kill -15 %%PID3%%>> agent_stop.bat
+echo rm -Rf /OGP/.svn>> agent_start.bat
+echo rm -Rf /usr/bin/.svn>> agent_start.bat
+echo bash ogp_agent -pidfile /OGP/ogp_agent_run.pid>> agent_start.bat
+REM Create a vbs to run agent_start.bat hidden
+echo Dim strSavePath> agent_start_background.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\agent_start.bat">> agent_start_background.vbs
+echo CreateObject("Wscript.Shell").Run "" ^& strSavePath ^& "" , 0, false>> agent_start_background.vbs
+REM download the bash script that starts the agent setup 
+echo Downloading the agent setup bash script from SVN ...
+svn co svn://svn.code.sf.net/p/hldstart/code/trunk/agent_win/bin bin
+chmod +x bin/ogp_install
+REM Asks for adding OGP agent to the system startup 
+set /p ONBOOT= Start OGP agent at system boot[Y/n]:
+IF "X%ONBOOT%" == "X" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "Xy" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "XN" (
+set ONBOOT=n
+)
+IF "X%ONBOOT%" == "XY" (
+set /p PASS=please enter the password for user '%USERNAME%':
+schtasks /create /tn "OGP agent start on boot" /rl highest /ru %USERDOMAIN%\%USERNAME% /rp "%PASS%" /tr %WD%agent_start.bat /sc onstart
+) ELSE (
+IF "X%ONBOOT%" == "Xn" (
+schtasks /delete /tn "OGP agent start on boot"
+)
+)
+REM run the agent setup
+bash -i ogp_install
+

+ 165 - 0
win_script/panel_installer-x86_64.bat

@@ -0,0 +1,165 @@
+@echo off
+net session >nul 2>&1
+if NOT %errorLevel% == 0 (
+	echo Failure: Current permissions inadequate.
+	echo[
+	echo Run this script by using "Run as administrator" in the context menu.
+	pause >nul
+	exit
+)
+set WD=%~dp0
+pushd %WD%
+REM Set the needed enviroment variables to run Cygwin executables without writing the full path
+set CYGWIN=server ntsec
+set path=%WD%\bin;%WD%\usr\sbin;%path%
+set SHELL=/bin/bash
+REM Create a vbs script that downloads the installer for Cygwin
+echo strFileURL = "http://cygwin.com/setup-x86_64.exe" > dwl_setup.vbs
+echo Dim strSavePath >> dwl_setup.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\setup-x86_64.exe" >> dwl_setup.vbs
+echo Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") >> dwl_setup.vbs
+echo objXMLHTTP.open "GET", strFileURL, false >> dwl_setup.vbs
+echo objXMLHTTP.send() >> dwl_setup.vbs
+echo If objXMLHTTP.Status = 200 Then >> dwl_setup.vbs
+echo     Set objADOStream = CreateObject("ADODB.Stream") >> dwl_setup.vbs
+echo     objADOStream.Open >> dwl_setup.vbs
+echo     objADOStream.Type = 1 'adTypeBinary >> dwl_setup.vbs
+echo     objADOStream.Write objXMLHTTP.ResponseBody >> dwl_setup.vbs
+echo     objADOStream.Position = 0 >> dwl_setup.vbs
+echo     Set objFso = Createobject("Scripting.FileSystemObject") >> dwl_setup.vbs
+echo     If objFso.Fileexists(strSavePath) Then objFSO.DeleteFile strSavePath >> dwl_setup.vbs
+echo     Set objFso = Nothing >> dwl_setup.vbs
+echo     objADOStream.SaveToFile strSavePath >> dwl_setup.vbs
+echo     objADOStream.Close >> dwl_setup.vbs
+echo     Set objADOStream = Nothing >> dwl_setup.vbs
+echo End if >> dwl_setup.vbs
+echo Set objXMLHTTP = Nothing >> dwl_setup.vbs
+REM Advice 
+echo DO NOT CLOSE THIS WINDOW YET.
+echo The setup process will continue once cygwin installation ends.
+REM start the download for Cygwin setup.exe 
+dwl_setup.vbs
+REM start the setup for cygwin with the requiered repositories, paths and packages
+setup-x86_64.exe -K http://cygwinports.org/ports.gpg -s ftp://mirrors.kernel.org/sources.redhat.com/cygwinports -s ftp://ftp.gwdg.de/pub/linux/sources.redhat.com/cygwin --quiet-mode --root %WD% --local-package-dir %WD%cygTemp -P apache2 -P php5 -P mysql -P mysqld -P apache2-mod_php5 -P php -P php-Archive_Tar -P php-xmlrpc -P php-curl -P php-xmlreader -P php-simplexml -P php-json -P php-mysql -P php-gd -P php-PEAR -P php-session -P php-ftp -P php-ctype -P php-zip -P curl -P cygrunsrv -P subversion -P cron -P dos2unix -P bzip2 -P ca-certificates -P crypt -P csih -P diffutils -P gettext -P groff -P less -P libarp1 -P libaprutil1 -P libasn1_8 -P libattr1 -P libbz2_1 -P libcom_err2 -P libcurl4 -P libdb4.5 -P libdb4.8 -P libexpat1 -P libfreetype6 -P libgcc1 -P libgdbm4 -P libgmp10 -P libgmp3 -P libgssapi3 -P libheimbase1 -P libheimntlm0 -P libhx509_5 -P libiconv2 -P libidn11 -P libintl8 -P libiodbc2 -P libjpeg8 -P libkrb5_26 -P liblzma5 -P libmetalink3 -P libmpfr4 -P libmysqlclient18 -P libncurses10 -P libncursesw10 -P libneon27 -P libopenldap2_4_2 -P libopenssl100 -P libpcre0 -P libpcre1 -P libpng15 -P libpopt0 -P libpq5 -P libproxy1 -P libroken18 -P libsasl2_3 -P libserf1_0 -P libsqlite3_0 -P libssh2_1 -P libssp0 -P libstdc++6 -P libuuid1 -P libuuid1 -P libvpx1 -P libwind0 -P libwrap0 -P libX11_6 -P libXau6 -P libxcb1 -P libXdmcp6 -P libxml2 -P libXpm4 -P openssl -P perl -P perl-Clone -P perl-DBD-mysql -P perl-DBI -P perl_vendor -P php-bz2 -P php-Console_Getopt -P php-Structures_Graph -P php-XML_Util -P php-zlib -P php-mbstring -P t1lib5 -P texinfo -P xz -P _autorebase -P _update-info-dir -P libapr1 -P libasprintf0 -P libcrypt0 -P libdb5.3 -P libreadline7 -P perl-Params-Util -P terminfo > cygwin_setup.log
+mkpasswd -l > /etc/passwd
+mkgroup -l > /etc/group
+REM Stop servers and remove any service that can be running from a previous setup
+net stop cygserver
+net stop cron
+set /p MYSQLD_PID=<%WD%var\run\mysqld.pid
+kill -15 %MYSQLD_PID%
+bash /usr/sbin/apachectl2 stop
+cls
+sc delete cygserver
+sc delete cron
+cls
+REM Runs 'rebaseall' that fixes owners and/or permissions for all Cygwin file system
+dash -c '/usr/bin/rebaseall -v'
+REM Runs the the setup for cygserver service
+bash cygserver-config
+REM Creating a bash script that configures cron as service with the administrator privilegies of the current user
+echo In order to schedule tasks from the panel,
+echo you need to run cron as a Windows administrator so
+set /p PASS=please enter the password for user '%USERNAME%':
+echo cron-config ^<^< EOF> auto-cron-config
+echo yes>> auto-cron-config
+echo[>> auto-cron-config
+echo no>> auto-cron-config
+echo no>> auto-cron-config
+echo no>> auto-cron-config
+echo %PASS%>> auto-cron-config
+echo %PASS%>> auto-cron-config
+echo no>> auto-cron-config
+echo EOF>> auto-cron-config
+dos2unix auto-cron-config
+chmod +x auto-cron-config
+REM Runs the script that configures cron
+bash auto-cron-config
+REM Creating a pair of bash scripts to configure PHP and php-PEAR
+echo if test "$(cat /etc/php5/php.ini | grep "^^include_path")" == ""; then echo "include_path = \".:/usr/share/pear\"" ^>^> /etc/php5/php.ini; fi > test_pear_path
+echo sed -i 's/DirectoryIndex .*/DirectoryIndex index.html index.php/g' /etc/apache2/httpd.conf > test_index_php
+chmod +x test_pear_path 
+chmod +x test_index_php
+dos2unix test_pear_path 
+dos2unix test_index_php
+REM Run PHP scripts
+bash test_pear_path
+bash test_index_php
+REM Delete (once used) useless scripts
+rm -f test_pear_path test_index_php
+cls
+REM Create the database files, needed to run MySQL server
+bash  mysql_install_db
+REM Creating a bash script that starts MySQL server with a pid file
+echo /usr/sbin/mysqld --pid-file=/var/run/mysqld.pid --log-error=/var/log/mysql_err.log> %WD%\bin\mysqld_start
+REM Fixing the file to run in bash and make it executable
+dos2unix /usr/bin/mysqld_start
+chmod +x /usr/bin/mysqld_start
+REM Creating a bash script that stops MySQL server by its pid file
+echo kill -15 ^`cat /var/run/mysqld.pid^` > %WD%\bin\mysqld_stop
+REM Fixing the file to run in bash and make it executable
+dos2unix /usr/bin/mysqld_stop
+chmod +x /usr/bin/mysqld_stop
+REM Creating batch scripts to stop/start MySQL server using bash and their respective bash scripts
+echo @echo off> mysqld_start.bat
+echo set WD=%%~dp0>> mysqld_start.bat
+echo pushd %%WD%%>> mysqld_start.bat
+echo set path=%%WD%%bin;%%WD%%usr\sbin;%%path%%>> mysqld_start.bat
+echo set CYGWIN=server ntsec>> mysqld_start.bat
+echo set SHELL=/bin/bash>> mysqld_start.bat
+cp -f mysqld_start.bat mysqld_stop.bat
+cp -f mysqld_start.bat apache2_stop.bat
+cp -f mysqld_start.bat apache2_start.bat
+echo bash mysqld_start>> mysqld_start.bat
+echo bash mysqld_stop>> mysqld_stop.bat
+REM Creating bash scripts to start/stop Apache2 web server
+echo net start cygserver>> apache2_start.bat
+echo net start httpd2>> apache2_start.bat
+echo net stop httpd2>> apache2_stop.bat
+echo net stop cygserver>> apache2_stop.bat
+REM Creating a vbs script that hiddes the window of the batch script that starts MySQL server
+echo Dim strSavePath> mysql_start_background.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\mysqld_start.bat">> mysql_start_background.vbs
+echo CreateObject("Wscript.Shell").Run "" ^& strSavePath ^& "" , 0, false>> mysql_start_background.vbs
+REM Running MySQL server hidden
+mysql_start_background.vbs
+cls
+echo Waiting for Mysql Server to start...
+@ping 127.0.0.1 -n 15 -w 1000 > nul
+cls
+REM Creating a blank database named ogp_panel to use it for the panel later
+%WD%\bin\mysql -u root -e "CREATE DATABASE ogp_panel";
+cls
+REM Setting up the SQL server
+%WD%\bin\bash mysql_secure_installation
+REM Getting the lastest version of OGP web panel from SVN
+echo Getting the lastest version of OGP web panel from SVN...
+%WD%\bin\svn co svn://svn.code.sf.net/p/hldstart/code/trunk/upload /srv/www/htdocs
+rm -f /srv/www/htdocs/index.html
+REM Asks for adding mysqld and httpd to the system startup 
+set /p ONBOOT= Start MySQL server at system boot[Y/n]:
+IF "X%ONBOOT%" == "X" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "Xy" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "XN" (
+set ONBOOT=n
+)
+IF "X%ONBOOT%" == "XY" (
+schtasks /create /tn "MySQL server start on boot" /rl highest /ru %USERDOMAIN%\%USERNAME% /rp "%PASS%" /tr %WD%mysqld_start.bat /sc onstart
+) ELSE (
+IF "X%ONBOOT%" == "Xn" (
+schtasks /delete /tn "MySQL server start on boot"
+)
+)
+bash /usr/sbin/httpd2-config
+net start cygserver
+net start httpd2
+echo Now you can close this window and complete the installation 
+echo of the panel from http://localhost/install.php.
+echo PS: The database name is ogp_panel.
+pause
+REM Start Intrenet explorer and show the panel setup
+start iexplore "http://localhost/install.php"

+ 165 - 0
win_script/panel_installer.bat

@@ -0,0 +1,165 @@
+@echo off
+net session >nul 2>&1
+if NOT %errorLevel% == 0 (
+	echo Failure: Current permissions inadequate.
+	echo[
+	echo Run this script by using "Run as administrator" in the context menu.
+	pause >nul
+	exit
+)
+set WD=%~dp0
+pushd %WD%
+REM Set the needed enviroment variables to run Cygwin executables without writing the full path
+set CYGWIN=server ntsec
+set path=%WD%\bin;%WD%\usr\sbin;%path%
+set SHELL=/bin/bash
+REM Create a vbs script that downloads the installer for Cygwin
+echo strFileURL = "http://cygwin.com/setup-x86.exe" > dwl_setup.vbs
+echo Dim strSavePath >> dwl_setup.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\setup-x86.exe" >> dwl_setup.vbs
+echo Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP") >> dwl_setup.vbs
+echo objXMLHTTP.open "GET", strFileURL, false >> dwl_setup.vbs
+echo objXMLHTTP.send() >> dwl_setup.vbs
+echo If objXMLHTTP.Status = 200 Then >> dwl_setup.vbs
+echo     Set objADOStream = CreateObject("ADODB.Stream") >> dwl_setup.vbs
+echo     objADOStream.Open >> dwl_setup.vbs
+echo     objADOStream.Type = 1 'adTypeBinary >> dwl_setup.vbs
+echo     objADOStream.Write objXMLHTTP.ResponseBody >> dwl_setup.vbs
+echo     objADOStream.Position = 0 >> dwl_setup.vbs
+echo     Set objFso = Createobject("Scripting.FileSystemObject") >> dwl_setup.vbs
+echo     If objFso.Fileexists(strSavePath) Then objFSO.DeleteFile strSavePath >> dwl_setup.vbs
+echo     Set objFso = Nothing >> dwl_setup.vbs
+echo     objADOStream.SaveToFile strSavePath >> dwl_setup.vbs
+echo     objADOStream.Close >> dwl_setup.vbs
+echo     Set objADOStream = Nothing >> dwl_setup.vbs
+echo End if >> dwl_setup.vbs
+echo Set objXMLHTTP = Nothing >> dwl_setup.vbs
+REM Advice 
+echo DO NOT CLOSE THIS WINDOW YET.
+echo The setup process will continue once cygwin installation ends.
+REM start the download for Cygwin setup.exe 
+dwl_setup.vbs
+REM start the setup for cygwin with the requiered repositories, paths and packages
+setup-x86.exe -K http://cygwinports.org/ports.gpg -s ftp://mirrors.kernel.org/sources.redhat.com/cygwinports -s ftp://ftp.gwdg.de/pub/linux/sources.redhat.com/cygwin --quiet-mode --root %WD% --local-package-dir %WD%cygTemp -P apache2 -P php5 -P mysql -P mysqld -P apache2-mod_php5 -P php -P php-Archive_Tar -P php-xmlrpc -P php-curl -P php-xmlreader -P php-simplexml -P php-json -P php-mysql -P php-gd -P php-PEAR -P php-session -P php-ftp -P php-ctype -P php-zip -P curl -P cygrunsrv -P subversion -P cron -P bzip2 -P ca-certificates -P crypt -P csih -P diffutils -P gettext -P groff -P less -P libarp1 -P libaprutil1 -P libasn1_8 -P libattr1 -P libbz2_1 -P libcom_err2 -P libcurl4 -P libdb4.5 -P libdb4.8 -P libexpat1 -P libfreetype6 -P libgcc1 -P libgdbm4 -P libgmp10 -P libgmp3 -P libgssapi3 -P libheimbase1 -P libheimntlm0 -P libhx509_5 -P libiconv2 -P libidn11 -P libintl8 -P libiodbc2 -P libjpeg8 -P libkrb5_26 -P liblzma5 -P libmetalink3 -P libmpfr4 -P libmysqlclient18 -P libncurses10 -P libncursesw10 -P libneon27 -P libopenldap2_4_2 -P libopenssl100 -P libpcre0 -P libpcre1 -P libpng15 -P libpopt0 -P libpq5 -P libproxy1 -P libroken18 -P libsasl2_3 -P libserf1_0 -P libsqlite3_0 -P libssh2_1 -P libssp0 -P libstdc++6 -P libuuid1 -P libuuid1 -P libvpx1 -P libwind0 -P libwrap0 -P libX11_6 -P libXau6 -P libxcb1 -P libXdmcp6 -P libxml2 -P libXpm4 -P openssl -P perl -P perl-Clone -P perl-DBD-mysql -P perl-DBI -P perl_vendor -P php-bz2 -P php-Console_Getopt -P php-Structures_Graph -P php-XML_Util -P php-zlib -P php-mbstring -P t1lib5 -P texinfo -P xz -P _autorebase -P _update-info-dir -P libapr1 -P libonig2 -P libp11-kit0 -P libtasn1_6 -P p11-kit -P p11-kit-trust> cygwin_setup.log
+mkpasswd -l > /etc/passwd
+mkgroup -l > /etc/group
+REM Stop servers and remove any service that can be running from a previous setup
+net stop cygserver
+net stop cron
+set /p MYSQLD_PID=<%WD%var\run\mysqld.pid
+kill -15 %MYSQLD_PID%
+bash /usr/sbin/apachectl2 stop
+cls
+sc delete cygserver
+sc delete cron
+cls
+REM Runs 'rebaseall' that fixes owners and/or permissions for all Cygwin file system
+dash -c '/usr/bin/rebaseall -v'
+REM Runs the the setup for cygserver service
+bash cygserver-config
+REM Creating a bash script that configures cron as service with the administrator privilegies of the current user
+echo In order to schedule tasks from the panel,
+echo you need to run cron as a Windows administrator so
+set /p PASS=please enter the password for user '%USERNAME%':
+echo cron-config ^<^< EOF> auto-cron-config
+echo yes>> auto-cron-config
+echo[>> auto-cron-config
+echo no>> auto-cron-config
+echo no>> auto-cron-config
+echo no>> auto-cron-config
+echo %PASS%>> auto-cron-config
+echo %PASS%>> auto-cron-config
+echo no>> auto-cron-config
+echo EOF>> auto-cron-config
+dos2unix auto-cron-config
+chmod +x auto-cron-config
+REM Runs the script that configures cron
+bash auto-cron-config
+REM Creating a pair of bash scripts to configure PHP and php-PEAR
+echo if test "$(cat /etc/php5/php.ini | grep "^^include_path")" == ""; then echo "include_path = \".:/usr/share/pear\"" ^>^> /etc/php5/php.ini; fi > test_pear_path
+echo sed -i 's/DirectoryIndex .*/DirectoryIndex index.html index.php/g' /etc/apache2/httpd.conf > test_index_php
+chmod +x test_pear_path 
+chmod +x test_index_php
+dos2unix test_pear_path 
+dos2unix test_index_php
+REM Run PHP scripts
+bash test_pear_path
+bash test_index_php
+REM Delete (once used) useless scripts
+rm -f test_pear_path test_index_php
+cls
+REM Create the database files, needed to run MySQL server
+bash  mysql_install_db
+REM Creating a bash script that starts MySQL server with a pid file
+echo /usr/sbin/mysqld --pid-file=/var/run/mysqld.pid --log-error=/var/log/mysql_err.log> %WD%\bin\mysqld_start
+REM Fixing the file to run in bash and make it executable
+dos2unix /usr/bin/mysqld_start
+chmod +x /usr/bin/mysqld_start
+REM Creating a bash script that stops MySQL server by its pid file
+echo kill -15 ^`cat /var/run/mysqld.pid^` > %WD%\bin\mysqld_stop
+REM Fixing the file to run in bash and make it executable
+dos2unix /usr/bin/mysqld_stop
+chmod +x /usr/bin/mysqld_stop
+REM Creating batch scripts to stop/start MySQL server using bash and their respective bash scripts
+echo @echo off> mysqld_start.bat
+echo set WD=%%~dp0>> mysqld_start.bat
+echo pushd %%WD%%>> mysqld_start.bat
+echo set path=%%WD%%bin;%%WD%%usr\sbin;%%path%%>> mysqld_start.bat
+echo set CYGWIN=server ntsec>> mysqld_start.bat
+echo set SHELL=/bin/bash>> mysqld_start.bat
+cp -f mysqld_start.bat mysqld_stop.bat
+cp -f mysqld_start.bat apache2_stop.bat
+cp -f mysqld_start.bat apache2_start.bat
+echo bash mysqld_start>> mysqld_start.bat
+echo bash mysqld_stop>> mysqld_stop.bat
+REM Creating bash scripts to start/stop Apache2 web server
+echo net start cygserver>> apache2_start.bat
+echo net start httpd2>> apache2_start.bat
+echo net stop httpd2>> apache2_stop.bat
+echo net stop cygserver>> apache2_stop.bat
+REM Creating a vbs script that hiddes the window of the batch script that starts MySQL server
+echo Dim strSavePath> mysql_start_background.vbs
+echo strSavePath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ^& "\mysqld_start.bat">> mysql_start_background.vbs
+echo CreateObject("Wscript.Shell").Run "" ^& strSavePath ^& "" , 0, false>> mysql_start_background.vbs
+REM Running MySQL server hidden
+mysql_start_background.vbs
+cls
+echo Waiting for Mysql Server to start...
+@ping 127.0.0.1 -n 15 -w 1000 > nul
+cls
+REM Creating a blank database named ogp_panel to use it for the panel later
+%WD%\bin\mysql -u root -e "CREATE DATABASE ogp_panel";
+cls
+REM Setting up the SQL server
+%WD%\bin\bash mysql_secure_installation
+REM Getting the lastest version of OGP web panel from SVN
+echo Getting the lastest version of OGP web panel from SVN...
+%WD%\bin\svn co svn://svn.code.sf.net/p/hldstart/code/trunk/upload /srv/www/htdocs
+rm -f /srv/www/htdocs/index.html
+REM Asks for adding mysqld and httpd to the system startup 
+set /p ONBOOT= Start MySQL server at system boot[Y/n]:
+IF "X%ONBOOT%" == "X" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "Xy" (
+set ONBOOT=Y
+)
+IF "X%ONBOOT%" == "XN" (
+set ONBOOT=n
+)
+IF "X%ONBOOT%" == "XY" (
+schtasks /create /tn "MySQL server start on boot" /rl highest /ru %USERDOMAIN%\%USERNAME% /rp "%PASS%" /tr %WD%mysqld_start.bat /sc onstart
+) ELSE (
+IF "X%ONBOOT%" == "Xn" (
+schtasks /delete /tn "MySQL server start on boot"
+)
+)
+bash /usr/sbin/httpd2-config
+net start cygserver
+net start httpd2
+echo Now you can close this window and complete the installation 
+echo of the panel from http://localhost/install.php.
+echo PS: The database name is ogp_panel.
+pause
+REM Start Intrenet explorer and show the panel setup
+start iexplore "http://localhost/install.php"

+ 37 - 0
win_script/rebaseall.bat

@@ -0,0 +1,37 @@
+@echo off
+set WD=%~dp0
+pushd %WD%
+REM Set the needed enviroment variables to run Cygwin executables without writing the full path
+set CYGWIN=server ntsec
+set path=%WD%\bin;%WD%\usr\sbin;%path%
+set SHELL=/bin/bash
+REM Stop running services
+echo Stopping OGP services...
+net stop cygserver
+net stop httpd2
+net stop cron
+net stop mysqld
+net stop ogp_agent
+pause
+cls
+echo Trying to kill all running screen
+echo kill ^`(ps -a ^| grep "$((ps -a |grep screen) | awk '{ print $1 }')")^|awk '{ print $1 }'^` > checkscreen
+dos2unix checkscreen
+chmod +x checkscreen
+bash checkscreen
+rm -f checkscreen
+screen -wipe
+pause
+cls
+echo Runing rebaseall -v
+REM Runs 'rebaseall' that fixes owners and/or permissions for all Cygwin file system
+dash -c '/usr/bin/rebaseall -v'
+pause
+cls
+echo Starting OGP services...
+net start cygserver
+net start httpd2
+net start cron
+net start mysqld
+net start ogp_agent
+pause

+ 37 - 0
win_script/remove_all_cygwin_related.bat

@@ -0,0 +1,37 @@
+@echo off
+set WD=%~dp0
+pushd %WD%
+REM Set the needed enviroment variables to run Cygwin executables without writing the full path
+set CYGWIN=server ntsec
+set path=%WD%\bin;%WD%\usr\sbin;%path%
+set SHELL=/bin/bash
+echo Stopping OGP services...
+net stop cygserver
+sc delete cygserver
+net stop httpd2
+sc delete httpd2
+net stop cron
+sc delete cron
+net stop mysqld
+sc delete mysqld
+net stop ogp_agent
+sc delete ogp_agent
+pause
+cls
+echo Trying to kill all running screen
+echo kill ^`(ps -a ^| grep "$((ps -a |grep screen) | awk '{ print $1 }')")^|awk '{ print $1 }'^` > checkscreen
+dos2unix checkscreen
+chmod +x checkscreen
+bash checkscreen
+rm -f checkscreen
+screen -wipe
+pause
+cls
+set /p CONFIRM= Are you sure that you want remove all contents in %WD% (Y to confirm):
+IF "X%CONFIRM%" == "XY" (
+echo rm -Rf --no-preserve-root `cygpath -ua %WD%\`> eraser.sh
+echo echo "removed `cygpath -ua %WD%\`">>eraser.sh
+dos2unix eraser.sh
+bash eraser.sh
+)
+pause