// List all files and subdirectories recursively static void list_files(const char *filepath, ListCallback list_callback) { void * hFind; char *fname; u32 dwError; RDIR* rdir = retro_opendir(filepath); if(!rdir) return; if(retro_dirent_error(rdir)) { retro_closedir(rdir); return; } for(;;) { if(!retro_readdir(rdir)) break; const char* fname = retro_dirent_get_name(rdir); list_callback(rdir,EListCallbackArg_Item); if(retro_dirent_is_dir(rdir) && (strcmp(fname, ".")) && (strcmp(fname, ".."))) { std::string subdir = (std::string)filepath + path_default_slash() + fname; list_files(subdir.c_str(), list_callback); list_callback(rdir, EListCallbackArg_Pop); } } retro_closedir(rdir); }
dir_information* open_directory(const char* dirname) { static dir_information dir; dir.dir = retro_opendir(dirname); safe_strncpy(dir.base_path,dirname,CROSS_LEN); return dir.dir ? &dir : NULL; }
/** * dir_list_new: * @dir : directory path. * @ext : allowed extensions of file directory entries to include. * @include_dirs : include directories as part of the finished directory listing? * @include_compressed : Only include files which match ext. Do not try to match compressed files, etc. * * Create a directory listing. * * Returns: pointer to a directory listing of type 'struct string_list *' on success, * NULL in case of error. Has to be freed manually. **/ struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs, bool include_compressed) { struct RDIR *entry = NULL; struct string_list *ext_list = NULL; struct string_list *list = NULL; if (!(list = string_list_new())) return NULL; if (ext) ext_list = string_split(ext, "|"); entry = retro_opendir(dir); if (!entry) goto error; if (retro_dirent_error(entry)) goto error; while (retro_readdir(entry)) { char file_path[PATH_MAX_LENGTH]; bool is_dir; int ret = 0; const char *name = retro_dirent_get_name(entry); const char *file_ext = path_get_extension(name); fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = retro_dirent_is_dir(entry, file_path); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, include_compressed, list, ext_list, file_ext); if (ret == -1) goto error; if (ret == 1) continue; } retro_closedir(entry); string_list_free(ext_list); return list; error: retro_closedir(entry); string_list_free(list); string_list_free(ext_list); return NULL; }
bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { assert(_isDirectory); struct RDIR *dirp = retro_opendir(_path.c_str()); if (dirp == NULL) return false; // loop over dir entries using readdir while ((retro_readdir(dirp))) { const char *d_name = retro_dirent_get_name(dirp); // Skip 'invisible' files if necessary if (d_name[0] == '.' && !hidden) continue; // Skip '.' and '..' to avoid cycles if ((d_name[0] == '.' && d_name[1] == 0) || (d_name[0] == '.' && d_name[1] == '.')) continue; // Start with a clone of this node, with the correct path set POSIXFilesystemNode entry(*this); entry._displayName = d_name; if (_path.lastChar() != '/') entry._path += '/'; entry._path += entry._displayName; entry._isValid = true; entry._isDirectory = retro_dirent_is_dir(dirp, d_name); // Skip files that are invalid for some reason (e.g. because we couldn't // properly stat them). if (!entry._isValid) continue; // Honor the chosen mode if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) || (mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory)) continue; myList.push_back(new POSIXFilesystemNode(entry)); } retro_closedir(dirp); return true; }
/** * dir_list_read: * @dir : directory path. * @list : the string list to add files to * @ext_list : the string list of extensions to include * @include_dirs : include directories as part of the finished directory listing? * @include_hidden : include hidden files and directories as part of the finished directory listing? * @include_compressed : Only include files which match ext. Do not try to match compressed files, etc. * @recursive : list directory contents recursively * * Add files within a directory to an existing string list * * Returns: -1 on error, 0 on success. **/ int dir_list_read(const char *dir, struct string_list *list, struct string_list *ext_list, bool include_dirs, bool include_hidden, bool include_compressed, bool recursive) { struct RDIR *entry = retro_opendir(dir); if (!entry) return -1; if (retro_dirent_error(entry)) { retro_closedir(entry); return -1; } #ifdef _WIN32 if (include_hidden) entry->entry.dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; else entry->entry.dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN; #endif while (retro_readdir(entry)) { char file_path[PATH_MAX_LENGTH]; bool is_dir = false; int ret = 0; const char *name = retro_dirent_get_name(entry); const char *file_ext = path_get_extension(name); file_path[0] = '\0'; fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = retro_dirent_is_dir(entry, file_path); if (!include_hidden) { if (*name == '.') continue; } if(is_dir && recursive) { if(strstr(name, ".") || strstr(name, "..")) continue; dir_list_read(file_path, list, ext_list, include_dirs, include_hidden, include_compressed, recursive); } ret = parse_dir_entry(name, file_path, is_dir, include_dirs, include_compressed, list, ext_list, file_ext); if (ret == -1) { retro_closedir(entry); return -1; } if (ret == 1) continue; } retro_closedir(entry); return 0; }