Beispiel #1
0
void show_nandroid_advanced_backup_menu()
{
    if (ensure_root_path_mounted("SDCARD:") != 0) {
        LOGE ("Can't mount /sdcard\n");
        return;
    }

    static char* headers[] = {  "Nandroid Advanced Backup",
                                "",
                                NULL
    };

    static char* list[] = { "Backup boot",
                            "Backup system",
                            "Backup data",
                            "Backup cache",
                            "Backup sd-ext",
                            NULL
    };

    char backup_path[PATH_MAX];
                time_t t = time(NULL);
                struct tm *tmp = localtime(&t);
                if (tmp == NULL)
                {
                    struct timeval tp;
                    gettimeofday(&tp, NULL);
                    sprintf(backup_path, "/sdcard/clockworkmod/backup/%d", tp.tv_sec);
                }
                else
                {
                    strftime(backup_path, sizeof(backup_path), "/sdcard/clockworkmod/backup/%F.%H.%M.%S", tmp);
                }
    static char* confirm_restore  = "Confirm backup?";

    int chosen_item = get_menu_selection(headers, list, 0);
    switch (chosen_item)
    {
        case 0:
            if (confirm_selection(confirm_restore, "Yes - Backup boot"))
                nandroid_backup_boot(backup_path);
            break;
        case 1:
            if (confirm_selection(confirm_restore, "Yes - Backup system"))
                nandroid_backup_system(backup_path);
            break;
        case 2:
            if (confirm_selection(confirm_restore, "Yes - Backup data"))
                nandroid_backup_data(backup_path);
            break;
        case 3:
            if (confirm_selection(confirm_restore, "Yes - Backup cache"))
                nandroid_backup_cache(backup_path);
            break;
        case 4:
            if (confirm_selection(confirm_restore, "Yes - Backup sd-ext"))
                nandroid_backup_sd(backup_path);;
            break;
    }
}
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;
    return;
}
void show_nandroid_restore_menu()
{
    const char* sdcard_path;
    char* backup_path[PATH_MAX];

    if (target_sdcard == TARGET_INTERNAL_SDCARD) {
        sdcard_path = INTERNAL_SDCARD_PATH;
    } else {
        sdcard_path = EXTERNAL_SDCARD_PATH;
    }

    if (ensure_path_mounted(sdcard_path) != 0) {
        LOGE ("Can't mount %s\n", sdcard_path);
        return;
    }

    static char* headers[] = {  "Choose an image to restore",
                                "",
                                NULL
    };

    sprintf(backup_path, "%s/clockworkmod/backup/", sdcard_path);
    char* file = choose_file_menu(backup_path, NULL, headers);
    if (file == NULL)
        return;

    if (confirm_selection("Confirm restore?", "Yes - Restore"))
        nandroid_restore(file, 1, 1, 1, 1, 1, 0);
}
void show_install_update_menu()
{
    static char* headers[] = {  "Apply update from .zip file on SD card",
                                "",
                                NULL
    };
    for (;;)
    {
        int chosen_item = get_menu_selection(headers, INSTALL_MENU_ITEMS, 0, 0);
        switch (chosen_item)
        {
            case ITEM_ASSERTS:
                toggle_script_asserts();
                break;
            case ITEM_SIG_CHECK:
                toggle_signature_check();
                break;
            case ITEM_APPLY_SDCARD:
            {
                if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
                    install_zip(SDCARD_UPDATE_FILE);
                break;
            }
            case ITEM_CHOOSE_ZIP:
                show_choose_zip_menu();
                break;
            default:
                return;
        }

    }
}
static void
prompt_and_wait() {
    char** headers = prepend_title((const char**)MENU_HEADERS);

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

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

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

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

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

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

            case ITEM_APPLY_SDCARD:
                show_install_update_menu();
                break;

            case ITEM_NANDROID:
                show_nandroid_menu();
                break;

            case ITEM_PARTITION:
                show_partition_menu();
                break;

            case ITEM_ADVANCED:
                show_advanced_menu();
                break;
                
            case ITEM_POWEROFF:
                poweroff = 1;
                return;
        }
    }
}
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;
	return;
}
static int
really_install_package(const char *path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_print("正在查找升级包...\n");
    ui_show_indeterminate_progress();
    LOGI("Update location: %s\n", path);

    if (ensure_path_mounted(path) != 0) {
        LOGE("Can't mount %s\n", path);
        return INSTALL_CORRUPT;
    }

    ui_print("正在打开升级包...\n");

    int err;

    if (signature_check_enabled) {
        int numKeys;
        RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
        if (loadedKeys == NULL) {
            LOGE("Failed to load keys\n");
            return INSTALL_CORRUPT;
        }
        LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);

        // Give verification half the progress bar...
        ui_print("正在校验升级包...\n");
        ui_show_progress(
                VERIFICATION_PROGRESS_FRACTION,
                VERIFICATION_PROGRESS_TIME);

        err = verify_file(path, loadedKeys, numKeys);
        free(loadedKeys);
        LOGI("verify_file returned %d\n", err);
        if (err != VERIFY_SUCCESS) {
            LOGE("signature verification failed\n");
            ui_show_text(1);
            if (!confirm_selection("Install Untrusted Package?", "确认 - 安装不严格的zip卡刷包"))
                return INSTALL_CORRUPT;
        }
    }

    /* Try to open the package.
     */
    ZipArchive zip;
    err = mzOpenZipArchive(path, &zip);
    if (err != 0) {
        LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
        return INSTALL_CORRUPT;
    }

    /* Verify and install the contents of the package.
     */
    ui_print("正在安装更新...\n");
    return try_update_binary(path, &zip);
}
Beispiel #8
0
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");
    erase_volume("/cache");
    ensure_path_mounted("/cache");
    write_string_to_file(UBUNTU_COMMAND_FILE, "format data\n");
    reboot_main_system(ANDROID_RB_RESTART2, 0, "recovery");
}
int verify_root_and_recovery() {
    if (ensure_path_mounted("/system") != 0)
        return 0;

    int ret = 0;
    struct stat st;
    if (0 == lstat("/system/etc/install-recovery.sh", &st)) {
        if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
            ui_show_text(1);
            ret = 1;
            if (confirm_selection("ROM may flash stock recovery on boot. Fix?", "Yes - Disable recovery flash")) {
                __system("chmod -x /system/etc/install-recovery.sh");
            }
        }
    }

    if (0 == lstat("/system/bin/su", &st)) {
        if (S_ISREG(st.st_mode)) {
            if ((st.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("Root access possibly lost. Fix?", "Yes - Fix root (/system/bin/su)")) {
                    __system("chmod 6755 /system/bin/su");
                }
            }
        }
    }

    if (0 == lstat("/system/xbin/su", &st)) {
        if (S_ISREG(st.st_mode)) {
            if ((st.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("Root access possibly lost. Fix?", "Yes - Fix root (/system/xbin/su)")) {
                    __system("chmod 6755 /system/xbin/su");
                }
            }
        }
    }

    ensure_path_unmounted("/system");
    return ret;
}
void show_install_update_menu()
{
    static char* headers[] = {  "从SD卡选择ZIP格式文件进行刷机",
                                "",
                                NULL
    };
    
    char* install_menu_items[] = {  "从SD卡中选择一个ZIP格式刷机包",
                                    "从电脑用ADB载入刷机包",
                                    "直接应用/sdcard/update.zip刷机",
                                    "启用/禁用签名校验",
                                    NULL,
                                    NULL };

    char *other_sd = NULL;
    if (volume_for_path("/emmc") != NULL) {
        other_sd = "/emmc/";
        install_menu_items[4] = "从内置SD卡选择ZIP文件";
    }
    else if (volume_for_path("/external_sd") != NULL) {
        other_sd = "/external_sd/";
        install_menu_items[4] = "从外置SD卡选择ZIP文件";
    }
    
    for (;;)
    {
        int chosen_item = get_menu_selection(headers, install_menu_items, 0, 0);
        switch (chosen_item)
        {
            case ITEM_SIG_CHECK:
                toggle_signature_check();
                break;
            case ITEM_APPLY_UPDATE:
            {
                if (confirm_selection("确认安装?", "是-直接刷入/sdcard/update.zip"))
                    install_zip(SDCARD_UPDATE_FILE);
                break;
            }
            case ITEM_CHOOSE_ZIP:
                show_choose_zip_menu("/sdcard/");
                write_recovery_version();
                break;
            case ITEM_APPLY_SIDELOAD:
                apply_from_adb();
                break;
            case ITEM_CHOOSE_ZIP_INT:
                if (other_sd != NULL)
                    show_choose_zip_menu(other_sd);
                break;
            default:
                return;
        }

    }
}
void show_install_update_menu()
{
    static char* headers[] = {  "Install update from zip file",
                                "",
                                NULL
    };
    
    char* install_menu_items[] = {  "choose zip from sdcard",
                                    "install zip from sideload",
                                    "apply /sdcard/update.zip",
                                    "toggle signature verification",
                                    NULL,
                                    NULL };

    char *other_sd = NULL;
    if (volume_for_path("/emmc") != NULL) {
        other_sd = "/emmc/";
        install_menu_items[4] = "choose zip from internal sdcard";
    }
    else if (volume_for_path("/external_sd") != NULL) {
        other_sd = "/external_sd/";
        install_menu_items[4] = "choose zip from external sdcard";
    }
    
    for (;;)
    {
        int chosen_item = get_menu_selection(headers, install_menu_items, 0, 0);
        switch (chosen_item)
        {
            case ITEM_SIG_CHECK:
                toggle_signature_check();
                break;
            case ITEM_APPLY_UPDATE:
            {
                if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
                    install_zip(SDCARD_UPDATE_FILE);
                break;
            }
            case ITEM_CHOOSE_ZIP:
                show_choose_zip_menu("/sdcard/");
                write_recovery_version();
                break;
            case ITEM_APPLY_SIDELOAD:
                apply_from_adb();
                break;
            case ITEM_CHOOSE_ZIP_INT:
                if (other_sd != NULL)
                    show_choose_zip_menu(other_sd);
                break;
            default:
                return;
        }

    }
}
void apply_root_menu() {
    static char* headers[] = {  "Install superuser",
                                "",
                                NULL
    };

    static char* list[] = { "Simple: install busybox+su",
                            "Adv: also rm some toolbox cmds",
                            "Ext: also rm most toolbox cmds",
                            NULL
    };

    for (;;)
    {
        int chosen_item = get_menu_selection(headers, list, 0);
        if (chosen_item == GO_BACK)
            break;
        switch (chosen_item)
        {
            case 0:
              if (confirm_selection("Confirm root","Yes - apply root to device")) {
                apply_root_to_device(0);
              }
              break;
            case 1:
              if (confirm_selection("Confirm root","Yes - apply root to device")) {
                apply_root_to_device(1);
              }
              break;
            case 2:
              if (confirm_selection("Confirm root","Yes - apply root to device")) {
                apply_root_to_device(2);
              }
              break;
        }
    }

}
Beispiel #13
0
void updatemenu()
{

static char* headers[] = {  "Update Menu",
                                "",
                                NULL
    };

 static char* list[] = { "~~~> Go Back <~~~",
			 "Update.zip from Sdcard",
                         "Select .zip from Sdcard",
                         "Toggle Signature Verification",
                         "Toggle Script Asserts",
                            NULL
};

for (;;)
    {
        int chosen_item = get_menu_selection(headers, list, 0);
	if (chosen_item == GO_BACK)
            break;
	switch (chosen_item)
	{
		case 0:
		{
		return;
		break;
		}
		case 1:
		 {
                if (confirm_selection("Confirm install?", "Yes - Install /sdcard/update.zip"))
                    install_zip(SDCARD_PACKAGE_FILE);
                break;
            }
		case 2:
		{
		show_choose_zip_menu();
                break;
		}
		case 3:
		 toggle_signature_check();
                break;
		case 4:
		toggle_script_asserts();
		break;
	}
     }
}
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");
}
Beispiel #15
0
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");
}
Beispiel #16
0
/* On recovery exit, check if there is a settings file (PHILZ_SETTINGS_FILE)
   if not, try to restore the copy we do on primary storage (PHILZ_SETTINGS_FILE2)
 * Also, if no copy is found, always create it if there is a settings file
   we shouldn't always copy settings file on exit to avoid loosing user config after a wipe if he just change brightness by error for exp...

 Function is called when rebooting
 After success install of a new rom, before reboot, it will preserve settings if they were wiped by installed ROM
*/
void verify_settings_file() {
    char settings_copy[PATH_MAX];
    sprintf(settings_copy, "%s/%s", get_primary_storage_path(), PHILZ_SETTINGS_FILE2);

    // always have a copy of settings file in primary storage
    if (file_found(PHILZ_SETTINGS_FILE) && !file_found(settings_copy))
        copy_a_file(PHILZ_SETTINGS_FILE, settings_copy);

    // restore settings from the copy if needed (after a wipe)
    if (!file_found(PHILZ_SETTINGS_FILE) && file_found(settings_copy)) {
        ui_SetShowText(true);
        if (!auto_restore_settings.value && !confirm_selection("Restore recovery settings?", "Yes - Restore from sdcard"))
            return;
        if (copy_a_file(settings_copy, PHILZ_SETTINGS_FILE) == 0)
            ui_print("Recovery settings restored.\n");
    }
}
void show_nandroid_restore_menu(const char* volume)
{
    if (ensure_path_mounted(volume) != 0) {
        LOGE ("Can't mount %s\n", volume);
        return;
    }

    int restore_webtop = 1;
    static char* headers[] = {  "Choose an image to restore",
                                "",
                                NULL
    };

    char backup_path[PATH_MAX];
    sprintf(backup_path, "%s/clockworkmod/backup/", volume);
    char* file = choose_file_menu(backup_path, NULL, headers);
    if (file == NULL)
        return;

#ifdef BOARD_HAS_WEBTOP
    static char* header[] = {  "Include webtop in restore?",
                               "",
                               NULL
    };

    static char* list[] = {  "Yes",
                             "No",
                             NULL
    };

    switch (get_menu_selection(header, list, 0, 0))
    {
        case 0:
            restore_webtop = 1;
            break;
        case 1:
            restore_webtop = 0;
            break;
        default:
            return;
    }
#endif

    if (confirm_selection("Confirm restore?", "Yes - Restore"))
        nandroid_restore(file, 1, 1, 1, 1, restore_webtop, 0, restore_webtop, 0);
}
void erase_dalvik_cache(int orscallback) {
	if(orscallback && orswipeprompt && !confirm_selection("Confirm wipe?","Yes- Wipe Dalvik Cache")) {
		ui_print("Skipping dalvik cache wipe...\n");
		return;
	}
	if (0 != ensure_path_mounted("/data"))
		return;

	ensure_path_mounted("/sd-ext");
	ensure_path_mounted("/cache");

	__system("rm -r /data/dalvik-cache");
	__system("rm -r /cache/dalvik-cache");
	__system("rm -r /sd-ext/dalvik-cache");
	ui_print("Dalvik Cache wiped.\n");

	ensure_path_unmounted("/data");
	return;
}
void show_nandroid_restore_menu()
{
    if (ensure_path_mounted("/sdcard") != 0) {
        LOGE ("Can't mount /sdcard\n");
        return;
    }

    static char* headers[] = {  "Choose an image to restore",
                                "",
                                NULL
    };

    char* file = choose_file_menu("/sdcard/clockworkmod/backup/", NULL, headers);
    if (file == NULL)
        return;

    if (confirm_selection("Confirm restore?", "Yes - Restore"))
        nandroid_restore(file, 1, 1, 1, 1, 1, 0);
}
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");
}
void device_toggle_truedualboot(void) {
	char confirm[PATH_MAX];
	int enable = dualboot_is_tdb_enabled();

#ifndef PHILZ_TOUCH_RECOVERY
	ui_setMenuTextColor(MENU_TEXT_COLOR_RED);
#endif

	sprintf(confirm, "Yes - %s TrueDualBoot", enable?"DISABLE":"ENABLE");

	if (confirm_selection("This will WIPE DATA. Confirm?", confirm)) {
		// unmount /data
		if(ensure_path_unmounted("/data")!=0) {
			LOGE("Error unmounting /data!\n");
			return;
		}

		// format /data
		ui_set_background(BACKGROUND_ICON_INSTALLING);
		ui_show_indeterminate_progress();
		ui_print("Formatting /data...\n");
		set_force_raw_format_enabled(1);
		if(format_volume("/data")!=0) {
			ui_print("Error formatting /data!\n");
			ui_reset_progress();
			return;
		}
		ui_reset_progress();
		set_force_raw_format_enabled(0);
		ui_print("Done.\n");

		// toggle
		dualboot_set_tdb_enabled(!enable);
	}

#ifndef PHILZ_TOUCH_RECOVERY
	ui_setMenuTextColor(MENU_TEXT_COLOR);
#endif

	return;
}
void show_nandroid_restore_menu(const char* path)
{
    if (ensure_path_mounted(path) != 0) {
        LOGE("Can't mount %s\n", path);
        return;
    }

    static char* headers[] = {  "Choose an image to restore",
                                "",
                                NULL
    };

    char tmp[PATH_MAX];
    sprintf(tmp, "%s/clockworkmod/backup/", path);
    char* file = choose_file_menu(tmp, NULL, headers);
    if (file == NULL)
        return;

    if (confirm_selection("Confirm restore?", "Yes - Restore"))
        nandroid_restore(file, 1, 1, 1, 1, 1, 0);
}
void show_choose_zip_menu(const char *mount_point)
{
    if (ensure_path_mounted(mount_point) != 0) {
        LOGE ("Can't mount %s\n", mount_point);
        return;
    }

    static char* headers[] = {  "Choose a zip to apply",
                                "",
                                NULL
    };

    char* file = choose_file_menu(mount_point, ".zip", headers);
    if (file == NULL)
        return;
    static char* confirm_install  = "Confirm install?";
    static char confirm[PATH_MAX];
    sprintf(confirm, "Yes - Install %s", basename(file));
    if (confirm_selection(confirm_install, confirm))
        install_zip(file);
}
void show_choose_zip_menu(const char *mount_point)
{
    if (ensure_path_mounted(mount_point) != 0) {
        LOGE ("无法挂载 %s\n", mount_point);
        return;
    }

    static char* headers[] = {  "选择一个ZIP格式刷机包",
                                "",
                                NULL
    };

    char* file = choose_file_menu(mount_point, ".zip", headers);
    if (file == NULL)
        return;
    static char* confirm_install  = "确认安装?";
    static char confirm[PATH_MAX];
    sprintf(confirm, "是-刷入%s", basename(file));
    if (confirm_selection(confirm_install, confirm))
        install_zip(file);
}
void show_nandroid_restore_menu(const char* path)
{
    if (ensure_path_mounted(path) != 0) {
        LOGE("无法挂载 %s\n", path);
        return;
    }

    static char* headers[] = {  "选择恢复镜像",
                                "",
                                NULL
    };

    char tmp[PATH_MAX];
    sprintf(tmp, "%s/clockworkmod/backup/", path);
    char* file = choose_file_menu(tmp, NULL, headers);
    if (file == NULL)
        return;

    if (confirm_selection("确认恢复?", "是 - 恢复"))
        nandroid_restore(file, 1, 1, 1, 1, 1, 0);
}
void show_nandroid_delete_menu(const char* path)
{
    if (ensure_path_mounted(path) != 0) {
        LOGE("无法挂载 %s\n", path);
        return;
    }

    static char* headers[] = {  "选择删除镜像",
                                "",
                                NULL
    };

    char tmp[PATH_MAX];
    sprintf(tmp, "%s/clockworkmod/backup/", path);
    char* file = choose_file_menu(tmp, NULL, headers);
    if (file == NULL)
        return;

    if (confirm_selection("确认删除?", "是 - 删除")) {
        // nandroid_restore(file, 1, 1, 1, 1, 1, 0);
        sprintf(tmp, "rm -rf %s", file);
        __system(tmp);
    }
}
void show_choose_zip_menu()
{
    if (ensure_root_path_mounted("SDCARD:") != 0) {
        LOGE ("Can't mount /sdcard\n");
        return;
    }

    static char* headers[] = {  "Choose a zip to apply",
                                "",
                                NULL 
    };
    
    char* file = choose_file_menu("/sdcard/", ".zip", headers);
    if (file == NULL)
        return;
    char sdcard_package_file[1024];
    strcpy(sdcard_package_file, "SDCARD:");
    strcat(sdcard_package_file,  file + strlen("/sdcard/"));
    static char* confirm_install  = "Confirm install?";
    static char confirm[PATH_MAX];
    sprintf(confirm, "Yes - Install %s", basename(file));
    if (confirm_selection(confirm_install, confirm))
        install_zip(sdcard_package_file);
}
void show_nandroid_advanced_restore_menu(const char* path)
{
    if (ensure_path_mounted(path) != 0) {
        LOGE ("Can't mount sdcard\n");
        return;
    }

    static char* advancedheaders[] = {  "Choose an image to restore",
                                "",
                                "Choose an image to restore",
                                "first. The next menu will",
                                "show you more options.",
                                "",
                                NULL
    };

    char tmp[PATH_MAX];
    sprintf(tmp, "%s/clockworkmod/backup/", path);
    char* file = choose_file_menu(tmp, NULL, advancedheaders);
    if (file == NULL)
        return;

    static char* headers[] = {  "Advanced Restore",
                                "",
                                NULL
    };

    static char* list[] = { "Restore boot",
                            "Restore system",
                            "Restore data",
                            "Restore cache",
                            "Restore sd-ext",
                            "Restore wimax",
                            NULL
    };
    
    if (0 != get_partition_device("wimax", tmp)) {
        // disable wimax restore option
        list[5] = NULL;
    }

    static char* confirm_restore  = "Confirm restore?";

    int chosen_item = get_menu_selection(headers, list, 0, 0);
    switch (chosen_item)
    {
        case 0:
            if (confirm_selection(confirm_restore, "Yes - Restore boot"))
                nandroid_restore(file, 1, 0, 0, 0, 0, 0);
            break;
        case 1:
            if (confirm_selection(confirm_restore, "Yes - Restore system"))
                nandroid_restore(file, 0, 1, 0, 0, 0, 0);
            break;
        case 2:
            if (confirm_selection(confirm_restore, "Yes - Restore data"))
                nandroid_restore(file, 0, 0, 1, 0, 0, 0);
            break;
        case 3:
            if (confirm_selection(confirm_restore, "Yes - Restore cache"))
                nandroid_restore(file, 0, 0, 0, 1, 0, 0);
            break;
        case 4:
            if (confirm_selection(confirm_restore, "Yes - Restore sd-ext"))
                nandroid_restore(file, 0, 0, 0, 0, 1, 0);
            break;
        case 5:
            if (confirm_selection(confirm_restore, "Yes - Restore wimax"))
                nandroid_restore(file, 0, 0, 0, 0, 0, 1);
            break;
    }
}
void show_partition_menu()
{
    static char* headers[] = {  "Mounts and Storage Menu",
                                "",
                                NULL
    };

    static MountMenuEntry* mount_menu = NULL;
    static FormatMenuEntry* format_menu = NULL;

    typedef char* string;

    int i, mountable_volumes, formatable_volumes;
    int num_volumes;
    Volume* device_volumes;

    num_volumes = get_num_volumes();
    device_volumes = get_device_volumes();

    string options[255];

    if(!device_volumes)
        return;

    mountable_volumes = 0;
    formatable_volumes = 0;

    mount_menu = malloc(num_volumes * sizeof(MountMenuEntry));
    format_menu = malloc(num_volumes * sizeof(FormatMenuEntry));

    for (i = 0; i < num_volumes; ++i) {
        Volume* v = &device_volumes[i];
        if(strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) != 0 && strcmp("emmc", v->fs_type) != 0 && strcmp("bml", v->fs_type) != 0) {
            if (strcmp("datamedia", v->fs_type) != 0) {
                sprintf(&mount_menu[mountable_volumes].mount, "mount %s", v->mount_point);
                sprintf(&mount_menu[mountable_volumes].unmount, "unmount %s", v->mount_point);
                mount_menu[mountable_volumes].v = &device_volumes[i];
                ++mountable_volumes;
            }
            if (is_safe_to_format(v->mount_point)) {
                sprintf(&format_menu[formatable_volumes].txt, "format %s", v->mount_point);
                format_menu[formatable_volumes].v = &device_volumes[i];
                ++formatable_volumes;
            }
        }
        else if (strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) == 0 && is_safe_to_format(v->mount_point))
        {
            sprintf(&format_menu[formatable_volumes].txt, "format %s", v->mount_point);
            format_menu[formatable_volumes].v = &device_volumes[i];
            ++formatable_volumes;
        }
    }

    static char* confirm_format  = "Confirm format?";
    static char* confirm = "Yes - Format";
    char confirm_string[255];

    for (;;)
    {
        for (i = 0; i < mountable_volumes; i++)
        {
            MountMenuEntry* e = &mount_menu[i];
            Volume* v = e->v;
            if(is_path_mounted(v->mount_point))
                options[i] = e->unmount;
            else
                options[i] = e->mount;
        }

        for (i = 0; i < formatable_volumes; i++)
        {
            FormatMenuEntry* e = &format_menu[i];

            options[mountable_volumes+i] = e->txt;
        }

        if (!is_data_media()) {
          options[mountable_volumes + formatable_volumes] = "mount USB storage";
          options[mountable_volumes + formatable_volumes + 1] = NULL;
        }
        else {
          options[mountable_volumes + formatable_volumes] = "format /data and /data/media (/sdcard)";
          options[mountable_volumes + formatable_volumes + 1] = NULL;
        }

        int chosen_item = get_menu_selection(headers, &options, 0, 0);
        if (chosen_item == GO_BACK)
            break;
        if (chosen_item == (mountable_volumes+formatable_volumes)) {
            if (!is_data_media()) {
                show_mount_usb_storage_menu();
            }
            else {
                if (!confirm_selection("format /data and /data/media (/sdcard)", confirm))
                    continue;
                ignore_data_media_workaround(1);
                ui_print("Formatting /data...\n");
                if (0 != format_volume("/data"))
                    ui_print("Error formatting /data!\n");
                else
                    ui_print("Done.\n");
                ignore_data_media_workaround(0);
            }
        }
        else if (chosen_item < mountable_volumes) {
            MountMenuEntry* e = &mount_menu[chosen_item];
            Volume* v = e->v;

            if (is_path_mounted(v->mount_point))
            {
                if (0 != ensure_path_unmounted(v->mount_point))
                    ui_print("Error unmounting %s!\n", v->mount_point);
            }
            else
            {
                if (0 != ensure_path_mounted(v->mount_point))
                    ui_print("Error mounting %s!\n",  v->mount_point);
            }
        }
        else if (chosen_item < (mountable_volumes + formatable_volumes))
        {
            chosen_item = chosen_item - mountable_volumes;
            FormatMenuEntry* e = &format_menu[chosen_item];
            Volume* v = e->v;

            sprintf(confirm_string, "%s - %s", v->mount_point, confirm_format);

            if (!confirm_selection(confirm_string, confirm))
                continue;
            ui_print("Formatting %s...\n", v->mount_point);
            if (0 != format_volume(v->mount_point))
                ui_print("Error formatting %s!\n", v->mount_point);
            else
                ui_print("Done.\n");
        }
    }

    free(mount_menu);
    free(format_menu);
}
int verify_root_and_recovery() {
    if (ensure_path_mounted("/system") != 0)
        return 0;

    int ret = 0;
    struct stat st;
    // check to see if install-recovery.sh is going to clobber recovery
    // install-recovery.sh is also used to run the su daemon on stock rom for 4.3+
    // so verify that doesn't exist...
    if (0 != lstat("/system/etc/.installed_su_daemon", &st)) {
        // check install-recovery.sh exists and is executable
        if (0 == lstat("/system/etc/install-recovery.sh", &st)) {
            if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("ROM may flash stock recovery on boot. Fix?", "Yes - Disable recovery flash")) {
                    __system("chmod -x /system/etc/install-recovery.sh");
                }
            }
        }
    }


    int exists = 0;
    if (0 == lstat("/system/bin/su", &st)) {
        exists = 1;
        if (S_ISREG(st.st_mode)) {
            if ((st.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("Root access possibly lost. Fix?", "Yes - Fix root (/system/bin/su)")) {
                    __system("chmod 6755 /system/bin/su");
                }
            }
        }
    }

    if (0 == lstat("/system/xbin/su", &st)) {
        exists = 1;
        if (S_ISREG(st.st_mode)) {
            if ((st.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID)) {
                ui_show_text(1);
                ret = 1;
                if (confirm_selection("Root access possibly lost. Fix?", "Yes - Fix root (/system/xbin/su)")) {
                    __system("chmod 6755 /system/xbin/su");
                }
            }
        }
    }

    if (!exists) {
        ui_show_text(1);
        ret = 1;
        if (confirm_selection("Root access is missing. Root device?", "Yes - Root device (/system/xbin/su)")) {
            __system("/sbin/install-su.sh");
        }
    }

    ensure_path_unmounted("/system");
    return ret;
}