#include "input-accessor.hh" #include "store-api.hh" namespace nix { StorePath InputAccessor::fetchToStore( ref store, const CanonPath & path, std::string_view name, FileIngestionMethod method, PathFilter * filter, RepairFlag repair) { Activity act(*logger, lvlChatty, actUnknown, fmt("copying '%s' to the store", showPath(path))); auto source = sinkToSource([&](Sink & sink) { if (method == FileIngestionMethod::Recursive) dumpPath(path, sink, filter ? *filter : defaultPathFilter); else readFile(path, sink); }); auto storePath = settings.readOnlyMode ? store->computeStorePathFromDump(*source, name, method, htSHA256).first : store->addToStoreFromDump(*source, name, method, htSHA256, repair); return storePath; } SourcePath InputAccessor::root() { return {ref(shared_from_this()), CanonPath::root}; } std::ostream & operator << (std::ostream & str, const SourcePath & path) { str << path.to_string(); return str; } StorePath SourcePath::fetchToStore( ref store, std::string_view name, FileIngestionMethod method, PathFilter * filter, RepairFlag repair) const { return accessor->fetchToStore(store, path, name, method, filter, repair); } std::string_view SourcePath::baseName() const { return path.baseName().value_or("source"); } SourcePath SourcePath::parent() const { auto p = path.parent(); assert(p); return {accessor, std::move(*p)}; } SourcePath SourcePath::resolveSymlinks() const { auto res = accessor->root(); int linksAllowed = 1024; std::list todo; for (auto & c : path) todo.push_back(std::string(c)); while (!todo.empty()) { auto c = *todo.begin(); todo.pop_front(); if (c == "" || c == ".") ; else if (c == "..") res.path.pop(); else { res.path.push(c); if (auto st = res.maybeLstat(); st && st->type == InputAccessor::tSymlink) { if (!linksAllowed--) throw Error("infinite symlink recursion in path '%s'", path); auto target = res.readLink(); res.path.pop(); if (hasPrefix(target, "/")) res.path = CanonPath::root; todo.splice(todo.begin(), tokenizeString>(target, "/")); } } } return res; } }