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; } } Wire Service, Author at Smart Office - Page 2 of 5

    Smart Office

    Microsoft Hypes Vista

    Microsoft is set to brief resellers and white box manufactures on the performance specifications of their new Vista OS. They are also set to roll out channel marketing programs so that system manufacturers can develop their own solutions.

    Millions To Watch World Cup On A Mobile Phone

    The World Cup will be a testing ground for TV on mobile phones, says a report.

    The football tournament will give phone owners a taste of what the technology promises and let operators work out how their networks will handle demand. The report by analysts Informa predicts that more than 210 million people will be watching TV on their mobile by 2011.

    By that date, the technology behind mobile TV should have settled down and handsets that can handle the shows will be widely available.

    Cup challenge

    Mobile phone operators across the world are planning to use the World Cup as a way to get customers more interested in watching TV on their mobile phones, says the report from Informa Telecoms and Media.

    The report predicts that up to $300m in revenue will come from fans downloading and watching clips on mobile phones.  TV is a medium that everyone understands, and so is mobile

    Dave McQueen, Informa


    Dave McQueen, principal analyst at Informa and one of the authors of the report, said 2006 will see mobile TV begin to take off. As well as clips of matches, so-called “mobisodes” of shows such as Desperate Housewives and 24 are being prepared for watching on phones. Pop bands such as the Sugababes are also preparing material just for fans’ handsets.

    But, said Mr McQueen, the technology pumping programmes to phones needs to be stabilised for the technology to support large audiences.

    His comments were echoed by Robin Kelly, spokesman for T-Mobile, which is planning to offer subscribers a package of highlights after World Cup matches.

    “We expect that to be pretty popular,” he said.

    “But it’s not a mass market product yet. I don’t think anyone would say it was.”

    This was because, he said, the clips will be streamed to people across the network and there could cause “bandwidth issues” if too many people subscribed.

    Many operators are planning to use the World Cup to show off mobile TV. For instance in the UK 3 has set up three mobile TV channels that will be free to customers and will show match highlights, the best action of the day and a magazine show created just for phones.

    Better phones

    Data from South Korea, where mobile TV has been on offer since May 2005, showed there was a real appetite for it, said Mr McQueen from Informa.

     
    Pop band Sugababes are creating mobisodes
    Many Koreans were now watching up to 90 minutes of TV on their mobiles every day, said Mr McQueen. By contrast participants in UK trials of mobile TV were watching 180 minutes per week.

    By the Olympics in 2008 and next World Cup in 2010, mobile TV technology will be well established, said Mr McQueen.

    He predicted that 10% of handsets in 2010 will be able to handle broadcast mobile TV signals. Battery life will also have improved to the point where watching for a few hours does not completely drain a phone.

    “TV is a medium that everyone understands, and so is mobile,” said Mr McQueen

    “Combining the two in the imagination of consumers is not as great a challenge as it is for other forms of mobile entertainment.”

    Old PC’s Wanted For Medical Cure

    Researcher David Baker believes the key to an AIDS vaccine or a cure for cancer may be that old PC sitting under a layer of dust in your closet or the one on your desk doing little else but running a screen saver. Those outdated or idle computers may be just what Baker needs to turn his ideas into scientific breakthroughs.

    Baker, 43, a professor of biochemistry at the University of Washington, realized about two years ago that he didn’t have access to the computing horsepower needed for his research – nor the money to buy time on supercomputers elsewhere.

    So he turned to the kindness – and the computers – of strangers.

    Using software made popular in a massive yet so far fruitless search for intelligent life beyond Earth, he and his research team are tapping the computing power of tens of thousands of PCs whose owners are donating spare computer time to chop away at scientific problems over the Internet.

    Baker’s Rosetta@home project is attracting PC users who like the idea of helping find a cure for cancer and admire the way Baker has involved regular people in his research that aims to predict how protein structures unfold at the atomic level.

    “We’re getting these volunteer virtual communities popping up that are doing wonderful things,” Baker said. “People like to get together for good causes.”

    Baker’s work could one day lead to cures to diseases from cancer to Alzheimer’s. The project takes a more direct approach to other diseases, including the search for an HIV vaccine. In that case, his team hopes to develop a way to help the body recognize critical parts of the virus’ proteins so that it can no longer hide from the body’s immune system.

     

    The project sends work to computers that have installed the necessary free software. When the machine is idle, it figures out how an individual protein – a building block of life – might fold or contort, displaying the possibilities in a screen saver. When the PC is done crunching, it sends the results back to Baker’s team and grabs more work.

    More than 60,000 people are donating computer power to Baker’s research – equivalent to the power of one supercomputer. He hopes to increase that number by at least tenfold – enough to lead to major scientific breakthroughs.

    The technology, known as distributed or network computing, isn’t new. In the late 1990s, a project at the University of California, Berkeley started inviting people to donate their computer power to scan distant radio signals for signs of extraterrestrial intelligence. Millions of people have participated in the SETI@home project.

    Two years ago, as Baker was realizing his project’s limitations, the Berkeley group developed new software and opened it to other research that could benefit. The SETI work continues and remains its biggest beneficiary, with donated computer time from nearly 953,000 computers.

    Baker’s project now has participants from around the world, but the earliest donor of idle computer time came from across campus at the university’s Housing and Food Services.

    “I knew the kind of power that personal computers could have if you pulled them all together,” said Ethan Owens, 27, an employee who first offered his department’s 200 computers to the Astronomy Department before taking his offer to Baker.

    Soon, dormitory front desks, computer labs, maintenance offices and kitchen business centers became part of Rosetta@home.

    By the time school started last fall, the two organizations were working together to recruit students to put the networking software on their PCs.

    The project has grown both on and off campus ever since.

    Many of the most active volunteers are cancer survivors or people who have lost close friends or relatives to the disease.

    Philip Williams, 53, who writes computer software for the federal government in Washington, D.C., said he started pulling old Macs out of the closet when he learned more about the Rosetta project. The two-time Hodgkin’s survivor plans to add more computers soon.

    Although he continues to contribute computer time to a few other projects, Williams’ loyalty clearly is with Baker.

    “Baker’s group has a way of making people think that they are part of the project,” said Williams, who has also volunteered to help diagnose problems other participants are having with the software.

     

    Baker said users don’t just think they are important to the project, they really are.

    “As a scientist, one of the things you’re supposed to do is outreach. Outreach has become fundamental to solving the problem,” Baker said, pointing out that his team has received some ideas about new research angles by involving the public. Some were generated on the project’s message boards.

    The volunteers also have recruited more people to help, have made useful suggestions about software issues and have helped test new software versions before they are sent to everyone using Rosetta@home.

    Williams said Baker’s participation in project message boards has made Rosetta much more than a quirky project of the month.

    David P. Anderson, director of the Berkeley Open Infrastructure for Network Computing, said Baker’s lab has done a particularly good job of connecting the participants to the science, including sharing the potential medical impact of the project.

    “Hopefully, Rosetta is setting a standard that the other projects will have to live up to if they want to hold onto their participants,” Anderson said.

    Mark Pottorff, 40, a computer programmer in Rochester, Minn., was contributing computer time for the search for extraterrestrial life when he heard about Rosetta@home and decided to switch.

    “The outcome is much more beneficial,” and more likely to get results than a search for ET, Pottorff said, adding, “If you reach him, he’s still 100 million light years away.”

    18 Flaws In Microsoft Windows And Office

    Microsoft has released seven security updates to address 18 separate flaws in its Windows operating systems and Office software, including 13 problems that earned a “critical” severity rating.

     

    Microsoft labels a security hole as “critical” if it can be used to hijack vulnerable machines without any action on the part of the user. All but two of the flaws addressed in today’s patches can be exploited on some version of either Microsoft Office or Windows to let attackers seize total control over a vulnerable system.

    Three of the patches mend flaws in Microsoft Office, including eight specific to Microsoft Excel. As Security Fix noted in recent posts, software blueprints showing would-be attackers just how to exploit two of these Excel flaws are already available online.

    The most serious of the Excel vulnerabilities affect versions found in Microsoft Office 2000. Unfortunately, patching this older version of Office takes a few more manual steps These users will need to fire up Internet Explorer and mosey on over to Microsoft’s Office site and click on “Check for Updates” in the upper right-hand corner of the page.

    If you are an Office 2000 user and have never installed an Office update before, you are in for a real treat. There are no fewer than three service packs (bundles of patches) worth of updates to install, and you will need to have your Office installation CD handy, as the Office patch installer will prod you to drop it into your CD-Rom drive at some point. Remember, if you’re using Windows 2000, even if you have Windows configured to download and install patches automatically, the Office updates won’t be installed. Whatever you do, don’t put off installing these important fixes: Microsoft has acknowledged that hackers already are exploiting at least some of them to break into computers or steal information from victims.

    Users of Microsoft Office XP or Office 2003 have it much easier — they can quickly download the updates from Microsoft Update, the same place where Windows patches are made available. These vulnerabilities also are present in Microsoft Works Office 2004 for Mac systems, as well as in Office v. X for Mac. Users of those products can download the fixes directly from this link here.

    One critical vulnerability fixed today that appears very serious is a critical flaw in the Windows DHCP service, which handles assigning the computer an Internet address when it first boots up or connects to a network. This vulnerability is present in fully patched versions of Windows 2000, Windows XP and Windows Server 2003.

    Another dangerous security hole resides in the Windows “Mailslot” function, which handles certain communications traffic between Windows machines on the same network. Computer security company Symantec said it considers this flaw the most critical of today’s security bulletins, as it could be used to rapidly compromise multiple systems within a network. This problem exists in all Windows 2000, XP and Server 2003 systems.

    Under its support policy, today was to mark the last time Microsoft would ship security updates for Windows 98, Windows 98 Second Edition (SE), and WIndows Millenium Edition (ME) systems. As it happens, none of today’s updates address those older OSes, unless you count the vulnerabilities in Microsoft Office, which could be (and probably are) running on millions of Windows 98 and ME machines.

    Earlier today, Security Fix posted the results of a series of tests on which security software titles still play nice with Windows 98/ME, so if you’re considering sticking with one of these operating systems for some time, you may want to check it out.

    New iPod in A Monitor From Viewsonic

    Viewsonics as announced a monitor that incorporates an iPod.

     Called the ViewDock will initially come in two widescreen sizes – 19″ and 22″. A dock for your iPod is molded directly into the base, allowing you a host of options. First, you can use the dock just like a standard dock, to synch and charge your iPod. But the real news comes from the connection’s other purpose – a direct connection to use the monitor as the iPod’s display, letting you just plop your iPod in to watch some videos. Details on resolution, response time, contrast, etc. are still unknown, as is price. Along with the iPod dock is an 8-in-one card reader and four USB ports. Handy stuff!

    Click to enlarge

    For many, this iPod addition could be a nice feature – but I see one important issue with it. You’re not going to buy a monitor with a convenient video iPod dock if you don’t own a video iPod. If you own a video iPod, you are already likely using iTunes or some other video player on your PC. Since you aren’t likely going to buy a 22″ wide-screen monitor for your “spare” rig, you should just be able to hit play in iTunes as quickly as you could navigate your iPod’s menu.

    It does have two very useful benefits, despite the above logic. If you have a friend who also uses a video iPod, you can plug it in to watch things at 22″ rather than 2″. Secondly, and more importantly, you don’t have to turn on your whole PC to watch a video or crank some tunes.

    Lie Detector Phone Service Launched

    A device that measures stress levels over the phone is set to wreak havoc with punters who play up and lie to their spouses.

    The Kishkish lie detector is set to be used by Skype on it’d VOIP service. According to Skype,  they can monitor (in real-time) the stress levels of a person who is talking on the phone.

    It could be the perfect tool for suspicious spouses wanting to check whether their loved ones are playing away from home.

    A new telephone lie detector system promises to pick up on tell-tale signs of stress in a caller’s voice whenever they tell a fib.

    Available for free, the Kishkish lie detector can be easily downloaded from the web and used by those who make phone calls over the internet.

    Scientists have found that frequencies in the human voice are sensitive to honesty, becoming higher when a person is lying.

    This is because in moments of stress, such as telling a lie, our muscles tighten as our body prepares to flee or fight causing the pitch of our voice to alter.

    The inventors of the lie detector claim the software mimics police technology by monitoring the stress levels of the person speaking on the phone to judge whether they are telling the truth.

    Already 320,000 people have downloaded the lie detector system. Using the infamous example of Bill Clinton’s denial about his relationship with Monica Lewinsky, the developers show on their website a graph which rises as he utters the lie: ‘I did not have sexual relations with that woman.’

    The software measures stress levels between one and 100, with a green light which shows when stress levels are normal, which then changes to red when they rise to high, allowing the user to gauge whether the other person is lying.

    Many police forces across America use the controversial technology when interviewing crime suspects, and it has also been used by the US military in the ‘war on terror’.

    The lie detector is currently available for those who make calls using Skype technology.

    Skype, which has over 100 million registered users worldwide, is one of the best known of several internet-based phone systems which allow callers to make free calls around the world.

    Using the communication software, calls to other computers are free, while other calls to landlines are charged at around 1p a minute.

    Paul Amery, director of Skype developer program, said: ‘This is a really neat application, and the kind of thing we want to see more of. The Kishkish team has managed perfectly to integrate this unique application to meet the needs of our clients.’

    ‘Lie detector is the latest in a variety of products in our premium add-on program which greatly enhance the Skype communication experience. Extras are all about helping end users do more with Skype, and this will certainly encourage it,’ said Dr Zvi Marom from the programmes makers, BATM.

    ‘We are delighted to be able to introduce this unique software to Skype’s premium offering and will continue to work closely with them to develop new software-based communication applications.’

     

    Drive By Code Infecting Web Sites Say Google

    Tens of housands of web sites in Australia could be infected with what has been described by Google researchers as “drive by” downloads of malicious code, such as spyware, without a user’s knowledge.

    One in 10 web pages scrutinised by search giant Google contained malicious code that could infect a user’s PC. Researchers from the firm surveyed billions of sites, subjecting 4.5 million pages to “in-depth analysis”.

    About 450,000 were capable of launching so-called “drive-by downloads”, sites that install malicious code, such as spyware, without a user’s knowledge. A further 700,000 pages were thought to contain code that could compromise a user’s computer, the team report.

    To address the problem, the researchers say the company has “started an effort to identify all web pages on the internet that could be malicious”.

    Phantom sites

    Drive-by downloads are an increasingly common way to infect a computer or steal sensitive information. They usually consist of malicious programs that automatically install when a potential victim visits a booby-trapped website. “To entice users to install malware, adversaries employ social engineering,” wrote Google researcher Niels Provos and his colleagues in a paper titled The Ghost In The Browser.

    Avoiding attacks 

    “The user is presented with links that promise access to ‘interesting’ pages with explicit pornographic content, copyrighted software or media. A common example are sites that display thumbnails to adult videos.” The vast majority exploit vulnerabilities in Microsoft’s Internet Explorer browser to install themselves.

    Some downloads, such as those that alter bookmarks, install unwanted toolbars or change the start page of a browser, are an annoyance. But increasingly, criminals are using drive-bys to install keyloggers that steal login and password information. Other pieces of malicious code hijack a computer turning it into a “bot”, a remotely controlled PC.

    Drive-by downloads represent a shift away from traditional methods of infecting a computer, such as spam and email attachments.

    Attack plan

    As well as characterising the scale of the problem on the net, the Google study analysed the main methods by which criminals inject malicious code on to innocent web pages.

     
    Spam e-mails are a common way to infect a computer It found that the code was often contained in those parts of the website not designed or controlled by the website owner, such as banner adverts and widgets.

    Widgets are small programs that may, for example, display a calendar on a webpage or a web traffic counter. These are often downloaded from third-party sites. The rise of web 2.0 and user-generated content gave criminals other channels, or vectors, of attack, it found.

    For example, postings in blogs and forums that contain links to images or other content could unwittingly infect a user. The study also found that gangs were able to hijack web servers, effectively taking over and infecting all of the web pages hosted on the computer.

    In a test, the researchers’ computer was infected with 50 different pieces of malware by visiting a web page hosted on a hijacked server.

    The firm is now in the process of mapping the malware threat. Google, part of the StopBadware coalition, already warns users if they are about to visit a potentially harmful website, displaying a message that reads “this site may harm your computer” next to the search results.

    “Marking pages with a label allows users to avoid exposure to such sites and results in fewer users being infected,” the researchers wrote.

    However, the task will not be easy, they say.  “Finding all the web-based infection vectors is a significant challenge and requires almost complete knowledge of the web as a whole,” they wrote.

    New Apple Mac Screen Technology Coming Soon

    Apple is set to launch a new range of notebooks with backlight screens. The LED Blu technology will deliver a significant screen improvement but it could well lift the price of the notebooks.

    With Apple recently confirming plans to launch Macs featuring LED backlight technology in 2007, sources in the industry said the notebooks will use components from AU Optronics (AUO), Chi Mei Optoelectronics (CMO), Coretronic and Kenmos Technology.

    AUO and CMO are both having their samples of 13.3- and 15.4-inch panels certified by Apple, with shipments to officially commence in the second or third quarter of 2007, the sources noted.

    In the meantime, backlight unit (BLU) makers Coretronic and Kenmos are also sending samples to be incorporated in the panels, with official shipments to also kick off around a similar period, the sources added.

    The Taiwan-based makers all declined to comment, citing customer confidentiality.

    Sources recently said AUO and CMO will enter volume production for LED-based LCD modules (LCMs) in the second and third quarter, respectively, of 2007, with CMO being more aggressive in the segment since it will launch more models than AUO.

    Coretronic’s LED BLUs will be applied in the panels from AUO and CMO for use in Apple’s LED-based notebooks, the sources said. The BLU maker started developing LED BLU technologies in 2003 and is likely to see notebook-use BLU shipments form nearly 5% of its LED BLU business in 2007, sources said.

    Component makers indicated Apple plans to use the LED V-cut light-guide panel technology from Japan’s Stanley Electric, which is a technology authorizer and major shareholder (11%) of Taiwan’s Kenmos. Therefore, CMO has decided to adopt Kenmos’ LED BLUs for the panels it will ship to Apple, the sources noted.

    Of all LED backlighting applications, notebook will rise to account for 39.5% of the market in 2010, up from only 4.9% in 2007, according to Displaybank.

     

    Fibre Optic Broadband In Two Weeks Says Telstra

    Telstra has admiited that it can roll out a fibre optic broadband network in two weeks if it gets Government approval.

    The rival Optus-led G9 consortium has lodged a high-speed network proposal with the Australian Competition and Consumer Commission (ACCC) but Telstra says the plan gives the ACCC too much power over access and pricing decisions.Telstra’s managing director of public policy Phil Burgess says while its charges would be higher than G9’s, Telstra has the infrastructure and finances in place for a very fast roll-out.

    “I think if the G9 wins, it’ll be like the dog who caught the car,” he said. “I don’t think they would know what to do. “I don’t think they have any of the engineering plans or financing plans or deployment schedules or even a management plan ready to go.”

     

    “We’ve got all that ready to go and we unveiled that for the press last week,” he said.

    Mr Burgess says the Federal Government should not let the competition watchdog be involved in any new tender process to build a national broadband optical fibre network.He says the ACCC has shown a clear preference for the G9 deal, and the regulator’s position in any decision-making process would see Telstra unfairly disadvantaged.

    “The ACCC has embraced the G9 plan and that’s why I think it would be unbecoming for the ACCC to sit on this expert panel,” he said.