void savegame::check_filename(const std::string& filename, CVideo& video) { if (is_gzip_file(filename)) { gui2::show_error_message(video, _("Save names should not end on '.gz'. " "Please choose a different name.")); throw illegal_filename_exception(); } }
void manager::read_save_file(const std::string& name, config& cfg, std::string* error_log) { std::string modified_name = name; replace_space2underbar(modified_name); // Try reading the file both with and without underscores, if needed append .gz as well scoped_istream file_stream = istream_file(get_saves_dir() + "/" + modified_name); if (file_stream->fail()) { file_stream = istream_file(get_saves_dir() + "/" + name); } if(file_stream->fail() && !is_gzip_file(modified_name)) { file_stream = istream_file(get_saves_dir() + "/" + modified_name + ".gz"); if (file_stream->fail()) { file_stream = istream_file(get_saves_dir() + "/" + name + ".gz"); } modified_name += ".gz"; } cfg.clear(); try{ /* * Test the modified name, since it might use a .gz * file even when not requested. */ if(is_gzip_file(modified_name)) { read_gz(cfg, *file_stream); } else { read(cfg, *file_stream); } } catch (config::error &err) { LOG_SAVE << err.message; if (error_log) *error_log += err.message; throw game::load_game_failed(); } if(cfg.empty()) { LOG_SAVE << "Could not parse file data into config\n"; throw game::load_game_failed(); } }
int twrp_restore_wrapper(const char* backup_file_image, const char* backup_path, int callback) { char path[PATH_MAX]; char cmd[PATH_MAX]; char tar_args[10]; int ret; // tar vs tar.gz format? if ((ret = is_gzip_file(backup_file_image)) < 0) return ret; if (ret == 0) sprintf(tar_args, "-xvpf"); else sprintf(tar_args, "-xzvpf"); check_restore_size(backup_file_image, backup_path); if (strlen(backup_file_image) > strlen("win000") && strcmp(backup_file_image + strlen(backup_file_image) - strlen("win000"), "win000") == 0) { // multiple volume archive detected char main_filename[PATH_MAX]; memset(main_filename, 0, sizeof(main_filename)); strncpy(main_filename, backup_file_image, strlen(backup_file_image) - strlen("000")); int index = 0; sprintf(path, "%s%03i", main_filename, index); while (file_found(path)) { ui_print(" * Restoring archive %d\n", index + 1); sprintf(cmd, "cd /; tar %s '%s'; exit $?", tar_args, path); if (0 != (ret = twrp_tar_extract_wrapper(cmd, backup_path, callback))) return ret; index++; sprintf(path, "%s%03i", main_filename, index); } } else { //single volume archive sprintf(cmd, "cd %s; tar %s '%s'; exit $?", backup_path, tar_args, backup_file_image); ui_print("Restoring archive %s\n", BaseName(backup_file_image)); ret = twrp_tar_extract_wrapper(cmd, backup_path, callback); } return ret; }
// check size of archive files to get total backed up data size // find all backup image files of a given partition and increment Backup_Size // Backup_Size is set to 0 at start of nandroid_restore() process so that we do not print size progress on void check_restore_size(const char* backup_file_image, const char* backup_path) { // refresh target partition size if (Get_Size_Via_statfs(backup_path) != 0) { Backup_Size = 0; return; } Before_Used_Size = Used_Size; char tmp[PATH_MAX]; char filename[PATH_MAX]; char** files; int numFiles = 0; sprintf(tmp, "%s/", DirName(backup_file_image)); files = gather_files(tmp, "", &numFiles); // if it's a twrp multi volume backup, ensure we remove trailing 000: strlen("000") = 3 if (strlen(backup_file_image) > strlen("win000") && strcmp(backup_file_image + strlen(backup_file_image) - strlen("win000"), "win000") == 0) snprintf(tmp, strlen(backup_file_image) - 3, "%s", backup_file_image); else strcpy(tmp, backup_file_image); sprintf(filename, "%s", BaseName(tmp)); int i; unsigned long fsize; for(i = 0; i < numFiles; i++) { if (strstr(files[i], filename) != NULL) { fsize = Get_File_Size(files[i]); // check if it is a compressed archive and increase size by 45% // this needs a better implementation to do later if (is_gzip_file(files[i]) > 0) fsize += (fsize * 45) / 100; Backup_Size += fsize; } } free_string_array(files); }
inline bool is_compressed_file(const std::string& filename) { return is_gzip_file(filename) || is_bzip2_file(filename); }