websvn |
Subversion Repositories: |
Rev 1 | Rev 3 | |
---|---|---|
Line 23... | Line 23... | |
// Create gz/tar files of the requested item |
// Create gz/tar files of the requested item | |
|
| |
require_once("include/setup.php"); |
require_once("include/setup.php"); | |
require_once("include/svnlook.php"); |
require_once("include/svnlook.php"); | |
require_once("include/utils.php"); |
require_once("include/utils.php"); | |
| ||
ini_set('include_path', $locwebsvnreal.'/lib/pear'.$config->pathSeparator.ini_get('include_path')); | ||
@include_once("Archive/Tar.php"); | ||
| ||
function setDirectoryTimestamp($dir, $ts) { | ||
global $config; | ||
// changing the modification time of a directory under windows is only supported since php 5.3.0 | ||
if (!$config->serverIsWindows || version_compare(PHP_VERSION, '5.3.0alpha') !== -1) { | ||
touch($dir, $ts); | ||
| ||
$handle = opendir($dir); | ||
if ($handle) { | ||
while (($file = readdir($handle)) !== false) { | ||
if ($file == '.' || $file == '..') { | ||
continue; | ||
} | ||
$f = $dir.DIRECTORY_SEPARATOR.$file; | ||
if (is_dir($f)) { | ||
setDirectoryTimestamp($f, $ts); | ||
} | ||
} | ||
closedir($handle); | ||
} | ||
} | ||
} | ||
|
| |
function removeDirectory($dir) { |
function removeDirectory($dir) { | |
if (is_dir($dir)) { |
if (is_dir($dir)) { | |
$dir = rtrim($dir, '/'); |
$dir = rtrim($dir, '/'); | |
$handle = dir($dir); |
$handle = dir($dir); | |
Line 50... | Line 75... | |
} |
} | |
|
| |
// Make sure that this operation is allowed |
// Make sure that this operation is allowed | |
|
| |
if (!$rep->isDownloadAllowed($path)) { |
if (!$rep->isDownloadAllowed($path)) { | |
header('HTTP/1.x 403 Forbidden', true, 403); | ||
print 'Unable to download path '.$path."\n"; | ||
exit; |
exit; | |
} |
} | |
|
| |
$svnrep = new SVNRepository($rep); |
$svnrep = new SVNRepository($rep); | |
|
| |
// Fetch information about latest revision for this path |
// Fetch information about latest revision for this path | |
if (empty($rev)) { |
if (empty($rev)) { | |
$history = $svnrep->getLog($path, 'HEAD', '', true, 1); |
$history = $svnrep->getLog($path, 'HEAD', '', true, 1); | |
} else { |
} else { | |
$history = $svnrep->getLog($path, $rev, $rev - 1, true, 1); |
$history = $svnrep->getLog($path, $rev, $rev - 1, true, 1); | |
} | ||
if (is_string($history)) { | ||
echo $history; | ||
exit; | ||
} |
} | |
$logEntry = $history->entries[0]; |
$logEntry = $history->entries[0]; | |
|
| |
if (empty($rev)) { |
if (empty($rev)) { | |
$rev = $logEntry->rev; |
$rev = $logEntry->rev; | |
Line 76... | Line 107... | |
@unlink($tmpname); |
@unlink($tmpname); | |
|
| |
if (mkdir($tmpname)) { |
if (mkdir($tmpname)) { | |
// Get the name of the directory being archived |
// Get the name of the directory being archived | |
$arcname = $path; |
$arcname = $path; | |
if (substr($arcname, -1) == '/') { |
$isDir = (substr($arcname, -1) == '/'); | |
if ($isDir) { | ||
$arcname = substr($arcname, 0, -1); |
$arcname = substr($arcname, 0, -1); | |
} |
} | |
$arcname = basename($arcname); |
$arcname = basename($arcname); | |
if ($arcname == '') { |
if ($arcname == '') { | |
$arcname = $rep->name; |
$arcname = $rep->name; | |
} |
} | |
|
| |
$plainfilename = $arcname; | ||
$arcname = $arcname.'.r'.$rev; |
$arcname = $arcname.'.r'.$rev; | |
$tararc = $arcname.'.tar'; |
||
$gzarc = $arcname.'.tar.gz'; |
||
|
| |
$svnrep->exportDirectory($path, $tmpname.DIRECTORY_SEPARATOR.$arcname, $rev); |
$svnrep->exportDirectory($path, $tmpname.DIRECTORY_SEPARATOR.$arcname, $rev); | |
| ||
// Set datetime of exported directory (and subdirectories) to datetime of revision so that every archive is equal | ||
$date = $logEntry->date; | ||
$ts = mktime(substr($date, 11, 2), substr($date, 14, 2), substr($date, 17, 2), substr($date, 5, 2), substr($date, 8, 2), substr($date, 0, 4)); | ||
setDirectoryTimestamp($tmpname.DIRECTORY_SEPARATOR.$arcname, $ts); | ||
|
| |
// change to temp directory so that only relative paths are stored in tar |
// change to temp directory so that only relative paths are stored in tar | |
chdir($tmpname); |
chdir($tmpname); | |
|
| |
// Set datetime of exported and directory to datetime of revision |
if ($isDir) { | |
$date = $logEntry->date; |
$dlmode = $config->getDefaultFolderDlMode(); | |
$ts = substr($date, 0, 4).substr($date, 5, 2).substr($date, 8, 2).substr($date, 11, 2).substr($date, 14, 2).'.'.substr($date, 17, 2); |
} else { | |
exec(quoteCommand($config->touch.' -t '.$ts.' '.quote($tmpname.DIRECTORY_SEPARATOR.$arcname))); |
$dlmode = $config->getDefaultFileDlMode(); | |
} | ||
|
| |
// Create the tar file |
// $_REQUEST parameter can override dlmode | |
exec(quoteCommand($config->tar.' -cf '.quote($tmpname.DIRECTORY_SEPARATOR.$tararc).' '.quote($arcname))); |
if (!empty($_REQUEST['dlmode'])) { | |
$dlmode = $_REQUEST['dlmode']; | ||
if (substr($logEntry->path, -1) == '/') { | ||
if (!in_array($dlmode, $config->validFolderDlModes)) { | ||
$dlmode = $config->getDefaultFolderDlMode(); | ||
} | ||
} else { | ||
if (!in_array($dlmode, $config->validFileDlModes)) { | ||
$dlmode = $config->getDefaultFileDlMode(); | ||
} | ||
} | ||
} | ||
|
| |
// Set datetime of tar file to datetime of revision |
if ($dlmode == 'plain') { | |
exec(quoteCommand($config->touch.' -t '.$ts.' '.quote($tmpname.DIRECTORY_SEPARATOR.$tararc))); |
$dlarc = $arcname; | |
$dlmime = 'application/octetstream'; | ||
|
| |
// ZIP it up |
} else if ($dlmode == 'zip') { | |
exec(quoteCommand($config->gzip.' '.quote($tmpname.DIRECTORY_SEPARATOR.$tararc))); |
$dlarc = $arcname.'.zip'; | |
$dlmime = 'application/x-zip'; | ||
// Create zip file | ||
$cmd = $config->zip.' -r '.quote($dlarc).' '.quote($arcname); | ||
execCommand($cmd, $retcode); | ||
if ($retcode != 0) { | ||
print'Unable to call zip command "'.$config->zip.'"'; | ||
} | ||
| ||
} else { | ||
$tararc = $arcname.'.tar'; | ||
$dlarc = $arcname.'.tar.gz'; | ||
$dlmime = 'application/x-gzip'; | ||
| ||
// Create the tar file | ||
$retcode = 0; | ||
if (class_exists('Archive_Tar')) { | ||
$tar = new Archive_Tar($tararc); | ||
$created = $tar->create($arcname); | ||
if (!$created) { | ||
$retcode = 1; | ||
print'Unable to create tar archive'; | ||
} | ||
| ||
} else { | ||
$cmd = $config->tar.' -cf '.quote($tararc).' '.quote($arcname); | ||
execCommand($cmd, $retcode); | ||
if ($retcode != 0) { | ||
print'Unable to call tar command "'.$config->tar.'"'; | ||
} | ||
} | ||
if ($retcode != 0) { | ||
chdir('..'); | ||
removeDirectory($tmpname); | ||
exit(0); | ||
} | ||
| ||
// Set datetime of tar file to datetime of revision | ||
touch($tararc, $ts); | ||
| ||
// GZIP it up | ||
if (function_exists('gzopen')) { | ||
$srcHandle = fopen($tmpname.DIRECTORY_SEPARATOR.$tararc, 'rb'); | ||
$dstHandle = gzopen($tmpname.DIRECTORY_SEPARATOR.$dlarc, 'wb'); | ||
if (!$srcHandle || !$dstHandle) { | ||
print'Unable to open file for gz-compression'; | ||
chdir('..'); | ||
removeDirectory($tmpname); | ||
exit(0); | ||
} | ||
while (!feof($srcHandle)) { | ||
gzwrite($dstHandle, fread($srcHandle, 1024 * 512)); | ||
} | ||
fclose($srcHandle); | ||
gzclose($dstHandle); | ||
| ||
} else { | ||
$cmd = $config->gzip.' '.quote($tararc); | ||
$retcode = 0; | ||
execCommand($cmd, $retcode); | ||
if ($retcode != 0) { | ||
print'Unable to call gzip command "'.$config->gzip.'"'; | ||
chdir('..'); | ||
removeDirectory($tmpname); | ||
exit(0); | ||
} | ||
} | ||
} | ||
|
| |
// Give the file to the browser |
// Give the file to the browser | |
if (is_readable($tmpname.DIRECTORY_SEPARATOR.$gzarc)) { |
if (is_readable($dlarc)) { | |
$size = filesize($tmpname.DIRECTORY_SEPARATOR.$gzarc); |
$size = filesize($dlarc); | |
|
| |
header('Content-Type: application/x-gzip'); |
if ($dlmode == 'plain') { | |
$dlfilename = $plainfilename; | ||
} else { | ||
$dlfilename = $rep->name.'-'.$dlarc; | ||
} | ||
| ||
header('Content-Type: '.$dlmime); | ||
header('Content-Length: '.$size); |
header('Content-Length: '.$size); | |
header('Content-Disposition: attachment; filename="'.$rep->name.'-'.$gzarc.'"'); |
header('Content-Disposition: attachment; filename="'. $dlfilename .'"'); | |
| ||
readfile($dlarc); | ||
|
| |
readfile($tmpname.DIRECTORY_SEPARATOR.$gzarc); |
||
} else { |
} else { | |
print'Unable to open file '.$gzarc; |
header('HTTP/1.x 404 Not Found', true, 404); | |
| ||
print 'Unable to open file '.$dlarc."\n"; | ||
} |
} | |
|
| |
chdir('..'); |
chdir('..'); | |
|
| |
removeDirectory($tmpname); |
removeDirectory($tmpname); |