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

    Smart Office

    Creative Technology Struggling

    The struggling Creative Technology group is back in decline after Microsoft denied that it was buying into the company. Facing a share decline this year of 50% and a massive downturn in profits the company is evaluating its future.

    Microsoft will not buy into the struggling Creative Technology group according to a Microsoft spokesperson. Microsoft claims that will continue to work with Creative in developing new products as ‘we are the platform provider and Creative provides music devices,’ said Charlene Chian, the company’s public relations manager for Asia Pacific.

     

    In early July, Microsoft Chairman Bill Gates said at an industry briefing that the US software giant would work with vendors like Creative to produce better-designed MP3 players to help gain market share on leader Apple Computer.

    That fuelled speculation that Microsoft would invest in Creative. And within days, Creative shares jumped by more than 20%. Some market watchers even predicted that the stock had ended its six-month slide.
    Creative shares have fallen by about 49% since the start of the year and are trading at about 25 times their estimated 2005 earnings.

     

    Many people say that Creative are not in a position to compete in the MP3 market and that all they are doing is dressing up old MP3 technology in an effort to take on the success of the iPod. Now with companies like Samsung and Toshiba tipping millions into MP3 marketing Creative are set to come under further pressure.

     

    A Citgroup spokesperson said “Creative Technology is struggling and resellers are starting to turn to a new generation of MP3 players from a variety of other vendors. All that Creative has done this year is back peddling in an effort to compete on price. They don’t have deep pockets and investors are recognising this. The issue for them going forward is that the MP3 and Video Player battle is set to suck cash and this could impact on other parts of their business”.

     

    NIck Angelluci Marketing Manager for Creative in Australia said “We are defiantly under pressure on margins. Everyone is coming after us from Olympus to Samsung to Toshiba. The future for us in the video player market as in the MP3 market  everyone is screaming for margin which is not there”.

    Telstra To Kill Off T Box, Replaced By Roku Telstra TV Streaming Box With Netflix

    More than 860,000 Australians who invested in Telstra’s T Box service are set to find out that their entertainment box is set to get killed off in September to be replaced by a new Roku mini streaming box.

    The brand new entry level Roku streaming box, will see Apple compete head on with Apple TV, Fetch TV and several other media players that are offering access to streaming services such as Netflix, Stan and Presto. 

    Roku executives said that they have been talking to Telstra for several months, they also confirmed that the service will launch in September under the Telstra TV branding and that testing is already taking place in Australia. 

    Andrew Ferrone, vice president of Pay TV at Roku said “As part of the strategic agreement Telstra will leverage the Roku streaming platform to deliver its new streaming service and player, Telstra TV, to consumers. 

    The Telstra TV streaming service will launch later this year in Australia and will bundle BigPond movie service together with the most popular streaming services including Presto, Stan, Netflix and various catch up TV channels. Telstra is the fourth operator after Sky UK, Sky Deutschland and Sky Italia to join the Roku Powered licensing program”.

      “The Roku Powered program is a great solution for operators like Telstra looking to leverage our streaming platform and players to deliver a next-generation TV experience that integrates their own video services with third-party OTT services. Telstra is an industry leader and through our partnership they will bring a great streaming experience to Australian consumers this summer”

    “Roku pioneered streaming and continues to innovate in new ways that make it easier and more convenient for consumers to watch entertainment they love. Licensing the Roku streaming platform enables us to launch a streaming service and player without the magnitude of cloud services, software and tools otherwise needed to become an OTT operator,” said Joe Pollard, group managing director Media and Marketing at Telstra.

     “Roku already has millions of pleased customers and thousands of content partners and a handful of licensing partners, the platform has clearly proven itself in terms of scalability, richness and, most importantly, engagement.” he added. 

    “We hope to make this the leading streaming platform for SVOD services, moving forward,” said Joe Pollard, Telstra’s head of media and marketing. “Apple TV is more of a closed ecosystem, where this will be more of an open system.

    “We think this will slot into the market well and there’s a big addressable audience, with 70 per cent odd of the population not paying in some way, shape or form for video content.”

    The launch of Telstra TV in September will mean the T-Box device – of which there are more than 800,000 units in the market – will be axed as Telstra moves to pitch their offering to price conscious consumers. 

    The new box will be sold at JB Hi Fi, pricing has not been officially announced however it is expected that the device will sell for around $109.95 outright or for $89 a month that will include a broadband connection with 200GB of monthly data and free local calls.

    Telstra is also considering ?offering users of the Telstra TV service a “Sports Pass” that will allow customers to purchase a weekly pass to a selected sports channel, including Fox Sports.

    Future Of Clive Peeters Decision Soon

    EXCLUSIVE: Greg Smith the CEO of Victorian retailer Clive Peeters has said that he is close to a decision on the future of the business following an extensive review by KPMG. He admits that that he is talking to several interested parties with a view to getting either “an investment of capital” or an “additional shareholder”, failing this it will be “business as usual”.

    Greg Smith the CEO of Victorian retailer Clive Peeters has said that he is close to a decision on the future of the business following an extensive review by KPMG. He admits that that he is talking to several interested parties with a view to getting either “an investment of capital” or an “additional shareholder”,.

    “We are going to bring the issue to a conclusion soon, as there is too much uncertainty about the future of the business. We believe that it is in the best interests of everybody that that the review process which has been going on for 6 months has a finale. We are currently cutting capital expenditure and controlling inventory in an effort to preserve capital”.

    When asked what will happen if no one makes a bid for the Company Smith said “This is a real possibility, it will be business as normal. I stress that we need to get this issue behind us. We have engineered the business to continue through the downturn and that is what we will do”.

    Smith, who is also a major shareholder in the troubled group refused to speculate on which other retail groups, he was talking to however he categorically ruled out Woolworths as a potential investor or shareholder. However he did not rule out the Good Guys as a potential investor or even owner of the group.

    Commenting on the recent Good Guys publicity in the Australian Financial Review he said “It was extremely unusual. While I have no knowledge of whether they are talking to Woolworths it does appear that something is happening as they are an extremely private Company”.

     

    Smith said that during the past two weeks business had picked up but after this week’s Federal Budget he was not confident that “growth will be sustainable”.

    He has also said that the Australian Federal Government may have to step in and support retailers and suppliers across the consumer electronics and appliance markets, if a potential cash-flow crisis emerges because trade insurance underwriters, such QBE, start cutting back on their exposure to the sector.  

    “In Australia QBE started cutting back last year and while there are no indication currently that there will be further cuts from QBE the issue could arise similar to what has happened in Europe where Governments have had to move in to support retailers. This could be an issue for the Federal Government going forward”. 

    OZ Interest Rates Not Cut As Expected

    At its meeting today, the Australian Reserve Bank Board decided to leave the cash rate unchanged at 3.25 per cent. In a statement to the markets Board Govenor Glenn Stevens said that Australia was in a better position than a lot of other Countries and that demand had not weakened.

    The statement said that recent data confirm that the world economy has remained very weak following the sharp decline in demand that occurred late last year. The major industrial economies reported large contractions in output in the December quarter, as did a number of emerging market economies across Asia and eastern Europe. Many countries are likely to be experiencing further falls in output in the current quarter.

    Conditions in global credit markets have improved since November, but sentiment remains fragile. Share prices have weakened and banking systems in several major countries are still under pressure, as authorities work towards a resolution of the balance-sheet problems. Significant macroeconomic policy stimulus is being put in place around the world, but it is too soon to see the effects of those measures.

    In Australia, demand has not weakened as much as in other countries and, on the basis of currently available information, the Australian economy has not experienced the sort of large contraction seen elsewhere. The Australian financial system remains strong and the monetary policy transmission process is working to deliver large reductions in interest rates to end borrowers. Nonetheless, economic conditions are clearly weak, and given the speed and scale of the global economic deterioration and its effect on confidence, weak conditions are likely to continue in the near term. Inflation is likely to decline over time.

     

    In response to that outlook, there has already been a major change in both monetary and fiscal policy. Market and mortgage rates are at very low levels by historical standards and business loan rates are below recent averages, reducing debt-servicing burdens considerably. Together with the substantial fiscal initiatives, the cumulative decline in interest rates will provide significant support to domestic demand over the period ahead. On this basis, notwithstanding evident economic weakness at present, the Board judged that the stance of monetary policy was appropriate for the moment. The Board will consider the position again at its next meeting.

    Epson Slashes Profit Forcast By 50%

    Epson has slashed its profit forcasts by 50% following poor sales of printers. The downturn in the market could also affect HP.

    Epson the world’s second- biggest printer maker has cut its full-year profit forecast by 50 percent because of falling prices for printers and liquid-crystal displays. Net income is estimated at 22 billion yen (US$197 million) in the year ending March 31, compared with the previous forecast of 44 billion yen, the Nagano prefecture, Japan-based company said  in a statemnent to the Tokyo Stock Exchange. That compares with a 55.7 billion yen profit a year earlier.

    The company also cut its sales estimate 1.3 percent to 1.618 trillion yen. The company had 1.48 trillion sales a year earlier.

    Falling prices for inkjet printers, mainly in Europe, are cutting into profit as lower-priced printers account for more of revenue, the company said. In the second half starting Oct. 1, sales of small LCDs used in projectors and LCD rear-projection televisions are expected to fall short of forecasts

    HTC Facebook Phone Set To Be Dumped

    HTC who have a reputation for producing “hot” selling phones may have to go back to dance school following news that their Cha Cha and Salsa Facebook phones which were launched recently on the Vodafone network phones are struggling to find partners.

    According to a Vodafone source the two HTC Facebook phones that were launched recently at an event in Sydney, are struggling to sell compared to other HTC phones. Currently one of the most popular phones is the HTC Sensation.

     According to people that Smarthouse has spoken to the issue appears to be the use of a keypad and a small screen alongside a Facebook button that is turning consumers off the HTC Facebook phone.

    One Vodafone store manager said “Most people want the large screen that the Samsung Galaxy or the HTC Sensation offers. Keypad similar to what is on the Cha Cha is yesterday’s technology which is why we are seeing a move away from Blackberry keypad phones. Most people are happy with a Facebook Icon on the opening page of their screen Vs a button”.

    In the USA AT & T is rumoured to be ready to drop the HTC Facebook phone due to poor sales.

    According to Tech Crunch the network may have already “dumped” the phone.

    At the Sydney launch HTC Australia executives said that they were “uncertain” as to where the market was for the Cha Cha and Salsa models as “they are so unique”.
     
    The device which lets users share music, photos, location, and status updates via the dedicated Facebook button also lets owners take a picture or shoot a video and share it instantly with a press of the Facebook button.

    The Facebook button on the two phones glow when playing music.

    Cisco to buy EMC rumours persist.

    Rumours that CISCO are set to buy storage outfit EMC will not go away. According to US web site Search Storage Word Cisco is considering a $56 billion dollar acquisition of EMC.

    Search Storage at www.searchstorage.com claim that when Sun Microsystems announced that it would acquire StorageTek for $4 billion a couple of weeks ago, most people rubbed their eyes in amazement and read the news again. As for Symantec buying Veritas, no one in their right mind had put these two companies together. They were just so different.

    But getting into adjacent markets is the name of the game these days to sustain the strong revenue growth that’s come to be expected of large technology suppliers. Two companies gobbling up adjacent and emerging market players faster than you can say “storage virtualization” is Cisco and EMC. (We’ll come back to the v-word later.)

    Search Storage also claims that what’s interesting about some of the company’s Cisco and EMC are acquiring is that they overlap each other.

    EMC recently acquired network management software company Smarts for US$260 million while Cisco has forked out over US $400 million for Actona Technologies, FineGround and TopSpin – all considered storage networking companies at one stage or another. Brocade too, recently took its first steps into a new market outside of storage buying server provisioning company Therion Software.

    However, buying a little bit here and little bit there gets you incremental growth but not dominance, which is why the rumour that Cisco is in talks to acquire EMC for $43 billion, might just be worth considering.

    A quick look at the numbers shows that Cisco can easily afford to buy EMC. Cisco has a market capitalization of just over $121 billion and $24 billion in sales while EMC has a market cap of $32 billion. Buying EMC for $43 billion represents about a 30% premium, pretty steep but not out of the question.

    From Cisco’s perspective

    Cisco has saturated the networking market, but still has to grow. However, its choices are limited. Microsoft owns the desktop. The server market is commoditized by IBM, Dell and HP with IBM taking the lion’s share of the services business. This leaves storage, which happens to be the only growth area left.

    Buying EMC would give Cisco another chunk of the enterprise and tremendous sway with customers. Its mantra for some time has been that users want fewer suppliers to deal with and products from companies that they can be sure will be around a year from now.

    Cisco would also like to see as much functionality as possible moved into the network, including storage applications, which it has slowly been tapping away at for a while. With 10 Gigabit Ethernet on the horizon, Cisco might also have its sights set on finally nailing the coffin on Fibre Channel, to bring storage networking and data networking together over the same pipe. Buying EMC could put an end to Fibre Channel diehards Brocade and McData in one fell swoop. There’ll be no such thing as a SAN company anymore. Cisco would probably say who cares if it’s IP or FC or telephony anyway, as long as it’s always available, secure and runs everything?

    From EMC’s perspective

    The company’s shareholders get a healthy premium. Looked at another way, what is EMC’s risk in not doing this deal? It may be at the top of its game right now, but what does the future hold? Can it really be a major software player outside its customer base in an industry where proprietary barriers to heterogeneity are still significant? Can it ultimately triumph in the midrange, which is clearly going to be the heart of the market for at least 5 years, against more technically and commercially aggressive players?

    Before the going gets tough, EMC CEO Joe Tucci has the chance to sell the company to Cisco, exit on a high note and probably earn himself a fat $200 million or so in the process.

    Who wouldn’t want VMware?

    Returning to the topic of virtualization, Cisco will undoubtedly be licking its lips at the idea of owning server virtualization leader, VMware. This business, owned by EMC, reported first quarter revenues of $80 million — that’s a year-over-year increase of 104% in a brand new and rapidly growing market.

    But in the grand scheme of things, virtualization should not be a separate technology for storage and for networking and for servers as this adds complexity for users. It should be a single technology. Owning VMware would give Cisco the opportunity to create virtualized servers, storage and networking under one umbrella — in other words a very powerful, long-term play.

    Do users benefit?

    Like Sun’s justification for buying Storagetek and Symantec’s for buying Veritas, Cisco will argue that fewer suppliers makes purchasing and deploying technology much easier for users.

    By acquiring EMC, Cisco might also be able to pull off storage on demand or utility storage, which requires standardization of all the pieces of the infrastructure to make it as simple as turning on a tap.

    Then again, all that might not work and users might end up with less choice, less bargaining power and lot of hassle in the process.

    More downsides to the deal

    Storage could also become a commodity faster than Cisco can absorb EMC — thereby driving the company’s margins down. There’s also a chance Cisco will alienate IBM, damaging a partnership that spans a decade.

    Then there’s the challenge of integrating these two giants: one on the east coast of the US, the other on the west. And after paying a premium, can Cisco really integrate the two firms to get the efficiencies needed to become a dominant player?

    The Cisco/EMC rumour may turn out to be just that, but it seems certain that more large-scale mergers are on the horizon in storage.

    Major Top Level Management Shake Up At LG

    LG Electronics Korea, used the evening before Thanksgiving in the USA, to announce major management changes to their struggling smartphone operation as well as at to their appliance and air conditioning business.

    This is normally done when a Company is trying to hide

    information as most US news organisations have already cut back staff for what

    is the biggest holiday break in the USA.


    The major leadership change announced by LG, will see

    control of LG Electronics operations split three ways between Jo Seong-jin,

    president and CEO of Home Appliances & Air Solutions, Juno Cho, president

    and CEO of Mobile Communications and David Jung, president and CFO. 

    The Company that is struggling in the mobile business both

    domestically in Australia and globally, is also facing some tough decisions

    over their TV business with LG Display looking for partners to fund a new OLED

    manufacturing plant.

    In Q3 2015, LG Electronics generated US$3.67 billion, from

    Home Entertainment, US$2.89 billion from LG Mobile Communications, US$3.55

    billion from Home Appliance and Air Solutions and US$409.41 million from LG

    Vehicle Components business.

    In Australia LG has failed to announce a replacement for

    Michael Doyle their former sales director who suddenly quit the Company two

    months ago.

    ChannelNews has been told by two leading recruitment

    executives that several people have been offered the position but have refused

    due to perceived “culture problems” that exist at the Korean Company.

    One recruitment executive said “We have proposed a number of

    people, but they have refused to put themselves up as candidates. Michael Doyle

    was an excellent sales director who got business because of his personal

    relationships with retailers, unfortunately he failed to develop a prodigy or

    deputy who could easily be promoted to take on his role”.

    Wayne Park, currently global sales and marketing officer,

    will be executive vice president and head of LG’s European Operations.

     Brian Na will be

    responsible for LG’s Overseas Sales and Marketing operations which includes

    Australia where the Company recently appointed Angus Jones as the new General

    Manager of Marketing for LG Australia’s marketing operations.

    The big question now is how long will Jones last, he is a

    former marketing manager at Dell, a Company who invested more in direct

    response marketing than brand and mass consumer electronics marketing. 

     

    To date Jones has refused any requests for an interview with ChannelNews.

    During the past five years LG Australia has seen several

    senior marketing executives join the Company only to quit after a short while

    due to differences with Korean management and the work culture at the Korean Owned

    Company.

     In 2009, the Company

    appointed David Brand a former senior liquor industry marketing director, as

    head of LG marketing, he quit in 2010 after LG Australia was fined $3 million

    for falsifying claims about their air conditioners.

    “David came on board in 2007 and has had a profound

    influence over LG Australia’s marketing activities” said William Cho, the

    then Managing Director, of LG Electronics Australia. “His efforts to

    enhance LG’s brand within the local market have been heavily valued by all

    parts of the business”.

    Brand told ChannelNews that he could not get out of the

    Company “quick enough”.

    Also quitting in 2010 was Carli Wilson, the former Marketing

    Manager of LG’s Communications Division.

    LG Australia then appointed Nick Gibson as Marketing

    Director, a former senior marketing executive at Electrolux and Johnson and

    Johnson, he was also the former Vice President of Product Development Asia

    Pacific for Fabric Care.

    He quit after LG was exposed by Choice Australia for duping

    Australian consumers by using an illegal device within some fridges to make

    them appear more energy efficient. The Company was fined $4M by the Federal

    Court and place on strict monitoring of their marketing.

    Then in 2012 LG lured Lambro Skropidis to the Company, the

    former marketing director of arch rival Samsung Australia, Skropidis also quit

    the role this year to take up the role as head of marketing at Electrolux.

    LG Australia’s Head of Mobile Communications, Jonathan

    Banks, also quit the company in March 2015.

    Globally David Jung will look after sales and marketing,

    global production and quality management in the role of Business Administration

    Officer, said LG.

    LG said that they expect its next high-growth areas to be

    energy, IT, B2B and its automotive business, according to a press release

    announcing the management changes.

    Freeing up these businesses will allow them more of an

    opportunity to excel independently without getting bogged down with the poorer

    performing areas.

    Smart New Wireless Speakers To Be Launched By Cambridge

    Cambridge Audio is set to launch a new AirPlay and Bluetooth-enabled speaker system in Australia called Minx Air.

    The Cambridge Audio Minx Air 100 and 200 are set to be sold via specialist dealers in Australia. They allow a user to stream music from a smartphone or tablet.

    The smaller Minx Air 100 model features two BMR (Balanced Mode Radiator) drivers, while the Minx Air 200 also adds a 6-inch subwoofer into the mix.

    The speaker systems also have a Minx Air companion app, which allows users to access over 20,000 internet radio stations, as well as controlling volume and EQ settings.


    Click to enlarge

    Built using Cambridge Audio’s patented BMR speaker technology, the Cambridge Audio Minx 200 features Digital Signal Processing capabilities that combine with the speaker to produce louder and fuller sounds than similar sized traditional speakers.

    An on-board subwoofer offers enhanced bass tones and 200 Watts of sound power will bounce sound around any room despite the Cambridge Audio Minx 200’s compact design.

    The compact speaker system connects to the majority of smart devices, including any Bluetooth enabled phone, tablet or computer. Utilising the Apple AirPlay technology, the Cambridge Audio Minx 200 will synch with desktop based iTunes libraries and to Apple devices like the Apple iPhone 5 or iPad mini.

    Once set-up, any synched device will remain connected and play any audio application through the Cambridge Audio Minx 200 speaker system automatically. Music streamed from services such as the BBC iPlayer Radio, Spotify or YouTube can also play through the Cambridge Audio Minx 200 via any of the connected smart devices.

    EXCLUSIVE: Telstra Management Report “Massive Failure” For Sony Xperia Z3

    Up to 70% 0f Sony Xperia Z3 smartphones have failed when consumers have tried to reboot their smartphones after they have been activated at Telstra stores according to Telstra sources.

    ChannelNews has been told that “hundreds” of Sony Xperia smartphones have “gone dead” within days of the device being activated on the Telstra network.

    Telstra management who spoke to ChannelNews on the basis that we did not reveal their identity said that Sony were well aware of the issue as they had replaced the problem devices. 

    Sony who has a track record of trying to manipulate the media is refusing to acknowledge the problem.

    Initially ChannelNews spoke to Joshua Velling Account Director for Telstra at Sony Mobile Communications.

    He did not deny the failure.

    He said “I cannot make a comment on this issue, I have to pass you onto our PR Company Hausmann”. 
     
    A spokesperson for Hausmann said after contacting Sony, “Sony does not comment on rumours or speculation”.

    ChannelNews has been shown Telstra incident reports relating to the problem.

    The issue is believed to have arisen in the second quarter of 2015 when Sony Mobile Communications only managed to sell 14,350 units.  

    New smartphone sales figures issued by IDC reveal that Sony, only managed to sell 14,350 of their current model between April and June Vs 797,661 Apple iPhones and 760,001 and Samsung Galaxy smartphones.

    The Company is not saying whether their biggest customer Telstra stopped ranging the Xperia smartphone until the problem was fixed.

    Telstra store managers said that there was a period when there was “no new Xperia smartphones available” in stores as Sony moved to fix the problem.

    The Sony Xperia 3 has been a problem smartphone for Sony. Issues reported around the world include, touchscreen unresponsive or glitchy, Texts won’t send, there has also been overheating problems.


    Click to enlarge


    Other problems include a bug, where no notifications appear on the lock screen, rapid battery drain, call and notification volume too low, Wi-Fi slow, won’t connect, or dropping
    Issue and the Z3 failing to turn on.

    A Telstra manager said The XperiaZ3 has been a problem smartphone from day one. We have had constant problems. One of the biggest was when customers took the device home and then found that it would not switch on. We simply sent them back to Sony who supplied a replacement Xperia Z3.

    We are still waiting for a response from Telstra.