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; } } Oonagh Reidy, Author at Smart Office - Page 69 of 116

    Smart Office

    iOS Rule: Nokia, Droid Drool – Apple King AGAIN

    Look out Samsung: Apple is back on top as world No.1 smartphone, according to analysts.


    Click to enlarge
    Apple V Samsung: let the smartphone battle begin (again)

    Apple reclaimed top position as the world’s No.1  smartphone vendor during final months of 2011, taking the crown off Android rival Samsung, who held the spot in Q3 (stealing Apple prided position).

    Thats according to Strategy Analytics who confirmed this week global shipments of iPhones, Androids and others grew at an astounding 54% hitting “record” 155 m units in Q4.

    Read Jobs: ‘Stop Pinching Apples’, Google Here

    Shipments of Apple’s cult smartie, the iPhone, surged a startling 128% compared to same period in 2010, to 37 million devices.

    Korean brand Samsung shifted 36.5 million smartphones during the quarter, while Nokia lagged in third place with 19.6m.

    “Apple overtook Samsung to become the world’s largest smartphone vendor by volume with 24 percent market share,” Alex Spektor, Director at Strategy Analytics, said.

    This was down to Cupertino’s crafty phone strategy which saw the “distribution of the iPhone family expanded across numerous countries, dozens of operators and multiple price points” he added.

    In other words, Apple left no corner of the market unturned in its bid for iPhone domination and sold more new 4S’ than any other model in months October to December, it told investors last week.

    However, all is not lost for arch rival Samsung and its flagship Galaxies, say analysts.


    Click to enlarge

    While Apple nabbed the top spot for Q4, the Galaxy creator were the overall smartphone leader in 2011 – for the first time ever – with 20% share of the smartphone pie, noted Strategy’s Neil Mawston.

    Shipments of its Android Galaxy devices, including flagship S II, Nexus and Ace, hit almost one hundred million last year – or 97.4m to be precise, beating Apple’s 93m.

    And its most definitely a two horse race between the arch rivals, says Mawston, meaning Galaxy V iPhone is shaping up to be the 2012 smartphone battle, again.

     

    “With Samsung is now well positioned alongside Apple in a two-horse race at the forefront of one of the world’s largest and most valuable consumer electronics markets,” said Mawston.

    And former mobile darlings Nokia also halved its share of smartphones from 33% to 16% in the past year due to a lackluster portfolio of smartphones and a limited presence in the huge US market – something the Lumia maker is looking to resolve in 2012 via its newly released Windows Phone’s and a concrete US strategy,  which CEO Stephen Elop spelt out last week.

    Nokia’s partnership with Microsoft will be very much in focus in 2012, and the industry will be watching closely to see how the duo can expand in the high-value 4G across the US and elsewhere, analysts noted.

    NBN Fit? Internode Boots CIO To Move Hackett In, Prepares For War

    Self declared ‘National broadband company’ restructures its business ahead of NBN rollout.



    Click to enlarge

    Adelaide based Internode has chopped several roles including Chief Information Officer, to be replaced by MD Simon Hackett as Chief Technology Officer well as keeping his existing role. 

    The broadband giant, which has over 200,000 customers, has been busy reshuffling staff and made four roles redundant, in changes announced today.
    The change was driven by the need to get Internode “match fit” and get its house in order ahead of the “opportunities” presented by the NBN, CEO, Patrick Tapper, said.

    “A major focus for us is to make it easier for our customers to deal with us online. Simon is taking on the role of CTO in order to provide additional ‘hands-on’ leadership of this process.”
    Just recently Tapper’s company released made its NBN pricing structure public, which starting at $59 was higher than anticipated and started off a price war, with cut-price operator Dodo announcing plans for services starting below $40, and Exetel undercutting both rivals pricing. 
    “The position of CTO formalises the role that Simon has consistently performed in the business during its 20-year history. Simon will also retain the role of managing director.” 
    However, Tapper laughed off any hint of woes at the Internet provider, saying, “t is very much full steam ahead at Internode.” 
    The four people who have left each played a great role at Internode, but there would have been too much overlap if remained unchanged, he insisted. 
    And, despite the departures, Internode is still “actively” hiring people for its 100-strong Technology division, with 13 positions currently open. 
     

    Internode has about 200,000 customers connected to its national network, the third largest ISP.

    LinkedIn Hack: 6.5 Million Passwords Spill Russia

    LeakedIn: Social network for pros suffers attack, 6.5 million passwords leaked to a Russian website.


    Click to enlarge

    A leaked password database has been published on a Russian hacking forum belonging to LinkedIn members, company Director, Vicente Silveira confirmed on a blog post, yesterday.

    The passwords appear in the form of a cryptographic “hash” which converts text into a sequence of numbers and letters using a mathematical formula, say security experts.

    The LinkedIn passwords did not contain a “salt” which usually protects against dictionary and other attacks.

    “We can confirm that some of the passwords that were compromised correspond to LinkedIn accounts,” wrote Silveira. 

    The social network for professionals has around 160 million members globally, all of who have been advised by security experts to change their password.

    Security experts SophosLabs who examined the password “dump” says there are 5.8 million unique password hashes in the leak, or which 3.5 m have already been ‘brute forced.’

    “That means over 60% of the stolen hashes are now publicly known,” warned Chester Wisniewski, SophosLabs.

    Other passwords the security experts found in the dump include ‘linkedin’, ‘linkedinpassword’, ‘p455w0rd’ and ‘redsox’.

    “We even found passwords that suggest people should know better like ‘sophos’, ‘mcafee’, ‘symantec’, ‘kaspersky’, ‘microsoft’ and ‘f-secure’,” Wisniewski added.

    The social network said it is “continuing to investigate this situation” and says members whose passwords have been compromised are no longer valid.

    Members affected will also receive an email from LinkedIn with instructions on how to reset their passwords.

     

    There won’t be any links in this email but you follow this step and request password assistance, users will receive an email from LinkedIn with a password reset link.

    “Affected members who update their passwords and members whose passwords have not been compromised benefit from the enhanced security we just recently put in place, which includes hashing and salting of our current password databases,” Silveira confirmed.

    “We sincerely apologize for the inconvenience this has caused our members. We take the security of our members very seriously,” he added.

    Cooked: Conroy Blasts Turnbull’s NBN Rumble

    Minister for Broadband blasts political foe as “lazy, financially illiterate, or both”


    Click to enlarge
    The Hon Malcolm Turnbull and Minister Conroy, in happier times.

    Senator Stephen Conroy has come out fighting today, declaring Shadow Communications minister, MP Malcolm Turnbull, has ‘once again’ misled the public, with claims the National Broadband Network (NBN) has witnessed a $400m “blowout” after the recent budget.

    “Mr Turnbull has manufactured claims of a ‘blowout’ and a ‘fiddle’ in the budget treatment of the National Broadband Network,” Senator Conroy said today.

    And in a startling attack on the Liberal MP for East Sydney, Conroy added: “Mr Turnbull is either lazy, financially illiterate, or both.”

    Turnbull claimed figures for NBN revealed in the latest Budget, announced Tuesday, show the cost of NBN has risen over $400m compared to last year.

    “As a former merchant banker, Mr Turnbull presumably knows that you pay your bills when they fall due,” Conroy continued.

    “The $450 million additional Departmental expenditure in 2011-12 is the payments made to Telstra under the terms of the Definitive Agreements.These agreements came into force on 7 March last.”

    There is “nothing new” about the payments (set to total $11 bn across several years) to Telstra nor can they be described as having been ‘brought forward,’ he added.

    Turnbull, a vehement opposer to the $36bn high speed NBN and Labor’s pet project, latest claims are totally “false,” according to Conroy.

    “Mr Turnbull’s assertion that there has been an increase in equity of $400M simply reflects that equity funding of $350M was deferred from 2011-12 to 2012-13. This was detailed in the 2011-12 Departmental Portfolio Additional Estimate Statement on page 39.”

    “Mr Turnbull also continues to claim that the treatment of the equity injection into NBN Co by the Government should be expensed in the budget. This is completely wrong.”

     

    The broadband fibre network currently being rolled out, is an investment in an asset from which the Government will receive a return, says the Broadband Minister and is classified as an ‘equity investment’ rather than a ‘budget expense.’

    This practice is consistent with long-standing budget treatment applied by this and previous Governments, says Conroy.

    Turnbull also attacked the numbers using NBN currently  in a statement Tuesday, criticising the” “5000 or so customers currently using its fibre network, compared to the 137,000 projected by June 2012 in NBN Co’s corporate plan.”

    Hello Stiletto: Westpac Backs World’s Biggest Brothel

    Westpac is financing the world’s biggest ever brothel, set for Sydney’s Paramatta Road.

    Parramatta Rd, synonymous with heavy traffic will now be know for something else – a ‘three-storey 42-room mega-sex-plex’ to be built opposite Sydney University, reports SMH.

    No. 84 and 86 will be joined with the existing establishment at No. 82 Parramatta Road, and those pesky pile ups will also be a thing of the past – the enlarged premises will also boast a large underground car park.

    The super brothel plan, devised by porn king, Malcolm Day, will also include seven swanky suites kitted out with pool tables and dual beds set up for parties and group booking on the top floor. 

    Stiletto, the current brothel occupying No.82, owned by racing industry figure, Eddie Hayson, is to be bought out. 

    Day, who is currently raising investment backing is already said to have a major backer – one of Australia’s biggest banks, Westpac, who are set to be key to the go ahead of the mega brothel, investing $12.1 million in the sex scheme. 

    If Day’s plan come to light, Stiletto will be the largest known brothel in the globe.

    And it also looks as if it will a good money spinner: “The new complex will create the largest short-stay bordello globally. On completion, earnings are projected to double to $40 million of revenue and $12 million of EBITDA,” according to a stockbroker presentation.

     

    The presentation also claims the plan is approved by state and regulatory bodies and already a “fully incensed and legal premises, with all regulatory approvals obtained – 10 year operating history.”

    Bye Bye TV: Sony, Sharp & Samsung Flee Big Displays – Tabs Takeover

    Traditional TV giants are fleeing the industry en masse as tight margins, poor demand and falling prices blight the sector.


    Click to enlarge

    LCD TVs once hailed as the consumer ‘must have’ now appears to be hitting a wall, as the tablet category, kicked off by the iPad and followed closely by a stream of Android clones, now reigns supreme. 

    So much so that three major TV makers, Sony, Toshiba and Hitachi, today announced a merger of its display businesses to create a bulwark against the likes of Samsung and Sharp, lower costs and get a grasp of the small display industry. 
     Read Team LCD: Sony, Toshiba & Hitachi Shock Merger As Tabs Boom Here 
     The Japanese display giant aims to “establish a leading global company by integrating three companies’ businesses” to make displays for tablets and smartphones as well as invest in OLED technology, it said today. 
    “The global market of small- and medium-sized displays is expected to grow rapidly due to anticipated strong demand for high resolution, high value-added products” the trio said. 
     The tech powerhouse will be ran in partnership with government innovation body, backed by 200 billion yen in public investment, a welcome funding boost for all three makers, who have recorded dramatic falls in their display operations, with Sony noting dropping global demand for its flagship Bravia LCDs in its most recent financial report. 
    And Samsung and LG, two of the top Australian TV brands, are also to follow suit, with reports this week suggesting both Korean smart 3D TV makers are planning to slash panel production and convert lines into tab and small display factories.
    Samsung, the current No.1 display maker globally, are said to be to be planing to cut LCD TV production by a massive 80% and concentrate on notebook and tablet screens, with LG also set to cut production as its panel business struggles with major losses, and chop capital investment by 25%. 
    “We plan around 3 trillion won ($2.8 billion) of capital spending next year and have no plans to build a new factory,” a LG Display spokesman confirmed. 
     In July, the 3D Cinema TV maker reported an 87.3% plunge in net profits for Q2 and its display division posting a 96 per cent dip in net profits to 21.3 billion won. 
    This comes as a sales of Android handsets grew over 350% during Q2 alone and tablet sales reach record heights, and estimated to be worth $35 billion as an industry next year, with global shipments of around 80 million, according to JP Morgan Securities forecasts. 
     

    In June, Sharp said it would cut large display production from October and focus on small screens in its TV-panel plant in the Japan’s Kameyama city. 

    Read Tab Threat: LG Slash LCDs As iPad 2 & Androids Call The Shots Here
    Sony net profit also slumped into negative territory in its most recent quarter, to -$191m, compared to a profit of 25.7bn yen the same period in 2010, blamed partly on losses in its consumer business, including TVs, forcing it to downgrade LCD sales forecasts even further. 
    The Bravia maker, who has never made a profit selling flat panel TVs, has seen global sales fall to 22 million during the past 12 months, had previously said it would reconfigure its TV production operations. 
    In the past, Sony has partnered with Samsung and Sharp in the production of flat panel TVs. It also banked on 3D to give them an edge in the TV market, although boss Howard Stringer is confident the new venture will help resurrect its troubled display business. 
    “By integrating each partner company’s wealth of display expertise and know-how, I am confident the new company will become a driving force for technological innovation and new growth in the rapidly expanding small- and medium- sized display market, said Stringer, Sony CEO and President. 
    “It’s been one of the losers,” Keith Wirtz, the chief investment officer at Fifth Third Asset Management, which owns 40,000 Sony shares, previously observed about its TV business.

    iCloud iPhone: ‘Transition’ 4 To Steal iPhone 5 Thunder, Say Sources

    iPhone 4 is to get a makeover…from the cloud. How? iOS 5 + iCloud.


    Click to enlarge
    Image: Beam me up Scottie, iCloud iPhone.

    It has come to our attention that Apple is planning to combine iOS 5 and iCloud of hardware internally referred to as the iCloud iPhone,” according to Applenapps, citing sources ‘familar with the matter.’ 

     So, is this iPhone 5? Well, apparently not. 
     There are two models in the making – which we knew already – iPhone 5 and a rumoured iPhone 4 cheapie, which now appears to be the smartphone getting the iCloud treatment. 
     iCloud, Apple’s free cloud storage service, launched in June, carries “the centre of our digital lives into the cloud,” said Steve Jobs at the launch.
     “iCloud iPhone will rely heavily on Apple’s new cloud based offering, and less on internal storage,” say Applenapps sources. 
    Previously, Apple did say there was ‘transition’ in store for its new phones, so this could well be the change described. 
     This move would allow Apple cut its production costs by farming out internal storage to its fledgling iCloud and having less Flash memory on board. Bingo. 
     This news comes as iPhone has come under increasing pressure from cheaper Androids hitting the market a dime a dozen. Apple could have well woken up to the fact that its elitist device needs to get some mainstream pricing to fend off rivals. 
     Other changes to our beloved iPhone 4 will include mostly external redesigns – which will be different to the current version – and will wear an an aluminum back panel the same as the iPad 2, shying away from the glass encasing. (And run iOS 5, bien sur.)
     And the differences will be quiet noticeable, say sources, and is said to look like an iPad at first glance (can’t wait). 
     Like the iPad 2, ‘5’ will indeed be thinner, faster, and lighter sporting the same A5 chip for fast processing, as well as design changes to address previous antennae issues with ‘4’, but “the real star of the show will be the iCloud iPhone,” the sources indicate. 
     And another thing, iPhone 5 is said to be lacking 4G LTE technology, giving its understudy, the iCloud iPhone, another reason to steal its thunder. 
    Prices of the iPhone 4 are already being slashed stateside as retailers prepare for the new inventory. 
    So, how much will the cheapie version be? Apple are said to be ‘aiming’ for US$400 outright and free on a two year contract, while the new 5 will be $199 on contract. 
     

    This report appears to have legs, coming from three reliable sources from various levels of Cupertino. 

    iOS 5 and iCloud are due to launch in the “fall” (i.e. spring Down Under) – an ideal time to roll out the spanking new iPhones also, we do think. 

    Oh, and one additional footnote: iPhone 5 is said to feature Qualcomm’s wireless chip meaning GSM and CDMA version will be mashed into the one model.

    Apple TV By Foe Samsung?

    Apple look set to launch iOS TV using hardware from an arch rival.Rumor is rife within the industry that Apple are looking to relaunch its TV offering, first unveiled in 2007, but this time its actual branded Apple sets, as opposed to set top boxes of previous. 

     The latest project inside Apple is a devious plot to “blow Netflix and all those other guys away” with an internet ready TV kitted out with iTunes, one unnamed former Apple exec told Dailytech. 
     Last year it launched low cost $99 Apple TV device that gives users access to IPTV content and this is the latest move by Steve Jobs’ operation to give Google TV and other internet streamers a run for its money. 
     And the Cupertino firm is said to be teaming up with OEM manufacturer in the guise of rival Samsung – the arch enemies who cant seem to help not getting into bed together despite a highly publicised legal dispute, to make this happen. 
     That aside, Apple are one of Korean maker Samsung’s biggest customers behind Sony, making parts for its products including A4 and A5 processors found in the iPhone and iPad 2, so this rumoured partnership, if true, would certainly make business sense.
    Samsung, one of the high kings of the TV industry are certainly no stranger to smart TV’s and could do nicely out of the deal. “You’ll go into an Apple retail store and be able to walk out with a TV. It’s perfect” the source chirped. 
     

     However, when this is to launch is yet unknown although the source indicated a timeline between the fall (ie September) and next year was on the cards. 

    Fisher & Paykel “Serious” Cooking In SA

    Appliance giant Aussie invasion continues as unveiled showroom in South Australia, last night.
    The new showroom focusing on kitchen and cooking appliances is just for the retail community initially, but will open up to the general public at a later date, where consumers can purchase F&P goods.

    Among the appliances in working order are a compact oven, coffee maker, steam oven and microwave oven – all completely new appliances from the Fisher & Paykel brand in Australia, as well as outdoor cooking gear.

    The yet to-be-released DCS Grill will also be on show.


    Click to enlarge

    Fisher & Paykel, who may be subject to a takeover from Chinese brand Haier, is revamping its Australian showrooms to reflect the brand’s “globally aligned aesthetic and values” and is the second to be re-branded, after Subiaco, Western Australia.

    Fisher & Paykel says it is looking to strengthen its position as a “human-centred and social brand.”

    Around 80 guests – including members of the design, architectural and retail community- were at the opening, unveiled by F&P Chief Operating Officer Mike Church.


    Click to enlarge

    “The new showroom definitely has a strong focus on kitchen appliances, which shows we are serious about cooking,” says Fisher & Paykel SA and NT State Manager, Terry Williams.

     

    The market has been challenging in Adelaide for a while now, but Williams believes the new showroom opening comes at the perfect time.

    “I’m proud that Fisher & Paykel has such a stunning new showroom andour spectacular new products will stand us in good stead for the future,.”

    The new Fisher & Paykel SA showroom is located at 297 South Road, Mile End,Adelaide. Call 08 8344 0400 to make anappointment to visit the newshowroom.

    Telstra: Don’t Buy, BYO As It Goes Retro

    Happy with your old phone? That’s cool, says Telstra who are looking to rival Virgin’s BYO offer with its own deal.


    Click to enlarge

    The BYO offer on Freedom Connect plan out today are “specifically for customers who don’t want a new handset” and are looking for more bang for their buck.

    Bring a “compatible mobile to Telstra, and enjoy one plan that’s better value” than the equivalent Freedom Connect plan, it is urging consumers.

    This is also a bid to capture some mobile customers lured in by Virgin’s much publicised BYO offers. Optus also have similar deals ranging from $10 to $49 for 12 month contract. 

    Those who sign up to Telstra’s $59 BYO will enjoy the value of the $79 deal which includes $800 monthly calls, unlimited standard national SMS, unlimited messagebank retrieval and 2GB of data to use in Australia.

    The other plans are:

    ·    $49 Plan with $550 monthly call allowance, unlimited standard national SMS and 1.5GB of data to use in Australia.

    ·    $59 Plan with $800 monthly call allowance, 2GB of data use in Australia, unlimited standard national SMS and unlimited MessageBank retrieval.

    ·    $79 Plan with $1,200 monthly call allowance, 2.5GB of data to use in Australia, unlimited standard national SMS and unlimited MessageBank retrieval.

    ·    $99 Plan with an unlimited monthly call allowance for standard national voice and video calls, SMS and MessageBank retrieval, 3GB of data to use in Australia, $50 of international calling value.

    These plans include unmetered Green Dot BigPond browsing and free browsing on Facebook and Twitter.

     

     “Our Freedom Connect plans launched last month are doing even better than we’d forecast, with great call and data inclusions and an impressive line-up of mobile phones,” Telstra Consumer Exec Director, Rebekah O’Flaherty, said.

    “The new BYO plans acknowledge not everyone wants a new mobile phone.”