示例#1
0
int
main(int argc, char **argv) {
    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);
    miuiIntent_register(INTENT_SETSYSTEM, &intent_setsystem);
    device_ui_init();
    load_volume_table();
    get_args(&argc, &argv);

    struct bootloader_message boot;
    memset(&boot, 0, sizeof(boot));
    set_bootloader_message(&boot);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        //case 't': ui_show_text(1); break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

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

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        if (wipe_cache) erase_volume("/cache");
        miuiIntent_send(INTENT_INSTALL, 3, update_package,"0", "0");
        //if echo 0 ,don't print success dialog 
        status = miuiIntent_result_get_int();
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        status = INSTALL_ERROR;  // No command specified
    }
    if (status != INSTALL_SUCCESS) device_main_ui_show();//show menu
    device_main_ui_release();
    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    android_reboot(ANDROID_RB_RESTART, 0, 0);
    return EXIT_SUCCESS;
}
int
main(int argc, char **argv) {
	if (strcmp(basename(argv[0]), "recovery") != 0)
	{
	    if (strstr(argv[0], "flash_image") != NULL)
	        return flash_image_main(argc, argv);
	    if (strstr(argv[0], "volume") != NULL)
	        return volume_main(argc, argv);
	    if (strstr(argv[0], "edify") != NULL)
	        return edify_main(argc, argv);
	    if (strstr(argv[0], "dump_image") != NULL)
	        return dump_image_main(argc, argv);
	    if (strstr(argv[0], "erase_image") != NULL)
	        return erase_image_main(argc, argv);
	    if (strstr(argv[0], "mkyaffs2image") != NULL)
	        return mkyaffs2image_main(argc, argv);
	    if (strstr(argv[0], "unyaffs") != NULL)
	        return unyaffs_main(argc, argv);
        if (strstr(argv[0], "nandroid"))
            return nandroid_main(argc, argv);
        if (strstr(argv[0], "reboot"))
            return reboot_main(argc, argv);
#ifdef BOARD_RECOVERY_HANDLES_MOUNT
        if (strstr(argv[0], "mount") && argc == 2 && !strstr(argv[0], "umount"))
        {
            load_volume_table();
            return ensure_path_mounted(argv[1]);
        }
#endif
        if (strstr(argv[0], "poweroff")){
            return reboot_main(argc, argv);
        }
        if (strstr(argv[0], "setprop"))
            return setprop_main(argc, argv);
		return busybox_driver(argc, argv);
	}
    __system("/sbin/postrecoveryboot.sh");

    int is_user_initiated_recovery = 0;
    time_t start = time(NULL);

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    printf("Starting recovery on %s", ctime(&start));

    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_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);

    sync();
    if(!poweroff) {
        ui_print("Rebooting...\n");
        android_reboot(ANDROID_RB_RESTART, 0, 0);
    }
    else {
        ui_print("Shutting down...\n");
        android_reboot(ANDROID_RB_POWEROFF, 0, 0);
    }
    return EXIT_SUCCESS;
}
示例#3
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], "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;
}
static void
prompt_and_wait() {
    char** headers = prepend_title((const char**)MENU_HEADERS);

    for (;;) {
        finish_recovery(NULL);
        ui_reset_progress();

        allow_display_toggle = 1;
        int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);
        allow_display_toggle = 0;

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
        chosen_item = device_perform_action(chosen_item);

        switch (chosen_item) {
            case ITEM_REBOOT:
                poweroff=0;
                return;

            case ITEM_WIPE_DATA:
                wipe_data(ui_text_visible());
                if (!ui_text_visible()) return;
                break;

            case ITEM_WIPE_CACHE:
                if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache"))
                {
                    ui_print("\n-- Wiping cache...\n");
                    erase_volume("/cache");
                    ui_print("Cache wipe complete.\n");
                    if (!ui_text_visible()) return;
                }
                break;

            case ITEM_APPLY_SDCARD:
                if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
                {
                    ui_print("\n-- Install from sdcard...\n");
                    int status = install_package(SDCARD_PACKAGE_FILE);
                    if (status != INSTALL_SUCCESS) {
                        ui_set_background(BACKGROUND_ICON_ERROR);
                        ui_print("Installation aborted.\n");
                    } else if (!ui_text_visible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui_print("\nInstall from sdcard complete.\n");
                    }
                }
                break;
            case ITEM_INSTALL_ZIP:
                show_install_update_menu();
                break;
            case ITEM_NANDROID:
                show_nandroid_menu();
                break;
            case ITEM_PARTITION:
                show_partition_menu();
                break;
            case ITEM_ADVANCED:
                show_advanced_menu();
                break;
            case ITEM_POWEROFF:
                poweroff=1;
                return;
        }
    }
}
示例#5
0
static void
prompt_and_wait() {
    char** headers = prepend_title((const char**)MENU_HEADERS);

    for (;;) {
        finish_recovery(NULL);
        ui_reset_progress();

        int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
        chosen_item = device_perform_action(chosen_item);

        int status;
        int wipe_cache;
        switch (chosen_item) {
        case ITEM_REBOOT:
            return;

        case ITEM_WIPE_DATA:
            wipe_data(ui_text_visible());
            if (!ui_text_visible()) return;
            break;

        case ITEM_WIPE_CACHE:
            ui_print("\n-- Wiping cache...\n");
            erase_volume("/cache");
            ui_print("Cache wipe complete.\n");
            if (!ui_text_visible()) return;
            break;

        case ITEM_APPLY_SDCARD:
            status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache);
            if (status == INSTALL_SUCCESS && wipe_cache) {
                ui_print("\n-- Wiping cache (at package request)...\n");
                if (erase_volume("/cache")) {
                    ui_print("Cache wipe failed.\n");
                } else {
                    ui_print("Cache wipe complete.\n");
                }
            }
            if (status >= 0) {
                if (status != INSTALL_SUCCESS) {
                    ui_set_background(BACKGROUND_ICON_ERROR);
                    ui_print("Installation aborted.\n");
                } else if (!ui_text_visible()) {
                    return;  // reboot if logs aren't visible
                } else {
                    ui_print("\nInstall from sdcard complete.\n");
                }
            }
            break;
        case ITEM_APPLY_CACHE:
            // Don't unmount cache at the end of this.
            status = update_directory(CACHE_ROOT, NULL, &wipe_cache);
            if (status == INSTALL_SUCCESS && wipe_cache) {
                ui_print("\n-- Wiping cache (at package request)...\n");
                if (erase_volume("/cache")) {
                    ui_print("Cache wipe failed.\n");
                } else {
                    ui_print("Cache wipe complete.\n");
                }
            }
            if (status >= 0) {
                if (status != INSTALL_SUCCESS) {
                    ui_set_background(BACKGROUND_ICON_ERROR);
                    ui_print("Installation aborted.\n");
                } else if (!ui_text_visible()) {
                    return;  // reboot if logs aren't visible
                } else {
                    ui_print("\nInstall from cache complete.\n");
                }
            }
            break;

        }
    }
}
示例#6
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;
    int wipe_data = 0, wipe_cache = 0;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p':
            previous_runs = atoi(optarg);
            break;
        case 's':
            send_intent = optarg;
            break;
        case 'u':
            update_package = optarg;
            break;
        case 'w':
            wipe_data = wipe_cache = 1;
            break;
        case 'c':
            wipe_cache = 1;
            break;
        case 't':
            ui_show_text(1);
            break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    device_recovery_start();

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

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
        if (status == INSTALL_SUCCESS && wipe_cache) {
            if (erase_volume("/cache")) {
                LOGE("Cache wipe (requested by package) failed.");
            }
        }
        if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device_wipe_data()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
    } else {
        status = INSTALL_ERROR;  // No command specified
    }

    if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
    if (status != INSTALL_SUCCESS || ui_text_visible()) {
        prompt_and_wait();
    }

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui_print("Rebooting...\n");
    android_reboot(ANDROID_RB_RESTART, 0, 0);
    return EXIT_SUCCESS;
}
static void
prompt_and_wait() {
    char** headers = prepend_title((const char**)MENU_HEADERS);

    for (;;) {
        finish_recovery(NULL);
        ui_reset_progress();
        
        ui_root_menu = 1;
        // ui_menu_level is a legacy variable that i am keeping around to prevent build breakage.
        ui_menu_level = 0;
        // allow_display_toggle = 1;
        int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);
        ui_menu_level = 1;
        ui_root_menu = 0;
        // allow_display_toggle = 0;

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
        chosen_item = device_perform_action(chosen_item);

        int status;
        switch (chosen_item) {
            case ITEM_REBOOT:
                poweroff=0;
                return;

            case ITEM_WIPE_DATA:
                wipe_data(ui_text_visible());
                if (!ui_text_visible()) return;
                break;

            case ITEM_WIPE_CACHE:
                if (confirm_selection("确认清空?", "是 - 清空CACHE分区"))
                {
                    ui_print("\n-- 正在清空CACHE分区...\n");
                    erase_volume("/cache");
                    ui_print("CACHE分区已清空.\n");
                    if (!ui_text_visible()) return;
                }
                break;

            case ITEM_APPLY_SDCARD:
                show_install_update_menu();
                break;

            case ITEM_APPLY_SIDELOAD:
                apply_from_adb();
                break;

            case ITEM_NANDROID:
                show_nandroid_menu();
                break;

            case ITEM_PARTITION:
                show_partition_menu();
                break;

            case ITEM_ADVANCED:
                show_advanced_menu();
                break;

            case ITEM_POWEROFF:
                poweroff = 1;
                return;
        }
    }
}
// call a clean reboot
void reboot_main_system(int cmd, int flags, char *arg) {
    verify_root_and_recovery();
    finish_recovery(NULL); // sync() in here
    android_reboot(cmd, flags, arg);
}
示例#9
0
int
main(int argc, char **argv) {
    time_t start = time(NULL);
	char firmware[50] = {0};
	property_get("ro.reversion.aw_sdk_tag", firmware, "unknow");
	strcat(reversion,firmware);
	
	char storage_type[50] = {0};
	property_get("ro.sys.storage_type",storage_type,"");
	if(!strcmp(storage_type,"emulated")){
		internal_storage_type = 1;
	}

    // If these fail, there's not really anywhere to complain...
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    

    // If this binary is started with the single argument "--adbd",
    // instead of being the normal recovery binary, it turns into kind
    // of a stripped-down version of adbd that only supports the
    // 'sideload' command.  Note this must be a real argument, not
    // anything in the command file or bootloader control block; the
    // only way recovery should be run with this argument is when it
    // starts a copy of itself from the apply_from_adb() function.
    if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
        adb_main();
        return 0;
    }
    
    printf("Starting recovery on %s", ctime(&start));

    load_volume_table();
    get_args(&argc, &argv);

    int previous_runs = 0;
    const char *send_intent = NULL;
    const char *update_package = NULL;
    int wipe_data = 0, wipe_cache = 0, show_text = 0;
    bool just_exit = false;

    int arg;
    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
        switch (arg) {
        case 'p': previous_runs = atoi(optarg); break;
        case 's': send_intent = optarg; break;
        case 'u': update_package = optarg; break;
        case 'w': wipe_data = wipe_cache = 1; break;
        case 'c': wipe_cache = 1; break;
        case 't': show_text = 1; break;
        case 'x': just_exit = true; break;
        case 'l': locale = optarg; break;
        case '?':
            LOGE("Invalid command argument\n");
            continue;
        }
    }

    if (locale == NULL) {
        load_locale_from_cache();
    }
    printf("locale is [%s]\n", locale);

    Device* device = make_device();
    ui = device->GetUI();

    ui->Init();
    ui->SetLocale(locale);
    ui->SetBackground(RecoveryUI::NONE);
    if (show_text) ui->ShowText(true);

#ifdef HAVE_SELINUX
    struct selinux_opt seopts[] = {
      { SELABEL_OPT_PATH, "/file_contexts" }
    };

    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);

    if (!sehandle) {
        fprintf(stderr, "Warning: No file_contexts\n");
        ui->Print("Warning:  No file_contexts\n");
    }
#endif

    device->StartRecovery();

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

    if (update_package) {
        // For backwards compatibility on the cache partition only, if
        // we're given an old 'root' path "CACHE:foo", change it to
        // "/cache/foo".
        if (strncmp(update_package, "CACHE:", 6) == 0) {
            int len = strlen(update_package) + 10;
            char* modified_path = (char*)malloc(len);
            strlcpy(modified_path, "/cache/", len);
            strlcat(modified_path, update_package+6, len);
            printf("(replacing path \"%s\" with \"%s\")\n",
                   update_package, modified_path);
            update_package = modified_path;
        }
    }
    printf("\n");

    property_list(print_property, NULL);
    printf("\n");

    int status = INSTALL_SUCCESS;

    if (update_package != NULL) {
        status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
        if (status == INSTALL_SUCCESS && wipe_cache) {
            if (erase_volume("/cache")) {
                LOGE("Cache wipe (requested by package) failed.");
            }
        }
        if (status != INSTALL_SUCCESS) ui->Print("Installation aborted.\n");
    } else if (wipe_data) {
        if (device->WipeData()) status = INSTALL_ERROR;
        if (erase_volume("/data")) status = INSTALL_ERROR;
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
		copy_databk_to_data();
        if (status != INSTALL_SUCCESS) ui->Print("Data wipe failed.\n");
    } else if (wipe_cache) {
        if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR;
        if (status != INSTALL_SUCCESS) ui->Print("Cache wipe failed.\n");
    } else if (!just_exit) {
        status = INSTALL_NONE;  // No command specified
//        ui->SetBackground(RecoveryUI::NO_COMMAND); // modify by cjcheng
    }

    if (status == INSTALL_ERROR || status == INSTALL_CORRUPT) {
        ui->SetBackground(RecoveryUI::ERROR);
    }
    if (status != INSTALL_SUCCESS || ui->IsTextVisible()) {
        ui->ShowText(false); // modify by cjcheng
        ui->SetTipTitle(RecoveryUI::TIP_TITLE_READY); // add by cjcheng
        prompt_and_wait(device, status);

	/* add by cjcheng start... */
        if (install_flag == INSTALL_SUCCESS){
            ui->SetTipTitle(RecoveryUI::TIP_TITLE_SUCCESS);
            status = INSTALL_SUCCESS;
        }
	/* add by cjcheng end... */
    }

    /* add by cjcheng start... */
    if (status != INSTALL_SUCCESS){
        ui->SetBackground(RecoveryUI::ERROR);
        ui->SetTipTitle(RecoveryUI::TIP_TITLE_ERROR);
    }
    /* add by cjcheng end... */

    sleep(2);

    // Otherwise, get ready to boot the main system...
    finish_recovery(send_intent);
    ui->Print("Rebooting...\n");
    sync();
    android_reboot(ANDROID_RB_RESTART, 0, 0);
    return EXIT_SUCCESS;
}
示例#10
0
static void
prompt_and_wait(Device* device, int status) {
    const char* const* headers = prepend_title(device->GetMenuHeaders());

    int chosen_item = 6; // add by cjcheng
    for (;;) {
        finish_recovery(NULL);
        switch (status) {
            case INSTALL_SUCCESS:
            case INSTALL_NONE:
                ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); // modify by cjcheng
                break;
        }
        ui->SetProgressType(RecoveryUI::EMPTY);

//        int chosen_item = get_menu_selection(headers, device->GetMenuItems(), 0, 0, device); // modify by cjcheng

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
//        chosen_item = device->InvokeMenuItem(chosen_item); // modify by cjcheng
        int wipe_cache;
        switch (chosen_item) {
            case Device::REBOOT:
                return;

            case Device::WIPE_DATA:
                wipe_data(ui->IsTextVisible(), device);
                if (!ui->IsTextVisible()) return;
                break;

            case Device::WIPE_CACHE:
                ui->ShowText(false);
                ui->Print("\n-- Wiping cache...\n");
                erase_volume("/cache");
                ui->Print("Cache wipe complete.\n");
                if (!ui->IsTextVisible()) return;
                break;

            case Device::APPLY_CACHE:
                // Don't unmount cache at the end of this.
                status = update_directory(CACHE_ROOT, NULL, &wipe_cache, device);
                if (status == INSTALL_SUCCESS && wipe_cache) {
                    ui->Print("\n-- Wiping cache (at package request)...\n");
                    if (erase_volume("/cache")) {
                        ui->Print("Cache wipe failed.\n");
                    } else {
                        ui->Print("Cache wipe complete.\n");
                    }
                }
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (!ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from cache complete.\n");
                    }
                }
                break;

            case Device::APPLY_ADB_SIDELOAD:
                ensure_path_mounted(CACHE_ROOT);
                status = apply_from_adb(ui, &wipe_cache, TEMPORARY_INSTALL_FILE);
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (!ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from ADB complete.\n");
                    }
                }
                break;
	    /* add by cjcheng start... */
            case Device::APPLY_SDCARD:
                // Some packages expect /cache to be mounted (eg,
                // standard incremental packages expect to use /cache
                // as scratch space).
                ensure_path_mounted(CACHE_ROOT);
                status = smdt_update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache);
		install_flag = status;
                if (status == INSTALL_SUCCESS && wipe_cache) {
                    ui->Print("\n-- Wiping cache (at package request)...\n");
                    if (erase_volume("/cache")) {
                        ui->Print("Cache wipe failed.\n");
                    } else {
                        ui->Print("Cache wipe complete.\n");
                    }
                }
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from sdcard complete.\n");
		        chosen_item = 1;
                    }
                }
                break;
            case Device::APPLY_EXT:
                // Some packages expect /cache to be mounted (eg,
                // standard incremental packages expect to use /cache
                // as scratch space).
                ensure_path_mounted(CACHE_ROOT);
                status = smdt_update_directory(EXTSD_ROOT, EXTSD_ROOT, &wipe_cache);
		install_flag = status;
                if (status == INSTALL_SUCCESS && wipe_cache) {
                    ui->Print("\n-- Wiping cache (at package request)...\n");
                    if (erase_volume("/cache")) {
                        ui->Print("Cache wipe failed.\n");
                    } else {
                        ui->Print("Cache wipe complete.\n");
                    }
                }
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from sdcard complete.\n");
		        chosen_item = 1;
                    }
                }
                break;
            case Device::APPLY_USB1:
                // Some packages expect /cache to be mounted (eg,
                // standard incremental packages expect to use /cache
                // as scratch space).
                ensure_path_mounted(CACHE_ROOT);
                status = smdt_update_directory(USB1_ROOT, USB1_ROOT, &wipe_cache);
		install_flag = status;
                if (status == INSTALL_SUCCESS && wipe_cache) {
                    ui->Print("\n-- Wiping cache (at package request)...\n");
                    if (erase_volume("/cache")) {
                        ui->Print("Cache wipe failed.\n");
                    } else {
                        ui->Print("Cache wipe complete.\n");
                    }
                }
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from sdcard complete.\n");
		        chosen_item = 1;
                    }
                }
                break;
            case Device::APPLY_USB0:
                // Some packages expect /cache to be mounted (eg,
                // standard incremental packages expect to use /cache
                // as scratch space).
                ensure_path_mounted(CACHE_ROOT);
                status = smdt_update_directory(USB0_ROOT, USB0_ROOT, &wipe_cache);
		install_flag = status;
                if (status == INSTALL_SUCCESS && wipe_cache) {
                    ui->Print("\n-- Wiping cache (at package request)...\n");
                    if (erase_volume("/cache")) {
                        ui->Print("Cache wipe failed.\n");
                    } else {
                        ui->Print("Cache wipe complete.\n");
                    }
                }
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from sdcard complete.\n");
		        chosen_item = 1;
                    }
                }
                break;
            case Device::APPLY_SATA:
                // Some packages expect /cache to be mounted (eg,
                // standard incremental packages expect to use /cache
                // as scratch space).
                ensure_path_mounted(CACHE_ROOT);
                status = smdt_update_directory(SATA_ROOT, SATA_ROOT, &wipe_cache);
		install_flag = status;
                if (status == INSTALL_SUCCESS && wipe_cache) {
                    ui->Print("\n-- Wiping cache (at package request)...\n");
                    if (erase_volume("/cache")) {
                        ui->Print("Cache wipe failed.\n");
                    } else {
                        ui->Print("Cache wipe complete.\n");
                    }
                }
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
//                        ui->SetBackground(RecoveryUI::ERROR);
                        ui->Print("Installation aborted.\n");
                    } else if (ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from sdcard complete.\n");
		        chosen_item = 1;
                    }
                }
                break;
	    /* add by cjcheng end... */
        }
	/* add by cjcheng start... */
        if (chosen_item < 11 && chosen_item != 1)
            chosen_item++;
        else
            chosen_item = 1;
	/* add by cjcheng end... */
    }
}
示例#11
0
static void
prompt_and_wait()
{
	char* menu_files[MAX_MENU_LEVEL] = { NULL };
	char* menu_scripts[MAX_MENU_LEVEL] = { NULL };
	int menu_sel[MAX_MENU_LEVEL] = { 0 };
	unsigned int menu_level = 0;  
	int menu_result;
  
  //always ensure if mountings are good
  ensure_common_roots_mounted();
  
	//initialize the recovery -> either call the script for initalization, or switch to full version
#if !OPEN_RCVR_VERSION_LITE
	run_shell_script("/bin/init_recovery.sh "OPEN_RECOVERY_PHONE_SWITCH, 1, NULL);
#endif 

  menu_files[0] = malloc(strlen(MAIN_MENU_FILE)+1);
  strcpy(menu_files[0], MAIN_MENU_FILE);
  ui_led_blink(1);
  create_menu(menu_files[0], menu_scripts[0]);
  ui_led_toggle(0);
  int title_length;  
	char** headers;
	headers = prepend_title(MENU_HEADERS, &title_length);
	int override_initial_selection = -1;	
	
	int call_finish_in_loop = 1;
			
  for (;;) {  

		if (call_finish_in_loop)
		{
			finish_recovery(NULL);
			call_finish_in_loop = 0;
		}

		int menu_item;		
		
		if (override_initial_selection != -1)
		{
			menu_item = get_menu_selection(headers, MENU_ITEMS, MENU_ITEMS_SELECTABLE, title_length, override_initial_selection, 0);
			override_initial_selection = -1;
		}
		else
    	menu_item = get_menu_selection(headers, MENU_ITEMS, MENU_ITEMS_SELECTABLE, title_length, 0, 0);

    // Parse open recovery commands
    int chosen_item = select_action(menu_item);
    chosen_item = device_perform_action(chosen_item);

		//if tag, menu, or scripted menu -> don't hide menu
		//do it here explicitly, it would be a mess in the switch
		if (chosen_item != ITEM_TAG && chosen_item != ITEM_NEW_MENU 
		    && chosen_item != ITEM_NEW_MENU_SCRIPTED)
			hide_menu_selection();

		fprintf(stderr, "Menu: %d, %d, %s\n", menu_item, chosen_item, MENU_ITEMS_TARGET[menu_item]);

    switch (chosen_item) {
    	case ITEM_REBOOT:
       	return;

      case ITEM_WIPE_DATA:
        wipe_data(ui_text_visible());

        if (!ui_text_visible()) 
        	return;
        	
        ui_set_background(BACKGROUND_ICON_ERROR);
        break;

      case ITEM_WIPE_CACHE:
        ui_print("\n-- Wiping cache...\n");
				ui_led_blink(1);
        erase_root("CACHE:");
        ensure_common_roots_mounted();
				ui_led_toggle(0);
        ui_print("Cache wipe complete.\n");
        if (!ui_text_visible()) 
        	return;
        ui_set_background(BACKGROUND_ICON_ERROR);
        break;

      case ITEM_APPLY_SDCARD:
      
      	//HACK for "error: a label can only be part of a statement and a declaration is not a statement"
      	//the rule is retarted, the follwing "dummy" statement is cut in optimization
      	override_initial_selection=override_initial_selection; 
      
      	//confirm it	
      	char* confirm_headers[] = { "Confirm installing update package?",
      															 MENU_ITEMS[menu_item],
      															 "",
      															 NULL
      														};
      	char* confirm_items[] = { "Yes", "No", NULL };
      	int confirm_item = show_interactive_menu(confirm_headers, confirm_items);
      	
      	if (confirm_item == 1) //YES!
      	{      	
		      ui_print("\n-- Install from sdcard...\n");
		      ui_led_blink(1);
		      ensure_common_roots_unmounted();
		      ensure_root_path_mounted("SDCARD:");
		      set_sdcard_update_bootloader_message();
		      call_finish_in_loop = 1;
		      int status = install_package(MENU_ITEMS_TARGET[menu_item]);
		      ensure_common_roots_mounted();
		      if (status != INSTALL_SUCCESS) 
		      {
						ui_set_background(BACKGROUND_ICON_ERROR);
						ui_print("Installation aborted.\n");
		      } 
		      else if (!ui_text_visible()) 
	          return;  // reboot if logs aren't visible
		      else 
		      {
		        if (firmware_update_pending()) 
		        {
	        		ui_set_background(BACKGROUND_ICON_ERROR);
	            ui_print("\nReboot via menu to complete\n"
	                     "installation.\n");
		        } 
		        else 
		        {
	        		ui_set_background(BACKGROUND_ICON_ERROR);
	            ui_print("\nInstall from sdcard complete.\n");
		        }
		      }
		      
		      create_menu(menu_files[menu_level], menu_scripts[menu_level]);
		      free(headers);
		      headers = prepend_title(MENU_HEADERS, &title_length);
		      ui_led_toggle(0);
		    }
        
        override_initial_selection = menu_item;											
 				break; 

      case ITEM_SHELL_SCRIPT:
        ui_print("\n-- Shell script...\n");
        ui_print("%s\n", MENU_ITEMS_TARGET[menu_item]);
				ui_led_blink(1);
				ensure_common_roots_mounted();
				
				run_shell_script(MENU_ITEMS_TARGET[menu_item], 1, NULL);
				create_menu(menu_files[menu_level], menu_scripts[menu_level]);
				free(headers);
				headers = prepend_title(MENU_HEADERS, &title_length);
				
				ui_led_toggle(0);
        ui_print("Done.\n");
				
				override_initial_selection = menu_item;											
 				break; 
				
			case ITEM_TAG:
			
				if (MENU_ITEMS_TAG[menu_item] == 0x00)
				{
					int tag_fd = creat(MENU_ITEMS_TARGET[menu_item], 0644);
					if (tag_fd < 0)
						LOGE("Failed to set the tag.\n");
					else
					{
						MENU_ITEMS_TAG[menu_item] = 0x01;
						MENU_ITEMS[menu_item][1] = 'X';
						close(tag_fd);
					}					 
				}
				else if (MENU_ITEMS_TAG[menu_item] == 0x01) //just a little check if 0xFF aint there if bug is present
				{
					remove(MENU_ITEMS_TARGET[menu_item]);
					MENU_ITEMS_TAG[menu_item] = 0x00;
					MENU_ITEMS[menu_item][1] = ' '; 
				}
			
				override_initial_selection = menu_item;											
 				break; 

      case ITEM_NEW_MENU:
				if (menu_level + 1 >= MAX_MENU_LEVEL)
				{
					//too much menus, ignore
					break;
				}
							
				ui_led_blink(1);
				if (!strcmp(MENU_ITEMS_TARGET[menu_item], ".."))
				{
					if (menu_level)
					{
						free(menu_files[menu_level]);
						menu_files[menu_level] = NULL;
						
						if (menu_scripts[menu_level])
						{
							free(menu_scripts[menu_level]);
							menu_scripts[menu_level] = NULL;
						}
						
						menu_sel[menu_level] = 0;
						menu_level--;
						override_initial_selection = menu_sel[menu_level];
					}
				}
				else
				{
					menu_sel[menu_level] = menu_item;
					menu_level++;
					menu_files[menu_level] = malloc(strlen(MENU_ITEMS_TARGET[menu_item]) + 1);
					strcpy(menu_files[menu_level], MENU_ITEMS_TARGET[menu_item]);				
				}
					
				ensure_common_roots_mounted();	
				menu_result = create_menu(menu_files[menu_level], menu_scripts[menu_level]);
				
				//if fail, remove the new menu
				if (menu_result && menu_level)
				{
					free(menu_files[menu_level]);
					menu_files[menu_level] = NULL;
					
					if (menu_scripts[menu_level])
					{
						free(menu_scripts[menu_level]);
						menu_scripts[menu_level] = NULL;
					}
					
					menu_level--;
				}
				
				free(headers);
				headers = prepend_title(MENU_HEADERS, &title_length);
				ui_led_toggle(0);
				break;
			
			case ITEM_NEW_MENU_SCRIPTED:
			
				if (menu_level + 1 >= MAX_MENU_LEVEL)
				{
					//too much menus, ignore
					break;
				}
			
				ui_led_blink(1);
				char cmdBuff[MAX_LINE_LENGTH];
				strcpy(cmdBuff, MENU_ITEMS_TARGET[menu_item]);
				char* ptr;
										
				//menufile:script
				ptr = strtok(cmdBuff, ":");
				if (ptr != NULL)
				{
					menu_sel[menu_level] = menu_item;
					menu_level++;
					menu_files[menu_level] = malloc(strlen(ptr) + 1);
					strcpy(menu_files[menu_level], ptr);						
					
					ptr = strtok(NULL, "");
					if (ptr != NULL)
					{
						if (ptr[0] == '/' || (ptr[0] == '\"' && ptr[1] == '/'))
						{
							menu_scripts[menu_level] = malloc(strlen(ptr) + 1);
							strcpy(menu_scripts[menu_level], ptr);					
						}
						else
						{
							menu_scripts[menu_level] = malloc(strlen(CUSTOM_SHELL_SCRIPT_PATH) + strlen(ptr) + 2);
						
							if (ptr[0] == '\"')
								sprintf(menu_scripts[menu_level], "\"%s/%s", CUSTOM_SHELL_SCRIPT_PATH, ptr+1);
							else
								sprintf(menu_scripts[menu_level], "%s/%s", CUSTOM_SHELL_SCRIPT_PATH, ptr);

						}
					}
					
					ensure_common_roots_mounted();
					menu_result = create_menu(menu_files[menu_level], menu_scripts[menu_level]);
					
					//if fail, remove the new menu
					if (menu_result && menu_level)
					{
						free(menu_files[menu_level]);
						menu_files[menu_level] = NULL;
						
						if (menu_scripts[menu_level])
						{
							free(menu_scripts[menu_level]);
							menu_scripts[menu_level] = NULL;
						}
						
						menu_level--;
					}
					
					free(headers);
					headers = prepend_title(MENU_HEADERS, &title_length);
				}
					
				ui_led_toggle(0);
				break;
			
			case ITEM_CONSOLE:
#if OPEN_RECOVERY_HAVE_CONSOLE
				ensure_common_roots_mounted();
				
				ui_print("Opening console...\n");
				int console_error = run_console(NULL);
				
				if (console_error)
					if (console_error == CONSOLE_FORCE_QUIT)
						ui_print("Console was forcibly closed.\n");
					else if (console_error == CONSOLE_FAILED_START)
						ui_print("Console failed to start.\n");
					else
					{
						ui_print("Closing console...\n"); //don't bother printing error to UI
						fprintf(stderr, "Console closed with error %d.\n", console_error);
					}		
				else
					ui_print("Closing console...\n");
					
				create_menu(menu_files[menu_level], menu_scripts[menu_level]);
				free(headers);
				headers = prepend_title(MENU_HEADERS, &title_length);
#else
				LOGE("This phone doesn't support console.\n");
#endif
				override_initial_selection = menu_item;											
 				break; 
			
			case ITEM_ERROR:
				LOGE("Unknown command: %s.\n", MENU_ITEMS_ACTION[menu_item]);
				break;
    }
  }
}
示例#12
0
int
main(int argc, char **argv)
{
  if (getppid() != 1)
  {
  	fprintf(stderr, "Parent process must be init.\n"); 
		return EXIT_FAILURE;
  }
  
	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 Open Recovery on %s", ctime(&start));

	//menu title
	//lite - just the base
	//full - look for mod
	
#if OPEN_RCVR_VERSION_LITE
	MENU_TITLE = BASE_MENU_TITLE;
#else
	//keep'em malloced even if empty :p
	char* mod_author = malloc(81);
	char* mod_version = malloc(81);
	
	char mod_author_prop[81];
	char mod_version_prop[81];
	
	property_get(MOD_AUTHOR_PROP, mod_author_prop, "");
	property_get(MOD_VERSION_PROP, mod_version_prop, "");
	
	//assume there are some mod properties, leave NULL if there ain't
	MENU_TITLE = malloc((sizeof(BASE_MENU_TITLE) + 3) * sizeof(char*));
	memset(MENU_TITLE, 0, (sizeof(BASE_MENU_TITLE) + 3) * sizeof(char*));
	
	char** b = BASE_MENU_TITLE;
	char** m = MENU_TITLE;
	while (*b)
	{
		*m = *b;
		m++;
		b++;
	}
	
	//append "" if one of the props exist
	int append_empty = 0;	
	
	if (mod_author_prop[0] != '\0')
	{
		//mod version only if mod author
		if (mod_version_prop[0] != '\0')
		{
			snprintf(mod_version, 80, MOD_VERSION_BASE, mod_version_prop);
			*m = mod_version;
			m++;
		}

		snprintf(mod_author, 80, MOD_AUTHOR_BASE, mod_author_prop);
		*m = mod_author;
		m++;
		append_empty = 1;
	}		
			
	if (append_empty)
	{
		*m = malloc(1);
		(*m)[0] = '\0';
		m++;
	}
	
#endif

	ui_init();

	//react on the command
	//full version only checks for it's own command file
	//the rest is done by lite version
#if OPEN_RCVR_VERSION_LITE
	get_args(&argc, &argv);
#else
	argc = 1;
	get_cmd_file_args(&argc, &argv);
#endif
	

	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;

  if (update_package != NULL) 
  {
    status = install_package(update_package);
    if (status != INSTALL_SUCCESS) 
    	ui_print("Installation aborted.\n");
    
    char package_path[PATH_MAX] = "";
    if (!ensure_root_path_mounted(update_package) &&
    		translate_root_path(update_package, package_path, sizeof(package_path)))
    	unlink(package_path);
  } 
  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 OPEN_RCVR_VERSION_LITE
	int or_up_sts = install_package(FULL_PACKAGE_FILE);
  if (or_up_sts != INSTALL_SUCCESS) 
  {
		ui_print("Failed to switch into the full version.\n");
		ui_print("Running Lite version only.\n");
  } 
#endif

	//lite OR doesn't have text visible by default
	//but full OR does

#if OPEN_RCVR_VERSION_LITE
  if (status != INSTALL_SUCCESS) 
  	ui_set_background(BACKGROUND_ICON_ERROR);
  if (status != INSTALL_SUCCESS || ui_text_visible())
  	prompt_and_wait();
#else
	if (status != INSTALL_SUCCESS) 
	{
		ui_set_background(BACKGROUND_ICON_ERROR);
		prompt_and_wait();
	}
#endif

  // 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");
  sync();
  ensure_common_roots_unmounted();
  reboot(RB_AUTOBOOT);
  return EXIT_SUCCESS;
}
示例#13
0
int main(int argc, char **argv)
{
	int interactive = 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));

    ui_init();
    ui_set_background(BACKGROUND_ICON_INSTALLING);

    // djp952 - at least for now I want to see everything
    ui_show_text(1);

    volumes_init("/sbin/recovery.fstab");
    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 toggle_secure_fs = 0;
	
	// TEMP: Dump arguments to see what they look like
	//int index = 0;
	//for(index = 0; index < argc; index++) ui_print("ARG%d = [%s]\n", index, argv[index]);

    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 = 1; break;
        case 'c': wipe_cache = 1; break;
        case 't': ui_show_text(1); break;
        case '?':
            LOGE("Invalid command argument: %c\n", arg);
            continue;
        }
    }

    device_recovery_start();

    //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");
	
	//
	// EXECUTE RECOVERY
	//

	// Automatic: --wipe_data
	if(wipe_data) {
		
		interactive = 0;				// No interactive menu mode
		cmd_wipe_device();				// Wipe the device
	}
	
	// Automatic: --wipe_cache
	if(wipe_cache) {

		interactive = 0;				// No interactive menu mode
		cmd_wipe_cache();				// Wipe the cache
	}
	
	// Interactive
	if(interactive) {
		
		cmd_show_usage();				// Explain how to navigate
		menu_mainmenu();				// Launch the main menu
	}
	
	//
	// FINISH RECOVERY
	//

    // Clean up and write out the logs
    finish_recovery(send_intent);
	
	// Unmount all volumes
	const Volume* iterator = foreach_volume(NULL);
	while(iterator != NULL) {
	
		unmount_volume(iterator, NULL);
		iterator = foreach_volume(iterator);
	}
	
    sync();							// One more sync for good luck
    reboot(RB_AUTOBOOT);			// Reboot
    return EXIT_SUCCESS;			// Done
}
示例#14
0
static void
prompt_and_wait() {
    const char** headers = prepend_title((const char**)MENU_HEADERS);

    for (;;) {
        finish_recovery(NULL);
        ui_reset_progress();

        ui_root_menu = 1;
        // ui_menu_level is a legacy variable that i am keeping around to prevent build breakage.
        ui_menu_level = 0;
        int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, 0);
        ui_menu_level = 1;
        ui_root_menu = 0;

        // device-specific code may take some action here.  It may
        // return one of the core actions handled in the switch
        // statement below.
        chosen_item = device_perform_action(chosen_item);

        int status;
        int ret = 0;

        for (;;) {
            switch (chosen_item) {
                case ITEM_REBOOT:
                    return;

                case ITEM_WIPE_DATA:
                    wipe_data(ui_text_visible());
                    if (!ui_text_visible()) return;
                    break;

                case ITEM_WIPE_CACHE:
                    if (confirm_selection("Confirm wipe?", "Yes - Wipe Cache"))
                    {
                        ui_print("\n-- Wiping cache...\n");
                        erase_volume("/cache");
                        ui_print("Cache wipe complete.\n");
                        if (!ui_text_visible()) return;
                    }
                    break;

                case ITEM_APPLY_ZIP:
                    ret = show_install_update_menu();
                    break;

                case ITEM_NANDROID:
                    ret = show_nandroid_menu();
                    break;

                case ITEM_PARTITION:
                    ret = show_partition_menu();
                    break;

                case ITEM_ADVANCED:
                    ret = show_advanced_menu();
                    break;
            }
            if (ret == REFRESH) {
                ret = 0;
                continue;
            }
            break;
        }
    }
}
示例#15
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;
}
示例#16
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;
        }
        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) {
    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();
    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;

    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_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");
    sync();
    reboot(RB_AUTOBOOT);
    return EXIT_SUCCESS;
}