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

    Smart Office

    EMC Moves Further Into SMB Market

    EMC have finally consolidated a hardware software solution for SMB organisations following the purchase last year of Dantz.

    EMC have introduced a new line of Insignia storage hardware and software that enable small and medium businesses of up to 20 employees to store, manage, protect, and share business information.

    The EMC Insignia products are designed specifically to address SMB’s needs spanning critical information management and storage issues. Low cost the EMC Insignia products have beeneveloped to work individually, together, and with third-party software and hardware.

     In October 2004, EMC acquired Dantz Development who developed the Retrospect backup and recovery software. Since then the Company has combined the extensive SMB market knowledge acquired through Dantz with EMC’s expertise in information management and storage to create the Insignia product line.

    Joe Tucci, Chairman, President, and CEO of EMC, said, “Small and medium businesses are faced with the same challenges as our enterprise customers – explosive information growth, the need to improve productivity and lower costs, and a requirement for simplicity. EMC Insignia brings EMC expertise in these areas to a new and adjacent market at appropriate price points. Our new solution enable SMBs to focus on growing their businesses rather than expending unnecessary effort to store, manage, protect, and share their information.”

    Larry Zulch, Vice President and General Manager, EMC Insignia, and former CEO and co-founder of Dantz Development  will manage the EMC Insignia business. The EMC Insignia line includes the following new hardware and software products:

    EMC CLARiiON AX Series disk arrays enable SMBs to consolidate and share storage efficiently among multiple computers and capitalise on the advantages of backup to disk. The combination of EMC networked storage for fibre channel or iSCSI delivers easy-to-use, highly reliable data storage at an affordable price.

    EMC Storage Administrator for Exchange SMB Edition information management software works with the EMC CLARiiON AX series to simplify management of Microsoft Exchange Server data, provide fast recovery from an Exchange server failure, and make migration to Exchange Server 2003 a straightforward and streamlined process achievable in just a few hours in many cases.

    EMC Retrospect gives SMBs a simple but powerful way to protect servers, 24×7 applications, desktops, and notebooks. The backup and recovery software is renowned for its ease of use, self-adjusting backup operations, accurate point-in-time restores, simplified onsite and offsite media management, and encryption of backup media with government-certified AES.

    EMC RepliStor SMB Edition guards SMB’s vital information against hardware failure or site-wide disaster. The software provides easy-to-manage replication of data between two Windows computers locally or remotely across the Internet and maintains a continuously updated copy.

    EMC VisualSRM SMB Edition helps businesses stay ahead of information growth and rein in costs while meeting storage needs. This storage resource management software presents a consolidated view of a company’s storage and hosts automated policies to manage it.

    EMC eRoom SMB Edition brings efficiency to how employees, partners, and suppliers work together. The collaboration software provides a browser-accessed, highly secure collaborative workspace to share information, manage projects, and deliver higher-quality products and services.

    “We’re seeing the IT needs of small and medium businesses mirroring those of large enterprises, but on a different scale,” said Ray Boggs, VP of SMB Research at IDC. “SMBs just don’t have the financial and IT resources to deploy the same comprehensive approaches to storage. Small and mid-size firms definitely prefer suppliers that can provide comprehensive solutions, but they also like the option of adding capabilities a la carte as needed. The EMC Insignia line of hardware and software products offers SMBs the flexibility of a complete portfolio of capabilities that work together and can be put into place when the time is right.”

    Pricing and Availability
    The CLARiiON AX100/i, Storage Administrator for Exchange SMB Edition, and Retrospect are available immediately from authorised EMC resellers and EMC Velocity SMB channel partners. RepliStor SMB Edition, VisualSRM SMB Edition, and eRoom SMB Edition will be available in Q1 ’06. Pricing for the CLARiiON AX100/i starts at AU$8289 / NZ$9028, Storage Administrator for Exchange SMB Edition costs AU$3006 / NZ$3274, RepliStor SMB Edition costs AU$1500 / NZ$1634 per node, VisualSRM SMB Edition starts at AU$1500 / NZ$1634, eRoom SMB Edition starts at AU$1500 / NZ$1634 for 10 users, and Retrospect starts at AU$601 / NZ$655. Available in ANZ from April 1, 2006.

    Senior CE Industry Executives Exposed In Ashley Maddison Saga As New Data Dumped Online

    As more Australians find that they have been exposed in the Ashley Maddison extra-marital web site drama comes news that an even bigger dump of data has been posted online.

     Millions of personal names, addresses and emails of

    those who signed up to affairs website Ashley Madison have been published online

    including several executives working for mass retailers and manufacturers.

    It already appears that several CE and appliance industry

    executives have been looking for extra-marital love behind their partners back

    including one high profile executive from a mass retailer whose name pops up on

    the dumped data.

    ChannelNews obtained the names of several executives in the

    CE industry by typing in known email addresses.

    Now how can you find out if you know someone who has been

    exposed by the big dump?

    A developer known as “Rufo” has created a simple

    website for searching the massive database of emails that have been published

    by the hackers.

    The site, called ashley.cynic.al, will only reveal emails

    that have been used to sign up for a profile with Ashley Madison.

    It won’t reveal if the user behind the email address has

    been actively using the site.

    What’s more, it doesn’t reveal anything like names, credit

    card details or sexual preferences that could be exposed in the second dump of

    data that was released a few hours ago.

    The fresh set of Ashley Maddison files have been uploaded to

    a part of the internet known by some as the “dark web”.

    The data dump was accompanied by a note addressed to the

    infidelity dating website’s boss saying: “Hey Noel, you can admit its real

    now.”

    The name of one of the files indicates that it contains

    nearly 14 gigabytes worth of data from the chief executive’s email account.

    However, there is a problem with it.

    The new upload contains a large file whose name indicates it

    contain emails taken from Avid Life Media’s chief executive.

    The archive in question has been compressed, and efforts to

    expand it to normal size bring up an error message, “It’s in a zipped

    format, and when I try to decompress the contents a message comes up saying it

    won’t work,” Per Thorsheim, chief executive of cybersecurity firm God

    Praksis, told the BBC.

    “I can’t yet say why.”

    Several security Companies have independently verified that

    the archive appears to be damaged.

    Other files, however, can be viewed.

    Mr Thorsheim said they appeared to contain collections of

    computer instructions.

    “The one that I opened up – Avid.tgz – looks to me like

    source code,” Mr Thorsheim said.

    “I can’t say [for sure] that it’s from Ashley Madison,

    but I wouldn’t be surprised if it is.”

    Another security firm that has taken a cursory look at these

    files highlighted the threat they could pose.

    “If this turns out to be legitimate, which it in all

    aspects appears to be, having full source code to these websites means that

    other hacker groups now have the ability to find new flaws in Avid Life’s

    websites, and further compromise them more,” wrote Dave Kennedy, chief

    executive of TrustedSec, on his firm’s blog.

     

    Ashley Madison’s owner, Avid Life Media, could not be

    reached for comment.

     

    Weather Resistant LCD TV

    Sanyo is set to role out a weather resistant LCD TV. Set to go on sale in the UK first Sanyo say it’s ideal for soaking up warm pommy beer and the odd tear as England get booted out of the World Cup.

    The World Cup’s looming – and if you have the idea of sitting outside and watching the action, or are a pub who wants to entertain customers outside the answer is this weather-resistant, flat panel LCD TV from Sanyo – claimed to be first of it’s kind in the world. They say its great for spilt beer and the tears of Poms as they mourn yet another failure to Australia in the World Cup.

    The 32″ panel is suited to both interior and exterior use and can withstand a range of weather conditions, plus harsh environments, such as dusty or humid conditions. Picture sharpness comes courtesy of the high-resolution LCD panel with high brightness level, high contrast ratio and a 176 degree viewing angle.

    Aimed mainly at the corporate market with an eye on filling beer gardens and barbecues, the weather-resistant TV should be on the market in time for the World Cup. No price available as yet.

    EMC Secret Revealed

    The retiring CEO & Chairman of EMC has revealed the secrets to EMC’s success.

    Mike Ruettgers, former CEO and chairman of EMC, has revealed that the recipe for extreme business success is so obvious. First, you take an entrepreneurial furniture salesman and hand him some memory. Next, you add a college dropout turned Harvard graduate who designs missile systems. Lastly, mix the executives, dash them with bankruptcy and bake. Presto! You’ve got the best-performing company on the NYSE during the 1990s – EMC.

    According to the Regiser web site, Mike Ruettgers, former CEO and chairman of EMC, revealed this simple path to fame and fortune during a question and answer session last night here at the Computer History Museum. Having been retired for all of three weeks, Ruettgers didn’t hesitate to divulge the keys to making EMC the dominant storage player. Such openness, however, won’t help too many aspiring business leaders, given the unconventional path Ruettgers and EMC took.

    Ruettgers began his education at UCLA where, as a freshman, he “looked old enough to be able to drink”. A penchant for partying and playing bridge over attending class made short work of his UCLA tenure. “At the end of myfirst year, UCLA – in its wisdom – asked me not to come back,” he said.

    After one year, Ruettgers went to another university where he excelled. This made acceptance at Harvard’s business school possible, and off went Ruettgers to snake an MBA. Out of Harvard, Ruettgers went to work for Raytheon where he was asked to analyze the company’s Patriot missile development program. Ever the helpful MBA, “I said, ‘As far as I can tell, we are going to be about eight years late and have about a $700m overrun.'”

    Music to a military contractor’s ears, especially with the pressure of the Vietnam War looming.

    “To Raytheon’s credit, within about 30 days, they reorganized how they were developing the product,” Ruettgers said. “What I learned at Raytheon was that good engineers, by themselves, are not enough… Engineers work best when they have schedules, and they work best when you spend a lot of time asking them about their schedules.” (To all our engineer friends out there, please direct all your feedback on this issue to EMC. Or, what the heck, send it to us.)

    Eventually, Ruettgers moved to Raytheon’s services division that worked on mainframes and related hardware. That’s how he ran into then EMC founder and ex furniture salesman, Dick Egan. Egan told Ruettgers that EMC’s young staff lacked maturity and could use some wisdom. “I was indeed the silverback or greybeard who could come in and provide some adult supervision.” Ruettgers said.

    At the time, EMC was selling memory to a variety of customers. “We were plugging Prime,” Ruettgers said. “We were plugging Wang.”

     


     

    LG Scarlet TV Launch More C Grade Than A grade

    COMMENT: There are A grade celebrity launches and C grade celebrity launches but the event held last night in Sydney for the new LG Scarlet LCD TV was definitely a C grade launch attended by B grade celebrities and those paid to attend which included actress Natassia Malthe who is best known for her appearances in B grade movie flicks such as Sex & Death, Blood Suckers, and Alone in The Dark.
    Also making a quick appearance were members of the Sharks NRL football team who just happen to be sponsored by LG the makers of the new Scarlet LCD TV and a host of reality TV rejects who appeared quite happy sipping warm pink champagne.

    Click to enlarge

    Click to enlarge
    Unknown models parade on a catwalk


    In a desperate attempt to reverse their declining position in the LCD TV market LG, under the direction of Warren Kim the former national merchandising manager for Telstra’s Digital, Data, IT and Fixed Line business the Korean Company is spending over $100 million dollars in an attempt to take market share away from Sony, Samsung and Panasonic in the flat screen TV market.

    LG’s strategy however is flawed. Rather than be evolutionary like Sony Samsung and Panasonic LG has chosen to be revolutionary. Their strategy is wrapped around the launch of a bright red backed LCD TV called Scarlet.

    Talk to any automotive marketing manager and they will tell you that red cars do not sell and even worse is their resale value.  But to convince consumers to buy a red backed TV which in 2 years time will look so dated is a massive risk.

     

    In an attempt to jack up interest in their new Scarlet TV LG in their wise wisdom decided on a global tease campaign  the company made readers and TV viewers believe that a new movie starring Norwegian model and actress Natassia Scarlet Malthe and produced by David Nutter ? of the hit show “The Sopranos” ? was in the making.

    From billboards and bus shelter posters to online banners, Malthe has made public appearances at film premiers around the world including last night in Sydney in support of her fictitious role, while the ad copy offered no hint of LG. Also in toe was Director David Nutter who between them they are believed to be netting in excess of $15M dollars.

    Click to enlarge
    Graham Cunningham LG sales Spruikes Scarlet TV

    Click to enlarge
    LG sales boss spruiks Scarlet


    Not making a show at the local Scarlet TV launch was Aussie actors Gary Sweet or former Home and Away star Sharni Vinson who appear in the tease trailer alongside Natassia Scarlet Malthe. Also missing was recently appointed LG Marketing Director David Brand who gave the event a pass in favour of LG marketing events in New York and Paris.

    “To spend money without letting people know about our brand is really risky. But that’s the punch line of this campaign. It will change the rules of the game,” Lee Kwan-sup, vice president of LG’s Digital Display Global Brand Marketing Team, said, adding his company can’t match its bigger rivals on media spending.

    “What we really want is to increase our brand recognition. Strengthening consumers’ emotional attachment to that brand is the key to long-term success,” Lee said.
     


    The only problem is that the new Scarlet LCD TV is very ordinary up against some tough new offerings from Samsung, Panasonic and Sony the current market leader in the TV market.

    Rather than be evolutionary LG is banking on being revolutionary and like the big budget tease flick the TV lacks any substance above and beyond what LG has offered in LCD TV’s in the past. This is the same Company that 3 years ago rolled out the Internet fridge which at the time they said would be a big hit. Today I cannot find one retailer stocking the fridge let alone a consumer owning one.

    Why Deloitte’s Should Have Read ChannelNews Before Signing Off On Dick Smith Accounts

    The Dick Smith retail chain is up for sale lock stock and barrel, following yesterday’s decision to place the consumer electronics retailer into receivership owing creditors almost $300 ?million.

    Around Australia landlords who have rented space for Dick Smith or Move stores are facing massive losses if the receivers fail to provide a buyer so are hundreds of suppliers many who have tried to get stock that has not been paid for returned. 

    Questions are also being asked of the Company’s auditors Deloitte who signed off the Companies accounts back in August 2014 despite their being clear information in the market that the Company was struggling due to cash flow issues. 

    What suppliers want to know is why Deloitte who have had a long time relationship with Dick Smith didn’t raise red flags about refinancing problems and inventory issues.

    Even back in August ChannelNews knew the Company was struggling to raise revenue and had moved to heavying suppliers to invest marketing dollars into the Company up front prior to June the 23rd.

    Back in May we highlighted the fact that Dick Smith had not placed orders on vendors due to cash flow problems. 


    We also pointed out back in April 2015 that Dick Smith was sacking staff, cutting costs while demanding higher CO-OP investments from retailers.


    The question now is why Deloitte was not able to identify these problems when senior staff were telling ChannelNews that the Company was in serious financial difficulty. 

    One person who blatantly lie to ChannelNews was Marketing Director and head of Buyer Neil Merola. On several occasions we asked Merola to respond to our questions concerning the health of the Company.
    His most common line was “Who is feeding you this bullshit, trust me there is nothing to the claims” it pure fantasy on somebody’s part”.

    THE AFR said that Deloitte gave Dick Smith’s 2014-15 finances a clean bill of health in August. 

    Deloitte earned $338,000 for conducting the audit of what now appears to be a set of dodgy books, in addition to $103,927 for other services rendered.
    On Tuesday, Dick Smith was placed into receivership by major lenders NAB and HSBC after weak sales and cash generation in the crucial Christmas trading period.

    Poor inventory management is being blamed for the collapse, following a $60 million write down last November – a 20 per cent reduction in the value of Dick Smith’s stock.

    The Australian has reported that there has been a mixed reaction by market observers yesterday, with several long-term criticisms about the sustainability of the business re-emerging. Others expressed shock at the quick undoing of the retailer, which had traded above $2 a share as late as August last year.

    Dean Fergie, of Cyan Investment Management, said he was surprise that what appeared to have been a “reasonably solid business” six months ago had entered receivership.

    “It appears there were some ?serious underlying issues that the market and potentially even the management were unaware of,” Mr Fergie said.

    But he said there would be limited interest in Dick Smith’s store network from other large retailers, although its chain of Move outlets at airports could attract buyers.

    “The low to mid-end home electronics market is pretty dead. Aldi and the supermarkets are coming in and JB Hi-Fi has the higher end, so they are being squeezed from both ends,” he said.

    Evan Lucas, an analyst at IG Group, said any buyer of Dick Smith faced a situation where it was the market’s third player, with higher costs than JB Hi-Fi, while lacking Harvey Norman’s diversified product range.

    “That’s why over the last two year’s JB Hi-Fi have diversified into home appliances, and Dick Smith has only had one option which was a high-turnover business,” Mr Lucas said.

    “There’s been a lot of questions around the Dick Smith branding, the use of their own private brands, which is a major part of the inventory issue first raised in November.

    Nick Abboud, the company’s chief executive, had originally forecast earnings of up to $48m, before reducing it to between $37m and $43m, and later ditching the forecast alto?gether.

    That pushed the shares more than 80 per cent lower, with the company last trading at 35.5c on New Year’s Eve.

    Harvey Norman chairman Gerry Harvey said it was clear that the Dick Smith business “had run its course”. He said: “Woolworths couldn’t keep it, they knew they had to get rid of it, and suddenly it goes from being worth nothing to being worth $500m, then suddenly nothing again.

    “Every time a competitor disappears their opposition benefits. It won’t just be Harvey Norman, it will be JB Hi-Fi and the Good Guys as well.

    Harvey Norman Looking To Expand Into The UK, As Gerry Praises Tony Abbott

    Gerry Harvey the Chairman of the Harman Norman retail group has said that he is looking to expand into the UK despite his Northern Ireland operation struggling.

    In an interview with the UK Financial Times Harvey said that he will move into the UK market with Harvey Norman branded stores, when the Irish operation is profitable and conditions are right.

    When asked about the political landscape in Australia he described former Labor Prime Ministers Kevin Rudd and Julia Gillard as “idiots while praising Prime Minister Tony Abbott as a “good bloke” but admits the public simply does not like him.

    “The political system is broke,” he says. “It doesn’t matter who the leader is if you are frozen in time and your hands are tied. Social media is so strong that minority groups get a huge say,” he says.

    He gives warning that Australia’s inability to pass reforms leaves its economy vulnerable.

    “It’s crazy, Australia is in a situation where it is one of the most expensive countries in the world to do business and the resources boom is over,” he says.

    “The one thing we know for sure is we are entering a period of uncertainty in the world that is unprecedented.”

    On the question of online retailer Harvey said that the Harvey Norman online web site accounts for about 3 per cent of electrical and computer sales, he also bragged that “his” web site does a better job than any other retailer in Australia. 

    “Even now the internet is hyped,” said Harvey, who likens the zealotry of some online advocates to religious cults. “If you are a manufacturer an internet company doesn’t suit you. An internet company does not display your product, it can’t upsell. But we do a better job than any of the opposition.”

    Harvey even admitted that he often shoots from the mouth. 

    He said “I’ve got into trouble before with journalists for being candid,” he says.

    After four decades of expansion, which saw Harvey Norman grow into one of Australia’s few multinational successes, the business hit trouble in 2012 due to heavy losses in their Irish operation.

    At the time Harvey Norman’s market value plummeted from a$7bn in 2007 to below a$2bn by early 2012.

    At the time one rival branded Mr Harvey a “whingeing dinosaur” for failing to master internet retailing. Some commentators called on him to follow the advice of his company’s catchy “Go, Harvey” advertising jingle and leave more than a half century of retailing behind.

    He said “There were people saying Harvey Norman had had its day, it was yesterday’s retailer. We’d certainly been given a kick in the arse,” says Mr Harvey, who owns almost a third of the business.

    “Most businesses which face a dip like that go broke. The Ireland problem is disappearing, New Zealand is very strong and we expect Asia to improve: we are regaining our mojo,” he adds.

    On the question of how long he will stay at the helm of Harvey Norman he told the Financial Times “I was talking to Rupert Murdoch the other day at a lunch and he said ‘maybe I’ll live to 100’. He actually thinks he will live to 100!” says Mr Harvey, who is an admirer of the News Corp executive chairman’s passion for managing his business in good times and bad.

     “I enjoy what I do,” he says from behind a desk piled high with spreadsheets, research reports and sales figures. “If I have to go because I’m mentally or physically f****d then maybe I’ve got to go, but I’m not going willingly, I’m going screaming,” he says.

    Farina Parsons, an analyst at Morningstar, is critical of Mr Harvey’s record. “The last 18 months have been good for Harvey Norman with a housing boom in Australia helping Gerry Harvey to turn round the business. But I have a feeling this is masking underlying issues with the company,” she argues.

    “He hasn’t embraced the online strategy as well as he could have. The online business is pretty poor,” she says. “Gerry and his wife Katie own 30 per cent of the equity?.?.?.?raising questions around whether it should be a listed company. It is run like a private company and it would be good to see a larger cross section of industry experience on the board.”

    Microsoft Has A Shocking Problem With Surface Pro Tablets

    Microsoft has a problem with their Surface Pro tablets 2 and 3 with some owners getting a shock when using the devices.

    Microsoft has a problem with their Surface Pro tablets 2 and 3 with some owners getting a shock when using the devices.

    According to Company executives hundreds of thousands of power cords for its Surface Pro range are set to be recalled. The Company has not said how many Australian cords are affected, what we do know is that the issue is serious and is already affecting owners in the USA and Europe. 

    The voluntary recall is due to a risk of overheating and causing fires and will reportedly apply to all models except the new Surface Pro 4, sold before July 15 2015.

    “Microsoft has received some reports of a short duration flame and a few reports of shock” a Company executive said. 

    The executive said “As a result of damage caused by AC power cords being wound too tightly, twisted or pinched over an extended period of time, owners have reported issues. We will be releasing details of how customers can obtain a free replacement cable shortly.”


    Click to enlarge


    The first Surface Pro went on sale in February 2013, followed by three more generations which were part of an evolution to a true laptop-tablet hybrid. 

    In January last year, Microsoft announced that Surface revenue had crossed the $1bn mark in the fourth quarter of 2014 for the first time, driven by sales of the Surface Pro 3.

    Sales estimates vary from an estimate of 1.8 million units sold in 2014 globally, to at least two million sold in the last quarter of 2014 alone.

    Estimates also point to 1.5 million units sold in the first half of 2015.

    Microsoft claims you should only return your power cords if you often wind them up tightly or twist them for prolonged periods.

    But if you use your power cord regularly, you could get a potentially safer product for free by sending back your current one.

    HP Takes Top Storage Spot

    More than 5720 Terabytes of storage was shipped in the second quarter of 2005. This is up from 4,600 for the same period last year.

    On the eve of the opening of the Storage Networking World expo in Sydney, Gartner says external disk storage revenue in Australia totalled A$97.8 million in the second quarter of 2005.

    The amount of external disk storage capacity shipped in the same period was an “impressive” 5725 terabytes, Gartner said – up from 4600 terabytes in the first six months of 2004. The top three vendors in Australia for Q2 were Hewlett-Packard with a vendor revenue market share of 28.8pc, EMC with 18.1 and IBM with 17.9. For Hewlett-Packard alone this mean revenue of
    A$28 million, according to Gartner.

    “As more e-mail, video, graphic and audio information is created, organisations’ appetites for disk storage will continue to grow,”
    said Phil Sargeant, Gartner’s storage VP. “The challenge for organisations will be to digest this volume of storage. Good management techniques and good people will be required.” Storage Networking World opens at Sydney’s Darling Harbour complex today, with security exert and author Ira Winkler discussing Secrets Of Super Spies – The Truth Behind The Most Devastating Computer And Information Crimes. Larry Krantz of the Storage Networking Industry Association delivers a keynote at 9.50am. At 10.30 there’s a storage roundtable discussion with SNIA board members, conference presenters and end users including reps of Griffith University, Baycorp Advantage and Qld Uni of Technology. Around 40 storage companies will be showing their wares at the accompanying exhibition. They include Sun, H-P, HDS, IBM, Imation, Quantum, Sony, Falconstor, McData and Bakbone.

    According to IT research group IDC the worldwide external disk storage market was worth $3.8 billion  in Q2, 2005. This was up 8.6%.The total disk market was up 9.9% to $5.6 billion. IDC says: “Capacity continues to outpace overall revenue growth with total disk storage systems petabytes growing 59.3% year over year to 457 petabytes for the second quarter.”
    Sales of servers with 3 or more disk drives is driving internal storage sales, said Brad Nisbet, program manager in IDC’s Storage Systems program.
    EMC leads the external disk storage market with 21.2% revenue share, followed by HP and IBM with 18.8% and 13.8% revenue share, respectively. Dell edged out Hitachi for the fourth position with 8.3% revenue share while Hitachi ended the quarter with 7.3%.
    The total network storage market (NAS combined with Open and iSCSI SAN) posted 16.1% year-over-year growth in the second quarter to nearly $2.5 billion. EMC continues to maintain its leadership in the total network storage market with 27.9% revenue share, followed by HP with 21.3%. Dell and IBM posted the strongest year-over-year revenue growth for the quarter among the top 5 vendors, with 33.2% and 22.9% growth, respectively.
    The Open/iSCSI SAN market grew 17.8% year over year, surpassing $2.0 billion in revenues for the first time. Unlike the first quarter of 2005, there was no clear leader: EMC and HP were in a statistical tie for the first place position. EMC had 25.0% revenue share and HP had 24.8% revenue share for the second quarter. Dell and IBM posted the strongest revenue share gain among the top 5 vendors, with 1.6 and 0.6 year-over-year share point gain, respectively.
    In the NAS market, which grew 9.5% year over year, EMC led with 40.2% revenue share, followed by Network Appliance with 35.2% share. The iSCSI SAN market posted nearly 140% revenue growth year-over-year. Network Appliance continues to lead the market with 41.6% share, followed by EMC with 26.0% share.
    But then again Dow Jones newswires reports that “Hewlett-Packard Outgrows Market, Continues To Rank No. 1 In Worldwide Total Disk Storage Systems Rev” so there is some solace for everyone

    How To Turn an Excellent $777 55″ Aldi 4K UHD TV Into a Top End Streaming TV For $59

    There are two types of Ultra High Definition TV’s, there are those that cost an arm and a leg and are priced up to $1,900 for a 55″ inch plus model, or there are those like the Aldi model which is a seriously good 4K UHD TV for sub $800.

    The Sony Bravia X8000C Series 55″ 4K Ultra HD LED LCD Smart TV retails at Harvey Norman for $1,268, while the LG 55″ 4K Ultra HD LED LCD 3D Capable Smart TV is selling for $1,995 both have similar specifications to the Aldi Bauhn 4K UHD TV.

    Ironically a lot of the 55″ TV’s come off the same production lines and out of the same factories as the $777 Aldi 55″ TV that went on sale in Australia last week.


    Resolution on the Aldi TV is 3840 x 2160, it has a built in HD tuner and within minutes of booting up this TV we were able to watch 4K movies on YouTube, we did this by simply going to the Smart TV function and instantly accessing YouTube. 

    For those who want to access the Netflix 4K content which is some of the best UHD content available in Australia today I strongly recommend that you fork out $59 for a Chromecast dongle.

    All you have to then do is plug the Chromecast USB into your TV. 

    Switch your TV to the right HDMI input, then Download the Google Chromecast application on your mobile or desktop device and follow the setup instructions. Have a look on the TV, you should see matching codes on your TV and mobile device. 

    The beauty of getting Netflix via an Android or iOS mobile device is that your phone or tablet becomes your television remote control when watching Netflix content on you $777 Aldi TV. 

    With the Bauhn Aldi TV you can share media files via a DLNA-Enabled media PC, smart phone or tablet on the TVARC.

    Using HDMI 1.4 Audio Return Channel function, you can now send TV sound back to an AV receiver without using additional cables.

    You can also easily record favourite TV program via the built in PVR. 

    A smart way to use this TV is to connect a 1 terabyte drive and then you can record hours of your favourite programs. 

    There is also Catch Up TV which means that if you’ve missed an episode of your favourite show you can watch back full shows for free, this service is dependent on what part of Australia you live in. 

    Built in Screen Mirroring allows you to access high definition videos, music and images from your phone or tablet without the need for cables.

    Conclusion:
    This TV delivers value for money. Screen resolution is good and by adding a Chromecast you are able to not only access excellent 4K UHD content you can also access a lot of the services found on top end TV’s.