From 50156302c033323895ababb6c190086cbc5cec46 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 19 Oct 2023 15:20:10 +0200 Subject: [PATCH] Deduplicate FSSourceAccessor and FSInputAccessor --- src/libfetchers/fs-input-accessor.cc | 31 +++++------------ src/libutil/archive.cc | 52 +--------------------------- src/libutil/source-accessor.cc | 49 ++++++++++++++++++++++++++ src/libutil/source-accessor.hh | 24 +++++++++++++ 4 files changed, 82 insertions(+), 74 deletions(-) diff --git a/src/libfetchers/fs-input-accessor.cc b/src/libfetchers/fs-input-accessor.cc index a35955465..e40faf03f 100644 --- a/src/libfetchers/fs-input-accessor.cc +++ b/src/libfetchers/fs-input-accessor.cc @@ -3,7 +3,7 @@ namespace nix { -struct FSInputAccessorImpl : FSInputAccessor +struct FSInputAccessorImpl : FSInputAccessor, PosixSourceAccessor { CanonPath root; std::optional> allowedPaths; @@ -23,28 +23,20 @@ struct FSInputAccessorImpl : FSInputAccessor { auto absPath = makeAbsPath(path); checkAllowed(absPath); - return nix::readFile(absPath.abs()); + return PosixSourceAccessor::readFile(absPath); } bool pathExists(const CanonPath & path) override { auto absPath = makeAbsPath(path); - return isAllowed(absPath) && nix::pathExists(absPath.abs()); + return isAllowed(absPath) && PosixSourceAccessor::pathExists(absPath); } Stat lstat(const CanonPath & path) override { auto absPath = makeAbsPath(path); checkAllowed(absPath); - auto st = nix::lstat(absPath.abs()); - return Stat { - .type = - S_ISREG(st.st_mode) ? tRegular : - S_ISDIR(st.st_mode) ? tDirectory : - S_ISLNK(st.st_mode) ? tSymlink : - tMisc, - .isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR - }; + return PosixSourceAccessor::lstat(absPath); } DirEntries readDirectory(const CanonPath & path) override @@ -52,16 +44,9 @@ struct FSInputAccessorImpl : FSInputAccessor auto absPath = makeAbsPath(path); checkAllowed(absPath); DirEntries res; - for (auto & entry : nix::readDirectory(absPath.abs())) { - std::optional type; - switch (entry.type) { - case DT_REG: type = Type::tRegular; break; - case DT_LNK: type = Type::tSymlink; break; - case DT_DIR: type = Type::tDirectory; break; - } - if (isAllowed(absPath + entry.name)) - res.emplace(entry.name, type); - } + for (auto & entry : PosixSourceAccessor::readDirectory(absPath)) + if (isAllowed(absPath + entry.first)) + res.emplace(entry); return res; } @@ -69,7 +54,7 @@ struct FSInputAccessorImpl : FSInputAccessor { auto absPath = makeAbsPath(path); checkAllowed(absPath); - return nix::readLink(absPath.abs()); + return PosixSourceAccessor::readLink(absPath); } CanonPath makeAbsPath(const CanonPath & path) diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index e48fc7522..6508ba807 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -110,59 +110,9 @@ void SourceAccessor::dumpPath( } -struct FSSourceAccessor : SourceAccessor -{ - time_t mtime = 0; // most recent mtime seen - - std::string readFile(const CanonPath & path) override - { - return nix::readFile(path.abs()); - } - - bool pathExists(const CanonPath & path) override - { - return nix::pathExists(path.abs()); - } - - Stat lstat(const CanonPath & path) override - { - auto st = nix::lstat(path.abs()); - mtime = std::max(mtime, st.st_mtime); - return Stat { - .type = - S_ISREG(st.st_mode) ? tRegular : - S_ISDIR(st.st_mode) ? tDirectory : - S_ISLNK(st.st_mode) ? tSymlink : - tMisc, - .isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR - }; - } - - DirEntries readDirectory(const CanonPath & path) override - { - DirEntries res; - for (auto & entry : nix::readDirectory(path.abs())) { - std::optional type; - switch (entry.type) { - case DT_REG: type = Type::tRegular; break; - case DT_LNK: type = Type::tSymlink; break; - case DT_DIR: type = Type::tDirectory; break; - } - res.emplace(entry.name, type); - } - return res; - } - - std::string readLink(const CanonPath & path) override - { - return nix::readLink(path.abs()); - } -}; - - time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter) { - FSSourceAccessor accessor; + PosixSourceAccessor accessor; accessor.dumpPath(CanonPath::fromCwd(path), sink, filter); return accessor.mtime; } diff --git a/src/libutil/source-accessor.cc b/src/libutil/source-accessor.cc index e3adee5f1..d5c8cbcdd 100644 --- a/src/libutil/source-accessor.cc +++ b/src/libutil/source-accessor.cc @@ -33,4 +33,53 @@ std::string SourceAccessor::showPath(const CanonPath & path) return path.abs(); } +std::string PosixSourceAccessor::readFile(const CanonPath & path) +{ + return nix::readFile(path.abs()); +} + +bool PosixSourceAccessor::pathExists(const CanonPath & path) +{ + return nix::pathExists(path.abs()); +} + +SourceAccessor::Stat PosixSourceAccessor::lstat(const CanonPath & path) +{ + auto st = nix::lstat(path.abs()); + mtime = std::max(mtime, st.st_mtime); + return Stat { + .type = + S_ISREG(st.st_mode) ? tRegular : + S_ISDIR(st.st_mode) ? tDirectory : + S_ISLNK(st.st_mode) ? tSymlink : + tMisc, + .isExecutable = S_ISREG(st.st_mode) && st.st_mode & S_IXUSR + }; +} + +SourceAccessor::DirEntries PosixSourceAccessor::readDirectory(const CanonPath & path) +{ + DirEntries res; + for (auto & entry : nix::readDirectory(path.abs())) { + std::optional type; + switch (entry.type) { + case DT_REG: type = Type::tRegular; break; + case DT_LNK: type = Type::tSymlink; break; + case DT_DIR: type = Type::tDirectory; break; + } + res.emplace(entry.name, type); + } + return res; +} + +std::string PosixSourceAccessor::readLink(const CanonPath & path) +{ + return nix::readLink(path.abs()); +} + +std::optional PosixSourceAccessor::getPhysicalPath(const CanonPath & path) +{ + return path; +} + } diff --git a/src/libutil/source-accessor.hh b/src/libutil/source-accessor.hh index c2d35d6b5..a251ae31c 100644 --- a/src/libutil/source-accessor.hh +++ b/src/libutil/source-accessor.hh @@ -93,4 +93,28 @@ struct SourceAccessor } }; +/** + * A source accessor that uses the Unix filesystem. + */ +struct PosixSourceAccessor : SourceAccessor +{ + /** + * The most recent mtime seen by lstat(). This is a hack to + * support dumpPathAndGetMtime(). Should remove this eventually. + */ + time_t mtime = 0; + + std::string readFile(const CanonPath & path) override; + + bool pathExists(const CanonPath & path) override; + + Stat lstat(const CanonPath & path) override; + + DirEntries readDirectory(const CanonPath & path) override; + + std::string readLink(const CanonPath & path) override; + + std::optional getPhysicalPath(const CanonPath & path) override; +}; + }