allow choosing of subdirectories when searching for a zip file to install
diff --git a/extendedcommands.c b/extendedcommands.c
index d54321f..7c60999 100644
--- a/extendedcommands.c
+++ b/extendedcommands.c
@@ -15,6 +15,7 @@
#include <sys/wait.h>
#include <sys/limits.h>
#include <dirent.h>
+#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>
@@ -103,7 +104,7 @@
}
}
-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 @@
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 @@
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 @@
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 @@
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];