/** * * retro_dirent_is_dir: * @rdir : pointer to the directory entry. * @path : path to the directory entry. * * Is the directory listing entry a directory? * * Returns: true if directory listing entry is * a directory, false if not. */ bool retro_dirent_is_dir(struct RDIR *rdir) { #if defined(_WIN32) const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry; return entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; #elif defined(PSP) || defined(VITA) const SceIoDirent *entry = (const SceIoDirent*)&rdir->entry; #if defined(PSP) return (entry->d_stat.st_attr & FIO_SO_IFDIR) == FIO_SO_IFDIR; #elif defined(VITA) return PSP2_S_ISDIR(entry->d_stat.st_mode); #endif #elif defined(__CELLOS_LV2__) CellFsDirent *entry = (CellFsDirent*)&rdir->entry; return (entry->d_type == CELL_FS_TYPE_DIRECTORY); #elif defined(DT_DIR) const char *path = NULL; const struct dirent *entry = (const struct dirent*)rdir->entry; if (entry->d_type == DT_DIR) return true; /* This can happen on certain file systems. */ path = retro_dirent_get_name(rdir); if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) return path_is_directory(path); return false; #else /* dirent struct doesn't have d_type, do it the slow way ... */ const char *path = retro_dirent_get_name(rdir); return path_is_directory(path); #endif }
// 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); }
void build_ListCallback(RDIR* rdir, EListCallbackArg arg) { const char* fname = retro_dirent_get_name(rdir); if(arg == EListCallbackArg_Pop) { currPath = pathStack.top(); pathStack.pop(); currVirtPath = virtPathStack.top(); virtPathStack.pop(); return; } if(retro_dirent_is_dir(rdir)) { if(!strcmp(fname,".")) return; if(!strcmp(fname,"..")) return; pathStack.push(currPath); virtPathStack.push(currVirtPath); currVirtPath = currVirtPath + "/" + fname; bool ok = LIBFAT::MkDir(currVirtPath.c_str()); if(!ok) printf("ERROR adding dir %s via libfat\n",currVirtPath.c_str()); currPath = currPath + path_default_slash() + fname; return; } else { std::string path = currPath + path_default_slash() + fname; FILE* inf = fopen(path.c_str(),"rb"); if(inf) { fseek(inf,0,SEEK_END); long len = ftell(inf); fseek(inf,0,SEEK_SET); u8 *buf = new u8[len]; fread(buf,1,len,inf); fclose(inf); std::string path = currVirtPath + "/" + fname; printf("FAT + (%10.2f KB) %s \n",len/1024.f,path.c_str()); bool ok = LIBFAT::WriteFile(path.c_str(),buf,len); if(!ok) printf("ERROR adding file to fat\n"); delete[] buf; } else printf("ERROR opening file for fat\n"); } }
/** * 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; }
void count_ListCallback(RDIR *rdir, EListCallbackArg arg) { if(arg == EListCallbackArg_Pop) return; u32 sectors = 1; if (!retro_dirent_is_dir(rdir)) { /* allocate sectors for file */ int32_t fileSize = path_get_size(retro_dirent_get_name(rdir)); sectors += (fileSize+511)/512 + 1; } dataSectors += sectors; }
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; }
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) { struct stat status; static char buffer[2*CROSS_LEN] = { 0 }; while (retro_readdir(dirp->dir)) { char file_path[4096]; safe_strncpy(entry_name, retro_dirent_get_name(dirp->dir), CROSS_LEN); is_directory = retro_dirent_is_dir(dirp->dir, file_path); return true; } return false; }
/** * 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; }