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

    Smart Office

    SocialDial: Facebook Phone.. With No Numbers

    Phone your Facebook friends on your iPhone without even knowing their number. SocialDial is an app for iOS and Android that lets you call and text Facebook and LinkedIn friends from your mobile.


    Click to enlarge

    The no-numbers phone call builds a new address book that includes all social networking friends and contacts, similar to the way Skype’s mobile app captures phone book contacts.

    Users can call or text any of them simply by touching on their name.

    Know someone on your Facebook that you dont want to call you? Easy, SocialDial can block anyone from calling or texting your account.

    You can also make group calls, set up an invitation-only conference call among people on your social network as well contacts on your regular phone list.

    And best of all, the phone app is free.

    And unlike VoIP systems that can produce poor quality calls on mobile phones (that’s you Skype), the app uses your carrier’s local connection to provide the highest quality call possible.

    Just yesterday, SmartHouse reported how Australia was running out of ’04’ mobile numbers as demand rockets.

    And rather than fixed area access codes the future – by 2020 – will be dominated by ‘service’ numbers and IP addresses, say the Australia Media And Communications Authority.

    “For the last 130 years, the only way you could call someone was to have their phone number, it was their unique identity, their only identity as far as the telephone company was concerned,” said Randy Adams, CEO of Bababoo, the creators of SocialDial.

    “But today we have lots of unique identities, our Facebook name, our LinkedIn name and our email address, just to name a few.

     

    “There’s no reason we shouldn’t be able to call someone based on those identities, and that’s exactly what SocialDial lets you do.”

    SocialDial is available free of charge on the company’s web site http://socialdial.com.

    Myer: Online Sales Up 200%, Downgrades Profit

    Myer sales dip 0.9% as “challenging” environment bites, although online up a massive 200%.


    Click to enlarge

    The retailer announced third quarter sales today, which showed a slight dip in sales to $651.1m.

    On a like-for-like basis, sales in the 13 weeks to April 28, fell 2.1%, although excluding Myer’s rationalised categories including white goods, games and music, sales fell 0.2%.

    Myer Chief, Bernie Brookes, said the result was solid considering the very difficult trading environment in April, which has continued into May, he confirmed.

    This less than stellar performance has prompted Myer to downgrade its net profit forecast for full year 2012 to $162.7m – a 15% drop.

    The result “reflect[s] a very challenging trading environment and subdued consumer spending” the retailer said in a statement.

    Clothing, both womenswear and mensware, were the big performers during the quarter while Stores in WA, SA and QLD performed well, while NSW and Vic less so.

    The troubled retailer also said e-sales soared a whopping 200% compared to a year ago and is now placing a lot of eggs in its e-commerce offering, it confirmed:

    “We have continued to make improvements to our website incorporating an increased range. We have astrong pipeline of improvements planned.”

    Brookes also said feedback on its new customer services was positive and hinted economic changes including the recent rate cut may spur consumers to part with their dollars:

    “Despite the challenging sales environment, we are continuing to see positive customer feedbackfrom our investment in improving service, the addition of new wanted brands, growth in our MyerExclusive Brands as well as our enhanced loyalty program.”

    “While there may be a delay in any positive impacts on discretionary spend, the recent rate cut by the Reserve Bank, as well as an improving employment rate and the upcoming cessation of the flood levy, are timely as we head into the fourth quarter and the important Mid Year Stocktake Sale in June.”

     

    Brookes also blamed the fallout in equity markets and the ongoing turmoil in Europe continued to influence consumer sentiment.

    But the majority of net profit made in H2 comes from Myer’s Mid Year Stocktake sale, Brookes said, adding this was “disappointing” for the retailer last year.

    “However, we have made a number of changes to improve the offer,” he said.

    JB HiFi: TV Slump, PCs Soar

    JB Hi reveals product Movers and Shakers, by category

    JB Hi-Fi store sales grew 3.6% to $1.71b FY13 July-Dec, but TVs took a battering at the expense of PCs and accessories.

    Although sales rose here in Oz, they declined 6% in New Zealand to NZ$117.5m due to the boost prompted by the Rugby World Cup last year.

    By category, in Australia TV sales fell 12% (18% on a comparable store basis).

    The retailer said comparable store sales were down due to JB dropping TV categories in its newer stores.

    However, its not all bad for the TV market as the retailer is still experiencing “strong market share gains” and believes “the visual market is moving into a more typical replacement cycle, where volumes should stabilise”, it said in an investor presentation.

    Hardware sales were up 6.5%, although excluding the ailing TVs category, rose 11.5% and PC, IT and accessories are selling like hot cakes, JB Hi Fi CEO Terry Smart told CN, who said the stores were a “destination” for PC buyers, “as we’re able to offer range and excellent pricing.”

    Comparable store hardware sales fell 0.8%, although excluding TVs rose 4%, driven by strong sales of Cameras and Telecommunications gear.

    The retailer did say the launch of Windows 8 in October did hit PC sales, although JB Marketing Manager Scott Browning told CN late last year he expects 2013 to be a hugeyear for Microsoft’s touch based platform.

    Gross margin in HY13 increased to 21.8%, driven in part by the reduction in the heavy discounting seen in December 2011–good news for retailers who have been forced to engage in a price war of attrition, of late.

    But pricing is expected to remain “aggressive” during the remainder of FY13 across the ditch in NZ.

    However, it wasn’t such a good six months for sales of content ‘software’ like Music, Movies and Games for JB Hi-Fi stores which stumbled almost 5% and, on a comparable store basis, fell almost 11%.

    JB is forecasting a fall in value of software sales from 26% (74% hardware) to 24% (hardware +2%), and said the rate of comparable store decline in software was similar to FY12.

     

    However, its Now music streaming service continues to grow steadily and will provide longer term growth as it expands into other digital content categories, although it is not yet clear what these new digital categories will be.

    JB were not available for contact at the time of writing.

    On the appliance front, the retailer said its four JB Home concept store trials and sales were “encouraging”, and ahead of internal expectation.

    “The new concept appears to have been positively accepted by ourcustomers, with no negative impact on the traditional JB Hi-Fi categories,” the retailer said.

    Will The Real ‘Price Gougers’ Please Stand Up?

    After ‘stonewalling’ the IT pricing inquiry, Apple and Microsoft are being asked to answer to Parliament.
    Apple and Microsoft are to appear before the parlimentary inquiry into IT price gouging, forced to defend the alleged price ‘gouging’ of Aussie consumers.

    Adobe has also been summoned to appear at the Inquiry into IT Pricing, as well as Apple and Microsoft for a public hearing in Canberra on March 22, the House Committee on Infrastructure and Communications today confirmed

    The Committee, running since July last, is looking at the impacts of excessive prices charged to Australian consumers for IT products, like iPads, Microsoft Windows software and digital music downloads like iTunes compared to the US, examining claims made by consumer watchdog Choice that we pay around 50% more for “identical” tech products.

    Choice welcomed the move and says it hopes the inquiry can create real pressure for lower prices here.

    “We welcome the move by the Committee to force these companies to front the Australian public and explain why they think it is okay to charge Australians more,” says Choice CEO Alan Kirkland.

    “We found that with one Microsoft software development product, you could fly to Los Angeles return to buy the software and still save thousands of dollars.”

    CHOICE also warned Apple and Co to come to the hearings prepared with answers and not just excuses, and says the inquiry has been hampered by ‘stonewalling’ from Apple, Adobe and Microsoft, who refused to publically front the inquiry and explain why they charge extortionate prices.

    The IT pricing inquiry is seeking to determine why those extreme price differences exist and the actions that should be taken to address any differences.

     

    Labor MP Ed Husic, a MP for Chifley has also been a major advocate of the inquiry, which may force big companies to lower their prices down under.

    “With price differences this stark, the same old excuses just won’t cut it anymore”, Choice warned in a statement today. 

    “Australians are waking up to the fact that we are being ripped off. We believe it’s time that these companies realise this and start pricing fairly in the Australian market,” says Kirkland.

    1.3M Added To NBN ‘By 2016’, Despite Delays

    “We’re getting on with the job,” says NBN boss, but experts doubt new rollout figures.


    The NBN Co. add 1.35 million new premises to the fibre broadband roll out, to be complete by June 2016. 
    The updated NBN three-year plan, announced yesterday, adds almost 190 new towns and suburbs in areas covered by the previous rollout plan and some brand new locations in every state.
    These include Albion Park, Bankstown and Gunnedah in NSW, Airlie Beach, Sunshine Coast Caloundra in Queensland, and North Melbourne and Glen Iris in Victoria.
    For a full list of all areas click here 
    4.85 million premises will have fibre broadband services commenced or complete within the three year timetable, if the new figures are met, NBN Co. claims. 
    Image credit: The Australian

    50,000 Australians are currently using the NBN with construction currently commenced or complete in around 1 million premises. 

    This comes after NBN Co earlier this year admitted  that it would not meet its targets of connecting 341,000 premises to fibre by the end of June this year and was forced to push back the roll out timetable, blaming construction contractor delays. 
    “We’re getting on with the job of rolling out the NBN in every state and territory. Our plan is to deliver better broadband to every Australian over the remaining 8 years of this 10 year build.” NBN Co. CEO Mike Quigley said. 
    One third of eligible families have purchased an NBN broadband package in areas where the fibre network is live, and are guzzling data like never before, Quigley claims, as he seeks to give the controversial project credibility. 
    “One third of people with an NBN fibre connection have subscribed to the fastest speeds available. And households in the NBN fibre footprint are downloading around 50% more data than the average Australian broadband user every month.” 
    It is clear the NBN is becoming increasingly political ahead of this year’s election, with Labor and Liberals fighting over the cost and roll out of the mammoth plan, with Shadow Communication minister Malcolm Turnbull and Stephen Conroy having regular wars of words of the $37.4bn project. 
    At an event in Blacktown, NSW, to mark the connection of the first area of Sydney to the NBN yesterday, Minister for Broadband Stephen Conroy warned of a “digital divide” if the Opposition’s alternative NBN  fibre-to-node plan was put into practice. 
    “Your kids will be sitting there, and unless you can fork out up to $5000, your kids will not get access to the sort of learning we have seen today, and the sort of learning that is to come in the future,” Senator Conroy said.
    “The only risk to Labor’s NBN is Tony Abbott. Under Tony Abbott, households across the country will have their planned connection cancelled and be forced to pay up to $5,000 or be left disconnected from Labor’s NBN.”
    One expert told AFR the NBN Co. are “putting out essentially meaningless figures to give the project political cover”.
    However, NBN Co. boss also insists the price of NBN packages are competitive, and released additional figures to prove his point. 
    Nearly half of NBN users polled said household internet costs were roughly the same since switching to the NBN, NBN Co. claimed in a statement. 14% were paying less by using an internet phone service instead of a separate land line.

    Cyber-Mercenaries Target Tech Co’s

    Security analysts discovered “Icefog”, an APT group targeting supply chainsSecurity analysts Kaspersky Lab’s have reported the discovery of “Icefog”, an APT group targeting companies in South Korea and Japan, which is ultimately, hitting Western supply chains. Many sinkhole connections were also observed in Australia. 

    These cyber-mercenaries for hire have now emerged – smaller hit-and-run gangs that “go after information with surgical precision”, the security experts have warned. 
    The attackers are targeting the tech industry, in particular – computer and software development, telecom and satellite operators, mass media including Korea Telecom and Fuji TV. 
    The end result is hitting Western companies supply chains. 
    Military, shipbuilding and maritime operations are also under attack.
    The attackers hijack sensitive documents and company plans, e-mail account credentials, and passwords to access various resources within and outside the corporate victim’s network. 
    Such cyber attacks usually lasts for a few days or weeks and after, the gangs clean up the leave without a trace. 
    Those cyber mercenaries are thought to be based in China, South Korea and Japan.  
    Kaspersky researchers have sinkholed 13 of the 70+ domains used by the attackers, and observed more than 4,000 unique infected IPs and several hundred victims (a few dozen Windows victims and more than 350 Mac OS X victims). 
    The ‘Icefog’ command and control servers maintain encrypted logs of their victims together with the various operations performed on them.  
     

    Andrew Mamonitis, Kaspersky Lab ANZ’s Managing Director, says cyber networks often exploit the most vulnerable entry points by using corporate networks as a platform from which to access other channels.  

    In most cases, auxiliary companies have more relaxed security parameters in place despite holding valuable data about the parent target. 
    It is these secondary business service providers across the corporate chain which are most vulnerable to external breaches.In the future, the number of small, focused ‘APT-to-hire’ groups specialising in hit-and-run operations are set to grow. 
    Find out more about Icefrog here

    Are Internet Explorer Users Ditzy?

    A new study certainly thinks so. Canadian researchers AptiQuant has conducted an IQ study based on Internet browsers, and found Microsoft IE users had the lowest IQ out of the lot.


    Click to enlarge

    And it appears, Chrome, Firefox and Safari users had just “marginally higher” brainpower than average person, i.e over 100.  

    But users of Camino, Opera and IE with Chrome Frame were the smartest of all, with “exceptionally” higher IQ levels, the study also showed. 
    However, Microsoft IE browser users were painted as dim, showing IQ scores in the low eighties. 

    Vancouver based Psychometric consultants, AptiQuant, gave a free online IQ tested to 100,000 people and then plotted the average IQ scores based on the browser on which the test was taken. 

    The analysts sought to measure the effects of cognitive ability on the choice of web browser. 

    “It comes out pretty clear that Internet Explorer users scored lower than average on the IQ tests. Chrome, Firefox and Safari users had just a teeny bit higher than average IQ scores,” AptiQuant said, releasing its findings this week. 

    However, indignant Microsoft IE users have fought back and are threatening to sue AptiQuant, reports indicate. 

    And it appears its not just IE users that are disputing the results: Cambridge Professor David Spiegelhalter of the University’s Statistical Laboratory is branding the findings “an insult” and says they are flaky to day the least.

    “They’ve got IE6 users with an IQ of around eighty. That’s borderline deficient, marginally able to cope with the adult world,” he told the BBC.

    “I believe these figures are implausibly low – and an insult to IE users.”

    The report also goes on to engage in a scathing criticism of on the of the first ever browsers to hit the web: 

    “Internet Explorer has traditionally been considered a pain in the back for web developers….millions of man hours are wasted each year to make otherwise perfectly functional websites work in IE, because of its lack of compatibility with web standards.”

     

    “The continuous use of older versions of IE by millions of people around the world has often haunted web developers. It not only makes their job tougher, but has also “pulled back innovation by at least a decade,” the report states. 


    “Microsoft created a conspiracy with Internet Explorer’s shell integration with Windows Explorer, and making its removal complicated, if not impossible.”

    However, it sings the praises of open source browsers like Mozilla Firefox and Google Chrome that have taken away a large share out of Microsoft’s pie. 

    “These browsers are not only better in performance than IE, but offer better compatibility with W3C standards.”

    Hmm, it certainly seems very odd findings. Although not being a regular IE user anymore, Chrome is starting to bug me as is Google Search, to the point where I can’t find what  I am looking for or am redirected elsewhere. (And Google Docs keep crashing out.)
    Leonard Howard, CEO of AptiQuant said he has been receiving hate mail from IE users since yesterday. 

    “I just want to make it clear that the report released by my company did not suggest that if you use IE that means you have a low IQ, but what it really says is that if you have a low IQ then there are high chances that you use Internet Explorer,” he said.  

    The company did not feel threatened by lawsuit threats because they have all the scientific data and logs to back their claims, he said. 

    “A win in a court would only give a stamp of approval and more credibility to our report,” Howard quipped.

     

    The company spokesman said that they are really surprised by the unexpected attention that their study got. 


    He said that the company first thought of doing this study when they were trying to add some new features to the website and found IE versions 6.0 and 7.0 extremely difficult to work with.

    Its Bad: Sony Hack Jacko Nicked, Security SCREWED

    Sony’s latest Michael Jackson hack scandal spells serious trouble for the already troubled giant, as experts warn attacks are worsening.


    Sony latest hacking revelation is bad.

    Sony Music’s entire Michael Jackson back catalogue collection, worth more than $250 million, was stolen by “Internet hackers” last year, it emerged yesterday.

    The hackers took more than 50,000 music files, most of which were by the late pop singer by compromising Sony’s security systems.

    High profile artists like Jimi Hendrix, Paul Simon, Foo Fighters and Avril Lavigne were also affected.

    Sources say there was “a degree of sophistication” associated with the latest attack, according to The Sun.

    However, Sony refused to say how many tracks or artists were affected. 

    This latest hacking revelation comes despite the giant promising “all” their sites had been secured following a major hack attack on their PlayStation network, which took the Japanese giant weeks to inform its 77 million PSN users, whose accounts and personal data may have been stolen.

    And it appears the attack on the Jackson files occurred not long after this but has not been revealed to the public, until now.

    Shortly after Jackson’s death, the singer’s estate signed their biggest recording deal in history worth $250m with Sony Music, giving it the rights to sell his whole back catalogue as well as unreleased tracks.

    Two men who were arrested in May last year in the UK appeared in court last week accused of offences in relation to the Sony hack.

    This latest revelation does not bode well for Sony and is having a major negative impact on its business, say web security experts.

    “Cyber crime has certainly reached its tipping point around the world,” admits Ty Miller, Chief Technology Officer, Pure Hacking.

    “As is the case with Sony and its ongoing issues, these attacks are making a very significant commercial impact.”

    “It is no longer optional for organisations to ignore security requirements and prepare their organisation for a new operating environment where they may be under constant attack,” Miller warns.

    So what does this mean for web security as more and more big names are being attacked? Internet security experts McAfee Labs predict the “true” Anonymous hacking group will either reinvent itself, or die out while others are also predicting hacktivism on companies, public figures and politicians is on the rise.

     

    Organisations need to understand the risk profile that they have by regularly performing penetration testing, which allows them to mitigate their vulnerabilities before a security incident occurs, says Miller.

    Companies should proactively protect their corporate data through the use of Data Loss Prevention (DLP) systems. If not, they are accepting a needlessly large level of risk.

    Miller also says there has been a tripling of data attacks in its Australian client’s already this year. “And we don’t expect this to diminish,” he warns.

    “Organisations also need to monitor attacks by implementing Web Application Firewalls and Security Information and Event Management (SIEM) systems to detect ongoing attacks.”

    Bold Telstra Take Optus’ BlackBerry

    Telstra are going Bold but also doing the BIS on it. That’s right, the telco are offering BB server bundling on BlackBerry Bold 9900 with free/web mails. BlackBerry’s skinniest smartphone, Bold 9900 touchscreen, first carried by Optus as an ‘exclusive’ has now been passed over to Telstra featuring a 1.2 GHz processor, Liquid Graphics to bring the screen to life , 720p HD video recording.
    But 2.8″ Bold also boasts the infamous BB QWERTY keyboard, a 5MP camera, 8GD of internal memory, HSPA+, Wi-Fi and runs on BlackBerry 7 OS.

    Looks wise, the next gen skinny Bold (10.5mm) features “premium materials, a lustrous exterior with a brushed stainless steel frame and a high-gloss glass-weave backplate.”

    Telstra expect the new Bold will go down a treat, according to Tim Webber, Director of Mobile, as it is thinner, faster and more powerful than before. BlackBerry, notorious as a business device also now doubles over as a personal phone, separating personal from corporate content.


    Click to enlarge

    Bold 9900 features some “innovative enhancements, entertainment features and apps which combine with trusted BlackBerry security and best-in-class email to create the perfect smartphone for work and play,” said Adele Beachley, RIM the maker of BlackBerry, Managing Director Australia.
     
    BlackBerry latest 7 OS is faster with a better user experience, improved browsing, voice-activated searches like it’s iPhone rival Siri, BBM 6 (BlackBerry’s Instant Messenger service to communicate with other BB mates) and connect via apps and music.

    Telstra are offering the BlackBerry on Freedom Connect plans from today and unlike Optus are bundling a very sweet extra: BlackBerry Individual Service (BIS), which gives ‘unlimited’ BB emails and internet browsing via BlackBerry’s own browser, meaning users can web surf ’til the cows come home, literally.

    $99 Freedom Connect Plan for 24 months (min cost over 24 months is $2,376) with $0 upfront, includes $1,200 worth of calls and MMS plus unlimited text and 2.5GB of data in Australia.

    Business customers can get Bold on a range of Business Maximiser plans including for $0 upfront on the $129 Unlimited plan (min cost over 24 months $3,096).

    Optus, on the other hand, who have been flogging the device since August, are offering 9900 on a $79 cap over 24 months, with 3GB data and $900 of calls/ texts but BIS service is extra.

     

    This plan includes unlimited calls, SMS, MMS & Messagebank within Australia and includes 3GB of data for use in Australia.

    And despite the relationship with Optus, RIM say they are “excited” to be heading to Telstra with the 9900.

    “We’ve received great feedback that consumers and business customers alike are very impressed by the new BlackBerry Bold 9900 and we are excited to offer the device to Telstra customers,” Beachley added.

     

    Its Live! NBN Hits More Tassies

    Triabunna, Sorrell, and Kingston Beach now connected to high-speed broadband service.


    Click to enlarge

    Almost 4000 more Tassie residents can now receive super fast broadband of “up to” 100 Mbps following the completion of the latest phase of NBN rollout.

    The $36bn National Broadband Network is scheduled to hit a total of 12,800 Tas premises in total in the coming weeks, NBN Co said today.

    At a ceremony in Launceston today, the NBN fibre broadband was formally switched on in Deloraine, Triabunna, and Sorrell and Kingston Beach near Hobart.

    This comes as three Councils in Victoria have rejected NBN Co tower applications in the past few weeks – the latest in Moorabool Shire following objections by locals following visual impact concerns.

    The four new sites switched on today cover 3900 premises in addition to the 4000 already live in the test sites of Smithton, Scottsdale and Midway Point.

    Rollout to the rest of Oz won’t be complete until 2015.

    The activation of the network in George Town and St Helens is to take place in the coming weeks, adding a further 4900 homes and businesses to the NBN footprint.

    Chairman of NBN Tasmania, Mr. Greg McCann, said: “Tasmanians were the first in the nation to take advantage of the improved broadband access that the NBN will eventually deliver to every Australian.

    “I’m delighted that from today many more will be able to benefit from this essential upgrade to Australia’s decades-old telecommunications infrastructure.”

     

    Tasmania will become the first state in Australia to complete NBN rollout. The fibre optic broadband network will cover around 200,000 premises in all.

    NBN Co also announced today that it had begun plans to deliver its fixed wireless broadband to around 32,000 premises on the island state not covered by fibre.

    Construction in the new sites was carried out by Lend Lease Infrastructure Services working with NBN Co agent Aurora.To get connected to the network, homes in the new rollout locations need to contact one of the internet service providers offering NBN retail packages.