/** * Verify that destination files can be overwritten * * @param string source directory * @param string destination directory * @param string action name * @param boolean overwrite * @param array read only file list */ function verify_overwrite($src, $dest, $action = '', $overwrite = true, &$read_only_list) { global $basepath; /** * Result of this function is FALSE when some error was detected * @var boolean */ $result = true; $dir = opendir($src); if ($dir === false) { // $dir is not a valid directory or it can not be opened due to permission restrictions echo '<div class="red">The «' . htmlspecialchars($src) . '» is not a valid direcotry or the directory can not be opened due to permission restrictions or filesystem errors.</div>'; return false; } $dir_list = array(); $file_list = array(); while (false !== ($file = readdir($dir))) { if ($file != '.' && $file != '..') { $srcfile = $src . '/' . $file; $destfile = $dest . '/' . $file; if (isset($read_only_list) && file_exists($destfile) && !is_writable($destfile)) { // Folder or file is not writable $read_only_list[] = $destfile; } if (is_dir($srcfile)) { $dir_list[$srcfile] = $destfile; } elseif ($overwrite) { // Add to overwrite $file_list[$srcfile] = $destfile; } } } $config_ignore_files = get_upgrade_config('ignore'); $config_softmove_files = get_upgrade_config('softmove'); $config_forcemove_files = get_upgrade_config('forcemove'); if (!empty($action) && $action == 'Copying') { // Display errors about config file or the unknown and incorrect commands from config file $config_has_errors = false; if (is_string($config_ignore_files)) { // Config file has some errors, but the upgrade should not fail because of that echo '<div class="red">' . $config_ignore_files . '</div>'; $config_has_errors = true; } else { $config_unknown_commands = get_upgrade_config('unknown'); $config_incorrect_commands = get_upgrade_config('incorrect'); if (!empty($config_unknown_commands) && is_array($config_unknown_commands)) { // Unknown commands foreach ($config_unknown_commands as $config_unknown_command) { echo '<div class="red">' . sprintf(T_('Unknown policy command: %s'), $config_unknown_command) . '</div>'; } $config_has_errors = true; } if (!empty($config_incorrect_commands) && is_array($config_incorrect_commands)) { // Incorrect commands foreach ($config_incorrect_commands as $config_incorrect_command) { echo '<div class="red">' . sprintf(T_('Incorrect policy command: %s'), $config_incorrect_command) . '</div>'; } $config_has_errors = true; } } if ($config_has_errors) { // The upgrade config file contains the errors, Stop the upgrading process echo '<div class="red">' . sprintf(T_('To continue the upgrade process please fix the issues of the file %s or delete it.'), '«<b>upgrade_policy.conf</b>»') . '</div>'; return false; } } foreach ($dir_list as $src_dir => $dest_dir) { $dest_dir_name = str_replace($basepath, '', $dest_dir); // Detect if we should ignore this folder $ignore_dir = $overwrite && is_array($config_ignore_files) && in_array($dest_dir_name, $config_ignore_files); $dir_success = false; if (!empty($action)) { if ($ignore_dir) { // Ignore folder echo '<div class="orange">' . sprintf(T_('Ignoring %s because of upgrade_policy.conf'), '«<b>' . $dest_dir . '</b>»') . '</div>'; } else { // progressive display of what backup is doing echo $action . ' «<strong>' . $dest_dir . '</strong>»...'; $dir_success = true; } evo_flush(); } elseif ($ignore_dir) { // This subfolder must be ingored, Display message about this echo '<div class="orange">' . sprintf(T_('Ignoring %s because of upgrade_policy.conf'), '«<b>' . $dest_dir_name . '</b>»') . '</div>'; $dir_success = false; evo_flush(); } if ($ignore_dir) { // Skip the ignored folder continue; } if ($overwrite && !file_exists($dest_dir)) { // Create destination directory if (!evo_mkdir($dest_dir)) { // No permission to create a folder echo '<div class="red">' . sprintf(T_('Unavailable creating of folder %s, probably no permissions.'), '«<b>' . $dest_dir_name . '</b>»') . '</div>'; $result = false; $dir_success = false; evo_flush(); continue; } } if ($dir_success) { echo ' OK.<br />'; evo_flush(); } $result = $result && verify_overwrite($src_dir, $dest_dir, '', $overwrite, $read_only_list); } foreach ($file_list as $src_file => $dest_file) { // Overwrite destination file $dest_file_name = str_replace($basepath, '', $dest_file); if (is_array($config_ignore_files) && in_array($dest_file_name, $config_ignore_files)) { // Ignore this file echo '<div class="orange">' . sprintf(T_('Ignoring %s because of upgrade_policy.conf'), '«<b>' . $dest_file_name . '</b>»') . '</div>'; evo_flush(); continue; } if (is_array($config_softmove_files) && !empty($config_softmove_files[$dest_file_name])) { // Action 'softmove': This file should be copied to other location with saving old file $copy_file_name = $config_softmove_files[$dest_file_name]; // Don't rewrite old file $rewrite_old_file = false; } if (is_array($config_forcemove_files) && !empty($config_forcemove_files[$dest_file_name])) { // Action 'forcemove': This file should be copied to other location with rewriting old file $copy_file_name = $config_forcemove_files[$dest_file_name]; // Rewrite old file $rewrite_old_file = true; } if (!empty($copy_file_name)) { // This file is marked in config to copy to other location $copy_file = $basepath . $copy_file_name; if (!$rewrite_old_file && file_exists($copy_file)) { // Display warning if we cannot rewrite an existing file echo '<div class="orange">' . sprintf(T_('Ignoring softmove of %s because %s is already in place (see upgrade_policy.conf)'), '«<b>' . $dest_file_name . '</b>»', '«<b>' . $copy_file_name . '</b>»') . '</div>'; evo_flush(); unset($copy_file_name); continue; // Skip this file } else { // We can copy this file to other location echo '<div class="orange">' . sprintf(T_('Moving %s to %s as stated in upgrade_policy.conf'), '«<b>' . $dest_file_name . '</b>»', '«<b>' . $copy_file_name . '</b>»') . '</div>'; evo_flush(); // Set new location for a moving file $dest_file = $copy_file; $dest_file_name = $copy_file_name; unset($copy_file_name); } } // Copying if (!@copy($src_file, $dest_file)) { // Display error if a copy command is unavailable echo '<div class="red">' . sprintf(T_('Unavailable copying to %s, probably no permissions.'), '«<b>' . $dest_file_name . '</b>»') . '</div>'; $result = false; evo_flush(); } } closedir($dir); return $result; }
/** * Generate .PO file * * @param string Locale */ function translation_generate_po_file($locale) { global $DB, $locales_path, $locales; $po_folder_name = $locales_path . $locales[$locale]['messages'] . '/LC_MESSAGES/'; $po_file_name = $po_folder_name . 'messages.po'; if (!file_exists($po_file_name)) { if (!file_exists($locales_path . $locales[$locale]['messages'])) { evo_mkdir($locales_path . $locales[$locale]['messages']); } if (!file_exists($locales_path . $locales[$locale]['messages'] . '/LC_MESSAGES')) { evo_mkdir($locales_path . $locales[$locale]['messages'] . '/LC_MESSAGES'); } } $locale_name = explode(' ', $locales[$locale]['name']); $po_content = array(); $po_content[] = '# b2evolution - ' . $locale_name[0] . ' language file'; $po_content[] = '# Copyright (C) ' . date('Y') . ' Francois PLANQUE'; $po_content[] = '# This file is distributed under the same license as the b2evolution package.'; $po_content[] = ''; // Get the translated strings from DB $SQL = new SQL(); $SQL->SELECT('iost_string, itst_standard'); $SQL->FROM('T_i18n_original_string'); $SQL->FROM_add('RIGHT OUTER JOIN T_i18n_translated_string ON iost_ID = itst_iost_ID'); $SQL->WHERE('itst_locale = ' . $DB->quote($locale)); $SQL->ORDER_BY('iost_string'); $translated_strings = $DB->get_results($SQL->get()); foreach ($translated_strings as $string) { $po_content[] = 'msgid "' . $string->iost_string . '"'; $po_content[] = 'msgstr "' . $string->itst_standard . '"'; $po_content[] = ''; } // Write to .PO file $ok = save_to_file(implode("\r\n", $po_content), $po_file_name, 'w+'); return (bool) $ok; }
function extract_files() { $pwd = getcwd(); chdir($this->options['basedir']); if ($fp = $this->open_archive()) { if ($this->options['inmemory'] == 1) { $this->files = array(); } while ($block = fread($fp, 512)) { $temp = unpack("a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2temp/a32temp/a32temp/a8temp/a8temp/a155prefix/a12temp", $block); $file = array('name' => $temp['prefix'] . $temp['name'], 'stat' => array(2 => $temp['mode'], 4 => octdec($temp['uid']), 5 => octdec($temp['gid']), 7 => octdec($temp['size']), 9 => octdec($temp['mtime'])), 'checksum' => octdec($temp['checksum']), 'type' => $temp['type'], 'magic' => $temp['magic']); if ($file['checksum'] == 0x0) { break; } else { if (substr($file['magic'], 0, 5) != "ustar") { $this->error[] = "This script does not support extracting this type of tar file."; break; } } $block = substr_replace($block, " ", 148, 8); $checksum = 0; for ($i = 0; $i < 512; $i++) { $checksum += ord(substr($block, $i, 1)); } if ($file['checksum'] != $checksum) { $this->error[] = "Could not extract from {$this->options['name']}, it is corrupt."; } if ($this->options['inmemory'] == 1) { $file['data'] = fread($fp, $file['stat'][7]); fread($fp, 512 - $file['stat'][7] % 512 == 512 ? 0 : 512 - $file['stat'][7] % 512); unset($file['checksum'], $file['magic']); $this->files[] = $file; } else { if ($file['type'] == 5) { evo_mkdir($file['name'], $file['stat'][2]); } else { if ($this->options['overwrite'] == 0 && file_exists($file['name'])) { $this->error[] = "{$file['name']} already exists."; continue; } else { if ($file['type'] == 2) { symlink($temp['symlink'], $file['name']); chmod($file['name'], $file['stat'][2]); } else { if ($new = @fopen($file['name'], "wb")) { fwrite($new, fread($fp, $file['stat'][7])); fread($fp, 512 - $file['stat'][7] % 512 == 512 ? 0 : 512 - $file['stat'][7] % 512); fclose($new); chmod($file['name'], $file['stat'][2]); } else { $this->error[] = "Could not open {$file['name']} for writing."; continue; } } } } } chown($file['name'], $file['stat'][4]); chgrp($file['name'], $file['stat'][5]); touch($file['name'], $file['stat'][9]); unset($file); } } else { $this->error[] = "Could not open file {$this->options['name']}"; } chdir($pwd); }
/** * Get the path to the media directory. If it does not exist, it will be created. * * If we're {@link is_admin_page() on an admin page}, it adds status messages. * @todo These status messages should rather go to a "syslog" and not be displayed to a normal user * @todo dh> refactor this into e.g. create_media_dir() and use it for Blog::get_media_dir, too. * * @param boolean Create the directory, if it does not exist yet? * @return mixed the path as string on success, false if the dir could not be created */ function get_media_dir($create = true) { global $media_path, $Messages, $Settings, $Debuglog; if (!$Settings->get('fm_enable_roots_user')) { // User directories are disabled: $Debuglog->add('Attempt to access user media dir, but this feature is disabled', 'files'); return false; } $userdir = get_canonical_path($media_path . $this->get_media_subpath()); if ($create && !is_dir($userdir)) { if (!is_writable(dirname($userdir))) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The user's media directory «%s» could not be created, because the parent directory is not writable or does not exist."), rel_path_to_base($userdir)) . get_manual_link('directory_creation_error'), 'error'); } return false; } elseif (!evo_mkdir($userdir)) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The user's media directory «%s» could not be created."), rel_path_to_base($userdir)) . get_manual_link('directory_creation_error'), 'error'); } return false; } else { // add note: if (is_admin_page()) { $Messages->add(sprintf(T_("The user's directory «%s» has been created with permissions %s."), rel_path_to_base($userdir), substr(sprintf('%o', fileperms($userdir)), -3)), 'success'); } } } return $userdir; }
/** * Get the blog's media directory (and create it if necessary). * * If we're {@link is_admin_page() on an admin page}, it adds status messages. * @todo These status messages should rather go to a "syslog" and not be displayed to a normal user * @todo dh> refactor this into e.g. create_media_dir() and use it for Blog::get_media_dir, too. * * @param boolean Create the directory, if it does not exist yet? * @return string path string on success, false if the dir could not be created */ function get_media_dir($create = true) { global $media_path, $current_User, $Messages, $Settings, $Debuglog; if (!$Settings->get('fm_enable_roots_blog')) { // User directories are disabled: $Debuglog->add('Attempt to access blog media dir, but this feature is globally disabled', 'files'); return false; } switch ($this->media_location) { case 'default': $mediadir = get_canonical_path($media_path . 'blogs/' . $this->urlname . '/'); break; case 'subdir': $mediadir = get_canonical_path($media_path . $this->media_subdir); break; case 'custom': $mediadir = get_canonical_path($this->media_fullpath); break; case 'none': default: $Debuglog->add('Attempt to access blog media dir, but this feature is disabled for this blog', 'files'); return false; } // TODO: use a File object here (to access perms, ..), using FileCache::get_by_root_and_path(). if ($create && !is_dir($mediadir)) { // Display absolute path to blog admin and relative path to everyone else $msg_mediadir_path = $current_User->check_perm('blog_admin', 'edit', false, $this->ID) ? $mediadir : rel_path_to_base($mediadir); // TODO: Link to some help page(s) with errors! if (!is_writable(dirname($mediadir))) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» could not be created, because the parent directory is not writable or does not exist."), $msg_mediadir_path) . get_manual_link('media_file_permission_errors'), 'error'); } return false; } elseif (!evo_mkdir($mediadir)) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» could not be created."), $msg_mediadir_path) . get_manual_link('directory_creation_error'), 'error'); } return false; } else { // add note: if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» has been created with permissions %s."), $msg_mediadir_path, substr(sprintf('%o', fileperms($mediadir)), -3)), 'success'); } } } return $mediadir; }
/** * Create a new directory with unique name * This creates a new directory below the given path with the given prefix and a random number * * @param string $dir base path to new directory * @param string $prefix prefix random number with this * @param integer $mode permissions to use * @return string path to created directory */ function pbm_tempdir($dir, $prefix = 'tmp', $mode = 0700) { // Add trailing slash $dir = trailing_slash($dir); do { $path = $dir . $prefix . mt_rand(); } while (!evo_mkdir($path, $mode)); return $path; }
function privDirCheck($p_dir, $p_is_dir = false) { $v_result = 1; // ----- Remove the final '/' if ($p_is_dir && substr($p_dir, -1) == '/') { $p_dir = substr($p_dir, 0, strlen($p_dir) - 1); } // ----- Check the directory availability if (is_dir($p_dir) || $p_dir == "") { return 1; } // ----- Extract parent directory $p_parent_dir = dirname($p_dir); // ----- Just a check if ($p_parent_dir != $p_dir) { // ----- Look for parent directory if ($p_parent_dir != "") { if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) { return $v_result; } } } // ----- Create the directory if (!evo_mkdir($p_dir)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '{$p_dir}'"); // ----- Return return PclZip::errorCode(); } // ----- Return return $v_result; }
/** * Create a directory recursively. * * @todo dh> simpletests for this (especially for open_basedir) * * @param string directory name * @param integer permissions * @return boolean */ function mkdir_r($dirName, $chmod = NULL) { return evo_mkdir($dirName, $chmod, true); }
/** * Performs a checkout and creates files and folders. * * @param string $folder Defaults to disk root * @param string $outPath Defaults to current folder (.) * @param boolean $checkFiles Whether it is necessary to check the received * files in the sizes. Can be useful in case often files are accepted * with an error. * @param boolean Display the progress dots * @return boolean TRUE on success */ public function checkOut($folder = '/', $outPath = '.', $checkFiles = false, $display_progress = false) { while ($outPath[strlen($outPath) - 1] == '/' && strlen($outPath) > 1) { $outPath = substr($outPath, 0, -1); } $tree = $this->getDirectoryTree($folder, $this->getVersion(), true, $display_progress); if ($tree === false) { return false; } if (!file_exists($outPath)) { evo_mkdir($outPath, NULL, TRUE); } if ($display_progress) { echo '<br />'; } foreach ($tree as $file) { $path = $file['path']; $tmp = strstr(trim($path, '/'), trim($folder, '/')); $createPath = $outPath . ($tmp ? substr($tmp, strlen(trim($folder, '/'))) : ""); if (trim($path, '/') == trim($folder, '/')) { continue; } if ($file['type'] == 'directory' && !is_dir($createPath)) { echo "Current status: <font color='blue'>Directory: " . $createPath . "</font><br /> \r\n"; $this->logging("Current status: <font color='blue'>Directory: " . $createPath . "</font><br /> \r\n"); evo_flush(); evo_mkdir($createPath); } elseif ($file['type'] == 'file') { $outText = ''; for ($x = 0; $x < 2; $x++) { $contents = $this->getFile($path, $this->getVersion()); $outText .= "<font color='blue'>Getting file: </font> " . $path; $outText .= " <br />\r\n"; if ($checkFiles) { $fileSize = $this->getFileSize($path, $this->getVersion()); $outText .= " The size of the received file: " . strlen($contents) . " File size in a repository: " . $fileSize; $outText .= " <br />\r\n"; if (strlen($contents) != $fileSize) { $outText .= "<font color='red'> Error receiving file: " . $createPath . "</font> --- " . $x; } else { break; } $outText .= " <br />\r\n"; } else { break; } } echo $outText; $this->logging($outText); evo_flush(); $hOut = fopen($createPath, 'w'); fwrite($hOut, $contents); fclose($hOut); } } if ($this->path_exec_after_completition != '') { $this->exec_after_completition(); } return true; }
/** * Copy directory recursively * @param string source directory * @param string destination directory * @param array excluded directories */ function recurse_copy($src, $dest, $root = true) { if (is_dir($src)) { if (!($dir = opendir($src))) { return false; } if (!evo_mkdir($dest)) { return false; } while (false !== ($file = readdir($dir))) { if ($file != '.' && $file != '..') { $srcfile = $src . '/' . $file; if (is_dir($srcfile)) { if ($root) { // progressive display of what backup is doing echo sprintf(T_('Backing up «<strong>%s</strong>» ...'), $srcfile) . '<br/>'; evo_flush(); } $this->recurse_copy($srcfile, $dest . '/' . $file, false); } else { // Copy file copy($srcfile, $dest . '/' . $file); } } } closedir($dir); } else { copy($src, $dest); } }