1 // 2 // Copyright 2011 The Android Open Source Project 3 // 4 5 // File Finder implementation. 6 // Implementation for the functions declared and documented in FileFinder.h 7 8 #include <utils/Vector.h> 9 #include <utils/String8.h> 10 #include <utils/KeyedVector.h> 11 12 #include <dirent.h> 13 #include <sys/stat.h> 14 15 #include "DirectoryWalker.h" 16 #include "FileFinder.h" 17 18 //#define DEBUG 19 20 using android::String8; 21 22 // Private function to check whether a file is a directory or not 23 bool isDirectory(const char* filename) { 24 struct stat fileStat; 25 if (stat(filename, &fileStat) == -1) { 26 return false; 27 } 28 return(S_ISDIR(fileStat.st_mode)); 29 } 30 31 32 // Private function to check whether a file is a regular file or not 33 bool isFile(const char* filename) { 34 struct stat fileStat; 35 if (stat(filename, &fileStat) == -1) { 36 return false; 37 } 38 return(S_ISREG(fileStat.st_mode)); 39 } 40 41 bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions, 42 KeyedVector<String8,time_t>& fileStore, 43 DirectoryWalker* dw) 44 { 45 // Scan the directory pointed to by basePath 46 // check files and recurse into subdirectories. 47 if (!dw->openDir(basePath)) { 48 return false; 49 } 50 /* 51 * Go through all directory entries. Check each file using checkAndAddFile 52 * and recurse into sub-directories. 53 */ 54 struct dirent* entry; 55 while ((entry = dw->nextEntry()) != NULL) { 56 String8 entryName(entry->d_name); 57 if (entry->d_name[0] == '.') // Skip hidden files and directories 58 continue; 59 60 String8 fullPath = basePath.appendPathCopy(entryName); 61 // If this entry is a directory we'll recurse into it 62 if (isDirectory(fullPath.string()) ) { 63 DirectoryWalker* copy = dw->clone(); 64 findFiles(fullPath, extensions, fileStore,copy); 65 delete copy; 66 } 67 68 // If this entry is a file, we'll pass it over to checkAndAddFile 69 if (isFile(fullPath.string()) ) { 70 checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore); 71 } 72 } 73 74 // Clean up 75 dw->closeDir(); 76 77 return true; 78 } 79 80 void SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats, 81 Vector<String8>& extensions, 82 KeyedVector<String8,time_t>& fileStore) 83 { 84 // Loop over the extensions, checking for a match 85 bool done = false; 86 String8 ext(path.getPathExtension()); 87 ext.toLower(); 88 for (size_t i = 0; i < extensions.size() && !done; ++i) { 89 String8 ext2 = extensions[i].getPathExtension(); 90 ext2.toLower(); 91 // Compare the extensions. If a match is found, add to storage. 92 if (ext == ext2) { 93 done = true; 94 fileStore.add(path,stats->st_mtime); 95 } 96 } 97 } 98 99