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 45 of 116

    Smart Office

    PayPal Support Online Clampdown On Phishing & Spoof Emails

    AS watchdog pledges to clamp down on consumers protection online, PayPal says phishing and spoof emails are now commonplace

    Online rorts like ‘drip pricing’ on comparator websites are priorities for the ACCC this year, Chairman Rod Sims said yesterday, as it emerged 76 per cent of Aussie internet users purchased online, last year. 

    According to a recent ABC 7.30 report, Australians are losing $7 million a month to internet fraud.   
    Online scams and consumer guarantee rights are bugbears the watchdog will be tackling this year. The consumer watchdog, Australian Competition and Consumer Commission, now receives around 160,000 consumer complaints annually. 
    “We welcome the ACCC’s increased focus on protecting consumers in the digital age,” says Jeff Clementz, managing director for PayPal Australia. 

    The digital economy, has caused “a number of consumer protection challenges” that industry and government need to address to create a safe digital environment for consumers and businesses, he said.
    Phishing and spoof emails are a common issue facing business in the online marketplace, says PayPal, which is owned by ecomm giant eBay. ‘Scammers’ will attempt to replicate the identity of service providers in an effort to attract personal information. 
    The payment giant told ChannelNews it is tackling online scams via new technology solutions, carrying out investigations, and consumer education. 
    “Consumer education is key in helping address scams,” says Clementz, and says PayPal, is “committed” to protecting its 5.5 million Australian account holders. 
    “We’re thrilled that ACCC is taking the next steps and exploring how they can proactively reach out to victims to stop money being sent to scammers.”
    The company has also expanded Seller Protection to merchants that use PayPal to process transactions for tangible, big box items. 
    “We will be continuing to collaborate with organisations such as the ACCC and the Australian Government to help address consumer protection challenges, ensuring Australians are adequately protected to enjoy the choice and convenience afforded by global online and mobile commerce.”
    Any PayPal customer that feels they have received correspondence that is suspicious can contact customer support or email spoof@paypal.com.au to verify the legitimacy of the correspondence. Additionally, customers should never click on links in emails and log in to their PayPal account to check on the status of transactions.

    NBN Unleash Tassie Stage II But Is Super-Speed Broadband Here Already?

    Stage II of NBN’s Tassie project has kicked off as AARNET says it is doing now what the NBN promises in ten years time.

    AARNet and Cisco have announced “successful” trial of a 40GB service, which “demonstrates Australia has the infrastructure and capabilities in place to support the demanding ICT requirements of the Square Kilometre Array (SKA)” it said in a statement yesterday.  

    This means the new technology is likely to deliver speeds of up to 100 Gigabits per second (Gbps) on its east coast network within a year –  far greater than the NBN projected speed of  100MB p/s, Australia’s Academic and Research Network (AARNet) claims. 

    The project team which included Cisco installed new 40Gbps muxponders onto its existing cables enabling it to transmit parallel wavelengths greater distances without regeneration. 

    The high capacity network is critical for “big data” transfer, data processing tools and collaboration needed to produce global research for scientific disciplines such as radio astronomy. 

    The 40/100Gbps trial is a “quantum leap” forward, the CEO of AARNet said yesterday. 

    “We will be doing things than the NBN might be doing in 10 years, except we’re doing them today,” Don Robertson, chief operating officer confirmed to News Ltd. 

    However, Robertson insisted the NBN would be “complementary” as opposed to competing with the controversial $36bn national broadband network, currently under construction. 

    “The NBN is a complementary to AARNET but it (the NBN) more particularly provides short to medium term connections to individual houses, small companies and schools.”

    “They’re talking 100MB per second, possibly moving to one gigabit per second. We’re talking many orders of magnitude greater.

    “We’re complementary rather than competitive and for the foreseeable future the NBN wouldn’t be carrying the sort of data rates we’re talking about here.”

     

    The project is being carried on behalf of the Commonwealth Scientific and Industrial Research Organisation (CSIRO) and radio astronomy community as part of Australia’s bid to host Square Kilometre Array radio telescope international science project in 2012. 


    The trial connected three CSIRO landmarks including the Parkes Radio Telescope known as ‘The Dish’ in central west New South Wales, Narrabri Observatory in northwest of the state, and the CSIRO’s main radio astronomy headquarters in Marsfield, Sydney. 

    “The high bandwidth required for this sort of trial is a great example of how Australia’s existing infrastructure can support the SKA’s vision in a cost-effective manner,” Dr Brian Boyle, SKA Director of the CSIRO. 

    With the right equipment on the back end of the fibres, the network can deliver up to terabytes per second, he added. 


    However, its use in practical terms will be limited for the moment as it is light years ahead of current internet traffic requirements. 

    This comes as second stage two of the controversial NBN project kicks off in Sorell, Tasmania, which “will provide access to high-speed broadband to more than 11,000 homes and businesses (in Tasmania) upon completion,” the Broadband minister, Stephen Conroy, said. 

    “The Gillard Government is getting on with the job of delivering enhanced broadband services to Tasmania, which has traditionally had the lowest proportion of households with broadband access,” Senator Conroy said.

    However, it appears take up has, to date, been limited with recent reports suggesting take up among Tasmanian’s was just 16%. Senator Conroy denied this figure, insisting it was far higher. 

    The other “stage two” communities of Triabunna, Kingston Beach, Deloraine, St Helens, George Town and South Hobart will also kick off “shortly” with services expected to be “available progressively” from March 2012.

    This follows the launch of commercial services in Tasmania in July 2010 in Scottsdale, Smithton and Midway Point.

     

    Households, businesses and schools in these communities are already experiencing the benefits of high-speed broadband and improved competition,” Senator Conroy said.

    Bendy Battle: Samsung V Nokia 2012 War

    Who is the bendiest of them all? Phone titans Samsung and Nokia are to go head to head in a bid to create the most flexible smartphone displays. Just last week, Nokia unveiled its answer to the flexible smartphone in London, at its “Future Lounge’ which saw the debut of a prototype device that can be controlled by bending it.


    Click to enlarge

    For instance, folding the top right-hand side of the clever screen will command the device to scroll upwards and bending the bottom will scroll down. Although still in development stage, Nokia hopes to debut the flexi-phone, Kinetic, next year.

    But phone rival Samsung, who already made public its intention to mass produce flexible OLED screens, confirmed bendy models will be a reality in first half 2012 at  earnings call last week.

    “The flexible display, we are looking to introduce sometime in 2012, hopefully the earlier part,” Samsung’s Vp of Investor Relations Robert Yi revealed at last week’s earnings call.

    “The application probably will start from the handset side.”

    Previously, it was flagging 2013 – 2014 release date but now it looks like its stepping up the ante as Nokia rivals device gears up for a release next year.

    But its not just phones Samsung are bringing bendy technology to, tablets too and maybe even TV’s are to get the flexi treatment.

    “We will start with handsets and migrate to tablet PCs and other devices,” he added.

    Earlier this year it revealed an AMOLED screen for Galaxy smartphone that could be folded over 100,000 times yet lose only a tiny percentage of screen quality.

    Recently reports were also circulating about a bendable Galaxy S II model planned using “rollable [and] bendable” plastic polyimide substrate strong enough to “survive blows from a hammer.”


    Click to enlarge
    Images from Nokia Future Lounge, London last week.

    However, flexi phone are just part of the war currently being waged between phone rival Nokia and South Korea’s Samsung.

    Galaxy maker’s are now the top phone maker by shipment, beating Nokia to the title, according to latest statistics from Strategy Analytics.

    Samsung last week revealed phone shipments soared 44% to 117m units in Q3 and shipped approximately 28 m smartphones – beating former king Nokia (16.8m) by 10 million as well as arch enemies Apple’s 17.1m units, losing its palce at the top.

    “After just one quarter in the top spot, Apple slipped behind Samsung to second position and captured 15 percent share. Apple’s global smartphone growth rate slowed to just 21 percent annually in Q3 2011, its lowest level for two years,” Neil Mawston, Strategy Analytics Director, said. 

     

    “We believe Apple’s growth during the third quarter was affected by consumers and operators awaiting the launch of the new iPhone  4S in the fourth quarter, volatile economic conditions in several key countries, and tougher competition from Samsung’s popular Galaxy S2 model.”

    However, the analysts did point out the turmoil Nokia engendered by its changeover from Symbian to Windows phone during the third quarter so Q4 should tell more, particularly when Apple iPhone 4S released earlier this month sold 4 million on its first weekend comes into play, and could put Cupertino back in pole position.

    “Strong growth was mainly lead by smartphones with regional expansion of Samsung Galaxy S II,” Samsung confirmed  at earnings call on Friday.

    Solid growth across all segments was also down to enhanced “mass market” models like Galaxy Wave and Galaxy Y Pro and  shipments were also up in emerging markets China, South America and Southeast Asia. 

    iTV: “Full TV, Touch, iOS Halo Effect” – Analyst

    Apple TV is coming to a living room near you and will be as touch friendly as an iPad.
    iTV will be a set-top box built into the Apple TV and your home screen will work like an inflated iPad.

    Thats what Peter Misek, senior tech analyst from Jefferies & Co revealed on Friday telling CBNC what he believes iTV will be:

    “An integrated full feature TV set, set top box integrated in the set….much as you would touch iPhone, iPad you would touch the air in front of you with gesture control.”

    “Asian manufacturers we’ve been in contact with have indicated production yield on iPhone 5 has improved, and we think iPad mini, and also believe iTV has gone into production,” he added.


    Click to enlarge

    But other clues iTV is definitely coming appeared last week, Misek noted.

    “GDSU indicated yesterday that they had a new customer ‘Livingroom Base’ – we believe its not a gaming company….that’s Apple.”

    Read: Hello iPhone 5, iTV: Apple To Hit $1 TRILLION Value?

    But iTV wont be a big driver for Apple earnings per se, says Minsk, rather it will have a huge ‘halo effect’, where the new Apple device will encourage users to stay within the iOS ecosystem.

    “If you have an iTV or are hooked into iTV services you’re unlikely to buy any other phones other than an iPhone and certainly you’re next tablet will be an iPad,” the Jefferies & Co analysts added.

     

    “Its more about selling more iPad and iPhones than selling TVs.”

    Other rumours that have ran about Apple TV of late are a 42″ 20:9 screen (ditching iPad’s 4:3) res, Siri to search the Internet for TV content, iSight camera and is highly likely Apple TV will run a version of iOS tailored for the big screen but will be similar to iPhone, iPod and iPad.

    Read: What Does The Internet Know About An Apple TV?

    What A Turn Off! Google TVs Returned By Users

    Disgruntled Google TV users are returning sets in droves. Logitech International, which makes hardware running Google TV technology including Revue set-top box andl keyboard, recently announced revenue losses in the category, saying more units were returned than sold.


    Click to enlarge


    This was “partly due to the fact that Google TV has not yet fully delivered to its own promises,” Logitech Chairman Guerrino De Luca, said in a conference call Thursday.

    Logitech itself had promised “there’s no telling what your TV will be able to do” with its hardware running Google. 

    Revue has a keyboard with integrated touch and directional pad, an HDMI cable and IR blaster. 

    He also admitted his company has misjudged the smart TV market. It is now to slash the price of Reuve by 60% – from US$249 to just US$99. It was originally launched with an RRP of US $299.

    “We launched Revue with the expectation that it would generate significant sales growth in spite of a relatively high price point and the newness of both the smart TV category and the underlying platform,” De Luca lamented. 

    Sony were also said to be unhappy with the performance of its TVs running on Google Android, first launched in the US last September. 

    However, despite the dissing, Google say Logitech’s complaints wouldn’t stop the giant chasing its TV dreams.

    “It’s still early days for smart TVs and we’re investing to continue to bring innovation and progress for our partners and users,” a spokesperson said. 

    The Android creators are also said to be working on a second version of Google TV, which will run You Tube movies and a stash of apps, to be delivered later this year.

    Unprepared: How Dicks Sale Went (Horribly) Wrong

    You don’t plan to fail but you can fail to plan.


    Click to enlarge

    That’s the lesson to be gained out of Dick Smith’s disastrous gaming sale, which kicked off on Monday last and left thousands of consumers sour faced-after the mammoth sale went horribly wrong.

    Some were even branding the $7m clearance sale a “scam” after Dick’s website crashed with enthusiastic consumers wishing to get their hands on massive bargains including Sony’s PSP for $40 and Assassins Creed 2 for just $5, while others arrived instore to find out the sale goods were not even in stock.

    A document leaked online which listed everything – including consoles, gaming titles that were to go on sale was part of the problem, a ‘mystery’ DS employee told Gizmodo.

    Read: Scorned Customers Lash Out Over Dick Smith’s $7M Sale ‘Scam

    The leaked list didn’t mean every item would be available in every store, the staffer added.

    “To us staff, we can translate that document immediately to see what’s in stock and what isn’t, whereas anyone else would have looked at it and thought ‘EVERYTHING IS ON SALE!”

    The leaked item list forced the retailer to fast forward the sale to April 02 – a full ten days before it was actually scheduled to take place on the 12th.

    “We were meant to be given a week to price all the games and have it ready for sale come April 12th but due to the leak the entire thing was bumped up, giving us staff very little time to prepare for it,” the employee revealed.

    And was it a way for Dick to flog gaming stock due to discontinuation of its gaming department?

    No it was “just to clear out old gaming stock,” the mystery employee insists.

    “Dick Smith is certainly continuing to sell games because no new games were put on sale and our system is still being actively stocked. I’d wager they’re trying to liquidate old stock as Woolworths do want to sell the business off.”

     

    Dick Smith’s General Manger blamed “the unforseen popularity of Dick Smith gaming sale”  for customers leaving the store empty handed.

    “We understand a certain amount of misinformation was published online last week that led some customers to believe certain products were on sale when they were not or they were a different discount.”

    What Christmas? December Retail Down: ABS

    December retail down slightly, according to newly released ABS figures.
    The Australian Bureau of Statistics’ (ABS) latest figures show retail turnover fell 0.2 per cent in December, despite the widely expected Christmas spending boom.

    The drop was identical to the previous month’s fall. The trend estimate for retail turnover also fell 0.1 per cent last month, according the the ABS. However, compared to 2011, sales rose 2.3%.

    Online retail sales fell slightly last month, according to NAB Index released this week, although were up 23% y-o-y.

    The largest contributor to the fall was ‘Other’ retailing fell -2.8 per cent, followed by cafes, food services (-1.1 per cent) and food retailing. 

    However, there were rises in clothing, footwear and personal accessory retailing (+2.1%), household goods which includes consumer electronics (+0.8%), and department stores (+0.8). Electrical and electronic goods retailing rose 0.2%. 

    Over the longer term, ‘Other’ retailing and household goods were the weakest performing industries in trend terms, down 0.5 and 0.4 per cent respectively.

    ARA Executive Director Russell Zimmerman said the figures would be disappointing to retailers who were hoping for some love from shoppers for the festive season and showed consumers were under too much pressure with tax hikes, increases in utility bills and private health insurance.

    “Compared to December 2011 overall retail growth sat at 2.3 percent for December 2012, which is well below the rate of inflation. It was clear in the lead up to Christmas household budgets were stretched to the limit,” he said. 

    NSW retailers bore the brunt of the fall in spending down 0.7%, followed by Victoria (-0.2 per cent), Western Australia (-0.3 per cent) and the Australian Capital Territory (-0.8 per cent).

    Retail turnover in Tasmania (+2%), the Northern Territory (+0.7) and South Australia (+0.1), all rose.

    Orange IT Shuts Stores, JB Hi-Fi Bites

    Orange IT appears to have closed retail stores as competition from JB HiFi and big retailers bite

    AS one retailer closes….

    As one electronics retailer closes…The Orange IT store in North Sydney closed its doors several weeks ago just JB HiFi opened a new store a few doors away in Walker St earlier this month. 

    Inside the North Sydney Store all stock has been cleared, although there is no closing sign on the door. It appears the price friendly electronics retailer is shutting all its stores in Sydney, including Clarence St and Haymarket in Sydney CDB, according to IT consumers on Whirlpool.

    The company could not be contacted for comment and is not answering calls on the phone numbers listed on its website and Facebook page, and appears to have gone underground.

    The company has an address listed as T9 and T15, Level 1, 730 George St Sydney.

    Orange IT has not updated its Facebook page since November, even though customers are contacting them with complaints and queries about products purchased.

    Another opens….Jb Hi-Fi North Sydney

    Whirlpool user ‘rickyt’ wrote on January 25: “Word to the wise, we normally use Orange IT on Clarence St in Sydney to sort out our PC’s in the office. Today they have advised that they cant deliver our order and they are closing… not sure if this is all stores but I suspect it is.”

    The company, which sells everything from HP notebooks to PC accessories like Logitech speakers, Toshiba storage devices and Targus laptop bags, appears to be still selling online, however.

     

    Orange IT’s eBay store is still alive and kicking and has listed products dated as recent as 20 February. They’re even offering free delivery on most goods.

    Orange IT customers include “corporates, small business, government, students” according to its website.

    “I like Orange IT however recently they haven’t had much in stock. It’s sad if the whole chain closed down,” another consumer wrote on the forum.

    Malware Turns 0.5 M Telstra Users To ‘Zombies’?

    They will if malware threat becomes a reality.


    Click to enlarge

    That’s according to Telstra Internet and broadband domain boss, Barrie Hall, who revealed recent tests to prevent botnets on BigPond network could prevent a mass number being infected with malware, which could turn their PCs into a zombie army.

    The tests, which were successful, involved using Domain Name System poisoning, often used by cyber criminals, and Nominum Network Protection System (NPS) to detect malware amongst its customer network, Hall told Internet Industry Association’s (IIA) iCode Forum yesterday, reports CIO.

    Telstra’s tests used Nominum systems to get a hold of domain names usually used by botnets to communicate with their mother ships. Hall and his team tested 1 million BigPond IP addresses and found 5.4% (or 54,000) had signs of being infected by a botnet, which is a group of infected or compromised PCs.

    This means, overall, up to half a million Telstra broadband customers could “potentially” be infected with malicious software, he said. The tests excluded mobile broadband services.

    Across Australia generally, the botnet infection rate is around 10% for fixed line and is lower, 5%, for wireless services.

    That means one in ten of us have some infection or malware on our PCs. Scary.

    But this seemingly alarming number is low compared to some other countries, including the US where it can reach 10% infection rate and Thailand which can hit an astonishing 40%.

    So why does Australia have such a low botnet rate compared our friends abroad?

    Most of our internet is accessed via gateways and routers, which often has a level of inbuilt level of protection compared to older systems, Hall said.

     

    However, some might say using DSN poisoning in tests is not a great idea, he admits “a lot of my colleagues would say that mucking with DNS is evil.”

    “We’re at war,” with these malicious attacks and the harm that could result, Hall warned.

    However, making consumers aware of the problem of malware and what to do about it is also vital, the iCode forum also heard.

    This comes as Australian Media and Communication Authority (ACMA) that between 7,000-7,500 internet users in Oz are either infected with DNSChanger or  continue to use the rogue settings.

    Read: Malware Alert! ‘Thousands’ Face Web Blackout

    The Authority also warns that D-day is coming for computers infected with the DNSChanger malware, which changes a user’s Domain Name System (DNS) settings, enabling cybercriminals to direct unsuspecting web users to fraudulent websites and interfere with their web browsing.

    Computers that remain infected after 9 July will have” severely crippled internet access”, so Aussies should check their PC’s now, ACMA said in a statement.

    You should also check that computer’s settings for accessing the internet are not the ‘rogue’ settings installed by DNSChanger.

    Even if you have removed DNSChanger malware, it is possible your computer is still using rogue settings.

    Check here if your PC is infected.