Commit d584360d authored by topjohnwu's avatar topjohnwu

More optimized APK traversal

parent 4eed6794
...@@ -188,51 +188,64 @@ static bool process_pid(int pid) { ...@@ -188,51 +188,64 @@ static bool process_pid(int pid) {
return true; return true;
} }
static void listdir_apk(const char *name) { static int xinotify_add_watch(int fd, const char* path, uint32_t mask) {
DIR *dir; int ret = inotify_add_watch(fd, path, mask);
struct dirent *entry; if (ret >= 0) {
const char *ext; LOGI("proc_monitor: Monitoring %s\n", path);
char path[4096]; } else {
PLOGE("proc_monitor: Monitor %s", path);
}
return ret;
}
static char *append_path(char *eof, const char *name) {
*(eof++) = '/';
char c;
while ((c = *(name++)))
*(eof++) = c;
*eof = '\0';
return eof;
}
#define DATA_APP "/data/app"
if (!(dir = opendir(name))) static void find_apks(char *path, char *eof) {
DIR *dir = opendir(path);
if (dir == nullptr)
return; return;
while ((entry = readdir(dir)) != NULL) { // assert(*eof == '\0');
snprintf(path, sizeof(path), "%s/%s", name,
entry->d_name);
if (entry->d_type == DT_DIR) { struct dirent *entry;
if (strcmp(entry->d_name, ".") == 0 while ((entry = xreaddir(dir))) {
|| strcmp(entry->d_name, "..") == 0) if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue; continue;
listdir_apk(path); if (entry->d_type == DT_DIR) {
} else { find_apks(path, append_path(eof, entry->d_name));
ext = &path[strlen(path) - 4]; *eof = '\0';
if (!strncmp(".apk", ext, 4)) { } else if (strend(entry->d_name, ".apk") == 0) {
pthread_mutex_lock(&list_lock); // Path will be in this format: /data/app/[pkg]-[hash or 1 or 2]
char *dash = strchr(path, '-');
*dash = '\0';
for (auto &s : hide_list) { for (auto &s : hide_list) {
// Compare with (path + 10) to trim "/data/app/" if (s == path + sizeof(DATA_APP)) {
if (strncmp(path + 10, s.c_str(), s.length()) == 0) { *dash = '-';
if (inotify_add_watch(inotify_fd, path, IN_OPEN | IN_DELETE) > 0) { append_path(eof, entry->d_name);
LOGI("proc_monitor: Monitoring %s\n", path); xinotify_add_watch(inotify_fd, path, IN_OPEN | IN_DELETE);
} else { *eof = '\0';
LOGE("proc_monitor: Failed to monitor %s: %s\n", path, strerror(errno));
}
break; break;
} }
} }
pthread_mutex_unlock(&list_lock); *dash = '-';
} break;
} }
} }
closedir(dir); closedir(dir);
} }
// Iterate through /data/app and search all .apk files // Iterate through /data/app and search all .apk files
void update_inotify_mask() { void update_inotify_mask() {
// Setup inotify char buf[4096];
const char data_app[] = "/data/app";
if (inotify_fd >= 0) if (inotify_fd >= 0)
close(inotify_fd); close(inotify_fd);
...@@ -244,14 +257,13 @@ void update_inotify_mask() { ...@@ -244,14 +257,13 @@ void update_inotify_mask() {
} }
LOGI("proc_monitor: Updating APK list\n"); LOGI("proc_monitor: Updating APK list\n");
listdir_apk(data_app); strcpy(buf, DATA_APP);
pthread_mutex_lock(&list_lock);
find_apks(buf, buf + sizeof(DATA_APP) - 1);
pthread_mutex_unlock(&list_lock);
// Add /data/app itself to the watch list to detect app (un)installations/updates // Add /data/app itself to the watch list to detect app (un)installations/updates
if (inotify_add_watch(inotify_fd, data_app, IN_CLOSE_WRITE | IN_MOVED_TO | IN_DELETE) > 0) { xinotify_add_watch(inotify_fd, DATA_APP, IN_CLOSE_WRITE | IN_MOVED_TO | IN_DELETE);
LOGI("proc_monitor: Monitoring %s\n", data_app, inotify_fd);
} else {
LOGE("proc_monitor: Failed to monitor %s: %s\n", strerror(errno));
}
} }
void proc_monitor() { void proc_monitor() {
......
...@@ -60,7 +60,7 @@ int mkdirs(const char *pathname, mode_t mode) { ...@@ -60,7 +60,7 @@ int mkdirs(const char *pathname, mode_t mode) {
return 0; return 0;
} }
void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) { void post_order_walk(int dirfd, void (*fn)(int, struct dirent *)) {
struct dirent *entry; struct dirent *entry;
int newfd; int newfd;
DIR *dir = fdopendir(dirfd); DIR *dir = fdopendir(dirfd);
...@@ -73,10 +73,10 @@ void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) { ...@@ -73,10 +73,10 @@ void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) {
continue; continue;
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
in_order_walk(newfd, callback); post_order_walk(newfd, fn);
close(newfd); close(newfd);
} }
callback(dirfd, entry); fn(dirfd, entry);
} }
} }
...@@ -93,7 +93,7 @@ void rm_rf(const char *path) { ...@@ -93,7 +93,7 @@ void rm_rf(const char *path) {
} }
void frm_rf(int dirfd) { void frm_rf(int dirfd) {
in_order_walk(dirfd, [](auto dirfd, auto entry) -> void { post_order_walk(dirfd, [](auto dirfd, auto entry) -> void {
unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0); unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0);
}); });
} }
......
...@@ -108,7 +108,7 @@ struct file_attr { ...@@ -108,7 +108,7 @@ struct file_attr {
int fd_getpath(int fd, char *path, size_t size); int fd_getpath(int fd, char *path, size_t size);
int fd_getpathat(int dirfd, const char *name, char *path, size_t size); int fd_getpathat(int dirfd, const char *name, char *path, size_t size);
int mkdirs(const char *pathname, mode_t mode); int mkdirs(const char *pathname, mode_t mode);
void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)); void post_order_walk(int dirfd, void (*fn)(int, struct dirent *));
void rm_rf(const char *path); void rm_rf(const char *path);
void frm_rf(int dirfd); void frm_rf(int dirfd);
void mv_f(const char *source, const char *destination); void mv_f(const char *source, const char *destination);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment