static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

        if (title_headers == NULL) {
            char* headers[] = { "确认是否清除所有数据?",
                                "这一步操作不可挽回.",
                                "",
                                NULL };
            title_headers = prepend_title((const char**)headers);
        }

        char* items[] = { " 取消",
                          " 确认 -- 删除所有用户数据",   // [1]
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 1) {
            return;
        }
    }

    ui_print("\n-- 格式化 Data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("格式化 Data 完成.\n");
}
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

        if (title_headers == NULL) {
            char* headers[] = { "确认清空所有数据?",
                                "",
                                "",
                                NULL };
            title_headers = prepend_title((const char**)headers);
        }

        char* items[] = { " 是的 - 清空所有数据", //[1]
                           " 取消 - 返回",   // [0]
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 0) {
            return;
        }
    }

    ui_print("\n-- 清空 data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("所有数据清空完毕.\n");
}
static 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",
                          " Yes -- delete all user data",   // [1]
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 1) {
            return;
        }
    }

    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sdcard/.android_secure");
    ui_print("Data wipe complete.\n");
}
static void
wipe_data(int confirm) {
    if (confirm && !confirm_selection( "Confirm wipe of all user data?", "Yes - Wipe all user data"))
        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");
    erase_volume("/sdcard/.android_secure");
    ui_print("Data wipe complete.\n");
}
static void
wipe_data(int confirm) {
    if (confirm && !confirm_selection( "确定清空数据?", "是 - 清空数据"))
        return;

    ui_print("\n-- 正在清空Data分区...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("Data分区已清空\n");
}
Exemple #6
0
void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

	ui_set_background(BACKGROUND_ICON_WIPE_CHOOSE);
        if (title_headers == NULL) {
            char* headers[] = { "Confirm wipe of all user data?",
                                "  THIS CAN NOT BE UNDONE.",
                                "",
                                NULL };
            title_headers = prepend_title((const char**)headers);
        }

        char* items[] = { " No",
                          " Yes -- delete all user data",   // [1]
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 1) {
            return;
        }
    }
    ui_set_background(BACKGROUND_ICON_WIPE);
    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    struct stat st;
    if (stat("/sd-ext",&st) == 0)
    {
        ui_print("Formatting /sd-ext...\n");
        __system("rm -rf /sd-ext/* && rm -rf /sd-ext/.*");
    } else {
        ui_print("/sd-ext not found, skipping...\n");
    }
    if (0 == stat("/sdcard/.android_secure", &st))
    {
        __system("rm -rf /sdcard/.android_secure/* && rm -rf /sdcard/.android_secure/.*");
        ui_print("Formatting /sdcard/.android_secure...\n");
    } else {
        ui_print("/sdcard/.android_secure not found, skipping...\n");
    }
	ui_reset_progress();
    ui_print("-- Data wipe complete.\n");
}
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

        if (title_headers == NULL) {
            char* headers[] = { "确认清空DATA分区?",
                                "该操作将会删除您设备内的个人数据",
                                "注意!该操作无法撤销.",
                                "",
                                NULL };
            title_headers = prepend_title((const char**)headers);
        }

        char* items[] = { " 否",
                          " 否",
                          " 否",
                          " 否",
                          " 否",
                          " 否",
                          " 否",
                          " 是 -- 清空所有个人数据",   // [7]
                          " 否",
                          " 否",
                          " 否",
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 7) {
            return;
        }
    }

    ui_print("\n-- 正在清空DATA分区...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("DATA分区已清空.\n");
}
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

        if (title_headers == NULL) {
            char* headers[] = { "你真的要清除数据?",
                                "  这个操作可是不允许撤销的啊 ",
                                "",
                                NULL };
            title_headers = prepend_title((const char**)headers);
        }

        char* items[] = { "  呀买碟",
                          "  呀买碟",
                          "  呀买碟",
                          "  呀买碟",
                          "  呀买碟",
                          "  呀买碟",
                          "  呀买碟",
                          "  我一定要删除所有用户数据",   // [7]
                          "  呀买碟",
                          "  呀买碟",
                          "  呀买碟",
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 7) {
            return;
        }
    }

    ui_print("\n-- 清除数据中 \n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("已经抹掉数据\n");
}
Exemple #9
0
static 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(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);
        if (chosen_item != 7) {
            return;
        }
    }

    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_root("DATA:");
#ifdef BOARD_HAS_DATADATA
    erase_root("DATADATA:");
#endif
    erase_root("CACHE:");
    erase_root("SDEXT:");
    erase_root("SDCARD:/.android_secure");
    ui_print("Data wipe complete.\n");
}
static void
wipe_data(int confirm) {
    if (confirm && !confirm_selection( "确认清除所有数据?", "确认 - 清除所有用户数据"))
        return;

    ui_print("\n-- 正在清除数据...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    if (volume_for_path("/external_sd") != NULL)
    erase_volume("/external_sd/.android_secure");
    else if (volume_for_path("/emmc") != NULL)
        erase_volume("/emmc/.android_secure");
    ui_print("清除数据完成.\n");
}
// remove static to be able to call it from ors menu
void
wipe_data(int confirm) {
    const char* headers[] = {
        "Wipe all user data ?",
        "   data | cache | datadata",
        "   sd-ext| android_secure",
        "",
        NULL
    };

    if (confirm && !confirm_with_headers(headers, "Yes - Wipe all user data")) {
        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");

    // erase .android_secure from /sdcard or /storage/sdcard0
    erase_volume(get_android_secure_path());

    // erase .android_secure from any secondary storage
    char buf[80];
    char** extra_paths = get_extra_storage_paths();
    int num_extra_volumes = get_num_extra_volumes();
    int i;
    if (extra_paths != NULL) {
        for(i = 0; i < num_extra_volumes; i++) {
            sprintf(buf, "%s/.android_secure", extra_paths[i]);
            erase_volume(buf);
        }
        free_string_array(extra_paths);
    }
    ui_print("Data wipe complete.\n");
}
Exemple #12
0
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

        if (title_headers == NULL) {
            char* headers[] = { "Confirm wipe of ALL user data?",
                                "following partitions will be WIPED:",
                                "   /data",
				"   /cache",
				"   /sd-ext",
				"   /sdcard/.android_secure",
                                "",
                                "  THIS CAN NOT BE UNDONE.",
                                "",
                                NULL };
            title_headers = prepend_title((const char**)headers);
        }

        char* items[] = { " No",
                          " Yes -- delete ALL user data",   // [1]
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 1) {
            return;
        }
    }

    ui_print("\n-- 正在清空用户数据...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("清空完毕\n");
}
Exemple #13
0
static void
wipe_data(int confirm) 
{
  if (confirm) 
  {
    char* headers[] = { "Confirm wipe of all user data?",
                        "  THIS CAN NOT BE UNDONE.",
                        "",
                        NULL };

    char* items[] = { " No",
                      " No",
                      " No",
                      " No",
                      " No",
                      " No",
                      " No",
                      " Yes -- delete all user data",   // [7]
                      " No",
                      " No",
                      " No",
                      NULL };
                      
    int chosen_item = show_interactive_menu(headers, items);
		hide_menu_selection();
    if (chosen_item != 8) 
        return;
  }

	ui_led_blink(1);
  ui_print("\n-- Wiping data...\n");
  device_wipe_data();
  erase_root("DATA:");
  erase_root("CACHE:");
  ensure_common_roots_mounted();
  ui_print("Data wipe complete.\n");
 	ui_led_toggle(0);
}
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_show_text(1);
        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) {
    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;

    //check delta update first
    handle_deltaupdate_status();

    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;
}
Exemple #16
0
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;
    const char *update_patch = NULL;
	const char *file_copy_from_partition_args = NULL;
	const char *copy_custom_files_dir = NULL; //add ainuo
	const char *file1_copy_from_partition_args = NULL;
    int wipe_data = 0, wipe_cache = 0;
    int reboot_to_factorymode = 0;
#ifdef RECOVERY_HAS_MEDIA
    int wipe_media = 0;
#endif /* RECOVERY_HAS_MEDIA */
#ifdef RECOVERY_HAS_EFUSE
    const char *efuse_version = NULL;
	const char *efuse_machine = NULL;					/* add for m6 */
    int set_efuse_version = 0;
    int set_efuse_ethernet_mac = 0;
    int set_efuse_bluetooth_mac = 0;
	int set_efuse_machine_id = 0;						/* add for m6 */
#ifdef EFUSE_LICENCE_ENABLE
    int set_efuse_audio_license = 0;
#endif /* EFUSE_LICENCE_ENABLE */
#endif /* RECOVERY_HAS_EFUSE */

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'a': copy_custom_files_dir = optarg; break; //add ainuo
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
		case 'x': update_patch = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case 'f': reboot_to_factorymode = 1; break;
		case 'z': file_copy_from_partition_args = optarg; break;
		case 'y': file1_copy_from_partition_args = optarg; break;
#ifdef RECOVERY_HAS_MEDIA
        case 'm': wipe_media = 1; break;
#endif /* RECOVERY_HAS_MEDIA */
        case 't': ui_show_text(1); break;
#ifdef RECOVERY_HAS_EFUSE
        case 'v': set_efuse_version = 1; efuse_version = optarg; break;
        case 'd': set_efuse_ethernet_mac = 1; break;
        case 'b': set_efuse_bluetooth_mac = 1; break;
		case 'M': set_efuse_machine_id = 1; efuse_machine = optarg; break; 	/* add for m6 */
#ifdef EFUSE_LICENCE_ENABLE
        case 'l': set_efuse_audio_license = 1; break;
#endif /* EFUSE_LICENCE_ENABLE */

#endif /* RECOVERY_HAS_EFUSE */
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

    printf("Command:");
    for (arg = 0; arg < argc; arg++) {
        printf(" \"%s\"", argv[arg]);
    }
    printf("\n");

    /**
     *  Disable auto reformat, we should *NOT* do this.
     *
     *  For /media partition, we cannot do it because this will break
     *  any file system that's non-FAT.
     */
#if 0
    if (ensure_path_mounted("/data") != 0) {
        ui_print("Can't mount 'data', wipe it!\n");
        if (erase_volume("/data")) {
            ui_print("Data wipe failed.\n");
        }
    }

    if (ensure_path_mounted("/cache") != 0) {
        ui_print("Can't mount 'cache', wipe it!\n");
        if (erase_volume("/cache")) {
            ui_print("Cache wipe failed.\n");
        }
    }

#ifdef RECOVERY_HAS_MEDIA
    if (ensure_path_mounted(MEDIA_ROOT) != 0) {
        ui_print("Can't mount 'media', wipe it!\n");
        if (erase_volume(MEDIA_ROOT)) {
            ui_print("Media wipe failed.\n");
        }
    }
#endif
#endif /* 0 */

	char *file_path = NULL;
	char *partition_type = NULL;
	char *partition = NULL;
	char *offset_str = NULL;
	char *size_str = NULL;
	ssize_t part_offset;
	ssize_t file_size;

	if(file_copy_from_partition_args)
	{
		if(((file_path = strtok(file_copy_from_partition_args, ":")) == NULL) ||
			((partition_type = strtok(NULL, ":")) == NULL)	||
			((partition = strtok(NULL, ":")) == NULL)	||
			((offset_str = strtok(NULL, ":")) == NULL)	||
			((size_str = strtok(NULL, ":")) == NULL))
		{
			printf("file_copy_from_partition_args Invalid!\n");
		}
		else
		{
			part_offset = atoi(offset_str);
			file_size = atoi(size_str);
			file_copy_from_partition(file_path, partition_type, partition, part_offset, file_size);
		}	
	}

	if(file1_copy_from_partition_args)
	{
		if(((file_path = strtok(file1_copy_from_partition_args, ":")) == NULL) ||
			((partition_type = strtok(NULL, ":")) == NULL)	||
			((partition = strtok(NULL, ":")) == NULL)	||
			((offset_str = strtok(NULL, ":")) == NULL)	||
			((size_str = strtok(NULL, ":")) == NULL))
		{
			printf("file1_copy_from_partition_args Invalid!\n");
		}
		else
		{
			part_offset = atoi(offset_str);
			file_size = atoi(size_str);
			file_copy_from_partition(file_path, partition_type, partition, part_offset, file_size);
		}	
	}

    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");
			goto process_failed;
        }
    }

    if (update_patch != NULL) {
        status = install_package(update_patch, &wipe_cache, TEMPORARY_INSTALL_FILE);
        if (status != INSTALL_SUCCESS)
		{
			ui_print("Installation patch aborted.\n");
			goto process_failed;
		}
    }
	
    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");
			goto process_failed;
        }
    }
    
    if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS)
		{
			ui_print("Cache wipe failed.\n");
			goto process_failed;
        }
    }
    
#ifdef RECOVERY_HAS_MEDIA
    if (wipe_media) {
        if (wipe_media && erase_volume(MEDIA_ROOT)) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS)
		{
			ui_print("Media wipe failed.\n");
			goto process_failed;
        }
    } 
#endif /* RECOVERY_HAS_MEDIA */    
//    else {
//        status = INSTALL_ERROR;  // No command specified
//    }

    //add ainuo
    if (copy_custom_files_dir != NULL) {
        status = copy_custom_files(MEDIA_ROOT, copy_custom_files_dir);
        if (status != INSTALL_SUCCESS) ui_print("Copy custom files failed.\n");
    }

#ifdef RECOVERY_HAS_EFUSE
    if (set_efuse_version) {
        status = recovery_efuse(EFUSE_VERSION, efuse_version);
		if (status != INSTALL_SUCCESS)
		{
			ui_print("efuse write version failed.\n");
			goto process_failed;
        }
    }
#ifdef EFUSE_LICENCE_ENABLE
    if (set_efuse_audio_license) {
        status = recovery_efuse(EFUSE_LICENCE, NULL);
		if (status != INSTALL_SUCCESS)
		{
			ui_print("efuse write licence failed.\n");
			goto process_failed;
        }
    }
#endif /* EFUSE_LICENCE_ENABLE */

    if (set_efuse_ethernet_mac) {
        status = recovery_efuse(EFUSE_MAC, NULL);
		if (status != INSTALL_SUCCESS)
		{
			ui_print("efuse write MAC addr failed.\n");
			goto process_failed;
        }
    }

    if (set_efuse_bluetooth_mac) {
        status = recovery_efuse(EFUSE_MAC_BT, NULL);
		if (status != INSTALL_SUCCESS)
		{
			ui_print("efuse write BT MAC failed.\n");
			goto process_failed;
        }
	}
	
	if (set_efuse_machine_id) {							/* add for m6 */
        status = recovery_efuse(EFUSE_MACHINEID, efuse_machine);
    }	
#endif /* RECOVERY_HAS_EFUSE */

	int howReboot;
process_failed:
    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        ui_show_text(1);
        howReboot = prompt_and_wait();
        if (REBOOT_FACTORY_TEST == howReboot)
            reboot_to_factorymode = 1;
    }

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");

    sync();

    if (reboot_to_factorymode) {
        property_set("androidboot.mode", "factorytest");
        android_reboot(ANDROID_RB_RESTART, 0, "factory_testl_reboot");
    } else {
        android_reboot(ANDROID_RB_RESTART, 0, 0);
    }

    return EXIT_SUCCESS;
}
Exemple #17
0
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;
}
Exemple #18
0
int
main(int argc, char **argv) {
	if (strstr(argv[0], "recovery") == NULL)
	{
	    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], "amend"))
            return amend_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
        if (strstr(argv[0], "setprop"))
            return setprop_main(argc, argv);
		return busybox_driver(argc, argv);
	}
    __system("/sbin/postrecoveryboot.sh");
    create_fstab();
    
    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);
    fprintf(stderr, "Starting recovery on %s", ctime(&start));

    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\n");
#ifdef BOARD_GOAPK_DEFY
    ui_print(EXPAND(RECOVERY_VERSION_GOAPK)"\n");
    ui_print(EXPAND(RECOVERY_VERSION_QUN)"\n");
#endif
    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 '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

    fprintf(stderr, "Command:");
    for (arg = 0; arg < argc; arg++) {
        fprintf(stderr, " \"%s\"", argv[arg]);
    }
    fprintf(stderr, "\n\n");

    property_list(print_property, NULL);
    fprintf(stderr, "\n");

    int status = INSTALL_SUCCESS;
    
    RecoveryCommandContext ctx = { NULL };
    if (register_update_commands(&ctx)) {
        LOGE("Can't install update commands\n");
    }

    if (update_package != NULL) {
        if (wipe_data && erase_root("DATA:")) status = INSTALL_ERROR;
        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_root("DATA:")) status = INSTALL_ERROR;
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_root("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);
        
        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();

#ifndef BOARD_HAS_NO_MISC_PARTITION
    // If there is a radio image pending, reboot now to install it.
    maybe_install_firmware_update(send_intent);
#endif

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}
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;
        }

    }
}
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);
}
Exemple #21
0
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;
}
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;
}
Exemple #23
0
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;
}
int
main(int argc, char **argv) {
        if (strstr(argv[0], "recovery") == NULL)
        {
            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);
            if (strstr(argv[0], "setprop"))
                return setprop_main(argc, argv);
            if (strstr(argv[0], "getprop"))
                return getprop_main(argc, argv);
            return busybox_driver(argc, argv);
        }
    
    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);
    fprintf(stderr, "Starting recovery on %s", ctime(&start));
    
    ui_init();
    ui_print(EXPAND(RECOVERY_VERSION)"\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 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 '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    //device_recovery_start();

    fprintf(stderr, "Command:");
    for (arg = 0; arg < argc; arg++) {
        fprintf(stderr, " \"%s\"", argv[arg]);
    }
    fprintf(stderr, "\n\n");

    property_list(print_property, NULL);
    fprintf(stderr, "\n");

    int status = INSTALL_SUCCESS;

    //Register amend commands
    RecoveryCommandContext ctx = { NULL };
    if (register_update_commands(&ctx)) {
        LOGE("Can't install update commands\n");
    }

    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_root("DATA:")) status = INSTALL_ERROR;
        if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_root("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_text_visible()) prompt_and_wait();

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}
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;
}
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");
}
Exemple #27
0
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));

    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;
        }
    }

    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 {
        status = INSTALL_ERROR;  // No command specified
    }

    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        //assume we want to be here and its not an error - give us the pretty icon!
        ui_set_background(BACKGROUND_ICON_MAIN);
        prompt_and_wait();
    }

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    sync();
    reboot(RB_AUTOBOOT);
    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);

    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;
}
int
main(int argc, char **argv) {
    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], "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);

    // Recovery needs to install world-readable files, so clear umask
    // set by init
    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));

    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;

    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 '?':
            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 (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 (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 {
        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_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");
	#ifdef BOARD_HAS_DUAL_SYSTEM
        if(multiboot==1){
	#endif
			android_reboot(ANDROID_RB_RESTART, 0, 0);
	#ifdef BOARD_HAS_DUAL_SYSTEM
		}else{
			set_reboot_message(multiboot==2);
			sync();
			android_reboot(ANDROID_RB_RESTART, 0, 0);
		}
	#endif
    }
    else {
        ui_print("关闭手机...\n");
        android_reboot(ANDROID_RB_POWEROFF, 0, 0);
    }
    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);
        if (strstr(argv[0], "getprop"))
            return getprop_main(argc, argv);
        return busybox_driver(argc, argv);
    }

#ifdef RECOVERY_CHARGEMODE
    handle_chargemode();
#endif

    //__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));

#ifdef RECOVERY_CHARGEMODE
    int flag;
    flag = get_chargemode();

    if(flag == 1){
//        __system("mount /dev/block/mmcblk0p12 /system");
//        __system("sleep 1");
        __system("charge");
    }else {
#endif

    device_ui_init(&ui_parameters);
    ui_init();
    ui_print(EXPAND(RECOVERY_WELCOME)"\n");
    ui_print(EXPAND(RECOVERY_VERSION_INFO)"\n");
    ui_print(EXPAND(RECOVERY_BUILD_DATE)"\n");
	__system("/sbin/postrecoveryboot.sh");

#ifdef BOARD_RECOVERY_SWIPE
#ifndef BOARD_TOUCH_RECOVERY
    //display directions for swipe controls
    ui_print("上/下滑动选择.\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();
    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;
//    int headless = 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 '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 '?':
            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();

    enable_key_backlight();

    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) ui_print("安装终止.\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) ui_print("清除数据失败.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("清除缓存失败.\n");
    } else 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);
        }
    } 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_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 (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()) {
    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;
}

#ifdef RECOVERY_CHARGEMODE
	return 0;
}