[WIP] init: quirks: implement shared OverrideFileWith logic

Use a callback function to handle replacement etc.
This commit is contained in:
Peter Cai 2021-10-15 19:09:46 -04:00
parent 37f6b0069d
commit 80f1d3004a
2 changed files with 42 additions and 4 deletions

View file

@ -6,6 +6,8 @@
#include <vector>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>
// Default destructor for DeviceQuirk
DeviceQuirk::~DeviceQuirk() {
@ -52,7 +54,7 @@ void EnsureTmpMount() {
}
}
void Quirks::OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement) {
void Quirks::OverrideFileWith(filesystem::path p, function<void(istream&, ostream&)> proc) {
if (!filesystem::is_regular_file(p)) return;
EnsureTmpMount();
@ -61,13 +63,39 @@ void Quirks::OverrideFileReplaceSubstr(filesystem::path p, string pattern, strin
filesystem::path tmp_path = QUIRKS_TMP_FILES_PATH + p.string();
EnsureDirectory(tmp_path.parent_path());
// TODO: Actually implement pattern replacement
filesystem::copy_file(p, tmp_path);
ifstream ifs;
ifs.open(p, ifstream::in);
int err = mount(tmp_path.c_str(), p.c_str(), nullptr, MS_BIND, nullptr);
ofstream ofs(tmp_path);
proc(ifs, ofs);
ifs.close();
ofs.close();
// Synchronize ownership and permission
// C++ filesystem does not support uid / gid manipulation
struct stat st;
int err = stat(p.c_str(), &st);
if (err < 0) {
ALOGE("Failed to stat %s: %d\n", tmp_path.c_str(), errno);
return;
}
err = chown(tmp_path.c_str(), st.st_uid, st.st_gid);
if (err < 0) {
ALOGE("Failed to chown %s: %d\n", tmp_path.c_str(), errno);
}
err = chmod(tmp_path.c_str(), st.st_mode);
if (err < 0) {
ALOGE("Failed to chmod %s: %d\n", tmp_path.c_str(), errno);
}
// Bind mount and override the file
err = mount(tmp_path.c_str(), p.c_str(), nullptr, MS_BIND, nullptr);
if (err < 0) {
ALOGE("bind mount %s on %s err = %d\n", tmp_path.c_str(), p.c_str(), errno);
return;
}
// Call restorecon via execl, because for some reason
@ -75,3 +103,9 @@ void Quirks::OverrideFileReplaceSubstr(filesystem::path p, string pattern, strin
// (probably related to other magic present in our process)
fork_execl("/system/bin/restorecon", "restorecon", p.c_str());
}
void Quirks::OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement) {
Quirks::OverrideFileWith(p, [](istream& is, ostream& os) {
os << is.rdbuf();
});
}

View file

@ -1,5 +1,8 @@
#pragma once
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
#include <string>
#include <sys/wait.h>
@ -28,5 +31,6 @@ namespace Quirks {
void Add(DeviceQuirk* quirk);
void Run();
void OverrideFileWith(filesystem::path p, function<void(istream&, ostream&)> proc);
void OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement);
}