Skip to content

Commit

Permalink
added check if temporary files can be created and proper message in c…
Browse files Browse the repository at this point in the history
…ase of problems
  • Loading branch information
dirk-thomas committed Apr 29, 2011
1 parent 3f3fedf commit bb82221
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 144 deletions.
4 changes: 2 additions & 2 deletions blame.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@
$vars['javascript'] = '';
} else {
// Get the contents of the file
$tfname = tempnam($config->getTempDir(), '');
$tfname = tempnamWithCheck($config->getTempDir(), '');
$highlighted = $svnrep->getFileContents($path, $tfname, $rev, $peg, '', 'line');

if ($file = fopen($tfname, 'r')) {
// Get the blame info
$tbname = tempnam($config->getTempDir(), '');
$tbname = tempnamWithCheck($config->getTempDir(), '');

$svnrep->getBlameDetails($path, $tbname, $rev, $peg);

Expand Down
4 changes: 2 additions & 2 deletions diff.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@
}

// Get the contents of the two files
$newerFile = tempnam($config->getTempDir(), '');
$newerFile = tempnamWithCheck($config->getTempDir(), '');
$newerFileHl = $newerFile.'highlight';
$normalNew = $svnrep->getFileContents($history->entries[0]->path, $newerFile, $history->entries[0]->rev, $peg, '', 'no');
$highlightedNew = $svnrep->getFileContents($history->entries[0]->path, $newerFileHl, $history->entries[0]->rev, $peg, '', 'line');

$olderFile = tempnam($config->getTempDir(), '');
$olderFile = tempnamWithCheck($config->getTempDir(), '');
$olderFileHl = $olderFile.'highlight';
$normalOld = $svnrep->getFileContents($history->entries[0]->path, $olderFile, $history->entries[1]->rev, $peg, '', 'no');
$highlightedOld = $svnrep->getFileContents($history->entries[0]->path, $olderFileHl, $history->entries[1]->rev, $peg, '', 'line');
Expand Down
264 changes: 128 additions & 136 deletions dl.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,171 +103,163 @@ function removeDirectory($dir) {

// Create a temporary filename to be used for a directory to archive a download.
// Here we have an unavoidable but highly unlikely to occur race condition.
$tempDir = tempnam($config->getTempDir(), 'websvn');
$tempDir = tempnamWithCheck($config->getTempDir(), 'websvn');

if ($tempDir == false) {
@unlink($tempDir);
mkdir($tempDir);
// Create the name of the directory being archived
$archiveName = $path;
$isDir = (substr($archiveName, -1) == '/');
if ($isDir) {
$archiveName = substr($archiveName, 0, -1);
}
$archiveName = basename($archiveName);
if ($archiveName == '') {
$archiveName = $rep->name;
}
$plainfilename = $archiveName;
$archiveName .= '.r'.$rev;

// Export the requested path from SVN repository to the temp directory
$svnExportResult = $svnrep->exportRepositoryPath($path, $tempDir.DIRECTORY_SEPARATOR.$archiveName, $rev, $peg);
if ($svnExportResult != 0) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('Unable to create a temporary directory.');
print 'Unable to create a temporary directory.';
error_log('svn export failed for: '.$archiveName);
print 'svn export failed for "'.xml_entities($archiveName).'".';
removeDirectory($tempDir);
exit(0);
}

// Set timestamp of exported directory (and subdirectories) to timestamp of
// the revision so every archive of a given revision has the same timestamp.
$revDate = $logEntry->date;
$timestamp = mktime(substr($revDate, 11, 2), // hour
substr($revDate, 14, 2), // minute
substr($revDate, 17, 2), // second
substr($revDate, 5, 2), // month
substr($revDate, 8, 2), // day
substr($revDate, 0, 4)); // year
setDirectoryTimestamp($tempDir, $timestamp);

// Change to temp directory so that only relative paths are stored in archive.
$oldcwd = getcwd();
chdir($tempDir);

if ($isDir) {
$downloadMode = $config->getDefaultFolderDlMode();
} else {
@unlink($tempDir);
mkdir($tempDir);
// Create the name of the directory being archived
$archiveName = $path;
$isDir = (substr($archiveName, -1) == '/');
if ($isDir) {
$archiveName = substr($archiveName, 0, -1);
}
$archiveName = basename($archiveName);
if ($archiveName == '') {
$archiveName = $rep->name;
$downloadMode = $config->getDefaultFileDlMode();
}

// $_REQUEST parameter can override dlmode
if (!empty($_REQUEST['dlmode'])) {
$downloadMode = $_REQUEST['dlmode'];
if (substr($logEntry->path, -1) == '/') {
if (!in_array($downloadMode, $config->validFolderDlModes)) {
$downloadMode = $config->getDefaultFolderDlMode();
}
} else {
if (!in_array($downloadMode, $config->validFileDlModes)) {
$downloadMode = $config->getDefaultFileDlMode();
}
}
$plainfilename = $archiveName;
$archiveName .= '.r'.$rev;
}

// Export the requested path from SVN repository to the temp directory
$svnExportResult = $svnrep->exportRepositoryPath($path, $tempDir.DIRECTORY_SEPARATOR.$archiveName, $rev, $peg);
if ($svnExportResult != 0) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('svn export failed for: '.$archiveName);
print 'svn export failed for "'.xml_entities($archiveName).'".';
removeDirectory($tempDir);
exit(0);
$downloadArchive = $archiveName;
if ($downloadMode == 'plain') {
$downloadMimeType = 'application/octetstream';

} else if ($downloadMode == 'zip') {
$downloadMimeType = 'application/x-zip';
$downloadArchive .= '.zip';
// Create zip file
$cmd = $config->zip.' -r '.quote($downloadArchive).' '.quote($archiveName);
execCommand($cmd, $retcode);
if ($retcode != 0) {
error_log('Unable to call zip command: '.$cmd);
print 'Unable to call zip command. See webserver error log for details.';
}

// Set timestamp of exported directory (and subdirectories) to timestamp of
// the revision so every archive of a given revision has the same timestamp.
$revDate = $logEntry->date;
$timestamp = mktime(substr($revDate, 11, 2), // hour
substr($revDate, 14, 2), // minute
substr($revDate, 17, 2), // second
substr($revDate, 5, 2), // month
substr($revDate, 8, 2), // day
substr($revDate, 0, 4)); // year
setDirectoryTimestamp($tempDir, $timestamp);
} else {
$downloadMimeType = 'application/x-gzip';
$downloadArchive .= '.tar.gz';
$tarArchive = $archiveName.'.tar';

// Change to temp directory so that only relative paths are stored in archive.
$oldcwd = getcwd();
chdir($tempDir);
// Create the tar file
$retcode = 0;
if (class_exists('Archive_Tar')) {
$tar = new Archive_Tar($tarArchive);
$created = $tar->create(array($archiveName));
if (!$created) {
$retcode = 1;
header('HTTP/1.x 500 Internal Server Error', true, 500);
print 'Unable to create tar archive.';
}

if ($isDir) {
$downloadMode = $config->getDefaultFolderDlMode();
} else {
$downloadMode = $config->getDefaultFileDlMode();
}

// $_REQUEST parameter can override dlmode
if (!empty($_REQUEST['dlmode'])) {
$downloadMode = $_REQUEST['dlmode'];
if (substr($logEntry->path, -1) == '/') {
if (!in_array($downloadMode, $config->validFolderDlModes)) {
$downloadMode = $config->getDefaultFolderDlMode();
}
} else {
if (!in_array($downloadMode, $config->validFileDlModes)) {
$downloadMode = $config->getDefaultFileDlMode();
}
$cmd = $config->tar.' -cf '.quote($tarArchive).' '.quote($archiveName);
execCommand($cmd, $retcode);
if ($retcode != 0) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('Unable to call tar command: '.$cmd);
print 'Unable to call tar command. See webserver error log for details.';
}
}
if ($retcode != 0) {
chdir($oldcwd);
removeDirectory($tempDir);
exit(0);
}

$downloadArchive = $archiveName;
if ($downloadMode == 'plain') {
$downloadMimeType = 'application/octetstream';
// Set timestamp of tar file to timestamp of revision
touch($tarArchive, $timestamp);

} else if ($downloadMode == 'zip') {
$downloadMimeType = 'application/x-zip';
$downloadArchive .= '.zip';
// Create zip file
$cmd = $config->zip.' -r '.quote($downloadArchive).' '.quote($archiveName);
execCommand($cmd, $retcode);
if ($retcode != 0) {
error_log('Unable to call zip command: '.$cmd);
print 'Unable to call zip command. See webserver error log for details.';
// GZIP it up
if (function_exists('gzopen')) {
$srcHandle = fopen($tarArchive, 'rb');
$dstHandle = gzopen($downloadArchive, 'wb');
if (!$srcHandle || !$dstHandle) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
print 'Unable to open file for gz-compression.';
chdir($oldcwd);
removeDirectory($tempDir);
exit(0);
}
while (!feof($srcHandle)) {
gzwrite($dstHandle, fread($srcHandle, 1024 * 512));
}
fclose($srcHandle);
gzclose($dstHandle);

} else {
$downloadMimeType = 'application/x-gzip';
$downloadArchive .= '.tar.gz';
$tarArchive = $archiveName.'.tar';

// Create the tar file
$cmd = $config->gzip.' '.quote($tarArchive);
$retcode = 0;
if (class_exists('Archive_Tar')) {
$tar = new Archive_Tar($tarArchive);
$created = $tar->create(array($archiveName));
if (!$created) {
$retcode = 1;
header('HTTP/1.x 500 Internal Server Error', true, 500);
print 'Unable to create tar archive.';
}

} else {
$cmd = $config->tar.' -cf '.quote($tarArchive).' '.quote($archiveName);
execCommand($cmd, $retcode);
if ($retcode != 0) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('Unable to call tar command: '.$cmd);
print 'Unable to call tar command. See webserver error log for details.';
}
}
execCommand($cmd, $retcode);
if ($retcode != 0) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('Unable to call gzip command: '.$cmd);
print 'Unable to call gzip command. See webserver error log for details.';
chdir($oldcwd);
removeDirectory($tempDir);
exit(0);
}

// Set timestamp of tar file to timestamp of revision
touch($tarArchive, $timestamp);

// GZIP it up
if (function_exists('gzopen')) {
$srcHandle = fopen($tarArchive, 'rb');
$dstHandle = gzopen($downloadArchive, 'wb');
if (!$srcHandle || !$dstHandle) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
print 'Unable to open file for gz-compression.';
chdir($oldcwd);
removeDirectory($tempDir);
exit(0);
}
while (!feof($srcHandle)) {
gzwrite($dstHandle, fread($srcHandle, 1024 * 512));
}
fclose($srcHandle);
gzclose($dstHandle);

} else {
$cmd = $config->gzip.' '.quote($tarArchive);
$retcode = 0;
execCommand($cmd, $retcode);
if ($retcode != 0) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('Unable to call gzip command: '.$cmd);
print 'Unable to call gzip command. See webserver error log for details.';
chdir($oldcwd);
removeDirectory($tempDir);
exit(0);
}
}
}
}

// Give the file to the browser
if (is_readable($downloadArchive)) {
if ($downloadMode == 'plain') {
$downloadFilename = $plainfilename;
} else {
$downloadFilename = $rep->name.'-'.$downloadArchive;
}
header('Content-Type: '.$downloadMimeType);
header('Content-Length: '.filesize($downloadArchive));
header('Content-Disposition: attachment; filename="'. $downloadFilename .'"');
readfile($downloadArchive);
// Give the file to the browser
if (is_readable($downloadArchive)) {
if ($downloadMode == 'plain') {
$downloadFilename = $plainfilename;
} else {
header('HTTP/1.x 404 Not Found', true, 404);
print 'Unable to open file: '.xml_entities($downloadArchive);
$downloadFilename = $rep->name.'-'.$downloadArchive;
}
header('Content-Type: '.$downloadMimeType);
header('Content-Length: '.filesize($downloadArchive));
header('Content-Disposition: attachment; filename="'. $downloadFilename .'"');
readfile($downloadArchive);
} else {
header('HTTP/1.x 404 Not Found', true, 404);
print 'Unable to open file: '.xml_entities($downloadArchive);
}

chdir($oldcwd);
Expand Down
10 changes: 6 additions & 4 deletions include/svnlook.php
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ function getFileContents($path, $filename, $rev = 0, $peg = '', $pipe = '', $hig

$tempname = $filename;
if ($highlight == 'line') {
$tempname = tempnam($config->getTempDir(), '');
$tempname = tempnamWithCheck($config->getTempDir(), '');
}
$highlighted = true;
if ($highlight != 'no' && $config->useGeshi && $geshiLang = $this->highlightLanguageUsingGeshi($ext)) {
Expand Down Expand Up @@ -810,9 +810,11 @@ function listFileContents($path, $rev = 0, $peg = '') {
$ext = strrchr($path, '.');

if ($config->useGeshi && $geshiLang = $this->highlightLanguageUsingGeshi($ext)) {
$tempname = tempnam($config->getTempDir(), 'wsvn');
print toOutputEncoding($this->applyGeshi($path, $tempname, $geshiLang, $rev, $peg, true));
@unlink($tempname);
$tempname = tempnamWithCheck($config->getTempDir(), 'wsvn');
if ($tempname !== false) {
print toOutputEncoding($this->applyGeshi($path, $tempname, $geshiLang, $rev, $peg, true));
@unlink($tempname);
}
} else {
$pre = false;
$cmd = $this->svnCommandString('cat', $path, $rev, $peg);
Expand Down
18 changes: 18 additions & 0 deletions include/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,21 @@ function getUserLanguage($languages, $default, $userchoice) {
}

// }}}

function tempnamWithCheck($dir, $prefix) {
$tmp = tempnam($dir, $prefix);

if ($tmp == false) {
if (!headers_sent()) {
header('HTTP/1.x 500 Internal Server Error', true, 500);
error_log('Unable to create a temporary file. Either make the currently used folder ("' . $dir . '") writable for WebSVN or change the folder in the configuration.');
print 'Unable to create a temporary file. Either make the currently used folder writable for WebSVN or change the folder in the configuration.';
exit(0);
} else {
global $vars;
$vars['warning'] = 'Unable to create a temporary file. Either make the currently used folder writable for WebSVN or change the folder in the configuration.';
}
}

return $tmp;
}

0 comments on commit bb82221

Please sign in to comment.