* * * This software is protected by copyright, please * read the file COPYRIGHT. * This program 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. Please * read the file LICENCE. * * @link www.rooty.me * @copyright Copyright © 2004-2005, ARD Limousin * @author Rooty * @since 2004/09/03 * @version 0.3 * @package package * @subpackage backupFile */ if ( !defined('SYSTEM_IN') ) { //die("Hacking attempt"); } /** * classe de gestion de gestion de l'arborescence système. * @package package * @subpackage backupFile */ Class backupFile { /** *Liste le contenu d'un répertoire * @access public * @param chaine path vers le répertoire à lister * @return tableau tableau deux dimensions avec chemin+nom de fichier, type de fichier(rep="Directory", fichier="File", other="Inconnu"), nom fichier */ function getContentDir($path) { $cptfile=0; $tabFile=array(); //Test de l'existence du répertoire if (is_dir($path)) { //Ouverture du répertoire if ($rep = opendir($path)) { //Lecture et stockage du contenu du repertoire dans le tableau en précisant le type du fichier lu //les répertoires "." et ".." sont ignorés while (($file = readdir($rep)) !== false ) { if ($file != "." && $file != "..") { $tabFile[$cptfile][2]=$file; $file=$path.$file; $tabFile[$cptfile][0]=$file; if (is_dir($file)) { $tabFile[$cptfile][1]="Directory"; } else { if (is_file($file)) { $tabFile[$cptfile][1]="File"; } else { $tabFile[$cptfile][1]="Inconnu"; } } $cptfile++; } } } closedir($rep); } else { addError(3 , "BackUpFile", "chemin non valide ".$path, __line__, __file__); } return $tabFile; } /** * Suppresion d'un repertoire (récursivement) * @access public * @param chaine path vers le fichier à tester * @param chaine droit à tester sur le fichier(r:read,w:write,x:execute)==>exemple(rwx) * @return booleen */ function deleteDir($path) { $cptfile=0; if ($rep = opendir($path)) { //Lecture et stockage du contenu du repertoire dans le tableau en précisant le type du fichier lu //les répertoires "." et ".." sont ignorés while (($file = readdir($rep)) !== false ) { if ($file != "." && $file != "..") { if (is_dir($file)) { $this->deleteDir($path."/".$file); } else { @unlink($path."/".$file); } $cptfile++; } } } closedir($rep); @rmdir($path); } /** *Test les droits sur un fichier * @access public * @param chaine path vers le fichier à tester * @param chaine droit à tester sur le fichier(r:read,w:write,x:execute)==>exemple(rwx) * @return booleen */ function verifFilePerm($filePath, $droit) { $nbtest=strlen($droit); //Recupere le nombre de test de droit à effectuer switch ($nbtest) { case 1: if ($droit=="r"){ if (is_readable($filePath)){ return true; } } if ($droit=="w"){ if (is_writable($filePath)){ return true; } } if ($droit=="x"){ if (is_executable($filePath)){ return true; } } break; case 2: if ( $droit=="rw" || $droit=="wr"){ if (is_readable($filePath) && is_writable($filePath)){ return true; } } if ( $droit=="rx" || $droit=="xr"){ if (is_readable($filePath) && is_executable($filePath)){ return true; } } if ( $droit=="xw" || $droit=="wx"){ if (is_executable($filePath) && is_writable($filePath)){ return true; } } break; case 3: if (is_readable($filePath) && is_writable($filePath) && is_executable($filePath)){ return true; } break; } return false; } /** *Renomme un fichier * @access public * @param chaine path vers le fichier à renommer * @param chaine nouveau nom (penser à préciser l'extension!) * @return booleen */ function renameFile($sourcepath, $destination_name) { //Teste de l'existence du fichier if (file_exists($sourcepath)) { //On renomme le fichier if (rename($sourcepath,$destination_name)) { return true; } } return false; } /** *Renomme les fichiers éxistant pour un éventuel backup * @access public * @param chaine path vers le fichier à renommer * @param chaine extension du fichier sauvegardé * @return tableau tableau contenant l'ancien nom [oldname], le nouveau nom [newname], et le status de reussite ou non du renommage (true or false) */ function rename($sourcepath,$ext=".bkp") { $tabbackup=array(); //On change l'extension en gardant le path $pos=strrpos($sourcepath,"."); $ch=substr($sourcepath,0,$pos); $ch=$ch.$ext; //On renomme le fichier if ($this->renameFile($sourcepath,$ch)) { $tabbackup["oldname"]=$sourcepath; $tabbackup["newname"]=$ch; $tabbackup["success"]=true; } else { $tabbackup["oldname"]=$sourcepath; $tabbackup["newname"]=$ch; $tabbackup["success"]=false; } return $tabbackup; } /** *copie un fichier * @access public * @param chaine path vers le fichier à renommer * @param chaine nouveau nom (penser à préciser l'extension!) * @return booleen */ function copyFile($sourcepath, $destination_name){ //Teste de l'existence du fichier if (file_exists($sourcepath)) { //On renomme le fichier if (copy($sourcepath,$destination_name)) { return true; } } return false; } /** *Supprime un répertoire *Utilisation de la récursivité pour supprimé les sous-répertoire du répertoire racine passé en paramétre *Retourne TRUE si suppression reussie, retourne FALSE si un répertoire n'est pas vide * @access public * @param chaine path vers le répertoire a supprimer * @return booleen */ function EraseDir($sourcepath) { $tabficdir=$this->getContentDir($sourcepath); if (count($tabficdir)==0) { rmdir($sourcepath); return true; } else { foreach ($tabficdir as $key=>$val) { if ($tabficdir[$key][1]=="Directory") { $this->EraseDir($tabficdir[$key][0]); } else { return False; } } } } /** *copie les fichiers éxistant pour un éventuel backup * @access public * @param chaine path vers le fichier à renommer * @param chaine extension du fichier sauvegardé * @return tableau tableau contenant l'ancien nom [oldname], le nouveau nom [newname], et le status de reussite ou non du renommage (true or false) */ function copy($sourcepath,$ext=".bkp") { $tabbackup=array(); //On change l'extension en gardant le path $pos=strrpos($sourcepath,"."); $ch=substr($sourcepath,0,$pos); $ch=$ch.$ext; //On renomme le fichier if ($this->copyFile($sourcepath,$ch)) { $tabbackup["oldname"]=$sourcepath; $tabbackup["newname"]=$ch; $tabbackup["success"]=true; } else { $tabbackup["oldname"]=$sourcepath; $tabbackup["newname"]=$ch; $tabbackup["success"]=false; } return $tabbackup; } /** *Cette fonction permet d'attribuée des droits à un fichier * @access public * @param chaine path vers le fichier * @param entier droits à attribuer (ex:0775==>droits de lecture et d'écriture pour l'utilisateur et le groupe, droits d'exécution pour tous) * @return booleen */ function setFilePerm($Path,$FileMode) { //Test de l'existence du fichier if (file_exists($Path)) { //Affectation des droits si l'utilisateur éxécutant le script est autorisé if (@chmod($Path, $FileMode)) return true; else return false; } else { echo "
Le fichier n'existe pas!"; return false; } } /** *Fonction permettant d'affecter des droits à un répertoire de maniére recurssive * @access public * @param chaine path vers le repertoire * @param entier droit à attribuer (ex:0775==>droits de lecture et d'écriture pour l'utilisateur et le groupe, droits d'exécution pour tous) * @return tableau tableau 2 dimensions avec une dimension pour la profondeur et une dimension pour les path du fichier, les droits tester et la reussite ou non de l'affection des doits */ function setTreePerm($dirPath, $chmod) { $tabarbo=array(); $tabarbo=$this->getContentDir($dirPath); $tabresult=array(); $cpt=0; //Parcours du repertoire for ($i=0;$i < count($tabarbo);$i++) { if ($tabarbo[$i][1]=="Directory") { //Parcours des sous-répertoire de maniére recursive $tabresult=array_merge($tabresult,$this->setTreePerm($tabarbo[$i][0]."/", $chmod)); $cpt=count($tabresult); } //Affectation des droits et enregistrement des opérations dans le tableau else if ($tabarbo[$i][1]=="File") { $tabresult[$cpt]["path"]=$tabarbo[$i][0]; $tabresult[$cpt]["perm"]=$chmod; if ($this->setFilePerm($tabarbo[$i][0],$chmod)) { $tabresult[$cpt]["success"]=true; } else { $tabresult[$cpt]["success"]=false; } $cpt++; } } return $tabresult; } /** * Fonction qui parcours le fichier .ini et verifie l'existence des fichiers sources * @access public * @param chaine path vers le fichier ini * @return tableau tableau assosiatif du contenu du fichier .ini */ function parcoursInitoTab($PathIni, $path="./", $chmod) { $tabresult=array(); $tabini=array(); //Copie des fichiers dans l'arbo avec enregistrement dans le tableau du resultat de la copie //enregistrement également des paths source et destination if ($tabini=parse_ini_file($PathIni)) { foreach ($tabini as $key=>$val) { //Verifie l'existence du fichier source $tabresult[$key][0]=$val; if (file_exists($path.$key) && $this->setFilePerm($path.$key, $chmod)) { $tabresult[$key][0]=$val; $tabresult[$key][1]=True; } else { $tabresult[$key][1]=False; } } } else { echo "
Erreur de lecture du fichier .ini!"; } return $tabresult; } /** * Création d'un répertoire * Ne gére pas un path absolu * @access public * @param tableau tableau associatif du fichier ini * @param entier droit à attribuer à la création d'un répertoire * @return tableau tableau associatif des états de création des reps */ function createRep($tab, $chmod) { $tabTmp=array(); $tabresult=array(); $cpt=0; //Création de l'arbo avec les valeurs contenues dans le fichier .ini foreach ($tab as $key=>$val) { $tabTmp=mb_split('/',$this->getSystemPath($val[0])); $pathTmp=""; $tabresult[$cpt][0]=$this->getSystemPath($val[0]); $tabresult[$cpt][1]=true; for ($i=0; $i<(count($tabTmp)-1); $i++) { $pathTmp.=$tabTmp[$i]."/"; if ( !is_dir($pathTmp) ) { if(mkdir($pathTmp,$chmod)===true){ $tabresult[$cpt][1]=true; chmod($pathTmp, $chmod); }else{ $tabresult[$cpt][1]=false; return $tabresult; } } } $cpt++; } return $tabresult; } /** *Cette fonction charge un fichier ini, qui indique ou copier les fichier dans l'arbo granilim *Le fichier .ini doit etre strucuturé comme suit: *[source] *testsource="./test/testdestination/" * @access public * @param chaine path vers le fichier ini * @param entier valeur du umask * @return tableau tableau d'état des fichier copier avec les paths sources et destinations et le status de la copie (true or false) */ function copyFileFromTab($tabini, $pkgname ,$chmod) { $tabresultcopie=array(); $tabperm=array(); $tabrep=array(); $tabbackup=array(); $cpt=0; //Création des répertoires inexistant //Appel fonction création rep, avec un umask en lecture et écriture sur tous les reps créés et les fichiers copiés $tabrep=$this->createRep($tabini,$chmod); if (count($tabini)>0){ foreach ($tabini as $key=>$struct) { $val=$this->getSystemPath($struct[0]); //On verifie les permissions pour écraser le fichier s'il existe if ($tabini[$key][1]===true && $tabrep[$cpt][1]===true) { if ($this->rename($val, ".php~")!==false) { if (copy($GLOBALS["CONF_DATA_PATH"]."data/upload/install/package/".$pkgname."/".$key, $val)) { $tabresultcopie[$key][0]=$val; $tabresultcopie[$key][1]=$this->setFilePerm($val, $chmod); if (file_exists($val."~")) { @unlink($val."~"); } } else { $tabresultcopie[$key][0]=$val; $tabresultcopie[$key][1]=false; } }else{ $tabresultcopie[$key][0]=$val; $tabresultcopie[$key][1]=false; } } $cpt++; } } return $tabresultcopie; } /** *Fonction qui verifie que les fichiers distants existent, et si ils existent qu'on a les droits pour les écraser. * @access public * @param tableau type tableau renvoyé par ParcoursIniTab * @return tableau tableau contenant le path vers le fichier dont on veut vérifier les perms, et l'état de la permission testée (true or false) */ function verifFilePermFromTab($tab, $chmod) { $tabresult=array(); if (count($tab)>0) { //Vérification que les fichiers a copier existent, et si ils existent qu'on a les droits pour les écraser. foreach ($tab as $key=>$val) { $tabresult[$key][0]=$this->getSystemPath($tab[$key][0]); if (file_exists($this->getSystemPath($tab[$key][0]))) { //Test des permission pour l'écraser if ($this->verifFilePerm($this->getSystemPath($tab[$key][0]), "rw")) { $tabresult[$key][1]=true; }else{//Pas les droit pour écraser if ($this->setFilePerm($this->getSystemPath($tab[$key][0]), $chmod)){ $tabresult[$key][1]=true; }else{ $tabresult[$key][1]=false; } } } else { //Le fichier n'existe pas $tabresult[$key][1]=true; } } } return $tabresult; } /** * Permet de récupérer le bon path en fonction de la configuration serveur * Ce path s'appuira sur les variables: * - CONF_LIB_PATH (chemin d'accés à lib)
* - CONF_DATA_PATH (chemin d'accés aux données)
* - CONF_LOG_PATH (chemin d'accés aux logs)
* - $COMMUN_PATH_CONFIG (chemin d'accés aux fichiers de configuration)
* @return float version du fichier sinon 0 */ function getSystemPath($pathFile){ $tabTmp=mb_split('/',$pathFile); if ( (is_null($tabTmp[0])) || ($tabTmp[0]==".") ){ unset($tabTmp[0]); return ($this->getSystemPath(implode("/", $tabTmp))); } # pathFile doit être correct maintenant if(substr($pathFile, 0, 4)=="data") return $GLOBALS["CONF_DATA_PATH"].$pathFile; elseif(substr($pathFile, 0, 3)=="lib") return $GLOBALS["CONF_LIB_PATH"].$pathFile; elseif(substr($pathFile, 0, 3)=="log") return $GLOBALS["CONF_LOG_PATH"].$pathFile; elseif(substr($pathFile, 0, 6)=="config") return $GLOBALS["COMMUN_PATH_CONFIG"].$pathFile; elseif(substr($pathFile, 0, 7)=="install") return "./".$pathFile; return $pathFile; } /** * Vérifie la configuration des droits systéme (droit php && utilisateur) * retourne faux si les fichiers uploadés ne sont pas accessibles via php sinon int pour les droits à passer en chmod!!! * @return entier droits a affecter aux fichiers && faux si inaccessibles */ function checkConfigForPerms($path=null){ if ($path==null) { $path=$GLOBALS["CONF_DATA_PATH"]."data/upload/install/"; } // // Gestion des droits d'acces // $ok = false; $self = basename($_SERVER['PHP_SELF']); $uid = @fileowner('.'); $uid2 = @fileowner($self); $gid = @filegroup('.'); $gid2 = @filegroup($self); $perms = @fileperms($self); // var_dump(intval(substr(decoct( fileperms($self) ), 2))); // Comparer l'appartenance d'un fichier cree par PHP // avec celle du script et du repertoire courant if (is_dir($path.'test')){ @rmdir($path.'test'); }elseif(is_file($path.'test')){ @unlink($path.'test'); // effacer au cas ou } @touch($path.'test'); if ($uid > 0 && $uid == $uid2 && @fileowner($path.'test') == $uid) $chmod = 0700; else if ($gid > 0 && $gid == $gid2 && @filegroup($path.'test') == $gid) $chmod = 0770; else $chmod = 0775; // Appliquer de plus les droits d'acces du script if ($perms > 0) { $perms = ($perms & 0775) | (($perms & 0444) >> 2); $chmod |= $perms; } @unlink($path.'test'); // Verifier que les valeurs sont correctes @mkdir($path.'test', $chmod); @chmod($path.'test', $chmod); $f = @fopen($path.'test/test.php', 'w'); if ($f) { @fputs($f, ''); @fclose($f); @chmod($path.'test/test.php', $chmod); include($path.'test/test.php'); } if (!$ok) { return false; }else{ @unlink($path.'test/test.php'); @rmdir($path.'test'); return $chmod; } } /** * chown et chgrp en recursif !!!! * merci php.net * @link http://fr3.php.net/manual/fr/function.chown.php */ function recurse_chown_chgrp($path2dir, $uid, $gid){ $dir = new dir($path2dir); while(($file = $dir->read()) !== false) { if(is_dir($dir->path.$file)) { recurse_chown_chgrp($dir->path.$file, $uid, $gid); } else { chown($file, $uid); chgrp($file, $gid); } } $dir->close(); } } ?>