static bool SetFileData(const AString& path, const struct dirent& finddata, FILE_INFO *file) { struct stat statdata; bool success = false; file->FileName = path.CatPath(finddata.d_name); file->ShortName = file->FileName.FilePart(); file->Attrib = 0; if (stat(file->FileName, &statdata) == 0) { file->FileSize = statdata.st_size; file->CreateTime.fromtime(statdata.st_mtime); file->AccessTime.fromtime(statdata.st_atime); file->WriteTime.fromtime(statdata.st_mtime); if (statdata.st_mode & S_IRUSR) file->Attrib |= FILE_FLAG_READABLE; if (statdata.st_mode & S_IWUSR) file->Attrib |= FILE_FLAG_WRITABLE; if (statdata.st_mode & S_IXUSR) file->Attrib |= FILE_FLAG_EXECUTABLE; if (statdata.st_mode & S_IRGRP) file->Attrib |= FILE_FLAG_READABLE << 3; if (statdata.st_mode & S_IWGRP) file->Attrib |= FILE_FLAG_WRITABLE << 3; if (statdata.st_mode & S_IXGRP) file->Attrib |= FILE_FLAG_EXECUTABLE << 3; if (statdata.st_mode & S_IROTH) file->Attrib |= FILE_FLAG_READABLE << 6; if (statdata.st_mode & S_IWOTH) file->Attrib |= FILE_FLAG_WRITABLE << 6; if (statdata.st_mode & S_IXOTH) file->Attrib |= FILE_FLAG_EXECUTABLE << 6; if (S_ISDIR(statdata.st_mode)) file->Attrib |= FILE_FLAG_IS_DIR; success = true; } return success; }
bool CollectFiles(const AString& Path, const AString& Pattern, uint_t nSubdirs, AList& list, uint16_t attribMask, uint16_t attribCmp, AQuitHandler *pQuitHandler) { COLLECT_CONTEXT context; context.Pattern = ParsePathRegex(Pattern); context.pList = &list; context.pQuitHandler = pQuitHandler; context.AttribMask = attribMask; context.AttribCompare = attribCmp; context.bAnyName = IsRegexAnyPattern(context.Pattern); return ::Recurse(Path.CatPath("*"), nSubdirs, &__CollectFiles, &context); }
bool CollectFilesEx(const AString& Path, const AString& Pattern, uint_t nSubdirs, AList& list, uint_t sortFlags, uint16_t attribSet, uint16_t attribClr, AQuitHandler *pQuitHandler) { COLLECTEX_CONTEXT context; context.Pattern = ParsePathRegex(Pattern); context.pList = &list; context.pQuitHandler = pQuitHandler; context.AttribSet = attribSet; context.AttribClr = attribClr; context.bAnyName = IsRegexAnyPattern(context.Pattern); context.CmpFunc = AFileNode::GetSortFunction(sortFlags); context.CmpFlags = sortFlags; return ::Recurse(Path.CatPath("*"), nSubdirs, &__CollectFilesEx, &context); }
static void SetFileData(const AString& path, const WIN32_FIND_DATA& finddata, FILE_INFO *file) { file->FileName = path.CatPath(finddata.cFileName); file->ShortName = file->FileName.FilePart(); file->FileSize = (uint64_t)finddata.nFileSizeLow + ((uint64_t)finddata.nFileSizeHigh << 32); file->CreateTime = ConvertTime(finddata.ftCreationTime); file->AccessTime = ConvertTime(finddata.ftLastAccessTime); file->WriteTime = ConvertTime(finddata.ftLastWriteTime); file->Attrib = FILE_FLAG_NORMAL; if (finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY) file->Attrib &= ~FILE_FLAG_WRITABLE; file->Attrib |= (file->Attrib << 3); file->Attrib |= (file->Attrib << 3); if (finddata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) file->Attrib |= FILE_FLAG_HIDDEN; if (finddata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) file->Attrib |= FILE_FLAG_SYSTEM; if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) file->Attrib |= FILE_FLAG_IS_DIR; }
bool Recurse(const AString& Path, const AString& Pattern, uint_t nSubDirs, bool (*fn)(const FILE_INFO *file, void *Context), void *Context) { WIN32_FIND_DATA finddata; AString pattern, pattern1 = ParsePathRegex(Pattern); FILE_INFO file; HANDLE handle; bool ok = true, any = IsRegexAnyPattern(pattern1); pattern = Path.CatPath("*"); if ((handle = ::FindFirstFile(pattern, &finddata)) != INVALID_HANDLE_VALUE) { do { SetFileData(Path, finddata, &file); if ((file.ShortName != ".") && (file.ShortName != "..")) { bool done = false; if (any || MatchPathRegex(file.ShortName, pattern1)) { ok = (*fn)(&file, Context); if (!ok) break; done = true; } if ((nSubDirs > 0) && (file.Attrib & FILE_FLAG_IS_DIR)) { if (!done) { ok = (*fn)(&file, Context); if (!ok) break; } ok = Recurse(file.FileName, Pattern, nSubDirs - 1, fn, Context); if (!ok) break; } } } while (ok && ::FindNextFile(handle, &finddata)); ::FindClose(handle); } return ok; }
AString CatPath(const AString& dir1, const AString& dir2) { if (dir2[0] != '/') return dir1.CatPath(dir2); return dir2; }