Qware_core/lib/package/backup/backupfile.php

668 lines
17 KiB
PHP
Raw Normal View History

2020-12-03 16:35:44 +01:00
<?php
/**------------------------------------------------
*
* Rooty, 2018 <rooty@rooty.me>
*
*
* 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 &copy; 2004-2005, ARD Limousin
* @author Rooty <www.rooty.me|rooty@rooty.me>
* @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 "<br>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 "<br>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=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)<br/>
* - CONF_DATA_PATH (chemin d'accés aux données)<br/>
* - CONF_LOG_PATH (chemin d'accés aux logs)<br/>
* - $COMMUN_PATH_CONFIG (chemin d'accés aux fichiers de configuration)<br/>
* @return float version du fichier sinon 0
*/
function getSystemPath($pathFile){
$tabTmp=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);
// 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, '<?php $ok = true; ?>');
@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();
}
}
?>