#!/usr/bin/env perl

# include DBI libs for Plesk+SB installation on FreeBSD
use lib ( '/usr/local/psa/lib/perl5/site_perl/5.8.8/mach' );

# include DBI libs on Mac OS X
use lib ( '/usr/local/sitebuilder/lib/perl5/site_perl/5.8.6/darwin-thread-multi-2level' );

use Switch;
use File::Copy;
use File::Path;
use File::Basename;
use Getopt::Long;
use DBI;
use POSIX qw(strftime);
use Sys::Hostname;
use Digest::MD5 qw(md5_hex);;
use User::pwent;
use IO::Socket;
#use strict;
#use warnings;

if ( $< != 0) {
    print "This script can only be run as root\n";exit(1);
};

%messages = (
    root_msg 			=> "This script can be run only under ROOT\n",
    mysql_not_avail		=> "Could not connect to MySQL server on ",
    set_proper_mysql_settings => "Please define proper connection settings using the --db_host and --db_port keys.\n",
    httpd_owner_invalid => "The httpd_owner value is invalid.\n Please define proper parameter using the owner:group format.\n",
    cant_create_vhost   =>  "...could not create virtual host for SiteBuilder.\n",
    cant_start_httpd    =>  "...failed to start HTTPD.\n",
    vhost_created	=>  "Virtual host for SiteBuilder has been created.\n",
    vhost_creation	=>  "Virtual host creation",
    db_creation		=>  "Database creation",
    db_exist            =>  "Database already exists.\n",
    user_exist		=>  "System user already exists. User creation step will be skipped.\n",
    cant_chown		=>  "Could not change owner of the",
    try_chown		=>  "Try to set proper owner manually.\n",
    db_created 		=>  "Database has been created.\n",
    module_not_installed => "Module has NOT been installed properly.\n",
    httpd_will_restarted => "Apache service will be restarted and MySQL database will be modified during configuration.\n",
    do_you_want		 => "Do you want to continue? [Y/n]",
    ioncube_not_detected => "The PHP IonCube loader is not detected. \n",
    phpcli_not_detected => "Unable to determine the path to PHP-CLI(5.1). \n",
    phpcgi_not_detected => "Unable to determine the path to PHP-CGI(5.1). \n",
    install_finished    =>  "Reconfiguration has been finished.\n",
    is_available	=>  "SiteBuilder will be available on ",
    modules_installed   =>  "Modules have been updated.\n",
    modules_failed   =>  "Critical errors occured while updating MODULES!\n",
    locales_failed   =>  "Critical errors occured while updating LOCALES!\n",
    locales_installed   =>  "Locales have been updated.\n",
    templates_failed   =>  "Critical errors occured while updating TEMPLATES!\n",
    templates_installed   =>  "Templates have been updated.\n",
    cant_connect_db     => "Could not connect to SiteBuilder database ",
    config_log          => "Detailed log has been saved to ",
    try_help		=> "Try `--help' for more information. \n",
    memlimit_update_failed => "Cannot set proper memory limit in php.ini\n",
    memlimit_update_success => "Memory limit has been updated.\n",
    cant_parse_psa_config => "Cannot parse Plesk config file\n", 
    line	  	=> ("-" x 30)."\n"
);

$USING_PARAMS_STR="CURRENT PARAMETERS: ";

%httpd_port	= ( type => "internal",  val => "PORT",     title  => "Apache port for sitebuilder.conf");
%without_restart= ( type => "null",  val => "",     title  => "Do not restart HTTPD");
%db_host	= ( type => "database",  val => "HOSTNAME", title  => "MySQL host" );
%db_port	= ( type => "database",  val => "PORT",     title  => "MySQL port" );
%db_admin_name  = ( type => "internal",  val => "USER",     title  => "MySQL user with administrative privileges");
%db_admin_passwd= ( type => "internal",  val => "PASSWORD", title  => "Password for MySQL user with administrative privileges" );
%sb_admin_passwd= ( type=>"internal",  	 val => "PASSWORD", title => "SiteBuilder administrator password");
%sb_db_user_name= ( type=>"database",	 val => "USER",     title => "MySQL SiteBuilder user");
%sb_db_name	= ( type=>"database",	 val => "NAME",	    title => "SiteBuilder database name");
%sb_db_user_passwd = ( type=>"database", val => "PASSWORD", title => "Password for MySQL SiteBuilder user" );
%sb_hostname 	= ( type=>"internal", 	 val => "HOSTNAME", title => "SiteBuilder hostname");
%sb_host_ip     = ( type=>"internal",    val => "IP",       title => "IP address of SiteBuilder virtual host");
%ext_ip  	= ( type=>"internal", 	 val => "IP", 	    title => "Allowed to access database host");

%php_path  	= ( type=>"internal", 	 val => "PATH",     title => "Path to PHP-CGI binary");

%httpd_owner  	= ( type=>"internal", 	 val => "user:group", title => "Owner of SiteBuilder working directory");

%sb_resources_path = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder resources");
%sb_styles_path    = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder styles");
%sb_locale_path    = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder locales");
%sb_tmp_path       = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder TEMP directory");
%sb_sql_path       = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder SQL installation templates");
%sb_user_path      = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder user's working directories");
%sb_utils_path      = ( type=>"path", 	 val => "PATH",	    title => "Path to SiteBuilder utils");
%tmp_htdocs_path     = ( type=>"path", 	 val => "PATH",	    title => "");
%tmp_htdocs_url     = ( type=>"url", 	 val => "PATH",	    title => "");

%sb_debug       = ( type=>"debug", 	 val => "ON/OFF",    title => "ON/OFF debug mode");

%help           = ( type=>"null", 	 val => "",    title => "Help mode");
%advanced_help      = ( type=>"null", 	 val => "",    title => "Advanced help mode");
%migrate_all      = ( type=>"null", 	 val => "",    title => "Migrate all sites from v.2.1.3");

%force          = ( type=>"null", 	 val => "",    title => "Force mode. Apply default values.");
%update_locales       = ( type=>"null", 	 val => "",    title => "Skip all steps except locales configuration");
%update_modules       = ( type=>"null", 	 val => "",    title => "Skip all steps except modules configuration");
%update_templates     = ( type=>"null", 	 val => "",    title => "Skip all steps except templates configuration");


#%date_format		= ( type=>"general",  val => "FORMAT",     title => "Date format of logging subsystem");
%use_rewrite		= ( type=>"general",  val => "ON/OFF",     title => "Activate mod_rewrite engine");
%sb_system_log_level	= ( type=>"log",     val => "LEVEL",       title => "System log level");
%sb_security_log_level	= ( type=>"log",     val => "LEVEL",       title => "Security log level");
%sb_htdocs_path		= ( type=>"path",     val => "PATH",     title => "Path to SiteBuilder working directory"); 
%sb_styles_path		= ( type=>"path",     val => "PATH",     title => "Path to SiteBuilder styles");
%sb_templ_path		= ( type=>"path",     val => "PATH",     title => "Path to SiteBuilder templates");
%sb_logos_path		= ( type=>"path",     val => "PATH",     title => "Path to SiteBuilder logos");
%sb_templ_url		= ( type=>"url",     val => "PATH",     title => "URL to SiteBuilder templates");
%sb_logos_url		= ( type=>"url",     val => "PATH",     title => "URL to SiteBuilder logos");
%db_type		= ( type=>"database",     val => "PATH",     title => "SiteBuilder database type");

%phpcli_path    = ( type=>"internal",    val => "PATH",     title => "Path to PHP-CLI(5.1)  binary");
%phpcgi_path    = ( type=>"internal",    val => "PATH",     title => "Path to PHP-CGI(5.1) binary");


#sub getHostIP();
sub getOptFromConfig();
sub getHostIP();
sub parsePSAConfig($);

my $psa_config;
my @ARGV_BKP=();

# detect hostname
$platform=`uname`;
chomp($platform);

if ( $platform eq "Linux" ) {
	$sb_hostname="sitebuilder.".`hostname -f`;
} else {
	$sb_hostname="sitebuilder.".`hostname`;
}

chomp($sb_hostname);

my $SB_CONFIG="config";
my $log_format="\%Y \%b \%e \%H:\%M \%S";  
my $time = strftime "%y%m%d%H%M", localtime;  
my $psa_conf="/etc/psa/psa.conf"; 
my $sb_httpd_owner;	
my $host_ip =  getHostIP();
my %tmp_options =();

@phpcli_paths=("/usr/local/sitebuilder/bin/php",
               "/opt/php51/bin/php5",
               "/usr/bin/php5", 
               "/usr/bin/php", 
               "/usr/local/bin/php");

foreach $path (@phpcli_paths){
    if ( -x "$path" ){
            $php_ver=`echo "<?php echo phpversion(); ?>"|$path -q|awk -F. '{print \$1\$2}'`;
            if ( $php_ver == "51" ){ $phpcli_path=$path; last; }
    }
}

@phpcgi_paths=("/usr/local/sitebuilder/cgi-bin/php",
               "/opt/php51/cgi-bin/php5",
               "/usr/local/bin/php-cgi",
               "/srv/www/cgi-bin/php5", 
               "/usr/bin/php5-cgi", 
               "/usr/bin/php-cgi",);

foreach $path (@phpcgi_paths){
    if ( -x "$path" ){
            $php_ver=`echo "<?php echo phpversion(); ?>"|$path -q|awk -F. '{print \$1\$2}'`;
            if ( $php_ver == "51" ){ $phpcgi_path=$path; last; }
    }
}



#Path to Sitebuilder work directory:
if ( -e "/etc/debian_version" ){
	$SB_HTDOCS = "/opt/sitebuilder/htdocs";
	$SB_PREFIX = "/opt/sitebuilder";
}else{
	$SB_HTDOCS = "/usr/local/sitebuilder/htdocs";
	$SB_PREFIX = "/usr/local/sitebuilder";
}

# $^O is equal to $OSNAME perl has been compiled on (according to man perlvar)
# it yields values like "linux", "freebsd", "darwin", "openbsd" (in lower case)

# Warning! 
# The lexicographically biggest name takes precedence if several names match.
# To avoid such side-effects please make sure only one of subs return true
# on any given system

%os = ( redhat  => sub { return ($^O eq "linux") && ( -e "/etc/redhat-release" ); },
	debian  => sub { return ($^O eq "linux") && ( -e "/etc/debian_version" ); },
	suse	=> sub { return ($^O eq "linux") && ( -e "/etc/SuSE-release" ); },
	freebsd_psa => sub { return ($^O eq "freebsd") && ( -e $psa_conf ); },
	freebsd => sub { return ($^O eq "freebsd") && ( -e "/etc/rc.conf" ) && ! ( -e $psa_conf); },
	darwin_psa => sub { return ($^O eq "darwin") && ( -e $psa_conf ); },
	darwin => sub { return ($^O eq "darwin") && ! ( -e $psa_conf ); }
);

#Detect Operation System
foreach my $name (sort {$b cmp $a} (keys  %os)){
    if ( $os{$name}->() ) {
        $OS_NAME = $name;
        last;
    }
}
die "Cannot determine OS version" unless $OS_NAME;

#Get default apache user
%http_user =  (   redhat      => "apache:apache",
                  debian      => "www-data:www-data",
                  suse        => "wwwrun:www",
                  darwin      => "www:www",
                  darwin_psa  => "apache:psacln",
                  freebsd     => "www:www",
                  freebsd_psa => "apache:psacln"
                );

#Redirect stdout to log file
open(SAVED_STDOUT, ">&STDOUT");

my $logfile="$SB_PREFIX/tmp/sb_config-$time.log";
open(STDOUT, ">>$logfile");
chmod 0600, $logfile;

print "OS version determined as $OS_NAME\n";

#parameters for Sitebuilder config:
%config =(  db_host 		=> "host",
	    sb_db_user_name	=> "username",
	    use_rewrite		=> "use_rewrite",
	    db_port 		=> "port",
	    sb_db_user_passwd	=> "password",
	    sb_db_name		=> "dbname",
	    sb_resources_path	=> "resources",
	    sb_styles_path	=> "styles",
	    sb_user_path	=> "users",
	    sb_locale_path	=> "locale",
	    sb_tmp_path		=> "tmp",
	    sb_sql_path		=> "sql",
	    sb_debug		=> "debug",
	    date_format		=> "date_format",
	    sb_system_log_level	=> "system_log_level",
	    sb_security_log_level=> "security_log_level",
	    sb_htdocs_path	=> "htdocs",
	    sb_styles_path	=> "styles",
	    sb_templ_path	=> "templates",
	    sb_logos_path	=> "logos",
	    sb_utils_path	=> "utils",
	    sb_templ_url	=> "templates",
	    sb_logos_url	=> "logos",
	    db_type		=> "adapter"
	    
	 );

	 

#Configure options:
%options = (
    httpd_port		=> "80",
    db_host	 	=> "localhost",	
    db_port	 	=> "3306",
    db_admin_name	=> "root",
    db_admin_passwd	=> "",
    phpcli_path		=> $phpcli_path,
    phpcgi_path     => $phpcgi_path,

    sb_admin_passwd	=> "",
    sb_db_user_name	=> "sb_user",
    sb_db_user_passwd	=> "sb_user",
    sb_db_name		=> "sitebuilder3",
    sb_hostname		=> $sb_hostname,
    sb_host_ip      => $host_ip,
    ext_ip		    => "localhost",

    sb_resources_path	=> "resources",
    sb_styles_path	=> "resources/styles",
    sb_locale_path	=> "resources/locale",
    sb_tmp_path		=> "tmp",
    sb_sql_path		=> "resources/sql/",
    sb_user_path	=> "htdocs/users",
    
    httpd_owner	=>  	$http_user{$OS_NAME},
    
    sb_debug		=> "on",
    force		=> "false",
    use_rewrite		=> "On",
    
    date_format		=>  "Y.m.d H:i",
    sb_system_log_level	=> "1",
    sb_security_log_level=> "1",
    sb_htdocs_path	=> "htdocs",
    sb_styles_path	=> "resources/styles",
    sb_templ_path	=> "htdocs/templates",
    sb_logos_path	=> "htdocs/images/logos",
    sb_templ_url	=> "/templates",
    sb_logos_url	=> "/images/logos",
    db_type		=> "pdoMysql",
    tmp_htdocs_path     => "htdocs/tmp",
    tmp_htdocs_url     => "/tmp",
    update_locales     => "false",
    update_modules     => "false",
    update_templates     => "false",
    help                => "false",
    #            advanced_help       => "false",
    migrate_all    => "false",
    without_restart     => "false"
);


#Get options from config file if defined
getOptFromConfig();

if (!exists($options{"ext_ip"})){
    $options{"ext_ip"}=$options{"db_host"};
}
    

my $_db_name="false";

foreach (@ARGV) {
        $i++;
        if ( /--sb_db_user_passwd=(.*)/ ){
                $options{"sb_db_user_passwd"}=$1;
                delete $ARGV[$i-1];
        }
        if ( /--db_admin_passwd=(.*)/ ){
                $options{"db_admin_passwd"}=$1;
                delete $ARGV[$i-1];
        }
        if ( /--sb_db_name/ ){

                 $_db_name="true";
        }
}

#Replace options from @ARGV

$status=GetOptions( \%options,
	    "httpd_port=i", 	
	    "db_host=s",	
	    "db_port=s",
	    "db_admin_name=s",
	    "db_admin_passwd=s",
	    "sb_admin_passwd=s",
	    "sb_db_user_name=s",
	    "sb_db_name=s",
	    "sb_hostname=s",
	    "use_rewrite=s",
	    "ext_ip=s",
	    "sb_user_path=s",
	    "sb_sql_path=s",
	    "update_locales",
	    "update_modules",
	    "update_templates",
	    "force",
	    "help",
#	    "advanced_help",
	    "migrate_all",
        "date_format=s",
        "sb_system_log_level=i",
        "sb_security_log_level=i",
        "sb_htdocs_path=s",
        "sb_styles_path=s",
        "sb_templ_path=s",
        "sb_logos_path=s",
        "sb_templ_url=s",
        "sb_logos_url=s",
        "db_type=s",
	    "httpd_owner=s",
	    "sb_host_ip=s",
	    "without_restart",
	    "phpcli_path=s",
        "phpcgi_path=s"
	    );

if ( !$status ){

	print SAVED_STDOUT $messages{"try_help"};
	exit(1);
}

#VHost directories of defferent OS'es:
%apache_vhost = ( redhat   => "/etc/httpd/conf.d/",
		  debian   => "/etc/apache2/sites-available/",
		  suse     => "/etc/apache2/vhosts.d/",
		  freebsd  => "/usr/local/etc/apache2/Includes",
		  darwin   => "/private/etc/httpd/users/"
	  	);


%error_log = (    redhat => "logs/sitebuilder_error.log",
		  debian         => "/var/log/apache2/sitebuilder_error.log",
		  suse           => "/var/log/apache2/sitebuilder_error.log",
		  freebsd        => "/var/log/sitebuilder_error.log",
		  freebsd_psa    => "/var/log/sitebuilder_error.log",
		  darwin         => "/var/log/httpd/sitebuilder_error.log",
		  darwin_psa     => "/usr/local/psa/apache/logs/sitebuilder_error.log",
	  	);
#Apache control scripts of different OS'es:
%apache_ctl =  (  redhat   => "/etc/init.d/httpd restart",
		  debian   => "/etc/init.d/apache2 restart",
		  suse     => "/etc/init.d/apache2 restart",
		  freebsd  => "/usr/local/sbin/apachectl restart",
		  darwin   => "/System/Library/StartupItems/Apache/Apache restart",
		  psa	   => "/admin/sbin/websrvmng -v -a",
		  freebsd_psa => "/admin/sbin/websrvmng -v -a",
		  darwin_psa  => "/admin/sbin/websrvmng -v -a",
	  	);

%sql_adapter = ( pdoMysql  => "mysql" );

if (-e $psa_conf ){
    $options{"db_admin_name"}="admin";
    $options{"db_admin_passwd"}=`cat /etc/psa/.psa.shadow`;
    chomp($options{"db_admin_passwd"});
	$psa_config = parsePSAConfig($psa_conf) || return $messages{"cant_parse_psa_config"};
}

sub getTime(){
        $t = strftime $log_format, localtime;
        return "[".$t."] ";
}


sub printUsage( $ )
{	
	my %list=();
        select SAVED_STDOUT;	

	
	if ( $_[0] eq "advanced" ){


		%sections=(     internal => "Main options:\n",
				database => "Database options:\n",
				path => "Path options:\n",
				url => "URL options:\n",
				null   => "Common options:\n"
			  );
	
	}else{
		%sections=(     internal => "Main options:\n",
				database => "Database options:\n",
				null   => "Common options:\n",
				general   => "General options:\n"
			  );
	}


	print "[defaults in brackets after descriptions]\n";
	foreach $section (keys %sections){
  	
		print SAVED_STDOUT $sections{$section};

		foreach $k (keys %options)
		{
			if ( $$k{'type'} eq $section  ) {
				$val = $$k{'title'};
				if ( ($$k{'type'} eq "null") ){
					$list{$k} = $val;
				}elsif ( $options{$k} ){
					$list{$k}=$val."  [".$options{$k}."]";
				}else{
					$list{$k} = $val."  [empty]";
				};
	 		}
		}
	
			
		foreach $k (sort keys %list ){	
			my $offset;
			if ( $$k{"type"} eq "null" ){ 
				$separator=" ";
			}else{
				$separator="=";
			};
			$string = $k."".$separator."".$${'val'};
			foreach $i (1..30-length($string)){ $offset .= " " };
			print SAVED_STDOUT "--".$k.$offset.$list{$k}."\n";
			delete($list{$k}) ;
		
		}

		print SAVED_STDOUT "\n" ;

	}
}


sub printUsingParameters () {
	$time = strftime $log_format, localtime;  
	if ( $options{"force"} eq "false" ){
	    print SAVED_STDOUT "$USING_PARAMS_STR\n";
	}
	print STDOUT "[$time] $USING_PARAMS_STR\n";
	
	foreach $k (keys %options){
	if ( ($options{"force"} eq "false" ) and (length($$k{'title'}) >0 ) ){
    	    if ( ($$k{'type'} eq "database" ) or ($$k{'type'} eq "internal") or ($$k{'type'} eq "general")) {
			  print SAVED_STDOUT "$$k{'title'}:  $options{$k}\n"  if $$k{'type'} ne "null";
			  print STDOUT "$$k{'title'}:  $options{$k}\n"  if $$k{'type'} ne "null";
	  	  };
	}
	}

}
sub checkParameters () {
	my $owner=$options{"httpd_owner"};
	my $db_host = $options{"db_host"};
	my $db_port = $options{"db_port"};
	my $db_admin_name = $options{"db_admin_name"};
	my $db_admin_passwd = $options{"db_admin_passwd"};
	my $db_name = $options{"sb_db_name"};
	my $db_type = $options{"db_type"};
	my $result=0;
	
	#Try to connect to MySQL server	
	
	$dbh = DBI->connect("DBI:mysql:mysql:$db_host:$db_port",
                    "$db_admin_name", "$db_admin_passwd",
		    {PrintError => 0, RaiseError => 0, AutoCommit => 1 });
	
	if ( defined($DBI::errstr) ){
		$result = $messages{"mysql_not_avail"}." ".$db_host.":".$db_port.": ".$DBI::errstr."\n".$messages{"set_proper_mysql_settings"} ;
	    
	}

       if ( $_db_name eq "true" ){

                $query="select Db from db where Db=\"$options{'sb_db_name'}\" ";
                $sth = $dbh->prepare($query);
                $sth->execute();
                @row=$sth->fetchrow_array;
                if ($result ne "0"){
                        $result .= "Error: The".$options{"sb_db_name"}." ". $messages{"db_exist"} if (  defined($row[0]) );
                }else
                {        $result = "Error: The ".$options{"sb_db_name"}." ". $messages{"db_exist"} if (  defined($row[0]) );
                }

        }
	
	if ( ! -x $phpcli_path){
	    $result .= $messages{"phpcli_not_detected"};
	}

	if ( ! -x $phpcgi_path){
	    $result .= $messages{"phpcgi_not_detected"};
	    
	}

    $php_info=`$phpcli_path -m`;
	if ( $php_info !~ /ionCube/g ){
	    $result .= $messages{"ioncube_not_detected"};
	}
	($user,$group) = ($owner =~ /^(.*)\:(.*)/ );

	if ( ! defined($user) or ! defined($group) ){
                $result .= $messages{"httpd_owner_invalid"};
	    
	}
	return $result;
}

sub makeConfig {
    my %section=(); 
	
	$count = (keys %tmp_options);	
	if($count == 0) {
		%tmp_options = (%options);
}
	$count = (keys %tmp_options);	
	
	while ( my($key,$val) = each (%tmp_options) ){
		$key =~ s/(^[^_.]*)_//;
		LINE: while ( my($_key,$_val) = each (%config) ){
			if (  ( $key eq $_val) && ( $$_key{"type"} eq $1 )  ){
				$val = $options{$_key};
				last LINE;
			}
		}
		$secname=$1;
		$val = '"'.$val.'"' if $val =~ m/[=%\?\&]/; # quote values with =?&%
		push(@{ $section{$secname} },"\n".$key." = ".$val)  if $secname ne "internal" &&  $secname ne "null";	
	}
	
	open(F,">$SB_PREFIX/$SB_CONFIG") || die("$!\n") ;
	print F ";; Do not edit this file manually.\n";
	print F ";; Use the ../utils/configure utility to configure SiteBuilder. \n";
	foreach $string (keys %section) {
		if ( ! ($string eq "")) {
			print F "\n[$string]@{$section{$string}}\n";
		}
	}
	close(F);

	open(F,">$SB_PREFIX/options") || die("$!\n") ;
	while ( my($key,$val) = each (%options) ){
		print F "$key=$val\n";
	}
	close(F);	

}

sub restorecon($) {
	$file = shift;
	if ( ( -x "/sbin/restorecon") && ($OS_NAME eq "redhat") ){
		system("/sbin/restorecon $file");
	}
}

# Parses Plesk configuration file specified by the first paramenter
# and returns a reference to hash 
# Param: $_[0]  psa.conf  path
# Returns: reference to hash with key/value pairs of plesk config
sub parsePSAConfig($) {
  	my $psa_conf = shift;
	my %config = ();
	if  ( -e $psa_conf ) {
		open(F, "$psa_conf") or return \%config;
		while (<F>) {
			chomp;
			next if m/^\s*#/;
			next unless $_;
			#(my $key, my $value) = m/^\s*(\w+)\s+([^\s]*)\s*$/;
			(my $key, my $value) = split ;
			$config{$key} = $value;
		}
		close(F);
	}
	return \%config;
}

# Parses apache config (httpd.conf) specified by the first parameter and
# returns a string "user:group". If either of user or group is missing
# the default value from $http_user{$OS_NAME} is used
# Param $_[0]  path to apache config
# Returns "user:owner" string
sub getPSA_apacheUser($) {
	my $fn = shift;	
	(my $defaultuser, my $defaultgroup) = split /:/, $options{"httpd_owner"};
	my %owner = ( user => $defaultuser, group => $defaultgroup );
	open(PSACFG, "<$fn") or return "$owner{'user'}:$owner{'group'}";
	grep { 
		if (/^\s*User\s+(.*)$/i) {
			$owner{'user'} = $1;
		}
		if (/^\s*Group\s+(.*)$/i) {
			$owner{'group'} = $1;
		}
		0;
	} <PSACFG>;
	close(PSACFG);
	return "$owner{'user'}:$owner{'group'}";
}

sub makeVHost {
	$sb_hostname=$options{"sb_hostname"};
	my $filePath = $SB_PREFIX."/utils/sitebuilder.conf";
	my $fileContent;
	my $httpd_port=$options{"httpd_port"};
	my $owner=$options{"httpd_owner"};
	my $host_ip=$options{'sb_host_ip'}; #getHostIP();
	my $phpcli_path = $options{"phpcli_path"};
	
	$owner =~ s/:/ /g;
	open(F, "<$filePath") or die $!;
	binmode(F);
	
	{
	 local $/;
	 $fileContent = <F>;
	}
	close(F);

	$fileContent =~ s/__hostip__/$host_ip/g;
	$fileContent =~ s/__sitebuilder_path__/$SB_HTDOCS/g;
	$fileContent =~ s/__vhostname__/$sb_hostname/g;
	$fileContent =~ s/__port__/$httpd_port/g;
	$fileContent =~ s/__owner__/$owner/g;
	$fileContent =~ s/__error_log__/$error_log{$OS_NAME}/g;
	$basename = basename($phpcgi_path);
	$dirname  = dirname($phpcgi_path);

	$fileContent =~ s/__php_path__/$dirname/g;
	$fileContent =~ s/__php__/$basename/g;

	#get VHOST conf dir
	$HTTPD_INCLUDE_DIR=$apache_vhost{$OS_NAME};
	my $configpath = "$HTTPD_INCLUDE_DIR/zz011_sitebuilder.conf";

	#get APACHE restart command
	my $APACHE_CTL_CMD = $apache_ctl{$OS_NAME};

	if  ( -e $psa_conf ) {
		$HTTPD_INCLUDE_DIR = $psa_config->{'HTTPD_INCLUDE_D'};
		$APACHE_CTL_CMD = $psa_config->{'PRODUCT_ROOT_D'}."/".$apache_ctl{'psa'};
		$configpath = "$HTTPD_INCLUDE_DIR/zz011_sitebuilder.conf";
	}
	system("touch $configpath") == 0 || return $messages{"cant_create_vhost"}.": $!";
	# Restart Apache to make sure it is running before trying to connect to $httpd_port
	system($APACHE_CTL_CMD) == 0 || return $messages{"cant_start_httpd"};
	
	$result = listen_host_for_port($host_ip, $httpd_port);
	
	if ( $result == 1 ) {
	  $fileContent =~ s/^Listen/#Listen/mg;
	}

	open (F,">$configpath") || return $messages{"cant_create_vhost"}.": $!";
	print F $fileContent;
	close(F);

	# Should really restore context before restarting apache
	restorecon($configpath);
	if( $OS_NAME eq "debian" ){
		$result=system("a2ensite zz011_sitebuilder.conf")
	}
	system($APACHE_CTL_CMD) == 0 || return $messages{"cant_start_httpd"};

	return 0;	
}

sub changeOwner {
    my $owner=$options{"httpd_owner"};

    if ( -e $psa_conf ) {
	$owner = getPSA_apacheUser($psa_config->{'HTTPD_CONF_D'}."/httpd.conf");
    }

    ($user,$group)=  ($owner =~ /^(.*):(.*)/ );

    $pw = getpwnam($user);

    open(F, "</etc/group") or die $!;
    binmode(F);
    {
     local $/;
     $fileGroup = <F>;
    }

    if ($fileGroup=~ /^$group:/){ $isGroupNotExists=0} else {$isGroupNotExists=1;}
			    
    if (defined($pw)){ 
        $time = strftime $log_format, localtime;
	print  "[$time]".$messages{"user_exist"} ;
			  
    } else{
        if ($OS_NAME eq "freebsd"){
            if ( $isGroupNotExists ) {system("pw groupadd $group");}
	    system("pw useradd $user -m -c \"Sitebuilder httpd user\" -d $SB_PREFIX  -s /usr/bin/false -G $group");
        }else{
            if ( $isGroupNotExists ) {system("groupadd $group");}
	    system("useradd $user -m -c \"Sitebuilder httpd user\" -d $SB_PREFIX  -s /bin/false -g $group");
	}
    }
    $result=system("chown -R $owner $SB_HTDOCS/sites");
        if ( $result){
	    $time = strftime $log_format, localtime;
	    print "[$time]".$messages{"cant_chown"}.$SB_PREFIX."/sites.".$messages{"try_chown"};
	    print SAVED_STDOUT  $messages{"cant_chown"}.$SB_PREFIX."/sites.".$messages{"try_chown"};
   }
   $result=system("chown -R $owner $SB_HTDOCS/tmp");
   $result=system("chown -R $owner $SB_HTDOCS/images/logos");
   $result=system("chown -R $owner $SB_PREFIX/tmp");
}

sub createDBuser {
	my $db_host = $options{"db_host"};
	my $db_port = $options{"db_port"};
	my $db_admin_name = $options{"db_admin_name"};
	my $db_admin_passwd = $options{"db_admin_passwd"};
	my $db_name = $options{"sb_db_name"};
	my $db_type = $options{"db_type"};
        my $ext_ip;
	
        if (exists($options{"ext_ip"})){ $ext_ip=$options{"ext_ip"};}else{ $ext_ip="localhost";}
	
		
	#make system records
	$time = strftime $log_format, localtime;  
	$dbh = DBI->connect("DBI:mysql:mysql:$db_host:$db_port",
                    "$db_admin_name", "$db_admin_passwd",
		    {PrintError => 0, RaiseError => 0, AutoCommit => 1 })
		    or die "[$time] Could not connect to database: $DBI::errstr\n";

	$query="select User from user where User='$options{\"sb_db_user_name\"}';";
        $sth = $dbh->prepare($query);
        $sth->execute();
        @row=$sth->fetchrow_array;
	
        if ( !defined($row[0]) ){
	        if ( $options{"sb_sql_path"} =~ /^\// ){
	            $file=$options{"sb_sql_path"}."/".$sql_adapter{$db_type}."/system.sql";
	       }else{
        	   $file=$SB_PREFIX."/".$options{"sb_sql_path"}."/".$sql_adapter{$db_type}."/system.sql";
	       }

	       open(F, $file)  || die "[$time] Cannot open ".$file." for reading: $!";
		while (<F>) {
			chomp;	
			$query=$_;
			$query =~ s/%sb_db_host%/$ext_ip/;
			$query =~ s/%sb_db_user%/$options{"sb_db_user_name"}/;
			$query =~ s/%sb_db_password%/$options{"sb_db_user_passwd"}/;
			$query =~ s/%sb_db_name%/$options{"sb_db_name"}/;
			$sth = $dbh->prepare("$query");	
			print STDOUT "[$time] Process sql-query: $query\n";
			$sth->execute;
			$err=$DBI::err;
			if ($err){
				$status=$err;
			}else{
				$status="Ok";
			}		
			$time = strftime $log_format, localtime;  
			print STDOUT "[$time] Result: ...$status\n";
		
		}
	}else{
		@queries=("update user set  Host='$ext_ip', Password=PASSWORD('$options{'sb_db_user_passwd'}')
				 where User='$options{'sb_db_user_name'}'",

			   "update db set  Host='$ext_ip' where User='$options{'sb_db_user_name'}' and  Db='$db_name' ",

			    "update tables_priv set  Host='$ext_ip' where User='$options{'sb_db_user_name'}' and  Db='$db_name'"				, "FLUSH PRIVILEGES" );
		foreach $query (@queries){

		        $sth = $dbh->prepare("$query");
	        	$sth->execute();
			print STDOUT getTime().$query."\n";
			last if $DBI::err;
		}
		
	        $err=$DBI::errstr;
	        if ($err){
	            $status=$err;
	            $_status="failed";
	        }else{
	            $status="Ok";
	            $_status="Ok";
	        }

	        print STDOUT getTime()."Update SiteBuilder database user credentials: ";
	        print SAVED_STDOUT "Update SiteBuilder database user credentials: ";
	        print STDOUT "...$status\n";
	        print SAVED_STDOUT "...$_status\n";

	}
        $query="SHOW VARIABLES LIKE 'version';";
        $sth = $dbh->prepare($query);
        $sth->execute();
        @row=$sth->fetchrow_array;
        $version=$row[1];
	
	$def_charset="";
        if ( $version =~ /^4.1.([2-9]|[1-9][0-9])|^5/ ){

            $def_charset="DEFAULT CHARSET=utf8";
        }


	$sth = $dbh->prepare("CREATE DATABASE $db_name $def_charset ");	
	$sth->execute;
	$err=$DBI::errstr;
	print STDOUT getTime().$err."\n";
	close(F);

	$time = strftime $log_format, localtime;  
	$dbh->disconnect()  or warn "[$time] Disconnection error: $DBI::errstr\n";
	return $err;
}


sub changeAdmin {
	my $db_host = $options{"db_host"};
	my $db_port = $options{"db_port"};
	my $db_user_name = $options{"sb_db_user_name"};
	my $db_name = $options{"sb_db_name"};
	my $db_passwd = $options{"sb_db_user_passwd"};
	
	if ( $options{"sb_admin_passwd"} eq "" ) {
		return 0;
	}
	
	my $admin_passwd = md5_hex($options{"sb_admin_passwd"});
	my $db_type = $options{"db_type"};
	
	#make system records
	$time = strftime $log_format, localtime;  
        $dbh = DBI->connect("DBI:mysql:$db_name:$db_host:$db_port",
	                    "$db_user_name", "$db_passwd") or die "[$time] Could not connect to database: $DBI::errstr\n";
	
	$query="select user.id from user_settings,user where user_settings.is_built_in=1 and user.parent_id=0 and  user.user_settings_id=user_settings.id;";
        $sth = $dbh->prepare($query);
	$sth->execute();
	@row=$sth->fetchrow_array;
	$admin_id=$row[0];
    	
	print STDOUT getTime()."Update administrator credentials: ";
	print SAVED_STDOUT "Update administrator credentials: ";
	
	$sth = $dbh->prepare("update user set user_password=\"".$admin_passwd."\" where id=".$admin_id);
	$sth->execute();
	$err=$DBI::errstr;
	if ($err){
		$status=$err;
	}else{
		$status="Ok";
	}
	
	print STDOUT "...$status\n";
	print SAVED_STDOUT "...$status\n";
	
	$dbh->disconnect()  or warn getTime()."Disconnection error: $DBI::errstr\n";
	return $err;
}

sub createDatabase {
	my $db_host = $options{"db_host"};
	my $db_port = $options{"db_port"};
	my $db_user_name = $options{"sb_db_user_name"};
	my $db_name = $options{"sb_db_name"};
	my $db_passwd = $options{"sb_db_user_passwd"};
	my $sqlfile;
	my $query;
        my $db_type = $options{"db_type"};

	$time = strftime $log_format, localtime;  	
	#make system records
	$dbh = DBI->connect("DBI:mysql:$db_name:$db_host:$db_port",
                    "$db_user_name", "$db_passwd") or die "[$time] Could not connect to database: $DBI::errstr\n";


        $query="SHOW VARIABLES LIKE 'version';";
        $sth = $dbh->prepare($query);
        $sth->execute();
        @row=$sth->fetchrow_array;
        $version=$row[1];

	$structure="structure.sql";
        if ( $version =~ /3.2/ or $version =~ /4.0/ ){

	    $structure="structure3.sql";
	}
	$query="";

	
        $query="SHOW TABLES";
        $sth = $dbh->prepare($query);
        $sth->execute();
        @row=$sth->fetchrow_array;
	$query="";	
        return $messages{"db_created"} if (  defined($row[0]) );

	@files=($structure,"data.sql");
	foreach $file (@files){

           if ( $options{"sb_sql_path"} =~ /^\// ){
                $sqlfile=$options{"sb_sql_path"}."/".$sql_adapter{$db_type}."/".$file;
            }else{
                $sqlfile=$SB_PREFIX."/".$options{"sb_sql_path"}."/".$sql_adapter{$db_type}."/".$file;
            }


            open(F, $sqlfile)  || die "FATAL ERROR: Cannot open $sqlfile for reading: $!";

	    while (<F>) {
		chomp;
                next if  $_ =~ /^--/;
	        next if  $_ =~ /^[\t|\s]*$/;

                $query .=$_;

	
		$query =~ s/sb_admin_name/$options{"sb_admin_name"}/;
 		$query =~ s/sb_admin_password/$options{"sb_admin_passwd"}/;
                $uuid=getUuid();
                $query =~ s/%uuid%/$uuid/;
		
		$date = strftime "%Y-%m-%dT%H:%S:%M%z", localtime;		
                $query =~ s/%admin_date_create%/$date/;
						


		if ( /;[\t\s]*$/ ){
		
			$sth = $dbh->prepare("$query");	
			$time = strftime $log_format, localtime;  
			print STDOUT "[$time] Process sql-query: $query\n";
			if ($err){
				$status=$err;
			}else{
				$status="....Ok";
			}		
			$sth->execute;
			$err=$DBI::err;
			if ($err){
				$status=$err;
			}else{
				$status="Ok";
			}		
			$time = strftime $log_format, localtime;  
	    		print STDOUT "[$time] Result: ...$status\n";
	                $query="";
						
		}
	    }
	    close(F);
			    	    
	}
	
	$dbh->disconnect()  or warn "[$time] Disconnection error: $DBI::errstr\n";
        return $messages{"db_created"};

}

sub getUuid(){
    $random = int(rand(20000 ) );
    $hash = md5_hex($random);

    return substr($hash, 0, 8) . '-' . substr($hash, 8, 4) . '-'. substr($hash, 12, 4). '-' . substr($hash, 16, 4). '-' . substr($hash, 20);

}

sub getHostIP (){
    open(P, "/sbin/ifconfig|") or die("[$time] Cannot start process: ifconfig: $!\n");
    while(<P>) {
        if (/inet[\sA-Za-z:]+([\d\.]+)\s+/){ 
            $ip=$1; 
            return $ip if not $ip =~ /127.0.0/;
        }
    }

    $exit=`ping -c1 $sb_hostname > /dev/null;echo \$? `;
    if ( $exit == 0 ) {
        open(P, "host $sb_hostname|") or die("[$time] Cannot start process: host: $!\n");
        while(<P>) {
               if(/(\d{1,3}\.{1}\d{1,3}\.{1}\d{1,3}\.{1}\d{1,3})/) {return $1;}
        }
    } else {
         $time = strftime $log_format, localtime;
         print STDOUT "[$time] Server IP cannot be determined!";
         return "127.0.0.1";
    }
}

sub getOptFromConfig () {
    if ( -e "$SB_PREFIX/options" ){
        open(F,"<$SB_PREFIX/options");
        while(<F>) {
            chomp;
            if (/^(\w*)[\s\t]*=\s*([\w\d\/.:]*)[\s\t]*$/){
                $options{$1}= $2;
            }
        }	
        close(F);

        # remove incorrect options
        $options{"sb_admin_passwd"} = "";
        # do not override php paths
        $options{"phpcli_path"}=$phpcli_path;
        $options{"phpcgi_path"}=$phpcgi_path;
    }

	if ( -e "$SB_PREFIX/$SB_CONFIG" ){
		open(F,"<$SB_PREFIX/$SB_CONFIG");
		while(<F>) {
			chomp;
			next if (m/^\s*;/); # skip comments
			next if (m/^\s*$/); # skip empty lines
			if (/\[(\w*)\]/){ 
				$section=$1;
				next;
			}
			if (/^(\w*)\s*=(.*)$/){
				# \s*([\w\d\/.:]*)\s*
				$key = $1; $value = $2;
				$value =~ s/;.*$//;
				$value =~ s/^\s+//;
				$value =~ s/\s+$//;
				if (substr($value, 0, 1) eq '"') { 
					substr($value, 0, 1) = '';
					substr($value, -1, 1) = '';
				}
				$tmp_options{$section."_".$key}=$value;
			}
		}	
		close(F);
	}
	
    while ( my($key,$val) = each (%tmp_options) ){
		$key =~ s/(^[^_.]*)_//;
        A: while ( my($_key,$_val) = each (%config) ){
            if (  ( $key eq $_val) && ( $$_key{"type"} eq $1 )  ){
                $options{$_key}=$val;
#for fix #101593								
#               last A;
            }
	    }
    }
}


sub update_modules (){
    my $db_host = $options{"db_host"};
    my $db_port = $options{"db_port"};
    my $db_user_name = $options{"sb_db_user_name"};
    my $db_name = $options{"sb_db_name"};
    my $db_passwd = $options{"sb_db_user_passwd"};
    my $phpcli_path = $options{"phpcli_path"};
    $dbh = DBI->connect("DBI:mysql:$db_name:$db_host:$db_port",
                "$db_user_name", "$db_passwd", {PrintError => 0});
    if (defined($DBI::errstr)){
        return $messages{"cant_connect_db"}.": ".$DBI::errstr."\n";
    }

    $mod_inst=`$phpcli_path -q $SB_PREFIX/utils/modules/check.php db 2>/dev/null`;
    
    if ( $mod_inst =~ /[e|E]rror/ ){	
        print STDOUT $mod_inst;
        return    $messages{"modules_failed"};
    }


	@list= split(/ /, $mod_inst);
        foreach $module (@list) {
        next if !$module;
	    $exit_status=system("$phpcli_path -q $SB_PREFIX/utils/modules/install.php");
	    $status=`$phpcli_path -q $SB_PREFIX/utils/modules/install.php $module`;
		    

		    if ( ($status eq 0) and ($exit_status eq 0) ){ 
			     print SAVED_STDOUT "The $module module has been successfully installed\n";
			     print STDOUT getTime()."The $module module has been successfully installed\n";
		    }elsif ( $status ne 0 ){
    	                     print SAVED_STDOUT "Installation of the $module module has failed ($status)\n"; 
    	                     print STDOUT getTime()."Installation of the $module module has failed ($status)\n"; 
        	    }
		
       }
	$mod_inst=`$phpcli_path -q $SB_PREFIX/utils/modules/check.php source 2>/dev/null`;

	if ( $mod_inst =~ /[e|E]rror/ ){	
		$mod_inst   =~ s/\<[^\>]+\>//g;
		print STDOUT $mod_inst;
	        return    $messages{"modules_failed"};		
		
	}
	@list= split(/ /, $mod_inst);
        foreach $module (@list) {
		$exit_status=system("$phpcli_path -q $SB_PREFIX/utils/modules/uninstall.php");
		$status=`$phpcli_path -q $SB_PREFIX/utils/modules/uninstall.php $module`;
	 
	   	

		    if ( ($status eq 0) and ($exit_status eq 0) ){ 
			     print SAVED_STDOUT "The $module module has been successfully removed\n";
			     print STDOUT getTime()."The $module module has been successfully removed\n";
		    }elsif ( $status ne 0 ){
    	                     print SAVED_STDOUT "Failed to remove the $module module ($status)\n"; 
    	                     print STDOUT getTime()."Failed to remove the $module module ($status)\n"; 
        	    }
		
       }
      return	$messages{"modules_installed"};
}

sub migrate{
	open(STDOUT,">&SAVED_STDOUT")	;
	my $phpcli_path = $options{"phpcli_path"};
	print "\nMigration process started:\n";
	$status=system("$phpcli_path -q $SB_PREFIX/utils/migration.php");

	open(SAVED_STDOUT, ">&STDOUT");
	open(STDOUT, ">>$logfile");

	return $status;

}

sub migrate_all{
	open(STDOUT,">&SAVED_STDOUT")	;
	my $phpcli_path = $options{"phpcli_path"};
	print "\nMigration process started:\n";
	$status=system("$phpcli_path -q $SB_PREFIX/utils/migration.php  --migrate-all-sites");

	open(SAVED_STDOUT, ">&STDOUT");
	open(STDOUT, ">>$logfile");

	return $status;

}



sub update_locales (){

	my $db_host = $options{"db_host"};
	my $db_port = $options{"db_port"};
	my $db_user_name = $options{"sb_db_user_name"};
	my $db_name = $options{"sb_db_name"};
	my $db_passwd = $options{"sb_db_user_passwd"};
	my $phpcli_path = $options{"phpcli_path"};
    $dbh = DBI->connect("DBI:mysql:$db_name:$db_host:$db_port",
                    "$db_user_name", "$db_passwd", {PrintError => 0});
	
        if (defined($DBI::errstr)){
	
	    return $messages{"cant_connect_db"}.": ".$DBI::errstr."\n";
	
	}

	$loc_inst=`$phpcli_path -q $SB_PREFIX/utils/update_locales.php db 2>/dev/null`;
	
	if ( $loc_inst =~ /[e|E]rror/ ){	
		print STDOUT $mod_inst;
	        return    $messages{"locales_failed"};		
		
	}

	@list= split(/ /, $loc_inst);
        foreach $locale (@list) {

 	next if !$locale;


    $status=system("$phpcli_path -q $SB_PREFIX/utils/update_locales.php install $locale");
		    if ( ($status eq 0)){ 
			     print SAVED_STDOUT "The $locale locale has been successfully installed\n";
			     print STDOUT getTime()."The $locale locale has been successfully installed\n";
		    }elsif ( $status ne 0 ){
    	                     print SAVED_STDOUT "Failed to install the $locale locale\n"; 
    	                     print STDOUT getTime()."Failed to install the $locale locale\n"; 
        	    }
		
       }
	$loc_inst=`$phpcli_path -q $SB_PREFIX/utils/update_locales.php source 2>/dev/null`;

	if ( $loc_inst =~ /[e|E]rror/ ){	
		print STDOUT $mod_inst;
	        return    $messages{"locales_failed"};		
		
	}
	
	@list= split(/ /, $loc_inst);
        foreach $locale (@list) {
		$status=system("$phpcli_path -q $SB_PREFIX/utils/update_locales.php remove $locale");

		    if ( ($status eq 0)){ 
			     print SAVED_STDOUT "The $locale locale has been successfully removed\n";
			     print STDOUT getTime()."The $locale has been successfully removed\n";
		    }elsif ( $status ne 0 ){
    	                     print SAVED_STDOUT "Failed to remove the $locale locale\n"; 
    	                     print STDOUT getTime()."Failed to remove the $locale locale\n"; 
        	    }
		
       }
      return	$messages{"locales_installed"};
}

# fix for :BUG: 105376
sub adjust_cgi_memlimit() {
	# my $phpcgi_path = $options{"phpcgi_path"};
	open(FIL, "$phpcgi_path -i |") or return $messages{"memlimit_update_failed"};
	while (<FIL>) {
		chomp;
		if (/Configuration File/i) {
			($cgi_ini_path = $_) =~ s|.*<td class="v">([^<]*)</td>.*|$1|g;
			last;
		}
	}
	close(FIL);
	if (defined($cgi_ini_path)) {
		open(FIL, "$cgi_ini_path") or return $messages{"memlimit_update_failed"};
		@lines = <FIL>;
		close(FIL);
		for (@lines) {
			next unless m/^(\s)*memory_limit(\s)*=/;
			#($val = $_) =~ s/.*=[ \t]*(\d+).*/$1/;
			s/=(\s)*\d+/= 32/ unless (($val = $_) =~ s/.*=\s*(\d+).*/$1/) > 32;
			last;
		}
		if (!defined($val)) {
			push @lines, "memory_limit = 32M";
		}
		if (!defined($val) || $val < 32) {
			open(FIL, ">$cgi_ini_path") or return $messages{"memlimit_update_failed"};
			print FIL @lines;
			close(FIL);
			restorecon($cgi_ini_path);
		}
		#system('sed -i -e "/^[ \t]*memory_limit[ \t]*=/ s/=[ \t]*[0-9]\+M/= 32M/" '.$cgi_ini_path);
	} else {
		return $messages{"memlimit_update_failed"};
	}
	return $messages{"memlimit_update_success"};
}

sub update_templates (){
    my $db_host = $options{"db_host"};
    my $db_port = $options{"db_port"};
    my $db_user_name = $options{"sb_db_user_name"};
    my $db_name = $options{"sb_db_name"};
    my $db_passwd = $options{"sb_db_user_passwd"};
    my $phpcli_path = $options{"phpcli_path"};
    $dbh = DBI->connect("DBI:mysql:$db_name:$db_host:$db_port",
                    "$db_user_name", "$db_passwd", {PrintError => 0});

    if (defined($DBI::errstr)) {
        return $messages{"cant_connect_db"}.": ".$DBI::errstr."\n";
    }

    $loc_inst=`$phpcli_path -q $SB_PREFIX/utils/update_templates.php db 2>/dev/null`;

    if ( $loc_inst =~ /[e|E]rror/ ){
        print STDOUT $mod_inst;
            return    $messages{"templates_failed"};		
        
    }

	@list= split(/ /, $loc_inst);
        foreach $template (@list) {
        next if !$template;
	    $status=system("$phpcli_path -q $SB_PREFIX/utils/update_templates.php install $template");
		    if ( ($status eq 0)){ 
			     print STDOUT getTime()."The $template template has been successfully installed\n";
		    }elsif ( $status ne 0 ){
    	                     print SAVED_STDOUT "Failed to install the $template template\n"; 
    	                     print STDOUT getTime()."Failed to install the $template template\n"; 
        	    }
		
       }

	$loc_inst=`$phpcli_path -q $SB_PREFIX/utils/update_templates.php source 2>/dev/null`;

	if ( $loc_inst =~ /[e|E]rror/ ){	
		print STDOUT $mod_inst;
	        return    $messages{"templates_failed"};		
		
	}

	@list= split(/ /, $loc_inst);
        foreach $template (@list) {
		$status=system("$phpcli_path -q $SB_PREFIX/utils/update_templates.php remove $template");

		    if ( ($status eq 0)){ 
			     print STDOUT getTime()."The $template template has been successfully removed\n";
		    }elsif ( $status ne 0 ){
    	                     print SAVED_STDOUT "Failed to remove the $template template\n"; 
    	                     print STDOUT getTime()."Failed to remove the $template template\n"; 
        	    }
		
       }
      return	$messages{"templates_installed"};
}

# brief Check if anyone's listening on tcp/$_[0]:$_[1]
# param $_[0] local IP address or hostname to check
# param $_[1] local port
# return 0 if port is free
#         1 otherwise
sub listen_host_for_port($$)
{
	(my $host, my $port) = @_;

    my $proto = getprotobyname('tcp');
    my $iaddr = inet_aton($host) or return 0;

    my $paddr = sockaddr_in($port, $iaddr);

    my $res = socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
	# No, we don't wanna share 
	setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, pack("l", 0)) || die "setsockopt: $!";

	# Try to bind to the port specified and see if it fails (that's 
	# exaclty what apache does)
	$res = bind(SOCKET, $paddr);
    
    close SOCKET || return 0;
    return $res ? 0 : 1;
}

sub getSBVersionFromDB() {
	my $db_host = $options{"db_host"};
	my $db_port = $options{"db_port"};
	my $db_user_name = $options{"sb_db_user_name"};
	my $db_name = $options{"sb_db_name"};
	my $db_passwd = $options{"sb_db_user_passwd"};
	$dbh = DBI->connect("DBI:mysql:$db_name:$db_host:$db_port",
                    "$db_user_name", "$db_passwd", {PrintError => 0}) || return;
	my $sth = $dbh->prepare("select value from config_param where name='version'") || return;
	$sth->execute() || return;
	$row = $sth->fetchrow_hashref() || return;
	$version = $row->{'value'};
	$sth->finish();
	$dbh->disconnect();
	return $version;
}

sub performMigration() {
	open(MIGRATE, "<$SB_PREFIX/migrate") ||
			return "Migration failed: unable to determine previous version\n";
	my $version = <MIGRATE>;
	#chomp $version;
	close(MIGRATE);
	if ($version =~ m#3\.X\.X#) {
		$version = getSBVersionFromDB();
		if ($version) {
			open(MIGRATE, ">$SB_PREFIX/migrate");
			print MIGRATE $version;
			close(MIGRATE);
		}
		else { return "Migration failed: unable to determine previous version\n"; }
	}
	$status=migrate();
	unlink("$SB_PREFIX/migrate");
	if ( $status eq "0" ) {
		return "Migration process has finished\n";
	} else {
		return "Migration process has finished with errors\n";
	}
}



#if ( $options{"advanced_help"} eq 1 ){ printUsage( "advanced" );exit} ;
if ( ($options{"help"} eq 1) and ( $options{"advanced_help"} ne 1)  ){ printUsage("short");exit} ;


if ( ($options{"update_modules"} eq "false" ) && ($options{"update_templates"} eq "false" ) && ($options{"update_locales"} eq "false" ) && ($options{"migrate_all"} eq "false" )  ){


    $result = checkParameters();
    
    if (  $result ){
    
        print STDOUT getTime().$result;
	print SAVED_STDOUT $result;
        exit (1);
    }
    
    printUsingParameters();

    if ( $options{"force"} eq "false" ){
	select SAVED_STDOUT;
	
	print "------------\nPLEASE NOTE:\n";
	print $messages{"httpd_will_restarted"}."\n";
	print $messages{"do_you_want"};
	select STDOUT;
	chomp ( $answer = <STDIN> );
	$answer= lc($answer);
	$answer="yes" if ! $answer;
	print "\n";
	if ( ($answer ne "yes") && ($answer ne "y") ){ 
		print "Exit\n"; 
		exit(1); 
	}
    }

    select STDOUT;

    makeConfig();
    if ( $options{"without_restart"} eq "false" ){
	    $status=makeVHost();

 	    if ($status	){

		  print SAVED_STDOUT $messages{"vhost_creation"}.": ...failed\n";
		  print STDOUT getTime().$messages{"vhost_creation"}.": $status ";
	    }else{
	    
		  print SAVED_STDOUT $messages{"vhost_creation"}.": ...Ok\n";
		  print STDOUT getTime().$messages{"vhost_creation"}.": ...Ok\n";
	    }

    }

	

    $err=createDBuser();
    if ($err eq 1007){
	print getTime()."The '".$options{"sb_db_name"}." database already exists.\n";
	print SAVED_STDOUT $messages{"db_creation"}.": ...Ok\n";
	
    }else{
		createDatabase();
		my $status= update_templates();
		print getTime().$status;
		print SAVED_STDOUT $status;
	
		$status = adjust_cgi_memlimit();
		print getTime().$status;
		print SAVED_STDOUT $status;    
	
		$status= update_locales();
		print getTime().$status;
		print SAVED_STDOUT $status;
		
		$status = update_modules();
		print getTime().$status;
		print SAVED_STDOUT $status;
	
		
		if ( -e "$SB_PREFIX/migrate" ){
			$status = performMigration();
			print SAVED_STDOUT getTime().$status;
			print STDOUT getTime().$status;
		}    
    };

    changeOwner();
	

    changeAdmin();
    

    print getTime().$messages{"install_finished"};
    print SAVED_STDOUT $messages{"line"};
    print SAVED_STDOUT $messages{"install_finished"};
    print SAVED_STDOUT $messages{"line"};
    print SAVED_STDOUT "...".$messages{"config_log"}.$logfile."\n";

       
}
if($options{"update_modules"} eq 1 ){
    $status = update_modules();
    print getTime().$status;
    print SAVED_STDOUT $status;
    print SAVED_STDOUT "...".$messages{"config_log"}.$logfile."\n";
	    
}
if($options{"update_templates"} eq 1 ){

	$status=update_templates();
        print getTime().$status;
	print SAVED_STDOUT $status;
        print SAVED_STDOUT "...".$messages{"config_log"}.$logfile."\n";
    	

}
if($options{"update_locales"} eq 1 ){

        $status= update_locales();
        print getTime().$status;
        print SAVED_STDOUT $status;
        print SAVED_STDOUT "...".$messages{"config_log"}.$logfile."\n";
        			
			
}
if($options{"migrate_all"} eq 1 ){

        $status= migrate_all();
        changeOwner();
        if ( $status eq "0" ){
            print STDOUT getTime()."Migration process has finished\n";
        }else{
            print STDOUT getTime()."Migration process has finished with errors\n";
        }
        			
			
}
			
close (STDOUT);
close (SAVED_STDOUT);
