mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-27 02:27:39 +00:00
More optimized APK traversal
This commit is contained in:
parent
4eed6794c7
commit
d584360de2
@ -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;
|
|
||||||
char path[4096];
|
|
||||||
|
|
||||||
if (!(dir = opendir(name)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
|
||||||
snprintf(path, sizeof(path), "%s/%s", name,
|
|
||||||
entry->d_name);
|
|
||||||
|
|
||||||
if (entry->d_type == DT_DIR) {
|
|
||||||
if (strcmp(entry->d_name, ".") == 0
|
|
||||||
|| strcmp(entry->d_name, "..") == 0)
|
|
||||||
continue;
|
|
||||||
listdir_apk(path);
|
|
||||||
} else {
|
|
||||||
ext = &path[strlen(path) - 4];
|
|
||||||
if (!strncmp(".apk", ext, 4)) {
|
|
||||||
pthread_mutex_lock(&list_lock);
|
|
||||||
for (auto &s : hide_list) {
|
|
||||||
// Compare with (path + 10) to trim "/data/app/"
|
|
||||||
if (strncmp(path + 10, s.c_str(), s.length()) == 0) {
|
|
||||||
if (inotify_add_watch(inotify_fd, path, IN_OPEN | IN_DELETE) > 0) {
|
|
||||||
LOGI("proc_monitor: Monitoring %s\n", path);
|
LOGI("proc_monitor: Monitoring %s\n", path);
|
||||||
} else {
|
} else {
|
||||||
LOGE("proc_monitor: Failed to monitor %s: %s\n", path, strerror(errno));
|
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"
|
||||||
|
|
||||||
|
static void find_apks(char *path, char *eof) {
|
||||||
|
DIR *dir = opendir(path);
|
||||||
|
if (dir == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// assert(*eof == '\0');
|
||||||
|
|
||||||
|
struct dirent *entry;
|
||||||
|
while ((entry = xreaddir(dir))) {
|
||||||
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
if (entry->d_type == DT_DIR) {
|
||||||
|
find_apks(path, append_path(eof, entry->d_name));
|
||||||
|
*eof = '\0';
|
||||||
|
} else if (strend(entry->d_name, ".apk") == 0) {
|
||||||
|
// 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) {
|
||||||
|
if (s == path + sizeof(DATA_APP)) {
|
||||||
|
*dash = '-';
|
||||||
|
append_path(eof, entry->d_name);
|
||||||
|
xinotify_add_watch(inotify_fd, path, IN_OPEN | IN_DELETE);
|
||||||
|
*eof = '\0';
|
||||||
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() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|||||||
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*)) {
|
|||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user