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; } } Matthew Lentini, Author at Smart Office - Page 6 of 13

    Smart Office

    Nvidia Unleashes Record-Breaking GPU

    Nvidia has broken records with its latest high performance graphics processor, the Tesla M2090, achieving the fastest-ever performance in a scientific computing test.

    The M2090 is equipped with 512 CUDA parallel processing cores and delivers 665 gigaflops of peak double-precision performance. This high computing power is aimed at high-volume data centres, as well as scientific computing.

    Pitted onto a biomolecular simulation program as a veritable speed test, four M2090 GPUs together with four CPUs broke the record for the fastest AMBER (the simulation program) performance to date, reaching 69 nanoseconds of simulation per day, a notable step above the previous 46 ns/day set previously.

    The M2090 is currently heading out in servers like the HP ProLiant SL390 G7 4U which incorporates up to eight of the GPUs alongside two CPUs, offering the highest GPU-to-CPU density on the market.

    Nvidia is also bringing out new consumer graphics cards and drivers to up gaming performance in the wake of 3D gaming.

     

    Nvidia today announced the arrival of the GeForce GTX 560 – the kid brother to the GTX 560 Ti – and the R275 driver to max out current gaming performance. The GeForce GTX 560 GPU starts at US$199.

    The R275 driver, available to download from GeForce.com, acts as a patch to boost performance of current Nvidia GPUs for real gaming improvements.

    Crysis 2 runs at a six percent improvement in performance, while Bulletstorm runs at an extra 15 percent improvement with the updated driver.

    The update also adds greater support for 3D visuals including 3D applications and programmable profiles, improved scaling and improved resizing for HDTVs.

    Western Digital 3TB Hard Drives Too Big For PCs?

    Western Digital has upped the capacity of its media streaming internal hard drives to up to 3 TB, though the bigger sizes may not play nice with PCs.

    The 3.5 inch AV-GP hard drives are aimed at the audio-visual market with a keen eye for storage space-intensive applications.

    The AV-specific hard drives run fast and efficiently during high temperatures from continuous usage like with content streaming.

    High read speeds and the reliability of 24X7 for optimal power consumption makes these drives run smooth while capturing up to 12 HD video streams simultaneously without overworking.

    After 2.19 TB of storage, some operating systems like Windows XP stop supporting hard drives. 32-bit version of Vista and Windows 7 detect these larger drives as ‘secondary drives.’ In any case, it’d be a clever to check out WD’s white paper on the topic to see whether the extra-large drives are compatible with your PC or other AV devices.

    The 2.5 TB version (WD25EURS) comes in at $199, while the 3 TB (WD30EURS) runs at $219.

    Tech Wrap: All-In-One PCs & The Mobile Office

    Toshiba has just released its first ever all-in-one PC, while Apple has recently upgraded its own tried-and-true iMac. These aren’t the only two PC packages on the market, so we’re looking at some of the latest and greatest in the all-in-one market (plus a little scoop on how to create your own mobile office).

    Forget the large tower – an all-in-one puts the innards behind the monitor in one clean package – usually cheaper than you’d get in a typical all-out desktop set up. It’s not the most mobile experience, but multi-touch controls splayed across most touchscreen units gives that tablet feel and more control than the average desktop.

    Apple iMac
    $1399/$1949 | apple.com/au

    The iMac has been a staple of the Apple range for a decade, blending simple beauty with functionality and performance – it’s essentially what an all-in-one is meant to be. The software is simple and typical of any other Mac, and runs smooth.

    The tech giant’s new iMac All In One offering runs with the more powerful Intel Core i “Sandy Bridge” quad-core processors and 10Gbps Thunderbolt I/O data connections.

    THUNDERBOLT & LIGHTNING: Not only is it an eye catcher, but everything on the screen will grab you at high def resolution (which is stretched beyond typical HD on the 27-inch model) with high picture quality and extra-wide viewing angles.

    As before, the iMacs come in two screen sizes: 21.5 and 27 inches. Both now have quad-core i5 processors with an option to step up to Core i7 chips, with speeds up to 3.4GHz.

    The 21.5-inch iMac has a single Thunderbolt port while the 27-inch model has two. The new models also have built-in HD cameras for making video calls using Apple’s FaceTime technology in high definition to other FaceTime equipped macs or standard def to iPod, iPad and iPhone.

    TECH SPECS
    OS: Mac OS X
    CPU: Intel Core i5 or i7/4GB
    RAM: 4GB
    Graphics: Advanced AMD Radeon HD discrete graphics
    Screen: 21.5in, 1920×1080/27 inch 2560 x 1440
    Storage: 500GB/1TB hard drive

     

    Toshiba DX1210
    $1899 | toshiba.com.au

    This high-powered, stylish device is Toshiba’s first all-in-one offering, and it isn’t a shy first appearance. Apart from top hardware, it houses handy features like facial recognition, in-built TV tuner and a USB sleep-and-charge function.

    SMART, ON AND OFF: This clever package works on and off the field, with settings to charge USB devices while switched off and a function that turns the PC into a set of speakers while it sleeps.

    Preloaded CyberLink PowerCinema brings the whole entertainment system together, while HDMI input and six USB ports and Blu-ray player give it the whole connectivity range. Audio is top quality with Onkyo speakers pushed out in Dolby. On top of that is Resolution+ technology that automatically converts standard definition to HD to make the most of the 21.5 inch screen.

    TECH SPECS
    OS: Windows 7
    CPU: Intel Core i7 or i5
    RAM: 6GB DDR3
    Graphics: Intel HD Graphics 3000
    Screen: 21.5in
    Storage: 1TB
    Size: 531x190x405mm, 9kg

     

    Asus Eee Top ET2400IGTS
    $1899 | asus.com.au

    This monster of an all-in-one system tops the range with the latest high-end processor, high-end RAM (and lots of it), multi-touch functionality on the touchscreen and a whole heap of storage to boot. Two USB 3.0 ports plus 4x 2.0 and HDMI input add the most current connectivity on the all-in-one market.

    ULTIMATE IN MULTIMEDIA: Built-in Blu-ray reader on a 3D screen with Asus SonicMaster audio technology, all on a 1920 x 1080 resolution screen, makes this an audio-visual powerhouse to compliment your home cinema.

    Touted as the first all-in-one PC that can be upgraded, you can top up RAM and other internal components via an opening on the back of the monitor – customising your PC is as simple as tinkering with the tower of an ordinary desktop PC.

    TECH SPECS
    OS: Windows 7
    CPU: Intel Core i5-2400S
    RAM: Up to 8GB DDR3
    Graphics: AMD Radeon HD6470
    Screen: 23.6in multi-touch screen, 1920×1080
    Storage: 1TB
    Size: 582x495x~50mm, <13kg

     

    HP TouchSmart 610-1030a
    $2699 | hp.com

    This desktop goes up against the Asus for built-in power, with an Intel Core i7 processor, 8GB of DDR3 RAM and 2TB of storage in the boot. It’s also one hell of an entertainment hub with its stocked Blu-ray player, eight USB ports, audio line-out with a dedicated port for a sub, two separate headphone and two separate microphone jacks.

    FEEL THE BEAT: HP has jumped onto the Beats marketing trail by tying the brand into their latest TouchSmart model. Only available on HP computers, Beats Audio ups the sound quality on laptops and PCs.

    The screen is more malleable than most, reclining back to a 60-degree angle for a comfortable, personal computing experience.

    High-end Beats audio output and a TV tuner in-built means you can enjoy your own movies and some live TV in the highest quality.

    TECH SPECS
    OS: Windows 7
    CPU: Intel Core i7-870
    RAM: 8GB DDR3
    Graphics: ATI Radeon HD 5570
    Screen: 23in
    Storage: 2TB
    Size: 58.5×10.3×45.1cm, 11.2kg

     

    Dell Vostro 330
    $899 | dell.com/au

    Connectivity is right at home with Dell’s 7-in-1 media card reader, six USB ports, 2 megapixel webcam and HD audio speakers. The multi-touch widescreen display sits atop an Intel Core i3 or i5 processor and is designed to be strictly business, not featuring Dell’s multimedia launching utility or any other trial software of the like.

    WORK THE WEBCAM: Security features include facial recognition software, letting you tailor control to your own handsome mug. The deal gets sweater with cyber threats protection.

    A slew of business support utilities come in tow, and a removable rear cover allows the end-user to service their own product unlike most fixed-enclosure all-in-one PCs. Design-wise, it’s similar to the Inspiron One 2305, but the business professional angle sets it apart.

    TECH SPECS
    OS: Windows 7
    CPU: Intel Core i5
    RAM: 4GB DDR3
    Graphics: 1024MB ATI Radeon HD5470, Integrated Intel HD
    Screen: 23in, 1920×1080
    Storage: 500GB
    Size: 420x570x90mm, 8.95kg

     

    Lenovo ThinkCentre M90z
    $1939 | Lenovo.com/au

    Lenovo pushes its business edge with Lenovo Enhanced Experience configuration that speeds boot up and shut down times. An onboard DisplayPort lets users increase their screen space by attaching a second monitor. The PC doubles as standalone monitor that can be used as a second screen for a ThinkPad laptop.

    THINKING SMART: If you fork out an extra $300, you can pick up multi-touch control and an in-built camera on the same model, but it makes this a pretty pricey option.

    A digital array of microphones aid voice clarity alongside noise suppression and echo cancelation, and a HD 2 megapixel webcam make for high quality video conferencing – physical buttons for sound and picture power make controlling these settings extra simple.

    TECH SPECS
    OS: Windows 7
    CPU: 3.2GHz Intel Core i3-550 Processor
    RAM: 2GB DDR3
    Graphics: Integrated Intel
    Screen: 1920×1080
    Storage: 320GB

     

    Operating a home business or working in the corporate world means you’re constantly on the go. You can’t take your all in one with you, but who needs a PC with wireless internet, smartphones and tablets?

    Here are the five essentials for the office on the go:

    WiFi Dongle
    Virgin WiFi Modem
    $ plan | virginmobile.com.au

    A small device that houses a SIM card links up to three WiFi-enabled devices to the internet at once, so you can take the internet with you on your laptop, smartphone, or any other portable device you have with you on the run with a WiFi hotspot. It’s password protected just like your home router, so you’ll be mobile but protected.

    Smartphone
    Motorola Atrix
    $840 | Motorola.com

    This dual-core smartphone boasts PC power in a small phone package. Webtop, a web-based application used with optional docks, mobilises the office desktop in a device that’s smaller than any tablet PC on the market. It doubles as a miniature laptop, in-car navigation and entertainment centre. Custom widgets display as much (or little) info as suits.

    Storage
    Hitachi Portable Drive
    $94.50 | hitachi.com.au

    Designed sleek for portability and fast with USB 3.0 inter-face, the Hitachi Touro Mobil Pro is a 500GB storage device tailored to the mobile user. Better yet, cloud access to all backed up data means you don’t even need the portable hard drive with you to access your data on a notebook, smart-phone, tablet, or any other device with an internet connection.

    Tablet
    Apple iPad 2
    $579 | apple.com/au

    With intuitive controls, a wealth of apps, slim build and a healthy ten hours of battery life, the latest iPad makes for a lightweight, long lasting and functional addition to the mobile office. While not fit for any labour intensive jobs, it’ll tackle presentations, word processing and online interactions with ease – and just a little bit of style.

    Recording
    Livescribe Echo 4GB
    From $259 | Livescribe.com.au

    A computer in a pen? Making sharing, capturing and organisation simple, the Echo smartpen from Livescribe lets you record everything you hear and write. Giving clear recordings that can be replayed on the go, or transferred via a micro USB onto your desktop, it is available in two models, 4GB and 8GB, recording 400 or 800 hours.

    BenQ Monitor For The TV-On-PC Experience

    BenQ has announced a new computer monitor with ultra-high contrast, enhanced colour reproduction and a wider viewing angle for multimedia PCs.The EW2420 is a 16:9 Full HD LED panel, coming in at 24in with a 178/178 degree wide viewing angle for clear picture from more viewing angles than the average monitor.

    The monitor is aimed at media-centric computing like gaming and watching movies, with a range of picture quality perks and connectivity options for most viewing needs.

    “As multimedia entertainment increasingly shifts from the living room centric TV to PCs in different places in the house, consumers are looking for higher quality visual performance and better viewing enjoyment on their monitors,” said General Manager of BenQ Australia, Chee F Chung.

    The monitor is the first to feature BenQ’s ‘Vertical Alignment’ technology that offers improved colour reproduction, an ultra-high contrast ratio and darker ‘true’ blacks. This is coupled with BenQ’s Senseye Human Vision Technology that produces clearer picture quality on monitors.

    The EW2420 comes with DVI-D, two HDMI ports, four USB ports, D-Sub port and headphone and speaker ports for audio.

    The EW2420 currently runs at an RRP of $489.

    Acer Palm-Projector Smaller Than A Mobile

    The Acer C20 LED Pico Projector is a lightweight and compact projector, built into the frame the size of a mobile phone for content sharing on the go.

    While other units have doubled up and put a camera and projector in one, Acer has focused solely on creating a projection hub with the C20.

    The C20 features a Pico projector that displays images at 2000:1 contrast ratio at 16:9 format for widescreen picture at high quality, with an in-built speaker that can be plugged into external amplifiers for improved sound.

    It features USB and HDMI connectivity for linking laptops and phones to the projector and can also access multimedia from microSD cards and flash drives.

    The small unit (weighing in at 166 grams) has a battery life of two hours.

    The Acer C20 Projector is currently retailing at $349 from Acer Computer Australia. The optional 15-inch screen comes in at $49.

    DreamGear Creates Ultimate Portable Powerpoint

    dreamGear launched a portable battery that can fully charge an iPad two times over at CES, all while charging another four USB devices.
    The i.Sound Portable Power Max by dreamGear is a 16,000 mAh battery that can charge up to five USB-powered devices at once. dreamGear boast its ability to charge an iPad two times over or an iPhone 11x with its own single charge. It also sports a built-in flashlight for finding cables in the dark.

    The Power Max is the top unit in i.Sound’s portable battery range and is the ideal solution for road trips where a single cigarette lighter won’t suffice for more than just a single GPS navigator.

    With its LED indicators for battery life, multiple ports and rectangular composition, the Portable Power Max resembles more of a router or portable HDD than anything else, but could be a life-saver on long trips or for anyone constantly draining their phone battery on the move.

    WD Packs 6TB Into Hard Drive For Design Professionals

    Western Digital has come out with a spatial upgrade to its My Book series of external hard drives, now sporting six terabytes (TB) of storage.The My Book Studio Edition II is a dual drive storage system that functions on both Mac and Windows, with a focus on the creative professional who needs a large capacity bank that runs fast across multiple platforms for HD video and photo editing.

    Connectivity ranges up to the high end speed categories, with FireWire 800 and eSATA ports for top performance in data transfer and FireWire 400 and USB 2.0 for average use. The My Book also supports RAID configurations for linking multiple disk drives together.

    The upgrade on previous My Book models offers two extra TB at the same energy consumption with ‘GreenPower’ technology. Users can open the casing of the dual drive and replace drives manually if they need to.

    In-built software automatically backs up data on the storage device to make sure data says secure and lossless.

    The Western Digital My Book Studio Edition II (WDH2Q60000) is now available for $719.

    Samsung Galaxy Tab 10.1v Up For Vodafone Exclusive Preorder

    Vodafone has grabbed the Samsung Galaxy Tab 10.1v for an exclusive preorder sale with its customers starting April 20.

    Customers can order the 10.1 inch tablet that runs on Android’s Honeycomb from Vodafone next Wednesday with actual deliveries commencing from May 1. The official launch will commence on May 4.

    While the pre-sale is a Vodafone exclusive the device itself is not locked to Vodafone’s network, though prepaid consumers will be looking at a minimum of $729 for 6GB of data from Vodafone over three months with the Galaxy Tab.

    The device itself features a 10.1 inch capacitive touch screen with 1280×800 resolution, measuring up to 246 x 170 x 11mm and weighing just under 600 grams.

    The black tablet also features front and rear-facing cameras, with an 8MP camera at the rear and a 2MP cam facing forward.

    Vodafone is also offering 12 month and 24 month plans. For an upfront cost of $259, consumers can grab the Tab from $39 a month for 12 months with 1.5GB of data allowance, ranging up to $83 a month for 18GB.

    Prices are similar on the 24 month plan, but only range up to 14GB per month at $73 dollars, but with no upfront cost.

    Vodafone has similarly grabbed the new Galaxy Tab in Europe, with divisions like Vodafone Netherlands and Hungary putting the product up for preorder earlier this month.

    The exclusive rights in those parts of Europe will only last three months.

    Hanvon Tablets Mix Business With Pleasure At CeBIT 2011

    Hanvon, one of China’s leading e-reader manufacturers, is displaying a range of new tablets and e-book readers that are still running on Windows 7 at CeBIT 2011 in Germany.

    The IT industry trade show that is currently running in Germany is set to come to Australia on May 31 with companies like Hanvon displaying their products with Australian specs, prices and release dates.

    Hanvon’s upcoming range of tablets and e-readers includes high-resolution e-book readers, tablets for design and education professionals, tablets that blend business and pleasure, tabs for the average consumer as well as biometric technology for high-tech enterprise.

    The two e-book readers announced were the Hanvon 200dpi high-resolution WISEreader and the colour WISEreader. Each sports a 9.7 inch E INK screen and feature Wi-Fi and 3G connectivity.

    The readers are controlled with an electromagnetic pen which may seem a little outdated for typical e-readers, though when sitting in an office setting is used mainly for commenting on, modifying and cutting from documents and books – more functionality than the typically mono-functioning e-reader.

     

    On the professional side of tablets, Hanvon is showcasing the Art Master III and the SenTIP.

    The Art Master III is a professional graphics tablet for the design professional or anyone who works with art and graphics. It features 2,048-level pressure sensitivity that employs more subtlety in thickness and intensity of lines for greater precision in painting and drawing.

    Hanvon sees digital drawing as the inevitable future of animation, going so far as to say manual painting will gradually be replaced by digital technology.

    On the education side is the SenTIP pen display which doubles as a graphics tablet and display. The SenTIP pushes tablet screen quality with an LED-backlit LCD screen with the similar graphics tab technology to the Art Master.

    The sensitivity is halved from the Art Master since the detail intricacy isn’t as important on this model, running at 1,024-level pressure sensitivity.

    Educational software including teaching aids is integrated into the unit that is intended to be used with displays like projectors for interactive demonstrations in the corporate and education world.

     

    Tablets to go up against the rest of the general tablet market featuring the likes of the Motorola Xoom and Apple iPad include Hanvon’s Hpad and TouchPad, though running on Windows 7 with limited intuitive functionality compared to Android and iOS.

    The Hpad is a high-end portable running on Android 2.2 that’s built for integration of business and pleasure across the office and leisure worlds.

    The Hpad is 10.8mm thick, has built-in Wi-Fi, Bluetooth and 3G connectivity, sports built-in dual cameras and comes with customised Office handwriting functions. These customised functions can also identify text, business cards, translations and human faces.

    The TouchPad is another tablet from Hanvon that meshes business and consumer interests, with Hanvon marketing the product at businesspeople.

    The tablet PC that was made with Microsoft and Intel cooperation is an 18mm thick unit that weighs in just shy of a kilogram. Under the hood is 2GB DDR2 RAM and a 250GB hard drive, with a screen that runs at 1024×600 resolution.

    The TouchPad runs on Windows 7 and features USB, Audio in/out and mini HDMI connections.

    Hanvon’s also putting its biometric facial recognition systems on show with the F710.

    Lenovo Thinks Business With ThinkStation & ThinkCentre PC

    Lenovo is bringing its Think- line-up onto the desktop and into the office for 2011 with the ThinkStation E30 and ThinkCentre M81.

    The E30 is an upgrade on last year’s E20 and features a selection of 2nd generation Intel Core processors alongside an Intel Xeon processor. 

    It uses a modified version of Intel’s Turbo Boost overclocking technology that allows the PCs to stay in Turbo Boost mode for longer than other desktops for enhanced performance.

    The ThinkStation also comes with a choice of NVIDIA Quadro or NVS graphics cards for visual performance. 

    On the storage side, apart from traditional hard disk storage the E30 also offers either 80 or 160GB SSD storage for high-speed data access.

    Continuing the trend for speed is the SATA III and optional USB 3.0 ports for high-speed connectivity in file transfering and portable media.

    The ThinkCentre M81 also features Intel Core processors, up to 160GB SSD storage and optional SATA III and USB 3.0 ports.

     

    The M81 deviates with a choice of Intel HD graphics or ATI discrete Radeon graphics cards. 

    When adding a discrete graphics card, users can turn the M81 into a four headed beast that can drive four separate monitors.

    Both the E30 and M81 are optimised for quick processing and business functionality with some in-house Lenovo software and bundled tools.

    Similarly to other Think- notebooks and laptop computers, these PCs run Lenovo’s ‘Enhanced Experience’ program for Windows 7 that features a quick boot-up time. 

    The E30 boots up 57 percent faster and shuts down 38 percent faster than previous models, while the M81 starts up 30 faster than its predecessors.

    Other business-centric additives include security options such as port disablement and hardware password managing software for encrypted hard drives.

    The Lenovo ThinkStation E30 workstation and ThinkCentre M81 desktop will both be available this May, with the E30 starting at prices around $1,699 and the M81 starting at around $1,649.