From ed4df87b57789c68b8f6454d3edb4e818f3f7f6e Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 12 Feb 2019 02:44:46 -0500 Subject: [PATCH] Remove imgtool --- native/jni/Android.mk | 1 - native/jni/core/applets.cpp | 2 +- native/jni/core/img.cpp | 297 ------------------------------------ native/jni/include/img.h | 11 -- native/jni/include/magisk.h | 3 +- native/jni/utils/file.cpp | 22 +-- 6 files changed, 10 insertions(+), 326 deletions(-) delete mode 100644 native/jni/core/img.cpp delete mode 100644 native/jni/include/img.h diff --git a/native/jni/Android.mk b/native/jni/Android.mk index 2f2570462..96789cfd4 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -33,7 +33,6 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := \ core/applets.cpp \ - core/img.cpp \ core/magisk.cpp \ core/daemon.cpp \ core/logcat.cpp \ diff --git a/native/jni/core/applets.cpp b/native/jni/core/applets.cpp index e32b69745..eed645048 100644 --- a/native/jni/core/applets.cpp +++ b/native/jni/core/applets.cpp @@ -8,7 +8,7 @@ #include static int (*applet_main[]) (int, char *[]) = - { magisk_main, su_client_main, resetprop_main, magiskhide_main, imgtool_main, nullptr }; + { magisk_main, su_client_main, resetprop_main, magiskhide_main, nullptr }; char *argv0; diff --git a/native/jni/core/img.cpp b/native/jni/core/img.cpp deleted file mode 100644 index 803d298fa..000000000 --- a/native/jni/core/img.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* img.cpp - All image related functions - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define round_size(a) ((((a) / 32) + 2) * 32) -#define SOURCE_TMP "/dev/.img_src" -#define TARGET_TMP "/dev/.img_tgt" -#define MERGE_TMP "/dev/.img_mrg" - -struct fs_info { - unsigned size; - unsigned free; - unsigned used; -}; - -static char *loopsetup(const char *img) { - char device[32]; - struct loop_info64 info; - int lfd = -1, ffd; - memset(&info, 0, sizeof(info)); - if (access(BLOCKDIR, F_OK) == 0) { - for (int i = 8; i < 100; ++i) { - sprintf(device, BLOCKDIR "/loop%02d", i); - if (access(device, F_OK) != 0) - mknod(device, S_IFBLK | 0600, makedev(7, i * 8)); - lfd = open(device, O_RDWR); - if (lfd < 0) /* Kernel does not support this */ - break; - if (ioctl(lfd, LOOP_GET_STATUS64, &info) == -1) - break; - close(lfd); - lfd = -1; - } - } - // Fallback to existing loop in dev, but in reverse order - if (lfd < 0) { - for (int i = 7; i >= 0; --i) { - sprintf(device, "/dev/block/loop%d", i); - lfd = xopen(device, O_RDWR); - if (ioctl(lfd, LOOP_GET_STATUS64, &info) == -1) - break; - close(lfd); - lfd = -1; - } - } - if (lfd < 0) - return nullptr; - ffd = xopen(img, O_RDWR); - if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) - return nullptr; - strncpy((char *) info.lo_file_name, img, sizeof(info.lo_file_name)); - ioctl(lfd, LOOP_SET_STATUS64, &info); - close(lfd); - close(ffd); - return strdup(device); -} - -static void check_filesystem(struct fs_info *info, const char *img, const char *mount) { - struct stat st; - struct statfs fs; - stat(img, &st); - statfs(mount, &fs); - info->size = st.st_size / 1048576; - info->free = fs.f_bfree * (uint64_t)fs.f_frsize / 1048576; - info->used = (fs.f_blocks - fs.f_bfree) * (uint64_t)fs.f_frsize / 1048576; -} - -static void usage() { - fprintf(stderr, - "ImgTool v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) - EXT4 Image Tools\n" - "\n" - "Usage: imgtool [args...]\n" - "\n" - "Actions:\n" - " create IMG SIZE create ext4 image. SIZE is interpreted in MB\n" - " resize IMG SIZE resize ext4 image. SIZE is interpreted in MB\n" - " mount IMG PATH mount IMG to PATH and prints the loop device\n" - " umount PATH LOOP unmount PATH and delete LOOP device\n" - " merge SRC TGT merge SRC to TGT\n" - " trim IMG trim IMG to save space\n" - ); - exit(1); -} - -int imgtool_main(int argc, char *argv[]) { - if (argc < 2) - usage(); - if (strcmp(argv[1], "create") == 0) { - if (argc < 4) - usage(); - return create_img(argv[2], atoi(argv[3])); - } else if (strcmp(argv[1], "resize") == 0) { - if (argc < 4) - usage(); - return resize_img(argv[2], atoi(argv[3])); - } else if (strcmp(argv[1], "mount") == 0) { - if (argc < 4) - usage(); - // Redirect 1 > /dev/null - int fd = open("/dev/null", O_WRONLY); - int out = dup(STDOUT_FILENO); - xdup2(fd, STDOUT_FILENO); - char *loop = mount_image(argv[2], argv[3]); - // Restore stdin - xdup2(out, STDOUT_FILENO); - close(fd); - close(out); - if (loop == nullptr) { - fprintf(stderr, "Cannot mount image!\n"); - return 1; - } else { - printf("%s\n", loop); - free(loop); - return 0; - } - } else if (strcmp(argv[1], "umount") == 0) { - if (argc < 4) - usage(); - umount_image(argv[2], argv[3]); - return 0; - } else if (strcmp(argv[1], "merge") == 0) { - if (argc < 4) - usage(); - return merge_img(argv[2], argv[3]); - } else if (strcmp(argv[1], "trim") == 0) { - if (argc < 3) - usage(); - xmkdir(SOURCE_TMP, 0755); - char *loop = mount_image(argv[2], SOURCE_TMP); - int ret = trim_img(argv[2], SOURCE_TMP, loop); - umount_image(SOURCE_TMP, loop); - rmdir(SOURCE_TMP); - free(loop); - return ret; - } - usage(); - return 1; -} - -int create_img(const char *img, int size) { - if (size == 128) /* WTF...? */ - size = 132; - unlink(img); - LOGI("Create %s with size %dM\n", img, size); - char size_str[16]; - snprintf(size_str, sizeof(size_str), "%dM", size); - if (access("/system/bin/make_ext4fs", X_OK) == 0) - return exec_command_sync("/system/bin/make_ext4fs", "-b", "4096", "-l", size_str, img); - else if (access("/system/bin/mke2fs", X_OK) == 0) - // On Android P there is no make_ext4fs, use mke2fs - return exec_command_sync("/system/bin/mke2fs", "-b", "4096", "-t", "ext4", img, size_str); - else - return 1; -} - -int resize_img(const char *img, int size) { - LOGI("Resize %s to %dM\n", img, size); - exec_command_sync("/system/bin/e2fsck", "-yf", img); - char ss[16]; - snprintf(ss, sizeof(ss), "%dM", size); - return exec_command_sync("/system/bin/resize2fs", img, ss); -} - -char *mount_image(const char *img, const char *target) { - if (access(img, F_OK) == -1 || access(target, F_OK) == -1) - return nullptr; - exec_command_sync("/system/bin/e2fsck", "-yf", img); - char *device = loopsetup(img); - if (device) - xmount(device, target, "ext4", MS_NOATIME, nullptr); - return device; -} - -int umount_image(const char *target, const char *device) { - int ret = 0; - ret |= xumount(target); - int fd = xopen(device, O_RDWR); - ret |= ioctl(fd, LOOP_CLR_FD); - close(fd); - return ret; -} - -int merge_img(const char *source, const char *target) { - if (access(source, F_OK) == -1) - return 0; - if (access(target, F_OK) == -1) { - LOGI("* Move %s -> %s\n", source, target); - if (rename(source, target) < 0) { - // Copy and remove - int tgt = creat(target, 0644); - int src = xopen(source, O_RDONLY | O_CLOEXEC); - sendfile(tgt, src, 0, INT_MAX); - close(tgt); - close(src); - unlink(source); - } - return 0; - } - - char buf[PATH_MAX]; - - xmkdir(SOURCE_TMP, 0755); - xmkdir(TARGET_TMP, 0755); - char *s_loop, *t_loop, *m_loop; - s_loop = mount_image(source, SOURCE_TMP); - if (s_loop == nullptr) - return 1; - t_loop = mount_image(target, TARGET_TMP); - if (t_loop == nullptr) - return 1; - - snprintf(buf, sizeof(buf), "%s/%s", SOURCE_TMP, "lost+found"); - rm_rf(buf); - snprintf(buf, sizeof(buf), "%s/%s", TARGET_TMP, "lost+found"); - rm_rf(buf); - DIR *dir; - struct dirent *entry; - if (!(dir = xopendir(SOURCE_TMP))) - return 1; - while ((entry = xreaddir(dir))) { - if (entry->d_type == DT_DIR) { - if (strcmp(entry->d_name, ".") == 0 || - strcmp(entry->d_name, "..") == 0 || - strcmp(entry->d_name, ".core") == 0) - continue; - // Cleanup old module if exists - snprintf(buf, sizeof(buf), "%s/%s", TARGET_TMP, entry->d_name); - if (access(buf, F_OK) == 0) - rm_rf(buf); - LOGI("Upgrade/New module: %s\n", entry->d_name); - } - } - closedir(dir); - - struct fs_info src, tgt; - check_filesystem(&src, source, SOURCE_TMP); - check_filesystem(&tgt, target, TARGET_TMP); - snprintf(buf, sizeof(buf), "%s/tmp.img", dirname(target)); - create_img(buf, round_size(src.used + tgt.used)); - xmkdir(MERGE_TMP, 0755); - m_loop = mount_image(buf, MERGE_TMP); - if (m_loop == nullptr) - return 1; - - LOGI("* Merging %s + %s -> %s", source, target, buf); - cp_afc(TARGET_TMP, MERGE_TMP); - cp_afc(SOURCE_TMP, MERGE_TMP); - - // Unmount all loop devices - umount_image(SOURCE_TMP, s_loop); - umount_image(TARGET_TMP, t_loop); - umount_image(MERGE_TMP, m_loop); - rmdir(SOURCE_TMP); - rmdir(TARGET_TMP); - rmdir(MERGE_TMP); - free(s_loop); - free(t_loop); - free(m_loop); - // Cleanup - unlink(source); - LOGI("* Move %s -> %s", buf, target); - rename(buf, target); - return 0; -} - -int trim_img(const char *img, const char *mount, char *loop) { - struct fs_info info; - check_filesystem(&info, img, mount); - int new_size = round_size(info.used); - if (info.size > new_size) { - umount_image(mount, loop); - resize_img(img, new_size); - char *loop2 = mount_image(img, mount); - if (loop2 == nullptr) - return 1; - strcpy(loop, loop2); - free(loop2); - } - return 0; -} diff --git a/native/jni/include/img.h b/native/jni/include/img.h deleted file mode 100644 index 089b9b2c1..000000000 --- a/native/jni/include/img.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef IMG_H -#define IMG_H - -int create_img(const char *img, int size); -int resize_img(const char *img, int size); -char *mount_image(const char *img, const char *target); -int umount_image(const char *target, const char *device); -int merge_img(const char *source, const char *target); -int trim_img(const char *img, const char *mount, char *loop); - -#endif //IMG_H diff --git a/native/jni/include/magisk.h b/native/jni/include/magisk.h index 1ff30d2c9..94b3b5262 100644 --- a/native/jni/include/magisk.h +++ b/native/jni/include/magisk.h @@ -42,7 +42,7 @@ extern char *argv0; /* For changing process name */ extern int SDK_INT; -#define applet_names ((const char *[]) { "magisk", "su", "resetprop", "magiskhide", "imgtool", nullptr }) +#define applet_names ((const char *[]) { "magisk", "su", "resetprop", "magiskhide", nullptr }) #define init_applet ((const char *[]) { "magiskpolicy", "supolicy", nullptr }) // Multi-call entrypoints @@ -51,6 +51,5 @@ int magiskhide_main(int argc, char *argv[]); int magiskpolicy_main(int argc, char *argv[]); int su_client_main(int argc, char *argv[]); int resetprop_main(int argc, char *argv[]); -int imgtool_main(int argc, char *argv[]); #endif diff --git a/native/jni/utils/file.cpp b/native/jni/utils/file.cpp index cb4a9857e..719b6a403 100644 --- a/native/jni/utils/file.cpp +++ b/native/jni/utils/file.cpp @@ -80,20 +80,12 @@ void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) { } } -static void rm_cb(int dirfd, struct dirent *entry) { - switch (entry->d_type) { - case DT_DIR: - unlinkat(dirfd, entry->d_name, AT_REMOVEDIR); - break; - default: - unlinkat(dirfd, entry->d_name, 0); - break; - } -} - void rm_rf(const char *path) { - int fd = open(path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); - if (fd >= 0) { + struct stat st; + if (lstat(path, &st) < 0) + return; + if (S_ISDIR(st.st_mode)) { + int fd = open(path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); frm_rf(fd); close(fd); } @@ -101,7 +93,9 @@ void rm_rf(const char *path) { } void frm_rf(int dirfd) { - in_order_walk(dirfd, rm_cb); + in_order_walk(dirfd, [](auto dirfd, auto entry) -> void { + unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0); + }); } /* This will only on the same file system */