int gen_twrp_md5sum(const char* backup_path) { char md5file[PATH_MAX]; int numFiles = 0; ui_print("\n>> Generating md5 sum...\n"); ensure_path_mounted(backup_path); // this will exclude subfolders! char** files = gather_files(backup_path, "", &numFiles); if (numFiles == 0) { LOGE("No files found in backup path %s\n", backup_path); free_string_array(files); return -1; } int i = 0; for(i = 0; i < numFiles; i++) { ui_quick_reset_and_show_progress(1, 0); ui_print(" - %s\n", BaseName(files[i])); sprintf(md5file, "%s.md5", files[i]); if (write_md5digest(files[i], md5file, 0) < 0) { LOGE("Error while generating md5sum!\n"); ui_reset_progress(); free_string_array(files); return -1; } } ui_print("MD5 sum created.\n"); ui_reset_progress(); free_string_array(files); return 0; }
// called only for multi-volume backups to generate stats for progress bar // file list was gathered from mounted partition: no need to mount before stat line static void compute_twrp_backup_stats(int index) { char tmp[PATH_MAX]; char line[PATH_MAX]; struct stat info; int total = 0; sprintf(tmp, "/tmp/list/filelist%03i", index); FILE *fp = fopen(tmp, "rb"); if (fp != NULL) { while (fgets(line, sizeof(line), fp) != NULL) { line[strlen(line) - 1] = '\0'; stat(line, &info); if (S_ISDIR(info.st_mode)) { compute_directory_stats(line); total += nandroid_files_total; } else total += 1; } nandroid_files_total = total; fclose(fp); } else { LOGE("Cannot compute backup stats for %s\n", tmp); LOGE("No progress will be shown during backup\n"); nandroid_files_total = 0; } nandroid_files_count = 0; ui_reset_progress(); ui_show_progress(1, 0); }
static void prompt_and_wait() { char** headers = prepend_title((const char**)MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); allow_display_toggle = 1; int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); allow_display_toggle = 0; // device-specific code may take some action here. It may // return one of the core actions handled in the switch // statement below. chosen_item = device_perform_action(chosen_item); int status; switch (chosen_item) { case ITEM_REBOOT: poweroff=0; return; case ITEM_WIPE_DATA: wipe_data(ui_text_visible()); if (!ui_text_visible()) return; break; case ITEM_WIPE_CACHE: if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache")) { ui_print("\n-- Wiping cache...\n"); erase_volume("/cache"); ui_print("Cache wipe complete.\n"); if (!ui_text_visible()) return; } break; case ITEM_APPLY_SDCARD: show_install_update_menu(); break; case ITEM_NANDROID: show_nandroid_menu(); break; case ITEM_PARTITION: show_partition_menu(); break; case ITEM_ADVANCED: show_advanced_menu(); break; case ITEM_POWEROFF: poweroff = 1; return; } } }
int nandroid_backup_cache(const char* backup_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); int ret; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); if (0 != (ret = nandroid_backup_partition_extended(backup_path, "CACHE:", 0))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
int install_rom_from_tar (char *filename) { ui_print ("Attempting to install ROM from "); ui_print ("%s", filename); ui_print ("...\n"); char *argv[] = { "/sbin/nandroid-mobile.sh", "--install-rom", filename, "--progress", NULL }; char *envp[] = { NULL }; int status = runve ("/sbin/nandroid-mobile.sh", argv, envp, 1); if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { ui_printf_int ("ERROR: install exited with status %d\n", WEXITSTATUS (status)); return WEXITSTATUS (status); } else { ui_print ("(done)\n"); } ui_reset_progress (); return 0; }
int install_rom_from_tar(char* filename) { if (ui_key_pressed(KEY_SPACE)) { ui_print("Backing up before installing...\n"); nandroid_backup("preinstall",BSD|PROGRESS); } ui_print("Attempting to install ROM from "); ui_print(filename); ui_print("...\n"); char* argv[] = { "/sbin/nandroid-mobile.sh", "--install-rom", filename, "--progress", NULL }; char* envp[] = { NULL }; int status = runve("/sbin/nandroid-mobile.sh",argv,envp,1); if(!WIFEXITED(status) || WEXITSTATUS(status)!=0) { ui_printf_int("ERROR: install exited with status %d\n",WEXITSTATUS(status)); return WEXITSTATUS(status); } else { ui_print("(done)\n"); } ui_reset_progress(); return 0; }
static void compute_directory_stats(const char* directory) { char tmp[PATH_MAX]; char count_text[100]; // reset file count if we ever return before setting it nandroid_files_count = 0; nandroid_files_total = 0; sprintf(tmp, "find %s | %s wc -l > /tmp/dircount", directory, strcmp(directory, "/data") == 0 && is_data_media() ? "grep -v /data/media |" : ""); __system(tmp); FILE* f = fopen("/tmp/dircount", "r"); if (f == NULL) return; if (fgets(count_text, sizeof(count_text), f) == NULL) { fclose(f); return; } size_t len = strlen(count_text); if (count_text[len - 1] == '\n') count_text[len - 1] = '\0'; fclose(f); nandroid_files_total = atoi(count_text); ui_reset_progress(); ui_show_progress(1, 0); }
static void prompt_and_wait() { char** headers = prepend_title((const char**)MENU_HEADERS); int select = 0; for (;;) { ui_reset_progress(); int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, select); // device-specific code may take some action here. It may // return one of the core actions handled in the switch // statement below. chosen_item = device_perform_action(chosen_item); switch (chosen_item) { case ITEM_BOOT: if (show_menu_boot()) return; else break; case ITEM_SYSTEM: if (show_menu_system()) return; else break; case ITEM_RECOVERY: if (show_menu_recovery()) return; else break; case ITEM_TOOLS: if (show_menu_tools()) return; else break; case ITEM_REBOOT: ui_print("Reboot now....\n"); sync(); reboot(RB_AUTOBOOT); return; } select = chosen_item; } }
// runs the program and redirects it's output to the screen using ui_print int graphchoice_main(int argc, char** argv) { if (argc>=2) { ui_init(); ui_print(EXPAND(RECOVERY_VERSION)" - choice app\n"); ui_set_show_text(1); ui_reset_progress(); ui_clear_key_queue(); char** headers; char** list; headers = malloc(sizeof(char*)*3); headers[0] = argv[1]; headers[1] = ""; headers[2] = NULL; list = malloc(sizeof(char*)*(argc+2)); list[0] = NULL; list[1] = NULL; int i=2; while (argv[i]) { list[i-2] = argv[i]; list[i-1] = NULL; i++; } int chosen_item = GO_BACK; while (chosen_item == GO_BACK) { chosen_item = get_menu_selection(headers,list,0,0); } gr_exit(); ev_exit(); return chosen_item; } else { printf("Usage: graphchoice question [option1] [option2] [option3] [...].\n"); return -1; } }
int install_zip(const char* packagefilepath) { ui_print("\n-- Installing: %s\n", packagefilepath); set_sdcard_update_bootloader_message(); // will ensure_path_mounted(packagefilepath) // will also set background icon to installing and indeterminate progress bar int wipe_cache = 0; int status = install_package(packagefilepath, &wipe_cache, TEMPORARY_INSTALL_FILE); ui_reset_progress(); if (status != INSTALL_SUCCESS) { copy_logs(); ui_set_background(BACKGROUND_ICON_ERROR); LOGE("Installation aborted.\n"); return 1; } else if (wipe_cache && erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed.\n"); } #ifdef PHILZ_TOUCH_RECOVERY if (show_background_icon.value) ui_set_background(BACKGROUND_ICON_CLOCKWORK); else #endif ui_set_background(BACKGROUND_ICON_NONE); ui_print("\nInstall from sdcard complete.\n"); return 0; }
int tarbackup_backup(const char* backup_path, int backup_system, int backup_data, int backup_cache, int backup_android_secure) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); int ret=0; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 220) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); if (backup_system && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "SYSTEM:", 1))) return ret; if (backup_data && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "DATA:", 1))) return ret; if (backup_data && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "DATADATA:", 1))) return ret; /* struct stat st; if (0 != stat("/sdcard/.android_secure", &st)) { ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n"); } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; } */ if (backup_cache && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "CACHE:", 0))) return ret; /* ui_print("Generating md5 sum...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("Error while generating md5 sum!\n"); return ret; } */ sync(); ui_set_background(BACKGROUND_ICON_EBCLOCKWORK); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
int apply_from_adb() { stop_adbd(); set_usb_driver(1); ui_print("\n\n电脑端刷机开始 ...\n请在电脑上使用如下命令:\n" "\"adb sideload <刷机包路径>\"从电脑刷机...\n\n"); struct sideload_waiter_data data; if ((data.child = fork()) == 0) { execl("/sbin/recovery", "recovery", "adbd", NULL); _exit(-1); } pthread_t sideload_thread; pthread_create(&sideload_thread, NULL, &adb_sideload_thread, &data); static char* headers[] = { "ADB Sideload", "", NULL }; static char* list[] = { "返回取消", NULL }; get_menu_selection(headers, list, 0, 0); set_usb_driver(0); maybe_restart_adbd(); // kill the child kill(data.child, SIGTERM); pthread_join(sideload_thread, NULL); ui_clear_key_queue(); struct stat st; if (stat(ADB_SIDELOAD_FILENAME, &st) != 0) { if (errno == ENOENT) { ui_print("没有接收到刷机包.\n"); ui_set_background(BACKGROUND_ICON_ERROR); } else { ui_print("读取刷机包失败:\n %s\n", strerror(errno)); ui_set_background(BACKGROUND_ICON_ERROR); } return INSTALL_ERROR; } int install_status = install_package(ADB_SIDELOAD_FILENAME); ui_reset_progress(); if (install_status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); ui_print("电脑端刷机失败.\n"); } remove(ADB_SIDELOAD_FILENAME); return install_status; }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; //ui_print("Checking MD5 sums...\n"); //sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); //if (0 != __system(tmp)) // return print_and_error("MD5 mismatch!\n"); int ret; #ifndef BOARD_RECOVERY_IGNORE_BOOTABLES if (restore_boot) { ui_print("Erasing boot before restore...\n"); if (0 != (ret = format_root_device("BOOT:"))) return print_and_error("Error while formatting BOOT:!\n"); sprintf(tmp, "%s/boot.img", backup_path); ui_print("Restoring boot image...\n"); if (0 != (ret = restore_raw_partition("boot", tmp))) { ui_print("Error while flashing boot image!"); return ret; } } #endif if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "SYSTEM:"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATA:"))) return ret; #ifdef BOARD_HAS_DATADATA if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATADATA:"))) return ret; #endif if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "CACHE:", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "SDEXT:"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
/** * get_menu_selection() * */ int get_menu_selection(char** headers, char** items, int menu_only, int initial_selection) { // throw away keys pressed previously, so user doesn't // accidentally trigger menu items. ui_clear_key_queue(); ui_start_menu(headers, items, initial_selection); int selected = initial_selection; int chosen_item = -1; while (chosen_item < 0) { #ifdef BOARD_WITH_CPCAP int level = battery_level(); if (level > 0) { if ((50 * progress_value) != level / 2) { progress_value = level / 100.0; if (level < 20) ui_print("Low battery ! %3d %%\n", level); ui_reset_progress(); ui_show_progress(progress_value, 1); ui_set_progress(1.0); } } #endif int key = ui_wait_key(); int visible = ui_text_visible(); int action = device_handle_key(key, visible); if (action < 0) { switch (action) { case HIGHLIGHT_UP: --selected; selected = ui_menu_select(selected); break; case HIGHLIGHT_DOWN: ++selected; selected = ui_menu_select(selected); break; case SELECT_ITEM: chosen_item = selected; break; case ACTION_CANCEL: chosen_item = GO_BACK; break; case NO_ACTION: break; } } else if (!menu_only) { chosen_item = action; } } ui_end_menu(); return chosen_item; }
int apply_from_adb() { stop_adbd(); set_usb_driver(1); ui_print("\n\nSideload started ...\nNow send the package you want to apply\n" "to the device with \"adb sideload <filename>\"...\n\n"); struct sideload_waiter_data data; if ((data.child = fork()) == 0) { execl("/sbin/recovery", "recovery", "adbd", NULL); _exit(-1); } pthread_t sideload_thread; pthread_create(&sideload_thread, NULL, &adb_sideload_thread, &data); static const char* headers[] = { "ADB Sideload", "", NULL }; static char* list[] = { "Cancel sideload", NULL }; get_menu_selection(headers, list, 0, 0); set_usb_driver(0); maybe_restart_adbd(); // kill the child kill(data.child, SIGTERM); pthread_join(sideload_thread, NULL); ui_clear_key_queue(); struct stat st; if (stat(ADB_SIDELOAD_FILENAME, &st) != 0) { if (errno == ENOENT) { ui_print("No package received.\n"); ui_set_background(BACKGROUND_ICON_ERROR); } else { ui_print("Error reading package:\n %s\n", strerror(errno)); ui_set_background(BACKGROUND_ICON_ERROR); } return INSTALL_ERROR; } int install_status = install_package(ADB_SIDELOAD_FILENAME); ui_reset_progress(); if (install_status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); ui_print("Installation aborted.\n"); } remove(ADB_SIDELOAD_FILENAME); return install_status; }
static void prompt_and_wait() { char** headers = prepend_title(MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); ui_set_background(BACKGROUND_ICON_ERROR); int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0); // device-specific code may take some action here. It may // return one of the core actions handled in the switch // statement below. chosen_item = device_perform_action(chosen_item); switch (chosen_item) { case ITEM_REBOOT: return; case ITEM_APPLY_SDCARD: show_install_update_menu(); /* ui_print("\n-- Install from sdcard...\n"); set_sdcard_update_bootloader_message(); int status = install_package(SDCARD_PACKAGE_FILE); if (status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); ui_print("Installation aborted.\n"); } else if (!ui_text_visible()) { return; // reboot if logs aren't visible } else { ui_print("\nInstall from sdcard complete.\n"); } */ break; case ITEM_WIPE_DATA: wipe_data(ui_text_visible()); if (!ui_text_visible()) return; break; case ITEM_WIPE_CACHE: ui_print("\n-- Wiping cache...\n"); erase_root("CACHE:"); ui_print("Cache wipe complete.\n"); if (!ui_text_visible()) return; break; case ITEM_ADVANCED: show_advanced_menu(); break; } } }
void device_toggle_truedualboot(void) { char confirm[PATH_MAX]; int enable = dualboot_is_tdb_enabled(); #ifndef PHILZ_TOUCH_RECOVERY ui_setMenuTextColor(MENU_TEXT_COLOR_RED); #endif sprintf(confirm, "Yes - %s TrueDualBoot", enable?"DISABLE":"ENABLE"); if (confirm_selection("This will WIPE DATA. Confirm?", confirm)) { // unmount /data if(ensure_path_unmounted("/data")!=0) { LOGE("Error unmounting /data!\n"); return; } // format /data ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting /data...\n"); set_force_raw_format_enabled(1); if(format_volume("/data")!=0) { ui_print("Error formatting /data!\n"); ui_reset_progress(); return; } ui_reset_progress(); set_force_raw_format_enabled(0); ui_print("Done.\n"); // toggle dualboot_set_tdb_enabled(!enable); } #ifndef PHILZ_TOUCH_RECOVERY ui_setMenuTextColor(MENU_TEXT_COLOR); #endif return; }
// resetting progress bar and background icon once backup/restore done or cancelled by user void finish_nandroid_job() { ui_print("Finalizing, please wait...\n"); sync(); #ifdef PHILZ_TOUCH_RECOVERY vibrate_device(1500); if (show_background_icon.value) ui_set_background(BACKGROUND_ICON_CLOCKWORK); else #endif ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); }
static void compute_directory_stats(const char* directory) { char tmp[PATH_MAX]; sprintf(tmp, "find %s | %s wc -l > /tmp/dircount", directory, strcmp(directory, "/data") == 0 && is_data_media() ? "grep -v /data/media |" : ""); __system(tmp); char count_text[100]; FILE* f = fopen("/tmp/dircount", "r"); fread(count_text, 1, sizeof(count_text), f); fclose(f); nandroid_files_count = 0; nandroid_files_total = atoi(count_text); ui_reset_progress(); ui_show_progress(1, 0); }
int nandroid_backup_sd(const char* backup_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_path_mounted(backup_path) != 0) { return print_and_error("Can't mount backup path.\n"); } Volume* volume = volume_for_path(backup_path); if (NULL == volume) { if (strstr(backup_path, "/sdcard") == backup_path && is_data_media()) volume = volume_for_path("/data"); else return print_and_error("Unable to find volume for backup path.\n"); } int ret; struct statfs s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &s))) return print_and_error("Unable to stat backup path.\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); } char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); Volume *vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("No sd-ext found. Skipping backup of sd-ext.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
static void compute_directory_stats(const char* directory) { char tmp[PATH_MAX]; sprintf(tmp, "find %s | wc -l > /tmp/dircount", directory); __system(tmp); char count_text[100]; FILE* f = fopen("/tmp/dircount", "r"); fread(count_text, 1, sizeof(count_text), f); fclose(f); yaffs_files_count = 0; yaffs_files_total = atoi(count_text); ui_reset_progress(); ui_show_progress(1, 0); }
static void prompt_and_wait() { char** headers = prepend_title((const char**)MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); ui_menu_level = -1; allow_display_toggle = 1; int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); allow_display_toggle = 0; // device-specific code may take some action here. It may // return one of the core actions handled in the switch // statement below. chosen_item = device_perform_action(chosen_item); int status; switch (chosen_item) { case ITEM_REBOOT: show_reboot_menu(); break; case ITEM_WIPE_MENU: show_wipe_menu(); break; case ITEM_INSTALL_ZIP: show_install_update_menu(); break; case ITEM_NANDROID: show_nandroid_menu(); break; case ITEM_PARTITION: show_partition_menu(); break; case ITEM_ADVANCED: show_advanced_menu(); break; case ITEM_POWEROFF: poweroff=1; return; } } }
int check_twrp_md5sum(const char* backup_path) { char md5file[PATH_MAX]; char** files; int numFiles = 0; ui_print("\n>> Checking MD5 sums...\n"); ensure_path_mounted(backup_path); files = gather_files(backup_path, "", &numFiles); if (numFiles == 0) { LOGE("No files found in %s\n", backup_path); free_string_array(files); return -1; } int i = 0; for(i = 0; i < numFiles; i++) { // exclude md5 files char *str = strstr(files[i], ".md5"); if (str != NULL && strcmp(str, ".md5") == 0) continue; ui_quick_reset_and_show_progress(1, 0); ui_print(" - %s\n", BaseName(files[i])); sprintf(md5file, "%s.md5", files[i]); if (verify_md5digest(files[i], md5file) != 0) { LOGE("md5sum error!\n"); ui_reset_progress(); free_string_array(files); return -1; } } ui_print("MD5 sum ok.\n"); ui_reset_progress(); free_string_array(files); return 0; }
void prompt_and_wait() { char** headers = prepend_title((const char**)MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); // device-specific code may take some action here. It may // return one of the core actions handled in the switch // statement below. chosen_item = device_perform_action(chosen_item); switch (chosen_item) { case ITEM_REBOOT: return; case ITEM_WIPE_DATA: wipe_data(ui_text_visible()); if (!ui_text_visible()) return; break; case ITEM_WIPE_CACHE: printf("\n-- Wiping cache...\n"); erase_volume("/cache"); printf("Cache wipe complete.\n"); if (!ui_text_visible()) return; break; case ITEM_APPLY_SDCARD: ; int status = sdcard_directory(SDCARD_ROOT); if (status >= 0) { if (status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); printf("Installation aborted.\n"); } else if (!ui_text_visible()) { return; // reboot if logs aren't visible } else { printf("\nInstall from sdcard complete.\n"); } } break; } } }
static void compute_archive_stats(const char* archive_file) { char tmp[PATH_MAX]; sprintf(tmp, "cat %s* | tar -t | wc -l > /tmp/archivecount", archive_file); LOGE("Computing archive stats for %s\n", basename(archive_file)); __system(tmp); char count_text[100]; FILE* f = fopen("/tmp/archivecount", "r"); fread(count_text, 1, sizeof(count_text), f); fclose(f); nandroid_files_count = 0; nandroid_files_total = atoi(count_text); ui_reset_progress(); ui_show_progress(1, 0); }
int install_zip(const char* packagefilepath) { ui_print("\n-- Installing: %s\n", packagefilepath); if (device_flash_type() == MTD) { set_sdcard_update_bootloader_message(); } int status = install_package(packagefilepath); ui_reset_progress(); if (status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); ui_print("Installation aborted.\n"); return 1; } ui_set_background(BACKGROUND_ICON_NONE); ui_print("\nInstall from sdcard complete.\n"); return 0; }
void wipe_data(int confirm) { if (confirm) { static char** title_headers = NULL; ui_set_background(BACKGROUND_ICON_WIPE_CHOOSE); if (title_headers == NULL) { char* headers[] = { "Confirm wipe of all user data?", " THIS CAN NOT BE UNDONE.", "", NULL }; title_headers = prepend_title((const char**)headers); } char* items[] = { " No", " Yes -- delete all user data", // [1] NULL }; int chosen_item = get_menu_selection(title_headers, items, 1, 0); if (chosen_item != 1) { return; } } ui_set_background(BACKGROUND_ICON_WIPE); ui_print("\n-- Wiping data...\n"); device_wipe_data(); erase_volume("/data"); erase_volume("/cache"); struct stat st; if (stat("/sd-ext",&st) == 0) { ui_print("Formatting /sd-ext...\n"); __system("rm -rf /sd-ext/* && rm -rf /sd-ext/.*"); } else { ui_print("/sd-ext not found, skipping...\n"); } if (0 == stat("/sdcard/.android_secure", &st)) { __system("rm -rf /sdcard/.android_secure/* && rm -rf /sdcard/.android_secure/.*"); ui_print("Formatting /sdcard/.android_secure...\n"); } else { ui_print("/sdcard/.android_secure not found, skipping...\n"); } ui_reset_progress(); ui_print("-- Data wipe complete.\n"); }
int install_zip(const char* packagefilepath) { ui_print("\n-- 正在安装: %s\n", packagefilepath); if (device_flash_type() == MTD) { set_sdcard_update_bootloader_message(); } int status = install_package(packagefilepath); ui_reset_progress(); if (status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); ui_print("安装已取消.\n"); return 1; } ui_set_background(BACKGROUND_ICON_NONE); ui_print("\n从SD卡安装刷机包成功!\n"); return 0; }
int gen_nandroid_md5sum(const char* backup_path) { char md5file[PATH_MAX]; char** files; int ret = -1; int numFiles = 0; ui_print("\n>> Generating md5 sum...\n"); ensure_path_mounted(backup_path); // this will exclude subfolders! set_gather_hidden_files(1); files = gather_files(backup_path, "", &numFiles); set_gather_hidden_files(0); if (numFiles == 0) { LOGE("No files found in backup path %s\n", backup_path); goto out; } // create empty md5file, overwrite existing one if we're regenerating the md5 for the backup sprintf(md5file, "%s/nandroid.md5", backup_path); write_string_to_file(md5file, ""); int i = 0; for (i = 0; i < numFiles; i++) { // exclude md5 and log files if (strcmp(BaseName(files[i]), "nandroid.md5") == 0 || strcmp(BaseName(files[i]), "recovery.log") == 0) continue; ui_quick_reset_and_show_progress(1, 0); ui_print(" > %s\n", BaseName(files[i])); if (write_md5digest(files[i], md5file, 1) < 0) goto out; } ret = 0; out: ui_reset_progress(); free_string_array(files); if (ret != 0) LOGE("Error while generating md5 sum!\n"); return ret; }
static void prompt_and_wait() { ui_print("\n" "Home+Back - reboot system now\n" "Alt+L - toggle log text display\n" "Alt+S - apply sdcard:update.zip\n" "Alt+W - wipe data/factory reset\n"); for (;;) { finish_recovery(NULL); ui_reset_progress(); int key = ui_wait_key(); int alt = ui_key_pressed(KEY_LEFTALT) || ui_key_pressed(KEY_RIGHTALT); if (key == KEY_DREAM_BACK && ui_key_pressed(KEY_DREAM_HOME)) { // Wait for the keys to be released, to avoid triggering // special boot modes (like coming back into recovery!). while (ui_key_pressed(KEY_DREAM_BACK) || ui_key_pressed(KEY_DREAM_HOME)) { usleep(1000); } break; } else if (alt && key == KEY_W) { ui_print("\n"); erase_root("DATA:"); erase_root("CACHE:"); ui_print("Data wipe complete.\n"); if (!ui_text_visible()) break; } else if (alt && key == KEY_S) { ui_print("\nInstalling from sdcard...\n"); int status = install_package(SDCARD_PACKAGE_FILE); if (status != INSTALL_SUCCESS) { ui_set_background(BACKGROUND_ICON_ERROR); ui_print("Installation aborted.\n"); } else if (!ui_text_visible()) { break; // reboot if logs aren't visible } ui_print("\nPress Home+Back to reboot\n"); } } }