/* add by cjcheng start... */ static int smdt_update_directory(const char* path, const char* unmount_when_done, int* wipe_cache) { ensure_path_mounted(path); int result; char new_path[PATH_MAX]; strlcpy(new_path, path, PATH_MAX); strlcat(new_path, "/", PATH_MAX); strlcat(new_path, "update.zip", PATH_MAX); ui->Print("\n-- Install %s ...\n", new_path); if (access(new_path, F_OK) == 0) { ui->Print("\n read -- %s ok...\n", new_path); ui->SetTipTitle(RecoveryUI::TIP_TITLE_READ_PACKAGE); } else { ui->Print("\n read -- %s error...\n", new_path); if (unmount_when_done != NULL) { ensure_path_unmounted(unmount_when_done); } return INSTALL_ERROR; } 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; } return result; }
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; }
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; }