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

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

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

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

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

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

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

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

    ui_print("\n-- 清空 data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("所有数据清空完毕.\n");
}
static void
prompt_and_wait() {
  char** headers = prepend_title((const char**)MENU_HEADERS);
  int select = 0;

  for (;;) {
    ui_reset_progress();
    int chosen_item = get_menu_selection(headers, MENU_ITEMS, 0, select);

    // 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_BOOT:
        if (show_menu_boot()) return; else break;
      case ITEM_SYSTEM:
        if (show_menu_system()) return; else break;
      case ITEM_RECOVERY:
        if (show_menu_recovery()) return; else break;
      case ITEM_TOOLS:
        if (show_menu_tools()) return; else break;
      case ITEM_REBOOT:
        ui_print("Reboot now....\n");
        sync();
        reboot(RB_AUTOBOOT);
        return;
    }
    select = chosen_item;
  }
}
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;
        }
    }
}
Пример #5
0
void root_menu(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

        if (title_headers == NULL) {
            char* headers[] = { "ROOT installed ROM?",
								" ",
                                "Rooting without the superuser app installed",
                                "does nothing. Please install the superuser app",
								"from the market! (by ChainsDD)",
								" ",
                                NULL };
            title_headers = prepend_title(headers);
        }

        char* items[] = { " No",
                          " OK, give me root!",
                          NULL };

        int chosen_item = get_menu_selection(title_headers, items, 1, 0);
        if (chosen_item != 1) {
            return;
        }
    }
	char* argv[] = { "/sbin/actroot",
	NULL };

    char* envp[] = { NULL };
	
	ensure_root_path_mounted("SYSTEM:");
	remove("/system/recovery-from-boot.p");
    int status = runve("/sbin/actroot",argv,envp,1);
	ensure_root_path_unmounted("SYSTEM:");
	return;
}
Пример #6
0
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

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

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

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

    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sdcard/.android_secure");
    ui_print("Data wipe complete.\n");
}
static void headless_wait() {
  ui_show_text(0);
  char** headers = prepend_title((const char**)MENU_HEADERS);
  for (;;) {
    finish_recovery(NULL);
    get_menu_selection(headers, MENU_ITEMS, 0, 0);
  }
}
Пример #8
0
static void
prompt_and_wait() {
    char** headers = prepend_title(MENU_HEADERS);

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

        int chosen_item = get_menu_selection(headers, MENU_ITEMS, 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:
                return;

            case ITEM_APPLY_SDCARD:
                show_install_update_menu();
                /*
                ui_print("\n-- Install from sdcard...\n");
                set_sdcard_update_bootloader_message();
                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_WIPE_DATA:
                wipe_data(ui_text_visible());
                if (!ui_text_visible()) return;
                break;

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

            case ITEM_ADVANCED:
		show_advanced_menu();
                break;

         }
    }
}
Пример #9
0
void
nandroid_menu()
{	
	// define constants for menu selection
#define ITEM_BACKUP_MENU         0
#define ITEM_RESTORE_MENU        1
#define ITEM_MENU_RBOOT 	     2
#define ITEM_MENU_BACK           3
	
	// build headers and items in menu
	char* nan_headers[] = { "Nandroid Menu",
							"Choose Backup or Restore:",
							NULL };
	
	char* nan_items[] = { "Backup Partitions",
						  "Restore Partitions",
						  "--> Reboot System",
						  "<-- Back To Main Menu",
						  NULL };
	
	char** headers = prepend_title(nan_headers);
	
	int chosen_item;
    inc_menu_loc(ITEM_MENU_BACK); // record back selection into array
	for (;;)
	{
         ui_set_background(BACKGROUND_ICON_NANDROID);
		chosen_item = get_menu_selection(headers, nan_items, 0, 0);
		switch (chosen_item)
		{
			case ITEM_BACKUP_MENU:
				nan_backup_menu(0);
				break;
			case ITEM_RESTORE_MENU:
                choose_backup_folder();
				break;
			case ITEM_MENU_RBOOT:
				tw_reboot();
                break;
			case ITEM_MENU_BACK:
				dec_menu_loc();
                ui_set_background(BACKGROUND_ICON_MAIN);
				return;
		}
	    if (go_home) { 		// if home was called
	        dec_menu_loc();
                ui_set_background(BACKGROUND_ICON_MAIN);
	        return;
	    }
	}
}
static void
prompt_and_wait() {
    char** headers = prepend_title((const char**)MENU_HEADERS);

    for (;;) {
        finish_recovery(NULL);
        ui_reset_progress();
        
        ui_menu_level = -1;
        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:
                show_reboot_menu();
                break;

            case ITEM_WIPE_MENU:
                show_wipe_menu();
                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;
        }
    }
}
Пример #11
0
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);

        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:
                printf("\n-- Wiping cache...\n");
                erase_volume("/cache");
                printf("Cache wipe complete.\n");
                if (!ui_text_visible()) return;
                break;

            case ITEM_APPLY_SDCARD:
                ;
                int status = sdcard_directory(SDCARD_ROOT);
                if (status >= 0) {
                    if (status != INSTALL_SUCCESS) {
                        ui_set_background(BACKGROUND_ICON_ERROR);
                        printf("Installation aborted.\n");
                    } else if (!ui_text_visible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        printf("\nInstall from sdcard complete.\n");
                    }
                }
                break;
        }
    }
}
Пример #12
0
void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

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

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

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

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

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

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

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

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

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

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

    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_root("DATA:");
#ifdef BOARD_HAS_DATADATA
    erase_root("DATADATA:");
#endif
    erase_root("CACHE:");
    erase_root("SDEXT:");
    erase_root("SDCARD:/.android_secure");
    ui_print("Data wipe complete.\n");
}
Пример #15
0
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

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

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

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

    ui_print("\n-- 清除数据中 \n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("已经抹掉数据\n");
}
Пример #16
0
static void
wipe_data(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

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

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

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

    ui_print("\n-- 正在清空用户数据...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    erase_volume("/sd-ext");
    erase_volume("/sdcard/.android_secure");
    ui_print("清空完毕\n");
}
Пример #17
0
int show_interactive_menu(char** headers, char** items)
{
	int title_length;
	int item_length;
	char** title, **p;
	unsigned char* selectability;
	
	title = prepend_title(headers, &title_length);
	
	item_length = 0;
	for (p = items; *p; ++p, ++item_length);
	
	selectability = malloc(item_length);
	memset(selectability, 1, item_length);
	
	int chosen_item = get_menu_selection(title, items, selectability, title_length, 0, 1);
  hide_menu_selection();
  
  free(selectability);
  free(title);
  return chosen_item + 1;
}
Пример #18
0
static void
wipe_data(int confirm, Device* device) {
    if (confirm) {
        static const char** title_headers = NULL;

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

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

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

    ui->Print("\n-- Wiping data...\n");
    device->WipeData();
    erase_volume("/data");
    erase_volume("/cache");
    erase_persistent_partition();
    ui->Print("Data wipe complete.\n");
}
Пример #19
0
static void choose_recovery_file(Device* device) {
    int i;
    static const char** title_headers = NULL;
    char *filename;
    const char* headers[] = { "Select file to view",
                              "",
                              NULL };
    char* entries[KEEP_LOG_COUNT + 2];
    memset(entries, 0, sizeof(entries));

    for (i = 0; i < KEEP_LOG_COUNT; i++) {
        char *filename;
        if (asprintf(&filename, (i==0) ? LAST_LOG_FILE : (LAST_LOG_FILE ".%d"), i) == -1) {
            // memory allocation failure - return early. Should never happen.
            return;
        }
        if ((ensure_path_mounted(filename) != 0) || (access(filename, R_OK) == -1)) {
            free(filename);
            entries[i+1] = NULL;
            break;
        }
        entries[i+1] = filename;
    }

    entries[0] = strdup("Go back");
    title_headers = prepend_title((const char**)headers);

    while(1) {
        int chosen_item = get_menu_selection(title_headers, entries, 1, 0, device);
        if (chosen_item == 0) break;
        file_to_ui(entries[chosen_item]);
    }

    for (i = 0; i < KEEP_LOG_COUNT + 1; i++) {
        free(entries[i]);
    }
}
Пример #20
0
static void
wipe_media(int confirm) {
    if (confirm) {
        static char** title_headers = NULL;

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

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

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

    ui_print("\n-- Wiping media...\n");
    erase_volume(MEDIA_ROOT);
    ui_print("Media wipe complete.\n");
}
static void
prompt_and_wait(Device* device, int status) {
    const char* const* headers = prepend_title(device->GetMenuHeaders());

    for (;;) {
        finish_recovery(NULL);
        switch (status) {
            case INSTALL_SUCCESS:
            case INSTALL_NONE:
                ui->SetBackground(RecoveryUI::NO_COMMAND);
                break;

            case INSTALL_ERROR:
            case INSTALL_CORRUPT:
                ui->SetBackground(RecoveryUI::ERROR);
                break;
        }
        ui->SetProgressType(RecoveryUI::EMPTY);

        int chosen_item = get_menu_selection(headers, device->GetMenuItems(), 0, 0, device);

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

        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->Print("\n-- Wiping cache...\n");
                erase_volume("/cache");
                ui->Print("Cache wipe complete.\n");
                if (!ui->IsTextVisible()) return;
                break;

            case Device::APPLY_EXT:
                status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &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 sdcard complete.\n");
                    }
                }
                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:
                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");
                        copy_logs();
                    } else if (!ui->IsTextVisible()) {
                        return;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from ADB complete.\n");
                    }
                }
                break;
        }
    }
}
Пример #22
0
void
nan_backup_menu(int pIdx)
{
	tw_total = 0;
	char* nan_b_headers[] = { "Nandroid Backup",
							   "Choose Backup Options:",
							   NULL	};
	
	char* nan_b_items[] = { "--> Backup Naowz!",
							 nan_img_set(ITEM_NAN_SYSTEM,0),
							 nan_img_set(ITEM_NAN_DATA,0),
							 nan_img_set(ITEM_NAN_BOOT,0),
							 nan_img_set(ITEM_NAN_RECOVERY,0),
							 nan_img_set(ITEM_NAN_CACHE,0),
							 nan_img_set(ITEM_NAN_WIMAX,0),
							 nan_img_set(ITEM_NAN_ANDSEC,0),
							 nan_img_set(ITEM_NAN_SDEXT,0),
							 nan_compress(),
							 "<-- Back To Nandroid Menu",
							 NULL };

	char** headers = prepend_title(nan_b_headers);
	
    inc_menu_loc(ITEM_NAN_BACK);
	for (;;) {
		int chosen_item = get_menu_selection(headers, nan_b_items, 0, pIdx); // get key presses
		pIdx = chosen_item; // remember last selection location
		switch (chosen_item) {
			case ITEM_NAN_BACKUP:
				if (tw_total > 0) {
					nandroid_back_exe();
					dec_menu_loc();
					return;
				}
				break;
			case ITEM_NAN_SYSTEM:
            	if (DataManager_GetIntValue(TW_NANDROID_SYSTEM_VAR)) {
            		DataManager_SetIntValue(TW_NANDROID_SYSTEM_VAR, 0); // toggle's value
            		tw_total--; // keeps count of how many selected
            	} else {
            		DataManager_SetIntValue(TW_NANDROID_SYSTEM_VAR, 1);
            		tw_total++;
            	}
                break;
			case ITEM_NAN_DATA:
            	if (DataManager_GetIntValue(TW_NANDROID_DATA_VAR)) {
            		DataManager_SetIntValue(TW_NANDROID_DATA_VAR, 0);
            		tw_total--;
            	} else {
            		DataManager_SetIntValue(TW_NANDROID_DATA_VAR, 1);
            		tw_total++;
            	}
				break;
			case ITEM_NAN_BOOT:
            	if (DataManager_GetIntValue(TW_NANDROID_BOOT_VAR)) {
            		DataManager_SetIntValue(TW_NANDROID_BOOT_VAR, 0);
            		tw_total--;
            	} else {
            		DataManager_SetIntValue(TW_NANDROID_BOOT_VAR, 1);
            		tw_total++;
            	}
				break;
			case ITEM_NAN_RECOVERY:
            	if (DataManager_GetIntValue(TW_NANDROID_RECOVERY_VAR)) {
            		DataManager_SetIntValue(TW_NANDROID_RECOVERY_VAR, 0);
            		tw_total--;
            	} else {
            		DataManager_SetIntValue(TW_NANDROID_RECOVERY_VAR, 1);
            		tw_total++;
            	}
				break;
			case ITEM_NAN_CACHE:
            	if (DataManager_GetIntValue(TW_NANDROID_CACHE_VAR)) {
            		DataManager_SetIntValue(TW_NANDROID_CACHE_VAR, 0);
            		tw_total--;
            	} else {
            		DataManager_SetIntValue(TW_NANDROID_CACHE_VAR, 1);
            		tw_total++;
            	}
				break;
			case ITEM_NAN_WIMAX:
				if (tw_nan_wimax_x != -1) {
	            	if (DataManager_GetIntValue(TW_NANDROID_WIMAX_VAR)) {
	            		DataManager_SetIntValue(TW_NANDROID_WIMAX_VAR, 0);
	            		tw_total--;
	            	} else {
	            		DataManager_SetIntValue(TW_NANDROID_WIMAX_VAR, 1);
	            		tw_total++;
	            	}
				}
				break;
			case ITEM_NAN_ANDSEC:
				if (tw_nan_andsec_x != -1) {
	            	if (DataManager_GetIntValue(TW_NANDROID_ANDSEC_VAR)) {
	            		DataManager_SetIntValue(TW_NANDROID_ANDSEC_VAR, 0);
	            		tw_total--;
	            	} else {
	            		DataManager_SetIntValue(TW_NANDROID_ANDSEC_VAR, 1);
	            		tw_total++;
	            	}
				}
				break;
			case ITEM_NAN_SDEXT:
				if (tw_nan_sdext_x != -1) {
	            	if (DataManager_GetIntValue(TW_NANDROID_SDEXT_VAR)) {
	            		DataManager_SetIntValue(TW_NANDROID_SDEXT_VAR, 0);
	            		tw_total--;
	            	} else {
	            		DataManager_SetIntValue(TW_NANDROID_SDEXT_VAR, 1);
	            		tw_total++;
	           		}
				}
				break;
			case ITEM_NAN_COMPRESS:
            	DataManager_ToggleIntValue(TW_USE_COMPRESSION_VAR);
				break;
			case ITEM_NAN_BACK:
            	dec_menu_loc();
				return;
		}
	    if (go_home) { 
	        dec_menu_loc();
	        return;
	    }
		break;
	}
	ui_end_menu(); // end menu
    dec_menu_loc(); // decrease menu location
	nan_backup_menu(pIdx); // restart menu (to refresh it)
}
static int
update_directory(const char* path, const char* unmount_when_done,
                 int* wipe_cache, Device* device) {
    ensure_path_mounted(path);

    const char* MENU_HEADERS[] = { "Choose a package to install:",
                                   path,
                                   "",
                                   NULL };
    DIR* d;
    struct dirent* de;
    d = opendir(path);
    if (d == NULL) {
        LOGE("error opening %s: %s\n", path, strerror(errno));
        if (unmount_when_done != NULL) {
            ensure_path_unmounted(unmount_when_done);
        }
        return 0;
    }

    const char** headers = prepend_title(MENU_HEADERS);

    int d_size = 0;
    int d_alloc = 10;
    char** dirs = (char**)malloc(d_alloc * sizeof(char*));
    int z_size = 1;
    int z_alloc = 10;
    char** zips = (char**)malloc(z_alloc * sizeof(char*));
    zips[0] = strdup("../");

    while ((de = readdir(d)) != NULL) {
        int name_len = strlen(de->d_name);

        if (de->d_type == DT_DIR) {
            // skip "." and ".." entries
            if (name_len == 1 && de->d_name[0] == '.') continue;
            if (name_len == 2 && de->d_name[0] == '.' &&
                de->d_name[1] == '.') continue;

            if (d_size >= d_alloc) {
                d_alloc *= 2;
                dirs = (char**)realloc(dirs, d_alloc * sizeof(char*));
            }
            dirs[d_size] = (char*)malloc(name_len + 2);
            strcpy(dirs[d_size], de->d_name);
            dirs[d_size][name_len] = '/';
            dirs[d_size][name_len+1] = '\0';
            ++d_size;
        } else if (de->d_type == DT_REG &&
                   name_len >= 4 &&
                   strncasecmp(de->d_name + (name_len-4), ".zip", 4) == 0) {
            if (z_size >= z_alloc) {
                z_alloc *= 2;
                zips = (char**)realloc(zips, z_alloc * sizeof(char*));
            }
            zips[z_size++] = strdup(de->d_name);
        }
    }
    closedir(d);

    qsort(dirs, d_size, sizeof(char*), compare_string);
    qsort(zips, z_size, sizeof(char*), compare_string);

    // append dirs to the zips list
    if (d_size + z_size + 1 > z_alloc) {
        z_alloc = d_size + z_size + 1;
        zips = (char**)realloc(zips, z_alloc * sizeof(char*));
    }
    memcpy(zips + z_size, dirs, d_size * sizeof(char*));
    free(dirs);
    z_size += d_size;
    zips[z_size] = NULL;

    int result;
    int chosen_item = 0;
    do {
        chosen_item = get_menu_selection(headers, zips, 1, chosen_item, device);

        char* item = zips[chosen_item];
        int item_len = strlen(item);
        if (chosen_item == 0) {          // item 0 is always "../"
            // go up but continue browsing (if the caller is update_directory)
            result = -1;
            break;
        } else if (item[item_len-1] == '/') {
            // recurse down into a subdirectory
            char new_path[PATH_MAX];
            strlcpy(new_path, path, PATH_MAX);
            strlcat(new_path, "/", PATH_MAX);
            strlcat(new_path, item, PATH_MAX);
            new_path[strlen(new_path)-1] = '\0';  // truncate the trailing '/'
            result = update_directory(new_path, unmount_when_done, wipe_cache, device);
            if (result >= 0) break;
        } else {
            // selected a zip file:  attempt to install it, and return
            // the status to the caller.
            char new_path[PATH_MAX];
            strlcpy(new_path, path, PATH_MAX);
            strlcat(new_path, "/", PATH_MAX);
            strlcat(new_path, item, PATH_MAX);

            ui->Print("\n-- Install %s ...\n", path);
            set_sdcard_update_bootloader_message();
            char* copy = copy_sideloaded_package(new_path);
            if (unmount_when_done != NULL) {
                ensure_path_unmounted(unmount_when_done);
            }
            if (copy) {
                result = install_package(copy, wipe_cache, TEMPORARY_INSTALL_FILE);
                free(copy);
            } else {
                result = INSTALL_ERROR;
            }
            break;
        }
    } while (true);

    int i;
    for (i = 0; i < z_size; ++i) free(zips[i]);
    free(zips);
    free(headers);

    if (unmount_when_done != NULL) {
        ensure_path_unmounted(unmount_when_done);
    }
    return result;
}
Пример #24
0
void
nan_restore_menu(int pIdx)
{
	tw_total = 0;
	char* nan_r_headers[] = { "Nandroid Restore",
							  "Choose Restore Options:",
							  NULL	};
	
	char* nan_r_items[] = { "--> Restore Naowz!",
			 	 	 	 	nan_img_set(ITEM_NAN_SYSTEM,1),
			 	 	 	 	nan_img_set(ITEM_NAN_DATA,1),
			 	 	 	 	nan_img_set(ITEM_NAN_BOOT,1),
			 	 	 	 	nan_img_set(ITEM_NAN_RECOVERY,1),
			 	 	 	 	nan_img_set(ITEM_NAN_CACHE,1),
			 	 	 	 	nan_img_set(ITEM_NAN_WIMAX,1),
			 	 	 	 	nan_img_set(ITEM_NAN_ANDSEC,1),
			 	 	 	 	nan_img_set(ITEM_NAN_SDEXT,1),
							"<-- Back To Nandroid Menu",
							 NULL };

	char** headers = prepend_title(nan_r_headers);
	
    inc_menu_loc(ITEM_NAN_BACK);
	for (;;) {
		int chosen_item = get_menu_selection(headers, nan_r_items, 0, pIdx);
		pIdx = chosen_item; // remember last selection location
		switch (chosen_item)
		{
		case ITEM_NAN_BACKUP:
			if (tw_total > 0) {
				nandroid_rest_exe();
				dec_menu_loc();
				return;
			}
			break;
		case ITEM_NAN_SYSTEM:
			if (tw_nan_system_x == 0) {
				tw_nan_system_x = 1;
        		tw_total++;
			} else if (tw_nan_system_x == 1) {
				tw_nan_system_x = 0;
        		tw_total--;
			}
            break;
		case ITEM_NAN_DATA:
			if (tw_nan_data_x == 0) {
				tw_nan_data_x = 1;
        		tw_total++;
			} else if (tw_nan_data_x == 1) {
				tw_nan_data_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_BOOT:
			if (tw_nan_boot_x == 0) {
				tw_nan_boot_x = 1;
        		tw_total++;
			} else if (tw_nan_boot_x == 1) {
				tw_nan_boot_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_RECOVERY:
			if (tw_nan_recovery_x == 0) {
				tw_nan_recovery_x = 1;
        		tw_total++;
			} else if (tw_nan_recovery_x == 1) {
				tw_nan_recovery_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_CACHE:
			if (tw_nan_cache_x == 0) {
				tw_nan_cache_x = 1;
        		tw_total++;
			} else if (tw_nan_cache_x == 1) {
				tw_nan_cache_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_WIMAX:
			if (tw_nan_wimax_x == 0) {
				tw_nan_wimax_x = 1;
        		tw_total++;
			} else if (tw_nan_wimax_x == 1) {
				tw_nan_wimax_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_ANDSEC:
			if (tw_nan_andsec_x == 0) {
				tw_nan_andsec_x = 1;
        		tw_total++;
			} else if (tw_nan_andsec_x == 1) {
				tw_nan_andsec_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_SDEXT:
			if (tw_nan_sdext_x == 0) {
				tw_nan_sdext_x = 1;
        		tw_total++;
			} else if (tw_nan_sdext_x == 1) {
				tw_nan_sdext_x = 0;
        		tw_total--;
			}
			break;
		case ITEM_NAN_BACK - 1:
        	dec_menu_loc();
			return;
		}
	    if (go_home) { 
	        dec_menu_loc();
	        return;
	    }
	    break;
	}
	ui_end_menu();
    dec_menu_loc();
    nan_restore_menu(pIdx);
}
Пример #25
0
void
prompt_and_wait() {

	// Main Menu
	#define ITEM_APPLY_SDCARD        0
	#define ITEM_NANDROID_MENU     	 1
	#define ITEM_MAIN_WIPE_MENU      2
	#define ITEM_ADVANCED_MENU       3
	#define ITEM_MOUNT_MENU       	 4
	#define ITEM_USB_TOGGLE          5
	#define ITEM_REBOOT              6
	#define ITEM_SHUTDOWN		7


    finish_recovery(NULL);
    ui_reset_progress();

    // buying a split second for mmc driver to load to avoid error on some devices
    getLocations();
    tw_set_defaults();
    read_s_file();
    
	char** headers = prepend_title((const char**)MENU_HEADERS);
    char* MENU_ITEMS[] = {  "Install Zip",
                            "Nandroid Menu",
                            "Wipe Menu",
                            "Advanced Menu",
                            "Mount Menu",
                            "USB Storage Toggle",
                            "Reboot system now",
                            "Power down system",
                            NULL };
	
    for (;;) {

        go_home = 0;
        go_menu = 0;
        menu_loc_idx = 0;
		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);

        // delay reading settings during boot due to timings issues with sdcard not being available
        // read settings file once and only once after the user makes a menu selection
        if (need_to_read_settings_file) {
        	need_to_read_settings_file = 0;
        }
        
        switch (chosen_item) {
            case ITEM_APPLY_SDCARD:
                install_zip_menu(0);
                break;

            case ITEM_NANDROID_MENU:
            	nandroid_menu();
            	break;
            	
            case ITEM_MAIN_WIPE_MENU:
                main_wipe_menu();
                break;

            case ITEM_ADVANCED_MENU:
            	advanced_menu();
                break;

            case ITEM_MOUNT_MENU:
            	mount_menu(0);
                break;
                
            case ITEM_USB_TOGGLE:
            	usb_storage_toggle();
                break;

            case ITEM_REBOOT:
                return;

	    case ITEM_SHUTDOWN:
	        __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF, NULL);
		break;
        }
        if (go_menu) {
        	advanced_menu();
        }
    }
}
Пример #26
0
int
sdcard_directory(const char* path) {
    ensure_path_mounted(SDCARD_ROOT);

    const char* MENU_HEADERS[] = { "Choose a package to install:",
                                   path,
                                   NULL };
    DIR* d;
    struct dirent* de;
    d = opendir(path);
    if (d == NULL) {
        LOGE("error opening %s: %s\n", path, strerror(errno));
        ensure_path_unmounted(SDCARD_ROOT);
        return 0;
    }

    char** headers = prepend_title(MENU_HEADERS);

    int s_size = 0;
    int s_alloc = 10;
    char** sele = malloc(s_alloc * sizeof(char*));
    int d_size = 0;
    int d_alloc = 10;
    char** dirs = malloc(d_alloc * sizeof(char*));
    int z_size = 0;
    int z_alloc = 10;
    char** zips = malloc(z_alloc * sizeof(char*));
    if (get_new_zip_dir == 1)
    {
    	sele[0] = strdup("[SELECT CURRENT FOLDER]");
    	s_size++;
    }
	sele[s_size] = strdup("../");
    inc_menu_loc(s_size);
	s_size++;
    
    while ((de = readdir(d)) != NULL) {
        int name_len = strlen(de->d_name);

        if (de->d_type == DT_DIR) {
            // skip "." and ".." entries
            if (name_len == 1 && de->d_name[0] == '.') continue;
            if (name_len == 2 && de->d_name[0] == '.' &&
                de->d_name[1] == '.') continue;

            if (d_size >= d_alloc) {
                d_alloc *= 2;
                dirs = realloc(dirs, d_alloc * sizeof(char*));
            }
            dirs[d_size] = malloc(name_len + 2);
            strcpy(dirs[d_size], de->d_name);
            dirs[d_size][name_len] = '/';
            dirs[d_size][name_len+1] = '\0';
            ++d_size;
        } else if (de->d_type == DT_REG &&
                   name_len >= 4 &&
                   strncasecmp(de->d_name + (name_len-4), ".zip", 4) == 0) {
            if (z_size >= z_alloc) {
                z_alloc *= 2;
                zips = realloc(zips, z_alloc * sizeof(char*));
            }
            zips[z_size++] = strdup(de->d_name);
        }
    }
    closedir(d);

    notError = 0;
    qsort(dirs, d_size, sizeof(char*), compare_string);
    qsort(zips, z_size, sizeof(char*), compare_string);
    
    // append dirs to the zips list
    if (d_size + z_size + 1 > z_alloc) {
        z_alloc = d_size + z_size + 1;
        zips = realloc(zips, z_alloc * sizeof(char*));
    }
    memcpy(zips + z_size, dirs, d_size * sizeof(char*));
    free(dirs);
    z_size += d_size;
    zips[z_size] = NULL;

    if (z_size + s_size + 1 > s_alloc) {
        s_alloc = z_size + s_size + 1;
        sele = realloc(sele, s_alloc * sizeof(char*));
    }
    memcpy(sele + s_size, zips, z_size * sizeof(char*));
    s_size += z_size;
    sele[s_size] = NULL;
    
    int result;
    int chosen_item = 0;
    do {
        chosen_item = get_menu_selection(headers, sele, 1, chosen_item);

        char* item = sele[chosen_item];
        int item_len = strlen(item);

        if (chosen_item == 0) {          // item 0 is always "../"
            // go up but continue browsing (if the caller is sdcard_directory)
        	if (get_new_zip_dir == 1)
        	{
        		strcpy(tw_zip_location_val,path);
                write_s_file();
                return 1;
        	} else {
            	dec_menu_loc();
                result = -1;
                break;
        	}
        } else if (chosen_item == 1 && get_new_zip_dir == 1) {
        	dec_menu_loc();
            result = -1;
            break;
        } else if (item[item_len-1] == '/') {
            // recurse down into a subdirectory
            char new_path[PATH_MAX];
            strlcpy(new_path, path, PATH_MAX);
            strlcat(new_path, "/", PATH_MAX);
            strlcat(new_path, item, PATH_MAX);
            new_path[strlen(new_path)-1] = '\0';  // truncate the trailing '/'
            result = sdcard_directory(new_path);
    	    if (go_home) { 
    	    	notError = 1;
    	        dec_menu_loc();
    	        if (get_new_zip_dir == 1)
    	        {
        	        return 1;
    	        } else {
        	        return 0;
    	        }
    	    }
            if (result >= 0) break;
        } else {
        	if (get_new_zip_dir != 1)
        	{
                // selected a zip file:  attempt to install it, and return
                // the status to the caller.
                char new_path[PATH_MAX];
                strlcpy(new_path, path, PATH_MAX);
                strlcat(new_path, "/", PATH_MAX);
                strlcat(new_path, item, PATH_MAX);

                ui_print("\n-- Install %s ...\n", path);
                set_sdcard_update_bootloader_message();
                char* copy = copy_sideloaded_package(new_path);
                ensure_path_unmounted(SDCARD_ROOT);
                if (copy) {
                    result = install_package(copy);
                    free(copy);
                } else {
                    result = INSTALL_ERROR;
                }
                break;
        	}
        }
    } while (true);
    
    free(zips);
    free(sele);
    free(headers);

    //ensure_path_unmounted(SDCARD_ROOT);
    return result;
}
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;
        }
    }
}
Пример #28
0
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_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;
        }
    }
}
Пример #29
0
// Return REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER.  Returning NO_ACTION
// means to take the default, which is to reboot or shutdown depending
// on if the --shutdown_after flag was passed to recovery.
static Device::BuiltinAction
prompt_and_wait(Device* device, int status) {
    const char* const* headers = prepend_title(device->GetMenuHeaders());

    for (;;) {
        finish_recovery(NULL);
        switch (status) {
            case INSTALL_SUCCESS:
            case INSTALL_NONE:
                ui->SetBackground(RecoveryUI::NO_COMMAND);
                break;

            case INSTALL_ERROR:
            case INSTALL_CORRUPT:
                ui->SetBackground(RecoveryUI::ERROR);
                break;
        }
        ui->SetProgressType(RecoveryUI::EMPTY);

        int chosen_item = get_menu_selection(headers, device->GetMenuItems(), 0, 0, device);

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

        int wipe_cache = 0;
        switch (chosen_action) {
            case Device::NO_ACTION:
                break;

            case Device::REBOOT:
            case Device::SHUTDOWN:
            case Device::REBOOT_BOOTLOADER:
                return chosen_action;

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

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

            case Device::APPLY_EXT: {
                ensure_path_mounted(SDCARD_ROOT);
                char* path = browse_directory(SDCARD_ROOT, device);
                if (path == NULL) {
                    ui->Print("\n-- No package file selected.\n", path);
                    break;
                }

                ui->Print("\n-- Install %s ...\n", path);
                set_sdcard_update_bootloader_message();
                void* token = start_sdcard_fuse(path);

                int status = install_package(FUSE_SIDELOAD_HOST_PATHNAME, &wipe_cache,
                                             TEMPORARY_INSTALL_FILE, false);

                finish_sdcard_fuse(token);
                ensure_path_unmounted(SDCARD_ROOT);

                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 Device::NO_ACTION;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from sdcard complete.\n");
                    }
                }
                break;
            }

            case Device::APPLY_CACHE:
                ui->Print("\nAPPLY_CACHE is deprecated.\n");
                break;

            case Device::READ_RECOVERY_LASTLOG:
                choose_recovery_file(device);
                break;

            case Device::APPLY_ADB_SIDELOAD:
                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");
                        copy_logs();
                    } else if (!ui->IsTextVisible()) {
                        return Device::NO_ACTION;  // reboot if logs aren't visible
                    } else {
                        ui->Print("\nInstall from ADB complete.\n");
                    }
                }
                break;
        }
    }
}
Пример #30
0
// Returns a malloc'd path, or NULL.
static char*
browse_directory(const char* path, Device* device) {
    ensure_path_mounted(path);

    const char* MENU_HEADERS[] = { "Choose a package to install:",
                                   path,
                                   "",
                                   NULL };
    DIR* d;
    struct dirent* de;
    d = opendir(path);
    if (d == NULL) {
        LOGE("error opening %s: %s\n", path, strerror(errno));
        return NULL;
    }

    const char** headers = prepend_title(MENU_HEADERS);

    int d_size = 0;
    int d_alloc = 10;
    char** dirs = (char**)malloc(d_alloc * sizeof(char*));
    int z_size = 1;
    int z_alloc = 10;
    char** zips = (char**)malloc(z_alloc * sizeof(char*));
    zips[0] = strdup("../");

    while ((de = readdir(d)) != NULL) {
        int name_len = strlen(de->d_name);

        if (de->d_type == DT_DIR) {
            // skip "." and ".." entries
            if (name_len == 1 && de->d_name[0] == '.') continue;
            if (name_len == 2 && de->d_name[0] == '.' &&
                de->d_name[1] == '.') continue;

            if (d_size >= d_alloc) {
                d_alloc *= 2;
                dirs = (char**)realloc(dirs, d_alloc * sizeof(char*));
            }
            dirs[d_size] = (char*)malloc(name_len + 2);
            strcpy(dirs[d_size], de->d_name);
            dirs[d_size][name_len] = '/';
            dirs[d_size][name_len+1] = '\0';
            ++d_size;
        } else if (de->d_type == DT_REG &&
                   name_len >= 4 &&
                   strncasecmp(de->d_name + (name_len-4), ".zip", 4) == 0) {
            if (z_size >= z_alloc) {
                z_alloc *= 2;
                zips = (char**)realloc(zips, z_alloc * sizeof(char*));
            }
            zips[z_size++] = strdup(de->d_name);
        }
    }
    closedir(d);

    qsort(dirs, d_size, sizeof(char*), compare_string);
    qsort(zips, z_size, sizeof(char*), compare_string);

    // append dirs to the zips list
    if (d_size + z_size + 1 > z_alloc) {
        z_alloc = d_size + z_size + 1;
        zips = (char**)realloc(zips, z_alloc * sizeof(char*));
    }
    memcpy(zips + z_size, dirs, d_size * sizeof(char*));
    free(dirs);
    z_size += d_size;
    zips[z_size] = NULL;

    char* result;
    int chosen_item = 0;
    while (true) {
        chosen_item = get_menu_selection(headers, zips, 1, chosen_item, device);

        char* item = zips[chosen_item];
        int item_len = strlen(item);
        if (chosen_item == 0) {          // item 0 is always "../"
            // go up but continue browsing (if the caller is update_directory)
            result = NULL;
            break;
        }

        char new_path[PATH_MAX];
        strlcpy(new_path, path, PATH_MAX);
        strlcat(new_path, "/", PATH_MAX);
        strlcat(new_path, item, PATH_MAX);

        if (item[item_len-1] == '/') {
            // recurse down into a subdirectory
            new_path[strlen(new_path)-1] = '\0';  // truncate the trailing '/'
            result = browse_directory(new_path, device);
            if (result) break;
        } else {
            // selected a zip file: return the malloc'd path to the caller.
            result = strdup(new_path);
            break;
        }
    }

    int i;
    for (i = 0; i < z_size; ++i) free(zips[i]);
    free(zips);
    free(headers);

    return result;
}