CHips L MINI SHELL

CHips L pro

Current Path : /proc/2/root/usr/local/rvglobalsoft/rvsitebuilder7/auto/
Upload File :
Current File : //proc/2/root/usr/local/rvglobalsoft/rvsitebuilder7/auto/real_autorvadmintools.cgi

#!/bin/sh
eval 'if [ -x /usr/local/cpanel/3rdparty/bin/perl ]; then exec /usr/local/cpanel/3rdparty/bin/perl -x -- $0 ${1+"$@"}; else exec /usr/bin/perl -x $0 ${1+"$@"}; fi;'
if 0;

#!/usr/bin/perl


##################################################################################################
# Agreement
##################################################################################################

print qq(
		=================================================
			\e[1m\e[34mAgreement on Setup process in WHM\e[0m
			    \e[1m\e[34mSOFTWARE LICENSE AGREEMENT\e[0m 
			       \e[1m\e[34m(Updated May, 2018)\e[0m 
		=================================================

	In consideration for your use of the software and any updates,
	customizations and/or enhancements, entitled RVsitebuilder
	("Software") provided by RV Global Soft Co.,Ltd. ("Licensor"),
	you ("User"), as either an individual or a single business
	entity, agree to the following terms and conditions. If you do
	not agree to all of the terms of this agreement, click the "Do
	not agree" button and return the product to the place of
	purchase for a full refund. 
	
	\e[1m\e[34m1. License. \e[0m
	Licensor hereby grants the User a non-exclusive,
	non-transferable license to use the Software for use on a
	single server (virtual or physical) owned, leased, or
	otherwise controlled by you, at a single time. Licensor
	reserves the right at any time, without liability or prior
	notice, to change the features or characteristics of the
	Software, this Agreement, or the Software's documentation and
	related materials. 
	
	\e[1m\e[34m2. License Restrictions. \e[0m
	a. User acknowledges that the Software and its structure,
	organization, and source code constitute valuable trade
	secrets of Licensor. Accordingly, User agrees not to (i) copy,
	perform, distribute, modify, adapt, alter, translate, or
	create derivative works from the Software; (ii) merge the
	Software with other software; (iii) sublicense, lease, rent,
	or loan the Software to any third party; (iv) reverse
	engineer, decompile, disassemble, or otherwise attempt to
	derive the source code for the Software; or (v) otherwise use
	the Software except as expressly allowed in this Agreement. 
	b. Licensor retains exclusive ownership of all worldwide
	copyrights, trade marks, service marks, trade secrets, patent
	rights, moral rights, property rights and all other industrial
	rights in the Software and documentation, including any
	derivative works, modification, updates, or enhancements. All
	rights in and to the Software not expressly granted to User in
	this Agreement are reserved by Licensor. Nothing in this
	Agreement shall be deemed to grant, by implication, estoppel
	or otherwise, a license under any of Licensor's existing or
	future patents. 
	c. If User is an employee, contractor or agent of the United
	States Government, the following provision applies. The
	Software and documentation are comprised of "commercial
	computer software" and "commercial computer software
	documentation" as such terms as used in 48 C.F.R. 12.212 (SEPT
	1995) and are provided to the Government (i) for acquisition
	by or on behalf of civilian agencies, consistent with the
	policy set forth in 48 C.F.R. 12.212; or (ii) for acquisition
	by or on behalf of units of the Department of Defense,
	consistent with the policies set forth in 48 C.F.R. 227.7202-1
	(JUN 1995) and 227.7202-3 (JUN 1995). Unpublished rights
	reserved under the copyright laws of the United States. 
	d. User shall not use the Software in any way that violates
	any local, state, federal or law of other nations, including
	but not limited to the posting of information that may violate
	third party rights, that may defame a third party, that may be
	obscene or pornographic, that may harass or assault others,
	that may violate hacking or other computer crime regulations,
	etc. Licensor does not monitor or edit any transmissions,
	postings, routings or other materials which User may send,
	post, route, transmit or otherwise move through or with the
	Software. 
	
	\e[1m\e[34m3. WARRANTY DISCLAIMER. \e[0m
	THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY
	WHATSOEVER, INCLUDING BUT NOT LIMITED TO ANY FUNCTIONALITY OR
	ITS BEING VIRUS FREE. USER RECOGNIZES THAT THE AS IS CLAUSE OF
	THIS AGREEMENT IS AN IMPORTANT PART OF THE BASIS OF THIS
	AGREEMENT, WITHOUT WHICH LICENSOR WOULD NOT HAVE AGREED TO
	ENTER THIS AGREEMENT. LICENSOR AND THIRD PARTIES DISCLAIM ALL
	WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, REGARDING THE
	SOFTWARE, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS
	FOR A PARTICULAR PURPOSE, TITLE, AND NONINFRINGEMENT. NO
	REPRESENTATION OR OTHER AFFIRMATION OF FACT REGARDING THE
	SOFTWARE SHALL BE DEEMED A WARRANTY FOR ANY PURPOSE OR GIVE
	RISE TO ANY LIABILITY OF OR THIRD PARTIES WHATSOEVER. USER
	ACKNOWLEDGES THAT HE OR SHE HAS RELIED ON NO WARRANTIES OR
	STATEMENTS OTHER THAN AS MAY BE SET FORTH HEREIN. 
	
	\e[1m\e[34m4. LIMITATION OF LIABILITY. \e[0m
	LICENSOR SHALL NOT BE LIABLE TO USER OR ANY THIRD PARTY FOR
	ANY INCIDENTAL, INDIRECT, EXEMPLARY, SPECIAL OR CONSEQUENTIAL
	DAMAGES, UNDER ANY CIRCUMSTANCES, INCLUDING, BUT NOT LIMITED
	TO, LOST PROFITS, REVENUE OR SAVINGS, LOSS OF GOODWILL, OR THE
	LOSS OF USE OF ANY DATA, EVEN IF LICENSOR HAD BEEN ADVISED OF,
	KNEW, OR SHOULD HAVE KNOWN, OF THE POSSIBILITY THEREOF. UNDER
	NO CIRCUMSTANCES SHALL LICENSOR'S AGGREGATE CUMULATIVE
	LIABILITY HEREUNDER, WHETHER IN CONTRACT, TORT, OR OTHERWISE,
	EXCEED THE TOTAL AMOUNT OF FEES ACTUALLY PAID BY USER UNDER
	THIS AGREEMENT. USER ACKNOWLEDGES THAT THE FEES PAID BY HIM OR
	HER REFLECT THE ALLOCATION OF RISK SET FORTH IN THIS AGREEMENT
	AND THAT LICENSOR WOULD NOT ENTER INTO THIS AGREEMENT WITHOUT
	THESE LIMITATIONS ON ITS LIABILITY. 
	
	\e[1m\e[34m5. Indemnification. \e[0m
	User shall defend, indemnify and hold harmless Licensor, its
	officers, directors contractors, agents and employees, from
	any and all claims or causes of action arising out of use of
	or related to the Software, and pay any and all damages and
	expenses (including but not limited to attorneys fees incurred
	by Licensor and/or third parties) in connection therewith.
	Licensor reserves the right, at it own expense, to assume the
	exclusive defense and control of any matter otherwise subject
	to indemnification by User, in which event User shall
	cooperate with the Licensor in asserting any available
	defenses. 
	
	\e[1m\e[34m6. Termination. \e[0m
	This Agreement is effective unless terminated by Licensor at
	any time for any breach of this Agreement. If you are leasing
	the Software, and fail to pay the applicable license fees,
	Licensor shall have the right to terminate your License. User
	may terminate this Agreement at any time by destroying all
	copies of the Software in User's possession and deleting the
	Software from User's computer system and other storage media
	and provide written verification of such destruction to
	Licensor. This Agreement and User's right to use this Software
	automatically terminate if User breaches this Agreement. 
	
	\e[1m\e[34m7. Legal Compliance. \e[0m
	Licensor may suspend or terminate use of Software and this
	Agreement immediately upon receipt of any notice which alleges
	that User has used the Software for any purpose that violates
	any local, state, federal or law of other nations, including
	but not limited to the posting of information that may violate
	third party rights, that may defame a third party, that may be
	obscene or pornographic, that may harass or assault others,
	that may violate hacking or other criminal regulations, etc.
	of its agents, officers, directors, contractors or employees.
	In such event, Licensor may disclose the User's identity and
	contact information, if requested by a government or law
	enforcement body, or as a result of a subpoena or other legal
	action, and Licensor shall not be liable for damages or
	results thereof and User agrees not to bring any action or
	claim against this Licensor for such disclosure. 
	
	\e[1m\e[34m8. Miscellaneous. \e[0m
	Either party may assign this Agreement to any successor in
	interest who purchases or through change in control owns
	greater than fifty percent of the assets or equity of such
	entity and agrees in writing to be bound by the terms and
	conditions herein; any other assignment shall be void. This
	Agreement and any dispute arising hereunder shall be construed
	in accordance with the laws of the Thailand without regard to
	principles of conflict of laws. For the purpose of this
	Agreement, User consents to the personal jurisdiction and
	venue of the state and federal courts located in Thailand. If
	any provision of this Agreement is prohibited by law or held
	to be unenforceable, the remaining provisions hereof shall not
	be affected, and this Agreement shall continue in full force
	and effect as if such unenforceable provision had never
	constituted a part hereof, and the unenforceable provision
	shall be automatically amended to so as to best accomplish the
	objectives of such unenforceable provision within the limits
	of applicable law. This Agreement may be executed in
	counterparts, each of which shall be deemed an original but
	all of which together shall constitute the same instrument.
	Any waiver of a provision of this Agreement must be in writing
	and signed by the party to be charged. A valid waiver
	hereunder shall not be interpreted to be a waiver of that
	obligation in the future or any other obligation under this
	Agreement. This Agreement constitutes the entire agreement
	between the parties related to the subject matter hereof,
	supersedes any prior or contemporaneous agreement between the
	parties relating to the Software and shall not be changed
	except by written agreement signed by an officer of Licensor.
	
	Please \e[1m\e[34mtype 'yes'\e[0m (no quote) to accept agreement.
);

print "\n\nDo you want to upgrade/install (yes/no)? ";

eval {
    local $SIG{ALRM} = sub { die 'Timed Out'; };
    alarm 120;
    my($agree, $agreeconfirm);
    while($agree = <STDIN>) {
        $agree =~ s/\n//g;
        $agree = lc($agree);
        if ($agree eq 'yes' || $agree eq 'y') {
            $agreeconfirm = 1;
            last;
        }
        if ($agree eq 'no' || $agree eq 'n' ) {
            $agreeconfirm = 0;
            last;
        }
        print "\n\nDo you want to upgrade/install (Yes|No)? ";
    }

    if ($agreeconfirm ne "1") {
        exit;
    }
    #<-- Cancel the alarm -->
    alarm 0; 
};

alarm 0;
 
if ( $@ ) {
    if ( $@ =~/Timed Out/ ) {
        print "\n\nTimed out. Explicitly confirm to accept agreement is required.\n";
        print "If you get this error from cron, SSH to server and run\n";
        print "perl /usr/local/rvglobalsoft/rvadmintools/auto/autorvadmintools.cgi\n\n";
    }
    else {
        print "\nError: Eval corrupted: $@\n";
    }
    exit;
}
print "\n";


BEGIN {
    my $scriptInstallcpan = '/scripts/perlinstaller';
    if(-x $scriptInstallcpan){
        my $cpanModuldeAll = {
            'YAML::Syck'    => 'YAML/Syck.pm',
            'DBI'           => 'DBI.pm',
            'DBD::mysql'    => 'DBD/mysql.pm',
            'Net::SSLeay'   => 'Net/SSLeay.pm',
          	'IPC::Run3'     => 'IPC/Run3.pm',
        };
        foreach my $eachCpanModuldeName (keys %{$cpanModuldeAll}){
            my $cpanModuldeName = $eachCpanModuldeName->{$eachCpanModuldeName};
            my $hasModule = `perl -e 'eval { use $eachCpanModuldeName; print 1; }' 2>&1`;
            if ($hasModule ne '1') {
                print "Install cpan module $eachCpanModuldeName\n";
                system($scriptInstallcpan . ' ' . $eachCpanModuldeName);
            }
        }
    }
}

use strict;
use warnings;
use Socket;
use File::Basename;
use Data::Dumper;


my $inst = RVAdmintoolsRealInstaller->new(programName => 'rvadmintools', productDisplay => 'RVAdmintools' , INSTALLTITLE => 'RVAdmintools Package Installer');

#require reqPackage to call another
$inst->{'reqPackage'} = 'rvadmintools-package';

#setup reqPackage information
$inst->setInstallPackage("$inst->{'reqPackage'}.ProductName", 'RVAdmintools');
$inst->setInstallPackage("$inst->{'reqPackage'}.ProductCode", 'rvadmintools-package');
$inst->setInstallPackage("$inst->{'reqPackage'}.SaveFilename", 'rvadmintools.tar.bz2');

#setup for installer
$inst->setInstallPackage("$inst->{'reqPackage'}.auto.installer", 'autorvadmintools');
$inst->setInstallPackage("$inst->{'reqPackage'}.auto.real", 'real_autorvadmintools');

#override default functionConfig to extend call function
$inst->setFunctionConfig("begin.next", 'LicenseInfo'); #test
#add new functionConfig that already override from previous

#validate symantecvip license
$inst->setFunctionConfig("LicenseInfo.next", 'LicenseInfoGet');
$inst->setFunctionConfig("LicenseInfo.group", 'LicenseInfo');
$inst->setFunctionConfig("LicenseInfoGet.next", 'LicenseInfoType');
$inst->setFunctionConfig("LicenseInfoGet.group", 'LicenseInfo');
$inst->setFunctionConfig("LicenseInfoType.next", 'LicenseInfoExp');
$inst->setFunctionConfig("LicenseInfoType.group", 'LicenseInfo');
$inst->setFunctionConfig("LicenseInfoExp.next", 'GetLicense');
$inst->setFunctionConfig("LicenseInfoExp.group", 'LicenseInfo');

#$inst->setFunctionConfig("GetLicense.next", 'ValidateRVManager');
#$inst->setFunctionConfig("GetLicense.group", 'LicenseInfo');

#validate pass, require to install rvmanager
$inst->setFunctionConfig("GetLicense.next", 'installRVAdmintoolsUI');
$inst->setFunctionConfig("GetLicense.group", 'UpdateInstaller');

#fallback to main installer for rvadmintools
$inst->setFunctionConfig("installRVAdmintoolsUI.next", 'DownloadInstaller');
$inst->setFunctionConfig("installRVAdmintoolsUI.group", 'UpdateInstaller');
#override next function for SetupInstaller
$inst->setFunctionConfig("SetupInstaller.next", 'ConfigAndSetupRVAdmintools');

$inst->setFunctionConfig("ConfigAndSetupRVAdmintools.next", 'end');
$inst->setFunctionConfig("ConfigAndSetupRVAdmintools.group", 'UpdateInstaller');

$inst->startInstaller();

$inst->exitScript();






















package RVAdmintoolsRealInstaller;
use strict;
use warnings;
use File::Basename;
use Data::Dumper;
use IPC::Open3;
use Socket;
use IO::Socket;
use IPC::Run3;

BEGIN {
    push(@INC, dirname(__FILE__));
}
use base qw(RVSInstaller);
{
    sub new {
        my $class = shift;
        my $self = $class->SUPER::new( @_ );
        
        bless $self, $class;
        return $self;
    }
    
    
    sub Process_LicenseInfo{
    	my $self = shift;
	    my ($param) = $_[0];
	    my %hParam = %{$param};
	    
	    $self->{ScreenControl}->DisplayMsg('', 1);
	    $self->{ScreenControl}->DisplayMsg('########################################################################', 1);
	    $self->{ScreenControl}->DisplayMsg("#\t\t" . $self->{Language}->TranSlate('License Information') . '.', 1);
	    $self->{ScreenControl}->DisplayBoxMsg(0, $self->{Language}->TranSlate('License Information'), '');
	    $self->{ScreenControl}->DisplayMsg('########################################################################', 1);
	    if (defined $hParam{'force'}) {
	        $self->{ScreenControl}->DisplayMsg('Use option force update', '1');
	        if ( -e $self->getInstallConfig('packagePath')) {
	            system($self->{'cmd'}->{'rm'}, '-rf', $self->getInstallConfig('packagePath'),'/dev/null 2>&1');
	            system($self->{'cmd'}->{'mkdir'}.' -p ' . $self->getInstallConfig('packagePath'));
	        }
	    }
	
	    $self->callNextFunc(\%hParam);
    }
    
    sub Process_LicenseInfoGet {
	    #TODO license checker
	    my $self = shift;
	    
	    my ($param) = $_[0];
	    my %hParam = %{$param};
	    
	    # $self->{'programName'}
	    my $getrvCode = getRvCode();
	    $getrvCode =~ s/\n|\r|\t//gi;
	    	    
	    $hParam{'MainIP'} = RVSInstaller::Process::getMainIP();
	    $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('license for IP') . ' ' . $hParam{'MainIP'}, '1', 'subMsg' . $self->{ACTION});
	    push(@{$hParam{'boxMessages'}}, $self->{Language}->TranSlate('license for IP') . ' ' . $hParam{'MainIP'});
	    $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});
	    
	    $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Used xxx connection validate xxx for IP', 'SSL' ,'license') . ' ' . $hParam{'MainIP'}, '1', 'subMsg' . $self->{ACTION});
	    push(@{$hParam{'boxMessages'}}, $self->{Language}->TranSlate('Used xxx connection validate xxx for IP', 'SSL' ,'license') . ' ' . $hParam{'MainIP'});
	    $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});
	    $self->{ScreenControl}->LogMsg($self->{Language}->TranSlate('Used xxx connection validate xxx for IP', 'SSL', 'license') . ' ' . $hParam{'MainIP'} . "\n");
	    # <-- Connection to license site by SSL-->
	    

	    
	    #my %licenseInfo = %{$self->UrlConnection($self->getInstallConfig('SiteConf.license2.address.site1'), 443, '', 1, $self->getInstallConfig('SiteConf.license2.uri.site1') . $getrvCode)};
		my $url = 'https://license2.rvglobalsoft.com/getinfo/rvadmintools';
		#my %licenseInfo = RVSInstaller::Process::userAgentConnect($url,{'rvcode'=>$getrvCode},'post','https');
		my %licenseInfo = RVSInstaller::Process::getcontentbyurl($url,'post',"rvcode=$getrvCode");
				
	    if ( $licenseInfo{'Err'} ) {
	        # <-- Connection error -->
	        $licenseInfo{'Err'} =~s/\r|\n|\"//gi;
	        $self->{ScreenControl}->DisplayMsg($self->{failedColor});
	        $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Sorry') . ', ' . $self->{Language}->TranSlate('cannot used xxx connection to', 'SSL') . ' ' . $self->getInstallConfig('SiteConf.license.address.site1') . ': ' . $licenseInfo{'Err'} , 1, 'subMsg' . $self->{ACTION});
	        $self->{ScreenControl}->DisplayMsg("\e[0m", 1);
	        push(@{$hParam{'boxMessages'}}, 
	            ' -- ' . $self->{Language}->TranSlate('Sorry') . ', ' . $self->{Language}->TranSlate('cannot used xxx connection to', 'SSL') . ' ' . $self->getInstallConfig('SiteConf.license.address.site1') . ': ' . $licenseInfo{'Err'}
	        );
	        $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});
	            
	        # <-- Used NONE SSL Connection -->
	        $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Used xxx connection validate xxx for IP', 'NONE-SSL' ,'license') . ' ' . $hParam{'MainIP'}, '1', 'subMsg' . $self->{ACTION});
	        push(@{$hParam{'boxMessages'}}, 
	            $self->{Language}->TranSlate('Used xxx connection validate xxx for IP', 'NONE-SSL' ,'license') . ' ' . $hParam{'MainIP'}
	        );
	        $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});
	        $self->{ScreenControl}->LogMsg($self->{Language}->TranSlate('Used xxx connection validate xxx for IP', 'NONE-SSL', 'license') . ' ' . $hParam{'MainIP'} . "\n");
	        %licenseInfo = ();
	        #%licenseInfo = %{$self->UrlConnection($self->getInstallConfig('SiteConf.license2.address.site1'), 80, '', 0, $self->getInstallConfig('SiteConf.license2.uri.site1') . $getrvCode)};
	        
	        $url = 'http://license2.rvglobalsoft.com/getinfo/rvadmintools';
	        
	        %licenseInfo = RVSInstaller::Process::getcontentbyurl($url,'post',"rvcode=$getrvCode");
	     
	        if ( $licenseInfo{'Err'} ) {
	            # <-- Connection error -->
	            $licenseInfo{'Err'} =~s/\r|\n|\"//gi;
	            
	            $self->{ScreenControl}->LogMsg('SSL connection has error, ' . $licenseInfo{'Err'} . "\n");
	            $self->{ScreenControl}->DisplayMsg($self->{failedColor});
	            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Sorry') . ', ' . $self->{Language}->TranSlate('cannot connection to') . ' ' . $self->getInstallConfig('SiteConf.license.address.site1') . ': ' . $licenseInfo{'Err'} , 1, 'subMsg' . $self->{ACTION});
	            $self->{ScreenControl}->DisplayMsg("\e[0m", 1);
	           
	            $self->{ScreenControl}->LogMsg('Sorry, cannot connection with SSL and NONE-SSL' . ".\n");
	            $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});
	            # <-- End Process Installer -->
	            $self->exitScript();
	        }
	    }
	    
	    my %licenseData = RVSInstaller::Process::UnSerializerData($licenseInfo{'Page'});
	    
	    #if license active to write licen data to rvlogin config path
	    if (defined $licenseData{'rvadmintools'} ) {
	    	if (!-e '/var/cpanel/rvglobalsoft/.rvadmintools/conf') {
            	RVSInstaller::Process::mkdirp('/var/cpanel/rvglobalsoft/.rvadmintools/conf', "0755");
        	}
        	my $licenseData = \%licenseData;
	    	write_ini_file('/var/cpanel/rvglobalsoft/.rvadmintools/conf/licenseData.ini',$licenseData{'rvadmintools'});
	    	system('chmod','755','/var/cpanel/rvglobalsoft/.rvadmintools/conf/licenseData.ini');
	    }
	    
	    if ( $licenseData{'on error'} ) {
	            my $errortext = showerrortext (%licenseData);     	
	        	$self->{ScreenControl}->DisplayMsg($self->{failedColor});
	            $self->{ScreenControl}->DisplayMsg("\n".$errortext."\n");	        	
	            #$self->{ScreenControl}->DisplayMsg($licenseData{'issue_title'} , '', 'subMsg' . $self->{ACTION});
	            $self->{ScreenControl}->LogMsg($licenseData{'issue_title'} . "\n");
	            $self->{ScreenControl}->DisplayBoxMsg(0, '', $licenseData{'issue_title'});
	            $self->{ScreenControl}->DisplayMsg("\e[0m", 1);
	            $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});
	            # <-- End Process Installer -->
 	            if ($licenseData{'issue_id'} ne '501') {
                    #to exit
                    $self->exitScript();
                }  	            
	    }
	    
	    
	    $self->{ScreenControl}->LogMsg('Receive Data : ' . $licenseInfo{'Page'} . "\n");
	    $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('license for IP') . ' ' . $licenseData{'rvadmintools'}{'license-ip'}, '', 'subMsg' . $self->{ACTION});
	    $self->{ScreenControl}->LogMsg($self->{Language}->TranSlate('license for IP') . ' ' .  $licenseData{'rvadmintools'}{'license-ip'} . ' has been completed.' . "\n");
	    $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{completedColor}");
	    $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Pass') , '', 'subMsg' . $self->{ACTION});
	    $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
	    @{$hParam{'boxMessages'}} = ();
	    push(@{$hParam{'boxMessages'}}, $self->{Language}->TranSlate('license for IP') . ' ' .  $licenseData{'rvadmintools'}{'license-ip'} . ': ' . $self->{Language}->TranSlate('Pass'));
	    $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'boxMessages'}});

	    $hParam{'LicenseInfo'} = $licenseInfo{'Page'};
	    if(defined $self->{'productDisplay'}){
	    	 push(@{$hParam{'rvadmintools'}}, {'display' => $self->{'productDisplay'}});
	    }
	    push(@{$hParam{'BoxMessages'}}, @{$hParam{'boxMessages'}});
	    
	    $self->callNextFunc(\%hParam);
	}
    
    sub Process_LicenseInfoType {
	    my $self = shift;
	    
	    my ($param) = $_[0];
	    my (%hParam) = %{$param};
	
	    $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Product information'));
	    my (%hLicenseInfo) = RVSInstaller::Process::UnSerializerData($hParam{'LicenseInfo'});
	    $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{completedColor}");
	    
	    if ( exists $hLicenseInfo{$self->{'programName'}} ) {
	        $self->{ScreenControl}->DisplayMsg($hParam{$self->{'programName'}}[0]{'display'}, '', 'subMsg' . $self->{ACTION});
	        $self->{ScreenControl}->LogMsg('Your license type ' . $hLicenseInfo{$self->{'programName'}}{'expire-show'} . "\n");
	        push(@{$hParam{'BoxMessages'}}, 'Your license type: ' . $hLicenseInfo{$self->{'programName'}}{'expire-show'});
	        $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'BoxMessages'}});
	    }
	    else {
	        $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Unknown') , '', 'subMsg' . $self->{ACTION});
	        $self->{ScreenControl}->LogMsg('Your license type unknown' . "\n");
	        push(@{$hParam{'BoxMessages'}}, 'Your license type: Unknown');
	        $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'BoxMessages'}});
	    }
	    $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
	    $self->callNextFunc(\%hParam);
	}
	
	sub Process_LicenseInfoExp {
	    my $self = shift;
	    
	    my ($param) = $_[0];
	    my (%hParam) = %{$param};
	
	    $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Validate expired date'), '', 'subMsg' . $self->{ACTION});
	    $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'BoxMessages'}}, $self->{Language}->TranSlate('Validate expired date') . '...');
	    
	    my (%hLicenseInfo) = RVSInstaller::Process::UnSerializerData($hParam{'LicenseInfo'});
	    
	    if ( exists $hLicenseInfo{$self->{'programName'}}{'expire-date'} && $hLicenseInfo{$self->{'programName'}}{'expire-date'} > time ) {
	        $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{completedColor}");
	        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($hLicenseInfo{$self->{'programName'}}{'expire-date'});
	        $year += 1900;
	        $mon = $self->{'MONS'}->{$mon};
	        $self->{ScreenControl}->DisplayMsg("$mday $mon $year" , '', 'subMsg' . $self->{ACTION});
	        $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
	        $self->{ScreenControl}->LogMsg('Your license expired  on ' . "$mday $mon $year\n");
	        $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'BoxMessages'}}, $self->{Language}->TranSlate('Validate expired date') . ': ' . "$mday $mon $year");
	    }
	    elsif ( exists $hLicenseInfo{$self->{'programName'}}{'expire-date'} && $hLicenseInfo{$self->{'programName'}}{'expire-date'} < time ) {
	         $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{failedColor}");
	         my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($hLicenseInfo{$self->{'programName'}}{'expire-date'});
	        $year += 1900;
	        $mon = $self->{'MONS'}->{$mon};
	         $self->{ScreenControl}->DisplayMsg("Your license has expired. " .$hLicenseInfo{$self->{'programName'}}{'expire-date'}. "( $mday $mon $year)", '', 'subMsg' . $self->{ACTION});
	         $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
	         $self->{ScreenControl}->LogMsg('Your license has expired. ' . $hLicenseInfo{$self->{'programName'}}{'expire-date'} . "( $mday $mon $year )\n");
	         $self->{ScreenControl}->DisplayBoxMsg(0, '', @{$hParam{'BoxMessages'}}, "Your license has expired. " .$hLicenseInfo{$self->{'programName'}}{'expire-date'}. "( $mday $mon $year)");
	    } else {
	        $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{failedColor}");
	        if ( exists $hLicenseInfo{'on error'} && $hLicenseInfo{'on error'} ) {
	            $self->{ScreenControl}->DisplayMsg($hLicenseInfo{'issue_title'} , '', 'subMsg' . $self->{ACTION});
	            $self->{ScreenControl}->LogMsg($hLicenseInfo{'issue_title'} . "\n");
	            $self->{ScreenControl}->DisplayBoxMsg(0, '', $hLicenseInfo{'issue_title'});
	        }
	        else {
	            my $noneLicenseMsg = "Cannot get RVadmintools license from RVGlobalsoft. Please make a new order for RVLogin at http://www.rvlogin.technology/getrvlogin first. It's Free.";	            
	            $self->{ScreenControl}->DisplayMsg($noneLicenseMsg, '', 'subMsg' . $self->{ACTION});
	            $self->{ScreenControl}->LogMsg($noneLicenseMsg . "\n");
	            $self->{ScreenControl}->DisplayBoxMsg(0, '', $noneLicenseMsg);
	        }
	        $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
	        $self->exitScript();
	    }
	    $self->{ScreenControl}->CloseBoxMsg();
	    $self->callNextFunc(\%hParam);
	}
		
	sub Process_GetLicense {
	    my $self = shift;
	    
	    my ($param) = $_[0];
	    $self->{ScreenControl}->DisplayMsg('', 1);
	    $self->{ScreenControl}->DisplayMsg('########################################################################', 1);
	    $self->{ScreenControl}->DisplayMsg("#\t\t" . $self->{Language}->TranSlate("Updated License Key") . '.', 1);
	    $self->{ScreenControl}->DisplayMsg('########################################################################', 1);
	    $self->{ScreenControl}->LogMsg($self->{Language}->TranSlate("Updated License Key"));
	    $self->{ScreenControl}->DisplayBoxMsg(1, $self->{Language}->TranSlate("Updated License Key"), 'Please wait...');
	    $self->callNextFunc($param); 
	}
    
    
    sub Process_SetupInstaller_uncompressFile {
        my $self = shift;
        my @logTarData = ();
        #TODO uncompress solution
        chdir($self->getInstallConfig('sourcePath'));
        
        my @cmd = ($self->{'cmd'}->{'tar'},'-jxvf',$self->getInstallPackage("$self->{'reqPackage'}.SaveFilename"));
        my ($in,$out,$error);
        run3 \@cmd, \$in, \$out, \$error ;
        if($?) {
            printf "Exit code indicates problems: %i\n", $?>>8;
        }
        if ($error) { 
            my $errMsg = $error;
                $errMsg=~s/\n$//;
                $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{failedColor}");
                $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Failed'));
                $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
                $self->{ScreenControl}->DisplayMsg('', 1);
                $self->{ScreenControl}->DisplayMsg("$self->{failedColor}");
                $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Sorry') . ', '.$errMsg, 0, 'subMsg' . $self->{ACTION}, '', '#FF0000');
                $self->{ScreenControl}->DisplayMsg("\e[0m", 1);
                $self->{ScreenControl}->LogMsg('Uncompress the package has been uncompleted, ' . $errMsg . ".\n");
                $self->exitScript();
        } else {
            my @line = split /\n/, $out;
            foreach my $line (@line) {
                $line=~s/\r|\n//gi;
                $self->{ScreenControl}->DisplayMsg($line , '1', 'subMsg' . $self->{ACTION});
                $self->{ScreenControl}->LogMsg($line . "\n");
                push(@logTarData, $line);
            }
        }
        
        my $chData = 1;
        my $errorMsg = '';
        foreach my $data ( @logTarData ) {
            if ( $data =~ m/\/$/) {
                if ( !-d $data) {
                    $errorMsg = sprintf("%s %s %s", $self->{Language}->TranSlate('the folder'), $data, $self->{Language}->TranSlate('cannot uncompressed'));
                    $chData = 0;
                    last;
                }
            }
            else {
                if ( !-e $data) {
                    $errorMsg = sprintf("%s %s %s", $self->{Language}->TranSlate('the file'), $data, $self->{Language}->TranSlate('cannot uncompressed'));
                    $chData = 0;
                    last;
                }
            }
        }
        
        chdir($self->getInstallConfig('thisPath'));
        if ( !$chData ) {
            $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{failedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Failed'));
            $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
            $self->{ScreenControl}->DisplayMsg('', 1);
            $self->{ScreenControl}->DisplayMsg("$self->{failedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Sorry') . ', ' . $errorMsg . '.', 1, 'subMsg' . $self->{ACTION}, '', '#FF0000');
            $self->{ScreenControl}->DisplayMsg("\e[0m", 1);
            $self->{ScreenControl}->LogMsg('Uncompress the package has been uncompleted, ' . $errorMsg . ".\n");
            $self->exitScript();
        }
        else {
            if ( -e $self->getInstallPackage("$self->{'reqPackage'}.SaveFilename")) {
                unlink($self->getInstallPackage("$self->{'reqPackage'}.SaveFilename"));
            }
            if ( -e $self->getInstallPackage("$self->{'reqPackage'}.SaveFilename")) {
                unlink($self->getInstallPackage("$self->{'reqPackage'}.SaveFilename"));
            }
            
            $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{completedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Completed') , '', 'subMsg' . $self->{ACTION});
            $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
            $self->{ScreenControl}->LogMsg('Uncompress the package has been completed' . "\n");
        }
    }
    
    sub Process_SetupInstaller_rsyncFileAfterUncompress {
        my $self = shift;
        
        #avoid rsync to sync zip package
        my $packageFile = sprintf("%s/%s", $self->getInstallConfig('sourcePath'), $self->getInstallPackage("$self->{'reqPackage'}.SaveFilename"));
        if (-f $packageFile) {
            unlink($packageFile);
        }
        
        #my $pid3 = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $self->{'cmd'}->{'rsync'} . ' -avz --timeout=60 ' . $self->getInstallConfig('sourcePath') . '/ ' . $self->getInstallConfig('thisPath'));
        my @cmd = ($self->{'cmd'}->{'rsync'},'-avz','--timeout=60',$self->getInstallConfig('sourcePath').'/', $self->getInstallConfig('thisPath'));
        my ($in,$out,$error);
        run3 \@cmd, \$in, \$out, \$error ;
        if($?) {
            printf "Exit code indicates problems: %i\n", $?>>8;
        }
        if ($error) {
            my $errMsg = $error;
            $errMsg=~s/\n$//;
            $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{failedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Failed'));
            $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
            $self->{ScreenControl}->DisplayMsg('', 1);
            $self->{ScreenControl}->DisplayMsg("$self->{failedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Sorry') . ', '.$errMsg, 0, 'subMsg' . $self->{ACTION}, '', '#FF0000');
            $self->{ScreenControl}->DisplayMsg("\e[0m", 1);
            $self->{ScreenControl}->LogMsg("Rsync the package has not completed, $errMsg.\n");
            $self->exitScript();
        } else {
            my @line = split /\n/, $out;
            foreach my $line (@line) {
                $line=~s/\r|\n//gi;
                $self->{ScreenControl}->DisplayMsg($line , '1', 'subMsg' . $self->{ACTION});
                $self->{ScreenControl}->LogMsg($line . "\n");
            }
        }
    }
    
    sub Process_installRVAdmintoolsUI {
        my $self = shift;
        my $param = shift;
        my %hParam = %{$param};
        #just for naming package no process in this part
        
        $self->callNextFunc(\%hParam);
    }
    
    sub Process_ConfigAndSetupRVAdmintools {
        my $self = shift;
        my $param = shift;
        my %hParam = RVSInstaller::Process::UnSerializerData($param);
        
        $self->{ScreenControl}->DisplayMsg('', 1);
        $self->{ScreenControl}->DisplayMsg('########################################################################', 1);
        $self->{ScreenControl}->DisplayMsg("#\t\t" . "Configure and setup CPAN path for ".$self->getInstallPackage("$inst->{'reqPackage'}.ProductName") . '.', 1);
        $self->{ScreenControl}->DisplayMsg('########################################################################', 1);
        $self->{ScreenControl}->LogMsg("Configure and setup database for ".$self->getInstallPackage("$inst->{'reqPackage'}.ProductName") . "\n");
        
        $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Configuring CPAN path...') , '', 'subMsg' . $self->{ACTION});
        my $indexFile = $self->getInstallConfig('thisPath').'/public_html/index.cgi';
        my %configStatus = ();
        if (open(my $fh, '<', $indexFile)) {
            my @data = <$fh>;
            close($fh);
            
            my $strData = join('', @data);
            
            my $find = '@CPAN\-PATH@';
            my $replace = $self->getInstallConfig('libPath')."/lib/perl5";
            
            $strData =~ s/$find/$replace/g; 
            if (open(my $wh, '>', $indexFile)) {
                print $wh $strData;
                close($wh);
            } else {
                $configStatus{'Err'} = $!;
            }
        } else {
            $configStatus{'Err'} = $!;
        }
        
        if (!defined($configStatus{'Err'})) {
            $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{completedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Completed') , '', 'subMsg' . $self->{ACTION});
            $self->{ScreenControl}->DisplayMsg("\e[0m ]", 1);
            $self->{ScreenControl}->LogMsg('Configure CPAN path has been completed' . "\n");
        } else {
            $self->{ScreenControl}->DisplayMsg("<TAB>[ $self->{failedColor}");
            $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate('Failed') , '', 'subMsg' . $self->{ACTION});
            $self->{ScreenControl}->DisplayMsg(" ]\e[0m", 1);
            $self->{ScreenControl}->LogMsg('Configure CPAN path has error ' . $configStatus{'Err'} . ".\n");
            $self->exitScript();
        }
        
         $self->callNextFunc(RVSInstaller::Process::SerializerData(\%hParam));
    }
    
    sub Process_end {
        my $self = shift;
        
        #create global libPath if not exist
        my $defaultRVGlobalPerlLib = $self->getInstallConfig('libPath')."/perl5";
        if (!-e $defaultRVGlobalPerlLib) {
            RVSInstaller::Process::mkdirp($defaultRVGlobalPerlLib, "0755");
        }
        
        
        #make symlink path to libpath
        if (!-l $self->getInstallConfig('thisPath')."/lib/perl5") {
            symlink($defaultRVGlobalPerlLib, $self->getInstallConfig('thisPath')."/lib/perl5");
        }
        
        #create symlink to cgi path
        if(-l '/usr/local/cpanel/whostmgr/docroot/cgi/rvadmintools'){
        	system('rm','-rf','/usr/local/cpanel/whostmgr/docroot/cgi/rvadmintools')
        }
        if(!-l '/usr/local/cpanel/whostmgr/docroot/cgi/rvadmintools'){
        	system('ln','-s','/usr/local/rvglobalsoft/rvadmintools/public_html','/usr/local/cpanel/whostmgr/docroot/cgi/rvadmintools');
        }
        
        #create symlink to cpanel module
        if(!-l '/usr/local/cpanel/Cpanel/Rvadmintools.pm'){
        	system('ln','-s','/usr/local/rvglobalsoft/rvadmintools/data/admintoolsPerl/Rvadmintools.pm','/usr/local/cpanel/Cpanel/');
        }
        
        #create symlink to cpanel customizations/includes
        linktocpanelincludepath();
        
        #register appconfig
        if(-e '/usr/local/cpanel/cpkeyclt'){
	        $self->registerAppConfig();
	    }
	   
	   	#install cpan module UNIVERSAL::require
        if(-f '/root/installcpan.sh'){
        	system('rm','-f','/root/installcpan.sh');
        }
      	system('cp','/usr/local/rvglobalsoft/rvadmintools/auto/installcpan.sh','/root/');
      	system('chmod','+x','/root/installcpan.sh');
      	system('/root/installcpan.sh');
      	
       
        #touch install complete file
        system('touch','/usr/local/rvglobalsoft/rvadmintools/var/INSTALL_COMPLETE');
        
        ###=====Download RVLogin License ===+###
        #TODO ตรงนี้ให้ download licenseData.ini ด้วยหรือเปล่า
        #system('perl','/usr/local/rvglobalsoft/rvlogin/data/getLicenseFile.pl');
        
        #if register success
        $self->{ScreenControl}->DisplayMsg($self->{Language}->TranSlate("Install ".$self->getInstallPackage("$inst->{'reqPackage'}.ProductName")." has completed") .'.', 1, 'msg' . $self->{ACTION});
             
        
        $self->exitScript();
    }
     
   

#OLDBACKUP 	
# 	sub addVipUserToDB {
# 		my $vipUserConfFile = '/var/cpanel/rvglobalsoft/.rvglobalsoft/symantecvip/conf/vipuserConf.ini';
# 		my ($dbuser, $dbpass , $dbserver, $dbport);
#        ($dbuser, $dbpass, $dbserver, $dbport) = RVSInstaller::Process::getmycnfdata();
#        my $dbdb = 'rvlogin';
#        
#        if (!$dbserver) {
#            $dbserver = "localhost"; 
#        }
#        
#        if (!$dbport) {
#            $dbport = 3306;
#        }
#        if (!$dbuser) {
#            $dbuser = 'root';   
#        }
#
#		my $dsn = "DBI:mysql:database=$dbdb;host=$dbserver;port=$dbport";
#		my $dbh = DBI->connect($dsn, $dbuser, $dbpass);
#		my $sql = '';
#		my $q = $dbh->prepare("SELECT * FROM user_info");
#		$q->execute;
#		my $data = $q->fetchall_hashref('user_id');
#		$q->finish();
#		my $countValue = scalar(keys %{$data});
# 		my %dataConf;
# 		
# 		my $keyExit = 0;
# 		
# 		if(-f $vipUserConfFile)
# 		{
# 			%dataConf = parseIniFiles1($vipUserConfFile);
#			foreach my $vipUserName (keys %dataConf){
#				my ($vipId,$vipName) = split('_',$vipUserName);
#				foreach my $userId (keys %{$data}){
#					if($data->{$userId}->{description} eq $vipUserName)
#					{
#						$keyExit = 1;
#					}
#					last;
#				}
#				if(!$countValue && !$keyExit)
#				{
#					$sql = sprintf('INSERT INTO user_info (user_id,user_name,user_group_id,description) VALUES (NULL,"%s",1,"%s");',$vipName,$vipUserName);
#					$dbh->do("$sql");
#				}
#			}
# 		}
#		
#		$dbh->disconnect();		
# 		
# 	}
 	
	
	sub linktocpanelincludepath {
		
		if (!-e '/var/cpanel/customizations/includes') {
         	RVSInstaller::Process::mkdirp('/var/cpanel/customizations/includes', "0755");
     	}
        
		opendir(DH, '/usr/local/rvglobalsoft/rvadmintools/data/admintoolsIncludeUI/') || die "Can't opendir /usr/local/rvglobalsoft/rvadmintools/data/admintoolsIncludeUI/: $!";
	    my @files = readdir DH;
	    closedir(DH);
	    if (!-e '/var/cpanel/rvglobalsoft/.rvadmintools/conf') {
            	RVSInstaller::Process::mkdirp('/var/cpanel/rvglobalsoft/.rvadmintools/conf', "0755");
        	}
	    foreach my $file (@files) {
	    	next if ($file eq '.' || $file eq '..');
	    	#ลบไฟล์ manual เดิมที่มีปัญหาจากชื่อภาษาไทย
	    	if ($file =~/paper_lantern/) {
	    		system('rm','-f','/usr/local/rvglobalsoft/rvadmintools/data/admintoolsIncludeUI/'.$file);
	    	}
	    	if (!-l '/var/cpanel/customizations/includes/'.$file && $file =~ /\.html\.tt/) {
	    		system('ln','-s','/usr/local/rvglobalsoft/rvadmintools/data/admintoolsIncludeUI/'.$file,'/var/cpanel/customizations/includes/');
	    	}
	    }
	    
	    return 1;
	}
	
	sub trim {
	    my $string = $_[0];
	    $string =~ s/^\s+//;
	    $string =~ s/\s+$//;
	    return $string;
	}
	
	
	
	sub parseIniFiles1 {
		my $path  = $_[0];
		my %conf  = ();
		my @lines = file($path);
		foreach my $array (@lines) {
			next if ($array =~ /^$/);
			my ($keys, $values) = split('=', $array, 2);
			$keys        = trim($keys);
			$values      = trim($values);
			$conf{$keys} = $values;
		}
		return %conf;
	}
	
	sub parseIniFile {
		my ($file) = @_ ;
		
		my $ref_isReadSuccess =
		  $_[1];    #if '$_[1]' not defined '$ref_isReadSuccess' will not defined also
		my $res = {};

		#if (-e $file && -r $file) {
		if (open(my $FILERead, '<', $file)) {
			my $openGroup = '';
			while (<$FILERead>) {
				$_ =~ s/\r|\n//gi;
				next if (/^$/gi);
				next if (/^#/);

				#found group
				if (/^\[(.*?)\]$/) {
					$openGroup = $1;
					$openGroup =~ s/^ +//gi;
					$openGroup =~ s/ +$//gi;
					$res->{$openGroup} = {};
					next;
				}

				#normal ini
				my ($key, $value) = split(/=/, $_, 2);
				$key   = trim($key);
				$value = trim($value);

				if ($openGroup) {
					if (!exists $res->{$openGroup}->{$key}) {
						$res->{$openGroup}->{$key} = $value;
					}
				} else {
					$res->{$key} = $value;
				}

			}
			close($FILERead);
			if (defined($ref_isReadSuccess) && ref($ref_isReadSuccess) eq 'SCALAR') {
				${$ref_isReadSuccess} = 1;
			}
		} else {
			$res = {};
		}
		return $res;
	}
	
	sub write_ini_file {
        my ($filename, $iniConf) = @_;
        #RVL::logMessage('======================================' . $filename, __CONSTANT__::RVL_LOG_DEBUG);
        #RVL::logMessage('======================================' . $iniConf->{enabled}, __CONSTANT__::RVL_LOG_DEBUG);
        my $writeLine = '';
        my @aLines    = ();
        my @aLine1d   = ();
        my @aLine2d   = ();
        my $iswriteIniFile = 0;
        foreach my $confKey1 (sort keys %{$iniConf}) {
            #If 1d ini
            #RVL::logMessage('======================================' . $confKey1, __CONSTANT__::RVL_LOG_DEBUG);
            if (!is_hash($iniConf->{$confKey1})) {
            	#RVL::logMessage('======================================  ' . $confKey1 .  "   \$iniConf->{$confKey1} " .$iniConf->{$confKey1} , __CONSTANT__::RVL_LOG_DEBUG);
                $writeLine = sprintf("%s=%s", $confKey1, (defined $iniConf->{$confKey1} && $iniConf->{$confKey1} ne '') ? $iniConf->{$confKey1} : '');
                push(@aLine1d, $writeLine);
                next;
            }
            $writeLine = sprintf("[%s]", $confKey1);
            push(@aLine2d, $writeLine);
            foreach my $confKey2 (sort keys %{ $iniConf->{$confKey1} }) {
                $writeLine =
                  sprintf("%s=%s", $confKey2, $iniConf->{$confKey1}->{$confKey2});
                push(@aLine2d, $writeLine);
            }
        }
    
        push(@aLines, @aLine1d);
        push(@aLines, @aLine2d);
    
        if (open(my $FILEWrite, '>', $filename)) {
            foreach my $writeLine2 (@aLines) {
                chomp($writeLine2);
                print $FILEWrite $writeLine2."\n";
            }
            close($FILEWrite);
            $iswriteIniFile = 1;
        } else {
            $iswriteIniFile = $!.": $filename";
        }
        
        #RVL::logMessage('======================================  ' . $iswriteIniFile , __CONSTANT__::RVL_LOG_DEBUG);
        return $iswriteIniFile;
    }
    
    sub mkdirp {
	    my $pathName = $_[0];	    
	    my $permission = defined($_[1]) ? oct($_[1]) : oct("0644");
	    my @checkPath = split("/", $pathName);
	    my $pathNow = '';
	    my $ismkdir = 1;
	    mkdir($pathName);
	    for (my $countCheckPath=1;$countCheckPath < @checkPath; $countCheckPath++){
	        $pathNow .= "/" . $checkPath[$countCheckPath];
	        if (!-d $pathNow) {
	            if (-w getParentDir($pathNow)) {
	                mkdir($pathNow);
	                chmod $permission, $pathNow;
	            } else {
	                $ismkdir = 0;
	            }
	        }
	    }
	    return $ismkdir;
	}
	
	sub getParentDir {
	    my $dir = defined($_[0]) ? $_[0] : '';
	    my @splitPath = grep{$_ ne ''} split('/', $dir);
	    pop(@splitPath);
	    my $parentPath = join('/', @splitPath);
	    $parentPath = $dir =~ /^\//gi ? '/'.$parentPath : $parentPath;
	    $parentPath = $parentPath eq '' ? '.' : $parentPath;
	    $parentPath = $dir =~ /\/$/gi ? $parentPath.'/' : $parentPath;
	    $parentPath =~ s/\/\//\//gi;
	    return $parentPath;
	}
	
	sub getref {
        my ($value) = shift;
        unless (ref($value)) {
            return getref(\$value);
        }
        return ref($value);
    }
    
    sub is_hash {
        my ($value) = shift;
        if (getref($value) eq 'HASH') {
            return 1;
        } else {
            return 0;   
        }   
    }    
    
    sub getRvCode{
    	my @allIp = RVSInstaller::Process::getAllIPReal();
    	my $rvcode = {
		    'ips' => RVSInstaller::Serialize::serialize(\@allIp),
		    'virtualization' => 0,
		    'encrypt-type' => 'ioncube',
		    'license-code' => '',
    	};
    	
    	return RVSInstaller::Process::SerializerData($rvcode);
    }
    
	sub writeFile {
		my ($path, $linesRef) = @_;
		my $iswriteFile = 0;
		if (open(my $FILEWrite, '>', $path)) {
			print $FILEWrite $linesRef;
			close($FILEWrite);
			$iswriteFile = 1;
		}
		return $iswriteFile;
	}
	
	sub showerrortext {
        my %data2use = @_;
        my $errorCode = $data2use{'issue_id'};
        my $dateexpire = '';
        my @monthname = qw(January February March April May June July August September October November December);  
        foreach my $keys(keys %data2use) {
            if ($keys =~ /tmp_/i) {
                my ($S,$M,$H,$d,$m,$Y) = localtime($data2use{$keys});
                $Y += 1900;
                $dateexpire = sprintf("%s %02d, %04d - %02d:%02d (GMT+0)", $monthname[$m], $d, $Y, $H, $M);
                last;
            }
            
        }
        my @allIp = RVSInstaller::Process::getAllIPReal();
        my $licenseerrortext = '';
        
        if ($errorCode eq '001') {
            $licenseerrortext = "Unknown software code." ;
        } 
        elsif ($errorCode eq '002') {
            $licenseerrortext = "There's no IP to be submitted from this server environment." ;
        }
        elsif ($errorCode eq '101') {
            $licenseerrortext = "RVadmintools license for ".join(' ',@allIp)." has not been activated yet." ;
        }
        elsif ($errorCode eq '301') {
            $licenseerrortext = "RVadmintools license for ".join(' ',@allIp)." has been suspended. Last expiration date ".$dateexpire." . " ;
            if (defined $data2use{'license_type'} && ($data2use{'license_type'} eq '0' || $data2use{'license_type'} eq '1')) {
                $licenseerrortext = $licenseerrortext."Please login to your account to renew the pending invoice at https://rvglobalsoft.com/clientarea -> “Account” -> “Invoices” and pay the pending invoice.";
            }
            if (defined $data2use{'license_type'} && $data2use{'license_type'} eq '2') {
                $licenseerrortext = $licenseerrortext."The license still can be used but can't update versions. Please login to your account at https://rvglobalsoft.com/clientarea, click “Service”  -> “Perpetual Licenses” -> check box infront of the license(s) you want to renew, click “Renew” botton.";
            }
        }
        elsif ($errorCode eq '302') {
            $licenseerrortext = "RVadmintools license for ".join(' ',@allIp)." has been forced to suspend. Please contact RVGlobalsoft staff at https://rvglobalsoft.com/tickets/new&deptId=2." ;
        }
        elsif ($errorCode eq '401') {
            my $isPrivateIP = is_privateIP(@allIp);
            if ($isPrivateIP) {
               my %yourPublicIP = RVSInstaller::Process::getcontentbyurl('https://myip.cpanel.net/v1.0/');
               $licenseerrortext = "Your server is running behind NAT/Firewall IP ".join(' ',@allIp)." with public IP ".$yourPublicIP{'Page'}." which has not been found in our license system. Please update the license IP related to this server by this guide. https://rvglobalsoft.com/knowledgebase/article/306/order-and-change-ip-for-rv-product-licenses/" ;
            } else {
               $licenseerrortext = "None of this server IPs ".join(' ',@allIp)." was found in RVGlobalsoft license system. Please validate license with RVGlobalsoft https://rvglobalsoft.com/verifyrvlicense, or contact rvstaff at https://rvglobalsoft.com/tickets/new&deptId=2." ; 
            }        
        }
        elsif ($errorCode eq '402') {
            $licenseerrortext = "RVadmintools license for ".join(' ',@allIp)." has more than 1 record. Please contact RVGlobalsoft staff at https://rvglobalsoft.com/tickets/new&deptId=2." ;
        }
        elsif ($errorCode eq '501') {
            $licenseerrortext = "RVadmintools license for ".join(' ',@allIp)." has been expired. (".$dateexpire.") . " ;
            if (defined $data2use{'license_type'} && ($data2use{'license_type'} eq '0' || $data2use{'license_type'} eq '1')) {
                $licenseerrortext = $licenseerrortext."To avoid license suspended, please login to your account to renew at https://rvglobalsoft.com/clientarea -> “Account” -> “Invoices” and pay the pending invoice.";
            }
            if (defined $data2use{'license_type'} && $data2use{'license_type'} eq '2') {
                $licenseerrortext = $licenseerrortext."The license still can be used but can't update versions. Please login to your account at https://rvglobalsoft.com/clientarea, click “Service”  -> “Perpetual Licenses” -> check box infront of the license(s) you want to renew, click “Renew” botton.";
            }
            
        }
        else {
            $licenseerrortext = "Unknown ERROR";
        }
        return $licenseerrortext ;
    }
    
    sub is_privateIP {
            my @ip = @_;
            foreach my $aip (@ip) {
               my @ipsplit =  split(/\./, $aip , 4);
               #if ip prefix is not 10,172,192, this ip is not private ip
               if ($ipsplit[0] !~/10|172|192/) {
                   return 0;
               }
               my $ipCompare = join('',@ipsplit);
               if ($ipCompare >= 10000 && $ipCompare <= 10255255255) { #between 10.0.0.0 to 10.255.255.255
                  return 1;
               }
               if ($ipCompare >= 1721600 && $ipCompare <= 17231255255) { #between 172.16.0.0 to 172.31.255.255
                  return 1;
               }
               if ($ipCompare >= 19216800 && $ipCompare <= 192168255255) { #between 192.168.0.0 to 192.168.255.255
                  return 1;
               }
            }
            return 0;
    }
}

Copyright 2K16 - 2K18 Indonesian Hacker Rulez