mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-12 10:05:01 +00:00
152 lines
3.8 KiB
C++
152 lines
3.8 KiB
C++
#include <sys/mman.h>
|
|
#include <sys/sendfile.h>
|
|
#include <linux/fs.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
#include <base.hpp>
|
|
|
|
using namespace std;
|
|
|
|
int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
|
|
if (fd_path(dirfd, byte_data(path, size)) < 0)
|
|
return -1;
|
|
auto len = strlen(path);
|
|
path[len] = '/';
|
|
strscpy(path + len + 1, name, size - len - 1);
|
|
return 0;
|
|
}
|
|
|
|
void full_read(int fd, string &str) {
|
|
char buf[4096];
|
|
for (ssize_t len; (len = xread(fd, buf, sizeof(buf))) > 0;)
|
|
str.insert(str.end(), buf, buf + len);
|
|
}
|
|
|
|
void full_read(const char *filename, string &str) {
|
|
if (int fd = xopen(filename, O_RDONLY | O_CLOEXEC); fd >= 0) {
|
|
full_read(fd, str);
|
|
close(fd);
|
|
}
|
|
}
|
|
|
|
string full_read(int fd) {
|
|
string str;
|
|
full_read(fd, str);
|
|
return str;
|
|
}
|
|
|
|
string full_read(const char *filename) {
|
|
string str;
|
|
full_read(filename, str);
|
|
return str;
|
|
}
|
|
|
|
void write_zero(int fd, size_t size) {
|
|
char buf[4096] = {0};
|
|
size_t len;
|
|
while (size > 0) {
|
|
len = sizeof(buf) > size ? size : sizeof(buf);
|
|
write(fd, buf, len);
|
|
size -= len;
|
|
}
|
|
}
|
|
|
|
void file_readline(bool trim, FILE *fp, const function<bool(string_view)> &fn) {
|
|
size_t len = 1024;
|
|
char *buf = (char *) malloc(len);
|
|
char *start;
|
|
ssize_t read;
|
|
while ((read = getline(&buf, &len, fp)) >= 0) {
|
|
start = buf;
|
|
if (trim) {
|
|
while (read && "\n\r "sv.find(buf[read - 1]) != string::npos)
|
|
--read;
|
|
buf[read] = '\0';
|
|
while (*start == ' ')
|
|
++start;
|
|
}
|
|
if (!fn(start))
|
|
break;
|
|
}
|
|
free(buf);
|
|
}
|
|
|
|
void file_readline(bool trim, const char *file, const function<bool(string_view)> &fn) {
|
|
if (auto fp = open_file(file, "re"))
|
|
file_readline(trim, fp.get(), fn);
|
|
}
|
|
|
|
void file_readline(const char *file, const function<bool(string_view)> &fn) {
|
|
file_readline(false, file, fn);
|
|
}
|
|
|
|
void parse_prop_file(FILE *fp, const function<bool(string_view, string_view)> &fn) {
|
|
file_readline(true, fp, [&](string_view line_view) -> bool {
|
|
char *line = (char *) line_view.data();
|
|
if (line[0] == '#')
|
|
return true;
|
|
char *eql = strchr(line, '=');
|
|
if (eql == nullptr || eql == line)
|
|
return true;
|
|
*eql = '\0';
|
|
return fn(line, eql + 1);
|
|
});
|
|
}
|
|
|
|
void parse_prop_file(const char *file, const function<bool(string_view, string_view)> &fn) {
|
|
if (auto fp = open_file(file, "re"))
|
|
parse_prop_file(fp.get(), fn);
|
|
}
|
|
|
|
sDIR make_dir(DIR *dp) {
|
|
return sDIR(dp, [](DIR *dp){ return dp ? closedir(dp) : 1; });
|
|
}
|
|
|
|
sFILE make_file(FILE *fp) {
|
|
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
|
|
}
|
|
|
|
mmap_data::mmap_data(const char *name, bool rw) {
|
|
auto slice = rust::map_file(name, rw);
|
|
if (!slice.empty()) {
|
|
_buf = slice.data();
|
|
_sz = slice.size();
|
|
}
|
|
}
|
|
|
|
mmap_data::mmap_data(int dirfd, const char *name, bool rw) {
|
|
auto slice = rust::map_file_at(dirfd, name, rw);
|
|
if (!slice.empty()) {
|
|
_buf = slice.data();
|
|
_sz = slice.size();
|
|
}
|
|
}
|
|
|
|
mmap_data::mmap_data(int fd, size_t sz, bool rw) {
|
|
auto slice = rust::map_fd(fd, sz, rw);
|
|
if (!slice.empty()) {
|
|
_buf = slice.data();
|
|
_sz = slice.size();
|
|
}
|
|
}
|
|
|
|
mmap_data::~mmap_data() {
|
|
if (_buf)
|
|
munmap(_buf, _sz);
|
|
}
|
|
|
|
string resolve_preinit_dir(const char *base_dir) {
|
|
string dir = base_dir;
|
|
if (access((dir + "/unencrypted").data(), F_OK) == 0) {
|
|
dir += "/unencrypted/magisk";
|
|
} else if (access((dir + "/adb").data(), F_OK) == 0) {
|
|
dir += "/adb";
|
|
} else if (access((dir + "/watchdog").data(), F_OK) == 0) {
|
|
dir += "/watchdog/magisk";
|
|
} else {
|
|
dir += "/magisk";
|
|
}
|
|
return dir;
|
|
}
|