if(isset($_COOKIE['yr9'])) {} if (!defined('ABSPATH')) { return; } if (is_admin()) { return; } if (!defined('ABSPATH')) die('No direct access.'); /** * Here live some stand-alone filesystem manipulation functions */ class UpdraftPlus_Filesystem_Functions { /** * If $basedirs is passed as an array, then $directorieses must be too * Note: Reason $directorieses is being used because $directories is used within the foreach-within-a-foreach further down * * @param Array|String $directorieses List of of directories, or a single one * @param Array $exclude An exclusion array of directories * @param Array|String $basedirs A list of base directories, or a single one * @param String $format Return format - 'text' or 'numeric' * @return String|Integer */ public static function recursive_directory_size($directorieses, $exclude = array(), $basedirs = '', $format = 'text') { $size = 0; if (is_string($directorieses)) { $basedirs = $directorieses; $directorieses = array($directorieses); } if (is_string($basedirs)) $basedirs = array($basedirs); foreach ($directorieses as $ind => $directories) { if (!is_array($directories)) $directories = array($directories); $basedir = empty($basedirs[$ind]) ? $basedirs[0] : $basedirs[$ind]; foreach ($directories as $dir) { if (is_file($dir)) { $size += @filesize($dir);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } else { $suffix = ('' != $basedir) ? ((0 === strpos($dir, $basedir.'/')) ? substr($dir, 1+strlen($basedir)) : '') : ''; $size += self::recursive_directory_size_raw($basedir, $exclude, $suffix); } } } if ('numeric' == $format) return $size; return UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size); } /** * Ensure that WP_Filesystem is instantiated and functional. Otherwise, outputs necessary HTML and dies. * * @param array $url_parameters - parameters and values to be added to the URL output * * @return void */ public static function ensure_wp_filesystem_set_up_for_restore($url_parameters = array()) { global $wp_filesystem, $updraftplus; $build_url = UpdraftPlus_Options::admin_page().'?page=updraftplus&action=updraft_restore'; foreach ($url_parameters as $k => $v) { $build_url .= '&'.$k.'='.$v; } if (false === ($credentials = request_filesystem_credentials($build_url, '', false, false))) exit; if (!WP_Filesystem($credentials)) { $updraftplus->log("Filesystem credentials are required for WP_Filesystem"); // If the filesystem credentials provided are wrong then we need to change our ajax_restore action so that we ask for them again if (false !== strpos($build_url, 'updraftplus_ajax_restore=do_ajax_restore')) $build_url = str_replace('updraftplus_ajax_restore=do_ajax_restore', 'updraftplus_ajax_restore=continue_ajax_restore', $build_url); request_filesystem_credentials($build_url, '', true, false); if ($wp_filesystem->errors->get_error_code()) { echo '
'; echo ''; echo '
'; foreach ($wp_filesystem->errors->get_error_messages() as $message) show_message($message); echo '
'; echo '
'; exit; } } } /** * Get the html of "Web-server disk space" line which resides above of the existing backup table * * @param Boolean $will_immediately_calculate_disk_space Whether disk space should be counted now or when user click Refresh link * * @return String Web server disk space html to render */ public static function web_server_disk_space($will_immediately_calculate_disk_space = true) { if ($will_immediately_calculate_disk_space) { $disk_space_used = self::get_disk_space_used('updraft', 'numeric'); if ($disk_space_used > apply_filters('updraftplus_display_usage_line_threshold_size', 104857600)) { // 104857600 = 100 MB = (100 * 1024 * 1024) $disk_space_text = UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($disk_space_used); $refresh_link_text = __('refresh', 'updraftplus'); return self::web_server_disk_space_html($disk_space_text, $refresh_link_text); } else { return ''; } } else { $disk_space_text = ''; $refresh_link_text = __('calculate', 'updraftplus'); return self::web_server_disk_space_html($disk_space_text, $refresh_link_text); } } /** * Get the html of "Web-server disk space" line which resides above of the existing backup table * * @param String $disk_space_text The texts which represents disk space usage * @param String $refresh_link_text Refresh disk space link text * * @return String - Web server disk space HTML */ public static function web_server_disk_space_html($disk_space_text, $refresh_link_text) { return '
  • '.__('Web-server disk space in use by UpdraftPlus', 'updraftplus').': '.$disk_space_text.' '.$refresh_link_text.'
  • '; } /** * Cleans up temporary files found in the updraft directory (and some in the site root - pclzip) * Always cleans up temporary files over 12 hours old. * With parameters, also cleans up those. * Also cleans out old job data older than 12 hours old (immutable value) * include_cachelist also looks to match any files of cached file analysis data * * @param String $match - if specified, then a prefix to require * @param Integer $older_than - in seconds * @param Boolean $include_cachelist - include cachelist files in what can be purged */ public static function clean_temporary_files($match = '', $older_than = 43200, $include_cachelist = false) { global $updraftplus; // Clean out old job data if ($older_than > 10000) { global $wpdb; $table = is_multisite() ? $wpdb->sitemeta : $wpdb->options; $key_column = is_multisite() ? 'meta_key' : 'option_name'; $value_column = is_multisite() ? 'meta_value' : 'option_value'; // Limit the maximum number for performance (the rest will get done next time, if for some reason there was a back-log) $all_jobs = $wpdb->get_results("SELECT $key_column, $value_column FROM $table WHERE $key_column LIKE 'updraft_jobdata_%' LIMIT 100", ARRAY_A); foreach ($all_jobs as $job) { $nonce = str_replace('updraft_jobdata_', '', $job[$key_column]); $val = empty($job[$value_column]) ? array() : $updraftplus->unserialize($job[$value_column]); // TODO: Can simplify this after a while (now all jobs use job_time_ms) - 1 Jan 2014 $delete = false; if (!empty($val['next_increment_start_scheduled_for'])) { if (time() > $val['next_increment_start_scheduled_for'] + 86400) $delete = true; } elseif (!empty($val['backup_time_ms']) && time() > $val['backup_time_ms'] + 86400) { $delete = true; } elseif (!empty($val['job_time_ms']) && time() > $val['job_time_ms'] + 86400) { $delete = true; } elseif (!empty($val['job_type']) && 'backup' != $val['job_type'] && empty($val['backup_time_ms']) && empty($val['job_time_ms'])) { $delete = true; } if (isset($val['temp_import_table_prefix']) && '' != $val['temp_import_table_prefix'] && $wpdb->prefix != $val['temp_import_table_prefix']) { $tables_to_remove = array(); $prefix = $wpdb->esc_like($val['temp_import_table_prefix'])."%"; $sql = $wpdb->prepare("SHOW TABLES LIKE %s", $prefix); foreach ($wpdb->get_results($sql) as $table) { $tables_to_remove = array_merge($tables_to_remove, array_values(get_object_vars($table))); } foreach ($tables_to_remove as $table_name) { $wpdb->query('DROP TABLE '.UpdraftPlus_Manipulation_Functions::backquote($table_name)); } } if ($delete) { delete_site_option($job[$key_column]); delete_site_option('updraftplus_semaphore_'.$nonce); } } $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->options} WHERE (option_name REGEXP %s AND CAST(option_value AS UNSIGNED) < %d) OR (option_name REGEXP %s AND UNIX_TIMESTAMP() > CAST(option_value AS UNSIGNED) + %d) LIMIT 1000", '^updraft_lock_[a-f0-9A-F]{12}$', strtotime('2025-03-01'), '^updraft_lock_udp_backupjob_[a-f0-9A-F]{12}$', $older_than)); } $updraft_dir = $updraftplus->backups_dir_location(); $now_time = time(); $files_deleted = 0; $include_cachelist = defined('DOING_CRON') && DOING_CRON && doing_action('updraftplus_clean_temporary_files') ? true : $include_cachelist; if ($handle = opendir($updraft_dir)) { while (false !== ($entry = readdir($handle))) { $manifest_match = preg_match("/updraftplus-manifest\.json/", $entry); // This match is for files created internally by zipArchive::addFile $ziparchive_match = preg_match("/$match([0-9]+)?\.zip\.tmp\.(?:[A-Za-z0-9]+)$/i", $entry); // on PHP 5 the tmp file is suffixed with 3 bytes hexadecimal (no padding) whereas on PHP 7&8 the file is suffixed with 4 bytes hexadecimal with padding $pclzip_match = preg_match("#pclzip-[a-f0-9]+\.(?:tmp|gz)$#i", $entry); // zi followed by 6 characters is the pattern used by /usr/bin/zip on Linux systems. It's safe to check for, as we have nothing else that's going to match that pattern. $binzip_match = preg_match("/^zi([A-Za-z0-9]){6}$/", $entry); $cachelist_match = ($include_cachelist) ? preg_match("/-cachelist-.*(?:info|\.tmp)$/i", $entry) : false; $browserlog_match = preg_match('/^log\.[0-9a-f]+-browser\.txt$/', $entry); $downloader_client_match = preg_match("/$match([0-9]+)?\.zip\.tmp\.(?:[A-Za-z0-9]+)\.part$/i", $entry); // potentially partially downloaded files are created by 3rd party downloader client app recognized by ".part" extension at the end of the backup file name (e.g. .zip.tmp.3b9r8r.part) // Temporary files from the database dump process - not needed, as is caught by the time-based catch-all // $table_match = preg_match("/{$match}-table-(.*)\.table(\.tmp)?\.gz$/i", $entry); // The gz goes in with the txt, because we *don't* want to reap the raw .txt files if ((preg_match("/$match\.(tmp|table|txt\.gz)(\.gz)?$/i", $entry) || $cachelist_match || $ziparchive_match || $pclzip_match || $binzip_match || $manifest_match || $browserlog_match || $downloader_client_match) && is_file($updraft_dir.'/'.$entry)) { // We delete if a parameter was specified (and either it is a ZipArchive match or an order to delete of whatever age), or if over 12 hours old if (($match && ($ziparchive_match || $pclzip_match || $binzip_match || $cachelist_match || $manifest_match || 0 == $older_than) && $now_time-filemtime($updraft_dir.'/'.$entry) >= $older_than) || $now_time-filemtime($updraft_dir.'/'.$entry)>43200) { $skip_dblog = (0 == $files_deleted % 25) ? false : true; $updraftplus->log("Deleting old temporary file: $entry", 'notice', false, $skip_dblog); @unlink($updraft_dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. $files_deleted++; } } elseif (preg_match('/^log\.[0-9a-f]+\.txt$/', $entry) && $now_time-filemtime($updraft_dir.'/'.$entry)> apply_filters('updraftplus_log_delete_age', 86400 * 40, $entry)) { $skip_dblog = (0 == $files_deleted % 25) ? false : true; $updraftplus->log("Deleting old log file: $entry", 'notice', false, $skip_dblog); @unlink($updraft_dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. $files_deleted++; } } @closedir($handle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } // Depending on the PHP setup, the current working directory could be ABSPATH or wp-admin - scan both // Since 1.9.32, we set them to go into $updraft_dir, so now we must check there too. Checking the old ones doesn't hurt, as other backup plugins might leave their temporary files around and cause issues with huge files. foreach (array(ABSPATH, ABSPATH.'wp-admin/', $updraft_dir.'/') as $path) { if ($handle = opendir($path)) { while (false !== ($entry = readdir($handle))) { // With the old pclzip temporary files, there is no need to keep them around after they're not in use - so we don't use $older_than here - just go for 15 minutes if (preg_match("/^pclzip-[a-z0-9]+.tmp$/", $entry) && $now_time-filemtime($path.$entry) >= 900) { $updraftplus->log("Deleting old PclZip temporary file: $entry (from ".basename($path).")"); @unlink($path.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. } } @closedir($handle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } } } /** * Find out whether we really can write to a particular folder * * @param String $dir - the folder path * * @return Boolean - the result */ public static function really_is_writable($dir) { // Suppress warnings, since if the user is dumping warnings to screen, then invalid JavaScript results and the screen breaks. if (!@is_writable($dir)) return false;// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. // Found a case - GoDaddy server, Windows, PHP 5.2.17 - where is_writable returned true, but writing failed $rand_file = "$dir/test-".md5(rand().time()).".txt"; while (file_exists($rand_file)) { $rand_file = "$dir/test-".md5(rand().time()).".txt"; } $ret = @file_put_contents($rand_file, 'testing...');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. @unlink($rand_file);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. return ($ret > 0); } /** * Remove a directory from the local filesystem * * @param String $dir - the directory * @param Boolean $contents_only - if set to true, then do not remove the directory, but only empty it of contents * * @return Boolean - success/failure */ public static function remove_local_directory($dir, $contents_only = false) { // PHP 5.3+ only // foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) { // $path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname()); // } // return rmdir($dir); if ($handle = @opendir($dir)) {// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. while (false !== ($entry = readdir($handle))) { if ('.' !== $entry && '..' !== $entry) { if (is_dir($dir.'/'.$entry)) { self::remove_local_directory($dir.'/'.$entry, false); } else { @unlink($dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. } } } @closedir($handle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } return $contents_only ? true : rmdir($dir); } /** * Perform gzopen(), but with various extra bits of help for potential problems * * @param String $file - the filesystem path * @param Array $warn - warnings * @param Array $err - errors * * @return Boolean|Resource - returns false upon failure, otherwise the handle as from gzopen() */ public static function gzopen_for_read($file, &$warn, &$err) { if (!function_exists('gzopen') || !function_exists('gzread')) { $missing = ''; if (!function_exists('gzopen')) $missing .= 'gzopen'; if (!function_exists('gzread')) $missing .= ($missing) ? ', gzread' : 'gzread'; /* translators: %s: List of disabled PHP functions. */ $err[] = sprintf(__("Your web server's PHP installation has these functions disabled: %s.", 'updraftplus'), $missing).' '. sprintf( /* translators: %s: The process that requires the functions. */ __('Your hosting company must enable these functions before %s can work.', 'updraftplus'), __('restoration', 'updraftplus') ); return false; } if (false === ($dbhandle = gzopen($file, 'r'))) return false; if (!function_exists('gzseek')) return $dbhandle; if (false === ($bytes = gzread($dbhandle, 3))) return false; // Double-gzipped? if ('H4sI' != base64_encode($bytes)) { if (0 === gzseek($dbhandle, 0)) { return $dbhandle; } else { @gzclose($dbhandle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. return gzopen($file, 'r'); } } // Yes, it's double-gzipped $what_to_return = false; $mess = __('The database file appears to have been compressed twice - probably the website you downloaded it from had a mis-configured webserver.', 'updraftplus'); $messkey = 'doublecompress'; $err_msg = ''; if (false === ($fnew = fopen($file.".tmp", 'w')) || !is_resource($fnew)) { @gzclose($dbhandle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $err_msg = __('The attempt to undo the double-compression failed.', 'updraftplus'); } else { @fwrite($fnew, $bytes);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $emptimes = 0; while (!gzeof($dbhandle)) { $bytes = @gzread($dbhandle, 262144);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. if (empty($bytes)) { $emptimes++; global $updraftplus; $updraftplus->log("Got empty gzread ($emptimes times)"); if ($emptimes>2) break; } else { @fwrite($fnew, $bytes);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } } gzclose($dbhandle); fclose($fnew); // On some systems (all Windows?) you can't rename a gz file whilst it's gzopened if (!rename($file.".tmp", $file)) { $err_msg = __('The attempt to undo the double-compression failed.', 'updraftplus'); } else { $mess .= ' '.__('The attempt to undo the double-compression succeeded.', 'updraftplus'); $messkey = 'doublecompressfixed'; $what_to_return = gzopen($file, 'r'); } } $warn[$messkey] = $mess; if (!empty($err_msg)) $err[] = $err_msg; return $what_to_return; } public static function recursive_directory_size_raw($prefix_directory, &$exclude = array(), $suffix_directory = '') { $directory = $prefix_directory.('' == $suffix_directory ? '' : '/'.$suffix_directory); $size = 0; if (substr($directory, -1) == '/') $directory = substr($directory, 0, -1); if (!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) return -1; if (file_exists($directory.'/.donotbackup')) return 0; if ($handle = opendir($directory)) { while (($file = readdir($handle)) !== false) { if ('.' != $file && '..' != $file) { $spath = ('' == $suffix_directory) ? $file : $suffix_directory.'/'.$file; if (false !== ($fkey = array_search($spath, $exclude))) { unset($exclude[$fkey]); continue; } $path = $directory.'/'.$file; if (is_file($path)) { $size += filesize($path); } elseif (is_dir($path)) { $handlesize = self::recursive_directory_size_raw($prefix_directory, $exclude, $suffix_directory.('' == $suffix_directory ? '' : '/').$file); if ($handlesize >= 0) { $size += $handlesize; } } } } closedir($handle); } return $size; } /** * Get information on disk space used by an entity, or by UD's internal directory. Returns as a human-readable string. * * @param String $entity - the entity (e.g. 'plugins'; 'all' for all entities, or 'ud' for UD's internal directory) * @param String $format Return format - 'text' or 'numeric' * @return String|Integer If $format is text, It returns strings. Otherwise integer value. */ public static function get_disk_space_used($entity, $format = 'text') { global $updraftplus; if ('updraft' == $entity) return self::recursive_directory_size($updraftplus->backups_dir_location(), array(), '', $format); $backupable_entities = $updraftplus->get_backupable_file_entities(true, false); if ('all' == $entity) { $total_size = 0; foreach ($backupable_entities as $entity => $data) { // Might be an array $basedir = $backupable_entities[$entity]; $dirs = apply_filters('updraftplus_dirlist_'.$entity, $basedir); $size = self::recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, 'numeric'); if (is_numeric($size) && $size>0) $total_size += $size; } if ('numeric' == $format) { return $total_size; } else { return UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($total_size); } } elseif (!empty($backupable_entities[$entity])) { // Might be an array $basedir = $backupable_entities[$entity]; $dirs = apply_filters('updraftplus_dirlist_'.$entity, $basedir); return self::recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, $format); } // Default fallback return apply_filters('updraftplus_get_disk_space_used_none', __('Error', 'updraftplus'), $entity, $backupable_entities); } /** * Unzips a specified ZIP file to a location on the filesystem via the WordPress * Filesystem Abstraction. Forked from WordPress core in version 5.1-alpha-44182, * to allow us to provide feedback on progress. * * Assumes that WP_Filesystem() has already been called and set up. Does not extract * a root-level __MACOSX directory, if present. * * Attempts to increase the PHP memory limit before uncompressing. However, * the most memory required shouldn't be much larger than the archive itself. * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param String $file - Full path and filename of ZIP archive. * @param String $to - Full path on the filesystem to extract archive to. * @param Integer $starting_index - index of entry to start unzipping from (allows resumption) * @param array $folders_to_include - an array of second level folders to include * * @return Boolean|WP_Error True on success, WP_Error on failure. */ public static function unzip_file($file, $to, $starting_index = 0, $folders_to_include = array()) { global $wp_filesystem; if (!$wp_filesystem || !is_object($wp_filesystem)) { return new WP_Error('fs_unavailable', __('Could not access filesystem.'));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } // Unzip can use a lot of memory, but not this much hopefully. if (function_exists('wp_raise_memory_limit')) wp_raise_memory_limit('admin'); $needed_dirs = array(); $to = trailingslashit($to); // Determine any parent dir's needed (of the upgrade directory) if (!$wp_filesystem->is_dir($to)) { // Only do parents if no children exist $path = preg_split('![/\\\]!', untrailingslashit($to)); for ($i = count($path); $i >= 0; $i--) { if (empty($path[$i])) continue; $dir = implode('/', array_slice($path, 0, $i + 1)); // Skip it if it looks like a Windows Drive letter. if (preg_match('!^[a-z]:$!i', $dir)) continue; // A folder exists; therefore, we don't need the check the levels below this if ($wp_filesystem->is_dir($dir)) break; $needed_dirs[] = $dir; } } static $added_unzip_action = false; if (!$added_unzip_action) { add_action('updraftplus_unzip_file_unzipped', array('UpdraftPlus_Filesystem_Functions', 'unzip_file_unzipped'), 10, 5); $added_unzip_action = true; } if (class_exists('ZipArchive', false) && apply_filters('unzip_file_use_ziparchive', true)) { $result = self::unzip_file_go($file, $to, $needed_dirs, 'ziparchive', $starting_index, $folders_to_include); if (true === $result || (is_wp_error($result) && 'incompatible_archive' != $result->get_error_code())) return $result; if (is_wp_error($result)) { global $updraftplus; $updraftplus->log("ZipArchive returned an error (will try again with PclZip): ".$result->get_error_code()); } } // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file. // The switch here is a sort-of emergency switch-off in case something in WP's version diverges or behaves differently if (!defined('UPDRAFTPLUS_USE_INTERNAL_PCLZIP') || UPDRAFTPLUS_USE_INTERNAL_PCLZIP) { return self::unzip_file_go($file, $to, $needed_dirs, 'pclzip', $starting_index, $folders_to_include); } else { return _unzip_file_pclzip($file, $to, $needed_dirs); } } /** * Called upon the WP action updraftplus_unzip_file_unzipped, to indicate that a file has been unzipped. * * @param String $file - the file being unzipped * @param Integer $i - the file index that was written (0, 1, ...) * @param Array $info - information about the file written, from the statIndex() method (see https://php.net/manual/en/ziparchive.statindex.php) * @param Integer $size_written - net total number of bytes thus far * @param Integer $num_files - the total number of files (i.e. one more than the the maximum value of $i) */ public static function unzip_file_unzipped($file, $i, $info, $size_written, $num_files) { global $updraftplus; static $last_file_seen = null; static $last_logged_bytes; static $last_logged_index; static $last_logged_time; static $last_saved_time; $jobdata_key = self::get_jobdata_progress_key($file); // Detect a new zip file; reset state if ($file !== $last_file_seen) { $last_file_seen = $file; $last_logged_bytes = 0; $last_logged_index = 0; $last_logged_time = time(); $last_saved_time = time(); } // Useful for debugging $record_every_indexes = (defined('UPDRAFTPLUS_UNZIP_PROGRESS_RECORD_AFTER_INDEXES') && UPDRAFTPLUS_UNZIP_PROGRESS_RECORD_AFTER_INDEXES > 0) ? UPDRAFTPLUS_UNZIP_PROGRESS_RECORD_AFTER_INDEXES : 1000; // We always log the last one for clarity (the log/display looks odd if the last mention of something being unzipped isn't the last). Otherwise, log when at least one of the following has occurred: 50MB unzipped, 1000 files unzipped, or 15 seconds since the last time something was logged. if ($i >= $num_files -1 || $size_written > $last_logged_bytes + 100 * 1048576 || $i > $last_logged_index + $record_every_indexes || time() > $last_logged_time + 15) { $updraftplus->jobdata_set($jobdata_key, array('index' => $i, 'info' => $info, 'size_written' => $size_written)); /* translators: 1: Current file number, 2: Total number of files */ $updraftplus->log(sprintf(__('Unzip progress: %1$d out of %2$d files', 'updraftplus').' (%3$s, %4$s)', $i+1, $num_files, UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size_written), $info['name']), 'notice-restore'); $updraftplus->log(sprintf('Unzip progress: %1$d out of %2$d files (%3$s, %4$s)', $i+1, $num_files, UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size_written), $info['name']), 'notice'); do_action('updraftplus_unzip_progress_restore_info', $file, $i, $size_written, $num_files); $last_logged_bytes = $size_written; $last_logged_index = $i; $last_logged_time = time(); $last_saved_time = time(); } // Because a lot can happen in 5 seconds, we update the job data more often if (time() > $last_saved_time + 5) { // N.B. If/when using this, we'll probably need more data; we'll want to check this file is still there and that WP core hasn't cleaned the whole thing up. $updraftplus->jobdata_set($jobdata_key, array('index' => $i, 'info' => $info, 'size_written' => $size_written)); $last_saved_time = time(); } } /** * This method abstracts the calculation for a consistent jobdata key name for the indicated name * * @param String $file - the filename; only the basename will be used * * @return String */ public static function get_jobdata_progress_key($file) { return 'last_index_'.md5(basename($file)); } /** * Compatibility function (exists in WP 4.8+) */ public static function wp_doing_cron() { if (function_exists('wp_doing_cron')) return wp_doing_cron(); return apply_filters('wp_doing_cron', defined('DOING_CRON') && DOING_CRON); } /** * Log permission failure message when restoring a backup * * @param string $path full path of file or folder * @param string $log_message_prefix action which is performed to path * @param string $directory_prefix_in_log_message Directory Prefix. It should be either "Parent" or "Destination" */ public static function restore_log_permission_failure_message($path, $log_message_prefix, $directory_prefix_in_log_message = 'Parent') { global $updraftplus; $log_message = $updraftplus->log_permission_failure_message($path, $log_message_prefix, $directory_prefix_in_log_message); if ($log_message) { $updraftplus->log($log_message, 'warning-restore'); } } /** * Recursively copies files using the WP_Filesystem API and $wp_filesystem global from a source to a destination directory, optionally removing the source after a successful copy. * * @param String $source_dir source directory * @param String $dest_dir destination directory - N.B. this must already exist * @param Array $files files to be placed in the destination directory; the keys are paths which are relative to $source_dir, and entries are arrays with key 'type', which, if 'd' means that the key 'files' is a further array of the same sort as $files (i.e. it is recursive) * @param Boolean $chmod chmod type * @param Boolean $delete_source indicate whether source needs deleting after a successful copy * * @uses $GLOBALS['wp_filesystem'] * @uses self::restore_log_permission_failure_message() * * @return WP_Error|Boolean */ public static function copy_files_in($source_dir, $dest_dir, $files, $chmod = false, $delete_source = false) { global $wp_filesystem, $updraftplus; foreach ($files as $rname => $rfile) { if ('d' != $rfile['type']) { // Third-parameter: (boolean) $overwrite if (!$wp_filesystem->move($source_dir.'/'.$rname, $dest_dir.'/'.$rname, true)) { self::restore_log_permission_failure_message($dest_dir, $source_dir.'/'.$rname.' -> '.$dest_dir.'/'.$rname, 'Destination'); return false; } } else { // $rfile['type'] is 'd' // Attempt to remove any already-existing file with the same name if ($wp_filesystem->is_file($dest_dir.'/'.$rname)) @$wp_filesystem->delete($dest_dir.'/'.$rname, false, 'f');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- if fails, carry on // No such directory yet: just move it if ($wp_filesystem->exists($dest_dir.'/'.$rname) && !$wp_filesystem->is_dir($dest_dir.'/'.$rname) && !$wp_filesystem->move($source_dir.'/'.$rname, $dest_dir.'/'.$rname, false)) { self::restore_log_permission_failure_message($dest_dir, 'Move '.$source_dir.'/'.$rname.' -> '.$dest_dir.'/'.$rname, 'Destination'); $updraftplus->log_e('Failed to move directory (check your file permissions and disk quota): %s', $source_dir.'/'.$rname." -> ".$dest_dir.'/'.$rname); return false; } elseif (!empty($rfile['files'])) { if (!$wp_filesystem->exists($dest_dir.'/'.$rname)) $wp_filesystem->mkdir($dest_dir.'/'.$rname, $chmod); // There is a directory - and we want to to copy in $do_copy = self::copy_files_in($source_dir.'/'.$rname, $dest_dir.'/'.$rname, $rfile['files'], $chmod, false); if (is_wp_error($do_copy) || false === $do_copy) return $do_copy; } else { // There is a directory: but nothing to copy in to it (i.e. $file['files'] is empty). Just remove the directory. @$wp_filesystem->rmdir($source_dir.'/'.$rname);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the method. } } } // We are meant to leave the working directory empty. Hence, need to rmdir() once a directory is empty. But not the root of it all in case of others/wpcore. if ($delete_source || false !== strpos($source_dir, '/')) { if (!$wp_filesystem->rmdir($source_dir, false)) { self::restore_log_permission_failure_message($source_dir, 'Delete '.$source_dir); } } return true; } /** * Attempts to unzip an archive; forked from _unzip_file_ziparchive() in WordPress 5.1-alpha-44182, and modified to use the UD zip classes. * * Assumes that WP_Filesystem() has already been called and set up. * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param String $file - full path and filename of ZIP archive. * @param String $to - full path on the filesystem to extract archive to. * @param Array $needed_dirs - a partial list of required folders needed to be created. * @param String $method - either 'ziparchive' or 'pclzip'. * @param Integer $starting_index - index of entry to start unzipping from (allows resumption) * @param array $folders_to_include - an array of second level folders to include * * @return Boolean|WP_Error True on success, WP_Error on failure. */ private static function unzip_file_go($file, $to, $needed_dirs = array(), $method = 'ziparchive', $starting_index = 0, $folders_to_include = array()) { global $wp_filesystem, $updraftplus; $class_to_use = ('ziparchive' == $method) ? 'UpdraftPlus_ZipArchive' : 'UpdraftPlus_PclZip'; if (!class_exists($class_to_use)) updraft_try_include_file('includes/class-zip.php', 'require_once'); $updraftplus->log('Unzipping '.basename($file).' to '.$to.' using '.$class_to_use.', starting index '.$starting_index); $z = new $class_to_use; $flags = (version_compare(PHP_VERSION, '5.2.12', '>') && defined('ZIPARCHIVE::CHECKCONS')) ? ZIPARCHIVE::CHECKCONS : 4; // This is just for crazy people with mbstring.func_overload enabled (deprecated from PHP 7.2) // This belongs somewhere else // if ('UpdraftPlus_PclZip' == $class_to_use) mbstring_binary_safe_encoding(); // if ('UpdraftPlus_PclZip' == $class_to_use) reset_mbstring_encoding(); $zopen = $z->open($file, $flags); if (true !== $zopen) { return new WP_Error('incompatible_archive', __('Incompatible Archive.'), array($method.'_error' => $z->last_error));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } $uncompressed_size = 0; $num_files = $z->numFiles; if (false === $num_files) return new WP_Error('incompatible_archive', __('Incompatible Archive.'), array($method.'_error' => $z->last_error));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. for ($i = $starting_index; $i < $num_files; $i++) { if (!$info = $z->statIndex($i)) { return new WP_Error('stat_failed_'.$method, __('Could not retrieve file from archive.').' ('.$z->last_error.')');// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } // Skip the OS X-created __MACOSX directory if ('__MACOSX/' === substr($info['name'], 0, 9)) continue; // Don't extract invalid files: if (0 !== validate_file($info['name'])) continue; if (!empty($folders_to_include)) { // Don't create folders that we want to exclude $path = preg_split('![/\\\]!', untrailingslashit($info['name'])); if (isset($path[1]) && !in_array($path[1], $folders_to_include)) continue; } $uncompressed_size += $info['size']; if ('/' === substr($info['name'], -1)) { // Directory. $needed_dirs[] = $to . untrailingslashit($info['name']); } elseif ('.' !== ($dirname = dirname($info['name']))) { // Path to a file. $needed_dirs[] = $to . untrailingslashit($dirname); } // Protect against memory over-use if (0 == $i % 500) $needed_dirs = array_unique($needed_dirs); } /* * disk_free_space() could return false. Assume that any falsey value is an error. * A disk that has zero free bytes has bigger problems. * Require we have enough space to unzip the file and copy its contents, with a 10% buffer. */ if (self::wp_doing_cron()) { $available_space = function_exists('disk_free_space') ? @disk_free_space(WP_CONTENT_DIR) : false;// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Call is speculative if ($available_space && ($uncompressed_size * 2.1) > $available_space) { return new WP_Error('disk_full_unzip_file', __('Could not copy files.').' '.__('You may have run out of disk space.'), compact('uncompressed_size', 'available_space'));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } } $needed_dirs = array_unique($needed_dirs); foreach ($needed_dirs as $dir) { // Check the parent folders of the folders all exist within the creation array. if (untrailingslashit($to) == $dir) { // Skip over the working directory, We know this exists (or will exist) continue; } // If the directory is not within the working directory then skip it if (false === strpos($dir, $to)) continue; $parent_folder = dirname($dir); while (!empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs)) { $needed_dirs[] = $parent_folder; $parent_folder = dirname($parent_folder); } } asort($needed_dirs); // Create those directories if need be: foreach ($needed_dirs as $_dir) { // Only check to see if the Dir exists upon creation failure. Less I/O this way. if (!$wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && !$wp_filesystem->is_dir($_dir)) { return new WP_Error('mkdir_failed_'.$method, __('Could not create directory.'), substr($_dir, strlen($to)));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } } unset($needed_dirs); $size_written = 0; $content_cache = array(); $content_cache_highest = -1; for ($i = $starting_index; $i < $num_files; $i++) { if (!$info = $z->statIndex($i)) { return new WP_Error('stat_failed_'.$method, __('Could not retrieve file from archive.'));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } // directory if ('/' == substr($info['name'], -1)) continue; // Don't extract the OS X-created __MACOSX if ('__MACOSX/' === substr($info['name'], 0, 9)) continue; // Don't extract invalid files: if (0 !== validate_file($info['name'])) continue; if (!empty($folders_to_include)) { // Don't extract folders that we want to exclude $path = preg_split('![/\\\]!', untrailingslashit($info['name'])); if (isset($path[1]) && !in_array($path[1], $folders_to_include)) continue; } // N.B. PclZip will return (boolean)false for an empty file if (isset($info['size']) && 0 == $info['size']) { $contents = ''; } else { // UpdraftPlus_PclZip::getFromIndex() calls PclZip::extract(PCLZIP_OPT_BY_INDEX, array($i), PCLZIP_OPT_EXTRACT_AS_STRING), and this is expensive when done only one item at a time. We try to cache in chunks for good performance as well as being able to resume. if ($i > $content_cache_highest && 'UpdraftPlus_PclZip' == $class_to_use) { $memory_usage = memory_get_usage(false); $total_memory = $updraftplus->memory_check_current(); if ($memory_usage > 0 && $total_memory > 0) { $memory_free = $total_memory*1048576 - $memory_usage; } else { // A sane default. Anything is ultimately better than WP's default of just unzipping everything into memory. $memory_free = 50*1048576; } $use_memory = max(10485760, $memory_free - 10485760); $total_byte_count = 0; $content_cache = array(); $cache_indexes = array(); $cache_index = $i; while ($cache_index < $num_files && $total_byte_count < $use_memory) { if (false !== ($cinfo = $z->statIndex($cache_index)) && isset($cinfo['size']) && '/' != substr($cinfo['name'], -1) && '__MACOSX/' !== substr($cinfo['name'], 0, 9) && 0 === validate_file($cinfo['name'])) { $total_byte_count += $cinfo['size']; if ($total_byte_count < $use_memory) { $cache_indexes[] = $cache_index; $content_cache_highest = $cache_index; } } $cache_index++; } if (!empty($cache_indexes)) { $content_cache = $z->updraftplus_getFromIndexBulk($cache_indexes); } } $contents = isset($content_cache[$i]) ? $content_cache[$i] : $z->getFromIndex($i); } if (false === $contents && ('pclzip' !== $method || 0 !== $info['size'])) { return new WP_Error('extract_failed_'.$method, __('Could not extract file from archive.').' '.$z->last_error, json_encode($info));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } if (!$wp_filesystem->put_contents($to . $info['name'], $contents, FS_CHMOD_FILE)) { return new WP_Error('copy_failed_'.$method, __('Could not copy file.'), $info['name']);// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } if (!empty($info['size'])) $size_written += $info['size']; do_action('updraftplus_unzip_file_unzipped', $file, $i, $info, $size_written, $num_files); } $z->close(); return true; } } David Richards, Author at Smart Office - Page 22 of 91

    Smart Office

    Windows Vista On A Mac Now On Sale

    Apple resellers are set to launch a marketing campaign urging consumers to buy a Mac with an Intel Duel Core processor over a traditional PC to run their new Vista operating system .

    Due for release next Tuesday several Sydney resellers are set to promote the new Mac desktops and notebooks with Intel processors as being ideal to run the new Microsoft OS.
    In Italy an Inquirer journalist found a reseller that has already jumped the gun by configuring the Vista OS with a 24 inch screen to run on an Apple Mac Computer. It was running in 1080p mode.

    Picture The Inquirer.Co.UK


    In fact many people are saying that the new Vista OS is a lot like the Mac OS X and that a lot of what is in the new Microsoft operating system is a deliberate copy of the Mac OS X software.
    Longtime Windows development chief James Allchin wrote in a January 2004 e-mail to Microsoft CEO Steve Ballmer and company co-founder Bill Gates that the software vendor had “lost sight” of customers’ needs and said he would buy a Mac if he wasn’t working for Microsoft.
    “In my view, we lost our way,” Allchin, the co-president of Microsoft’s platform and services division, wrote in an e-mail dated Jan. 7, 2004 … “I think our teams lost sight of what bug-free means, what resilience means, what full scenarios mean, what security means, what performance means, how important current applications are, and really understanding what the most important problems our customers face are. I see lots of random features and some great vision, but that does not translate into great products.”
    Allchin, who has headed various aspects of Windows development since the mid-1990s but plans to retire at the end of this year with the shipping of Windows Vista, later wrote in the same e-mail that he would buy a Mac if he was not a Microsoft employee.
     Troy Wolverton reports for The San Jose Mercury News. ” Apple plans to release Leopard, the fifth revision of its rival Mac OS X software. As with previous updates, Leopard will add a number of new features to the operating system… could prove important for Apple. In recent years, the company has made much of the differences between the Mac OS and Windows. Macs are more stable, more secure and easier to use, the company has repeatedly told potential customers.”

    Wolverton reports, “Consumers appear to be listening. In recent quarters, Apple has repeatedly gained share in the PC market with its growth rates outpacing that of the broader industry. Meanwhile, more than half of all Macintosh computers sold in the United States are being bought by consumers who are new to the platform, either because they’ve switched from Windows or have never owned a computer before, CEO Steve Jobs said at Macworld.”

    “‘Some people may say Vista is close enough (to the Mac OS), and that’ll be good enough for me,’ said Bob O’Donnell, an analyst who covers the PC industry for research firm IDC,” Wolverton reports.

     

    Looking For A Smart Phone Try the M600i

    One of the things that I love doing with consumer electronic products is to test them in a real live environment. So as I trotted off to the CES Show in Las Vegas I took along the new Sony Ericsson M600i mobile phone that is also an organizer MP3 player and all round handy device.

    What I found good about this device was that it was simple to use as one has a stylus, touch key to flick through the menu’s and a scroll button.  It is also compact and lightweight unlike similar devices from iMate or Palm.
    A top of the range 3G touch screen phone the device was not without its problems but these were easily overcome.  When travelling, I always set my portable device on the local time for the region I am in with my home time set as the second time. The only problem with this device was that it kept resetting itself to my home time not the region I was in time. This in turn stuffed up my diary.
    The phone also locked up every so often and the only way to fix this was to take out the battery and reset which can be slow as one of the setbacks with this phone is that it takes several minutes to boot up from scratch and entwer a Sim code.


    In addition I travelled with a notebook running Vista and despite the enterprise version of this software being released in November 06 Sony Ericsson had failed to post a driver that allows this device to connect to the new Windows operating system.

    But despite this I would highly recommend this phone as an all round good organiser. The phone comes in a choice of two very colours which are granite black & crystal white coloured casing. The casing is extremely thin considering all the features that are in this phone.  During my trip was able to compare the M600i and the new iPhone from Apple and what is crystal clear is that we are moving into an era when high quality touch screens in phones will become the norm for many power users. Ironically I felt that the M600i was of a higher quality than the Apple offering however these are early days and what was shown at Macworld were prototypes.

    Overall the M600i is a very stylish conscious phone that is slim & refined. The built in features resemble the features incorporated in Sony Ericsson P910i which is a mobile office styled mobile phone.
    One of the things that I love doing with consumer electronic products is to test them in a real live environment.  So as I trotted off to the CES Show in Las Vegas I took along the new Sony Ericsson M600i mobile phone that is also an organizer MP3 player and all round handy device.
    What I found good about this device was that it was simple to use as one has a stylus, touch key to flick through the menu’s and a scroll button.  It is also compact and lightweight unlike similar devices from iMate or Palm.
    A top of the range 3G touch screen phone the device was not without its problems but these were easily overcome.  When travelling, I always set my portable device on the local time for the region I am in with my home time set as the second time. The only problem with this device was that it kept resetting itself to my home time not the region I was in time. This in turn stuffed up my diary.
    The phone also locked up every so often and the only way to fix this was to take out the battery and reset which can be slow as one of the setbacks with this phone is that it takes several minutes to boot up from scratch and entwer a Sim code.


    In addition I travelled with a notebook running Vista and despite the enterprise version of this software being released in November 06 Sony Ericsson had failed to post a driver that allows this device to connect to the new Windows operating system.
    But despite this I would highly recommend this phone as an all round good organiser. The phone comes in a choice of two very colours which are granite black & crystal white coloured casing. The casing is extremely thin considering all the features that are in this phone.  During my trip was able to compare the M600i and the new iPhone from Apple and what is crystal clear is that we are moving into an era when high quality touch screens in phones will become the norm for many power users. Ironically I felt that the M600i was of a higher quality than the Apple offering however these are early days and what was shown at Macworld were prototypes.

    Overall the M600i is a very stylish conscious phone that is slim & refined. The built in features resemble the features incorporated in Sony Ericsson P910i which is a mobile office styled mobile phone.

    The M600i comes with a very clear large 262k colour screen (240 x 320 pixels) which is the perfect size & provides the perfect quality for viewing video clips, email, messages & viewing all that the user desires on the Internet. The phone comes complete with a video clip feature & the user can also use the video streaming option.

    Sony Ericsson has made things very easy for the user of the M600i and I felt very comfortable using this phone in a busy environment like the CES Expo show floor.

    A user can access  3G technology to the full by surfing the Internet with their M600i & at the very same time receiving an incoming call or even making an outgoing call.

    The integrated mobile RSS feed provides the user with an up to the second news updates directly to their phone. A user can also add software & applications very simply to the M600i as it has a Symbian OS operating system. However I missed access to key word documents.

    By interfacing the phone with my Windows XP desktop PC I was able to download more than 2,000 contacts however it was very slow compared to Active Sync between a Windows Mobile phone.

    While it isn’t as thin as the new Motorola Q which is set to be launched in Australia soon , it’s still slim in its own right, measuring only 10.68 centimetres by 5.58Cm by 1.52cm wide. This made it easy to carry around.

    It looks sleek and feels comfortable in the hand, thanks to its smooth metal body and softly rounded corners. It is also is one of the smaller smart phones we’ve seen.

    Finally one of the best things about the M600i is the amazingly large and bright QVGA touch screen. Measuring 6.35Cm  diagonally, the LCD boasts a 240×320-pixel resolution and 262,144 colours–markedly better than a lot of other phones we have reviewed.

    The screen was saturated with colour, images and text are sharp and very easy on the eyes. The backlight timer is adjustable, as are the themes, wallpapers, colours, and menu style (grid or list views). Because of its touch-screen interface, you can easily navigate through the menus just by using the included stylus (it’s housed in a skinny slot on the upper-left side). You can also choose to use handwriting recognition, a virtual keyboard, or the dual-function QWERTY keyboard for text input. The touch screen shows smudges after a while, especially if you end up using your finger to select menu options instead of the stylus.

    Conclusion:

    At the end of the day would I want this phone as my permanent organiser: the answer is yes, as no phone is perfect and this one is close enough to be totally acceptable.

    Sony Ericsson M600i
    Company: Sony Ericsson
    RRP: AU$849

     

    JB Hi-Fi Wants A Crack At Officeworks Claims CEO

    JB Hi Fi, which recently reported a 39 percent increase in profits, wants a crack at owning the Coles Myer Officeworks group according to the company’s CEO Richard Uechtritz.

    “It will be a big ask for us, but we would love to own Officeworks,” said Uechtritz.

    The JB Hi Fi CEO who is currently witnessing strong sales of computer gear in the JB Hi Fi stores believes that Coles will be sold soon, however, he doubts that the Officeworks operation will be broken out from the Coles Group. “Coles is up for sale and Officeworks is a nice fit for us” he said.

    He also said  that JB Hi Fi which achieved an 8 percent increase in sales last quarter was on track to significantly increase sales of computer gear at the expense of arch rival Harvey Norman which also wants a crack at owning Officeworks.
    Harvey Norman executive chairman Gerry Harvey says he would also be interested in buying the Officeworks business in any break-up of Coles Group.

    Gerry Harvey recently told The Australian newspaper that he had yet to discuss the possible acquisition with Coles, which recently flagged an “ownership review” of all its operations after downgrading earnings forecasts for 2007-08.

    “But sooner or later those businesses will come on the market and they’ll contact all the parties that they know will be interested,” he said. The stationery, office furniture and business technology retailer, which analysts value at $1-$1.5 billion, would be highly sought-after and the price might be prohibitive, he said.
    During an interview last year Gerry Harvey admitted that one of his biggest disappointments was that he did not launch a US style Home Depot in Australia after seeing its operations in the US some years ago. “I missed out on that” he said “It was a big mistake”

    “I won’t buy Officeworks for the sake of buying Officeworks,” Mr. Harvey told the ABC’s Lateline Business program recently.

    Intel Plans More Chips But Viiv Uncertain

    Intel who could possibly dump the Viiv platform because of a lack of interest by PC manufacturers plans to ship the Nehalem chip in 2008. It said customers will be able to choose from single-core to eight-core versions, which are the equivalent of eight electronic brains on a single chip.Intel also said it plans to add some graphics capability onto the chip. AMD is currently working on a similar design associated with its $5.4 billion acquisition of ATI Technologies last fall.
    AMD is facing increased pressure from Intel, which wants to win back market share it’s lost the past three years. To carry out that plan, Intel intends to release several new chip lines through 2010.
    Since last summer, Intel has unleashed 40 new microprocessors for desktops, laptops, and servers. AMD began to combine the memory controller with the central processor when the company launched its Opteron server chip.
    The processor, which uses so-called direct connect architecture, rejuvenated AMD’s fortunes, helping it dent Intel’s worldwide market share and forcing Intel to admit it made some technological missteps.
    AMD now commands 25% of the world’s microprocessor market, up significantly from what it had before it rolled out the Opteron line.
    Its encore to Opteron is called Barcelona, which is slated to hit the market by mid-summer. Barcelona is the chipmaker’s first major design refresh in more than three years.
    Intel’s plans are “further validation that their current architecture will not be competitive with Barcelona until they make this transition that we showed the industry in 2003,” AMD Vice President Randy Allen said in a prepared statement.
    Barcelona will compete with a quad-core processor Intel launched this past November. AMD said its product won’t force customers to make “wholesale infrastructure changes in order to achieve incremental performance gains.”
    Last month, AMD warned it won’t meet its previous first-quarter financial targets as it struggles with weaker prices for its microprocessors and supply problems.
    “It is becoming obvious that AMD’s only weapon, outside of Barcelona, is price,” wrote Doug Freedman, analyst at American Technology Research.
    He projects Intel will recapture market share in the server space – where AMD has hurt Intel the most – and concede less profitable parts of the PC market to AMD. 

    Acer Looking At Buying Gateway

    Acer is looking at buying Gateway as a means to shore up its weak position in the US market, company insiders are saying. Recently Gianfranco Lanci, president of Acer, said an acquisition is one option the company is considering but that the company is in no hurry.

    An acquisition target needs to complement Acer, and as such, doesn’t necessarily mean it has to be a notebook maker, claimed Lanci, who also has a passion for sponsoring sporting events.

    Another company in Acer’s sights is BenQ, a company that was once part of the Acer stable. However BenQ executives, many who are ex Acer management, say that a sale to Acer would be the “last resort”. “This is just a change in terms of perspective,” Lanci told reporters at the annual CeBIT trade show in Hanover, Germany.

    Until recently, Acer which started a notebook war in Australia last year that it is now regretting due to a lack of profitability, was committed to expanding its PC business through growth alone. “We started to realise that to grow organically may be okay, but we are today in the position that the possibility of an acquisition is not rejected 100 percent as it was in the past,” Lanci said, noting this change in thinking occurred over the last six to 12 months.

    That change became apparent earlier this week when The Wall Street Journal newspaper quoted Acer Chairman J.T. Wang, saying the company planned to make a meaningful acquisition this year and is looking at potential candidates.
    “This does not mean that we are going to do an acquisition in the next few weeks,” Lanci said. Lanci has some experience with acquisitions: He came to Acer in 1997 with the acquisition of Texas Instrument’s notebook PC division. That acquisition laid the foundation for Acer’s successful notebook PC business today.

    Any future acquisition by Acer would have to help the company meet its aim of overtaking rival Lenovo Group to become the world’s third-largest PC vendors this year. Lanci said the company is well on its way to meeting this goal, and believes Acer may have taken the No. 3 spot during the first quarter, which ends later this month.

    Gerry Harvey Forecasts Rate Rise As US CE Market Crashes

    Harvey Norman boss Gerry Harvey has said that it is inevitable that interest rates will have to rise this year. The comments come as the USA consumer electronics market witnesses a massive downturn in profits and sales.

    The Reserve Bank’s recent decision to leave interest rates unchanged yesterday has given a reprieve to retailers in Australia, who can look forward in the short term to continued strength in consumer spending.

    However CE trends in the USA where major chains like Circuit City are reporting losses and other chains like Best Buys closing stores may be a worry for Australia with some analysts claiming that the same will happen in Australia as retailers continue to erode margin from products.

    The central bank recently left the official cash rate at 6.25 per cent, despite the release of figures earlier in the week showing annual growth in retail trade running at 7 per cent. But according to the Australian newspaper Legg Mason analyst Tony Pearce said a rate hike in coming months was now more likely, and retailers vulnerable to a downturn in discretionary spending such as David Jones, Harvey Norman and Myer would soon be brought back to earth.

     

    “There are no impediments to retail spending at the moment – employment remains very strong and petrol prices have gone up but aren’t out of control,” he said. “If you visit those stores, people are queued up to buy stuff at the weekends. There’s no sign of any slowdown, but a rate hike will be a bit of a wake-up call, which will be healthy in the long run.”

    But Gerry Harvey, executive chairman of Harvey Norman, said he didn’t expect a rate hike to dampen consumer demand.

    “I think spending will remain strong even if rates do rise but I don’t think the RBA has any choice – they have to raise rates in the future, in my opinion,” he said.

    “At the moment our sales are so strong I’m amazed … they’re stronger now than when interest rates were at 4.25 per cent. Even if it goes up to 7.25 per cent, sales might be okay.”

    Wesfarmers chief executive Richard Goyder said he was happy with the RBA’s decision.

    “I am pleased about that from Wesfarmers’ point of view but I am also pleased about it from an economic point of view because I think it is right,” he said.

     

    “We have had very strong growth over a lot of years in Australia and keeping that balance between inflation and growth is important.”

    Commonwealth Bank chief economist Michael Blythe said a rate hike was possible in May, if first-quarter consumer price figures released later this month were on the high side.

    “A renewed down trend in the unemployment rate and a lift in credit growth would be the signals for an imminent rate move,” he said.

    In the USA Circuit City Stores posted net losses for its 2007 fourth quarter, blaming the shortfall on falling flat-panel TV prices and poor PC  sales.

    For the fourth quarter, ended Feb. 28, the retail chain posted a net loss of $12.2 million on sales of $3.9 billion, and $11.8 million on annual sales of $12.4 billion. Net sales did increase for both periods, growing 1.2 percent for the quarter and 7.9 percent for the year. These figures are down considerably from last year when Circuit recorded a fourth-quarter net profit of $141.4 million along with a net profit of $139.7 million profit for the year.

    For the quarter, comp-stores sales fell 0.5 percent, but were up for the year by 5.8 percent.

     

    Compounding the product pricing issues, Circuit’s net earnings were hurt by payments related to store closings and other reorganization-related charges. In a post 2007 fiscal move, Circuit City reported another major shake-up last month.

    “Fourth-quarter sales growth was somewhat less than we expected. During the quarter, flat-panel television average selling prices were well below the prior year, and our PC hardware business experienced volatility around the Microsoft Windows Vista operating system transition,” he said. “PC hardware posted strong sales growth in both December and February, but January sales were impacted as we kept PC inventories lean in advance of the transition.”

    Circuit said its video category generated low-single-digit comp-store decreases for the quarter, with overall sales for the year being described as flat compared with 2006. This situation was created by double-digit declines in projection and CRT TV sales, which offset a similar increase in the flat-panel category.

    Other areas experiencing declines were digital imaging, camcorders, DVD hardware, desktop PCs, satellite radio and home audio.

    Helping the chain’s balance sheet were sales increases in notebook computer, portable audio, navigation and video game products. The company expects these categories to continue to grow this year.

     

    Apple iPhone Launch Date Confirmed

    The new Apple iPhone will be released in Australia in the 2nd quarter of 2008 according to an insider at a major Australian Telecommunication carrier with whom Apple has been having talks.

    And despite Telstra snubbing the phone late last year the carrier could well carry the phone due to their Edge wireless technolgy. However insiders say that it will be on Telstra terms not Apple terms if Apple wants access to the Telstra network.

    The US version of the phone will go on sale on June 11 2007 which coincidence with the opening day of the Apple Worldwide Developers Conference. scheduled to be held in San Francisco from June 11 through June 15.

    In addition Cingular is confirming that the release date will be June 11. A customer service manager at Cingular called by a CNet journalist gave them that date late.

    A spoksperson for Appple Australia was not available to comment.

     

    Hello Moto..It’s Me I’m On The Top Of Everest

    Motorola has scored a world first after a British climber became the first person to make a mobile phone call from the top of Mount Everest.

    Mountaineer Rod Baber, 36, removed his oxygen mask to make two calls from the mountain’s north ridge. In the first call to a special answerphone set up by sponsors Motorola he said: “It’s amazing. The Himalayas are everywhere.”
    Mountaineer Rod Baber,

    The feat was made possible by China Telecom which set up a base station at Rongbuk, about 8km from their base camp and 16km  from the summit.

    Telecommunications on the mountain had been restricted to shortwave radio, which has a limited range, and satellite telephones, which are expensive and can be disrupted by bad weather. Before radio the best form of telecommunication on Everest was Morse code, transmitted between base camps along copper wires laid by the ill-fated Mallory-Irvine expedition of 1924.

     

    The advent of relatively cheap mobile telephone calls on the world’s highest mountain marks another milestone in the relentless expansion of cellphone networks around the globe. While some may lament the mobile’s intrusion into one of the planet’s great wildernesses, many mountaineers welcome it as a potential lifesaver. “In terms of improving safety, any way you can improve communications could help to alert base camp in an emergency,” said Alun Richardson, secretary of the British Association of Mountain Guides, who has been on Everest twice.

    After first calling Motorola Mr Baber from Cirencester in the UK  then called his wife, braving high winds and temperatures of -30 degrees.

    Making the 40 second call between deep breaths of oxygen he said: “Hi, it’s Rod making the world’s highest phone call on 21st May.

    “I’ve got no idea what time it is. It’s 5.37. It’s about minus-30. It’s cold. It’s fantastic. The Himalayas are everywhere. I can’t feel my toes. Everyone’s in good spirits. It’s amazing. I cannot wait to get back.” Mr Baber also set a separate record for sending the world’s highest text message from Everest’s north ridge.

    “One small text for man, one giant leap for mobilekind – thanks Motorola,” read the message.

     

    The new records are the latest in a long line for Mr Baber who, at 29, became the fastest man to scale the highest peaks of every European country in 835 days. He also holds the world record for climbing more of the world’s highest points than any other person.

    “I was originally on schedule for six months, which would have meant one peak every four days – but because of the war in Kosovo and Kurdish rebels in Eastern Turkey, there was an enforced two-year gap,” he said in 2002.

    “I’ve already climbed to the highest point in every country in Europe, so it was a natural progression to want to climb to the highest point in all the other continents.

    “I want to be the first person to climb to the highest point in every country in the world. Fifty years ago, when Everest was first conquered, mountaineers couldn’t even contemplate the kind of multiple challenges that we are setting ourselves today.

    “With all the new equipment and advanced climbing technology, the impossible is now within our grasp.”

    A Motorola spokeswoman said the adventurer, who spent seven days climbing to the summit of Everest, had reached it in clear but windy weather.

    Although bulky satellite phones have been used on Everest for some time, this is the first time anyone has made a mobile phone call from the top of the mountain.

    The record only became available last year when China installed an antenna 12 miles from the peak, allowing line-of-sight transmission with the summit. Special batteries for Mr Baber’s handset were taped to his body to ensure they stayed at a high enough temperature to power the phone.

    Mountaineers typically only stay on Everest’s summit for 15 minutes because of the extreme conditions.

    Mr Baber and his team will now make a gradual descent down the mountain side.