* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ /** * this file contains a toolbox with misc. usefull functions * * @author Stephane Gully */ // To be sure the directory separator is defined // I don't know if this constant can be undefined or not so maybe this code is not necessary if (!defined("DIRECTORY_SEPARATOR")) define("DIRECTORY_SEPARATOR", "/"); /** * Returns the absolute script filename * takes care of php cgi configuration which do not support SCRIPT_FILENAME variable. */ function pfc_GetScriptFilename() { $sf = ''; if(function_exists('debug_backtrace')) { // browse the backtrace history and take the first unknown filename as the client script foreach(debug_backtrace() as $db) { $f = $db['file']; if (!preg_match('/phpfreechat.class.php/',$f) && !preg_match('/pfcglobalconfig.class.php/',$f) && !preg_match('/pfctools.class.php/',$f) && !preg_match('/pfcinfo.class.php/',$f) ) { $sf = $f; break; } } } else if (isset($_SERVER['PATH_TRANSLATED']) && file_exists($_SERVER['SCRIPT_FILENAME'])) // check for a cgi configurations { $sf = $_SERVER['PATH_TRANSLATED']; } else if (isset($_SERVER['SCRIPT_FILENAME'])&& file_exists($_SERVER['SCRIPT_FILENAME'])) // for non-cgi configurations { $sf = $_SERVER['SCRIPT_FILENAME']; } else { echo "
";
    echo "Error: pfc_GetScriptFilename function returns a wrong path. Please contact the pfc team (contact@phpfreechat.net) and copy/paste these data to help debugging:\n";
    print_r($_SERVER);
    print_r(debug_backtrace());
    echo "
"; exit; } return $sf; } function pfc_RelativePath($p1, $p2) { if (is_file($p1)) $p1 = dirname($p1); if (is_file($p2)) $p2 = dirname($p2); // using realpath function is necessary to resolve symbolic links $p1 = realpath(cleanPath($p1)); $p2 = realpath(cleanPath($p2)); $res = ""; // echo $p1."
"; // echo $p2."
"; while( $p1 != "" && $p1 != "/" && // for unix root dir !preg_match("/^[a-z]\:\\\$/i",$p1) && // for windows rootdir strpos($p2, $p1) !== 0) { $res .= "../"; $p1 = dirname($p1); } if (isset($_SERVER["WINDIR"]) || isset($_SERVER["windir"])) { $p2 = str_replace("\\","/",substr($p2, strlen($p1)+1, strlen($p2)-strlen($p1))); } else { if ($p1 === "/" || $p1 === "") { $p2 = substr($p2, strlen($p1)); } else { $p2 = substr($p2, strlen($p1)+1); } } $res .= $p2; // remove the last "/" if (preg_match("/.*\/$/", $res)) $res = preg_replace("/(.*)\//","$1",$res); // if rootpath is empty replace it by "." to avoide url starting with "/" if ($res == "") $res = "."; // echo $res."
"; return $res; } function cleanPath($path) { $result = array(); $pathA = explode(DIRECTORY_SEPARATOR, $path); if (!$pathA[0]) $result[] = ''; foreach ($pathA AS $key => $dir) { if ($dir == '..') { if (end($result) == '..') { $result[] = '..'; } elseif (!array_pop($result)) { $result[] = '..'; } } elseif ($dir && $dir != '.') { $result[] = $dir; } } if (!end($pathA)) $result[] = ''; return implode('/', $result); } function mkdir_r($path, $modedir = 0755) { // This function creates the specified directory using mkdir(). Note // that the recursive feature on mkdir() is broken with PHP 5.0.4 for // Windows, so I have to do the recursion myself. if (!file_exists($path)) { // The directory doesn't exist. Recurse, passing in the parent // directory so that it gets created. mkdir_r(dirname($path), $modedir); mkdir($path, $modedir); } } function rm_r($dir) { if(!$dh = @opendir($dir)) return; while (($obj = readdir($dh))) { if($obj=='.' || $obj=='..') continue; if (!@unlink($dir.'/'.$obj)) rm_r($dir.'/'.$obj); } closedir($dh); @rmdir($dir); } /** * Copy a file, or recursively copy a folder and its contents * * @author Aidan Lister * @link http://aidanlister.com/repos/v/function.copyr.php * @param string $source Source path * @param string $dest Destination path * @return bool Returns TRUE on success, FALSE on failure */ function copy_r($source, $dest, $modedir = 0755, $modefile = 0664) { // Simple copy for a file if (is_file($source)) { $ret = copy($source, $dest); chmod($dest, $modefile); return $ret; } // Make destination directory if (!is_dir($dest)) { mkdir($dest, $modedir); } // Take the directories entries $dir = dir($source); $entries = array(); while (false !== $entry = $dir->read()) { $entries[] = $entry; } // Loop through the folder foreach ($entries as $e) { // Skip pointers and subversion directories if ($e == '.' || $e == '..' || $e == '.svn') continue; // Deep copy directories if ($dest !== $source . DIRECTORY_SEPARATOR . $e) copy_r($source . DIRECTORY_SEPARATOR . $e, $dest . DIRECTORY_SEPARATOR . $e, $modedir, $modefile); } // Clean up $dir->close(); return true; } /** * Check the functions really exists on this server */ function check_functions_exist( $f_list ) { $errors = array(); foreach( $f_list as $func => $err ) { if (!function_exists( $func )) $errors[] = _pfc("%s doesn't exist: %s", $func, $err); } return $errors; } function test_writable_dir($dir, $name = "") { $errors = array(); if ($dir == "") $errors[] = _pfc("%s directory must be specified", ($name!="" ? $name : $dir)); if (is_file($dir)) $this->errors[] = _pfc("%s must be a directory",$dir); if (!is_dir($dir)) mkdir_r($dir); if (!is_dir($dir)) $errors[] = _pfc("%s can't be created",$dir); if (!is_writeable($dir)) $errors[] = _pfc("%s is not writeable",$dir); if (!is_readable($dir)) $errors[] = _pfc("%s is not readable",$dir); return $errors; } function install_file($src_file, $dst_file) { $errors = array(); $src_dir = dirname($src_file); $dst_dir = dirname($dst_file); if (!is_file($src_file)) $errors[] = _pfc("%s is not a file", $src_file); if (!is_readable($src_file)) $errors[] = _pfc("%s is not readable", $src_file); if (!is_dir($src_dir)) $errors[] = _pfc("%s is not a directory", $src_dir); if (!is_dir($dst_dir)) mkdir_r($dst_dir); copy( $src_file, $dst_file ); return $errors; } function install_dir($src_dir, $dst_dir) { $errors = array(); if (!is_dir($src_dir)) $errors[] = _pfc("%s is not a directory", $src_dir); if (!is_readable($src_dir)) $errors[] = _pfc("%s is not readable", $src_dir); copy_r( $src_dir, $dst_dir ); return $errors; } /** * file_get_contents_flock * define an alternative file_get_contents when this function doesn't exists on the used php version (<4.3.0) */ if (!defined('LOCK_SH')) { define('LOCK_SH', 1); } function file_get_contents_flock($filename, $incpath = false, $resource_context = null) { if (false === $fh = fopen($filename, 'rb', $incpath)) { user_error('file_get_contents() failed to open stream: No such file or directory ['.$filename.']', E_USER_WARNING); return false; } // Attempt to get a shared (read) lock if (!flock($fh, LOCK_SH)) { return false; } clearstatcache(); if ($fsize = @filesize($filename)) { $data = fread($fh, $fsize); } else { $data = ''; while (!feof($fh)) { $data .= fread($fh, 8192); } } fclose($fh); return $data; } /** * file_get_contents * define an alternative file_get_contents when this function doesn't exists on the used php version (<4.3.0) */ if (!function_exists('file_get_contents')) { function file_get_contents($filename, $incpath = false, $resource_context = null) { if (false === $fh = fopen($filename, 'rb', $incpath)) { trigger_error('file_get_contents() failed to open stream: No such file or directory ['.$filename.']', E_USER_WARNING); return false; } clearstatcache(); if ($fsize = filesize($filename)) { $data = fread($fh, $fsize); } else { while (!feof($fh)) { $data .= fread($fh, 8192); } } fclose($fh); return $data; } } /** * Replace file_put_contents() * * @category PHP * @package PHP_Compat * @link http://php.net/function.file_put_contents * @author Aidan Lister * @internal resource_context is not supported * @since PHP 5 * @require PHP 4.0.0 (user_error) */ if (!defined('FILE_USE_INCLUDE_PATH')) { define('FILE_USE_INCLUDE_PATH', 1); } if (!defined('LOCK_EX')) { define('LOCK_EX', 2); } if (!defined('FILE_APPEND')) { define('FILE_APPEND', 8); } if (!function_exists('file_put_contents')) { function file_put_contents($filename, $content, $flags = null, $resource_context = null) { // If $content is an array, convert it to a string if (is_array($content)) { $content = implode('', $content); } // If we don't have a string, throw an error if (!is_scalar($content)) { user_error('file_put_contents() The 2nd parameter should be either a string or an array ['.$filename.']', E_USER_WARNING); return false; } // Get the length of data to write $length = strlen($content); // Check what mode we are using $mode = ($flags & FILE_APPEND) ? 'a' : 'wb'; // Check if we're using the include path $use_inc_path = ($flags & FILE_USE_INCLUDE_PATH) ? true : false; // Open the file for writing if (($fh = @fopen($filename, $mode, $use_inc_path)) === false) { user_error('file_put_contents() failed to open stream: Permission denied ['.$filename.']', E_USER_WARNING); return false; } // Attempt to get an exclusive lock $use_lock = ($flags & LOCK_EX) ? true : false ; if ($use_lock === true) { if (!flock($fh, LOCK_EX)) { return false; } } // Write to the file $bytes = 0; if (($bytes = @fwrite($fh, $content)) === false) { $errormsg = sprintf('file_put_contents() Failed to write %d bytes to %s ['.$filename.']', $length, $filename); user_error($errormsg, E_USER_WARNING); return false; } // Close the handle @fclose($fh); // Check all the data was written if ($bytes != $length) { $errormsg = sprintf('file_put_contents() Only %d of %d bytes written, possibly out of free disk space. ['.$filename.']', $bytes, $length); user_error($errormsg, E_USER_WARNING); return false; } // Return length return $bytes; } } /** * iconv * define an alternative iconv when this function doesn't exists on the php modules */ if (!function_exists('iconv')) { if(function_exists('libiconv')) { // use libiconv if it exists function iconv($input_encoding, $output_encoding, $string) { return libiconv($input_encoding, $output_encoding, $string); } } else { // fallback if nothing has been found function iconv($input_encoding, $output_encoding, $string) { return $string; } } } /** * Replace html_entity_decode() * * @category PHP * @package PHP_Compat * @link http://php.net/function.html_entity_decode * @author David Irvine * @author Aidan Lister * @version $Revision: 1.8 $ * @since PHP 4.3.0 * @internal Setting the charset will not do anything * @require PHP 4.0.0 (user_error) */ if (!defined('ENT_NOQUOTES')) { define('ENT_NOQUOTES', 0); } if (!defined('ENT_COMPAT')) { define('ENT_COMPAT', 2); } if (!defined('ENT_QUOTES')) { define('ENT_QUOTES', 3); } if (!function_exists('html_entity_decode')) { function html_entity_decode($string, $quote_style = ENT_COMPAT, $charset = null) { if (!is_int($quote_style)) { user_error('html_entity_decode() expects parameter 2 to be long, ' . gettype($quote_style) . ' given', E_USER_WARNING); return; } $trans_tbl = get_html_translation_table(HTML_ENTITIES); $trans_tbl = array_flip($trans_tbl); // Add single quote to translation table; $trans_tbl['''] = '\''; // Not translating double quotes if ($quote_style & ENT_NOQUOTES) { // Remove double quote from translation table unset($trans_tbl['"']); } return strtr($string, $trans_tbl); } } ?>