From 49f5689b42b6f66b7821c3bc1340f0fa79721041 Mon Sep 17 00:00:00 2001 From: "Koushik K. Dutta" Date: Thu, 25 Feb 2010 14:51:05 -0800 Subject: [PATCH] allow choosing of subdirectories when searching for a zip file to install --- extendedcommands.c | 147 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 116 insertions(+), 31 deletions(-) diff --git a/extendedcommands.c b/extendedcommands.c index d54321f..7c60999 100644 --- a/extendedcommands.c +++ b/extendedcommands.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -103,7 +104,7 @@ void show_install_update_menu() } } -char* choose_file_menu(const char* directory, const char* extension, const char* headers[]) +char** gather_files(const char* directory, const char* fileExtensionOrDirectory, int* numFiles) { char path[PATH_MAX] = ""; DIR *dir; @@ -111,7 +112,9 @@ char* choose_file_menu(const char* directory, const char* extension, const char* int total = 0; int i; char** files; - char** list; + int pass; + *numFiles = 0; + int dirLen = strlen(directory); dir = opendir(directory); if (dir == NULL) { @@ -119,47 +122,121 @@ char* choose_file_menu(const char* directory, const char* extension, const char* return NULL; } - const int extension_length = strlen(extension); + int extension_length; + if (fileExtensionOrDirectory != NULL) + extension_length = strlen(fileExtensionOrDirectory); - while ((de=readdir(dir)) != NULL) { - if (de->d_name[0] != '.' && strlen(de->d_name) > extension_length && strcmp(de->d_name + strlen(de->d_name) - extension_length, extension) == 0) { - total++; - } + int isCounting = 1; + i = 0; + for (pass = 0; pass < 2; pass++) { + while ((de=readdir(dir)) != NULL) { + // skip hidden files + if (de->d_name[0] == '.') + continue; + + // NULL means that we are gathering directories, so skip this + if (fileExtensionOrDirectory != NULL) + { + // make sure that we can have the desired extension (prevent seg fault) + if (strlen(de->d_name) < extension_length) + continue; + // compare the extension + if (strcmp(de->d_name + strlen(de->d_name) - extension_length, fileExtensionOrDirectory) != 0) + continue; + } + else + { + struct stat info; + char* fullFileName = (char*)malloc(strlen(de->d_name) + dirLen + 1); + strcpy(fullFileName, directory); + strcat(fullFileName, de->d_name); + stat(fullFileName, &info); + free(fullFileName); + // make sure it is a directory + if (!(S_ISDIR(info.st_mode))) + continue; + } + + if (pass == 0) + { + total++; + continue; + } + + files[i] = (char*) malloc(dirLen + strlen(de->d_name) + 2); + strcpy(files[i], directory); + strcat(files[i], de->d_name); + if (fileExtensionOrDirectory == NULL) + strcat(files[i], "/"); + i++; + } + if (pass == 1) + break; + if (total == 0) + break; + rewinddir(dir); + *numFiles = total; + files = (char**) malloc((total+1)*sizeof(char*)); + files[total]=NULL; + } + + if(closedir(dir) < 0) { + LOGE("Failed to close directory."); } if (total==0) { - ui_print("No files found.\n"); - if(closedir(dir) < 0) { - LOGE("Failed to close directory."); - } return NULL; } - files = (char**) malloc((total+1)*sizeof(char*)); - files[total]=NULL; + return files; +} - list = (char**) malloc((total+1)*sizeof(char*)); - list[total]=NULL; +void free_string_array(char** array) +{ + char* cursor = array[0]; + int i = 0; + while (cursor != NULL) + { + free(cursor); + cursor = array[++i]; + } + free(array); +} - rewinddir(dir); +// pass in NULL for fileExtensionOrDirectory and you will get a directory chooser +char* choose_file_menu(const char* directory, const char* fileExtensionOrDirectory, const char* headers[]) +{ + char path[PATH_MAX] = ""; + DIR *dir; + struct dirent *de; + int numFiles = 0; + int numDirs = 0; + int i; - i = 0; - while ((de = readdir(dir)) != NULL) { - if (de->d_name[0] != '.' && strlen(de->d_name) > extension_length && strcmp(de->d_name + strlen(de->d_name) - extension_length, extension) == 0) { - files[i] = (char*) malloc(strlen(directory)+strlen(de->d_name)+1); - strcpy(files[i], directory); - strcat(files[i], de->d_name); + int dir_len = strlen(directory); - list[i] = (char*) malloc(strlen(de->d_name)+1); - strcpy(list[i], de->d_name); + char** files = gather_files(directory, fileExtensionOrDirectory, &numFiles); + char** dirs; + if (fileExtensionOrDirectory != NULL) + dirs = gather_files(directory, NULL, &numDirs); + int total = numDirs + numFiles; + if (total == 0) + { + ui_print("No files found.\n"); + return NULL; + } + char** list = (char**) malloc((total + 1) * sizeof(char*)); + list[total] = NULL; - i++; - } + + for (i = 0 ; i < numDirs; i++) + { + list[i] = strdup(dirs[i] + dir_len); } - if (closedir(dir) <0) { - LOGE("Failure closing directory."); - return NULL; + for (i = 0 ; i < numFiles; i++) + { + list[numDirs + i] = strdup(files[i] + dir_len); } for (;;) @@ -167,8 +244,16 @@ char* choose_file_menu(const char* directory, const char* extension, const char* int chosen_item = get_menu_selection(headers, list, 0); if (chosen_item == GO_BACK) break; + if (chosen_item < numDirs) + { + char* subret = choose_file_menu(dirs[chosen_item], fileExtensionOrDirectory, headers); + if (subret != NULL) + return subret; + continue; + } static char ret[PATH_MAX]; - strcpy(ret, files[chosen_item]); + strcpy(ret, files[chosen_item - numDirs]); + ui_print("File chosen: %s\n", ret); return ret; } return NULL; @@ -260,7 +345,7 @@ void show_nandroid_restore_menu() NULL }; - char* file = choose_file_menu("/sdcard/clockworkmod/backup/", "", headers); + char* file = choose_file_menu("/sdcard/clockworkmod/backup/", NULL, headers); if (file == NULL) return; char* command[PATH_MAX];