mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-05-06 17:34:25 +02:00
Refactor init.cpp to init.rs
This commit is contained in:
parent
563f0d5ad5
commit
143743d0b0
@ -63,7 +63,6 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libinit-rs
|
libinit-rs
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
init/init.cpp \
|
|
||||||
init/mount.cpp \
|
init/mount.cpp \
|
||||||
init/rootdir.cpp \
|
init/rootdir.cpp \
|
||||||
init/getinfo.cpp \
|
init/getinfo.cpp \
|
||||||
|
@ -192,7 +192,7 @@ void BootConfig::init() noexcept {
|
|||||||
print();
|
print();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_two_stage() {
|
bool MagiskInit::check_two_stage() const noexcept {
|
||||||
if (access("/first_stage_ramdisk", F_OK) == 0)
|
if (access("/first_stage_ramdisk", F_OK) == 0)
|
||||||
return true;
|
return true;
|
||||||
if (access("/second_stage_resources", F_OK) == 0)
|
if (access("/second_stage_resources", F_OK) == 0)
|
||||||
@ -206,19 +206,3 @@ bool check_two_stage() {
|
|||||||
mmap_data init(backup_init());
|
mmap_data init(backup_init());
|
||||||
return init.contains("selinux_setup");
|
return init.contains("selinux_setup");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unxz_init(const char *init_xz, const char *init) {
|
|
||||||
LOGD("unxz %s -> %s\n", init_xz, init);
|
|
||||||
int fd = xopen(init, O_WRONLY | O_CREAT, 0777);
|
|
||||||
fd_stream ch(fd);
|
|
||||||
unxz(ch, mmap_data{init_xz});
|
|
||||||
close(fd);
|
|
||||||
clone_attr(init_xz, init);
|
|
||||||
unlink(init_xz);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *backup_init() {
|
|
||||||
if (access("/.backup/init.xz", F_OK) == 0)
|
|
||||||
unxz_init("/.backup/init.xz", "/.backup/init");
|
|
||||||
return "/.backup/init";
|
|
||||||
}
|
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <xz.h>
|
|
||||||
|
|
||||||
#include <base.hpp>
|
|
||||||
|
|
||||||
#include "init.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#ifdef USE_CRT0
|
|
||||||
__BEGIN_DECLS
|
|
||||||
int tiny_vfprintf(FILE *stream, const char *format, va_list arg);
|
|
||||||
int vfprintf(FILE *stream, const char *format, va_list arg) {
|
|
||||||
return tiny_vfprintf(stream, format, arg);
|
|
||||||
}
|
|
||||||
__END_DECLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
|
|
||||||
uint8_t out[8192];
|
|
||||||
xz_crc32_init();
|
|
||||||
size_t size = bytes.size();
|
|
||||||
struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 1 << 26);
|
|
||||||
run_finally finally([&] { xz_dec_end(dec); });
|
|
||||||
struct xz_buf b = {
|
|
||||||
.in = bytes.data(),
|
|
||||||
.in_pos = 0,
|
|
||||||
.in_size = size,
|
|
||||||
.out = out,
|
|
||||||
.out_pos = 0,
|
|
||||||
.out_size = sizeof(out)
|
|
||||||
};
|
|
||||||
enum xz_ret ret;
|
|
||||||
do {
|
|
||||||
ret = xz_dec_run(dec, &b);
|
|
||||||
if (ret != XZ_OK && ret != XZ_STREAM_END)
|
|
||||||
return false;
|
|
||||||
strm.write(out, b.out_pos);
|
|
||||||
b.out_pos = 0;
|
|
||||||
} while (b.in_pos != size);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void restore_ramdisk_init() {
|
|
||||||
unlink("/init");
|
|
||||||
|
|
||||||
const char *orig_init = backup_init();
|
|
||||||
if (access(orig_init, F_OK) == 0) {
|
|
||||||
xrename(orig_init, "/init");
|
|
||||||
} else {
|
|
||||||
// If the backup init is missing, this means that the boot ramdisk
|
|
||||||
// was created from scratch, and the real init is in a separate CPIO,
|
|
||||||
// which is guaranteed to be placed at /system/bin/init.
|
|
||||||
xsymlink(INIT_PATH, "/init");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void recovery() {
|
|
||||||
LOGI("Ramdisk is recovery, abort\n");
|
|
||||||
restore_ramdisk_init();
|
|
||||||
rm_rf("/.backup");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MagiskInit::legacy_system_as_root() noexcept {
|
|
||||||
LOGI("Legacy SAR Init\n");
|
|
||||||
prepare_data();
|
|
||||||
bool is_two_stage = mount_system_root();
|
|
||||||
if (is_two_stage)
|
|
||||||
redirect_second_stage();
|
|
||||||
else
|
|
||||||
patch_ro_root();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MagiskInit::rootfs() noexcept {
|
|
||||||
LOGI("RootFS Init\n");
|
|
||||||
prepare_data();
|
|
||||||
LOGD("Restoring /init\n");
|
|
||||||
rename(backup_init(), "/init");
|
|
||||||
patch_rw_root();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MagiskInit::start() noexcept {
|
|
||||||
if (argv[1] != nullptr && argv[1] == "selinux_setup"sv)
|
|
||||||
second_stage();
|
|
||||||
else if (config.skip_initramfs)
|
|
||||||
legacy_system_as_root();
|
|
||||||
else if (config.force_normal_boot)
|
|
||||||
first_stage();
|
|
||||||
else if (access("/sbin/recovery", F_OK) == 0 || access("/system/bin/recovery", F_OK) == 0)
|
|
||||||
recovery();
|
|
||||||
else if (check_two_stage())
|
|
||||||
first_stage();
|
|
||||||
else
|
|
||||||
rootfs();
|
|
||||||
|
|
||||||
// Finally execute the original init
|
|
||||||
exec_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
umask(0);
|
|
||||||
|
|
||||||
auto name = basename(argv[0]);
|
|
||||||
if (name == "magisk"sv)
|
|
||||||
return magisk_proxy_main(argc, argv);
|
|
||||||
|
|
||||||
if (getpid() != 1)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
rust::start_magisk_init(argv);
|
|
||||||
}
|
|
@ -1,14 +1,10 @@
|
|||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <stream.hpp>
|
#include <stream.hpp>
|
||||||
|
|
||||||
#include "init-rs.hpp"
|
|
||||||
|
|
||||||
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
|
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
|
||||||
#define INIT_PATH "/system/bin/init"
|
#define INIT_PATH "/system/bin/init"
|
||||||
#define REDIR_PATH "/data/magiskinit"
|
#define REDIR_PATH "/data/magiskinit"
|
||||||
|
|
||||||
int magisk_proxy_main(int argc, char *argv[]);
|
int magisk_proxy_main(int argc, char *argv[]);
|
||||||
bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes);
|
|
||||||
bool check_two_stage();
|
#include "init-rs.hpp"
|
||||||
const char *backup_init();
|
|
||||||
void restore_ramdisk_init();
|
|
||||||
|
154
native/src/init/init.rs
Normal file
154
native/src/init/init.rs
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
use crate::ffi::{magisk_proxy_main, BootConfig, MagiskInit};
|
||||||
|
use crate::logging::setup_klog;
|
||||||
|
use base::{
|
||||||
|
cstr, debug, info,
|
||||||
|
libc::{basename, getpid, mount, umask},
|
||||||
|
raw_cstr, FsPath, LibcReturn, LoggedResult, ResultExt, Utf8CStr,
|
||||||
|
};
|
||||||
|
use std::ffi::{c_char, CStr};
|
||||||
|
use std::ptr::null as nullptr;
|
||||||
|
|
||||||
|
impl MagiskInit {
|
||||||
|
fn new(argv: *mut *mut c_char) -> Self {
|
||||||
|
Self {
|
||||||
|
preinit_dev: String::new(),
|
||||||
|
mount_list: Vec::new(),
|
||||||
|
argv,
|
||||||
|
config: BootConfig {
|
||||||
|
skip_initramfs: false,
|
||||||
|
force_normal_boot: false,
|
||||||
|
rootwait: false,
|
||||||
|
emulator: false,
|
||||||
|
slot: [0; 3],
|
||||||
|
dt_dir: [0; 64],
|
||||||
|
fstab_suffix: [0; 32],
|
||||||
|
hardware: [0; 32],
|
||||||
|
hardware_plat: [0; 32],
|
||||||
|
partition_map: Vec::new(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn legacy_system_as_root(&mut self) {
|
||||||
|
info!("Legacy SAR Init");
|
||||||
|
self.prepare_data();
|
||||||
|
if self.mount_system_root() {
|
||||||
|
self.redirect_second_stage();
|
||||||
|
} else {
|
||||||
|
self.patch_ro_root();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn rootfs(&mut self) {
|
||||||
|
info!("RootFS Init");
|
||||||
|
self.prepare_data();
|
||||||
|
debug!("Restoring /init\n");
|
||||||
|
FsPath::from(cstr!("/.backup/init"))
|
||||||
|
.rename_to(FsPath::from(cstr!("/init")))
|
||||||
|
.log()
|
||||||
|
.ok();
|
||||||
|
self.patch_rw_root();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn recovery(&self) {
|
||||||
|
info!("Ramdisk is recovery, abort");
|
||||||
|
self.restore_ramdisk_init();
|
||||||
|
FsPath::from(cstr!("/.backup")).remove_all().ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn restore_ramdisk_init(&self) {
|
||||||
|
FsPath::from(cstr!("/init")).remove().ok();
|
||||||
|
|
||||||
|
let orig_init = FsPath::from(unsafe { Utf8CStr::from_ptr_unchecked(self.backup_init()) });
|
||||||
|
|
||||||
|
if orig_init.exists() {
|
||||||
|
orig_init.rename_to(FsPath::from(cstr!("/init"))).log().ok();
|
||||||
|
} else {
|
||||||
|
// If the backup init is missing, this means that the boot ramdisk
|
||||||
|
// was created from scratch, and the real init is in a separate CPIO,
|
||||||
|
// which is guaranteed to be placed at /system/bin/init.
|
||||||
|
FsPath::from(cstr!("/system/bin/init"))
|
||||||
|
.symlink_to(FsPath::from(cstr!("/init")))
|
||||||
|
.log()
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start(&mut self) -> LoggedResult<()> {
|
||||||
|
if !FsPath::from(cstr!("/proc/cmdline")).exists() {
|
||||||
|
FsPath::from(cstr!("/proc")).mkdir(0o755)?;
|
||||||
|
unsafe {
|
||||||
|
mount(
|
||||||
|
raw_cstr!("proc"),
|
||||||
|
raw_cstr!("/proc"),
|
||||||
|
raw_cstr!("proc"),
|
||||||
|
0,
|
||||||
|
nullptr(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.as_os_err()?;
|
||||||
|
self.mount_list.push("/proc".to_string());
|
||||||
|
}
|
||||||
|
if !FsPath::from(cstr!("/sys/block")).exists() {
|
||||||
|
FsPath::from(cstr!("/sys")).mkdir(0o755)?;
|
||||||
|
unsafe {
|
||||||
|
mount(
|
||||||
|
raw_cstr!("sysfs"),
|
||||||
|
raw_cstr!("/sys"),
|
||||||
|
raw_cstr!("sysfs"),
|
||||||
|
0,
|
||||||
|
nullptr(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.as_os_err()?;
|
||||||
|
self.mount_list.push("/sys".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_klog();
|
||||||
|
|
||||||
|
self.config.init();
|
||||||
|
|
||||||
|
let argv1 = unsafe { *self.argv.offset(1) };
|
||||||
|
if !argv1.is_null() && unsafe { CStr::from_ptr(argv1) == c"selinux_setup" } {
|
||||||
|
self.second_stage();
|
||||||
|
} else if self.config.skip_initramfs {
|
||||||
|
self.legacy_system_as_root();
|
||||||
|
} else if self.config.force_normal_boot {
|
||||||
|
self.first_stage();
|
||||||
|
} else if FsPath::from(cstr!("/sbin/recovery")).exists()
|
||||||
|
|| FsPath::from(cstr!("/system/bin/recovery")).exists()
|
||||||
|
{
|
||||||
|
self.recovery();
|
||||||
|
} else if self.check_two_stage() {
|
||||||
|
self.first_stage();
|
||||||
|
} else {
|
||||||
|
self.rootfs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally execute the original init
|
||||||
|
self.exec_init();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn main(
|
||||||
|
argc: i32,
|
||||||
|
argv: *mut *mut c_char,
|
||||||
|
_envp: *const *const c_char,
|
||||||
|
) -> i32 {
|
||||||
|
umask(0);
|
||||||
|
|
||||||
|
let name = basename(*argv);
|
||||||
|
|
||||||
|
if CStr::from_ptr(name) == c"magisk" {
|
||||||
|
return magisk_proxy_main(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if getpid() == 1 {
|
||||||
|
MagiskInit::new(argv).start().log().ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
||||||
|
}
|
@ -2,23 +2,17 @@
|
|||||||
#![feature(once_cell_try)]
|
#![feature(once_cell_try)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
|
||||||
use base::{
|
|
||||||
cstr,
|
|
||||||
libc::{mount},
|
|
||||||
raw_cstr, FsPath, LibcReturn, LoggedResult,
|
|
||||||
};
|
|
||||||
use logging::setup_klog;
|
use logging::setup_klog;
|
||||||
use mount::{is_device_mounted, switch_root};
|
use mount::{is_device_mounted, switch_root};
|
||||||
use rootdir::{collect_overlay_contexts, inject_magisk_rc, reset_overlay_contexts};
|
use rootdir::{collect_overlay_contexts, inject_magisk_rc, reset_overlay_contexts};
|
||||||
// Has to be pub so all symbols in that crate is included
|
// Has to be pub so all symbols in that crate is included
|
||||||
use crate::ffi::{BootConfig, MagiskInit};
|
|
||||||
pub use magiskpolicy;
|
pub use magiskpolicy;
|
||||||
use std::ptr::null as nullptr;
|
|
||||||
|
|
||||||
mod logging;
|
mod logging;
|
||||||
mod mount;
|
mod mount;
|
||||||
mod rootdir;
|
mod rootdir;
|
||||||
mod getinfo;
|
mod getinfo;
|
||||||
|
mod init;
|
||||||
|
|
||||||
#[cxx::bridge]
|
#[cxx::bridge]
|
||||||
pub mod ffi {
|
pub mod ffi {
|
||||||
@ -55,21 +49,25 @@ pub mod ffi {
|
|||||||
fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool;
|
fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool;
|
||||||
fn collect_overlay_contexts(src: Utf8CStrRef);
|
fn collect_overlay_contexts(src: Utf8CStrRef);
|
||||||
fn reset_overlay_contexts();
|
fn reset_overlay_contexts();
|
||||||
unsafe fn start_magisk_init(argv: *mut *mut c_char);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
fn print(self: &BootConfig);
|
fn print(self: &BootConfig);
|
||||||
fn prepare_data(self: &MagiskInit);
|
fn prepare_data(self: &MagiskInit);
|
||||||
fn exec_init(self: &MagiskInit);
|
fn legacy_system_as_root(self: &mut MagiskInit);
|
||||||
|
fn restore_ramdisk_init(self: &MagiskInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!("../base/include/base.hpp");
|
include!("../base/include/base.hpp");
|
||||||
|
include!("init.hpp");
|
||||||
|
|
||||||
#[namespace = "rust"]
|
#[namespace = "rust"]
|
||||||
#[cxx_name = "Utf8CStr"]
|
#[cxx_name = "Utf8CStr"]
|
||||||
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
|
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
|
||||||
|
|
||||||
|
unsafe fn magisk_proxy_main(argc: i32, argv: *mut *mut c_char) -> i32;
|
||||||
|
|
||||||
fn init(self: &mut BootConfig);
|
fn init(self: &mut BootConfig);
|
||||||
type kv_pairs;
|
type kv_pairs;
|
||||||
fn set(self: &mut BootConfig, config: &kv_pairs);
|
fn set(self: &mut BootConfig, config: &kv_pairs);
|
||||||
@ -93,67 +91,7 @@ pub mod ffi {
|
|||||||
// SELinux
|
// SELinux
|
||||||
unsafe fn patch_sepolicy(self: &MagiskInit, in_: *const c_char, out: *const c_char);
|
unsafe fn patch_sepolicy(self: &MagiskInit, in_: *const c_char, out: *const c_char);
|
||||||
fn hijack_sepolicy(self: &mut MagiskInit) -> bool;
|
fn hijack_sepolicy(self: &mut MagiskInit) -> bool;
|
||||||
fn legacy_system_as_root(self: &mut MagiskInit);
|
fn backup_init(self: &MagiskInit) -> *const c_char;
|
||||||
fn rootfs(self: &mut MagiskInit);
|
fn check_two_stage(self: &MagiskInit) -> bool;
|
||||||
fn start(self: &mut MagiskInit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn start_magisk_init(argv: *mut *mut std::ffi::c_char) {
|
|
||||||
fn inner(argv: *mut *mut std::ffi::c_char) -> LoggedResult<()> {
|
|
||||||
let mut init = MagiskInit {
|
|
||||||
preinit_dev: String::new(),
|
|
||||||
mount_list: Vec::new(),
|
|
||||||
argv,
|
|
||||||
config: BootConfig {
|
|
||||||
skip_initramfs: false,
|
|
||||||
force_normal_boot: false,
|
|
||||||
rootwait: false,
|
|
||||||
emulator: false,
|
|
||||||
slot: [0; 3],
|
|
||||||
dt_dir: [0; 64],
|
|
||||||
fstab_suffix: [0; 32],
|
|
||||||
hardware: [0; 32],
|
|
||||||
hardware_plat: [0; 32],
|
|
||||||
partition_map: Vec::new(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if !FsPath::from(cstr!("/proc/cmdline")).exists() {
|
|
||||||
FsPath::from(cstr!("/proc")).mkdir(0o755)?;
|
|
||||||
unsafe {
|
|
||||||
mount(
|
|
||||||
raw_cstr!("proc"),
|
|
||||||
raw_cstr!("/proc"),
|
|
||||||
raw_cstr!("proc"),
|
|
||||||
0,
|
|
||||||
nullptr(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.as_os_err()?;
|
|
||||||
init.mount_list.push("/proc".to_string());
|
|
||||||
}
|
|
||||||
if !FsPath::from(cstr!("/sys/block")).exists() {
|
|
||||||
FsPath::from(cstr!("/sys")).mkdir(0o755)?;
|
|
||||||
unsafe {
|
|
||||||
mount(
|
|
||||||
raw_cstr!("sysfs"),
|
|
||||||
raw_cstr!("/sys"),
|
|
||||||
raw_cstr!("sysfs"),
|
|
||||||
0,
|
|
||||||
nullptr(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.as_os_err()?;
|
|
||||||
init.mount_list.push("/sys".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_klog();
|
|
||||||
|
|
||||||
init.config.init();
|
|
||||||
|
|
||||||
init.start();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
inner(argv).ok();
|
|
||||||
}
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <flags.h>
|
#include <flags.h>
|
||||||
|
#include <xz.h>
|
||||||
|
|
||||||
#include "init.hpp"
|
#include "init.hpp"
|
||||||
|
|
||||||
@ -17,6 +18,31 @@ static string magic_mount_list;
|
|||||||
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
#define NEW_INITRC_DIR "/system/etc/init/hw"
|
||||||
#define INIT_RC "init.rc"
|
#define INIT_RC "init.rc"
|
||||||
|
|
||||||
|
static bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
|
||||||
|
uint8_t out[8192];
|
||||||
|
xz_crc32_init();
|
||||||
|
size_t size = bytes.size();
|
||||||
|
struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 1 << 26);
|
||||||
|
run_finally finally([&] { xz_dec_end(dec); });
|
||||||
|
struct xz_buf b = {
|
||||||
|
.in = bytes.data(),
|
||||||
|
.in_pos = 0,
|
||||||
|
.in_size = size,
|
||||||
|
.out = out,
|
||||||
|
.out_pos = 0,
|
||||||
|
.out_size = sizeof(out)
|
||||||
|
};
|
||||||
|
enum xz_ret ret;
|
||||||
|
do {
|
||||||
|
ret = xz_dec_run(dec, &b);
|
||||||
|
if (ret != XZ_OK && ret != XZ_STREAM_END)
|
||||||
|
return false;
|
||||||
|
strm.write(out, b.out_pos);
|
||||||
|
b.out_pos = 0;
|
||||||
|
} while (b.in_pos != size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void magic_mount(const string &sdir, const string &ddir = "") {
|
static void magic_mount(const string &sdir, const string &ddir = "") {
|
||||||
auto dir = xopen_dir(sdir.data());
|
auto dir = xopen_dir(sdir.data());
|
||||||
if (!dir) return;
|
if (!dir) return;
|
||||||
@ -426,3 +452,28 @@ int magisk_proxy_main(int argc, char *argv[]) {
|
|||||||
execve("/sbin/magisk", argv, environ);
|
execve("/sbin/magisk", argv, environ);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unxz_init(const char *init_xz, const char *init) {
|
||||||
|
LOGD("unxz %s -> %s\n", init_xz, init);
|
||||||
|
int fd = xopen(init, O_WRONLY | O_CREAT, 0777);
|
||||||
|
fd_stream ch(fd);
|
||||||
|
unxz(ch, mmap_data{init_xz});
|
||||||
|
close(fd);
|
||||||
|
clone_attr(init_xz, init);
|
||||||
|
unlink(init_xz);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *MagiskInit::backup_init() const noexcept {
|
||||||
|
if (access("/.backup/init.xz", F_OK) == 0)
|
||||||
|
unxz_init("/.backup/init.xz", "/.backup/init");
|
||||||
|
return "/.backup/init";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_CRT0
|
||||||
|
__BEGIN_DECLS
|
||||||
|
int tiny_vfprintf(FILE *stream, const char *format, va_list arg);
|
||||||
|
int vfprintf(FILE *stream, const char *format, va_list arg) {
|
||||||
|
return tiny_vfprintf(stream, format, arg);
|
||||||
|
}
|
||||||
|
__END_DECLS
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user