CHips L MINI SHELL

CHips L pro

Current Path : /proc/2/root/usr/local/rvglobalsoft/rvsitebuilder7/etc/
Upload File :
Current File : //proc/2/root/usr/local/rvglobalsoft/rvsitebuilder7/etc/install2.pl

#!/usr/bin/perl

use strict;
use warnings;

use Cwd qw(realpath);
use DBI;
use Digest::MD5 qw(md5_hex);
use English;
use Getopt::Long;
use File::Basename qw(&dirname);
use File::Copy;
use File::Path qw(mkpath);
use MIME::Base64 ();
use POSIX;
use Sys::Hostname;


#global variable
#use vars qw($rvglobalPath $downloadPath $frameworkName $downloadRetry %cmd @modulesName);

my $rvglobalPath = '/usr/local/rvglobalsoft';
my $downloadPath = sprintf('%s/.download', $rvglobalPath);
my $fileVersion = 'rvversion';

my $frameworkName = 'rvframework';
my $downloadRetry = 3;

my %cmd = ();

my @modulesName = (
    'rvsubversion',
    'rvexploit',
    'rvskinallcp',
    'symantecvip',
);

my $reqDBUser = '';
my $reqDBPass = '';

my $nextInstallMsg = '';

#########################################################################################################
# require root to run this command
# perl ./install2.pl --modules[ rvsubversion[=version]] [--force-update] [--rollbackframework=version] [--devmode]
#   --modules           : modules to install eg. --modules rvsubversion --modules rvexploit=1.01
#   --force-update      : force download and install to the latest version(both modules and framework).
#   --rollbackframework : rollback framework to desire version
#   --devmode           : install on local developer mode
#########################################################################################################


########################################
# error code ref    
#   100xx error at main process include validateOption
#   101xx error at startInstaller
#   102xx error at main function
#   103xx error at utility function
########################################



##########################
##  start main process  ##
##########################

# check root to run this command
if (whoami() ne "root") {
    print "You must run this script as root, else you may not have privileges to properly restore all files.\n"
} else {
    if ($#ARGV >= 1) {
        # call checkOption to validate arguments
        if (!validateOption()) {
            # argv not support force quit
            print "[error] 10001 :: argument or modules name not valid.\n";
        } else {
            if (readyForMySQLdata()) {
                # start main installer
                printLog("Start Installer");
                startInstaller();
                printLog("End Installer");
            } else {
                printLog("require mysql admin user to run this script.");
            }
        }
    } else {
        # need an argument to run this command
        print "no argument found.\n";
    }
}

##########################
##   end main process   ##
##########################





#TODO note
# - compare version to latest or rollback -done
# - check force update -50%, waiting for test
# - generate database to hostname.yaml to each module -90%
#     - create user ($moduleName) -done
#     - gen password -done
#     - create empty database table -done
#     - find password -90% :need more information to find out. 
# - devmode : add dev mode to
#       'downloadPackageFromServer', 'prepareRvFramework', 'installModule'
#       or maybe startInstaller function : 100%
# - where is devmode(includefile,config,embed) to checkout from svn??
#
#
# - extract file from cli -90% :wait for download function to test extract
#
#
#
# next release todo, ctrl+f find #NEXT








###########################
##  start main function  ##
###########################


sub validateOption {
    my $validated = 1;
    
    printLog("Do validate options");
    if (!GetOptions(
        "modules=s" => \@{$cmd{'modules'}},
        "rollbackframework=s" => \$cmd{'rollbackframework'},
        "force-update" => \$cmd{'force-update'},
        "devmode" => \$cmd{'devmode'},
    )) {
        #argument not valid, force quit
        return 0;
    }
    
    #support argv: --modules=rvsubversion,rvexploit=1.01
    #            : --modules rvsubversion --modules=rvexploit
    #            : --modules rvsubversion=1.01
    @{$cmd{'modules'}} = split(/,/,join(',',@{$cmd{'modules'}}));

    foreach my $test (@{$cmd{'modules'}}) {
        my $data = extractModuleAndVersion($test);
        if (!in_array(\@modulesName, $data->{'module'})) {
            print "module $data->{'module'} not found.\n";
            $validated = 0;
        } elsif ($data->{'version'} !~ /latest|\d+\.\d+/ ) {
            print "version $data->{'version'} not valid.\n";
            $validated = 0;
        }
    }
    
    #NEXT note: rollback can not use with force-update

    return $validated;
}

sub readyForMySQLdata {
    my ($tmp, $check) = getmycnfdata();
    my $ready = 1;
    if ($check eq '') {
        print "cannot find mysql data\n";
        print "please provide mysql user and password\n";
        my $ok = 0;
        my $user = '';
        my $pass = '';
        do {
            print "mysql admin user:";
            $user = <STDIN>;
            chomp($user);
            if ($user ne '') {
                $ok = 1;
            }
        } while (!$ok);
        $ok = 0;
        do {
            system("stty -echo");
            print "mysql admin password:";
            $pass = <STDIN>;
            chomp($pass);
            print "\n";
            system("stty echo");
            if ($pass ne '') {
                $ok = 1;
            }
        } while (!$ok);
        if (!testSQLConnection($user,$pass)) {
            $ready = 0;
        } else {
            print "MySQL user and password correct!\n";
            $reqDBUser = $user;
            $reqDBPass = $pass;
        }
    }
    
    return $ready;
}

###################### main installer ###########################
sub startInstaller {
    
    my $license = 1;
    my $errorLicense = '';
    
    my $installed = 0;
    
    my $updateOrRollback = {};
    
    my @installModules = ();
    
    # check license
    foreach my $module (@{$cmd{'modules'}}) {
        my $data = extractModuleAndVersion($module);
        if (!validateLicense($data->{'module'})) {
            # error check license
            $errorLicense .= "[error] 10001 :: License for $data->{'module'} not valid.\n";
            $license = 0;
        }
    }
    
    if (!$license) {
        print $errorLicense;
    } else {
        my $errorMsg = '';
        #download rvframework
        #compare 
        if (!compareVersion($frameworkName, $cmd{'rollbackframework'}) ) {
            if (!downloadPackage($frameworkName, $cmd{'rollbackframework'})) {
                $errorMsg .= "[error] 10002 :: can't load $frameworkName\n";
            }
        }
        
        if ($errorMsg eq '') {
            #no error found during download framework
            #progress to download modules
            foreach my $module (@{$cmd{'modules'}}) {
                my $data = extractModuleAndVersion($module);
                if (!compareVersion($data->{'module'}, $data->{'version'}) ) {
                    if (!downloadPackage($data->{'module'}, $data->{'version'})) {
                        $errorMsg .= "[error] 10003 :: can't loaded $data->{'module'}.\n";
                        last;
                    } else {
                        push(@installModules, $module);
                    }
                }
            }
        }
        
        if ($errorMsg ne '') {
            print $errorMsg;
        } else {
            # no error found. install rvframework
#            if (!prepareRvFramework()) {
#                # can't install rvframework
#                # "[error] 10004 :: can't install rvframework"
#                printLog("[error] 10004 :: can't install rvframework");
#            } else {
                
                # install modules
                my $installerror = 0;
                
                foreach my $module (@installModules) {
                    my $data = extractModuleAndVersion($module);
                    
                    if (!installModule($data->{'module'})) {
                        $installerror = 1;
                        # can't install rvframework
                        # "[error] 10005 :: can't install $data->{'module'}"
                        printLog("[error] 10005 :: can't install $data->{'module'}");
                    }
                }
                
                if (!$installerror) {
                    $installed = 1;
                    if ($nextInstallMsg ne '') {
                        printLog("you need to run this command to complete your setup.\n");
                        printLog("$nextInstallMsg");
                        printLog("Note:: command may not working correctly due to have not enought information.")
                    }
                    #NEXT if want to run module installer, insert here.
                } else {
                    #error
                }
#            }
            
        } # end download and install modules
        
    } # end license
    
    return $installed;
}

sub validateLicense {
    my $moduleName = $_[0];
    my $downloadVersion = $_[1] || 'latest';
    
    printLog("Validate License for $moduleName version: $downloadVersion");
    #NEXT check module license from the rvskin server
    # develop next release
    
    #license ok return 1 otherwise return 0;
    return 1;
}

sub compareVersion {
    my $packageName = $_[0];
    my $packageVersion = $_[1];
    
    printLog("compare Version for $packageName");
    if ($cmd{'force-update'}) {
        #force mode do not check anything
        return 0;
    }
    
    my $installedVersion = getPackageVersion($packageName);
    
    my $cmpVersion = 1;
    
    if ($installedVersion eq '') {
        $cmpVersion = 0;
    } else {
        #already install package
        my @aInstlVersion = split(/\./, $installedVersion);
        my @aDLVersion = split(/\./, $packageVersion);
        
        if ($packageVersion eq 'latest') {
            #check update from server
            #NEXT get data from server
            #develop next release
            my $versionFromServer = '1.01';
            @aDLVersion = split(/\./, $versionFromServer);
        }
        
        #find length of array
        my $loopcount = 0;
        if ($#aInstlVersion >= $#aDLVersion) {
            $loopcount = $#aInstlVersion;
        } else {
            $loopcount = $#aDLVersion;
        }
        
        for (my $i = 0; $i <= $loopcount; $i++) {
            if ( int($aInstlVersion[$i]) != int($aDLVersion[$i]) ) {
                $cmpVersion = 0;
                last;
            }
        }
    }
    
    #return 1 if install version is latest version otherwise return 0;
    return $cmpVersion;
}

sub getPackageVersion {
    my $packageName = $_[0];
    my $packagePath = sprintf('%s/%s/%s', $rvglobalPath, $packageName, $fileVersion);
    
    my $rvversion = '';
    
    if (-f $packagePath) {
        if (open(my $fh, '<', $packagePath)) {
            my $data = <$fh>;
            close($fh);
            
            chomp($data);
            if ($data =~ m/^\d+\.\d+$/) {
                $rvversion = $data;
            }
        }
    }
    
    return $rvversion;
}

sub downloadPackage {
    #loop for retry download package, real download on 'downloadPackageFromServer'
    my $packageName = $_[0];
    
    my $retry = 1;
    my $success = 0;

    for (my $retry = 1; $retry <= $downloadRetry; $retry++) {
        # connect to server to download package
        printLog("downloading $packageName");
        if (downloadPackageFromServer($packageName)) {
            $success = 1;
            last;
        }
        printLog("cannot download $packageName, retry download $retry/$downloadRetry");
        printLog("waiting for try to download again in few seconds.");
        sleep(10);
    }
    
    return $success;
}

sub downloadPackageFromServer {
    #real download package
    my $packageName = $_[0];
    my $downloadStatus = 0;
    #NEXT download and validate package from server
    
    if ($cmd{'devmode'}) {
        #develop mode, export code from svn
        my $savePath = sprintf('%s/%s', $rvglobalPath, $packageName);
        my $confFile = dirname(realpath($0)).'/devmode.dat';
        #HOW TO export ??
        # - read from config file
        # - include another perl file
        # - embed code to this file
        #svn export svn://projectname savePath --username USER --password PASS
        if (-f $confFile) {
            my $devcode = '';
            if (open my $rh, '<', $confFile) {
                $devcode = <$rh>;
                close($rh);
                chomp($devcode);
                my $illustrateName = devIllustrateName($packageName);
                
                if ($packageName eq $frameworkName) {
                    foreach my $module (@{$cmd{'modules'}}) {
                        my $data = extractModuleAndVersion($module);
                        $savePath = sprintf('%s/%s', $rvglobalPath, $data->{'module'});
                        $devcode =~ s/projectName/$illustrateName/;
                        $devcode =~ s/savePath/$savePath/;
                        #printLog("[DEBUG] :: $devcode");
                        if (system($devcode) == 0) {
                            $downloadStatus = 1;
                        } else {
                            $downloadStatus = 0;
                            last;
                        }
                    }
                } else {
                    $devcode =~ s/projectName/$illustrateName/;
                    $devcode =~ s/savePath/$savePath/;
                    #printLog("[DEBUG] :: $devcode");
                    if (system($devcode) == 0) {
                        $downloadStatus = 1;
                    }
                }
            }
        }
    } else {
        #production mode, download tarball from server
    }
    
    return $downloadStatus;
}

sub devIllustrateName {
    my $packageName = $_[0];
    my $illustName = {
        'rvframework'   => 'RvFramework',
        'rvsubversion'  => 'rvsubversion',
        'rvexploit'     => 'rvmodules',
        'rvskinallcp'   => 'rvskinallcp',
        'symantecvip'	=> 'symantectvip',
    };
    
    return $illustName->{$packageName};
}

sub extractModuleAndVersion {
    my $module = $_[0];

    my @adata = split(/=/, $module, 2);
    
    my $data = {
        'module' => '',
        'version' => 'latest',
    };
    
    $data->{'module'} = $adata[0];
    $data->{'version'} = $adata[1] if defined $adata[1];
    
    
    return $data;
}

#sub prepareRvFramework {
#    # extract downloaded file to /usr/local/rvglobalsoft/.download/rvframework
#    # install cpan dependencies for rvframework
#    # /usr/local/rvglobalsoft/.download/rvframework/etc/buildcpan.pl
#    # setup hostname.yaml to /usr/local/rvglobalsoft/.download/rvframework/var/$hostname.yaml
#    my $prepareStatus = 0;
#    
#    my $fileName = 'rvframework.tar.gz';
#    
#    my $downloadFrameworkPath = sprintf('%s/%s/%s', $downloadPath, $frameworkName, $fileName);
#    my $extractPath = sprintf('%s/%s', $downloadPath, $frameworkName);
#    
#    printLog("preparing RvFramework..");
#    
#    my $extract = 0;
#    
#    if ($cmd{'devmode'}) {
#        $extract = 1;
#    } else {
#        if (!-d $extractPath) {
#            mkpath($extractPath);
#        }
#        if (-f $downloadFrameworkPath) {
#            $extract = extractFile($downloadFrameworkPath, $extractPath);
#            unlink($downloadFrameworkPath);
#        }
#    }
#    
#    if ($extract) {
#        #extract file succeed
#        my $servername = hostname;
#        
##        if (!copy("$extractPath/etc/default.conf.dist.yaml","$extractPath/var/$servername.yaml")) {
##            # [error] :: 102xx cannot copy default.conf.dist.yaml
##            printLog("[error] :: 102xx cannot copy default.conf.dist.yaml");
##        } else {
##            #xxx setup require field value in $servername.yaml
##            $prepareStatus = 1;
##        }
#
#        $prepareStatus = 1;
#    }
#    
#    return $prepareStatus;
#}

sub installModule {
    my $moduleName = $_[0];
    my $installStatus = 0;
    
    # extract downloaded framework to /usr/local/rvglobalsoft/$moduleName
    # extract downloaded module to /usr/local/rvglobalsoft/$moduleName
    # sync /usr/local/rvglobalsoft/.download/rvframework to /usr/local/rvglobalsoft/$moduleName
    # sync /usr/local/rvglobalsoft/.download/$moduleName to /usr/local/rvglobalsoft/$moduleName
    # updateCPANpath
    
    my $frameworkFileName = 'rvframework.tar.gz';
    
    my $downloadFrameworkPath = sprintf('%s/%s/%s', $downloadPath, $frameworkName, $frameworkFileName);
    
    my $downloadModulePath = sprintf('%s/%s/%s', $downloadPath, $moduleName, $moduleName."tar.gz");
    #my $extractPath = sprintf('%s/%s', $downloadPath, $moduleName);
    #my $frameworkPath = sprintf('%s/%s', $downloadPath, $frameworkName);
    my $installPath = sprintf('%s/%s', $rvglobalPath, $moduleName);
    
    printLog("install $moduleName to $installPath");
    
    my $extract = 0;
    
    if ($cmd{'devmode'}) {
        $extract = 1;
    } else {
        if (!-d $installPath) {
            mkpath($installPath);
        }
        if (-f $downloadFrameworkPath) {
            printLog("..Setup framework core modules");
            $extract = extractFile($downloadFrameworkPath, $installPath);
            if (-f $downloadModulePath) {
                printLog("..Setup modules");
                $extract = extractFile($downloadModulePath, $installPath);
                unlink($downloadModulePath);
            }
        }
    }
    
    if ($extract) {
        #extract file succeed, update cpan path (and run install dependencies).
        if (updateCpanPath($installPath)) {
            if (createFrameworkConfig($moduleName)) {
                $installStatus = 1;
                printLog("Change mode directory $installPath/lib/perl5 to 755");
                chmod(0755, "$installPath/lib/perl5");
                printLog("Change mode directory $installPath/public_html/index.pl to 755");
                chmod(0755, "$installPath/public_html/index.pl");
                #NEXT add command to help user install real module
                if (-f "$installPath/etc/buildcpan.pl") {
                    $nextInstallMsg .= "perl $installPath/etc/buildcpan.pl\n";
                }
            }
        } else {
            # [error] :: 102xx cannot update cpan path
            printLog("[error] :: 102xx cannot update cpan path");
        }
    }
    
    return $installStatus;
}

sub extractFile {
    my $source  = $_[0];
    my $dest    = $_[1];

    my $extractComplete = 0;

    if (!-e $source) {
        # [error] 102xx :: not found archive file
        printLog("[error] 102xx :: not found archive file");
    } else {
        if ($] > 5.010) {
            #use pure perl Archive::Extract to extract file
            #add 'if' to avoid error when running from an older perl version
            use if $] > 5.010, "Archive::Extract";
    
            
                my $ae = Archive::Extract->new( archive => $source );
                my $extract = $ae->extract( to => $dest );
                if (!$extract) {
                    # [error] 102xx :: can't extract file
                    printLog("[error] 102xx :: can't extract file");
                } else {
                    #extract success goto sync framework
                    $extractComplete = 1;
                }
        } else {
            #perl before 5.10.0 does not support Archive::Extract
            #use unix cmd system to extract file instead.
            my $cmd = getExtractCmd($source,$dest);
            if (system($cmd) == 0) {
                $extractComplete = 1;
            } else {
                printLog("[error] 102xx :: can't extract file");
            }
        }
    }

    return $extractComplete;
}

sub updateCpanPath {
    my $programPath = $_[0];
    
    my $updateStatus = 0;

    printLog("update CPAN path..");
    
    if (open(my $fh, '<', $programPath . '/public_html/index.pl')) {
        my @data = <$fh>;
        close($fh);
    
        my $strData = join('', @data);
    
        my $find    = '@CPAN\-PATH@';
        my $replace = "$programPath/lib/perl5";
    
        $strData =~ s/$find/$replace/g;
        if (open(my $wh, '>', $programPath . '/public_html/index.pl')) {
            print $wh $strData;
            close($wh);
            print "update $programPath/public_html/index.pl complete..\n";
            $updateStatus = 1;
        }
    }
    
    return $updateStatus;
}

sub printLog {
    my $message = $_[0];
    
    if ($cmd{'devmode'}) {
        print $message."\n";
    }
    
    return 1;
}

sub createFrameworkConfig {
    my $moduleName = $_[0];
    # - create user ($moduleName)
    #     - gen password
    #     - create empty database table
    # - setup hostname.yaml to /usr/local/rvglobalsoft/.download/rvframework/var/$hostname.yaml
    my $createStatus = 0;
    
    my $servername = hostname;
    my $installConfigPath = sprintf('%s/%s/var/%s.yaml', $rvglobalPath, $moduleName, $servername);
    my $defaultConfigPath = sprintf('%s/%s/etc/default.conf.dist.yaml', $rvglobalPath, $moduleName);
    
#    if (-f $installConfigPath) {
#        printLog("found existing config, skip to next action.");
#        return 1;
#    }
    
    my $genpassword = generatepassword();
    my $mysqlport = '3306';
    
    if (createDatabaseFramework($moduleName, $genpassword, $servername, $mysqlport)) {
        #setup hostname.yaml
        if (open(my $rh, '<', $defaultConfigPath)) {
            my @data = <$rh>;
            close($rh);
            my $strData = join('', @data);
            
            # host: localhost
            # port: 3306
            # user: root
            # pass: ''
            # name: rvframework
            $strData =~ s/host\: localhost/host\: $servername/;
            $strData =~ s/port\: 3306/port: $mysqlport/;
            $strData =~ s/user\: root/user\: $moduleName/;
            $strData =~ s/pass\: \'\'/pass: \'$genpassword\'/;
            $strData =~ s/name\: rvframework/name: $moduleName/;
            if (open(my $wh, '>', $installConfigPath)) {
                print $wh $strData;
                close($wh);
                $createStatus = 1;
            }
        }
    }
    
    return $createStatus;
}

sub createDatabaseFramework {
    my $moduleName = $_[0];
    my $passwd = $_[1];
    my $servername = $_[2];
    my $port = $_[3] || 3306;
    
    my $createStatus = 0;
    
    my $hostip = '127.0.0.1';
    my @hostList = ($servername, 'localhost', $hostip);
    
    my ($ruser,$rpasswd) = getmycnfdata();
    if ($reqDBUser ne '' && $ruser eq '') {
        $ruser = $reqDBUser;
    }
    if ($reqDBPass ne '' && $rpasswd eq '') {
        $rpasswd = $reqDBPass;
    }
    
    my $dbh = DBI->connect("dbi:mysql:mysql;localhost;$port",$ruser,$rpasswd);
    if (!$dbh) {
        printLog("[error] 102xx :: MySQL ERROR..\n".$dbh->errstr);
    } else {
        #create database table
        # CREATE DATABASE $moduleName;
        printLog("CREATE DATABASE $moduleName.");
        my $cdb = $dbh->do("CREATE DATABASE IF NOT EXISTS $moduleName");
        if ($cdb >= 0) {
            # check is user exist
            $dbh->do("USE mysql;");
            my $checkUser = $dbh->prepare('SELECT User, Host, Password FROM user WHERE user=?');
            $checkUser->bind_param(1, $moduleName);
            my $checkResult = $checkUser->execute();
            if ($checkResult && $checkResult ne '0E0') {
                printLog("GRANT privilege on existing user.");
                my $preGrant = $dbh->prepare("GRANT ALL PRIVILEGES ON `$moduleName`.* TO '$moduleName'\@?");
                foreach my $hostdata (@hostList) {
                    $preGrant->bind_param(1, $hostdata);
                    my $res = $preGrant->execute();
                    if ($res && $res eq '0E0') {
                        $createStatus = 1;
                    } else {
                        $createStatus = 0;
                        last;
                    }
                }
            } else {
                #dont have user
                printLog("GRANT privilege on new user.");
                my $preGrant = $dbh->prepare("GRANT ALL PRIVILEGES ON `$moduleName`.* TO '$moduleName'\@? IDENTIFIED BY '$passwd'");
                foreach my $hostdata (@hostList) {
                    $preGrant->bind_param(1, $hostdata);
                    my $res = $preGrant->execute();
                    if ($res && $res eq '0E0') {
                        $createStatus = 1;
                    } else {
                        $createStatus = 0;
                        last;
                    }
                }
                
            }
            if (!$createStatus) {
                printLog("[error] 102xx :: MySQL ERROR..\n".$dbh->errstr);
            }
        } else {
            #printLog("[error] 102xx :: cannot create database to mysql database");
            printLog("[error] 102xx :: MySQL ERROR..\n".$dbh->errstr);
        }
        $dbh->disconnect;
    }
    
    return $createStatus;
}

sub getmycnfdata {
    my $file = '';
    
    my $suser = '';
    my $spass = '';
    my $shost = '';
    my $iport = '';
    
    my $cpanel = '/root/.my.cnf';
    my $plesk = '/etc/psa/.psa.shadow';
    my $directadmin = '/usr/local/directadmin/conf/mysql.conf';
    my $unknown = '/etc/phpmyadmin/config-db.php';
    
    if (-e "/usr/local/cpanel/cpkeyclt") {
        #cPanel
        $file = $cpanel;
    } elsif (-e "/etc/psa/psa.key") {
        #Plesk
        $file = $plesk;
    } elsif (-e '/usr/local/directadmin/conf/license.key') {
        #DirectAdmin
        $file = $directadmin;
    } elsif (-e '/etc/phpmyadmin/config-db.php') {
        #unknown
        $file = $unknown;
    }
    
    if ($file ne '') {
        if (open(my $rh, '<', $file)) {
            while(<$rh>) {
                if ($file eq $cpanel) {
                    #cPanel
                    if (/^user=(\S+)/) {
                        $suser = $1;
                        $suser =~ s/^\"|\"$//g;
                    } elsif (/^pass=(\S+)/) {
                        $spass = $1;
                        $spass =~ s/^\"|\"$//g;
                    } elsif (/^host=(\S+)/) {
                        $shost = $1;
                        $shost =~ s/^\"|\"$//g;
                    } elsif (/^port=(\S+)/) {
                        $iport = $1;
                        $iport =~ s/^\"|\"$//g;
                    }
                } elsif ($file eq $plesk) {
                    #Plesk
                    $suser = 'admin';
                    $shost = 'localhost';
                    $iport = 3306;
                    $spass = trim($_);
                    last;
                } elsif ($file eq $directadmin) {
                    #DirectAdmin
                    $suser = 'da_admin';
                    $shost = 'localhost';
                    $iport = 3306;
                    if (/^user=(\S+)/) {
                        $suser = $1;
                        $suser =~ s/^\"|\"$//g;
                        $suser =~ s/^\'|\'$//g;
                    } elsif (/^passwd=(\S+)/) {
                        $spass = $1;
                        $spass =~ s/^\"|\"$//g;
                        $spass =~ s/^\'|\'$//g;
                    } elsif (/^host=(\S+)/) {
                        $shost = $1;
                        $shost =~ s/^\"|\"$//g;
                        $shost =~ s/^\'|\'$//g;
                    } elsif (/^port=(\S+)/) {
                        $iport = $1;
                        $iport =~ s/^\"|\"$//g;
                        $iport =~ s/^\'|\'$//g;
                    }
                } elsif ($file eq $unknown) {
                    #unknow
                    if (/^\$dbuser=(\S+)/) {
                        $suser = $1;
                        $suser =~ s/^\'|\';$//g;
                    } elsif (/^\dbpass=(\S+)/) {
                        $spass = $1;
                        $spass =~ s/^\'|\';$//g;
                    } elsif (/^\dbserver=(\S+)/) {
                        $shost = $1;
                        $shost =~ s/^\'|\';$//g;
                    } elsif (/^\dbport=(\S+)/) {
                        $iport = $1;
                        $iport =~ s/^\'|\';$//g;
                    }
                }
            }
            close($rh);
        }
    }
    
    return ($suser, $spass, $shost, $iport);
}

sub testSQLConnection {
    my $ruser = $_[0];
    my $rpasswd = $_[1];
    
    my $ok = 0;
    
    my $dbh = DBI->connect("dbi:mysql:mysql;localhost;3306;",$ruser,$rpasswd);
    if (!$dbh) {
        printLog("[error] 102xx :: MySQL ERROR..\n".$dbh->errstr);
    } else {
        $ok = 1;
        $dbh->disconnect;
    }
    
    return $ok;
}

###########################
##   end main function   ##
###########################



















####################
# utility function #
####################

sub whoami {
    my $whoami = '';
    $whoami = getpwuid($REAL_USER_ID);
    
    if ($whoami eq '') {
        $whoami = `whoami`;
        chomp($whoami);
    }
    
    return $whoami;
}

sub in_array {
    my ($arr,$search_for) = @_;
    return 1 if (grep {$search_for eq $_} @$arr);
    return 0;
}

sub whichCmd {
    my ($cmd) = $_[0];
    return if ($cmd eq '');
    return if ($cmd =~/\//);
    
    my $whichCmd = '';
    my $binpath = '';
    # get order from CentOS release 5.6 (Final)
    # /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    my @binpathList = (
        '/usr/local/sbin',
        '/usr/local/bin',
        '/sbin',
        '/bin',
        '/usr/sbin',
        '/usr/bin',
    );
    
    foreach my $path(@binpathList) {
        if ( -x $path . '/' . 'which') {
            $whichCmd = $path . '/' . 'which';
            last;
        }  
    }
    if ($whichCmd eq '') {
        
        print('which command is not support.');    
        return $binpath;
    }
    
    $binpath = callBackticks("$whichCmd $cmd");
    chomp ($binpath);
    $binpath =~s/\n|\r//gi;
    
    if ($binpath eq '') {
        foreach my $path(@binpathList) {
            if ( -x $path . '/' . $cmd) {
                $binpath = $path . '/' . $cmd;
                last;
            }
        }                
    }
    
    if ($binpath eq '') {
        print($cmd . ' is not support.');
    } elsif (!-x $binpath) {
        print($cmd . ' is not executeable.');
    }    
        
    return $binpath;
}

sub callBackticks {
    my $cmd = $_[0];
    return `$cmd`;
}

sub trim {
    my ($value) = shift;
    $value =~s/^[\s| ]*|[\s| ]*$//simx;
    return $value;
}

sub getFileExtension {
    my $fileName = $_[0] || '';
    my @fsplit = split(/\./,$fileName);
    
    my $ext = $fileName;
    if ($#fsplit > 0) {
        #tar, bz2, gz, tgz, tar.gz, tbz, tar.bz2
        if ($fsplit[$#fsplit] eq 'gz' || $fsplit[$#fsplit] eq 'bz2') {
            if ($fsplit[int($#fsplit-1)] eq 'tar') {
                $ext = sprintf("%s.%s", $fsplit[int($#fsplit-1)],$fsplit[$#fsplit]);
            } else {
                $ext = sprintf("%s", $fsplit[$#fsplit]);
            }
        } else {
            $ext = sprintf("%s", $fsplit[$#fsplit]);
        }
    }
    
    return $fileName;
}

sub getExtractCmd {
    my $sourcefileName = $_[0] || '';
    my $destPath = $_[1] || '';
    #tar, bz2, gz, tgz, tar.gz, tbz, tar.bz2
    #tar -xvf /data/package.tar -C /usr
    #tar -xvzf filename.tar.gz -C /desired/path
    #tar xvzf file-1.0.tar.gz - for uncompress a gzip tar file (.tgz or .tar.gz) 
    #tar xvjf file-1.0.tar.bz2 - for uncompress a bzip2 tar file (.tbz or .tar.bz2) 
    #tar xvf file-1.0.tar - for uncompressed tar file (.tar)
    
    my $option = '';
    
    if ($sourcefileName eq '') {
        return 0;
    } else {
        my $ext = getFileExtension($sourcefileName);
        
        if ($ext eq 'tgz' || $ext eq 'tar.gz') {
            $option = "tar zxvf $sourcefileName -C $destPath";
        } elsif ($ext eq 'tbz' || $ext eq 'tar.bz2') {
            $option = "tar jxvf $sourcefileName -C $destPath";
        } elsif ($ext eq 'tar') {
            $option = "tar xvf $sourcefileName -C $destPath";
        } elsif ($ext eq 'gz') {
            #gunzip -c file.gz > /THERE/file
            #zcat is a shortcut for gunzip -c
            my $gzip = whichCmd('zcat');
            if ($gzip eq '') {
                $gzip = whichCmd('gunzip');
                if ($gzip eq '') {
                    printLog("$ext not support.");
                } else {
                    $gzip .= " -c $sourcefileName > $destPath";
                }
            }
            $option = $gzip;
        } elsif ($ext eq 'bz2') {
            my $bzip2 = whichCmd('bzcat');
            if ($bzip2 eq '') {
                $bzip2 = whichCmd('bunzip2');
                if ($bzip2 eq '') {
                    printLog("$ext not support.");
                } else {
                    $bzip2 .= " -c $sourcefileName > $destPath";
                }
            }
            $option = $bzip2;
        } else {
            printLog("$ext not support.");
        }
    }
    
    return $option;
}

sub generatepassword {
    my $length = $_[0] || 10;
    
    if ($length !~ m/^\d+$/ || $length < 8) {
        $length = 10;
    }
    
    my @genpass = ();

    my $sDataString = 'ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; #not include 'Il' to avoid miss leading to 'LI'
    my $sDataNumber = '0123456789';
    my $sDataSymbol = '#-$%,;)]+_@(&}*!=^~?';
    
    my $fixLength = int($length*0.33+0.5);
    
    
    #random symbolic
    my @aDataSymbol = split(//,$sDataSymbol);
    for (my $i = 0 ; $i < $fixLength ; $i++) {
        my $index = int(rand($length-2))+1;
        
        my $idata = int(rand(scalar(@aDataSymbol)));
        
        $genpass[$index] = $aDataSymbol[$idata];
    }
    
    #random number
    my @aDataNumber = split(//,$sDataNumber);
    for (my $i = 0 ; $i < $fixLength ; $i++) {
        my $ok = 0;
        do {
            my $index = int(rand($length-2))+1;
            if (!$genpass[$index]) { 
                my $idata = int(rand(scalar(@aDataNumber)));
                $genpass[$index] = $aDataNumber[$idata];
                $ok = 1;
            }
        } while (!$ok);
    }
    
    #random string
    my @aDataString = split(//,$sDataString);
    for (my $i = 0 ; $i < $length ; $i++) {
        my $ok = 0;
        if (!$genpass[$i]) {
            my $idata = int(rand(scalar(@aDataString)));
            $genpass[$i] = $aDataString[$idata];
        }
    }
    
    return join('',@genpass);
}

Copyright 2K16 - 2K18 Indonesian Hacker Rulez