//INTENT_INSTALL install path, wipe_cache, install_file static intentResult* intent_install(int argc, char *argv[]) { return_intent_result_if_fail(argc == 3); return_intent_result_if_fail(argv != NULL); int wipe_cache = atoi(argv[1]); int echo = atoi(argv[2]); miuiInstall_init(&install_package, argv[0], wipe_cache, TEMPORARY_INSTALL_FILE); miui_install(echo); //echo install failed return miuiIntent_result_set(RET_OK, NULL); }
static STATUS sd_update_show(menuUnit *p) { char new_path[SD_MAX_PATH]; snprintf(new_path, SD_MAX_PATH, "%s", "/sdcard/update.zip"); int wipe_cache = 0; struct _intentResult* result = miuiIntent_send(INTENT_INSTALL, 2, new_path, &wipe_cache); if (strstr(miuiIntent_result_get_string(), "cache") != NULL) miuiIntent_send(INTENT_WIPE, 1, "/cache"); miui_install(p->name, p->icon); return MENU_BACK; }
static STATUS _sd_dir_show(struct _menuUnit *p, char *path) { DIR* d; struct dirent* de; d = opendir(path); return_val_if_fail(d != NULL, RET_FAIL); int d_size = 0; int d_alloc = 10; return_val_if_fail(sd_menu != NULL, RET_FAIL); char** dirs = malloc(d_alloc * sizeof(char*)); char** dirs_desc = malloc(d_alloc * sizeof(char*)); return_val_if_fail(dirs != NULL, RET_FAIL); return_val_if_fail(dirs_desc != NULL, RET_FAIL); int z_size = 1; int z_alloc = 10; char** zips = malloc(z_alloc * sizeof(char*)); char** zips_desc=malloc(z_alloc * sizeof(char*)); return_val_if_fail(zips != NULL, RET_FAIL); return_val_if_fail(zips_desc != NULL, RET_FAIL); zips[0] = strdup("../"); zips_desc[0]=strdup("../"); while ((de = readdir(d)) != NULL) { int name_len = strlen(de->d_name); char de_path[SD_MAX_PATH]; snprintf(de_path, SD_MAX_PATH, "%s/%s", path, de->d_name); struct stat st ; assert_if_fail(stat(de_path, &st) == 0); 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_desc = realloc(dirs_desc, d_alloc * sizeof(char*)); } dirs[d_size] = malloc(name_len + 2); dirs_desc[d_size] = malloc(64); strcpy(dirs[d_size], de->d_name); dirs[d_size][name_len] = '/'; dirs[d_size][name_len + 1] = '\0'; snprintf(dirs_desc[d_size], 64, "%s" ,ctime(&st.st_mtime)); ++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_desc = realloc(zips_desc, z_alloc * sizeof(char*)); } zips[z_size] = strdup(de->d_name); zips_desc[z_size] = malloc(64); snprintf(zips_desc[z_size], 64, "%s %lldbytes" ,ctime(&st.st_mtime), st.st_size); z_size++; } } closedir(d); // 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*)); zips_desc = realloc(zips_desc, z_alloc * sizeof(char*)); } memcpy(zips + z_size, dirs, d_size * sizeof(char *)); memcpy(zips_desc + z_size, dirs_desc, d_size * sizeof(char*)); free(dirs); z_size += d_size; zips[z_size] = NULL; zips_desc[z_size] = NULL; int result; int chosen_item = 0; do { chosen_item = miui_sdmenu(sd_menu->name, zips, zips_desc, z_size); return_val_if_fail(chosen_item >= 0, RET_FAIL); char * item = zips[chosen_item]; return_val_if_fail(item != NULL, RET_FAIL); int item_len = strlen(item); if ( chosen_item == 0) { //go up but continue browsing result = -1; break; } else if (item[item_len - 1] == '/') { char new_path[SD_MAX_PATH]; strlcpy(new_path, path, SD_MAX_PATH); strlcat(new_path, "/", SD_MAX_PATH); strlcat(new_path, item, SD_MAX_PATH); new_path[strlen(new_path) - 1] = '\0'; result = _sd_dir_show(p, new_path); if (result > 0) break; } else { // select a zipfile // the status to the caller char new_path[SD_MAX_PATH]; strlcpy(new_path, path, SD_MAX_PATH); strlcat(new_path, "/", SD_MAX_PATH); strlcat(new_path, item, SD_MAX_PATH); int wipe_cache = 0; struct _intentResult* result = miuiIntent_send(INTENT_INSTALL, 2, new_path, &wipe_cache); miui_install(p->name, p->icon); break; } } while(1); int i; for (i = 0; i < z_size; ++i) { free(zips[i]); free(zips_desc[i]); } free(zips); return result; }
int main(int argc, char **argv) { time_t start = time(NULL); // If these fail, there's not really anywhere to complain... unlink(TEMPORARY_LOG_FILE); freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s", ctime(&start)); //miuiIntent init miuiIntent_init(10); miuiIntent_register(INTENT_MOUNT, &intent_mount); miuiIntent_register(INTENT_ISMOUNT, &intent_ismount); miuiIntent_register(INTENT_UNMOUNT, &intent_unmount); miuiIntent_register(INTENT_REBOOT, &intent_reboot); miuiIntent_register(INTENT_INSTALL, &intent_install); miuiIntent_register(INTENT_WIPE, &intent_wipe); miuiIntent_register(INTENT_TOGGLE, &intent_toggle); miuiIntent_register(INTENT_FORMAT, &intent_format); miuiIntent_register(INTENT_RESTORE, &intent_restore); miuiIntent_register(INTENT_BACKUP, &intent_backup); miuiIntent_register(INTENT_ADVANCED_BACKUP, &intent_advanced_backup); miuiIntent_register(INTENT_SYSTEM, &intent_system); miuiIntent_register(INTENT_COPY, &intent_copy); device_ui_init(); load_volume_table(); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; int wipe_data = 0, wipe_cache = 0; int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; //case 't': ui_show_text(1); break; case '?': LOGE("Invalid command argument\n"); continue; } } device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { miuiInstall_init(&install_package, update_package, &wipe_cache,TEMPORARY_INSTALL_FILE); status = miui_install("<~sd.install.name>", "@sd.install"); if (status == INSTALL_SUCCESS && wipe_cache) { if (erase_volume("/cache")) { LOGE("Cache wipe (requested by package) failed."); } } if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; if (erase_volume("/data")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); } else { status = INSTALL_ERROR; // No command specified } if (status != INSTALL_SUCCESS) device_main_ui_show();//show menu device_main_ui_release(); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); android_reboot(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }