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 62 of 91

    Smart Office

    Dick Smith Store Revenues Slump, Creditors Meeting Delayed

    Administrators to the failed Dick Smith Chain have moved to delay the next creditors meeting until August 2.

    A none binding information memorandum relating to the sale of Dick Smith assets, was released earlier this week, offers have to be in by January 27. 

    The receivers claim that have attracted more than 30 expressions of interest to buy some or all of Dick Smith’s assets.

    However, ChannelNews has also been told that of the offers already received several are “extremely low ball” offers of less than $25M.

    Earlier today  recievers Fewrrier Hodgson said that Dick Smith will close its network of outlets in David Jones department stores as the company’s receivers try to find a buyer for the failed retailer. 


     Ferrier Hodgson said that the 27 concession stores located in David Jones stores (known as David Jones Electronics Powered by Dick Smith) would be closed.


    In a statement the receivers – James Stewart, Jim Sarantinos and Ryan Eagle – said the closure would affect 181 jobs, mostly part-time and casual.

    The receivers are in the middle of an attempted sale of Dick Smith after it went into administration in early January. An information memorandum has recently gone to potential buyers.

    “The receivers have been undertaking an ongoing review of the operations of the group with a view to maintaining stable operations in order to facilitate its sale as an ongoing concern,” they said in a statement.”As a result of this review, the receivers have determined that they will no longer continue to operate the 27 David Jones Electronics Powered by Dick Smith concession stores, contained within David Jones department stores.




    Several Dick Smith store managers who have contacted ChannelNews said that “very few” customers are visiting Dick Smith stores and those that do are walking out with no purchases.

    Recently existing stores were instructed to lift the price of Dick Smith and Move branded house products a move that some managers claim has seen a $5 cable suddenly priced at $25.

    Install the receivers had targeted to generate $18M a week by keeping the stores open according to sources, however revenues have slumped to sub $8M with the real possibility emerging that stores could be closed down and existing staff retrenched. 

    Dick Smith’s administrators confirmed to Fairfax Media that they intended to file a court application within the next week seeking orders to extend the period of time to convene the second meetings of creditors up to August 2.

    The administrators – Joseph Hayes, Jason Preston, Jamie Harris and Matt Caddy of McGrathNicol – flagged the postponement at the first creditors meeting last week but did not indicate the length of the proposed postponement.

    ChannelNews has also been told that several organisations who were initially interested in the Dick Smith New Zealand operation are now walking away from the prospect of buying the NZ stores, after it was revealed that operating costs associated with the NZ group were being picked up by the Australian operation in an effort to make the business look profitable in New Zealand. 

    A spokesman for McGrathNicol said the postponement would give the administrators more time to assess numerous creditors’ claims and to stabilise Dick Smith’s operations.

    Dick Smith called in McGrathNicol as voluntary administrators and a syndicate of lenders appointed Ferrier Hodgson as receivers on January 4 after lenders withdrew their support in the wake of slumping sales and rising debts.

    Secured creditors, including HSBC and National Australia Bank, have staked claim to about $140 million while unsecured creditors including Macquarie Group are owed about $250 million.

    Shareholders, whose shares were valued at $84 million at the time of the collapse, will only be repaid if Ferrier Hodgson can find buyers to stump up more than $400 million for Dick Smith’s assets, including its standalone chain Move and the New Zealand business.

    Microsoft Moves To Take On PC Partners With Their Own Premium Notebook

    Microsoft is set to take on their Windows 10 PC partners with a notebook of their own plus an all new two in one Surface Pro.

    The big US software Company now want a share of both the PC software and hardware markets have rolled out a hardware line-up aimed at stripping notebook and two in one sales from the likes of Lenovo, Dell, HP, Acer, Toshiba and Asus. 

    Not only does Microsoft believe it can replace a partners two in one offerings with their own Surface Pro 4, but it also wants to “redefine everything you expect in a laptop” and take on the Apple MacBook with the all-new Surface Book.

    The company also announced first-quarter availability of a HoloLens developers kit so developers can create games and other apps for the company’s planned HoloLens virtual-reality headset. The headset’s capabilities were demonstrated on stage in the USA overnight, showing how holographic robots would appear to break through the walls of your office or living room while you fight them off with a virtual wrist-worn weapon.

    Also new: Lumia phones, a new Microsoft Band, and a limited-edition Halo 5 Xbox One console which will go on sale at JB Hi Fi later this month.
    The company’s first-ever laptop, called the Surface Book, “redefines everything you expect in a laptop,” said Panos Panay, head of Microsoft’s devices group. The 13.5-inch laptop is a convertible laptop whose screen also detaches. The machined-magnesium laptop starts at US$1,499 and will be available Oct. 26 pricing in Australia is tipped to top $2,000.


    The 700gram, 7.7mm-thick laptop features sixth-generation Intel Core processor and is promoted as being twice the fastest 13-inch laptop in the world and twice as fast as the MacBook Pro. 

    It comes with Windows 10, 12-hour battery, a 3:2 display that assumes the proportions of A4 paper, more than 6 million pixels with 267 PPI, two USB 3.0 ports and a backlit keyboard.


    Click to enlarge


    Surface 4 Pro
    The fourth-generation Pro gets a larger screen size, more RAM and storage, a new pen, and thinner design with a starting price higher than previous models. It will be available Oct. 26.


    The screen size goes to 12.3 inches from 12 inches with 267 PPI and more than 5 million pixels, or 60 percent more pixels than the Surface Pro 3.  RAM options go up to 16GB from8GB, and storage options go up to 1 TB from 512MB. Depth goes to 8.4mm from 9.1mm.

    With new PixelSense display technology and a new pen that adds 1,024 points of pressure, users experience a natural ink-flow-like experience, said Panay. The pen also adds an eraser, one-year battery life, and magnetic attachment to the top of the tablet for storage.

    Also new are interchangeable pen tips optimized for different tasks such as writing, drawing, sketching and the like. It also comes for the first time in five colour options.
    With the Windows 10 Windows Hello feature, users can log in via enterprise-grade facial recognition, which will recognize different users and automatically set the tablet to that user’s preferred settings.

    The new Pro Type cover is said to be thinner yet sturdier, adding fingerprint ID and a 40 percent larger trackpad on the optional detachable backlit keyboard. A Surface Pro docking station features four USB 3.0 ports and two 4K DisplayPort connections.

    Lumia Phones


    Lumia 950
    Two of three new Lumia phones are positioned as premium phones, given Microsoft’s previously stated intentions to increase its focus on business and productivity users. All three run the Windows 10 OS and are the first phones with Windows Hello, which uses facial recognition to unlock the phones.

    The phones are the 5.2-inch Lumia 950, and the 5.7-inch Lumia 950XL. 

    They will be available in November with Windows 10 apps such as Outlook and PowerPoint. The phones will offer the same UI as the apps do on tablets and computers. “We want you to put Windows in your pocket,” said Panay.

    They feature Qualcomm hexacore and octacore processor, respectively, with 564 PPI and 518 PPI OLED displays, respectively. Both come with 32GB storage and microSD Card slot compatible with future 2TB cards. They also feature USB Type C connector, which delivers 5Gbps speeds and charges the phone up to 50 percent in less than 30 minutes.


    Click to enlarge


    Lumia 950XL
    Other key features include 20-megapixel main camera, 4K video capture, Carl Zeiss camera optics, and triple-LED RGB flash to deliver natural colours.

    With Glance Screen, users can glance at calendar items and other notifications without consuming battery life, Panay said.

    They also feature tablet-class liquid cooling borrowed from Surface tablets:” to push the hardware hard,” Panay said.

    The third phone is the LTE-equipped Lumia 550 with quad-core processor. It’s due in December.

    A Display Dock lets users connect the phones to monitors and keyboards to deliver a desktop-like Windows 10 interface with a task bar at the bottom and the phone’s Live Tiles turning into the monitor’s start menu. All apps scale up to monitor size. The dock comes with three USB ports and 1080p HDMI and DisplayPort outputs.
    Microsoft Band

    Due Oct. 30, the second generation Microsoft Band gets a curved screen, more flexible design with no hard edges, and OLED display that is more responsive to touch. It’s still focused on health and fitness and displays notifications like before.

    The price goes up to $249 from $199, and it adds such new features as a barometer to track elevation. The VO2 Max app estimates the maximum amount of oxygen that a wearer can process in a minute. Another new app is a golf app that counts swings but not practice shots and generates an automatics score card.

    Like before, it offers built-in GPS, Cortana voice-command technology, calendar and text notifications, caller ID, and sensors to monitor heart rate, steps, calories burned and sleep.
    HoloLens

    Executives described the work-in-progress as the only VR headset offering “mixed-reality gaming,” projecting holograms into a user’s living room to that consumers can wear virtual weapons around their wrist to battle robots that appear to break through the walls of their house. Microsoft also sees applications for productivity and health care.


    Click to enlarge
    New graphic memory processor in notebook


    The company began taking applications today from developers who want to use the platform to create apps. The developers kit will be available in the first quarter at $3,000.


    Click to enlarge
    New Microsoft band, one size looks bulky, no round face.

    Samsung On Fire In IT Market After Dud Start

    After struggling for years in the IT market, Samsung Australia is now reaping the benefits of a major restructure, with the company now reaching revenues of $18.5 million dollars a month compared to $6 million a year ago.

    Under the leadership of former BenQ Australia Vice President Phil Newton, Samsung Australia has become #1 in the monitor display market. It has also lifted sales of its commercial display screens by 40 per cent to snare the #1 slot ahead of Panasonic, Sony and LG. Samsung is also the #1 vendor in the multi-function laser printer market.

    After getting out of the notebook market two years ago, Samsung is now struggling to keep up with demand, with the company earlier today launching a new range of notebooks, including several models with 12-hour battery life and built-in Quad Band 3G Wi Fi capabilities.

    According to Newton, both Telstra and Vodafone are now ranging their notebooks, with Optus tipped to offer a Samsung bundle next month.

    Also selling their notebooks are retailers JB Hi-Fi, The Good Guys and Bing Lee.

    According to Newton, 35 per cent of Samsung notebook sales are coming from telecommunication carriers, 45 per cent via retailers and 20 per cent via the channel serviced by Synnex and Ingram Micro.

    “Next month we will have our first $20 million month, and I am confident that with the introduction of new Samsung IT products and the expansion of our partners, we can grow our monthly sales significantly,” said Newton.

    Late yesterday, Samsung was hosting several major resellers, including senior executives from Harvey Norman, which currently doesn’t sell Samsung notebooks. Samsung has also launched a new range of notebooks, which Newton is confident will help Samsung grow revenues from this category.

    “Today we have an excellent team in place at Samsung, as well as a strong range of products that keep just getting better and better. We have big advantages in that we manufacturer a lot of our components like storage, and we have excellent related product categories like TV’s and mobile phones. For example, with the carriers, we are now selling both mobile phones and notebooks and this helps. With the retailers, we are selling Samsung TVs, and IT products including notebooks, printers and display screens.

    “When I came on board we had 1 per cent of the commercial display market, today we have over 40 per cent,” Newton said.

    According to Mark Deere Jones, General Manager of Commercial Display at Panasonic, “Samsung has definitely become a threat.”

    “They have not only benefited from a restructure, but the exit of TV brands like NEC, Pioneer, Hitachi and Philips from the commercial display market. Both Samsung and Panasonic have also taken market share away from both Sony and LG in this market,” he said.

    In the monitor display market, Samsung is #1 in the consumer market, with Newton claiming that he is now shifting 40,000 units a month.

    Sharper Image Looking For OZ Distributor

    Sharper Image who made a fortune selling gadgets for smart houses and then lost it all when they went belly up last year in the USA is back and they are looking for either a distributor or retailers in Australia to sell their new range of products that were launched at this year’s CES show in Las Vegas.

    The private investors who purchased the brand name when “The Sharper Image” filed for Bankruptcy Protection in February of 2008 believe that the name and the products branded with the name “have enormous potential in Australia” according to a Company spokesperson at this year’s CES where they introduced a new range of iPod attach devices, Internet Radio’s and what they describe as “health care” products.


     Rather than operate its own web site, catalogue business or shops the Company wants to cut deals with distributors or retailers to whom they will license their products and brand name.


    The new Company has struck deals with HoMedics, a manufacturer of health and grooming products, luggage maker EnE and others to produce new products.


    The name The Smarter Image was purchased by private investment Company Blue Star Alliance, Gordon Brothers and Hilco Consumer Capital for $74 million in May.


    Since then, the company has reconstituted itself (minus the stores) to become a “global lifestyle brand licensor.”
    “We are keen to do business in Australia we have the brand name and the products that we believe will appeal to Australians. We will be expanding outside of the consumer electronics area so we could well end up with two or three different distributors in different markets” A Sharper Image spokesperson said at the CES Show.

     

    In the past the Company has flogged ionic air cleaners and fogless shaving mirrors as well as battery powered toys and massage chairs.


    “Sharper Image was an aspirational brand,” said Federico de Bellegarde, the company’s vice president for licensing. While people wanted the products, not enough could afford them. “Now we can be in consumer electronic stores and Bath & Bedroom stores as well as department stores,” Mr. de Bellegarde said.


    The new company, which has fewer than 10 employees, kept five of its original product licensees. It currently has the Sharper Image name on 40 furniture and accessory products. Stores Its big push will come at the end of this year, when it releases “hundreds” of new, less-expensive products in partnership with 12 unnamed partners.


    At the Consumer Electronics Show, the company showed a range of new products including home audio gadgets like iPod and iPhone docks, a floating waterproof wireless speaker, and a shower speaker that receives music wirelessly from an iPod. The products ranged from $120 to $300.
    The iPhone dock, which includes a motor to swivel the phone horizontally when watching videos, will sell for about $120, while the floating speaker will cost about $110.

    The company is also working on a new generation of its famous air purifier which ended up being slammed by consumer affairs departments in the USA.

    CISCO Grabs Big Share Of SMB Market

    Cisco in partnership with distributors like LAN Systems and Express Data have helped CISCO grow their share of the SMB market by 40%.

    Sales to small and medium size businesses through its distribution partners have surged almost 40 percent over the past year, Cisco Systems has said.

    The taking of more than 1 million orders is a record for the company, a Cisco spoksman said. Key distribution partners for Cisco’s efforts to drive more sales to the small, medium (SMB) business segment  are Lan Systems and Express Data. “Distributors are the backbone of our SMB channel strategy and last year when we announced an increased focus on the SMB market we knew that if we executed properly we would see a spike in annual distribution order volume,” said John DiLullo, vice president, of worldwide distribution at Cisco.

    “However, hitting the million order milestone in a single year came much quicker than we anticipated and it’s due in large part to our distribution partners,” he added. “They provide personalized ordering services, competitive pricing, and technical pre- and post-sales telephone support for even the smallest customers. We would need to hire an army of people to provide this level of support.”

    Cisco has over the past 18 months introduced more than 30 products focused on the SMB segment as well as signed on several new channel sales partners and offered more support services, financing, applications and training.

    Lasers Take Over MFD Low End

    IDC says the printer versus copier competition is heating up returning some interesting results in the colour part of the market.

    In the low-end colour space, printer-based colour MFDs grew 2212 per cent while copier based colour MFDs declined by 1 per cent between the final quarter of 2004 and 2005.

    IDC’s Katarzyna Czubak said, “The laser MFD market has seen major commodisation and downward pressure on cost per page. This is causing fundamental changes in the market positioning of printer and copier based MFD vendors.

    “End users now require more ‘bang for their buck’ from the devices, so copier vendors are introducing higher-end devices and slowly leaving the low end of the market for printer based MFDs.”
    Generally, IDC views copier-based MFDs as being primarily in the high end/high volume section of the market, while printer-based MFDs make up the the low end/low volume segment of the market.

    While the multifunction laser (combined mono and colour) market grew soft at the end of 2005, the Q4 results were still up more than 50 per cent on the equivalent 2004 numbers says IDC.

    IDC Australia says the laser MFD market grew less than 1 per cent sequentially over Q3, but increased 50.5 per cent from the same period in 2004.

    “HP had a solid quarter to maintain first position with almost 17 per cent market share. Canon had a market share decline of almost 2.5 per cent sequentially, which was caused by decrease in printer based MFDs sales.

    “Fuji Xerox finished in third position gaining almost 2 per cent market share sequentially as a result of the introduction of new models. Brother was able to rise to the fourth position in the market as they introduced their first colour MFD during the quarter.

    Rounding out the top 5 was Samsung, who declined by over 2 per cent in market share,” said Czubak.

    Top 5 Laser MFD Vendor Market Share
    Overall Share:

    HP

    16.9%

    Canon

    14.9%

    Xerox

    13.6%

    Brother

    9.4%

    Samsung

    8.9%

    Others

    36.3%

     

     

     

    Wireless Homes Is The Future Survey

    A recent consumer survey demonstrates that while respondents with existing home networks are fairly evenly split between Ethernet and Wi-Fi, future home network deployments are largely planned as Wi-Fi networks.

    A recent  consumer survey demonstrate that while respondents with existing home networks are fairly evenly split between Ethernet and Wi-Fi, future home network deployments are largely planned as Wi-Fi networks. The 640 tech-savvy consumers who participated in the survey still chose data-networking applications over consumer electronics applications as the applications for which they were most interested in using Wi-Fi connectivity.

    “Consumer electronics vendors have a challenge to educate consumers about Wi-Fi and to overcome the perception that Wi-Fi is simply a data networking technology,” says Norm Bogen, In-Stat analyst. “Nevertheless, Wi-Fi silicon vendors have fully committed to this market segment, and In-Stat believes the benefits to consumers of Wi-Fi connectivity in consumer electronics devices are significant enough to build a major market segment over the next five years.”

    A recent report by In-Stat found the following:

    – The challenges that Wi-Fi faces, in terms of range, bandwidth, security, and Quality-of-Service (QoS), are being addressed by new standards that have either recently been ratified or are set to be ratified over the next several years.

    – The prevalence of wireless network availability, especially in home networks, makes it increasingly likely that any consumer electronics device would benefit from Wi-Fi connectivity.

    – More PCs in a respondent_s household was positively correlated with a greater likelihood of having heard of Wi-Fi being used in various devices.

    The report, “Untethered Fun: WLAN in Consumer Electronics Consumer Survey” covers the results and analysis of a survey conducted in June 2005 of 640  consumers. The survey examined consumers_ knowledge, attitudes and actions regarding Wi-Fi as a home networking technology in general, and as a means for wirelessly connecting consumer electronics devices, in particular. This report is useful for product managers and marketing directors in Wi-Fi and consumer electronics equipment and semiconductor vendor companies, financial analysts covering these markets, and consultants advising clients in these markets.

    OZ First To Get Win 10 Multimillion Dollar Marketing Campaign Planned

    Australia and New Zealand will be the first Countries in the world to get Windows 10 with several PC manufacturers vying to be the first to deliver a new generation of PC’s running the Microsoft OS.

    Internal Microsoft emails seen by ChannelNews reveal that the Microsoft Corporation is set to use funds originally allocated for Europe to mount a major TV, digital and social marketing campaign in Australia.

    The OS which is set to be rolled out from July 29h in Australia will initially be automatically downloaded to PC’s running Windows 8. 

    Dell has already started accepting preorders for specific products that will Windows 10 on its web store.
    With the upcoming launch of Microsoft’s Windows 10 on July 29, Dell claim that they will ship the preorders on the same day.


    At the same time Windows 8 users in Australia have already been prompted as to whether they want to get the download installed on their PC.

    If you’re using a PC with Windows 7, 8, 8.1, or RT, Windows 10 is free, however if you want to run new applications or services the chances are that you are going to get prompted to pay a monthly subscription fee to get the expanded capability. 

    If you’re running a device operating on a pirated, or non-genuine, version of Windows, Microsoft is planning a “very attractive” upgrade offer. 

    While there was some confusion over Microsoft giving away Windows 10 to pirates, the software giant is now being clear about its free upgrade plans for Windows 10. 

    We already know that Windows 7 and Windows 8.1 users will get Windows 10 as a free upgrade (providing you install within a year of July 29th).

    Now Microsoft is introducing a new way for anyone to get Windows 10 free of charge.

     If you install the latest Windows 10 preview (build 10130) on a machine and use a Microsoft Account that’s registered for the Windows Insider program then you’ll get the final version of Windows 10 free. 

    Windows 10 will stay genuine, so you can clean install the preview right now and simply upgrade to the final bits for no charge.

    This will deliver millions of email addresses for Microsoft who are looking to on sell additional services to users who run the free version of Windows 10.

    Microsoft’s Gabe Aul confirmed this method on Twitter yesterday as part of a new blog post detailing some new changes to the way the company tests Windows 10.

     “As long as you are running an Insider Preview build and connected with the MSA (Microsoft Account) you used to register, you will receive the Windows 10 final release build and remain activated,” says Aul. Microsoft will soon require testers to use a Microsoft Account to receive updated builds, and even when Windows 10 is finalized testers can opt-in and keep receiving future test versions in the coming months. 

    So if you’re running Windows XP or Windows Vista and you’re looking to get a free copy of Windows 10, simply install the preview now and you’ll get the final copy free once it’s ready on July 29th.

    No New PC’s Running Windows 10 On Sale At Retailers As Manufacturers Battle Driver Problems

    No PC manufacturers will have PC product on sale at Australian retailers this week running the new Windows 10 OS.

    Late yesterday two major manufacturers confirmed to ChannelNews that they are having problems with the new OS conflicting with drivers including NVIDIA and Bluetooth drivers and that they have had to reload the new Win OS license onto  thousands of PC’s because of driver problems associated with the new licencing program. 

    One brand who claims that they are not affected by driver problems is Lenovo who yesterday said that they will begin shipping a wide selection of products loaded with Windows 10 “immediately”, however they did not specify when the new Windows 10 product will be in stores in Australia.

    What they did say was that Lenovo has an extensive list of products eligible for a Windows 10 upgrade including popular models like the YOGA 3 Pro and YOGA 500. 

    Lenovo said that they have worked with Microsoft to make the process of upgrading simple, for people with qualified Lenovo PC running Windows 7 SP1 or 8.1 to upgrade to Windows 10. Starting on July 29.

    Lenovo said that they have also upgraded their own apps to work on the new Windows OS while also introducing new apps. 

    They include a new Lenovo Companion 3.0 optimization tool that keeps devices running at peak performance. It can be used at any time to run a full-scale check-up and report back with specific actions to free up space and speed up the device.  

    As a “smart” device control hub, the new Lenovo settings lets users adapt and modify the way their device behaves. 

    For example, when in tablet mode, the product will customize its display and other settings based on its orientation versus in traditional laptop mode. 

    Alternatively, the device’s usage will also alter its settings, for example when watching a movie versus reading an e-book. With SHAREit, customers can quickly transfer files between devices.  For tablet users WRITEit takes the pen to a new level of functionality allowing users to write in any input field with their pen and the handwriting is converted to text.

    Lenovo has also integrated Cortana and REACHit, Lenovo’s new app that allows users who opt-in to search for and manage their content across multiple devices and cloud storage platforms. With REACHit, Cortana becomes even smarter and more personal, enabling users to find their content such as emails, photos and videos in ways they never thought possible. Cortana and REACHit gives users a seamless, intuitive way to search through natural language and contextual understanding. 

    This functionality will be available in beta to Lenovo users starting in the September. 

    UPDATED: Optus Restores Mobile Network After Major Outage

    Optus has finally restored their mobile phone services after a experiencing a “major outage” that affected users of their network in Victoria, New South Wales and Tasmania.

    The problem, identified around 3:30pm, meant customers were having intermittent problems making or receiving calls.

    The company said technicians worked “as a priority” to restore services and issued a statement at 6:30pm saying the problem had been fixed.

    “We apologise to customers and appreciate their patience,” a company spokesman said in a statement.

    “We will continue to monitor these services closely.”

    On Twitter a customer claimed to have smashed his phone in anger about the outage.

    Original story.

    The outage comes shortly after the Singapore owned network started piling on new broadband customers with a $90 dollar broadband package that included six months of free Netflix.

    This resulted in their recently expanded network being stretched according to Optus sources. 

    The latest outage has affected the Companies mobile, Voice, Pre Paid and Post Paid operations.

    Customers are already venting their anger.


    Click to enlarge


    “Awesome service Optus!!! Can’t make work calls. Will u pay for the lost time??” wrote Stef Lesser.

    “Your network sucks, why won’t my phone ring!!” wrote another customer, Shane Dickinson.

    “We’ve identified a fault which means you might experience issues with voice at the moment,” the telco said on its website. “Our team are on to it, and aim to fix this as soon as possible. We’re sorry.

    In Newcastle several businesses who rely on the network for communication with their service personnel and trades are angry that the carrier does not have a backup.

    A senior executive of one Newcastle Company “We are down we cannot communicate with our staff. This is a Company who brags about their reliability Vs Telstra yet they have no back up for essential business who rely on their network to run their day to day operations. We cannot text or voice call”.