blob: 69a8fa9fc6f276f3bd61c592cf4974b89531329b [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001//
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
Tomasz Wasilczyk804e8192023-08-23 02:22:53 +00008#include <androidfw/PathUtils.h>
Adam Lesinski282e1812014-01-23 18:17:42 -08009#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
21using android::String8;
22
23// Private function to check whether a file is a directory or not
24bool 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
34bool 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
42bool 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
Tomasz Wasilczyk804e8192023-08-23 02:22:53 +000061 String8 fullPath = appendPathCopy(basePath, entryName);
Adam Lesinski282e1812014-01-23 18:17:42 -080062 // If this entry is a directory we'll recurse into it
Tomasz Wasilczykd2a69832023-08-10 23:54:44 +000063 if (isDirectory(fullPath.c_str()) ) {
Adam Lesinski282e1812014-01-23 18:17:42 -080064 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
Tomasz Wasilczykd2a69832023-08-10 23:54:44 +000070 if (isFile(fullPath.c_str()) ) {
Adam Lesinski282e1812014-01-23 18:17:42 -080071 checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);
72 }
73 }
74
75 // Clean up
76 dw->closeDir();
77
78 return true;
79}
80
Chih-Hung Hsieh9b8528f2016-08-10 14:15:30 -070081void SystemFileFinder::checkAndAddFile(const String8& path, const struct stat* stats,
Adam Lesinski282e1812014-01-23 18:17:42 -080082 Vector<String8>& extensions,
83 KeyedVector<String8,time_t>& fileStore)
84{
85 // Loop over the extensions, checking for a match
86 bool done = false;
Tomasz Wasilczyk804e8192023-08-23 02:22:53 +000087 String8 ext(getPathExtension(path));
Adam Lesinski282e1812014-01-23 18:17:42 -080088 ext.toLower();
89 for (size_t i = 0; i < extensions.size() && !done; ++i) {
Tomasz Wasilczyk804e8192023-08-23 02:22:53 +000090 String8 ext2 = getPathExtension(extensions[i]);
Adam Lesinski282e1812014-01-23 18:17:42 -080091 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