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