mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-28 13:17:39 +00:00
Refactor several utility functions
This commit is contained in:
parent
1913125881
commit
e3df62d812
@ -136,8 +136,7 @@ static void exec_common_script(const char* stage) {
|
||||
if (access(buf2, X_OK) == -1)
|
||||
continue;
|
||||
LOGI("%s.d: exec [%s]\n", stage, entry->d_name);
|
||||
char *const command[] = { "sh", buf2, NULL };
|
||||
int pid = run_command2(0, NULL, bb_setenv, command);
|
||||
int pid = exec_command(0, NULL, bb_setenv, "sh", buf2, NULL);
|
||||
if (pid != -1)
|
||||
waitpid(pid, NULL, 0);
|
||||
}
|
||||
@ -154,8 +153,7 @@ static void exec_module_script(const char* stage) {
|
||||
if (access(buf2, F_OK) == -1 || access(buf, F_OK) == 0)
|
||||
continue;
|
||||
LOGI("%s: exec [%s.sh]\n", module, stage);
|
||||
char *const command[] = { "sh", buf2, NULL };
|
||||
int pid = run_command2(0, NULL, bb_setenv, command);
|
||||
int pid = exec_command(0, NULL, bb_setenv, "sh", buf2, NULL);
|
||||
if (pid != -1)
|
||||
waitpid(pid, NULL, 0);
|
||||
}
|
||||
@ -402,8 +400,7 @@ static void mount_mirrors() {
|
||||
|
||||
static void link_busybox() {
|
||||
mkdir_p(BBPATH, 0755);
|
||||
char *const command[] = { MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL};
|
||||
run_command(command);
|
||||
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
|
||||
symlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
|
||||
}
|
||||
|
||||
@ -442,7 +439,7 @@ static int prepare_img() {
|
||||
snprintf(buf, PATH_MAX, "%s/%s/remove", MOUNTPOINT, entry->d_name);
|
||||
if (access(buf, F_OK) == 0) {
|
||||
snprintf(buf, PATH_MAX, "%s/%s", MOUNTPOINT, entry->d_name);
|
||||
rm_rf(buf);
|
||||
exec_command_sync(BBPATH "/rm", "-rf", buf, NULL);
|
||||
continue;
|
||||
}
|
||||
snprintf(buf, PATH_MAX, "%s/%s/disable", MOUNTPOINT, entry->d_name);
|
||||
@ -520,8 +517,7 @@ void post_fs_data(int client) {
|
||||
#ifdef MAGISK_DEBUG
|
||||
// Start debug logs in new process
|
||||
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
|
||||
char *const command[] = { "logcat", "-v", "brief", NULL };
|
||||
debug_log_pid = run_command2(0, &debug_log_fd, NULL, command);
|
||||
debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "brief", NULL);
|
||||
close(debug_log_fd);
|
||||
#endif
|
||||
|
||||
@ -531,20 +527,25 @@ void post_fs_data(int client) {
|
||||
if (buf == NULL) buf = xmalloc(PATH_MAX);
|
||||
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
|
||||
|
||||
// Cache support
|
||||
if (access("/cache/data_bin", F_OK) == 0) {
|
||||
rm_rf(DATABIN);
|
||||
rename("/cache/data_bin", DATABIN);
|
||||
// Magisk binaries
|
||||
char *bin_path = NULL;
|
||||
if (access("/cache/data_bin", F_OK) == 0)
|
||||
bin_path = "/cache/data_bin";
|
||||
else if (access("/data/local/tmp/magisk_inject", F_OK) == 0)
|
||||
bin_path = "/data/local/tmp/magisk_inject";
|
||||
if (bin_path) {
|
||||
exec_command_sync("rm", "-rf", DATABIN, NULL);
|
||||
exec_command_sync("cp", "-r", bin_path, DATABIN, NULL);
|
||||
exec_command_sync("rm", "-rf", bin_path, NULL);
|
||||
exec_command_sync("chmod", "-R", "755", bin_path, NULL);
|
||||
}
|
||||
|
||||
// Magisk Manual Injector support
|
||||
if (access("/data/local/tmp/magisk_inject", F_OK) == 0) {
|
||||
rm_rf(DATABIN);
|
||||
rename("/data/local/tmp/magisk_inject", DATABIN);
|
||||
}
|
||||
// Lazy.... use shell blob to match files
|
||||
exec_command_sync("sh", "-c", "mv /data/magisk/stock_boot* /data", NULL);
|
||||
|
||||
// Lazy.... use shell blob
|
||||
system("mv /data/magisk/stock_boot* /data;");
|
||||
// Link busybox
|
||||
mount_mirrors();
|
||||
link_busybox();
|
||||
|
||||
// Merge images
|
||||
if (merge_img("/cache/magisk.img", MAINIMG)) {
|
||||
@ -556,15 +557,12 @@ void post_fs_data(int client) {
|
||||
goto unblock;
|
||||
}
|
||||
|
||||
// Link busybox
|
||||
mount_mirrors();
|
||||
link_busybox();
|
||||
|
||||
// uninstaller
|
||||
if (access(UNINSTALLER, F_OK) == 0) {
|
||||
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
|
||||
bb_setenv();
|
||||
system("(BOOTMODE=true sh " UNINSTALLER ") &");
|
||||
setenv("BOOTMODE", "true", 1);
|
||||
exec_command(0, NULL, NULL, "sh", UNINSTALLER, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -704,11 +702,11 @@ core_only:
|
||||
if (access(MANAGERAPK, F_OK) == 0) {
|
||||
while (1) {
|
||||
sleep(5);
|
||||
char *const command[] = { "app_process",
|
||||
"/system/bin", "com.android.commands.pm.Pm",
|
||||
"install", "-r", MANAGERAPK, NULL };
|
||||
int apk_res = -1, pid;
|
||||
pid = run_command2(1, &apk_res, pm_setenv, command);
|
||||
pid = exec_command(1, &apk_res, pm_setenv,
|
||||
"app_process",
|
||||
"/system/bin", "com.android.commands.pm.Pm",
|
||||
"install", "-r", MANAGERAPK, NULL);
|
||||
if (pid != -1) {
|
||||
waitpid(pid, NULL, 0);
|
||||
fdgets(buf, PATH_MAX, apk_res);
|
||||
|
@ -26,13 +26,11 @@ static void *logger_thread(void *args) {
|
||||
|
||||
while (1) {
|
||||
// Start logcat
|
||||
char *const command[] = { "logcat", "-s", "Magisk", "-v", "thread", NULL };
|
||||
log_pid = run_command2(0, &log_fd, NULL, command);
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-s", "Magisk", "-v", "thread", NULL);
|
||||
if (log_pid > 0)
|
||||
waitpid(log_pid, NULL, 0);
|
||||
// For some reason it went here, clear buffer and restart
|
||||
char *const restart[] = { "logcat", "-c", NULL };
|
||||
run_command(restart);
|
||||
exec_command_sync("logcat", "-c", NULL);
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
|
@ -75,21 +75,18 @@ unsigned get_radio_uid();
|
||||
int check_data();
|
||||
int file_to_vector(const char* filename, struct vector *v);
|
||||
int vector_to_file(const char* filename, struct vector *v);
|
||||
int isNum(const char *s);
|
||||
ssize_t fdgets(char *buf, size_t size, int fd);
|
||||
void ps(void (*func)(int));
|
||||
void ps_filter_proc_name(const char *filter, void (*func)(int));
|
||||
int create_links(const char *bin, const char *path);
|
||||
void unlock_blocks();
|
||||
void setup_sighandlers(void (*handler)(int));
|
||||
int run_command(char *const argv[]);
|
||||
int run_command2(int err, int *fd, void (*cb)(void), char *const argv[]);
|
||||
int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...);
|
||||
int exec_command_sync(char *const argv0, ...);
|
||||
int mkdir_p(const char *pathname, mode_t mode);
|
||||
int bind_mount(const char *from, const char *to);
|
||||
int open_new(const char *filename);
|
||||
int cp_afc(const char *source, const char *target);
|
||||
int clone_dir(const char *source, const char *target);
|
||||
void rm_rf(const char *target);
|
||||
void fclone_attr(const int sourcefd, const int targetfd);
|
||||
void clone_attr(const char *source, const char *target);
|
||||
void get_client_cred(int fd, struct ucred *cred);
|
||||
|
@ -32,4 +32,4 @@ struct vector *vec_dup(struct vector *v);
|
||||
e = v ? (v)->data[(v)->size - 1] : NULL; \
|
||||
for (size_t _ = (v)->size; v && _ > 0; --_, e = (v)->data[_ - 1])
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -181,13 +181,11 @@ void proc_monitor() {
|
||||
|
||||
while (1) {
|
||||
// Clear previous logcat buffer
|
||||
char *const restart[] = { "logcat", "-b", "events", "-c", NULL };
|
||||
run_command(restart);
|
||||
exec_command_sync("logcat", "-b", "events", "-c", NULL);
|
||||
|
||||
// Monitor am_proc_start
|
||||
char *const command[] = { "logcat", "-b", "events", "-v", "raw", "-s", "am_proc_start", NULL };
|
||||
log_fd = -1;
|
||||
log_pid = run_command2(0, &log_fd, NULL, command);
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "events", "-v", "raw", "-s", "am_proc_start", NULL);
|
||||
|
||||
if (log_pid < 0) continue;
|
||||
if (kill(log_pid, 0)) continue;
|
||||
|
@ -14,8 +14,7 @@ static int e2fsck(const char *img) {
|
||||
// Check and repair ext4 image
|
||||
char buffer[128];
|
||||
int pid, fd = -1;
|
||||
char *const command[] = { "e2fsck", "-yf", (char *) img, NULL };
|
||||
pid = run_command2(1, &fd, NULL, command);
|
||||
pid = exec_command(1, &fd, NULL, "e2fsck", "-yf", img, NULL);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
while (fdgets(buffer, sizeof(buffer), fd))
|
||||
@ -56,19 +55,17 @@ int create_img(const char *img, int size) {
|
||||
char file_contexts[] = "/magisk(/.*)? u:object_r:system_file:s0\n";
|
||||
// If not root, attempt to create in current diretory
|
||||
char *filename = getuid() == UID_ROOT ? "/dev/file_contexts_image" : "file_contexts_image";
|
||||
int pid, status, fd = xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
int ret, fd = xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
xwrite(fd, file_contexts, sizeof(file_contexts));
|
||||
close(fd);
|
||||
|
||||
char buffer[16];
|
||||
snprintf(buffer, sizeof(buffer), "%dM", size);
|
||||
char *const command[] = { "make_ext4fs", "-l", buffer, "-a", "/magisk", "-S", filename, (char *) img, NULL };
|
||||
pid = run_command2(0, NULL, NULL, command);
|
||||
if (pid < 0)
|
||||
ret = exec_command_sync("make_ext4fs", "-l", buffer, "-a", "/magisk", "-S", filename, img, NULL);
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
waitpid(pid, &status, 0);
|
||||
unlink(filename);
|
||||
return WEXITSTATUS(status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int get_img_size(const char *img, int *used, int *total) {
|
||||
@ -76,8 +73,7 @@ int get_img_size(const char *img, int *used, int *total) {
|
||||
return 1;
|
||||
char buffer[PATH_MAX];
|
||||
int pid, fd = -1, status = 1;
|
||||
char *const command[] = { "e2fsck", "-n", (char *) img, NULL };
|
||||
pid = run_command2(1, &fd, NULL, command);
|
||||
pid = exec_command(1, &fd, NULL, "e2fsck", "-n", img, NULL);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
while (fdgets(buffer, sizeof(buffer), fd)) {
|
||||
@ -109,8 +105,7 @@ int resize_img(const char *img, int size) {
|
||||
char buffer[128];
|
||||
int pid, status, fd = -1;
|
||||
snprintf(buffer, sizeof(buffer), "%dM", size);
|
||||
char *const command[] = { "resize2fs", (char *) img, buffer, NULL };
|
||||
pid = run_command2(1, &fd, NULL, command);
|
||||
pid = exec_command(1, &fd, NULL, "resize2fs", img, buffer, NULL);
|
||||
if (pid < 0)
|
||||
return 1;
|
||||
while (fdgets(buffer, sizeof(buffer), fd))
|
||||
@ -188,14 +183,14 @@ int merge_img(const char *source, const char *target) {
|
||||
snprintf(buffer, sizeof(buffer), "%s/%s", TARGET_TMP, entry->d_name);
|
||||
if (access(buffer, F_OK) == 0) {
|
||||
LOGI("Upgrade module: %s\n", entry->d_name);
|
||||
rm_rf(buffer);
|
||||
exec_command_sync(BBPATH "/rm", "-rf", buffer, NULL);
|
||||
} else {
|
||||
LOGI("New module: %s\n", entry->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
clone_dir(SOURCE_TMP, TARGET_TMP);
|
||||
cp_afc(SOURCE_TMP, TARGET_TMP);
|
||||
|
||||
// Unmount all loop devices
|
||||
umount_image(SOURCE_TMP, s_loop);
|
||||
|
146
jni/utils/misc.c
146
jni/utils/misc.c
@ -5,6 +5,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
@ -97,7 +98,7 @@ int vector_to_file(const char *filename, struct vector *v) {
|
||||
}
|
||||
|
||||
/* Check if the string only contains digits */
|
||||
int isNum(const char *s) {
|
||||
static int is_num(const char *s) {
|
||||
int len = strlen(s);
|
||||
for (int i = 0; i < len; ++i)
|
||||
if (s[i] < '0' || s[i] > '9')
|
||||
@ -129,7 +130,7 @@ void ps(void (*func)(int)) {
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
if (isNum(entry->d_name))
|
||||
if (is_num(entry->d_name))
|
||||
func(atoi(entry->d_name));
|
||||
}
|
||||
}
|
||||
@ -219,22 +220,13 @@ void setup_sighandlers(void (*handler)(int)) {
|
||||
}
|
||||
}
|
||||
|
||||
int run_command(char *const argv[]) {
|
||||
int pid = run_command2(0, NULL, NULL, argv);
|
||||
if (pid != -1)
|
||||
waitpid(pid, NULL, 0);
|
||||
else
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
fd == NULL -> Ignore output
|
||||
*fd < 0 -> Open pipe and set *fd to the read end
|
||||
*fd >= 0 -> STDOUT (or STDERR) will be redirected to *fd
|
||||
*cb -> A callback function which runs after fork
|
||||
*/
|
||||
int run_command2(int err, int *fd, void (*cb)(void), char *const argv[]) {
|
||||
static int v_exec_command(int err, int *fd, void (*cb)(void), const char *argv0, va_list argv) {
|
||||
int pipefd[2], writeEnd = -1;
|
||||
|
||||
if (fd) {
|
||||
@ -257,6 +249,9 @@ int run_command2(int err, int *fd, void (*cb)(void), char *const argv[]) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
// Don't affect the daemon if anything wrong happens
|
||||
err_handler = do_nothing;
|
||||
|
||||
if (cb) cb();
|
||||
|
||||
if (fd) {
|
||||
@ -264,11 +259,39 @@ int run_command2(int err, int *fd, void (*cb)(void), char *const argv[]) {
|
||||
if (err) xdup2(writeEnd, STDERR_FILENO);
|
||||
}
|
||||
|
||||
execvp(argv[0], argv);
|
||||
PLOGE("execv");
|
||||
// Collect va_list into vector
|
||||
struct vector v;
|
||||
vec_init(&v);
|
||||
vec_push_back(&v, (void *) argv0);
|
||||
for (void *arg = va_arg(argv, void*); arg; arg = va_arg(argv, void*))
|
||||
vec_push_back(&v, arg);
|
||||
vec_push_back(&v, NULL);
|
||||
|
||||
execvp(argv0, (char **) vec_entry(&v));
|
||||
PLOGE("execvp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int exec_command_sync(char *const argv0, ...) {
|
||||
va_list argv;
|
||||
va_start(argv, argv0);
|
||||
int pid, status;
|
||||
pid = v_exec_command(0, NULL, NULL, argv0, argv);
|
||||
va_end(argv);
|
||||
if (pid < 0)
|
||||
return pid;
|
||||
waitpid(pid, &status, 0);
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...) {
|
||||
va_list argv;
|
||||
va_start(argv, argv0);
|
||||
int pid = v_exec_command(err, fd, cb, argv0, argv);
|
||||
va_end(argv);
|
||||
return pid;
|
||||
}
|
||||
|
||||
int mkdir_p(const char *pathname, mode_t mode) {
|
||||
char *path = strdup(pathname), *p;
|
||||
errno = 0;
|
||||
@ -304,78 +327,57 @@ int open_new(const char *filename) {
|
||||
return xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
}
|
||||
|
||||
// file/link -> file/link only!!
|
||||
int cp_afc(const char *source, const char *target) {
|
||||
struct stat buf;
|
||||
xlstat(source, &buf);
|
||||
unlink(target);
|
||||
char *con;
|
||||
if (S_ISREG(buf.st_mode)) {
|
||||
int sfd, tfd;
|
||||
sfd = xopen(source, O_RDONLY);
|
||||
tfd = xopen(target, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
xsendfile(tfd, sfd, NULL, buf.st_size);
|
||||
fclone_attr(sfd, tfd);
|
||||
close(sfd);
|
||||
close(tfd);
|
||||
} else if (S_ISLNK(buf.st_mode)) {
|
||||
char buffer[PATH_MAX];
|
||||
xreadlink(source, buffer, sizeof(buffer));
|
||||
xsymlink(buffer, target);
|
||||
lchown(target, buf.st_uid, buf.st_gid);
|
||||
lgetfilecon(source, &con);
|
||||
lsetfilecon(target, con);
|
||||
free(con);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clone_dir(const char *source, const char *target) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char *s_path, *t_path;
|
||||
if (S_ISDIR(buf.st_mode)) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char *s_path, *t_path;
|
||||
|
||||
if (!(dir = xopendir(source)))
|
||||
return 1;
|
||||
if (!(dir = xopendir(source)))
|
||||
return 1;
|
||||
|
||||
s_path = xmalloc(PATH_MAX);
|
||||
t_path = xmalloc(PATH_MAX);
|
||||
s_path = xmalloc(PATH_MAX);
|
||||
t_path = xmalloc(PATH_MAX);
|
||||
|
||||
mkdir_p(target, 0755);
|
||||
clone_attr(source, target);
|
||||
mkdir_p(target, 0755);
|
||||
clone_attr(source, target);
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
snprintf(s_path, PATH_MAX, "%s/%s", source, entry->d_name);
|
||||
snprintf(t_path, PATH_MAX, "%s/%s", target, entry->d_name);
|
||||
switch (entry->d_type) {
|
||||
case DT_DIR:
|
||||
clone_dir(s_path, t_path);
|
||||
break;
|
||||
case DT_REG:
|
||||
case DT_LNK:
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
snprintf(s_path, PATH_MAX, "%s/%s", source, entry->d_name);
|
||||
snprintf(t_path, PATH_MAX, "%s/%s", target, entry->d_name);
|
||||
cp_afc(s_path, t_path);
|
||||
break;
|
||||
}
|
||||
free(s_path);
|
||||
free(t_path);
|
||||
|
||||
closedir(dir);
|
||||
} else{
|
||||
unlink(target);
|
||||
if (S_ISREG(buf.st_mode)) {
|
||||
int sfd, tfd;
|
||||
sfd = xopen(source, O_RDONLY);
|
||||
tfd = xopen(target, O_WRONLY | O_CREAT | O_TRUNC);
|
||||
xsendfile(tfd, sfd, NULL, buf.st_size);
|
||||
fclone_attr(sfd, tfd);
|
||||
close(sfd);
|
||||
close(tfd);
|
||||
} else if (S_ISLNK(buf.st_mode)) {
|
||||
char buffer[PATH_MAX];
|
||||
xreadlink(source, buffer, sizeof(buffer));
|
||||
xsymlink(buffer, target);
|
||||
clone_attr(source, target);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free(s_path);
|
||||
free(t_path);
|
||||
|
||||
closedir(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rm_rf(const char *target) {
|
||||
if (access(target, F_OK) == -1)
|
||||
return;
|
||||
// Use external rm command, saves a lot of headache and issues
|
||||
char *const command[] = { "rm", "-rf", (char*) target, NULL };
|
||||
run_command(command);
|
||||
}
|
||||
|
||||
void clone_attr(const char *source, const char *target) {
|
||||
int sourcefd, targetfd;
|
||||
sourcefd = xopen(source, O_RDONLY);
|
||||
|
Loading…
x
Reference in New Issue
Block a user