diff --git a/init/quirks.cpp b/init/quirks.cpp index a243189..6282e8f 100644 --- a/init/quirks.cpp +++ b/init/quirks.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include // 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 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(); + }); +} diff --git a/init/quirks.h b/init/quirks.h index a9d87bd..105c2f7 100644 --- a/init/quirks.h +++ b/init/quirks.h @@ -1,5 +1,8 @@ #pragma once #include +#include +#include +#include #include #include @@ -28,5 +31,6 @@ namespace Quirks { void Add(DeviceQuirk* quirk); void Run(); + void OverrideFileWith(filesystem::path p, function proc); void OverrideFileReplaceSubstr(filesystem::path p, string pattern, string replacement); }