mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Fix compile errors and cleanup
This commit is contained in:
parent
e58f98e844
commit
6b21091fe2
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../missing.hpp"
|
|
||||||
#include "../xwrap.hpp"
|
#include "../xwrap.hpp"
|
||||||
#include "../files.hpp"
|
#include "../files.hpp"
|
||||||
#include "../misc.hpp"
|
#include "../misc.hpp"
|
||||||
#include "../logging.hpp"
|
#include "../logging.hpp"
|
||||||
|
#include "../missing.hpp"
|
||||||
#include "../base-rs.hpp"
|
#include "../base-rs.hpp"
|
||||||
|
@ -179,10 +179,8 @@ struct byte_data : public byte_view {
|
|||||||
byte_data() = default;
|
byte_data() = default;
|
||||||
byte_data(void *buf, size_t sz) : byte_view(buf, sz) {}
|
byte_data(void *buf, size_t sz) : byte_view(buf, sz) {}
|
||||||
|
|
||||||
// We don't want mutable references to be copied or moved around; pass bytes as byte_view
|
// byte_data, or any of its subclass, can be copied as byte_data
|
||||||
// Subclasses are free to implement their own constructors
|
byte_data(const byte_data &o) : byte_data(o._buf, o._sz) {}
|
||||||
byte_data(const byte_data &) = delete;
|
|
||||||
byte_data(byte_data &&) = delete;
|
|
||||||
|
|
||||||
// Transparent conversion from common C++ types to mutable byte references
|
// Transparent conversion from common C++ types to mutable byte references
|
||||||
byte_data(std::string &s, bool with_nul = true)
|
byte_data(std::string &s, bool with_nul = true)
|
||||||
@ -194,9 +192,7 @@ struct byte_data : public byte_view {
|
|||||||
operator rust::Slice<uint8_t>() { return rust::Slice<uint8_t>(_buf, _sz); }
|
operator rust::Slice<uint8_t>() { return rust::Slice<uint8_t>(_buf, _sz); }
|
||||||
|
|
||||||
using byte_view::buf;
|
using byte_view::buf;
|
||||||
using byte_view::sz;
|
|
||||||
uint8_t *buf() { return _buf; }
|
uint8_t *buf() { return _buf; }
|
||||||
size_t &sz() { return _sz; }
|
|
||||||
|
|
||||||
void swap(byte_data &o);
|
void swap(byte_data &o);
|
||||||
std::vector<size_t> patch(byte_view from, byte_view to);
|
std::vector<size_t> patch(byte_view from, byte_view to);
|
||||||
|
@ -10,7 +10,7 @@ static inline int fexecve(int fd, char* const* argv, char* const* envp) {
|
|||||||
syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
|
syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
|
||||||
if (errno == ENOSYS) {
|
if (errno == ENOSYS) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
std::snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
|
ssprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
|
||||||
execve(buf, argv, envp);
|
execve(buf, argv, envp);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -132,7 +132,7 @@ void chunk_out_stream::finalize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t byte_channel::read(void *buf, size_t len) {
|
ssize_t byte_channel::read(void *buf, size_t len) {
|
||||||
len = std::min((size_t) len, _data.sz() - _pos);
|
len = std::min((size_t) len, _data._sz- _pos);
|
||||||
memcpy(buf, _data.buf() + _pos, len);
|
memcpy(buf, _data.buf() + _pos, len);
|
||||||
_pos += len;
|
_pos += len;
|
||||||
return len;
|
return len;
|
||||||
@ -142,7 +142,7 @@ bool byte_channel::write(const void *buf, size_t len) {
|
|||||||
resize(_pos + len);
|
resize(_pos + len);
|
||||||
memcpy(_data.buf() + _pos, buf, len);
|
memcpy(_data.buf() + _pos, buf, len);
|
||||||
_pos += len;
|
_pos += len;
|
||||||
_data.sz() = std::max(_data.sz(), _pos);
|
_data._sz= std::max(_data.sz(), _pos);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ off_t byte_channel::seek(off_t off, int whence) {
|
|||||||
np = _pos + off;
|
np = _pos + off;
|
||||||
break;
|
break;
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
np = _data.sz() + off;
|
np = _data._sz+ off;
|
||||||
break;
|
break;
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
np = off;
|
np = off;
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
use crate::ramdisk::MagiskCpio;
|
|
||||||
use anyhow::{anyhow, Context};
|
|
||||||
use base::libc::{
|
|
||||||
c_char, dev_t, gid_t, major, makedev, minor, mknod, mmap, mode_t, munmap, uid_t, MAP_FAILED,
|
|
||||||
MAP_PRIVATE, PROT_READ, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH,
|
|
||||||
S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR,
|
|
||||||
};
|
|
||||||
use base::{ptr_to_str_result, ResultExt, WriteExt};
|
|
||||||
use clap::{Parser, Subcommand};
|
|
||||||
use size::{Base, Size, Style};
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
@ -19,6 +9,19 @@ use std::os::unix::fs::{symlink, DirBuilderExt, FileTypeExt, MetadataExt};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Context};
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use size::{Base, Size, Style};
|
||||||
|
|
||||||
|
use base::libc::{
|
||||||
|
c_char, dev_t, gid_t, major, makedev, minor, mknod, mmap, mode_t, munmap, uid_t, MAP_FAILED,
|
||||||
|
MAP_PRIVATE, PROT_READ, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_IRGRP, S_IROTH,
|
||||||
|
S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR,
|
||||||
|
};
|
||||||
|
use base::{ptr_to_str_result, ResultExt, WriteExt};
|
||||||
|
|
||||||
|
use crate::ramdisk::MagiskCpio;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
struct CpioCli {
|
struct CpioCli {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
@ -108,6 +111,7 @@ impl Cpio {
|
|||||||
entries: BTreeMap::new(),
|
entries: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_from_data(data: &[u8]) -> anyhow::Result<Self> {
|
fn load_from_data(data: &[u8]) -> anyhow::Result<Self> {
|
||||||
let mut cpio = Cpio::new();
|
let mut cpio = Cpio::new();
|
||||||
let mut pos = 0usize;
|
let mut pos = 0usize;
|
||||||
@ -147,6 +151,7 @@ impl Cpio {
|
|||||||
}
|
}
|
||||||
Ok(cpio)
|
Ok(cpio)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn load_from_file(path: &str) -> anyhow::Result<Self> {
|
pub(crate) fn load_from_file(path: &str) -> anyhow::Result<Self> {
|
||||||
eprintln!("Loading cpio: [{}]", path);
|
eprintln!("Loading cpio: [{}]", path);
|
||||||
let file = File::open(path)?;
|
let file = File::open(path)?;
|
||||||
@ -173,6 +178,7 @@ impl Cpio {
|
|||||||
}
|
}
|
||||||
Ok(cpio)
|
Ok(cpio)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump(&self, path: &str) -> anyhow::Result<()> {
|
fn dump(&self, path: &str) -> anyhow::Result<()> {
|
||||||
eprintln!("Dumping cpio: [{}]", path);
|
eprintln!("Dumping cpio: [{}]", path);
|
||||||
let mut file = File::create(path)?;
|
let mut file = File::create(path)?;
|
||||||
@ -215,6 +221,7 @@ impl Cpio {
|
|||||||
file.write_zeros(align_4(pos) - pos)?;
|
file.write_zeros(align_4(pos) - pos)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn rm(&mut self, path: &str, recursive: bool) -> anyhow::Result<()> {
|
pub(crate) fn rm(&mut self, path: &str, recursive: bool) -> anyhow::Result<()> {
|
||||||
let path = norm_path(path);
|
let path = norm_path(path);
|
||||||
let entry = self
|
let entry = self
|
||||||
@ -242,6 +249,7 @@ impl Cpio {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_entry(&self, path: &str, out: &Path) -> anyhow::Result<()> {
|
fn extract_entry(&self, path: &str, out: &Path) -> anyhow::Result<()> {
|
||||||
let entry = self.entries.get(path).ok_or(anyhow!("No such file"))?;
|
let entry = self.entries.get(path).ok_or(anyhow!("No such file"))?;
|
||||||
eprintln!("Extracting entry [{}] to [{}]", path, out.to_string_lossy());
|
eprintln!("Extracting entry [{}] to [{}]", path, out.to_string_lossy());
|
||||||
@ -280,6 +288,7 @@ impl Cpio {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract(&self, path: Option<&str>, out: Option<&str>) -> anyhow::Result<()> {
|
fn extract(&self, path: Option<&str>, out: Option<&str>) -> anyhow::Result<()> {
|
||||||
let path = path.map(norm_path);
|
let path = path.map(norm_path);
|
||||||
let out = out.map(Path::new);
|
let out = out.map(Path::new);
|
||||||
@ -295,9 +304,11 @@ impl Cpio {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn exists(&self, path: &str) -> bool {
|
pub(crate) fn exists(&self, path: &str) -> bool {
|
||||||
self.entries.contains_key(&norm_path(path))
|
self.entries.contains_key(&norm_path(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&mut self, mode: &mode_t, path: &str, file: &str) -> anyhow::Result<()> {
|
fn add(&mut self, mode: &mode_t, path: &str, file: &str) -> anyhow::Result<()> {
|
||||||
if path.ends_with('/') {
|
if path.ends_with('/') {
|
||||||
return Err(anyhow!("path cannot end with / for add"));
|
return Err(anyhow!("path cannot end with / for add"));
|
||||||
@ -334,6 +345,7 @@ impl Cpio {
|
|||||||
eprintln!("Add file [{}] ({:04o})", path, mode);
|
eprintln!("Add file [{}] ({:04o})", path, mode);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkdir(&mut self, mode: &mode_t, dir: &str) {
|
fn mkdir(&mut self, mode: &mode_t, dir: &str) {
|
||||||
self.entries.insert(
|
self.entries.insert(
|
||||||
norm_path(dir),
|
norm_path(dir),
|
||||||
@ -348,6 +360,7 @@ impl Cpio {
|
|||||||
);
|
);
|
||||||
eprintln!("Create directory [{}] ({:04o})", dir, mode);
|
eprintln!("Create directory [{}] ({:04o})", dir, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ln(&mut self, src: &str, dst: &str) {
|
fn ln(&mut self, src: &str, dst: &str) {
|
||||||
self.entries.insert(
|
self.entries.insert(
|
||||||
norm_path(dst),
|
norm_path(dst),
|
||||||
@ -362,6 +375,7 @@ impl Cpio {
|
|||||||
);
|
);
|
||||||
eprintln!("Create symlink [{}] -> [{}]", dst, src);
|
eprintln!("Create symlink [{}] -> [{}]", dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mv(&mut self, from: &str, to: &str) -> anyhow::Result<()> {
|
fn mv(&mut self, from: &str, to: &str) -> anyhow::Result<()> {
|
||||||
let entry = self
|
let entry = self
|
||||||
.entries
|
.entries
|
||||||
@ -371,6 +385,7 @@ impl Cpio {
|
|||||||
eprintln!("Move [{}] -> [{}]", from, to);
|
eprintln!("Move [{}] -> [{}]", from, to);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ls(&self, path: Option<&str>, recursive: bool) {
|
fn ls(&self, path: Option<&str>, recursive: bool) {
|
||||||
let path = path
|
let path = path
|
||||||
.map(norm_path)
|
.map(norm_path)
|
||||||
@ -489,10 +504,7 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool {
|
|||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn x8u<U>(x: &[u8; 8]) -> anyhow::Result<U>
|
fn x8u<U: TryFrom<u32>>(x: &[u8; 8]) -> anyhow::Result<U> {
|
||||||
where
|
|
||||||
U: TryFrom<u32>,
|
|
||||||
{
|
|
||||||
// parse hex
|
// parse hex
|
||||||
let mut ret = 0u32;
|
let mut ret = 0u32;
|
||||||
for i in x {
|
for i in x {
|
||||||
|
@ -151,7 +151,7 @@ static bool dtb_patch(const char *file) {
|
|||||||
int len;
|
int len;
|
||||||
char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
||||||
byte_data data(value, len);
|
byte_data data(value, len);
|
||||||
patched |= patch_verity(data);
|
patched |= (patch_verity(data) != len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,9 +224,10 @@ static bool fdt_patch(void *fdt) {
|
|||||||
int len;
|
int len;
|
||||||
const void *value = fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
const void *value = fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
||||||
heap_data copy = byte_view(value, len).clone();
|
heap_data copy = byte_view(value, len).clone();
|
||||||
if (patch_verity(copy)) {
|
auto patched_sz = patch_verity(copy);
|
||||||
|
if (patched_sz != len) {
|
||||||
modified = true;
|
modified = true;
|
||||||
fdt_setprop(fdt, node, "fsmgr_flags", copy.buf(), copy.sz());
|
fdt_setprop(fdt, node, "fsmgr_flags", copy.buf(), patched_sz);
|
||||||
}
|
}
|
||||||
if (name == "system"sv) {
|
if (name == "system"sv) {
|
||||||
fprintf(stderr, "Setting [mnt_point] to [/system_root]\n");
|
fprintf(stderr, "Setting [mnt_point] to [/system_root]\n");
|
||||||
|
@ -20,8 +20,8 @@ pub mod ffi {
|
|||||||
include!("compress.hpp");
|
include!("compress.hpp");
|
||||||
include!("magiskboot.hpp");
|
include!("magiskboot.hpp");
|
||||||
fn decompress(buf: &[u8], fd: i32) -> bool;
|
fn decompress(buf: &[u8], fd: i32) -> bool;
|
||||||
fn patch_encryption(buf: &mut [u8]);
|
fn patch_encryption(buf: &mut [u8]) -> usize;
|
||||||
fn patch_verity(buf: &mut [u8]);
|
fn patch_verity(buf: &mut [u8]) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[namespace = "rust"]
|
#[namespace = "rust"]
|
||||||
|
@ -18,15 +18,12 @@ int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
|
|||||||
void repack(const char *src_img, const char *out_img, bool skip_comp = false);
|
void repack(const char *src_img, const char *out_img, bool skip_comp = false);
|
||||||
int split_image_dtb(const char *filename);
|
int split_image_dtb(const char *filename);
|
||||||
int hexpatch(const char *file, std::string_view from, std::string_view to);
|
int hexpatch(const char *file, std::string_view from, std::string_view to);
|
||||||
int cpio_commands(int argc, char *argv[]);
|
|
||||||
int dtb_commands(int argc, char *argv[]);
|
int dtb_commands(int argc, char *argv[]);
|
||||||
|
|
||||||
bool patch_verity(byte_data data);
|
size_t patch_verity(rust::Slice<uint8_t> data);
|
||||||
void patch_verity(rust::Slice<uint8_t> data);
|
size_t patch_encryption(rust::Slice<uint8_t> data);
|
||||||
bool patch_encryption(byte_data data);
|
|
||||||
void patch_encryption(rust::Slice<uint8_t> data);
|
|
||||||
|
|
||||||
inline bool check_env(const char *name) {
|
static inline bool check_env(const char *name) {
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
const char *val = getenv(name);
|
const char *val = getenv(name);
|
||||||
return val != nullptr && val == "true"sv;
|
return val != nullptr && val == "true"sv;
|
||||||
|
@ -39,36 +39,28 @@ static int skip_encryption_pattern(const char *s) {
|
|||||||
return skip;
|
return skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool remove_pattern(byte_data &data, int(*pattern_skip)(const char *)) {
|
static size_t remove_pattern(byte_data data, int(*pattern_skip)(const char *)) {
|
||||||
char *src = reinterpret_cast<char *>(data.buf());
|
char *src = reinterpret_cast<char *>(data.buf());
|
||||||
size_t orig_sz = data.sz();
|
size_t sz = data.sz();
|
||||||
int write = 0;
|
int write = 0;
|
||||||
int read = 0;
|
int read = 0;
|
||||||
while (read < orig_sz) {
|
while (read < data.sz()) {
|
||||||
if (int skip = pattern_skip(src + read); skip > 0) {
|
if (int skip = pattern_skip(src + read); skip > 0) {
|
||||||
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
|
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
|
||||||
data.sz() -= skip;
|
sz -= skip;
|
||||||
read += skip;
|
read += skip;
|
||||||
} else {
|
} else {
|
||||||
src[write++] = src[read++];
|
src[write++] = src[read++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(src + write, 0, orig_sz - write);
|
memset(src + write, 0, data.sz() - write);
|
||||||
return data.sz() != orig_sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool patch_verity(byte_data data) {
|
size_t patch_verity(rust::Slice<uint8_t> data) {
|
||||||
return remove_pattern(data, skip_verity_pattern);
|
return remove_pattern(data, skip_verity_pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_verity(rust::Slice<uint8_t> data) {
|
size_t patch_encryption(rust::Slice<uint8_t> data) {
|
||||||
patch_verity(byte_data{data.data(), data.size()});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool patch_encryption(byte_data data) {
|
|
||||||
return remove_pattern(data, skip_encryption_pattern);
|
return remove_pattern(data, skip_encryption_pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_encryption(rust::Slice<uint8_t> data) {
|
|
||||||
patch_encryption(byte_data{data.data(), data.size()});
|
|
||||||
}
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use crate::cpio::{Cpio, CpioEntry};
|
|
||||||
use crate::ffi::{patch_encryption, patch_verity};
|
|
||||||
use base::libc::{S_IFDIR, S_IFMT, S_IFREG};
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
|
|
||||||
|
use base::libc::{S_IFDIR, S_IFMT, S_IFREG};
|
||||||
|
|
||||||
|
use crate::cpio::{Cpio, CpioEntry};
|
||||||
|
use crate::ffi::{patch_encryption, patch_verity};
|
||||||
|
|
||||||
pub trait MagiskCpio {
|
pub trait MagiskCpio {
|
||||||
fn patch(&mut self);
|
fn patch(&mut self);
|
||||||
fn test(&self) -> i32;
|
fn test(&self) -> i32;
|
||||||
@ -40,17 +42,24 @@ impl MagiskCpio for Cpio {
|
|||||||
if !keep_verity {
|
if !keep_verity {
|
||||||
if fstab {
|
if fstab {
|
||||||
eprintln!("Found fstab file [{}]", name);
|
eprintln!("Found fstab file [{}]", name);
|
||||||
patch_verity(entry.data.as_mut_slice());
|
let len = patch_verity(entry.data.as_mut_slice());
|
||||||
|
if len != entry.data.len() {
|
||||||
|
entry.data.resize(len, 0);
|
||||||
|
}
|
||||||
} else if name == "verity_key" {
|
} else if name == "verity_key" {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !keep_force_encrypt && fstab {
|
if !keep_force_encrypt && fstab {
|
||||||
patch_encryption(entry.data.as_mut_slice());
|
let len = patch_encryption(entry.data.as_mut_slice());
|
||||||
|
if len != entry.data.len() {
|
||||||
|
entry.data.resize(len, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(&self) -> i32 {
|
fn test(&self) -> i32 {
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
for file in [
|
for file in [
|
||||||
@ -78,6 +87,7 @@ impl MagiskCpio for Cpio {
|
|||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore(&mut self) -> anyhow::Result<()> {
|
fn restore(&mut self) -> anyhow::Result<()> {
|
||||||
let mut backups = HashMap::<String, CpioEntry>::new();
|
let mut backups = HashMap::<String, CpioEntry>::new();
|
||||||
let mut rm_list = String::new();
|
let mut rm_list = String::new();
|
||||||
@ -106,6 +116,7 @@ impl MagiskCpio for Cpio {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn backup(&mut self, origin: &str) -> anyhow::Result<()> {
|
fn backup(&mut self, origin: &str) -> anyhow::Result<()> {
|
||||||
let mut backups = HashMap::<String, CpioEntry>::new();
|
let mut backups = HashMap::<String, CpioEntry>::new();
|
||||||
let mut rm_list = String::new();
|
let mut rm_list = String::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user