int main(int argc, char **argv) { time_t start = time(NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 2 && strcmp(argv[1], "--adbd") == 0) { adb_main(); return 0; } // Handle alternative invocations char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (strstr(argv[0], "start")) { property_set("ctl.start", argv[1]); return 0; } if (strstr(argv[0], "stop")) { property_set("ctl.stop", argv[1]); return 0; } return busybox_driver(argc, argv); } // devices can run specific tasks on recovery start __system("/sbin/postrecoveryboot.sh"); // Clear umask for packages that copy files out to /tmp and then over // to /system without properly setting all permissions (eg. gapps). umask(0); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); load_volume_table(); setup_data_media(1); vold_client_start(&v_callbacks, 0); vold_set_automount(1); setup_legacy_storage_paths(); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0, wipe_media = 0, show_text = 0, sideload = 0; bool just_exit = false; bool shutdown_after = false; printf("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'm': wipe_media = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': just_exit = true; break; case 'a': sideload = 1; break; case 'p': shutdown_after = true; break; case 'g': { if (stage == NULL || *stage == '\0') { char buffer[20] = "1/"; strncat(buffer, optarg, sizeof(buffer)-3); stage = strdup(buffer); } break; } case '?': LOGE("Invalid command argument\n"); continue; } } printf("stage is [%s]\n", stage); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_MOD_VERSION_BUILD) "\n"); ui_print("ClockworkMod " EXPAND(CWM_BASE_VERSION) "\n"); LOGI("Device target: " EXPAND(TARGET_COMMON_NAME) "\n"); #ifdef PHILZ_TOUCH_RECOVERY print_libtouch_version(0); #endif int st_cur, st_max; if (stage != NULL && sscanf(stage, "%d/%d", &st_cur, &st_max) == 2) { ui_SetStage(st_cur, st_max); } // ui_SetStage(5, 8); // debug if (show_text) ui_ShowText(true); struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed.\n"); } } if (status != INSTALL_SUCCESS) { ui_print("Installation aborted.\n"); // If this is an eng or userdebug build, then automatically // turn the text display on if the script fails so the error // message is visible. char buffer[PROPERTY_VALUE_MAX+1]; property_get("ro.build.fingerprint", buffer, ""); if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) { ui_ShowText(true); } } } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else if (wipe_media) { if (is_data_media() && erase_volume("/data/media")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Media wipe failed.\n"); } else if (sideload) { status = enter_sideload_mode(status); } else if (!just_exit) { // let's check recovery start up scripts (openrecoveryscript and ROM Manager extendedcommands) status = INSTALL_NONE; // No command specified, it is a normal recovery boot unless we find a boot script to run LOGI("Checking for extendedcommand & OpenRecoveryScript...\n"); // we need show_text to show boot scripts log bool text_visible = ui_IsTextVisible(); ui_SetShowText(true); if (0 == check_boot_script_file(EXTENDEDCOMMAND_SCRIPT)) { LOGI("Running extendedcommand...\n"); status = INSTALL_ERROR; if (0 == run_and_remove_extendedcommand()) status = INSTALL_SUCCESS; } if (0 == check_boot_script_file(ORS_BOOT_SCRIPT_FILE)) { LOGI("Running openrecoveryscript....\n"); status = INSTALL_ERROR; if (0 == run_ors_boot_script()) status = INSTALL_SUCCESS; } ui_SetShowText(text_visible); } if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) { copy_logs(); // ui_set_background(BACKGROUND_ICON_ERROR); // will be set in prompt_and_wait() after recovery lock check handle_failure(); } if (status != INSTALL_SUCCESS || ui_IsTextVisible()) { ui_SetShowText(true); #ifdef PHILZ_TOUCH_RECOVERY check_recovery_lock(); #endif prompt_and_wait(status); } // We reach here when in main menu we choose reboot main system or on success install of boot scripts and recovery commands finish_recovery(send_intent); if (shutdown_after) { ui_print("Shutting down...\n"); reboot_main_system(ANDROID_RB_POWEROFF, 0, 0); } else { ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); } return EXIT_SUCCESS; }
static void prompt_and_wait(int status) { const char** headers = prepend_title((const char**)MENU_HEADERS); switch (status) { case INSTALL_SUCCESS: case INSTALL_NONE: #ifndef PHILZ_TOUCH_RECOVERY ui_set_background(BACKGROUND_ICON_CLOCKWORK); #endif break; case INSTALL_ERROR: case INSTALL_CORRUPT: ui_set_background(BACKGROUND_ICON_ERROR); break; } for (;;) { finish_recovery(NULL); ui_root_menu = 1; ui_reset_progress(); int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); ui_root_menu = 0; // device-specific code may take some action here. It may // return one of the core actions handled in the switch // statement below. (this can alter show_text state!!) chosen_item = device_perform_action(chosen_item); int ret = 0; for (;;) { switch (chosen_item) { case ITEM_REBOOT: return; case ITEM_WIPE_DATA: if (ui_IsTextVisible()) wipe_data_menu(); else wipe_data(ui_IsTextVisible()); if (!ui_IsTextVisible()) return; break; case ITEM_WIPE_CACHE: if (ui_IsTextVisible()) { wipe_data_menu(); } else { ui_print("\n-- Wiping cache...\n"); erase_volume("/cache"); ui_print("Cache wipe complete.\n"); } if (!ui_IsTextVisible()) return; break; case ITEM_APPLY_ZIP: ret = show_install_update_menu(); break; case ITEM_NANDROID: ret = show_nandroid_menu(); break; case ITEM_PARTITION: ret = show_partition_mounts_menu(); break; case ITEM_ADVANCED: show_advanced_menu(); break; case ITEM_SETTINGS: show_philz_settings_menu(); break; case ITEM_POWEROFF: show_advanced_power_menu(); break; } if (ret == REFRESH) { // this will restart the for() loop and run switch (chosen_item) action forcing to return to previous menu and refresh it ret = 0; continue; } break; } } }
void wipe_data(int confirm) { if (confirm) { static char** title_headers = NULL; 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", #if TARGET_BOOTLOADER_BOARD_NAME == otter " Yes -- delete all user data", // [1] #else " No", " No", " No", " No", " No", " No", " Yes -- delete all user data", // [7] " No", " No", " No", #endif NULL }; int chosen_item = get_menu_selection(title_headers, items, 1, 0); #if TARGET_BOOTLOADER_BOARD_NAME == otter if (chosen_item != 1) { #else if (chosen_itme != 7) { #endif return; } } ui_print("\n-- Wiping data...\n"); device_wipe_data(); erase_volume("/data"); erase_volume("/cache"); if (has_datadata()) { erase_volume("/datadata"); } #if TARGET_BOOTLOADER_BOARD_NAME != otter // ToDo: make this check for the partition rather then the device erase_volume("/sd-ext"); #endif erase_volume("/sdcard/.android_secure"); ui_print("%s\n", datawipecomplete); } void erase_cache(int orscallback) { if(orscallback) { if(orswipeprompt && !confirm_selection("Confirm wipe?","Yes - Wipe Cache")) { ui_print("Skipping cache wipe...\n"); return; } } else if (!confirm_selection("Confirm wipe?", "Yes - Wipe Cache")) { return; } ui_print("\n-- Wiping cache...\n"); erase_volume("/cache"); ui_print("%s\n", cachewipecomplete); if (!ui_text_visible()) return; } void erase_dalvik_cache(int orscallback) { if(orscallback) { if(orswipeprompt && !confirm_selection("Confirm wipe?", "Yes - Wipe Dalvik Cache")) { ui_print("Skipping dalvik cache wipe...\n"); return; } } else if (!confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) { return; } if (0 != ensure_path_mounted("/data")) { return; } #if TARGET_BOOTLOADER_BOARD_NAME != otter ensure_path_mounted("/sd-ext"); #endif ensure_path_mounted("/cache"); __system("rm -r /data/dalvik-cache"); __system("rm -r /cache/dalvik-cache"); #if TARGET_BOOTLOADER_BOARD_NAME != otter __system("rm -r /sd-ext/dalvik-cache"); #endif ui_print("Dalvik Cache wiped.\n"); ensure_path_unmounted("/data"); } void wipe_all(int orscallback) { if(orscallback) { if(orswipeprompt && !confirm_selection("Confirm wipe all?", "Yes - Wipe All")) { ui_print("Skipping full wipe...\n"); return; } } else if (!confirm_selection("Confirm wipe all?", "Yes - Wipe All")) { return; } ui_print("\n-- Wiping system, data, cache...\n"); erase_volume("/system"); erase_volume("/data"); erase_volume("/cache"); ui_print("\nFull wipe complete!\n"); if (!ui_text_visible()) return; } int format_device(const char *device, const char *path, const char *fs_type) { Volume* v = volume_for_path(path); if (v == NULL) { // no /sdcard? let's assume /data/media if (strstr(path, "/sdcard") == path && is_data_media()) { return format_unknown_device(NULL, path, NULL); } // silent failure for sd-ext if (strcmp(path, "/sd-ext") == 0) return -1; LOGE("unknown volume \"%s\"\n", path); return -1; } if (strcmp(fs_type, "ramdisk") == 0) { // you can't format the ramdisk. LOGE("can't format_volume \"%s\"", path); return -1; } if (strcmp(fs_type, "rfs") == 0) { if (ensure_path_unmounted(path) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (0 != format_rfs_device(device, path)) { LOGE("format_volume: format_rfs_device failed on %s\n", device); return -1; } return 0; } if (strcmp(v->mount_point, path) != 0) { return format_unknown_device(v->device, path, NULL); } if (ensure_path_unmounted(path) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (strcmp(fs_type, "yaffs2") == 0 || strcmp(fs_type, "mtd") == 0) { mtd_scan_partitions(); const MtdPartition* partition = mtd_find_partition_by_name(device); if (partition == NULL) { LOGE("format_volume: no MTD partition \"%s\"\n", device); return -1; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_volume: can't open MTD \"%s\"\n", device); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_volume: can't erase MTD \"%s\"\n", device); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_volume: can't close MTD \"%s\"\n",device); return -1; } return 0; } if (strcmp(fs_type, "ext4") == 0) { int length = 0; if (strcmp(v->fs_type, "ext4") == 0) { // Our desired filesystem matches the one in fstab, respect v->length length = v->length; } reset_ext4fs_info(); int result = make_ext4fs(device, length, v->mount_point, sehandle); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", device); return -1; } return 0; } return format_unknown_device(device, path, fs_type); }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (!strcmp(command, "start")) { property_set("ctl.start", argv[1]); return 0; } if (!strcmp(command, "stop")) { property_set("ctl.stop", argv[1]); return 0; } return busybox_driver(argc, argv); } //__system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s\n", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); ui_print("Builder: "EXPAND(RECOVERY_BUILDER)"\n"); ui_print("Date: "EXPAND(RECOVERY_BUILD_TIME)"\n"); ui_print("weibo:@nx-baby\n"); __system("/sbin/postrecoveryboot.sh"); //#ifdef BOARD_RECOVERY_SWIPE //#ifndef BOARD_TOUCH_RECOVERY //display directions for swipe controls ui_print("Swipe up/down to change selections.\n"); ui_print("Swipe to the right for enter.\n"); ui_print("Swipe to the left for back.\n"); //#endif //#endif load_volume_table(); process_volumes(); vold_init(); setup_legacy_storage_paths(); #ifdef QCOM_HARDWARE parse_t_daemon_data_files(); apply_time_zone(); #endif LOGI("Processing arguments.\n"); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; int headless = 0; int shutdown_after = 0; LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 's': send_intent = optarg; break; case 'u': if (update_package == NULL) update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'h': ui_set_background(BACKGROUND_ICON_CID); ui_show_text(0); headless = 1; break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case 'p': shutdown_after = 1; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); //ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Installation aborted.\n"); } else if (!strcmp(TARGET_DEVICE, "A0001")) { //hack for a0001 ota if (strstr(update_package, "/.OTA/")) send_intent = "0"; } } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; preserve_data_media(0); if (erase_volume("/data")) status = INSTALL_ERROR; preserve_data_media(1); if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Data wipe failed.\n"); } } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Cache wipe failed.\n"); } } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; is_user_initiated_recovery = 1; if (!headless) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_CLOCKWORK); } if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } if (sideload) { signature_check_enabled = 0; if (!headless) ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } if (headless) { headless_wait(); } if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } else if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // We reach here when in main menu we choose reboot main system or for some wipe commands on start // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); if (shutdown_after) { ui_print("Shutting down...\n"); reboot_main_system(ANDROID_RB_POWEROFF, 0, 0); } else { ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); } return EXIT_SUCCESS; }
static void prompt_and_wait() { char** headers = prepend_title((const char**)MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); ui_root_menu = 1; // ui_menu_level is a legacy variable that i am keeping around to prevent build breakage. ui_menu_level = 0; // allow_display_toggle = 1; int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); ui_menu_level = 1; ui_root_menu = 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("你真的要清除数据?", "我就是要删除缓存数据")) { ui_print("\n-- 正在清除 \n"); erase_volume("/cache"); ui_print("已经成功清除\n"); if (!ui_text_visible()) return; } break; case ITEM_APPLY_SDCARD: show_install_update_menu(); break; case ITEM_APPLY_SIDELOAD: apply_from_adb(); break; case ITEM_NANDROID: show_nandroid_menu(); break; case ITEM_PARTITION: show_partition_menu(); break; case ITEM_ADVANCED: show_advanced_menu(); break; case ITEM_GUOHOWFLASH: // 调用exs.c中该函数 show_guohowflash_menu(); break; case ITEM_GUOHOWWHOLEWIPE: // 调用exs.c中该函数 show_guohowwholewipe_menu(); break; case ITEM_GUOHOWHELP: // 调用exs.c中该函数 show_guohowhelp_menu(); break; case ITEM_GUOHOWABOUT: // 调用exs.c中该函数 show_guohowabout_menu(); break; case ITEM_POWEROFF: poweroff = 1; return; } } }
int main(int argc, char **argv) { time_t start = time(NULL); char firmware[50] = {0}; property_get("ro.reversion.aw_sdk_tag", firmware, "unknow"); strcat(reversion,firmware); char storage_type[50] = {0}; property_get("ro.sys.storage_type",storage_type,""); if(!strcmp(storage_type,"emulated")){ internal_storage_type = 1; } // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // If this binary is started with the single argument "--adbd", // instead of being the normal recovery binary, it turns into kind // of a stripped-down version of adbd that only supports the // 'sideload' command. Note this must be a real argument, not // anything in the command file or bootloader control block; the // only way recovery should be run with this argument is when it // starts a copy of itself from the apply_from_adb() function. if (argc == 2 && strcmp(argv[1], "--adbd") == 0) { adb_main(); return 0; } printf("Starting recovery on %s", ctime(&start)); load_volume_table(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0, show_text = 0; bool just_exit = false; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': just_exit = true; break; case 'l': locale = optarg; break; case '?': LOGE("Invalid command argument\n"); continue; } } if (locale == NULL) { load_locale_from_cache(); } printf("locale is [%s]\n", locale); Device* device = make_device(); ui = device->GetUI(); ui->Init(); ui->SetLocale(locale); ui->SetBackground(RecoveryUI::NONE); if (show_text) ui->ShowText(true); #ifdef HAVE_SELINUX struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui->Print("Warning: No file_contexts\n"); } #endif device->StartRecovery(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = (char*)malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n"); } else if (wipe_data) { if (device->WipeData()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; copy_databk_to_data(); if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n"); } else if (!just_exit) { status = INSTALL_NONE; // No command specified // ui->SetBackground(RecoveryUI::NO_COMMAND); // modify by cjcheng } if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) { ui->SetBackground(RecoveryUI::ERROR); } if (status != INSTALL_SUCCESS || ui->IsTextVisible()) { ui->ShowText(false); // modify by cjcheng ui->SetTipTitle(RecoveryUI::TIP_TITLE_READY); // add by cjcheng prompt_and_wait(device, status); /* add by cjcheng start... */ if (install_flag == INSTALL_SUCCESS){ ui->SetTipTitle(RecoveryUI::TIP_TITLE_SUCCESS); status = INSTALL_SUCCESS; } /* add by cjcheng end... */ } /* add by cjcheng start... */ if (status != INSTALL_SUCCESS){ ui->SetBackground(RecoveryUI::ERROR); ui->SetTipTitle(RecoveryUI::TIP_TITLE_ERROR); } /* add by cjcheng end... */ sleep(2); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui->Print("Rebooting...\n"); sync(); android_reboot(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
static 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); int status; int wipe_cache; 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: 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: status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache); if (status == INSTALL_SUCCESS && wipe_cache) { ui_print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui_print("Cache wipe failed.\n"); } else { ui_print("Cache wipe complete.\n"); } } if (status >= 0) { 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_APPLY_CACHE: // Don't unmount cache at the end of this. status = update_directory(CACHE_ROOT, NULL, &wipe_cache); if (status == INSTALL_SUCCESS && wipe_cache) { ui_print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui_print("Cache wipe failed.\n"); } else { ui_print("Cache wipe complete.\n"); } } if (status >= 0) { 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 cache complete.\n"); } } break; } } }
static void prompt_and_wait() { char** headers = prepend_title((const char**)MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); ui_root_menu = 1; // ui_menu_level is a legacy variable that i am keeping around to prevent build breakage. ui_menu_level = 0; // allow_display_toggle = 1; int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); ui_menu_level = 1; ui_root_menu = 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_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; } } }
static void prompt_and_wait() { const char** headers = prepend_title((const char**)MENU_HEADERS); for (;;) { finish_recovery(NULL); ui_reset_progress(); ui_root_menu = 1; // ui_menu_level is a legacy variable that i am keeping around to prevent build breakage. ui_menu_level = 0; // allow_display_toggle = 1; int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0); ui_menu_level = 1; ui_root_menu = 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; int ret = 0; for (;;) { 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: 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_BACKUP_DATA: ui_print("\n-- Not really backing up data...\n"); break; case ITEM_ADVANCED: ret = show_advanced_menu(); break; } if (ret == REFRESH) { ret = 0; continue; } break; } } }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (!strcmp(command, "start")) { property_set("ctl.start", argv[1]); return 0; } if (!strcmp(command, "stop")) { property_set("ctl.stop", argv[1]); return 0; } /* Make sure stdout is not fully buffered, we don't want to * have issues when calling busybox commands */ setlinebuf(stdout); return busybox_driver(argc, argv); } __system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s\n", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); #ifdef BOARD_RECOVERY_SWIPE #ifndef BOARD_TOUCH_RECOVERY //display directions for swipe controls ui_print("Swipe up/down to change selections.\n"); ui_print("Swipe to the right for enter.\n"); ui_print("Swipe to the left for back.\n"); #endif #endif load_volume_table(); process_volumes(); vold_client_start(&v_callbacks, 0); vold_set_automount(1); setup_legacy_storage_paths(); LOGI("Processing arguments.\n"); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; const char *update_ubuntu_package = NULL; const char *user_data_update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; int headless = 0; try_autodeploy(AUTODEPLOY_PACKAGE_FILE); try_autodeploy(AUTODEPLOY_PACKAGE_FILE_MULTI); LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'd': user_data_update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'h': ui_set_background(BACKGROUND_ICON_CID); ui_show_text(0); headless = 1; break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case 'v': update_ubuntu_package = UBUNTU_UPDATE_SCRIPT; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Installation aborted.\n"); } } else if (update_ubuntu_package != NULL) { LOGI("Performing Ubuntu update"); ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Installing Ubuntu update.\n"); char tmp[PATH_MAX]; sprintf(tmp, "%s %s", UBUNTU_UPDATE_SCRIPT, UBUNTU_COMMAND_FILE ); __system(tmp); LOGI("Ubuntu update complete"); ui_print("Ubuntu update complete.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; ignore_data_media_workaround(1); if (erase_volume("/data")) status = INSTALL_ERROR; ignore_data_media_workaround(0); if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Data wipe failed.\n"); } } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Cache wipe failed.\n"); } } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; script_assert_enabled = 0; is_user_initiated_recovery = 1; if (!headless) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_UBUNTU); } if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } if (sideload) { signature_check_enabled = 0; if (!headless) ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } if (headless) { headless_wait(); } if (user_data_update_package != NULL) { status = install_package(user_data_update_package); if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } else if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // We reach here when in main menu we choose reboot main system or for some wipe commands on start // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
void wipe_data(int confirm) { if (confirm) { static char** title_headers = NULL; if (title_headers == NULL) { char* headers[] = { "Confirm wipe of all user data?", " Confirm?", "", NULL }; title_headers = prepend_title((const char**)headers); } char* items[] = { " No", " No", " No", " No", " No", " No", " No", " Yes -- delete all user data", // [7] " No", " No", " No", NULL }; int chosen_item = get_menu_selection(title_headers, items, 1, 0); if (chosen_item != 7) { return; } } ui_print("\n-- Wiping data...\n"); device_wipe_data(); erase_volume("/data"); erase_volume("/cache"); if (has_datadata()) { erase_volume("/datadata"); } erase_volume("/sd-ext"); ensure_path_mounted("/sdcard"); #ifdef BOARD_HAS_REMOVABLE_STORAGE ensure_path_mounted("/external_sd"); if( access( "/sdcard/clockworkmod/.is_as_external", F_OK ) != -1) { erase_volume("/external_sd/.android_secure"); } else { #endif erase_volume("/sdcard/.android_secure"); #ifdef BOARD_HAS_REMOVABLE_STORAGE } #endif ui_print("Data wipe complete.\n"); ensure_path_mounted("/data"); ensure_path_mounted("/sdcard"); ensure_path_mounted("/external_sd"); struct stat st; if (0 == lstat("/sdcard/0", &st)) { char* layout_version = "2"; FILE* f = fopen("/data/.layout_version", "wb"); if (NULL != f) { fwrite(layout_version, 1, 2, f); fclose(f); } else { LOGI("error opening /data/.layout_version for write.\n"); } } else if (0 == lstat("/external_sd/0", &st)) { char* layout_version = "2"; FILE* f = fopen("/data/.layout_version", "wb"); if (NULL != f) { fwrite(layout_version, 1, 2, f); fclose(f); } else { LOGI("error opening /data/.layout_version for write.\n"); } } else { LOGI("/sdcard/0,/external_sd/0 not found. migration may occur in Android 4.2.\n"); } ensure_path_unmounted("/data"); }
void show_wipe_menu() { static char* headers[] = { "Wipes of all shapes and sizes", "", NULL }; for (;;) { int chosen_item = get_menu_selection(headers, WIPE_MENU_ITEMS, 0, 0); switch (chosen_item) { case ITEM_WIPE_CACHE: if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache")) { erase_volume("/cache"); ui_print("Cache Wiped.\n"); } break; case ITEM_WIPE_DALVIK: { if (0 != ensure_path_mounted("/data")) break; ensure_path_mounted("/cache"); if (confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) { __system("rm -r /data/dalvik-cache"); __system("rm -r /cache/dalvik-cache"); __system("rm -r /sd-ext/dalvik-cache"); } ensure_path_unmounted("/data"); ui_print("Dalvik Cache Wiped.\n"); break; } case ITEM_WIPE_DATA_FACTORY: if (confirm_selection("Confirm wipe?", "Yes - delete all user data")) { ui_print("\n-- Wiping data...\n"); device_wipe_data(); erase_volume("/data"); erase_volume("/cache"); erase_volume("/dbdata"); erase_volume("/sdcard/.android_secure"); ui_print("All User Data Wiped.\n"); } break; case ITEM_WIPE_VOLTS: { if (0 != ensure_path_mounted("/system")) break; ensure_path_mounted("/system"); if (confirm_selection( "Confirm wipe?", "Yes - Wipe Voltage Settings")) { __system("rm -r /system/etc/init.d/S_volt_scheduler"); } ensure_path_unmounted("/system"); ui_print("Voltage Settings Wiped.\n"); break; } case ITEM_WIPE_BATT: { if (confirm_selection( "Confirm wipe?", "Yes - Wipe Battery Stats")) wipe_battery_stats(); break; } default: return; } } }
static void prompt_and_wait(Device* device, int status) { const char* const* headers = prepend_title(device->GetMenuHeaders()); int chosen_item = 6; // add by cjcheng for (;;) { finish_recovery(NULL); switch (status) { case INSTALL_SUCCESS: case INSTALL_NONE: ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); // modify by cjcheng break; } ui->SetProgressType(RecoveryUI::EMPTY); // int chosen_item = get_menu_selection(headers, device->GetMenuItems(), 0, 0, device); // modify by cjcheng // 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->InvokeMenuItem(chosen_item); // modify by cjcheng int wipe_cache; switch (chosen_item) { case Device::REBOOT: return; case Device::WIPE_DATA: wipe_data(ui->IsTextVisible(), device); if (!ui->IsTextVisible()) return; break; case Device::WIPE_CACHE: ui->ShowText(false); ui->Print("\n-- Wiping cache...\n"); erase_volume("/cache"); ui->Print("Cache wipe complete.\n"); if (!ui->IsTextVisible()) return; break; case Device::APPLY_CACHE: // Don't unmount cache at the end of this. status = update_directory(CACHE_ROOT, NULL, &wipe_cache, device); if (status == INSTALL_SUCCESS && wipe_cache) { ui->Print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui->Print("Cache wipe failed.\n"); } else { ui->Print("Cache wipe complete.\n"); } } if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (!ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from cache complete.\n"); } } break; case Device::APPLY_ADB_SIDELOAD: ensure_path_mounted(CACHE_ROOT); status = apply_from_adb(ui, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (!ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from ADB complete.\n"); } } break; /* add by cjcheng start... */ case Device::APPLY_SDCARD: // Some packages expect /cache to be mounted (eg, // standard incremental packages expect to use /cache // as scratch space). ensure_path_mounted(CACHE_ROOT); status = smdt_update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache); install_flag = status; if (status == INSTALL_SUCCESS && wipe_cache) { ui->Print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui->Print("Cache wipe failed.\n"); } else { ui->Print("Cache wipe complete.\n"); } } if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from sdcard complete.\n"); chosen_item = 1; } } break; case Device::APPLY_EXT: // Some packages expect /cache to be mounted (eg, // standard incremental packages expect to use /cache // as scratch space). ensure_path_mounted(CACHE_ROOT); status = smdt_update_directory(EXTSD_ROOT, EXTSD_ROOT, &wipe_cache); install_flag = status; if (status == INSTALL_SUCCESS && wipe_cache) { ui->Print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui->Print("Cache wipe failed.\n"); } else { ui->Print("Cache wipe complete.\n"); } } if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from sdcard complete.\n"); chosen_item = 1; } } break; case Device::APPLY_USB1: // Some packages expect /cache to be mounted (eg, // standard incremental packages expect to use /cache // as scratch space). ensure_path_mounted(CACHE_ROOT); status = smdt_update_directory(USB1_ROOT, USB1_ROOT, &wipe_cache); install_flag = status; if (status == INSTALL_SUCCESS && wipe_cache) { ui->Print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui->Print("Cache wipe failed.\n"); } else { ui->Print("Cache wipe complete.\n"); } } if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from sdcard complete.\n"); chosen_item = 1; } } break; case Device::APPLY_USB0: // Some packages expect /cache to be mounted (eg, // standard incremental packages expect to use /cache // as scratch space). ensure_path_mounted(CACHE_ROOT); status = smdt_update_directory(USB0_ROOT, USB0_ROOT, &wipe_cache); install_flag = status; if (status == INSTALL_SUCCESS && wipe_cache) { ui->Print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui->Print("Cache wipe failed.\n"); } else { ui->Print("Cache wipe complete.\n"); } } if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from sdcard complete.\n"); chosen_item = 1; } } break; case Device::APPLY_SATA: // Some packages expect /cache to be mounted (eg, // standard incremental packages expect to use /cache // as scratch space). ensure_path_mounted(CACHE_ROOT); status = smdt_update_directory(SATA_ROOT, SATA_ROOT, &wipe_cache); install_flag = status; if (status == INSTALL_SUCCESS && wipe_cache) { ui->Print("\n-- Wiping cache (at package request)...\n"); if (erase_volume("/cache")) { ui->Print("Cache wipe failed.\n"); } else { ui->Print("Cache wipe complete.\n"); } } if (status >= 0) { if (status != INSTALL_SUCCESS) { // ui->SetBackground(RecoveryUI::ERROR); ui->Print("Installation aborted.\n"); } else if (ui->IsTextVisible()) { return; // reboot if logs aren't visible } else { ui->Print("\nInstall from sdcard complete.\n"); chosen_item = 1; } } break; /* add by cjcheng end... */ } /* add by cjcheng start... */ if (chosen_item < 11 && chosen_item != 1) chosen_item++; else chosen_item = 1; /* add by cjcheng end... */ } }
int GUIAction::doAction(Action action, int isThreaded /* = 0 */) { static string zip_queue[10]; static int zip_queue_index; int simulate; std::string arg = gui_parse_text(action.mArg); std::string function = gui_parse_text(action.mFunction); DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate); if (function == "reboot") { //curtainClose(); this sometimes causes a crash sync(); if (arg == "recovery") tw_reboot(rb_recovery); else if (arg == "poweroff") tw_reboot(rb_poweroff); else if (arg == "bootloader") tw_reboot(rb_bootloader); else if (arg == "download") tw_reboot(rb_download); else tw_reboot(rb_system); // This should never occur return -1; } if (function == "home") { PageManager::SelectPackage("TWRP"); gui_changePage("main"); return 0; } if (function == "key") { PageManager::NotifyKey(getKeyByName(arg)); return 0; } if (function == "page") { std::string page_name = gui_parse_text(arg); return gui_changePage(page_name); } if (function == "reload") { int check = 0, ret_val = 0; std::string theme_path; operation_start("Reload Theme"); theme_path = DataManager::GetSettingsStoragePath(); if (ensure_path_mounted(theme_path.c_str()) < 0) { LOGE("Unable to mount %s during reload function startup.\n", theme_path.c_str()); check = 1; } theme_path += "/TWRP/theme/ui.zip"; if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0) { // Loading the custom theme failed - try loading the stock theme LOGI("Attempting to reload stock theme...\n"); if (PageManager::ReloadPackage("TWRP", "/res/ui.xml")) { LOGE("Failed to load base packages.\n"); ret_val = 1; } } operation_end(ret_val, simulate); } if (function == "readBackup") { set_restore_files(); return 0; } if (function == "set") { if (arg.find('=') != string::npos) { string varName = arg.substr(0, arg.find('=')); string value = arg.substr(arg.find('=') + 1, string::npos); DataManager::GetValue(value, value); DataManager::SetValue(varName, value); } else DataManager::SetValue(arg, "1"); return 0; } if (function == "clear") { DataManager::SetValue(arg, "0"); return 0; } if (function == "mount") { if (arg == "usb") { DataManager::SetValue(TW_ACTION_BUSY, 1); if (!simulate) usb_storage_enable(); else ui_print("Simulating actions...\n"); } else if (!simulate) { string cmd; if (arg == "EXTERNAL") cmd = "mount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT); else if (arg == "INTERNAL") cmd = "mount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT); else cmd = "mount " + arg; __system(cmd.c_str()); if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1) __system("mount /datadata"); } else ui_print("Simulating actions...\n"); return 0; } if (function == "umount" || function == "unmount") { if (arg == "usb") { if (!simulate) usb_storage_disable(); else ui_print("Simulating actions...\n"); DataManager::SetValue(TW_ACTION_BUSY, 0); } else if (!simulate) { string cmd; if (arg == "EXTERNAL") cmd = "umount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT); else if (arg == "INTERNAL") cmd = "umount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT); else if (DataManager::GetIntValue(TW_DONT_UNMOUNT_SYSTEM) == 1 && (arg == "system" || arg == "/system")) return 0; else cmd = "umount " + arg; __system(cmd.c_str()); if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1) __system("umount /datadata"); } else ui_print("Simulating actions...\n"); return 0; } if (function == "restoredefaultsettings") { operation_start("Restore Defaults"); if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting ui_print("Simulating actions...\n"); else { DataManager::ResetDefaults(); mount_current_storage(); } operation_end(0, simulate); } if (function == "copylog") { operation_start("Copy Log"); if (!simulate) { char command[255]; mount_current_storage(); sprintf(command, "cp /tmp/recovery.log %s", DataManager::GetCurrentStoragePath().c_str()); __system(command); sync(); ui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str()); } else simulate_progress_bar(); operation_end(0, simulate); return 0; } if (function == "compute" || function == "addsubtract") { if (arg.find("+") != string::npos) { string varName = arg.substr(0, arg.find('+')); string string_to_add = arg.substr(arg.find('+') + 1, string::npos); int amount_to_add = atoi(string_to_add.c_str()); int value; DataManager::GetValue(varName, value); DataManager::SetValue(varName, value + amount_to_add); return 0; } if (arg.find("-") != string::npos) { string varName = arg.substr(0, arg.find('-')); string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos); int amount_to_subtract = atoi(string_to_subtract.c_str()); int value; DataManager::GetValue(varName, value); value -= amount_to_subtract; if (value <= 0) value = 0; DataManager::SetValue(varName, value); return 0; } } if (function == "setguitimezone") { string SelectedZone; DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone string Zone = SelectedZone.substr(0, SelectedZone.find(';')); // parse to get time zone string DSTZone = SelectedZone.substr(SelectedZone.find(';') + 1, string::npos); // parse to get DST component int dst; DataManager::GetValue(TW_TIME_ZONE_GUIDST, dst); // check wether user chose to use DST string offset; DataManager::GetValue(TW_TIME_ZONE_GUIOFFSET, offset); // pull in offset string NewTimeZone = Zone; if (offset != "0") NewTimeZone += ":" + offset; if (dst != 0) NewTimeZone += DSTZone; DataManager::SetValue(TW_TIME_ZONE_VAR, NewTimeZone); update_tz_environment_variables(); return 0; } if (function == "togglestorage") { if (arg == "internal") { DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0); DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU)); } else if (arg == "external") { DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1); DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU)); } if (mount_current_storage() == 0) { if (arg == "internal") { // Save the current zip location to the external variable DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR)); // Change the current zip location to the internal variable DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_INTERNAL_VAR)); } else if (arg == "external") { // Save the current zip location to the internal variable DataManager::SetValue(TW_ZIP_INTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR)); // Change the current zip location to the external variable DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_EXTERNAL_VAR)); } } else { // We weren't able to toggle for some reason, restore original setting if (arg == "internal") { DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1); DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU)); } else if (arg == "external") { DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0); DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU)); } } return 0; } if (function == "overlay") return gui_changeOverlay(arg); if (function == "queuezip") { if (zip_queue_index >= 10) { ui_print("Maximum zip queue reached!\n"); return 0; } DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]); if (strlen(zip_queue[zip_queue_index].c_str()) > 0) { zip_queue_index++; DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); } return 0; } if (function == "cancelzip") { if (zip_queue_index <= 0) { ui_print("Minimum zip queue reached!\n"); return 0; } else { zip_queue_index--; DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); } return 0; } if (function == "queueclear") { zip_queue_index = 0; DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); return 0; } if (function == "sleep") { usleep(atoi(arg.c_str())); return 0; } if (isThreaded) { if (function == "flash") { int i, ret_val = 0; for (i=0; i<zip_queue_index; i++) { operation_start("Flashing"); DataManager::SetValue("tw_filename", zip_queue[i]); DataManager::SetValue(TW_ZIP_INDEX, (i + 1)); ret_val = flash_zip(zip_queue[i], arg, simulate); if (ret_val != 0) { ui_print("Error flashing zip '%s'\n", zip_queue[i].c_str()); i = 10; // Error flashing zip - exit queue ret_val = 1; } } zip_queue_index = 0; DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) { operation_start("ReinjectTWRP"); ui_print("Injecting TWRP into boot image...\n"); if (simulate) { simulate_progress_bar(); } else { __system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash"); ui_print("TWRP injection complete.\n"); } } operation_end(ret_val, simulate); return 0; } if (function == "wipe") { operation_start("Format"); DataManager::SetValue("tw_partition", arg); if (simulate) { simulate_progress_bar(); } else { if (arg == "data") wipe_data(0); else if (arg == "battery") wipe_battery_stats(); else if (arg == "rotate") wipe_rotate_data(); else if (arg == "dalvik") wipe_dalvik_cache(); else erase_volume(arg.c_str()); if (arg == "/sdcard") { ensure_path_mounted(SDCARD_ROOT); mkdir("/sdcard/TWRP", 0777); DataManager::Flush(); } } update_system_details(); operation_end(0, simulate); return 0; } if (function == "refreshsizes") { operation_start("Refreshing Sizes"); if (simulate) { simulate_progress_bar(); } else update_system_details(); operation_end(0, simulate); } if (function == "nandroid") { operation_start("Nandroid"); if (simulate) { DataManager::SetValue("tw_partition", "Simulation"); simulate_progress_bar(); } else { if (arg == "backup") nandroid_back_exe(); else if (arg == "restore") nandroid_rest_exe(); else { operation_end(1, simulate); return -1; } } operation_end(0, simulate); return 0; } if (function == "fixpermissions") { operation_start("Fix Permissions"); LOGI("fix permissions started!\n"); if (simulate) { simulate_progress_bar(); } else fix_perms(); LOGI("fix permissions DONE!\n"); operation_end(0, simulate); return 0; } if (function == "dd") { operation_start("imaging"); if (simulate) { simulate_progress_bar(); } else { char cmd[512]; sprintf(cmd, "dd %s", arg.c_str()); __system(cmd); } operation_end(0, simulate); return 0; } if (function == "partitionsd") { operation_start("Partition SD Card"); if (simulate) { simulate_progress_bar(); } else { int allow_partition; DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition); if (allow_partition == 0) { ui_print("This device does not have a real SD Card!\nAborting!\n"); } else { // Below seen in Koush's recovery char sddevice[256]; Volume *vol = volume_for_path("/sdcard"); strcpy(sddevice, vol->device); // Just need block not whole partition sddevice[strlen("/dev/block/mmcblkX")] = NULL; char es[64]; std::string ext_format; int ext, swap; DataManager::GetValue("tw_sdext_size", ext); DataManager::GetValue("tw_swap_size", swap); DataManager::GetValue("tw_sdpart_file_system", ext_format); sprintf(es, "/sbin/sdparted -es %dM -ss %dM -efs %s -s > /cache/part.log",ext,swap,ext_format.c_str()); LOGI("\nrunning script: %s\n", es); run_script("\nContinue partitioning?", "\nPartitioning sdcard : ", es, "\nunable to execute parted!\n(%s)\n", "\nOops... something went wrong!\nPlease check the recovery log!\n", "\nPartitioning complete!\n\n", "\nPartitioning aborted!\n\n", 0); // recreate TWRP folder and rewrite settings - these will be gone after sdcard is partitioned ensure_path_mounted(SDCARD_ROOT); mkdir("/sdcard/TWRP", 0777); DataManager::Flush(); DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, "/sdcard"); if (DataManager::GetIntValue(TW_USE_EXTERNAL_STORAGE) == 1) DataManager::SetValue(TW_ZIP_LOCATION_VAR, "/sdcard"); update_system_details(); } } operation_end(0, simulate); return 0; } if (function == "installhtcdumlock") { operation_start("Install HTC Dumlock"); if (simulate) { simulate_progress_bar(); } else install_htc_dumlock(); operation_end(0, simulate); return 0; } if (function == "htcdumlockrestoreboot") { operation_start("HTC Dumlock Restore Boot"); if (simulate) { simulate_progress_bar(); } else htc_dumlock_restore_original_boot(); operation_end(0, simulate); return 0; } if (function == "htcdumlockreflashrecovery") { operation_start("HTC Dumlock Reflash Recovery"); if (simulate) { simulate_progress_bar(); } else htc_dumlock_reflash_recovery_to_boot(); operation_end(0, simulate); return 0; } if (function == "cmd") { int op_status = 0; operation_start("Command"); ui_print("Running command: '%s'\n", arg.c_str()); if (simulate) { simulate_progress_bar(); } else { op_status = __system(arg.c_str()); if (op_status != 0) op_status = 1; } operation_end(op_status, simulate); return 0; } if (function == "reinjecttwrp") { int op_status = 0; operation_start("ReinjectTWRP"); ui_print("Injecting TWRP into boot image...\n"); if (simulate) { simulate_progress_bar(); } else { __system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash"); ui_print("TWRP injection complete.\n"); } operation_end(op_status, simulate); return 0; } } else { pthread_t t; pthread_create(&t, NULL, thread_start, this); return 0; } return -1; }
int main(int argc, char **argv) { time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_set_background(BACKGROUND_ICON_INSTALLING); load_volume_table(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case '?': LOGE("Invalid command argument\n"); continue; } } device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else { status = INSTALL_ERROR; // No command specified } if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR); if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); android_reboot(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
int main(int argc, char **argv) { // while(1); time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); // printf("Starting recovery on %s", ctime(&start)); // printf("............just for aibing debug \n\r"); // while(1); ui_init(); // ui_set_background(BACKGROUND_ICON_INSTALLING); load_volume_table(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; const char *encrypted_fs_mode = NULL; int wipe_data = 0, wipe_cache = 0; int toggle_secure_fs = 0; encrypted_fs_info encrypted_fs_data; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 'e': encrypted_fs_mode = optarg; toggle_secure_fs = 1; break; case 't': ui_show_text(1); break; case '?': LOGE("Invalid command argument\n"); continue; } } //reinit wipe_data and wipe_cache as it will do in clean boot; wipe_data = wipe_cache = 0; device_recovery_start(); printf("Aibing test Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { printf("in update_package run?????\n"); // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("list start\n"); property_list(print_property, NULL); printf("list end\n"); int status = INSTALL_SUCCESS; int mcu_status = INSTALL_SUCCESS; int mpeg_status = INSTALL_SUCCESS; int overridekey_status = INSTALL_SUCCESS; int tractor_prop_status = INSTALL_SUCCESS; int radio_status = INSTALL_SUCCESS; if (toggle_secure_fs) { if (strcmp(encrypted_fs_mode,"on") == 0) { encrypted_fs_data.mode = MODE_ENCRYPTED_FS_ENABLED; printf("Enabling Encrypted FS.\n"); } else if (strcmp(encrypted_fs_mode,"off") == 0) { encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED; printf("Disabling Encrypted FS.\n"); } else { printf("Error: invalid Encrypted FS setting.\n"); status = INSTALL_ERROR; } // Recovery strategy: if the data partition is damaged, disable encrypted file systems. // This preventsthe device recycling endlessly in recovery mode. if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) && (read_encrypted_fs_info(&encrypted_fs_data))) { printf("Encrypted FS change aborted, resetting to disabled state.\n"); encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED; } if (status != INSTALL_ERROR) { if (erase_volume("/data")) { printf("Data wipe failed.\n"); status = INSTALL_ERROR; } else if (erase_volume("/cache")) { printf("Cache wipe failed.\n"); status = INSTALL_ERROR; } else if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) && (restore_encrypted_fs_info(&encrypted_fs_data))) { printf("Encrypted FS change aborted.\n"); status = INSTALL_ERROR; } else { printf("Successfully updated Encrypted FS.\n"); status = INSTALL_SUCCESS; } } } else if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) printf("Installation aborted.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) printf("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) printf("Cache wipe failed.\n"); } else { status = INSTALL_ERROR; // No command specified } printf("Recovery svn version:%d, Compile Time: %s %s\n", SVN_VERSION,__DATE__, __TIME__); sprintf(version_buf, "Recovery svn version:%d, Compile Time: %s %s", SVN_VERSION,__TIME__, __DATE__); int fd = 0; fd = open("/dev/recovery",O_RDWR | O_CREAT | O_TRUNC); if(fd < 0) { printf("open recovery devices error\n"); return EXIT_SUCCESS; } int recovery_mode = 0; ioctl(fd, RECOVERY_GET_VAL, &recovery_mode); // recovery_mode = UPDATE_SYSTEM; /* test_functions() */ //remove_logo_config_file(); if(recovery_mode == CLEAN_MODE) { ui_set_cleanboot_background(); ui_set_cleanboot_system(); clean_boot(); while(system_cleanboot_end == 0) { //printf("waiting thread is end"); usleep(50000); } sync(); ui_set_cleanboot_succ(); sleep(3); close_backlight(); reboot(RB_AUTOBOOT); printf("reboot end, it should never been output\n"); } else if (recovery_mode == UPDATE_RECOVERY){ ui_set_prepare_background(); sleep(1); burning_recovery_image(); } else if (recovery_mode == UPDATE_SYSTEM || recovery_mode == BACKUP_MODE){ ui_set_burning_background(BURNING_MISC_UPDATING); sleep(1); overridekey_status = update_overridekey(); tractor_prop_status = update_tractorprop(); radio_status = update_radioCFG(); mpeg_status = mpeg_update(); update_status &= ~(0x03 << 2); update_status |= mpeg_status << 2; ui_set_burning_reflesh(update_status); sleep(1); printf("mcu_start\n"); mcu_status = mcu_update(); update_status &= ~(0x03 << 4); update_status |= (mcu_status << 4); ui_set_burning_reflesh(update_status); sleep(1); if(status == INSTALL_ERROR){ printf("++check auto Burning update.zip in data tractor...\n"); status = device_burn_data_if_exist(); if(status == INSTALL_SUCCESS) { //burning_recovery_image(); } ui_set_burning_status(); printf("--check auto Burning update.zip in data tractor: %d\n", status); update_status &= ~(0x03); update_status |= status; } ui_set_burning_reflesh(update_status); sleep(3); /* if ( (mcu_status == INSTALL_SUCCESS) || (status == INSTALL_SUCCESS) || (mpeg_status == INSTALL_SUCCESS)|| (overridekey_status == INSTALL_SUCCESS)) { if (set_skip() == INSTALL_ERROR) { ui_set_burning_background(BURNING_RESULT_FAILURE); sleep(3); mcu_reset_cpu(); return EXIT_FAILURE; } } */ printf("end \n"); if ( (status != INSTALL_SUCCESS) && (mcu_status != INSTALL_SUCCESS) && (mpeg_status != INSTALL_SUCCESS) && (overridekey_status != INSTALL_SUCCESS)&& (radio_status != INSTALL_SUCCESS)) { ui_set_burning_background(BURNING_RESULT_FAILURE); sleep(3); mcu_reset_cpu(); return EXIT_FAILURE; } sync(); ui_set_burning_background(BURNING_RESULT_SUCCESS); sleep(3); //while mcu is burning, the mcu need to restart and reset the main cpu. if (mcu_status == INSTALL_SUCCESS) { mcu_reset_cpu(); } else { close_backlight(); reboot(RB_AUTOBOOT); } }while(0); return EXIT_SUCCESS; }
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); 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: if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip")) { ui_print("\n-- Install 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()) { return; // reboot if logs aren't visible } else { ui_print("\nInstall from sdcard complete.\n"); } } 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 main(int argc, char **argv) { if (strcmp(basename(argv[0]), "recovery") != 0) { if (strstr(argv[0], "flash_image") != NULL) return flash_image_main(argc, argv); if (strstr(argv[0], "dump_image") != NULL) return dump_image_main(argc, argv); if (strstr(argv[0], "erase_image") != NULL) return erase_image_main(argc, argv); if (strstr(argv[0], "mkyaffs2image") != NULL) return mkyaffs2image_main(argc, argv); if (strstr(argv[0], "unyaffs") != NULL) return unyaffs_main(argc, argv); if (strstr(argv[0], "nandroid")) return nandroid_main(argc, argv); if (strstr(argv[0], "reboot")) return reboot_main(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount")) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (strstr(argv[0], "poweroff")){ return reboot_main(argc, argv); } } __system("/sbin/postrecoveryboot.sh"); time_t start = time(NULL); // If these fail, there's not really anywhere to complain... #ifndef DEBUG unlink(TEMPORARY_LOG_FILE); #endif freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); //miuiIntent init miuiIntent_init(10); miuiIntent_register(INTENT_MOUNT, &intent_mount); miuiIntent_register(INTENT_ISMOUNT, &intent_ismount); miuiIntent_register(INTENT_UNMOUNT, &intent_unmount); miuiIntent_register(INTENT_REBOOT, &intent_reboot); miuiIntent_register(INTENT_INSTALL, &intent_install); miuiIntent_register(INTENT_WIPE, &intent_wipe); miuiIntent_register(INTENT_TOGGLE, &intent_toggle); miuiIntent_register(INTENT_FORMAT, &intent_format); miuiIntent_register(INTENT_RESTORE, &intent_restore); miuiIntent_register(INTENT_BACKUP, &intent_backup); miuiIntent_register(INTENT_ADVANCED_BACKUP, &intent_advanced_backup); miuiIntent_register(INTENT_SYSTEM, &intent_system); miuiIntent_register(INTENT_COPY, &intent_copy); device_ui_init(); load_volume_table(); get_args(&argc, &argv); struct bootloader_message boot; memset(&boot, 0, sizeof(boot)); set_bootloader_message(&boot); create_fstab(); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; //case 't': ui_show_text(1); break; case '?': LOGE("Invalid command argument\n"); continue; } } device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { if (wipe_cache) erase_volume("/cache"); miuiIntent_send(INTENT_INSTALL, 3, update_package,"0", "0"); //if echo 0 ,don't print success dialog status = miuiIntent_result_get_int(); if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else { status = INSTALL_ERROR; // No command specified } if (status != INSTALL_SUCCESS) device_main_ui_show();//show menu device_main_ui_release(); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); android_reboot(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (strcmp(basename(argv[0]), "recovery") != 0) { if (strstr(argv[0], "flash_image") != NULL) return flash_image_main(argc, argv); if (strstr(argv[0], "volume") != NULL) return volume_main(argc, argv); if (strstr(argv[0], "edify") != NULL) return edify_main(argc, argv); if (strstr(argv[0], "dump_image") != NULL) return dump_image_main(argc, argv); if (strstr(argv[0], "erase_image") != NULL) return erase_image_main(argc, argv); if (strstr(argv[0], "mkyaffs2image") != NULL) return mkyaffs2image_main(argc, argv); if (strstr(argv[0], "unyaffs") != NULL) return unyaffs_main(argc, argv); if (strstr(argv[0], "nandroid")) return nandroid_main(argc, argv); if (strstr(argv[0], "reboot")) return reboot_main(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount")) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (strstr(argv[0], "poweroff")){ return reboot_main(argc, argv); } if (strstr(argv[0], "setprop")) return setprop_main(argc, argv); return busybox_driver(argc, argv); } __system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); load_volume_table(); process_volumes(); LOGI("Processing arguments.\n"); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; const char *encrypted_fs_mode = NULL; int wipe_data = 0, wipe_cache = 0; int toggle_secure_fs = 0; encrypted_fs_info encrypted_fs_data; LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'c': wipe_cache = 1; break; case 'e': encrypted_fs_mode = optarg; toggle_secure_fs = 1; break; case 't': ui_show_text(1); break; case '?': LOGE("Invalid command argument\n"); continue; } } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (toggle_secure_fs) { if (strcmp(encrypted_fs_mode,"on") == 0) { encrypted_fs_data.mode = MODE_ENCRYPTED_FS_ENABLED; ui_print("Enabling Encrypted FS.\n"); } else if (strcmp(encrypted_fs_mode,"off") == 0) { encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED; ui_print("Disabling Encrypted FS.\n"); } else { ui_print("Error: invalid Encrypted FS setting.\n"); status = INSTALL_ERROR; } // Recovery strategy: if the data partition is damaged, disable encrypted file systems. // This preventsthe device recycling endlessly in recovery mode. if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) && (read_encrypted_fs_info(&encrypted_fs_data))) { ui_print("Encrypted FS change aborted, resetting to disabled state.\n"); encrypted_fs_data.mode = MODE_ENCRYPTED_FS_DISABLED; } if (status != INSTALL_ERROR) { if (erase_volume("/data")) { ui_print("Data wipe failed.\n"); status = INSTALL_ERROR; } else if (erase_volume("/cache")) { ui_print("Cache wipe failed.\n"); status = INSTALL_ERROR; } else if ((encrypted_fs_data.mode == MODE_ENCRYPTED_FS_ENABLED) && (restore_encrypted_fs_info(&encrypted_fs_data))) { ui_print("Encrypted FS change aborted.\n"); status = INSTALL_ERROR; } else { ui_print("Successfully updated Encrypted FS.\n"); status = INSTALL_SUCCESS; } } } else if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; script_assert_enabled = 0; is_user_initiated_recovery = 1; ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_CLOCKWORK); if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) ui_set_background(BACKGROUND_ICON_ERROR); if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); if(!poweroff) ui_print("Rebooting...\n"); else ui_print("Shutting down...\n"); sync(); reboot((!poweroff) ? RB_AUTOBOOT : RB_POWER_OFF); return EXIT_SUCCESS; }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); if (strcmp(basename(argv[0]), "recovery") != 0) { if (strstr(argv[0], "minizip") != NULL) return minizip_main(argc, argv); if (strstr(argv[0], "dedupe") != NULL) return dedupe_main(argc, argv); if (strstr(argv[0], "flash_image") != NULL) return flash_image_main(argc, argv); if (strstr(argv[0], "volume") != NULL) return volume_main(argc, argv); if (strstr(argv[0], "edify") != NULL) return edify_main(argc, argv); if (strstr(argv[0], "dump_image") != NULL) return dump_image_main(argc, argv); if (strstr(argv[0], "erase_image") != NULL) return erase_image_main(argc, argv); if (strstr(argv[0], "mkyaffs2image") != NULL) return mkyaffs2image_main(argc, argv); if (strstr(argv[0], "make_ext4fs") != NULL) return make_ext4fs_main(argc, argv); if (strstr(argv[0], "unyaffs") != NULL) return unyaffs_main(argc, argv); if (strstr(argv[0], "nandroid")) return nandroid_main(argc, argv); if (strstr(argv[0], "bu") == argv[0] + strlen(argv[0]) - 2) return bu_main(argc, argv); if (strstr(argv[0], "reboot")) return reboot_main(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount")) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (strstr(argv[0], "poweroff")){ return reboot_main(argc, argv); } if (strstr(argv[0], "setprop")) return setprop_main(argc, argv); return busybox_driver(argc, argv); } __system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); load_volume_table(); process_volumes(); LOGI("Processing arguments.\n"); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); // ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("命令:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) ui_print("安装失败.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("清空data失败.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("清空cache失败.\n"); } else if (sideload) { signature_check_enabled = 0; ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } else { LOGI("Checking for extendedcommand \n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; script_assert_enabled = 0; is_user_initiated_recovery = 1; ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_CLOCKWORK); if (extendedcommand_file_exists()) { LOGI("Running extendedcommand \n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found \n"); } } setup_adbd(); if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } verify_root_and_recovery(); // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system finish_recovery(send_intent); sync(); if(!poweroff) { ui_print("重启中 \n"); android_reboot(ANDROID_RB_RESTART, 0, 0); } else { ui_print("关机中 \n"); android_reboot(ANDROID_RB_POWEROFF, 0, 0); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { time_t start = time(NULL); // If these fail, there's not really anywhere to complain... unlink(TEMPORARY_LOG_FILE); freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); //miuiIntent init miuiIntent_init(10); miuiIntent_register(INTENT_MOUNT, &intent_mount); miuiIntent_register(INTENT_ISMOUNT, &intent_ismount); miuiIntent_register(INTENT_UNMOUNT, &intent_unmount); miuiIntent_register(INTENT_REBOOT, &intent_reboot); miuiIntent_register(INTENT_INSTALL, &intent_install); miuiIntent_register(INTENT_WIPE, &intent_wipe); miuiIntent_register(INTENT_TOGGLE, &intent_toggle); miuiIntent_register(INTENT_FORMAT, &intent_format); miuiIntent_register(INTENT_RESTORE, &intent_restore); miuiIntent_register(INTENT_BACKUP, &intent_backup); miuiIntent_register(INTENT_ADVANCED_BACKUP, &intent_advanced_backup); miuiIntent_register(INTENT_SYSTEM, &intent_system); miuiIntent_register(INTENT_COPY, &intent_copy); device_ui_init(); load_volume_table(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; //case 't': ui_show_text(1); break; case '?': LOGE("Invalid command argument\n"); continue; } } device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { miuiInstall_init(&install_package, update_package, &wipe_cache,TEMPORARY_INSTALL_FILE); status = miui_install("<~sd.install.name>", "@sd.install"); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else { status = INSTALL_ERROR; // No command specified } if (status != INSTALL_SUCCESS) device_main_ui_show();//show menu device_main_ui_release(); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); android_reboot(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }