<?php
/* Reminder: always indent with 4 spaces (no tabs). */
// +---------------------------------------------------------------------------+
// WebSite: http://www.rvglobalsoft.com
// Unauthorized copying is strictly forbidden and may result in severe legal action.
// Copyright (c) 2006 RV Global Soft Co.,Ltd. All rights reserved.
//
// =====YOU MUST KEEP THIS COPYRIGHTS NOTICE INTACT AND CAN NOT BE REMOVE =======
// Copyright (c) 2006 RV Global Soft Co.,Ltd. All rights reserved.
// This Agreement is a legal contract, which specifies the terms of the license
// and warranty limitation between you and RV Global Soft Co.,Ltd. and RV Site Builder.
// You should carefully read the following terms and conditions before
// installing or using this software. Unless you have a different license
// agreement obtained from RV Global Soft Co.,Ltd., installation or use of this software
// indicates your acceptance of the license and warranty limitation terms
// contained in this Agreement. If you do not agree to the terms of this
// Agreement, promptly delete and destroy all copies of the Software.
//
// ===== Grant of License =======
// The Software may only be installed and used on a single host machine.
//
// ===== Disclaimer of Warranty =======
// THIS SOFTWARE AND ACCOMPANYING DOCUMENTATION ARE PROVIDED "AS IS" AND
// WITHOUT WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR ANY OTHER
// WARRANTIES WHETHER EXPRESSED OR IMPLIED. BECAUSE OF THE VARIOUS HARDWARE
// AND SOFTWARE ENVIRONMENTS INTO WHICH RV SITE BUILDER MAY BE USED, NO WARRANTY OF
// FITNESS FOR A PARTICULAR PURPOSE IS OFFERED. THE USER MUST ASSUME THE
// ENTIRE RISK OF USING THIS PROGRAM. ANY LIABILITY OF RV GLOBAL SOFT CO.,LTD. WILL BE
// LIMITED EXCLUSIVELY TO PRODUCT REPLACEMENT OR REFUND OF PURCHASE PRICE.
// IN NO CASE SHALL RV GLOBAL SOFT CO.,LTD. BE LIABLE FOR ANY INCIDENTAL, SPECIAL OR
// CONSEQUENTIAL DAMAGES OR LOSS, INCLUDING, WITHOUT LIMITATION, LOST PROFITS
// OR THE INABILITY TO USE EQUIPMENT OR ACCESS DATA, WHETHER SUCH DAMAGES ARE
// BASED UPON A BREACH OF EXPRESS OR IMPLIED WARRANTIES, BREACH OF CONTRACT,
// NEGLIGENCE, STRICT TORT, OR ANY OTHER LEGAL THEORY. THIS IS TRUE EVEN IF
// RV GLOBAL SOFT CO.,LTD. IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO CASE WILL
// RV GLOBAL SOFT CO.,LTD.'S LIABILITY EXCEED THE AMOUNT OF THE LICENSE FEE ACTUALLY PAID
// BY LICENSEE TO RV GLOBAL SOFT CO.,LTD.
// +---------------------------------------------------------------------------+
// $Id$
// +---------------------------------------------------------------------------+
if (class_exists('System') === false) {
require_once 'System.php';
}
/**
* RvSiteBuilder system libary
*
* @package RvsLibs
* @author Pairote Manunphol <pairote@rvglobalsoft.com>
* @version $Revision$
* @since PHP 5.1
*/
if (class_exists('RvsLibs_System') === false) {
class RvsLibs_System
{
/**
* Attempts to remove the directory or file specified by pathname.
*
* @param unknown_type $args
* exp. rm(array('-f', $filePath)) or
* rm(array('-rf', $dirPath))
* @return Returns TRUE on success or FALSE on failure.
*/
public static function rm($args)
{
return System::rm($args);
}
/**
* Attempts to create the directory specified by pathname.
* ไม่ได้ใช้ ใน System::mkDir() ของ seagull แล้ว
*
* @param Array $args
* exp. mkDir(array($dirPath)) or
* mkDir(array('-p', $dirPath)) or
* mkDir(array('-m', 0755, $dirPath)) or
* mkDir(array('-p', '-m', 0755, $dirPath))
* @return Returns TRUE on success or FALSE on failure.
*/
public static function mkDir($args)
{
$opts = System::_parseArgs($args, 'pm:');
if (SGL::isError($opts)) {
return System::raiseError($opts);
} elseif (is_array($args) === false) {
SGL::logMessage("Require agument is array", PEAR_LOG_ERR);
return false;
}
$mode = 0755; // default mode
foreach ($opts[0] as $opt) {
if ($opt[0] == 'p') {
$create_parents = true;
} elseif ($opt[0] == 'm') {
$res = RvsLibs_System::_checkMode($opt[1]);
if (SGL::isError($res) === true) {
return $res;
}
// if the mode is clearly an octal number (starts with 0)
// convert it to decimal
if (strlen($opt[1]) && $opt[1]{0} == '0') {
$opt[1] = octdec($opt[1]);
} else {
// convert to int
$opt[1] += 0;
}
$mode = $opt[1];
}
}
if (isset($create_parents)) {
foreach ($opts[1] as $dir) {
$dirstack = array();
while ((!file_exists($dir) || !is_dir($dir)) &&
$dir != DIRECTORY_SEPARATOR) {
array_unshift($dirstack, $dir);
$dir = dirname($dir);
}
while ($newdir = array_shift($dirstack)) {
if (!is_writeable(dirname($newdir))) {
return SGL::raiseError(
'cannot create directory. current directory is not permitted.' . $newdir
);
}
$resMkdir = @mkdir($newdir, $mode);
if (!$resMkdir) {
return SGL::raiseError(
'cannot create directory'
);
}
$resChmod = @chmod($newdir, $mode);
//$resChmod = RvsLibs_System::chmod($newdir, $mode);
if (SGL::isError($resChmod)) {
return $resChmod;
}
}
}
} else {
foreach($opts[1] as $dir) {
if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
return SGL::raiseError(
'cannot create directory'
);
} else {
$resChmod = @chmod($newdir, $mode);
//$resChmod = RvsLibs_System::chmod($newdir, $mode);
if (SGL::isError($resChmod)) {
return $resChmod;
}
}
}
}
return true;
}
/**
* Deletes filename . Similar to the Unix C unlink() function.
*
* @param String $filename
* @return Returns TRUE on success or FALSE on failure.
*/
public static function unlink($filename)
{
///@TODO : Under Windows System and Apache, denied access to file is an usual error to unlink file.
///@TODO : To delete file you must to change file's owern.
if (is_file($filename) === true || is_link($filename) === true) {
if (@unlink($filename) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'cannot delete file or link %FILE'
, 'vprintf'
, array('FILE' => $filename)
)
);
} else {
return true;
}
} else {
return SGL::raiseError(
RvsLibs_String::translate(
'%FILE is not file or link'
, 'vprintf'
, array('FILE' => $filename)
)
);
}
}
/**
* Attempts to change the mode of the specified file to that given in mode .
* @author Witoon Jansri <witoon.j@rvglobalsoft.com>
*
* @param String $fileName
* @param String $mode
* @param Boolean $recursive
* @return Returns TRUE on success or raise error on failure.
*
* @example
* chmod($a, '0755') // change mode $a
*
* chmod($a, '0755', true) // change mode $a and
* change mode any files and folder in path $a
*/
public static function chmod($fileName, $mode, $recursive = false)
{
//Check $mode valiable
$res = RvsLibs_System::_checkMode($mode);
if (SGL::isError($res) === true) {
return $res;
}
// if the mode is clearly an octal number (starts with 0)
// convert it to decimal
if (strlen($mode) && $mode{0} == '0') {
$mode = octdec($mode);
} else {
// convert to int
$mode += 0;
}
//Check file or directory exist
if (file_exists($fileName) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'This file or directory %PATH is not exist'
, 'vprintf'
, array('PATH' => $fileName)
)
);
}
//Check function exist
if (RvsLibs_System::function_exists('chmod') === false) {
return SGL::raiseError(
RvsLibs_String::translate('Function chmod is undefine')
);
}
if ($recursive === true) {
return RvsLibs_System::_rChmod($fileName, $mode);
}
if (is_link($fileName) === true) {
return true;
} elseif (@chmod($fileName, $mode)) {
return true;
} else {
return SGL::raiseError(
RvsLibs_String::translate(
'Cannot chmod %PATH, operation not permitted.'
, 'vprintf'
, array('PATH' => $fileName)
)
);
}
}
/**
* Attempts to change the mode of the all files/path specified by filename to that given in mode.
*
*/
public static function _rChmod($fileName, $mode)
{
if (is_link($fileName) === true) {
return true;
} elseif (@chmod($fileName, $mode) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Cannot chmod %PATH, operation not permitted.'
, 'vprintf'
, array('PATH' => $fileName)
)
);
}
if (is_dir($fileName) ) {
$folder = opendir($fileName);
while ($file = readdir($folder)) {
if ($file == '.' || $file == '..' ) {
continue;
}
$supPath = RvsLibs_File::buildPath(array($fileName, $file));
$res = RvsLibs_System::chmod($supPath, $mode);
if (is_link($supPath) === true) {
return true;
} elseif (@chmod($supPath, $mode) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Cannot chmod %PATH, operation not permitted.'
, 'vprintf'
, array('PATH' => $supPath)
)
);
}
if (is_dir($supPath)) {
RvsLibs_System::_rChmod($supPath, $mode);
}
}
closedir($folder);
}
return true;
}
public static function chown()
{
}
/**
* Execute an external program
*
* @param String|Array $command
* @param Array $output
* @param Int $returnVal (0 onsuccess or PEAR ERROR on failure)
*
* @return If the return_var argument is present along with the output argument
* , then the return status of the executed command will be written to this variable.
* And return PEAR Error if connot usage all execute functions.
*
* Meaning return error code
* http://www.faqs.org/docs/abs/HTML/exitcodes.html#EXITCODESREF
*/
public static function exec($command, &$output = array(), &$returnVal = 0)
{
$command = (is_array($command) === true)
? join(' ', $command)
: $command;
if (RvsLibs_System::function_exists('exec') === true) {
SGL::logMessage(' cmd: exec', PEAR_LOG_DEBUG);
exec($command, $output);
} elseif (RvsLibs_System::function_exists('system') === true) {
SGL::logMessage(' cmd: system', PEAR_LOG_DEBUG);
ob_start();
system($command, $returnVal);
$output = ob_get_contents();
ob_end_clean();
} elseif (RvsLibs_System::function_exists('passthru') === true) {
SGL::logMessage(' cmd: passthru', PEAR_LOG_DEBUG);
ob_start();
passthru($command, $returnVal);
$output = ob_get_contents();
ob_end_clean();
} /*elseif (RvsLibs_System::function_exists('shell_exec') === true) {
SGL::logMessage(' cmd: shell_exec', PEAR_LOG_DEBUG);
/// ไม่สามารถ detech error ได้ จาก command นี้
$output = shell_exec($command);
}*/ else {
return SGL::raiseError(
RvsLibs_String::translate(
'Function %FUNCTION is undefine'
, 'vprintf'
, array('FUNCTION' => 'exec')
)
);
}
if (is_object($returnVal) === false) {
/// $returnVal === 0 success
/// $returnVal = error code ต้องหาความหมายของ error error code แต่ละตัว
/// $returnVal 1 หรือ 127
SGL::logMessage(' returnVal:' . $returnVal, PEAR_LOG_DEBUG);
if ($returnVal != 0) {
return SGL::raiseError(
RvsLibs_String::translate(
'Execut command %COMMAND failure. error code : %ERRORCODE.'
, 'vprintf'
, array(
'COMMAND' => $command,
'ERRORCODE' => $returnVal,
)
)
);
}
}
if (is_array($output) === false) {
$output = RvsLibs_System::_retiveOutputForExecFunc($output);
}
}
/**
* @access private
* Enter description here...
*
* @param string $strVal
* @return array
*/
public static function _retiveOutputForExecFunc($strVal) {
$aval = array();
$aval = explode("\n", $strVal);
if ($aval[count($aval)-1] == '') {
unset($aval[count($aval) - 1]);
}
return $aval;
}
/**
* list directory contents
*
* Usage:
* 1) $aList = RvsLibs_System::ls('/home');
* 2) $aList = RvsLibs_System::ls(array('-a', '-R', '/home'));
* The -a option will do not ignore entries starting with .
* The -R option will list subdirectories recursively
* The -C option will auto-ignore files in the same way CVS/SVN does
* 3) $aList = RvsLibs_System::ls(array('-a', '-R', '/home'), array('dirnameToignore'));
* @param string $args the name of the director(y|ies) to create
*
* @return array
*
* ex: array(
* 'dirs' => array(...),
* 'files' => array(...),
* 'links' => array(...),
* )
*/
public static function ls($args, $aDirIgnore = array())
{
$opts = System::_parseArgs($args, 'aRC');
if (SGL::isError($opts)) {
return $opts;
}
$recursive = false;
$showHidden = false;
$cvsExclude = false;
foreach ($opts[0] as $opt) {
switch ($opt[0]) {
case 'R':
$recursive = true; break;
case 'a':
$showHidden = true; break;
case 'C':
$cvsExclude = true;
}
}
return RvsLibs_System::_multipleToStruct($opts[1], $recursive, $showHidden, $cvsExclude, $aDirIgnore);
}
public static function _multipleToStruct($files, $recursive = false, $showHidden = false, $cvsExclude = false, $aDirIgnore = array())
{
$struct = array('dirs' => array(), 'files' => array(), 'links' => array());
settype($files, 'array');
foreach ($files as $file) {
if (is_dir($file) && !is_link($file)) {
$tmp = RvsLibs_System::_dirToStruct($file, $recursive, $showHidden, $cvsExclude, 0, 0, $aDirIgnore);
$struct = array_merge_recursive($tmp, $struct);
} elseif (is_link($file) === true) {
$struct['links'][] = $file;
} else {
$struct['files'][] = $file;
}
}
return $struct;
}
public static function _dirToStruct($sPath, $recursive = false, $showHidden = false, $cvsExclude = false, $maxinst, $aktinst = 0, $aDirIgnore = array())
{
$struct = array('dirs' => array(), 'files' => array(), 'links' => array());
if (($dir = @opendir($sPath)) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Could not open dir %FORDER'
, 'vprintf'
, $sPath
)
); // XXX could not open error
}
$struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
$list = array();
while (false !== ($file = readdir($dir))) {
if ($file === '.' || $file === '..' || (count($aDirIgnore) && in_array($file, $aDirIgnore)) ) {
/// Continue if file is dot(.) or dot dot(..) ::BooM
continue;
} elseif ($showHidden === false && RvsLibs_String::dbeSubstr($file, 0, 1) === '.') {
/// Continue if set option show hidden is fasle and file name is start with dot(.) ::BooM
continue;
} elseif ($cvsExclude === true && is_dir($sPath . DIRECTORY_SEPARATOR . $file)
&& ($file === '.svn' || $file === '.cvs')) {
/// Continue if set option auto-ignore files in the same way CVS/SVN is true
/// and it is a folder, and folder name is start with .svn or .cvs ::BooM
continue;
} else {
$list[] = $file;
}
}
closedir($dir);
sort($list);
foreach ($list as $val) {
$path = $sPath . DIRECTORY_SEPARATOR . $val;
if (is_dir($path) && !is_link($path)) {
if ($recursive === true) {
$tmp = RvsLibs_System::_dirToStruct($path, $recursive, $showHidden, $cvsExclude, $maxinst, $aktinst+1, $aDirIgnore);
$struct = array_merge_recursive($tmp, $struct);
} else {
$struct['dirs'][] = realpath($path);
}
} elseif (is_link($path) === true) {
$struct['links'][] = $path;
} else {
$struct['files'][] = $path;
}
}
return $struct;
}
/// Validate
/**
* check correct permission string
*
* @param String $mode
* @return mix pear error or TRUE on success.
*/
public static function _checkMode($mode)
{
if (is_string($mode)) {
//fixed PHPMD scan 07/07/2554
if ( !preg_match('/^0/', $mode)) {
// premission incorrect
return SGL::raiseError(
RvsLibs_String::translate('The first digit of permission mode must be zero(0) only.')
);
}
} else {
$mode = '0' . decoct($mode);
}
if ( !preg_match('/[0-7]{4}/', $mode) ) {
return SGL::raiseError(
RvsLibs_String::translate('Enter number format 0-7')
);
}
$srtLength = RvsLibs_String::strlen($mode);
if ($srtLength != 4) {
return SGL::raiseError(
RvsLibs_String::translate('Enter 4 digit')
);
}
return true;
}
/**
* copy files and directories
*
* Usage:
* 1) $ok = RvsLibs_System::copy(array('/home/a.txt', '/home/b.txt'));
* 2) $ok = RvsLibs_System::copy(array('-f', '-R', '/home/a', '/home/b'));
*
* The option:
* -R copy directories recursively
* -f if an existing destination file cannot be opened, remove it and try again
* @param unknown_type $args
* @return unknown
*/
public static function copy($args)
{
$opts = System::_parseArgs($args, 'fR');
if (SGL::isError($opts)) {
return $opts;
}
$sPath = (isset($opts[1][0]) === true) ? $opts[1][0] : null;
$dPath = (isset($opts[1][1]) === true) ? $opts[1][1] : null;
if (is_link($sPath) === true || is_file($sPath) === true) {
if (@copy($sPath, $dPath) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Failed to copy %FILE to %DFILE.'
, 'vprintf'
, array('FILE' => $sPath, 'DFILE' => $dPath)
)
);
}
return true;
}
if (is_null($sPath) === true) {
return SGL::raiseError(
RvsLibs_String::translate(
'Wrong parameter count for copy'
, 'vprintf'
, array('FILE' => $sPath)
)
);
} elseif (file_exists($sPath) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Could not found %FORDER'
, 'vprintf'
, array('FORDER' => $sPath)
)
);
}
if (is_null($dPath) === true) {
return SGL::raiseError(
RvsLibs_String::translate(
'missing destination file operand after'
, 'vprintf'
, array('FILE' => $dPath)
)
);
}
$lsOpts = '-a';
$fOpts = false;
foreach ($opts[0] as $opt) {
switch ($opt[0]) {
case 'R':
$lsOpts .= ' -R'; break;
case 'f':
$fOpts = true; break;
}
}
$aList = array('dirs' => array(), 'files' => array(), 'links' => array());
if (is_dir($sPath) === true) {
$lsCommand = (is_null($lsOpts) === true) ? "{$sPath}" :"{$lsOpts} {$sPath}";
$aList = RvsLibs_System::ls($lsCommand);
} else {
$aList['files'][] = $opts[1];
}
$aRes = array('dirs' => array(), 'files' => array(), 'links' => array());
if (isset($aList['dirs']) && count($aList['dirs']) > 0) {
foreach ($aList['dirs'] as $k => $v) {
$makeDir = str_replace($sPath, $dPath, $v);
//แก้ปัญหากับ ต้นทางเป็น symlink
if ($makeDir == $v) {
$sPath2 = realpath($sPath);
$makeDir = str_replace($sPath2, $dPath, $v);
}
$aDStat = @stat($sPath);
//0644 แล้วมัน copy ไมได้เลยเปลี่ยนเป็น 0755
$dirMode = (!$aDStat)
? 0755
: sprintf("0%o", 0755 & $aDStat['mode']);
if (is_dir($makeDir) === false && is_link($makeDir) === false) {
$ok = RvsLibs_System::mkDir(array('-p', '-m', $dirMode, $makeDir));
if (SGL::isError($ok)) {
return $ok;
}
$aRes['dirs'][] = $makeDir;
} else if (is_link($makeDir) === false) {
}
}
}
if (isset($aList['files']) && count($aList['files']) > 0) {
foreach ($aList['files'] as $k => $v) {
$dFile = str_replace($sPath, $dPath, $v);
//แก้ปัญหากับ ต้นทางเป็น symlink
if ($v == $dFile) {
$sPath2 = realpath($sPath);
$dFile = str_replace($sPath2, $dPath, $v);
}
if (is_file($dFile) === true && $fOpts === false) {
continue;
} else if (is_file($dFile) === true && $fOpts === true) {
RvsLibs_System::rm(array('-f', $dFile));
}
if (@copy($v, $dFile) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Failed to copy %FILE to %DFILE.'
, 'vprintf'
, array('FILE' => $v, 'DFILE' => $dFile)
)
);
}
$aRes['files'][] = $dFile;
/*
$aStat = @stat($v);
if (!$aStat) {
SGL::logMessage('Not found stat.', PEAR_LOG_DEBUG);
continue;
} else {
$mode = sprintf("0%o", 0777 & $aStat['mode']);
SGL::logMessage('Chmod file ' . $dFile . ' to ' . $mode, PEAR_LOG_DEBUG);
RvsLibs_System::chmodr($dFile, $mode);
}
*/
}
}
return $aRes;
}
/**
* link files to file
*
* Usage:
* 1) $ok = RvsLibs_System::linkFiles('/home/b.txt', 'b');
*
*
* The option:
* -n copy directories recursively
* -s make symbolic links instead of hard links
* -f remove existing destination files
* -p copy if file is php
*
* @param unknown_type $args
* @return unknown
*/
public static function ln($args)
{
///TODO :: เหลือ test
$opts = System::_parseArgs($args, 'nsfp');
if (SGL::isError($opts)) {
return $opts;
}
$sPath = (isset($opts[1][0]) === true) ? $opts[1][0] : null;
$dPath = (isset($opts[1][1]) === true) ? $opts[1][1] : null;
$username = (isset($opts[1][2]) === true) ? $opts[1][2] : null;
$nOpts = false;
$sOpts = false;
$fOpts = false;
$pOpts = false;
foreach ($opts[0] as $opt) {
switch ($opt[0]) {
case 'n':
$nOpts = true; break;
case 's':
$sOpts = true; break;
case 'f':
$fOpts = true; break;
case 'p':
$pOpts = true; break;
break;
}
}
if (file_exists($dPath) == true && $fOpts) {
RvsLibs_System::rm(array('-rf',$dPath));
}
if (is_null($sPath) === true) {
return SGL::raiseError(
RvsLibs_String::translate(
'missing destination file operand after'
, 'vprintf'
, $sPath
)
);
}
/// If soruce path is dir
if ($nOpts === false) {
if (@symlink($sPath, $dPath) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'cannot create link %PATH to %LINK'
, 'vprintf'
, array('PATH' => $sPath, 'LINK' => $dPath)
)
);
}
return true;
} else {
$aList = array('dirs' => array(), 'files' => array(), 'links' => array());
$aList = RvsLibs_System::ls(array('-RC', $sPath));
$aRes = array('dirs' => array(), 'files' => array(), 'links' => array());
if (isset($aList['dirs']) && count($aList['dirs']) > 0) {
foreach ($aList['dirs'] as $k => $v) {
if (!preg_match("/\/$/",$dPath, $aMatch)) {
$dPath .= '/';
}
if (!preg_match("/\/$/",$sPath, $aMatch)) {
$sPath .= '/';
}
$makeDir = RvsLibs_String::str_replace($sPath, $dPath, $v);
$aDStat = @stat($v);
//fixed PHPMD scan 07/07/2544
//$dirMode = (!$aDStat) ? 0644 : sprintf("0%o", 0644 & $aDStat['mode']);
if (file_exists($makeDir) === false) {
$res = RvsLibs_System::mkDir(array('-p', '-m', 0755, $makeDir));
//$ok = RvsLibs_System::mkDir(array('-p', '-m', $dirMode, $makeDir));
$aRes['dirs'][] = $makeDir;
}
}
}
if (isset($aList['files']) && count($aList['files']) > 0) {
foreach ($aList['files'] as $fk => $fv) {
$dFile = str_replace($sPath, $dPath, $fv);
/// ยังไม่สมบูรณ์ ต้องปรับในส่วนที่ตัดนามสกุลไฟล์ออก:: Witoon
//$dFile = preg_replace('/(.+)\..*$/', '$1', $dFile);
$extension = RvsLibs_File::getFileExtension($fv);
if ($extension == 'php') {
//SGL::logMessage("CDF: dFile: $dFile fv:$fv ", PEAR_LOG_DEBUG);
$res = RvsLibs_System::copy(array('-R', $fv, $dFile));
RvsLibs_System::chmod($dFile, '0755');
if (SGL::isError($res) === true) {
return SGL::raiseError(
RvsLibs_String::translate(
'Cannot copy %source to %target'
, 'vprintf'
, array('source' => $fv, 'target' => $dFile)
)
);
}
} elseif (@symlink(realpath($fv), $dFile) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Failed to link %FILE to %DFILE.'
, 'vprintf'
, array('FILE' => $fv, 'DFILE' => $dFile)
)
);
}
$aRes['files'][] = $dFile;
}
}
if (isset($aList['links']) && count($aList['links']) > 0) {
foreach ($aList['links'] as $lk => $lv) {
$dLink = str_replace($sPath, $dPath, $lv);
if (@symlink(realpath($lv), $dLink) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Failed to link %LINK to %TARGET.'
, 'vprintf'
, array('LINK' => $lv, 'TARGET' => $sPath)
)
);
}
$aRes['links'][] = $dLink;
}
}
}
return true;
}
/**
* Enter description here...
*
* Usage: *
* 1) $aList = RvsLibs_System::ls(array('-a', '-R', '/home/a', '/home/b'));
* The -a option will do not ignore entries starting with .
* The -R option will list subdirectories recursively
* The -C option will auto-ignore files in the same way CVS/SVN does
* The -d option will auto-delete files.
* @param unknown_type $args
* @return unknown
*/
public static function rsync()
{
$opts = System::_parseArgs($args, 'aRCd');
if (SGL::isError($opts)) {
return $opts;
}
}
public static function mv($sPath, $dPath)
{
if (is_writable($sPath) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'%FILE is writable.'
, 'vprintf'
, array('FILE' => $sPath)
)
);
}
if (is_writable($dPath)) {
return SGL::raiseError(
RvsLibs_String::translate(
'%FILE is writable.'
, 'vprintf'
, array('FILE' => $dPath)
)
);
}
if (is_file($sPath) === false && is_dir($sPath) === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Source path %FILE is not file or directory.'
, 'vprintf'
, array('FILE' => $sPath)
)
);
}
if (RvsLibs_System::function_exists('exec')) {
$command = 'mv ' . $sPath . ' ' . $dPath;
exec($command, $ouput, $returnVal);
if($returnVal === false) {
return SGL::raiseError(
RvsLibs_String::translate(
'Failed to move %FILE to %DFILE.'
, 'vprintf'
, array('FILE' => $sPath, 'DFILE' => $dPath)
)
);
} else {
return $returnVal;
}
} else {
//TODO :: copy
//rm
}
}
/**
* Attempts to rename oldname to newname .
* @author Witoon Jansri <witoon.j@rvglobalsoft.com>
*
* @param String $oldname
* @param String $newname
* @param Resource $context
* Context support was added with PHP 5.0.0. For a description of contexts,
* refer to Stream Functions.
* @return Returns TRUE on success or raise error on failure.
*/
public static function rename($oldname, $newname, $context = null)
{
if (file_exists($oldname) === false) {
return SGL::raiseError(
RvsLibs_String::translate('The file or directory %FILE is not exist.'
, 'vprintf'
, array('FILE' => $oldname))
);
}
if (is_writable($oldname) === false) {
return SGL::raiseError(
RvsLibs_String::translate('The file or directory %FILE is not writable.'
, 'vprintf'
, array('FILE' => $oldname))
);
}
if (RvsLibs_System::function_exists('rename') === true) {
return is_null($context) === true
? rename($oldname, $newname)
: rename($oldname, $newname, $context);
} else {
//TODO:: if function rename not exist.use copy and unlink function
$resCopy = RvsLibs_System::copy(array($oldname, $newname));
if (SGL::isError($resCopy) === true) {
return $resCopy;
}
RvsLibs_System::unlink($oldname);
return true;
}
}
/**
* use security command...
*
* @param array $args
* optin -p paramitor for makeprojectsymlink command,
* -m paramitor server mode defaut CPMODE,
* example secureCommand('makeuserdownloadpath')),
* secureCommand('makeprojectsymlink', array('project-id' => '234fgfjsg255iffggfddd') )),
* @return mix PEAR error or TRUE on success,
*/
//fixed PHPMD scan 07/07/2554
public static function secureCommand($secureCmd, $args = array())
{
if (count($args) > 0) {
foreach ($args as $key => $val) {
switch ($key) {
case 'project-id':
$projectId = $val;
break;
case 'lic-file':
$licFile = $val;
break;
case 'lic-targer':
$licTarger = $val;
break;
case 'templateitemfolder':
$templateitemf = $val;
break;
case 'source_path':
$source_path = $val;
break;
case 'dest_path':
$dest_path = $val;
break;
}
}
}
$aAllowCmds = array('makeuserdatapath', 'makeprojectsymlink', 'deleteprojectsymlink', 'movelicense', 'deletelicense',
'downloadmd5template' , 'downloadtemplate', 'copytemplate', 'copyrvsecure'
);
if (in_array($secureCmd , $aAllowCmds) === false) {
return SGL::raiseError(
RvsLibs_String::translate('The secure command "%CMD" ISNOT allow.'
, 'vprintf'
, array('CMD' => $secureCmd)
)
);
}
/* modify CpHandle by nipaporn*/
$oCp = CpHandle::factory();
if(SGL::isError($oCp) === true) {
SGL_Error::pop();
return false;
}
$secureScript = $oCp->getRvBinPath();
if (file_exists($secureScript) === false || is_executable($secureScript) === false) {
return SGL::raiseError(
RvsLibs_String::translate('The file rvswrapper NOT exist or NOT executable.')
);
}
$secureId = RvsLibs_String::genUniqueId();
$sessionData = $_SESSION;
switch ($secureCmd) {
case 'makeuserdatapath':
$sessionData['RVS_SECURE_COMMAND'] = 'makeuserdatapath';
$sessionData['RVSITEBUILDER_USERDATA_PATH'] = RvsLibs_File::buildPath(
array(SGL_USERDATA_PATH)
);
break;
case 'makeprojectsymlink':
if (empty($projectId) === true) {
return SGL::raiseError(
RvsLibs_String::translate(
'syntag error for makeprojectsymlink command.'
)
);
}
$sessionData['RVS_SECURE_COMMAND'] = 'makeprojectsymlink';
$sessionData['RVSITEBUILDER_USER_PROJECT_PATH'] = RvsLibs_File::buildPath(
array( REAL_PROJECT_PATH , $projectId)
);
$sessionData{'RVSITEBUILDER_PROJECT_PATH'} = RvsLibs_File::buildPath(
array( PROJECT_PATH , $projectId)
);
break;
case 'deleteprojectsymlink':
if (empty($projectId) === true) {
return SGL::raiseError(
RvsLibs_String::translate(
'syntag error for delprojectsymlink command.'
)
);
}
$sessionData['RVS_SECURE_COMMAND'] = 'deleteprojectsymlink';
$sessionData{'RVSITEBUILDER_PROJECT_PATH'} = RvsLibs_File::buildPath(
array( PROJECT_PATH , $projectId)
);
$sessionData['RVSITEBUILDER_USER_PROJECT_PATH'] = RvsLibs_File::buildPath(
array( REAL_PROJECT_PATH , $projectId)
);
break;
case 'movelicense':
$sessionData['RVS_SECURE_COMMAND'] = 'movelicense';
$sessionData['RVS_LIC_File'] = $licFile;
$sessionData['RVS_LIC_TARGER'] = $licTarger;
break;
case 'deletelicense':
$sessionData['RVS_SECURE_COMMAND'] = 'deletelicense';
$sessionData['RVS_LIC_File'] = $licFile;
break;
case 'downloadmd5template':
$sessionData['RVS_SECURE_COMMAND'] = 'downloadmd5template';
break;
case 'downloadtemplate':
$sessionData['RVS_SECURE_COMMAND'] = 'downloadtemplate';
$sessionData['RVS_TEMPLATE_ITEM_FOLDER'] = $templateitemf;
break;
case 'copytemplate':
$sessionData['RVS_SECURE_COMMAND'] = 'copytemplate';
$sessionData['RVS_TEMPLATE_ITEM_FOLDER'] = $templateitemf;
$sessionData['RVS_TEMPLATE_SOURCE'] = USER_HOME_USERDATA_PATH . '/upload';
break;
case 'copyrvsecure':
$sessionData['RVS_SECURE_COMMAND'] = 'copyrvsecure';
$sessionData['RVS_SOURCE_PATH'] = $source_path;
$sessionData['RVS_DEST_PATH'] = $dest_path;
break;
default:
break;
}
$tmpPath = $oCp->getTmpPath();
if (is_dir($tmpPath) === false) {
RvsLibs_System::mkDir(array('-p', $tmpPath));
}
$tmpFile = RvsLibs_File::buildPath(array($tmpPath, 'rvsecurer_' . $secureId));
SGL::logMessage('rvdebug:command: ' . $secureCmd, PEAR_LOG_DEBUG);
SGL::logMessage('rvdebug:tmp file: ' . $tmpFile, PEAR_LOG_DEBUG);
if (file_exists($tmpFile) === true) {
RvsLibs_System::rm(array('-f',$tmpFile));
}
$hendle = RvsLibs_File::fopen($tmpFile, 'x+');
if (SGL::isError($hendle) === true) {
//// cannot write data to tmp file
return $hendle;
}
RvsLibs_File::fwrite($hendle, serialize($sessionData));
RvsLibs_File::fclose($hendle);
RvsLibs_System::chmod($tmpFile, '0660');
$returnVal = RvsLibs_System::exec(array($secureScript, $secureId, CPMODE, SGL_PATH));
RvsLibs_System::rm(array('-f', $tmpFile));
if (SGL::isError($returnVal) === true) {
return $returnVal;
}
return true;
}
public static function function_exists($functionName)
{
$oPhpSuhosin = phpSuhosin::singleton();
$sFunctionBacklist = (isset($oPhpSuhosin->func_blacklist)) ? $oPhpSuhosin->func_blacklist : '';
//$allowSym = @ini_get('suhosin.executor.allow_symlink');
/*TODO: validate เพิ่ม
* if($functionName == 'symlink' && $allowSym != '' && $allowSym == '0') {
return false;
}*/
//fixed PHPMD scan 07/07/2554
if(preg_match('/[,|,\s+]' . strtolower($functionName) . '[,|\s+,]/', strtolower($sFunctionBacklist))) {
return false;
} else {
return function_exists($functionName);
}
}
public static function runDetectPhpSuexecByRoot()
{
///Debug SGL::logMessage(null, PEAR_LOG_DEBUG);
/* modify CpHandle by nipaporn*/
$oCp = CpHandle::factory();
if(SGL::isError($oCp) === true) {
return $oCp;
/*
return SGL::raiseError(RvsLibs_String::translate('CpWaring %MESSAGE', 'vprintf', array('MESSAGE' => $oCp->getMessage())));
*/
}
$aAcctData = $oCp->listAllAcctsData();
if (SGL::isError($aAcctData) === true) {
return $aAcctData;
} else {
foreach ($aAcctData as $k => $aVal) {
$dns = (isset($aVal['domain'])) ? $aVal['domain'] : '';
if(RvsLibs_Config::skipDomainValidate($dns) == true) {
continue;
}
$user = (isset($aVal['user'])) ? $aVal['user'] : '';
$aUserInfo = posix_getpwnam($user);
$homeuser = $aUserInfo['dir'];
$docroot = $homeuser . '/public_html';
if (is_dir($docroot) && is_writable($docroot)) {
// Create Random Directory
$ranPath = 'rvphpinfo' . rand(100000,999999);
// write php ini
$res = MainComponent::writeRvphpDetect($user, $docroot, $ranPath,'phpsuexec');
// Read php_info
$site = $dns;
$request = '/' . $ranPath . '/_rvphpinfo.php';
//fixed PHPMD scan 07/07/2554
//$urlrequest = 'http://'. $site . $request;
//$site, $request, $port = 80, $authorizationl = null, $useSSL = false, $timeout = 30
$page2 = RvsLibs_Url::urlConnect($site, $request, 80, null, false, 30);
// Remove Random Directory
RvsLibs_System::unlink(RvsLibs_File::buildPath(array($docroot, $ranPath, '.htaccess')));
RvsLibs_System::unlink(RvsLibs_File::buildPath(array($docroot, $ranPath, '_rvphpinfo.php')));
// In some servesr there is error_log generated by web server
$path = RvsLibs_File::buildPath(array($docroot, $ranPath, 'error_log'));
$res = (file_exists($path)) ? RvsLibs_System::unlink($path) : '';
if (SGL::isError($res) === true) {
SGL_Error::pop();
}
if ($ranPath && is_dir($docroot . '/' . $ranPath)) {
RvsLibs_System::rm(array('-rf', $docroot . '/' . $ranPath));
}
if (empty($page2)) {
continue;
}
// match gd library
if (preg_match('/200 OK|true/i', $page2['data'], $aMatch)) {
if (preg_match('/true/', $page2['data'], $aMatch)) {
return 1;
}
return 0;
}
}
}
}
return 0;
}
public static function getCronTabPath()
{
if (file_exists('/usr/bin/crontab')) {
return '/usr/bin/crontab';
} elseif ( file_exists('/usr/local/bin/crontab')) {
return '/usr/local/bin/crontab';
} else {
$res = RvsLibs_System::exec('which crontab');
if (SGL::isError($res) === true) {
SGL_Error::pop();
return 0;
} else {
return $res;
}
}
}
public static function runDetectPhpSuexec($isRoot = FALSE)
{
// For root only
if ((RvsLibs_User::getUserStatus() == RVS_ROOT_USER_NAME ) || ($isRoot === TRUE)) {
return RvsLibs_System::runDetectPhpSuexecByRoot();
}
if (SGL_Output::isV6Session() == true) {
//v6 ไม่ต้องทำ
SGL::logMessage('is v6 return false only;', PEAR_LOG_DEBUG);
return false;
}
$oPublishReg = Publish_Registry::singleton();
$dns = RvsLibs_User::getUserDNS();
$dnsPublish = RvsLibs_User::getPublishUrl();
//action 1 = preview , 2 = publish
if ($oPublishReg->get('action') == 2) {
$dns = (isset($dnsPublish) && $dnsPublish)? $dnsPublish : $dns;
}
//SGL::logMessage('========> runDetectPhpSuexec == 000' . $dnsPublish, PEAR_LOG_DEBUG);
$aPath = RvsLibs_Publish::getPathByDomain($dns);
if (!is_writable($aPath['DIR'])) {
SGL::logMessage('cannot write ' . $aPath['DIR'], PEAR_LOG_ERR);
return false;
}
SGL::logMessage('========> runDetectPhpSuexec == dns = ' . $dns, PEAR_LOG_DEBUG);
// Create Random Directory
$ranPath = 'rvphpinfo' . rand(100000,999999);
// write php ini
//fixed PHPMD scan 07/07/2554
MainComponent::writeRvphpDetect(RVS_USER_NAME, $aPath['DIR'], $ranPath,'phpsuexec');
// Read php_info
$site = $dns;
$request = '/' . $ranPath . '/_rvphpinfo.php';
//detect::urlConnnect
//$site, $request, $port = 80, $authorizationl = null, $useSSL = false, $timeout = 30
//fixed PHPMD scan 07/07/2554
$page = RvsLibs_Url::urlConnect($site, $request, 80, null, false,30);
// Remove Random Directory
unlink($aPath['DIR'] . '/' . $ranPath . '/_rvphpinfo.php');
unlink($aPath['DIR'] . '/' . $ranPath . '/.htaccess');
// In some servesr there is error_log generated by web server
@unlink($aPath['DIR'] . '/' . $ranPath . '/error_log');
if ($ranPath && is_dir($aPath['DIR'] . '/' . $ranPath)) {
RvsLibs_System::rm(array('-rf', $aPath['DIR'] . '/' . $ranPath));
}
if (empty($page)) {
return 2;
}
/// ตัวแปร $page ถ้า urlConnect fail จะ return array ทำให้เกิด warning ตอน match
if (isset($page['CONNECT_ERROR']) && $page['CONNECT_ERROR'] == 1) {
return 0;
}
// match gd library
//fixed PHPMD scan 07/07/2554
return (preg_match('/true/', $page['data'])) ? 1 : 0;
}
}//End Class
}
if (class_exists('phpSuhosin') === false) {
class phpSuhosin
{
public function phpSuhosin()
{
}
public static function singleton()
{
static $oSuhosin;
if (isset($oSuhosin->func_blacklist) === false) {
$class = __CLASS__;
$oSuhosin = new $class();
$oSuhosin->func_blacklist = ini_get('suhosin.executor.func.blacklist');
}
return $oSuhosin;
}
}
}
?>
Copyright 2K16 - 2K18 Indonesian Hacker Rulez