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 "";
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 "";
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 "
".
"".
"| ".__('File')." | ".
"".__('Size')." | ".
"".__('Date')." | ".
" | ".
"
";
$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 "| $file | ".
"".Toolbox::getSize($taille_fic)." | ".
" " . Html::convDateTime(date("Y-m-d H:i",$date)) . " | ";
if (Session::haveRight('backup', PURGE)) {
echo " ";
//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 " | ";
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')." | ";
}
if (Session::haveRight('backup', CREATE)) {
echo " ".
"".__('Download').
" | ";
}
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 "
|
".
"| $file | ".
"".Toolbox::getSize($taille_fic)." | ".
" " . Html::convDateTime(date("Y-m-d H:i",$date)) . " | ";
if (Session::haveRight('backup', PURGE)) {
echo "";
//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 " | ";
}
if (Session::haveRight('backup', CREATE)) {
echo " ".
__('Download')." | ";
}
echo "
";
}
}
closedir($dir);
echo "
";
echo "
";
Html::footer();
?>