/* format <root> */ static int cmd_format(const char *name, void *cookie, int argc, const char *argv[], PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_WORDS(); if (argc != 1) { LOGE("Command %s requires exactly one argument\n", name); return 1; } const char *root = argv[0]; ui_print("Formatting %s...\n", root); int ret = format_root_device(root); if (ret != 0) { LOGE("Can't format %s\n", root); return 1; } #ifdef BOARD_HAS_DATADATA if (0 == strcmp(root, "DATA:")) { ret = format_root_device("DATADATA:"); if (ret != 0) { LOGE("Can't format %s\n", root); return 1; } } #endif return 0; }
int maybe_install_firmware_update(const char *send_intent) { if (update_data == NULL || update_length == 0) return 0; /* We destroy the cache partition to pass the update image to the * bootloader, so all we can really do afterwards is wipe cache and reboot. * Set up this instruction now, in case we're interrupted while writing. */ struct bootloader_message boot; memset(&boot, 0, sizeof(boot)); strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); strlcpy(boot.recovery, "recovery\n--wipe_cache\n", sizeof(boot.command)); if (send_intent != NULL) { strlcat(boot.recovery, "--send_intent=", sizeof(boot.recovery)); strlcat(boot.recovery, send_intent, sizeof(boot.recovery)); strlcat(boot.recovery, "\n", sizeof(boot.recovery)); } if (set_bootloader_message(&boot)) return -1; int width = 0, height = 0, bpp = 0; char *busy_image = ui_copy_image( BACKGROUND_ICON_FIRMWARE_INSTALLING, &width, &height, &bpp); char *fail_image = ui_copy_image( BACKGROUND_ICON_FIRMWARE_ERROR, &width, &height, &bpp); ui_print("Writing %s image...\n", update_type); if (write_update_for_bootloader( update_data, update_length, width, height, bpp, busy_image, fail_image)) { LOGE("Can't write %s image\n(%s)\n", update_type, strerror(errno)); format_root_device("CACHE:"); // Attempt to clean cache up, at least. return -1; } free(busy_image); free(fail_image); /* The update image is fully written, so now we can instruct the bootloader * to install it. (After doing so, it will come back here, and we will * wipe the cache and reboot into the system.) */ snprintf(boot.command, sizeof(boot.command), "update-%s", update_type); if (set_bootloader_message(&boot)) { format_root_device("CACHE:"); return -1; } reboot(RB_AUTOBOOT); // Can't reboot? WTF? LOGE("Can't reboot\n"); return -1; }
int clear_emmc_entry() { int result = 0; LOGD("before clear emmc ...\n"); result = format_root_device(DATA_PARTITION); sync(); LOGD("after clear DATA %s, %d...\n", DATA_PARTITION, result); result = format_root_device(CACHE_PARTITION); LOGD("after clear CACHE %s, %d...\n", DATA_PARTITION, result); sync(); return result; }
static int erase_root(const char *root) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting %s...\n", root); return format_root_device(root); }
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; }
int clear_emmc_entry(struct ftm_param *param, void *priv) { int result = 0; ui_printf(uistr_info_emmc_format_data_start); result = format_root_device(DATA_PARTITION); sync(); ui_printf(uistr_info_reboot); reboot(RB_AUTOBOOT); return result; }
int nandroid_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); unyaffs_callback callback = NULL; if (0 != stat("/sdcard/ebrecovery/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("Restoring %s...\n", name); /* if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } */ if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } if (0 != (ret = unyaffs(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
int tarbackup_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.tar", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.tar not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); ui_print("Restoring %s...\n", name); if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } sprintf(tmp, "tar -x -f %s/%s.tar", backup_path, name); if (0 != __system(tmp)) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
int clear_emmc_nomedia_entry(char *path) { int result = 0; DIR* d; struct dirent* de; d = opendir(path); if (d == NULL) { LOGE("error opening %s: %s\n", path, strerror(errno)); } int alloc_len = 10; char *files = malloc(alloc_len + 30); while ((de = readdir(d)) != NULL) { int name_len = strlen(de->d_name); if (de->d_type == DT_DIR) { // skip "." and ".." entries if (name_len == 1 && de->d_name[0] == '.') continue; if (name_len == 2 && de->d_name[0] == '.' && de->d_name[1] == '.') continue; if (name_len == 5 && strcmp(de->d_name, "media") == 0) continue; } if (name_len >= alloc_len) { files = realloc(files, (name_len + 30) * sizeof(char)); } strcpy(files, "/system/bin/rm -r /data/"); strcat(files, de->d_name); LOGD("the file is %s\n", de->d_name); if (system(files)) { LOGE("cant rm file %s,error %s\n", de->d_name, strerror(errno)); return -1; } } closedir(d); result = format_root_device(CACHE_PARTITION); LOGD("after clear CACHE %s, %d...\n", CACHE_PARTITION, result); sync(); return 0; }
/* format <root> */ static int cmd_format(const char *name, void *cookie, int argc, const char *argv[]) { UNUSED(name); UNUSED(cookie); CHECK_WORDS(); if (argc != 1) { LOGE("Command %s requires exactly one argument\n", name); return 1; } const char *root = argv[0]; ui_print("Formatting %s..", root); int ret = format_root_device(root); if (ret != 0) { LOGE("Can't format %s\n", root); return 1; } return 0; }
void show_partition_menu() { static char* headers[] = { "Mounts and Storage Menu", "", NULL }; typedef char* string; string mounts[MOUNTABLE_COUNT][3] = { { "mount /system", "unmount /system", "SYSTEM:" }, { "mount /data", "unmount /data", "DATA:" }, { "mount /dbdata", "unmount /dbdata", "DATADATA:" }, { "mount /cache", "unmount /cache", "CACHE:" }, { "mount /sdcard", "unmount /sdcard", "SDCARD:" }, { "mount /sd-ext", "unmount /sd-ext", "SDEXT:" }, { "", "", "" }, }; string mtds[MTD_COUNT][2] = { { "format system", "SYSTEM:" }, { "format data", "DATA:" }, { "format dbdata", "DATADATA:" }, { "format cache", "CACHE:" }, { "", "" }, }; string conv_mtds[MTD_COUNT][3] = { { "convert system", "SYSTEM:", "**" }, { "convert data", "DATA:", "**" }, { "convert dbdata", "DATADATA:", "**" }, { "convert cache", "CACHE:", "**" }, { "", "", "" }, }; string mmcs[MMC_COUNT][3] = { { "format sdcard", "SDCARD:" }, { "format sd-ext", "SDEXT:" }, { "", "" }, }; static char* confirm_format = "Confirm format?"; static char* confirm = "Yes - Format"; for (;;) { int ismounted[MOUNTABLE_COUNT]; int i; static string options[MOUNTABLE_COUNT + MTD_COUNT + MTD_COUNT + MMC_COUNT + 1 + 1]; // mountables, format mtds, convet mtds, format mmcs, usb storage, null for (i = 0; i < MOUNTABLE_COUNT; i++) { ismounted[i] = is_root_path_mounted(mounts[i][2]); options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + i] = mtds[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT + i] = conv_mtds[i][0]; } for (i = 0; i < MMC_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT*2 + i] = mmcs[i][0]; } options[MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT] = "mount USB storage"; options[MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT + 1] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) break; if (chosen_item == MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT) { show_mount_usb_storage_menu(); } else if (chosen_item < MOUNTABLE_COUNT) { if (ismounted[chosen_item]) { if (0 != ensure_root_path_unmounted(mounts[chosen_item][2])) ui_print("Error unmounting %s!\n", mounts[chosen_item][2]); } else { if (0 != ensure_root_path_mounted(mounts[chosen_item][2])) ui_print("Error mounting %s!\n", mounts[chosen_item][2]); } } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mtds[chosen_item][1]); if (0 != format_root_device(mtds[chosen_item][1])) ui_print("Error formatting %s!\n", mtds[chosen_item][1]); else ui_print("Done.\n"); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT*2) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT; if (0 == convert_mtd_device(conv_mtds[chosen_item][1], conv_mtds[chosen_item][2])) { ui_print("Done.\n"); detect_root_fs(); } ui_clear_backgroud(); ui_reset_progress(); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT*2 + MMC_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT*2; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mmcs[chosen_item][1]); if (0 != format_non_mtd_device(mmcs[chosen_item][1])) ui_print("Error formatting %s!\n", mmcs[chosen_item][1]); else ui_print("Done.\n"); } } }
int convert_mtd_device(const char *root, const char* fs_list) { static char* headers[] = { "Converting Menu", "", NULL, NULL }; static char* confirm_convert = "Confirm convert?"; static char* confirm = "Yes - Convert"; const char* root_fs = get_type_internal_fs(root); headers[2] = root; typedef char* string; string tfs[NUM_FILESYSTEMS] = { "rfs", "ext4" }; static string options[NUM_FILESYSTEMS*2 + 1 + 1]; int sel_fs[NUM_FILESYSTEMS*2 + 1 + 1]; int i,j=0; // with backup for (i=0; i<NUM_FILESYSTEMS; i++) { if (fs_list[i] == '*') { if (strcmp(tfs[i], root_fs)) { sel_fs[j] = i; options[j] = (string)malloc(32); sprintf(options[j++], "to %s with backup", tfs[i]); } } else break; } options[j++] = ""; // without backup for (i=0; i<NUM_FILESYSTEMS; i++) { if (fs_list[i] == '*') { if (strcmp(tfs[i], root_fs)) { sel_fs[j] = i; options[j] = (string)malloc(32); sprintf(options[j++], "to %s through format", tfs[i]); } } else break; } options[j] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) return 1; if (chosen_item < i) { // with backup if (!confirm_selection(confirm_convert, confirm)) return 1; ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); // mount $root if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount %s for backup\n", root); return -1; } // check size of $root struct statfs stat_root; if (0 != statfs(get_mount_point_for_root(root), &stat_root)) { ui_print("Can't get size of %s\n", root); return -1; } // mount SDCARD if (0 != ensure_root_path_mounted("SDCARD:")) { ui_print("Can't mount sdcard for backup\n", root); return -1; } // check size SD struct statfs stat_sd; if (0 != statfs(get_mount_point_for_root("SDCARD:"), &stat_sd)) { ui_print("Can't get size of sdcard\n"); return -1; } uint64_t root_fsize = (uint64_t)(stat_root.f_blocks-stat_root.f_bfree)*(uint64_t)stat_root.f_bsize; uint64_t sd_free_size = (uint64_t)stat_sd.f_bfree*(uint64_t)stat_sd.f_bsize; ui_print("SD free: %lluMB / need: %lluMB\n", sd_free_size/(1024*1024), root_fsize/(1024*1024)); if (root_fsize > sd_free_size) { ui_print("Can't backup need: %lluMB on SD\n", root_fsize/(1024*1024)); return -1; } // create folder for backup [/sdcard/ebrecovery/tmp] [mkdir -p /sdcard/ebrecovery/tmp] if (0 != __system("mkdir -p /sdcard/ebrecovery/tmp")) { ui_print("Can't create tmp folder for backup\n"); return -1; } ui_show_progress(0.3, root_fsize*30/(140*1024*1024)); // backup ui_print("Backuping %s...\n", root); char br_exec[256]; sprintf(br_exec, "tar -c --exclude=*RFS_LOG.LO* -f /sdcard/ebrecovery/tmp/ctmp.tar %s", get_mount_point_for_root(root)+1); if (0 != __system(br_exec)) { ui_print("Can't create backup file\n"); return -1; } // check size of backup file > sizeof($root)? // set new FS ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]); if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) { ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root); return -1; } // format $root ui_show_progress(0.05, 10); ui_print("Formatting %s...\n", root); if (0 != format_root_device(root)) { ui_print("Error format %s\n", root); return -1; } // mount $root if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount %s for backup\n", root); return -1; } // restore $root ui_show_progress(0.65, root_fsize*500/(140*1024*1024)); ui_print("Restoring %s...\n", root); if (0 != __system("tar -x -f /sdcard/ebrecovery/tmp/ctmp.tar")) { ui_print("Can't restore backup file\n"); return -1; } // check size of $root ? // delete temp backup files (delete tmp folder) ui_show_indeterminate_progress(); if (0 != __system("rm /sdcard/ebrecovery/tmp/ctmp.tar")) { ui_print("Can't remove backup file\n"); return -1; } return 0; } else { // without if (!confirm_selection(confirm_convert, confirm)) return 1; // change file system to new ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]); if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) { ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root); return -1; } // format ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting %s...\n", root); return format_root_device(root); } return -1; }
int clear_flash_entry(struct ftm_param *param, void *priv) { char *ptr; int chosen; bool exit = false; struct nand_info *flash = (struct nand_info *)priv; struct textview *tv = &flash->tv; struct itemview *iv; struct timeval tv1, tv2; flash->erase_result = false; LOGD(TAG "%s\n", __FUNCTION__); init_text(&flash->title, param->name, COLOR_YELLOW); init_text(&flash->text, &flash->info[0], COLOR_YELLOW); clear_flash_update_info(flash, flash->info); flash->exit_clr_thd = false; #if 0 if (!flash->iv) { iv = ui_new_itemview(); if (!iv) { LOGD(TAG "No memory"); return -1; } flash->iv = iv; } #endif ui_init_textview(tv, flash_key_handler, (void*)flash); #if 0 iv = flash->iv; iv->set_title(iv, &flash->title); iv->set_items(iv, clear_flash_items, 0); iv->set_text(iv, &flash->text); #endif tv->set_title(tv, &flash->title); tv->set_text(tv, &flash->text); pthread_create(&flash->update_thd, NULL, clear_flash_update_thread, priv); #if 0 do { chosen = iv->run(iv, &exit); switch (chosen) { case ITEM_PASS: case ITEM_FAIL: if (chosen == ITEM_PASS) { flash->mod->test_result = FTM_TEST_PASS; } else if (chosen == ITEM_FAIL) { flash->mod->test_result = FTM_TEST_FAIL; } exit = true; break; } if (exit) { flash->exit_clr_thd = true; break; } } while (1); #endif LOGD(TAG "Start the NAND flash erase operations !\n"); gettimeofday(&tv1, NULL); flash->teststart = tv1.tv_sec * 1000000 + tv1.tv_usec; flash->erase_result = format_root_device(DATA_PARTITION); gettimeofday(&tv2, NULL); flash->testend = tv2.tv_sec * 1000000 + tv2.tv_usec; LOGD(TAG "Finish the NAND flash erase operations !\n"); flash->exit_clr_thd = true; pthread_join(flash->update_thd, NULL); sync(); reboot(RB_AUTOBOOT); return 0; }
void show_cot_options_menu() { static char* headers[] = { "COT Options", "", NULL }; #define COT_OPTIONS_ITEM_RECDEBUG 0 #define COT_OPTIONS_ITEM_SETTINGS 1 #define COT_OPTIONS_ITEM_QUICKFIXES 2 #ifdef BOARD_HAS_QUICKFIXES static char* list[4]; list[0] = "Recovery Debugging"; list[1] = "COT Settings"; list[2] = "Quick Fixes"; list[3] = NULL; #else static char* list[3]; list[0] = "Recovery Debugging"; list[1] = "COT Settings"; list[2] = NULL; #endif for (;;) { int chosen_item = get_menu_selection(headers, list, 0, 0); switch (chosen_item) { case GO_BACK: return; case COT_OPTIONS_ITEM_RECDEBUG: show_recovery_debugging_menu(); break; case COT_OPTIONS_ITEM_SETTINGS: show_settings_menu(); break; case COT_OPTIONS_ITEM_QUICKFIXES: { static char* fixes_headers[3]; fixes_headers[0] = "Quick Fixes"; fixes_headers[1] = "\n"; fixes_headers[2] = NULL; #ifdef BOARD_NEEDS_RECOVERY_FIX static char* fixes_list[2]; fixes_list[0] = "Fix Recovery Boot Loop"; fixes_list[1] = NULL; #else static char* fixes_list[1]; fixes_list[0] = NULL; #endif int chosen_fix = get_menu_selection(fixes_headers, fixes_list, 0, 0); switch (chosen_fix) { case GO_BACK: continue; case 0: #ifdef BOARD_NEEDS_RECOVERY_FIX format_root_device("MISC:"); format_root_device("PERSIST:"); reboot(RB_AUTOBOOT); break; #else break; #endif } } } } }
void show_partition_menu() { static char* headers[] = { "Mounts and Storage Menu", "", NULL }; typedef char* string; string mounts[MOUNTABLE_COUNT][3] = { { "mount /system", "unmount /system", "SYSTEM:" }, { "mount /data", "unmount /data", "DATA:" }, { "mount /cache", "unmount /cache", "CACHE:" }, { "mount /sdcard", "unmount /sdcard", "SDCARD:" }, #ifdef BOARD_HAS_SDCARD_INTERNAL { "mount /emmc", "unmount /emmc", "SDINTERNAL:" }, #endif { "mount /sd-ext", "unmount /sd-ext", "SDEXT:" } }; string mtds[MTD_COUNT][2] = { { "format boot", "BOOT:" }, { "format system", "SYSTEM:" }, { "format data", "DATA:" }, { "format cache", "CACHE:" }, }; string mmcs[MMC_COUNT][3] = { { "format sdcard", "SDCARD:" }, #ifdef BOARD_HAS_SDCARD_INTERNAL { "format internal sdcard", "SDINTERNAL:" }, #endif { "format sd-ext", "SDEXT:" } }; static char* confirm_format = "Confirm format?"; static char* confirm = "Yes - Format"; for (;;) { int ismounted[MOUNTABLE_COUNT]; int i; static string options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT + 1 + 1]; // mountables, format mtds, format mmcs, usb storage, null for (i = 0; i < MOUNTABLE_COUNT; i++) { ismounted[i] = is_root_path_mounted(mounts[i][2]); options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + i] = mtds[i][0]; } for (i = 0; i < MMC_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT + i] = mmcs[i][0]; } options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT] = "mount USB storage"; options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT + 1] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) break; if (chosen_item == MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT) { show_mount_usb_storage_menu(); } else if (chosen_item < MOUNTABLE_COUNT) { if (ismounted[chosen_item]) { if (0 != ensure_root_path_unmounted(mounts[chosen_item][2])) ui_print("Error unmounting %s!\n", mounts[chosen_item][2]); } else { if (0 != ensure_root_path_mounted(mounts[chosen_item][2])) ui_print("Error mounting %s!\n", mounts[chosen_item][2]); } } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mtds[chosen_item][1]); if (0 != format_root_device(mtds[chosen_item][1])) ui_print("Error formatting %s!\n", mtds[chosen_item][1]); else ui_print("Done.\n"); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mmcs[chosen_item][1]); if (0 != format_unknown_device(mmcs[chosen_item][1])) ui_print("Error formatting %s!\n", mmcs[chosen_item][1]); else ui_print("Done.\n"); } } }