#!/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