2
0
forked from Wavyzz/dolibarr

FIX Several pb in export of documents

FIX Must escape shell
FIX Must exclude logs and some dirs for compressed backup
FIX gzip and bzip2 must use option -f
This commit is contained in:
Laurent Destailleur
2019-09-03 22:39:24 +02:00
parent 84800257e8
commit 0a17e6bfd5
4 changed files with 70 additions and 36 deletions

View File

@@ -50,10 +50,20 @@ if (! $user->admin)
if ($action == 'delete') if ($action == 'delete')
{ {
$file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha')); if (preg_match('/^backup\//', GETPOST('urlfile', 'alpha')))
$ret=dol_delete_file($file, 1); {
if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); $file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha'));
else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); $ret=dol_delete_file($file, 1);
if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
}
else
{
$file=$conf->admin->dir_output.'/documents/'.basename(GETPOST('urlfile', 'alpha'));
$ret=dol_delete_file($file, 1);
if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
}
$action=''; $action='';
} }
@@ -577,7 +587,7 @@ print "\n";
?> ?>
<br> <br>
<div class="center"><input type="submit" class="button" <div class="center"><input type="submit" class="button reposition"
value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br> value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br>
<br> <br>
</div> </div>

View File

@@ -112,21 +112,27 @@ $utils = new Utils($db);
if ($compression == 'zip') if ($compression == 'zip')
{ {
$ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression); $ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression, '/(\.log|\/temp\/|documents\/admin\/documents\/)/');
if ($ret < 0) if ($ret < 0)
{ {
$errormsg = $langs->trans("ErrorFailedToWriteInDir", $outputfile); $errormsg = $langs->trans("ErrorFailedToWriteInDir", $outputdir);
} }
} }
elseif (in_array($compression, array('gz', 'bz'))) elseif (in_array($compression, array('gz', 'bz')))
{ {
$file = substr($file, 0, strrpos($file, '.')); $userlogin = ($user->login ? $user->login : 'unknown');
$outputfile = $conf->admin->dir_temp.'/export_files.'.$userlogin.'.out'; // File used with popen method
$file = substr($file, 0, strrpos($file, '.'));
$file .= '.tar'; $file .= '.tar';
$cmd = 'tar -cf '.$outputdir."/".$file." --exclude=documents/admin/documents -C ".DOL_DATA_ROOT." ".DOL_DATA_ROOT."/../documents/"; // We also exclude '/temp/' dir and 'documents/admin/documents'
exec($cmd, $out, $retval); $cmd = "tar -cf ".$outputdir."/".$file." --exclude-vcs --exclude 'temp' --exclude 'dolibarr.log' --exclude='documents/admin/documents' -C ".dirname(DOL_DATA_ROOT)." ".basename(DOL_DATA_ROOT);
//var_dump($cmd, DOL_DATA_ROOT);exit;
$result = $utils->executeCLI($cmd, $outputfile);
if ($retval != 0)
$retval = $result['error'];
if ($result['result'] || ! empty($retval))
{ {
$langs->load("errors"); $langs->load("errors");
dol_syslog("Documents tar retval after exec=".$retval, LOG_ERR); dol_syslog("Documents tar retval after exec=".$retval, LOG_ERR);
@@ -136,15 +142,17 @@ elseif (in_array($compression, array('gz', 'bz')))
{ {
if ($compression == 'gz') if ($compression == 'gz')
{ {
$cmd = "gzip " . $outputdir."/".$file; $cmd = "gzip -f " . $outputdir."/".$file;
} }
if ($compression == 'bz') if ($compression == 'bz')
{ {
$cmd = "bzip2 " . $outputdir."/".$file; $cmd = "bzip2 -f " . $outputdir."/".$file;
} }
exec($cmd, $out, $retval); $result = $utils->executeCLI($cmd, $outputfile);
if ($retval != 0)
$retval = $result['error'];
if ($result['result'] || ! empty($retval))
{ {
$errormsg = 'Error '.$compression.' generation return '.$retval; $errormsg = 'Error '.$compression.' generation return '.$retval;
unlink($outputdir."/".$file); unlink($outputdir."/".$file);

View File

@@ -316,27 +316,29 @@ class Utils
// TODO Replace with executeCLI function // TODO Replace with executeCLI function
if ($execmethod == 1) if ($execmethod == 1)
{ {
exec($fullcommandclear, $readt, $retval); $output_arr = array(); $retval = null;
$result = $retval; exec($fullcommandclear, $output_arr, $retval);
if ($retval != 0) if ($retval != 0)
{ {
$langs->load("errors"); $langs->load("errors");
dol_syslog("Datadump retval after exec=".$retval, LOG_ERR); dol_syslog("Datadump retval after exec=".$retval, LOG_ERR);
$error = 'Error '.$retval; $errormsg = 'Error '.$retval;
$ok=0; $ok=0;
} }
else else
{ {
$i=0; $i=0;
if (!empty($readt)) if (!empty($output_arr))
foreach($readt as $key=>$read)
{ {
$i++; // output line number foreach($output_arr as $key => $read)
if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; {
fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); $i++; // output line number
if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) $ok=1; if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue;
elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) $ok=1; fwrite($handle, $read.($execmethod == 2 ? '' : "\n"));
if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) $ok=1;
elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) $ok=1;
}
} }
} }
} }
@@ -534,6 +536,7 @@ class Utils
if ($execmethod == 1) if ($execmethod == 1)
{ {
$retval = null;
exec($command, $output_arr, $retval); exec($command, $output_arr, $retval);
$result = $retval; $result = $retval;
if ($retval != 0) if ($retval != 0)
@@ -545,7 +548,6 @@ class Utils
} }
if ($execmethod == 2) // With this method, there is no way to get the return code, only output if ($execmethod == 2) // With this method, there is no way to get the return code, only output
{ {
$ok=0;
$handle = fopen($outputfile, 'w+b'); $handle = fopen($outputfile, 'w+b');
if ($handle) if ($handle)
{ {

View File

@@ -1221,9 +1221,12 @@ function dol_delete_file($file, $disableglob = 0, $nophperrors = 0, $nohook = 0,
} }
} }
} }
else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); else
// TODO Failure to remove can be because file was already removed or because of permission {
// If error because it does not exists, we should return true, and we should return false if this is a permission problem dol_syslog("Failed to remove file ".$filename, LOG_WARNING);
// TODO Failure to remove can be because file was already removed or because of permission
// If error because it does not exists, we should return true, and we should return false if this is a permission problem
}
} }
} }
else dol_syslog("No files to delete found", LOG_DEBUG); else dol_syslog("No files to delete found", LOG_DEBUG);
@@ -2062,9 +2065,10 @@ function dol_uncompress($inputfile, $outputdir)
* @param string $inputdir Source dir name * @param string $inputdir Source dir name
* @param string $outputfile Target file name (output directory must exists and be writable) * @param string $outputfile Target file name (output directory must exists and be writable)
* @param string $mode 'zip' * @param string $mode 'zip'
* @param string $excludefiles A regex pattern. For example: '/\.log$|\/temp\//'
* @return int <0 if KO, >0 if OK * @return int <0 if KO, >0 if OK
*/ */
function dol_compress_dir($inputdir, $outputfile, $mode = "zip") function dol_compress_dir($inputdir, $outputfile, $mode = "zip", $excludefiles = '')
{ {
$foundhandler=0; $foundhandler=0;
@@ -2095,6 +2099,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode = "zip")
return 1; return 1;
} }
else*/ else*/
//if (class_exists('ZipArchive') && ! empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_COMPRESS))
if (class_exists('ZipArchive')) if (class_exists('ZipArchive'))
{ {
$foundhandler=1; $foundhandler=1;
@@ -2102,6 +2107,13 @@ function dol_compress_dir($inputdir, $outputfile, $mode = "zip")
// Initialize archive object // Initialize archive object
$zip = new ZipArchive(); $zip = new ZipArchive();
$result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE);
if (! $result)
{
global $langs, $errormsg;
$langs->load("errors");
$errormsg=$langs->trans("ErrorFailedToWriteInFile", $outputfile);
return -4;
}
// Create recursive directory iterator // Create recursive directory iterator
/** @var SplFileInfo[] $files */ /** @var SplFileInfo[] $files */
@@ -2118,9 +2130,11 @@ function dol_compress_dir($inputdir, $outputfile, $mode = "zip")
// Get real and relative path for current file // Get real and relative path for current file
$filePath = $file->getRealPath(); $filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($inputdir) + 1); $relativePath = substr($filePath, strlen($inputdir) + 1);
if (empty($excludefiles) || ! preg_match($excludefiles, $filePath))
// Add current file to archive {
$zip->addFile($filePath, $relativePath); // Add current file to archive
$zip->addFile($filePath, $relativePath);
}
} }
} }