Hardlink files recursively

This commit is contained in:
topjohnwu 2018-02-02 03:22:38 +08:00
parent 28350e3ad9
commit bc2cac90fe
4 changed files with 37 additions and 14 deletions

View File

@ -141,13 +141,8 @@ void daemon_init() {
chmod("/root", 0755); chmod("/root", 0755);
root = xopen("/root", O_RDONLY | O_CLOEXEC); root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC); sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
dir = xfdopendir(sbin); link_dir(sbin, root);
while((entry = xreaddir(dir))) { unlink("/sbin/magisk");
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
linkat(sbin, entry->d_name, root, entry->d_name, 0);
if (strcmp(entry->d_name, "magisk") == 0)
unlinkat(sbin, entry->d_name, 0);
}
close(sbin); close(sbin);
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL); xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);

View File

@ -152,7 +152,7 @@ static void fstab_patch_cb(int dirfd, struct dirent *entry) {
size_t _size; size_t _size;
uint32_t size; uint32_t size;
full_read_at(dirfd, entry->d_name, &buf, &_size); full_read_at(dirfd, entry->d_name, &buf, &_size);
size = _size; /* Type conversion */ size = (uint32_t) _size; /* Type conversion */
if (!keepverity) if (!keepverity)
patch_verity(&buf, &size, 1); patch_verity(&buf, &size, 1);
if (!keepencrypt) if (!keepencrypt)
@ -203,8 +203,8 @@ static void patch_ramdisk(int root) {
} }
static int strend(const char *s1, const char *s2) { static int strend(const char *s1, const char *s2) {
int l1 = strlen(s1); size_t l1 = strlen(s1);
int l2 = strlen(s2); size_t l2 = strlen(s2);
return strcmp(s1 + l1 - l2, s2); return strcmp(s1 + l1 - l2, s2);
} }
@ -327,7 +327,7 @@ static int unxz(const void *buf, size_t size, int fd) {
lzma_stream strm = LZMA_STREAM_INIT; lzma_stream strm = LZMA_STREAM_INIT;
if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK) if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK)
return 1; return 1;
lzma_ret ret = 0; lzma_ret ret;
void *out = malloc(BUFSIZE); void *out = malloc(BUFSIZE);
strm.next_in = buf; strm.next_in = buf;
strm.avail_in = size; strm.avail_in = size;
@ -505,10 +505,10 @@ int main(int argc, char *argv[]) {
} }
} }
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
// Only patch rootfs if not intended to run in recovery // Only patch rootfs if not intended to run in recovery
if (access("/etc/recovery.fstab", F_OK) != 0) { if (access("/etc/recovery.fstab", F_OK) != 0) {
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
mv_dir(overlay, root); mv_dir(overlay, root);
patch_ramdisk(root); patch_ramdisk(root);
@ -528,16 +528,16 @@ int main(int argc, char *argv[]) {
umount("/system"); umount("/system");
} }
close(overlay);
if (fork_dont_care() == 0) { if (fork_dont_care() == 0) {
strcpy(argv[0], "magiskinit"); strcpy(argv[0], "magiskinit");
close(overlay);
close(root); close(root);
magisk_init_daemon(); magisk_init_daemon();
} }
} }
// Clean up // Clean up
close(overlay);
close(root); close(root);
umount("/vendor"); umount("/vendor");
rmdir("/overlay"); rmdir("/overlay");

View File

@ -111,6 +111,7 @@ void frm_rf(int dirfd);
void mv_f(const char *source, const char *destination); void mv_f(const char *source, const char *destination);
void mv_dir(int src, int dest); void mv_dir(int src, int dest);
void cp_afc(const char *source, const char *destination); void cp_afc(const char *source, const char *destination);
void link_dir(int src, int dest);
void clone_dir(int src, int dest); void clone_dir(int src, int dest);
int getattr(const char *path, struct file_attr *a); int getattr(const char *path, struct file_attr *a);
int getattrat(int dirfd, const char *pathname, struct file_attr *a); int getattrat(int dirfd, const char *pathname, struct file_attr *a);

View File

@ -228,6 +228,33 @@ void clone_dir(int src, int dest) {
} }
} }
void link_dir(int src, int dest) {
struct dirent *entry;
DIR *dir;
int newsrc, newdest;
struct file_attr a;
dir = xfdopendir(src);
while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (is_excl(entry->d_name))
continue;
if (entry->d_type == DT_DIR) {
getattrat(src, entry->d_name, &a);
xmkdirat(dest, entry->d_name, a.st.st_mode & 0777);
setattrat(dest, entry->d_name, &a);
newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
link_dir(newsrc, newdest);
close(newsrc);
close(newdest);
} else {
linkat(src, entry->d_name, dest, entry->d_name, 0);
}
}
}
int getattr(const char *path, struct file_attr *a) { int getattr(const char *path, struct file_attr *a) {
if (xlstat(path, &a->st) == -1) if (xlstat(path, &a->st) == -1)
return -1; return -1;