grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026. -------------------------------------------------------------------------- */ /** @file * @brief */ include ('../inc/includes.php'); if (isset($_POST['check_version'])) { Session::checkRight('backup', Backup::CHECKUPDATE); Toolbox::checkNewVersionAvailable(0, true); Html::back(); } Session::checkRight("backup", READ); // full path $path = GLPI_DUMP_DIR ; Html::header(__('Maintenance'), $_SERVER['PHP_SELF'], "admin", "backup"); $max_time = min(get_cfg_var("max_execution_time"), get_cfg_var("max_input_time")); if ($max_time == 0) { $defaulttimeout = 60; $defaultrowlimit = 5; } else if ($max_time > 5) { $defaulttimeout = $max_time-2; $defaultrowlimit = 5; } else { $defaulttimeout = max(1, $max_time-2); $defaultrowlimit = 2; } /** * Genere un fichier backup.xml a partir de base dbhost connecte avec l'utilisateur dbuser * et le mot de passe dbpassword sur le serveur dbdefault **/ function xmlbackup() { global $CFG_GLPI, $DB; //on parcoure la DB et on liste tous les noms des tables dans $table //on incremente $query[] de "select * from $table" pour chaque occurence de $table $result = $DB->list_tables(); $i = 0; while ($line = $DB->fetch_row($result)) { $table = $line[0]; $query[$i] = "SELECT * FROM `$table`"; $i++; } //le nom du fichier a generer... //Si fichier existe deja il sera remplac�par le nouveau $chemin = GLPI_DUMP_DIR."/backup.xml"; // Creation d'une nouvelle instance de la classe // et initialisation des variables $A = new XML(); // Your query $A->SqlString = $query; //File path $A->FilePath = $chemin; // Type of layout : 1,2,3,4 // For details about Type see file genxml.php if (empty($Type)) { $A->Type = 4; } else { $A->Type = $Type; } //appelle de la methode gerant le fichier XML $A->DoXML(); // Affichage, si erreur affiche erreur //sinon affiche un lien vers le fichier XML genere if ($A->IsError == 1) { printf(__('ERROR:'), $A->ErrorString); } //fin de fonction xmlbackup } ////////////////////////// DUMP SQL FUNCTIONS /** * Init time to computer time spend **/ function init_time() { global $TPSDEB, $TPSCOUR; list($usec,$sec) = explode(" ", microtime()); $TPSDEB = $sec; $TPSCOUR = 0; } /** * Get current time **/ function current_time() { global $TPSDEB, $TPSCOUR; list($usec,$sec) = explode(" ", microtime()); $TPSFIN = $sec; if (round($TPSFIN-$TPSDEB,1) >= $TPSCOUR+1) {//une seconde de plus $TPSCOUR = round($TPSFIN-$TPSDEB,1); } } /** Get data of a table * * @param $DB DB object * @param $table table name * @param $from begin from * @param $limit limit to **/ function get_content($DB, $table, $from, $limit) { $content = ""; $result = $DB->query("SELECT * FROM `$table` LIMIT ".intval($from).",".intval($limit)); if ($result) { $num_fields = $DB->num_fields($result); while ($row = $DB->fetch_row($result)) { $insert = "INSERT INTO `$table` VALUES ("; for( $j=0 ; $j<$num_fields ; $j++) { if (is_null($row[$j])) { $insert .= "NULL,"; } else if ($row[$j] != "") { $insert .= "'".addslashes($row[$j])."',"; } else { $insert .= "'',"; } } $insert = preg_replace("/,$/","",$insert); $insert .= ");\n"; $content .= $insert; } } return $content; } /** Get structure of a table * * @param $DB DB object * @param $table table name **/ function get_def($DB, $table) { $def = "### Dump table $table\n\n"; $def .= "DROP TABLE IF EXISTS `$table`;\n"; $query = "SHOW CREATE TABLE `$table`"; $result = $DB->query($query); $DB->query("SET SESSION sql_quote_show_create = 1"); $row = $DB->fetch_row($result); $def .= preg_replace("/AUTO_INCREMENT=\w+/i","",$row[1]); $def .= ";"; return $def."\n\n"; } /** Restore a mysql dump * * @param $DB DB object * @param $dumpFile dump file * @param $duree max delay before refresh **/ function restoreMySqlDump($DB, $dumpFile, $duree) { global $DB, $TPSCOUR, $offset, $cpt; // $dumpFile, fichier source // $duree=timeout pour changement de page (-1 = aucun) // Desactivation pour empecher les addslashes au niveau de la creation des tables // En plus, au niveau du dump on considere qu'on est bon // set_magic_quotes_runtime(0); if (!file_exists($dumpFile)) { echo sprintf(__('File %s not found.'), $dumpFile)."
"; return false; } if (substr($dumpFile, -2) == "gz") { $fileHandle = gzopen($dumpFile, "rb"); } else { $fileHandle = fopen($dumpFile, "rb"); } if (!$fileHandle) { //TRASN: %s is the name of the file echo sprintf(__('Unauthorized access to the file %s'), $dumpFile)."
"; return false; } if ($offset != 0) { if (substr($dumpFile, -2) == "gz") { if (gzseek($fileHandle,$offset,SEEK_SET) != 0) { //erreur //TRANS: %s is the number of the byte printf(__("Unable to find the byte %s"), Html::formatNumber($offset, false, 0)); echo "
"; return false; } } else { if (fseek($fileHandle,$offset,SEEK_SET) != 0) { //erreur //TRANS: %s is the number of the byte printf(__("Unable to find the byte %s"), Html::formatNumber($offset, false, 0)); echo "
"; return false; } } Html::glpi_flush(); } $formattedQuery = ""; if (substr($dumpFile, -2) == "gz") { while (!gzeof($fileHandle)) { current_time(); if (($duree > 0) && ($TPSCOUR >= $duree)) { //on atteint la fin du temps imparti return true; } // specify read length to be able to read long lines $buffer = gzgets($fileHandle, 102400); // do not strip comments due to problems when # in begin of a data line $formattedQuery .= $buffer; if (substr(rtrim($formattedQuery),-1) == ";") { // Do not use the $DB->query if ($DB->query($formattedQuery)) { //if no success continue to concatenate $offset = gztell($fileHandle); $formattedQuery = ""; $cpt++; } } } } else { while (!feof($fileHandle)) { current_time(); if (($duree > 0) && ($TPSCOUR >= $duree)) { //on atteint la fin du temps imparti return true; } // specify read length to be able to read long lines $buffer = fgets($fileHandle, 102400); // do not strip comments due to problems when # in begin of a data line $formattedQuery .= $buffer; if (substr(rtrim($formattedQuery),-1) == ";") { // Do not use the $DB->query if ($DB->query($formattedQuery)) { //if no success continue to concatenate $offset = ftell($fileHandle); $formattedQuery = ""; $cpt++; } } } } if ($DB->error) { echo "
"; //TRANS: %s is the SQL query which generates the error printf(__("SQL error starting from %s"), "[$formattedQuery]"); echo "
".$DB->error()."
"; } if (substr($dumpFile, -2) == "gz") { gzclose($fileHandle); } else { fclose($fileHandle); } $offset = -1; return true; } /** Backup a glpi DB * * @param $DB DB object * @param $dumpFile dump file * @param $duree max delay before refresh * @param $rowlimit rowlimit to backup in one time **/ function backupMySql($DB, $dumpFile, $duree, $rowlimit) { global $TPSCOUR, $offsettable, $offsetrow, $cpt; // $dumpFile, fichier source // $duree=timeout pour changement de page (-1 = aucun) if (function_exists('gzopen')) { $fileHandle = gzopen($dumpFile, "a"); } else { $fileHandle = gzopen64($dumpFile, "a"); } if (!$fileHandle) { //TRANS: %s is the name of the file echo sprintf(__('Unauthorized access to the file %s'), $dumpFile)."
"; return false; } if ($offsettable == 0 && $offsetrow == -1) { $time_file = date("Y-m-d-H-i"); $cur_time = date("Y-m-d H:i"); $todump = "#GLPI Dump database on $cur_time\n"; gzwrite ($fileHandle, $todump); } $result = $DB->list_tables(); $numtab = 0; while ($t = $DB->fetch_row($result)) { $tables[$numtab] = $t[0]; $numtab++; } for ( ; $offsettable<$numtab ; $offsettable++) { // Dump de la structure table if ($offsetrow == -1) { $todump = "\n".get_def($DB,$tables[$offsettable]); gzwrite ($fileHandle,$todump); $offsetrow++; $cpt++; } current_time(); if (($duree > 0) && ($TPSCOUR >= $duree)) { //on atteint la fin du temps imparti return true; } $fin = 0; while (!$fin) { $todump = get_content($DB,$tables[$offsettable],$offsetrow,$rowlimit); $rowtodump = substr_count($todump, "INSERT INTO"); if ($rowtodump > 0) { gzwrite ($fileHandle,$todump); $cpt += $rowtodump; $offsetrow += $rowlimit; if ($rowtodump<$rowlimit) { $fin = 1; } current_time(); if (($duree > 0) && ($TPSCOUR >= $duree)) { //on atteint la fin du temps imparti return true; } } else { $fin = 1; $offsetrow = -1; } } if ($fin) { $offsetrow = -1; } current_time(); if (($duree > 0) && ($TPSCOUR >= $duree)) { //on atteint la fin du temps imparti return true; } } if ($DB->error()) { echo "
"; //TRANS: %s is the SQL query which generates the error printf(__("SQL error starting from %s"), "[$formattedQuery]"); echo "
".$DB->error()."
"; } $offsettable = -1; gzclose($fileHandle); return true; } // #################" DUMP sql################################# if (isset($_GET["dump"]) && $_GET["dump"] != "") { $time_file = date("Y-m-d-H-i"); $cur_time = date("Y-m-d H:i"); $filename = $path . "/glpi-".GLPI_VERSION."-$time_file.sql.gz"; if (!isset($_GET["duree"]) && is_file($filename)) { echo "
".__('The file already exists')."
"; } else { init_time(); //initialise le temps //debut de fichier if (!isset($_GET["offsettable"])) { $offsettable = 0; } else { $offsettable = $_GET["offsettable"]; } //debut de fichier if (!isset($_GET["offsetrow"])) { $offsetrow = -1; } else { $offsetrow = $_GET["offsetrow"]; } //timeout de 5 secondes par defaut, -1 pour utiliser sans timeout if (!isset($_GET["duree"])) { $duree = $defaulttimeout; } else { $duree = $_GET["duree"]; } //Limite de lignes a dumper a chaque fois if (!isset($_GET["rowlimit"])) { $rowlimit = $defaultrowlimit; } else { $rowlimit = $_GET["rowlimit"]; } //si le nom du fichier n'est pas en parametre le mettre ici if (!isset($_GET["fichier"])) { $fichier = $filename; } else { $fichier = $_GET["fichier"]; } $tab = $DB->list_tables(); $tot = $DB->numrows($tab); if (isset($offsettable)) { if ($offsettable >= 0) { $percent = min(100,round(100*$offsettable/$tot,0)); } else { $percent = 100; } } else { $percent = 0; } if ($percent >= 0) { Html::displayProgressBar(400, $percent); echo '
'; } if ($offsettable >= 0) { if (backupMySql($DB,$fichier,$duree,$rowlimit)) { echo "
". "". __('Automatic redirection, else click').""; echo "
"; Html::glpi_flush(); exit; } } } } // ############################## fin dump sql########################"""" // ################################## dump XML ############################# if (isset($_GET["xmlnow"]) && ($_GET["xmlnow"] != "")) { xmlbackup(); } // ################################## fin dump XML ############################# if (isset($_GET["file"]) && ($_GET["file"] != "") && is_file($path."/".$_GET["file"])) { $_SESSION['TRY_OLD_CONFIG_FIRST'] = true; init_time(); //initialise le temps //debut de fichier if (!isset($_GET["offset"])) { $offset = 0; } else { $offset = $_GET["offset"]; } //timeout de 5 secondes par defaut, -1 pour utiliser sans timeout if (!isset($_GET["duree"])) { $duree = $defaulttimeout; } else { $duree = $_GET["duree"]; } $fsize = filesize($path."/".$_GET["file"]); if (isset($offset)) { if ($offset == -1) { $percent = 100; } else { $percent = min(100,round(100*$offset/$fsize,0)); } } else { $percent = 0; } if ($percent >= 0) { Html::displayProgressBar(400, $percent); echo '
'; } if ($offset != -1) { if (restoreMySqlDump($DB,$path."/".$_GET["file"],$duree)) { echo "
". ""; echo __('Automatic redirection, else click').""; echo "
"; Html::glpi_flush(); exit; } } else { DBmysql::optimize_tables(NULL, true); // Compatiblity for old version for utf8 complete conversion $cnf = new Config(); $input['id'] = 1; $input['utf8_conv'] = 1; $cnf->update($input); } } if (isset($_POST["delfile"])) { if (isset($_POST['file']) && ($_POST["file"] != "")) { $filename = $_POST["file"]; if (is_file($path."/".$_POST["file"])) { unlink($path."/".$_POST["file"]); // TRANS: %s is a file name echo "
".sprintf(__('%s deleted'), $filename)."
"; } } } if (Session::haveRight('backup', Backup::CHECKUPDATE)) { echo "
"; echo "
"; Html::showSimpleForm($_SERVER['PHP_SELF'], 'check_version', __('Check if a new version is available')); echo "
"; } // Title backup echo "
"; if (Session::haveRight('backup', CREATE)) { echo ""; echo ""; echo ""; echo "
". "\"".__s('Deleted')."\"". "".__('SQL Dump')." ".__('XML Dump')." 
"; } echo "
". "". "". "". "". "". ""; $dir = opendir($path); $files = array(); while ($file = readdir($dir)) { if (($file != ".") && ($file != "..") && (preg_match("/\.sql.gz$/i",$file) || preg_match("/\.sql$/i",$file))) { $files[$file] = filemtime($path."/".$file); } } arsort($files); if (count($files)) { foreach ($files as $file => $date) { $taille_fic = filesize($path."/".$file); echo "". "". ""; if (Session::haveRight('backup', PURGE)) { echo ""; echo ""; } if (Session::haveRight('backup', CREATE)) { echo ""; } echo ""; } } closedir($dir); $dir = opendir($path); unset($files); $files = array(); while ($file = readdir($dir)) { if (($file != ".") && ($file != "..") && preg_match("/\.xml$/i",$file)) { $files[$file] = filemtime($path."/".$file); } } arsort($files); if (count($files)) { foreach ($files as $file => $date) { $taille_fic = filesize($path."/".$file); echo "". "". "". ""; if (Session::haveRight('backup', PURGE)) { echo ""; } if (Session::haveRight('backup', CREATE)) { echo ""; } echo ""; } } closedir($dir); echo "
".__('File')."".__('Size')."".__('Date')." 
$file ".Toolbox::getSize($taille_fic)." " . Html::convDateTime(date("Y-m-d H:i",$date)) . " "; //TRANS: %s is the filename $string = sprintf(__('Delete the file %s?'), $file); Html::showSimpleForm($_SERVER['PHP_SELF'], 'delfile', _x('button', 'Delete permanently'), array('file' => $file),'','',$string); echo " "; // Multiple confirmation $string = array(); //TRANS: %s is the filename $string[] = array(sprintf(__('Replace the current database with the backup file %s?'), $file)); $string[] = array(__('Warning, your actual database will be totaly overwriten by the database you want to restore !!!')); echo "".__('Restore')."  ". "".__('Download'). "

$file ".Toolbox::getSize($taille_fic)." " . Html::convDateTime(date("Y-m-d H:i",$date)) . ""; //TRANS: %s is the filename $string = sprintf(__('Delete the file %s?'),$file); Html::showSimpleForm($_SERVER['PHP_SELF'], 'delfile', _x('button', 'Delete permanently'), array('file' => $file),'','',$string); echo " ". __('Download')."
"; echo "
"; Html::footer(); ?>