diff --git a/include/QF/quakefs.h b/include/QF/quakefs.h index 6796a8c1c..6604f053c 100644 --- a/include/QF/quakefs.h +++ b/include/QF/quakefs.h @@ -126,6 +126,9 @@ void QFS_FilelistAdd (filelist_t *filelist, const char *fname, void QFS_FilelistFill (filelist_t *list, const char *path, const char *ext, int strip); void QFS_FilelistFree (filelist_t *list); +void QFS_FilelistEnumerate(filelist_t* list, const char* path); +qboolean QFS_IsDirectory (const char *path); + // FIXME: This is here temporarily until fs_usercfg gets sorted out char *expand_squiggle (const char *path); diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 86921fb52..abf4937ca 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -53,6 +53,7 @@ static __attribute__ ((used)) const char rcsid[] = #include #include #include +#include #ifdef HAVE_FNMATCH_H # define model_t sunmodel_t @@ -1494,6 +1495,113 @@ QFS_FilelistFill (filelist_t *list, const char *path, const char *ext, } } +VISIBLE qboolean +QFS_IsDirectory (const char *path) +{ + searchpath_t *search; + + if (!path[0]) + return true; + + for (search = qfs_searchpaths; search != NULL; search = search->next) + { + if (search->pack) + { + int i; + pack_t *pak = search->pack; + + for (i = 0; i < pak->numfiles; i++) + { + const char* prefix = va("%s/", path); + const char* filename = pak->files[i].name; + + if (strlen(prefix) < strlen(filename) && !strncmp(prefix, filename, strlen(prefix))) + { + return true; + } + } + } + else + { + const char* truepath = va("%s/%s", search->filename, path); + struct stat buf; + + if (!stat(truepath, &buf) && S_ISDIR(buf.st_mode)) + return true; + } + } + + return false; +} + +VISIBLE void +QFS_FilelistEnumerate(filelist_t* list, const char* path) +{ + searchpath_t *search; + + for (search = qfs_searchpaths; search != NULL; search = search->next) + { + if (search->pack) + { + int i; + pack_t *pak = search->pack; + + for (i = 0; i < pak->numfiles; i++) + { + const char* prefix = path[0] ? va("%s/", path) : ""; + char* filename = pak->files[i].name; + + int j; + + for (j = 0; j < list->count; j++) + { + if (list->list[j] && !strncmp(list->list[j], filename, strlen(list->list[j]))) + { + goto OUT; + } + } + + if (strlen(prefix) < strlen(filename) && + !strncmp(prefix, filename, strlen(prefix))) + { + char* slash = strchr(filename + strlen(prefix), '/'); + if (slash) + *slash = 0; + int j; + qboolean exists = false; + for (j = 0; j < list->count; j++) + { + if (list->list[j] && !strcmp(list->list[j], filename)) + { + exists = true; + break; + } + } + if (!exists) + QFS_FilelistAdd(list, filename, false); + if (slash) + *slash = '/'; + } + OUT: ; + } + } + else + { + const char* truepath = va("%s/%s", search->filename, path); + DIR *dir_ptr = opendir (truepath); + struct dirent *dirent; + if (!dir_ptr) + continue; + while ((dirent = readdir (dir_ptr))) + { + if (strcmp(".", dirent->d_name) && strcmp("..", dirent->d_name)) + QFS_FilelistAdd(list, dirent->d_name, false); + } + closedir (dir_ptr); + } + } +} + VISIBLE void QFS_FilelistFree (filelist_t *list) {