Attempt to fix write permission issues in certain environments
authorAlexander Ebert <ebert@woltlab.com>
Thu, 30 May 2013 13:44:19 +0000 (15:44 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 30 May 2013 13:44:19 +0000 (15:44 +0200)
12 files changed:
wcfsetup/install.php
wcfsetup/install/files/lib/acp/form/MasterPasswordInitForm.class.php
wcfsetup/install/files/lib/action/GravatarDownloadAction.class.php
wcfsetup/install/files/lib/data/language/LanguageEditor.class.php
wcfsetup/install/files/lib/data/option/OptionEditor.class.php
wcfsetup/install/files/lib/data/style/StyleEditor.class.php
wcfsetup/install/files/lib/data/template/TemplateEditor.class.php
wcfsetup/install/files/lib/system/io/Tar.class.php
wcfsetup/install/files/lib/system/io/Zip.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/system/setup/Installer.class.php
wcfsetup/install/files/lib/util/FileUtil.class.php

index eafce16a5b50e96287b99c4463b163efbde7542e..22aa4fc1f89cbe74ef7e8d71b9d480ebcee96a77 100644 (file)
@@ -233,7 +233,7 @@ class BasicFileUtil {
                if (!empty($_SERVER['DOCUMENT_ROOT'])) {
                        if (!@file_exists($_SERVER['DOCUMENT_ROOT'].'/tmp/'.$tmpDirName)) {
                                @mkdir($_SERVER['DOCUMENT_ROOT'].'/tmp/'.$tmpDirName, 0777, true);
-                               @chmod($_SERVER['DOCUMENT_ROOT'].'/tmp/'.$tmpDirName, 0777);
+                               self::makeWritable($_SERVER['DOCUMENT_ROOT'].'/tmp/'.$tmpDirName);
                        }
                        
                        if (@file_exists($_SERVER['DOCUMENT_ROOT'].'/tmp/'.$tmpDirName) && @is_writable($_SERVER['DOCUMENT_ROOT'].'/tmp/'.$tmpDirName)) {
@@ -245,7 +245,7 @@ class BasicFileUtil {
                        if (isset($_ENV[$tmpDir]) && @is_writable($_ENV[$tmpDir])) {
                                $dir = $_ENV[$tmpDir] . '/' . $tmpDirName;
                                @mkdir($dir, 0777);
-                               @chmod($dir, 0777);
+                               self::makeWritable($dir);
                                
                                if (@file_exists($dir) && @is_writable($dir)) {
                                        return $dir;
@@ -255,7 +255,7 @@ class BasicFileUtil {
                
                $dir = INSTALL_SCRIPT_DIR . 'tmp/' . $tmpDirName;
                @mkdir($dir, 0777);
-               @chmod($dir, 0777);
+               self::makeWritable($dir);
                
                if (!@file_exists($dir) || !@is_writable($dir)) {
                        $tmpDir = explode('/', $dir);
@@ -267,6 +267,37 @@ class BasicFileUtil {
                
                return $dir;
        }
+       
+       /**
+        * Tries to make a file or directory writable. It starts of with the least
+        * permissions and goes up until 0777.
+        *
+        * @param       string          $filename
+        */
+       public static function makeWritable($filename) {
+               if (is_writable($filename)) {
+                       return;
+               }
+               
+               $chmods = array('0644', '0755', '0775', '0777');
+               
+               $startIndex = 0;
+               if (is_dir($filename)) {
+                       $startIndex = 1;
+               }
+               
+               for ($i = $startIndex; $i < 4; $i++) {
+                       @chmod($filename, octdec($chmods[$i]));
+                       
+                       if (is_writable($filename)) {
+                               break;
+                       }
+                       else if ($i == 3) {
+                               // does not work with 0777
+                               throw new SystemException("Unable to make '".$filename."' writable. This is a misconfiguration of your server, please contact your system administrator or hosting provider.");
+                       }
+               }
+       }
 }
 
 /**
@@ -465,12 +496,7 @@ class Tar {
                }
                
                $targetFile->close();
-               if (function_exists('apache_get_version') || !@$targetFile->is_writable()) {
-                       @$targetFile->chmod(0777);
-               }
-               else {
-                       @$targetFile->chmod(0755);
-               }
+               BasicFileUtil::makeWritable($destination);
                
                if ($header['mtime']) {
                        @$targetFile->touch($header['mtime']);
@@ -788,7 +814,7 @@ if (!file_exists(TMP_DIR . 'install/files/lib/system/WCFSetup.class.php')) {
                                $dir = TMP_DIR . dirname($file['filename']);
                                if (!@is_dir($dir)) {
                                        @mkdir($dir, 0777, true);
-                                       @chmod($dir, 0777);
+                                       BasicFileUtil::makeWritable($dir);
                                }
                                
                                $tar->extract($file['index'], TMP_DIR . $file['filename']);
@@ -799,10 +825,10 @@ if (!file_exists(TMP_DIR . 'install/files/lib/system/WCFSetup.class.php')) {
        
        // create cache folders
        @mkdir(TMP_DIR . 'setup/lang/cache/', 0777);
-       @chmod(TMP_DIR . 'setup/lang/cache/', 0777);
+       BasicFileUtil::makeWritable(TMP_DIR . 'setup/lang/cache/');
        
        @mkdir(TMP_DIR . 'setup/template/compiled/', 0777);
-       @chmod(TMP_DIR . 'setup/template/compiled/', 0777);
+       BasicFileUtil::makeWritable(TMP_DIR . 'setup/template/compiled/');
 }
 
 if (!class_exists('wcf\system\WCFSetup')) {
index a6f7724a9d380af9ff8cc6e2b1acbfa13464e81a..1b4c377d789b7bd4638a484c9ac94fc1a712d61e 100755 (executable)
@@ -6,6 +6,7 @@ use wcf\system\exception\UserInputException;
 use wcf\system\io\File;
 use wcf\system\Regex;
 use wcf\system\WCF;
+use wcf\util\FileUtil;
 use wcf\util\PasswordUtil;
 use wcf\util\StringUtil;
 
@@ -108,7 +109,7 @@ DO NOT EDIT THIS FILE */
 define('MASTER_PASSWORD', '".PasswordUtil::getDoubleSaltedHash($this->masterPassword)."');
 ?>");
                $file->close();
-               @chmod(WCF_DIR.'acp/masterPassword.inc.php', 0777);
+               FileUtil::makeWritable(WCF_DIR.'acp/masterPassword.inc.php');
                
                parent::save();
        }
index 1d568a11632b73208edaf0df6c555e73739b4096..f0c6ec1a29ed7fbbfffdd09e490d4c63c7bb84b3 100644 (file)
@@ -73,7 +73,7 @@ class GravatarDownloadAction extends AbstractAction {
                                $tmpFile = FileUtil::downloadFileFromHttp($gravatarURL, 'gravatar');
                                copy($tmpFile, WCF_DIR.$cachedFilename);
                                @unlink($tmpFile);
-                               @chmod(WCF_DIR.$cachedFilename, 0777);
+                               FileUtil::makeWritable(WCF_DIR.$cachedFilename);
                                
                                @header('Content-Type: image/png');
                                @readfile(WCF_DIR.$cachedFilename);
index 680756d3a42171e2227b543bcfebdb62489a3e4d..735b5dd12edcf93674a9ee5fdb320cb490ad1dea 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\data\language;
+use wcf\util\FileUtil;
+
 use wcf\data\language\category\LanguageCategory;
 use wcf\data\language\category\LanguageCategoryEditor;
 use wcf\data\language\item\LanguageItemEditor;
@@ -95,8 +97,9 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje
                                }
                        }
                        
-                       $file = new File(WCF_DIR.'language/'.$this->languageID.'_'.$category->languageCategory.'.php');
-                       @$file->chmod(0777);
+                       $filename = WCF_DIR.'language/'.$this->languageID.'_'.$category->languageCategory.'.php';
+                       $file = new File($filename);
+                       FileUtil::makeWritable($filename);
                        $file->write($content . '?>');
                        $file->close();
                }
index c57bbfd5c0bdb728d7e6a9509fa06f7d64f6670f..ae88e2fd9c9d98a86fa676aad6daee5a98fd4f81 100644 (file)
@@ -6,6 +6,7 @@ use wcf\system\cache\builder\OptionCacheBuilder;
 use wcf\system\cache\CacheHandler;
 use wcf\system\io\File;
 use wcf\system\WCF;
+use wcf\util\FileUtil;
 
 /**
  * Provides functions to edit options.
@@ -138,6 +139,6 @@ class OptionEditor extends DatabaseObjectEditor implements IEditableCachedObject
                
                // close file
                $file->close();
-               @$file->chmod(0777);
+               FileUtil::makeWritable(WCF_DIR.'options.inc.php');
        }
 }
index 9901acc1f313a6cae60eacbe6a794ba3b9f03c7c..4538256192ab482570c3ccfd457c2a54e55e68be 100644 (file)
@@ -365,7 +365,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                                foreach ($contentList as $key => $val) {
                                        if ($val['type'] == 'file') {
                                                $imagesTar->extract($key, $imagesLocation.basename($val['filename']));
-                                               @chmod($imagesLocation.basename($val['filename']), 0666);
+                                               FileUtil::makeWritable($imagesLocation.basename($val['filename']));
                                        }
                                }
                                
@@ -417,7 +417,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                                                // create template path
                                                if (!file_exists($templatesDir)) {
                                                        @mkdir($templatesDir, 0777);
-                                                       @chmod($templatesDir, 0777);
+                                                       FileUtil::makeWritable($templatesDir);
                                                }
                                                
                                                // copy templates
@@ -456,7 +456,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        if ($index !== false) {
                                $filename = WCF_DIR.'images/stylePreview-'.$style->styleID.$fileExtension;
                                $tar->extract($index, $filename);
-                               @chmod($filename, 0777);
+                               FileUtil::makeWritable($filename);
                                
                                if (file_exists($filename)) {
                                        $style->update(array('image' => 'stylePreview-'.$style->styleID.$fileExtension));
@@ -541,7 +541,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        $directory = $location . ($index === null ? '' : $index);
                        if (!is_dir($directory)) {
                                @mkdir($directory, 0777, true);
-                               @chmod($directory, 0777);
+                               FileUtil::makeWritable($directory);
                                
                                return FileUtil::addTrailingSlash($directory);
                        }
@@ -643,7 +643,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        // create templates tar
                        $templatesTarName = FileUtil::getTemporaryFilename('templates', '.tar');
                        $templatesTar = new TarWriter($templatesTarName);
-                       @chmod($templatesTarName, 0777);
+                       FileUtil::makeWritable($templatesTarName);
                        
                        // append templates to tar
                        // get templates
@@ -672,7 +672,7 @@ class StyleEditor extends DatabaseObjectEditor implements IEditableCachedObject
                        // create images tar
                        $imagesTarName = FileUtil::getTemporaryFilename('images_', '.tar');
                        $imagesTar = new TarWriter($imagesTarName);
-                       @chmod($imagesTarName, 0777);
+                       FileUtil::makeWritable($imagesTarName);
                        
                        // append images to tar
                        $path = FileUtil::addTrailingSlash(WCF_DIR.$this->imagePath);
index 8a169e7d00d820c8c0ab6ca70bd09bf01d8372fe..3e659b019b2ca337ec4371628fdd022928a8eccd 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\data\template;
+use wcf\util\FileUtil;
+
 use wcf\data\DatabaseObjectEditor;
 use wcf\system\io\File;
 use wcf\system\Regex;
@@ -50,7 +52,7 @@ class TemplateEditor extends DatabaseObjectEditor {
                $file = new File($path);
                $file->write($source);
                $file->close();
-               @$file->chmod(0777);
+               FileUtil::makeWritable($path);
        }
        
        /**
index d59ccaeeb66653232a935a323190e7ada0fc38fe..19b8a8ac3a74941f5833145adf52edb76aa1f710 100644 (file)
@@ -225,12 +225,7 @@ class Tar implements IArchive {
                $targetFile->write($buffer);
                $targetFile->close();
                
-               if (FileUtil::isApacheModule() || !@$targetFile->is_writable()) {
-                       @$targetFile->chmod(0777);
-               }
-               else {
-                       @$targetFile->chmod(0755);
-               }
+               FileUtil::makeWritable($destination);
                
                if ($header['mtime']) {
                        @$targetFile->touch($header['mtime']);
index 18be9bfbcfd59b475770d0cc48da4d183e969b3c..4509b1e571409c0f95495b98008a354c14d8fd56 100644 (file)
@@ -6,8 +6,8 @@ use wcf\util\FileUtil;
 /**
  * Reads zip files.
  * 
- * @author     Tim Düsterhus
- * @copyright  2012 Tim Düsterhus
+ * @author     Tim Duesterhus
+ * @copyright  2001-2013 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @subpackage system.io
@@ -114,12 +114,7 @@ class Zip extends File implements IArchive {
                $targetFile->write($file['content'], strlen($file['content']));
                $targetFile->close();
                
-               if (FileUtil::isApacheModule() || !@$targetFile->is_writable()) {
-                       @$targetFile->chmod(0777);
-               }
-               else {
-                       @$targetFile->chmod(0755);
-               }
+               FileUtil::makeWritable($destination);
                
                if ($file['header']['mtime']) {
                        @$targetFile->touch($file['header']['mtime']);
index 83a05d94410a01d7fdf11bbd144b5f778a30701c..b815abf671f7a8df8927e9d994723fa422fe8fb1 100644 (file)
@@ -669,7 +669,7 @@ class PackageInstallationDispatcher {
                                
                                // create directory and set permissions
                                @mkdir($packageDir, 0777, true);
-                               @chmod($packageDir, 0777);
+                               FileUtil::makeWritable($packageDir);
                        }
                        
                        return null;
index 3d56d8cad141f5e40f12157d72013b13aa28df15..6f9b6ba5278f803e1a155c70bd2ee4f95274fdf6 100644 (file)
@@ -9,7 +9,7 @@ use wcf\util\StringUtil;
  * Extracts files and directories from a tar archive.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2012 WoltLab GmbH
+ * @copyright  2001-2013 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @subpackage system.setup
@@ -203,11 +203,6 @@ class Installer {
         * @param       string          $target
         */
        protected function makeWriteable($target) {
-               if (!preg_match('/^WIN/i', PHP_OS)) {
-                       if (!@chmod($target, 0777)) {
-                               // todo: what to do in this case?
-                               //throw new SystemException("Could not chmod file '".$target."'");
-                       }
-               }
+               FileUtil::makeWritable($target);
        }
 }
index de5bff87cdb2e373dfdc5d74d487b704390afdf2..d1d49de60411927c264411e220a148ed8f223545 100644 (file)
@@ -34,7 +34,7 @@ final class FileUtil {
                                // create tmp folder in document root automatically
                                if (!@file_exists($_SERVER['DOCUMENT_ROOT'].'/tmp')) { 
                                        @mkdir($_SERVER['DOCUMENT_ROOT'].'/tmp/', 0777);
-                                       @chmod($_SERVER['DOCUMENT_ROOT'].'/tmp/', 0777);
+                                       self::makeWritable($_SERVER['DOCUMENT_ROOT'].'/tmp/');
                                }
                        }
                        if (@file_exists($_SERVER['DOCUMENT_ROOT'].'/tmp') && @is_writable($_SERVER['DOCUMENT_ROOT'].'/tmp')) {
@@ -183,10 +183,9 @@ final class FileUtil {
         * necessary.
         * 
         * @param       string          $path
-        * @param       integer         $chmod
         * @return      boolean
         */
-       public static function makePath($path, $chmod = 0777) {
+       public static function makePath($path) {
                // directory already exists, abort
                if (file_exists($path)) {
                        return false;
@@ -200,24 +199,18 @@ final class FileUtil {
                        $parent = self::addTrailingSlash($parent);
                        if (!@file_exists($parent)) {
                                // could not create parent directory either => abort
-                               if (!self::makePath($parent, $chmod)) {
+                               if (!self::makePath($parent)) {
                                        return false;
                                }
                        }
                        
                        // well, the parent directory exists or has been created
                        // lets create this path
-                       $oldumask = @umask(0);
-                       if (!@mkdir($path, $chmod)) {
+                       if (!@mkdir($path)) {
                                return false;
                        }
-                       @umask($oldumask);
-                       /*if (!@chmod($path, $chmod)) {
-                               return false;
-                       }*/
-                       if (self::isApacheModule() || !@is_writable($path)) {
-                               @chmod($path, 0777);
-                       }
+                       
+                       self::makeWritable($path);
                        
                        return true;
                }
@@ -457,12 +450,8 @@ final class FileUtil {
                }
                $targetFile->close();
                $sourceFile->close();
-               @$targetFile->chmod(0777);
                
-               /*if ($filesize != filesize($destination)) {
-                       @unlink($destination);
-                       return false;
-               }*/
+               self::makeWritable($destination);
                
                return true;
        }
@@ -491,5 +480,36 @@ final class FileUtil {
                return self::$finfo->file($filename);
        }
        
+       /**
+        * Tries to make a file or directory writable. It starts of with the least
+        * permissions and goes up until 0777.
+        * 
+        * @param       string          $filename
+        */
+       public static function makeWritable($filename) {
+               if (is_writable($filename)) {
+                       return;
+               }
+               
+               $chmods = array('0644', '0755', '0775', '0777');
+               
+               $startIndex = 0;
+               if (is_dir($filename)) {
+                       $startIndex = 1;
+               }
+               
+               for ($i = $startIndex; $i < 4; $i++) {
+                       @chmod($filename, octdec($chmods[$i]));
+                       
+                       if (is_writable($filename)) {
+                               break;
+                       }
+                       else if ($i == 3) {
+                               // does not work with 0777
+                               throw new SystemException("Unable to make '".$filename."' writable. This is a misconfiguration of your server, please contact your system administrator or hosting provider.");
+                       }
+               }
+       }
+       
        private function __construct() { }
 }