aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/archive.cc
diff options
context:
space:
mode:
authorBen Burdette <bburdette@protonmail.com>2022-04-07 13:42:01 -0600
committerBen Burdette <bburdette@protonmail.com>2022-04-07 13:42:01 -0600
commit1a93ac8133381eb692416c4e46b1706faa5cd89f (patch)
tree9a559f977ad6213c055099f6f2ab6be96f0c551b /src/libutil/archive.cc
parentd2ec9b4e15718e42720787140d7825dcbfd73249 (diff)
parent8b1e328d5d0ae7d3a4a8f6012ec065b59674ed4a (diff)
Merge remote-tracking branch 'upstream/master' into upstream-merge
Diffstat (limited to 'src/libutil/archive.cc')
-rw-r--r--src/libutil/archive.cc47
1 files changed, 29 insertions, 18 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index fdee643b1..30b471af5 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -37,7 +37,7 @@ static GlobalConfig::Register rArchiveSettings(&archiveSettings);
const std::string narVersionMagic1 = "nix-archive-1";
-static string caseHackSuffix = "~nix~case~hack~";
+static std::string caseHackSuffix = "~nix~case~hack~";
PathFilter defaultPathFilter = [](const Path &) { return true; };
@@ -64,11 +64,12 @@ static void dumpContents(const Path & path, off_t size,
}
-static void dump(const Path & path, Sink & sink, PathFilter & filter)
+static time_t dump(const Path & path, Sink & sink, PathFilter & filter)
{
checkInterrupt();
auto st = lstat(path);
+ time_t result = st.st_mtime;
sink << "(";
@@ -84,12 +85,12 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
/* If we're on a case-insensitive system like macOS, undo
the case hack applied by restorePath(). */
- std::map<string, string> unhacked;
+ std::map<std::string, std::string> unhacked;
for (auto & i : readDirectory(path))
if (archiveSettings.useCaseHack) {
- string name(i.name);
+ std::string name(i.name);
size_t pos = i.name.find(caseHackSuffix);
- if (pos != string::npos) {
+ if (pos != std::string::npos) {
debug(format("removing case hack suffix from '%1%'") % (path + "/" + i.name));
name.erase(pos);
}
@@ -103,7 +104,10 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
for (auto & i : unhacked)
if (filter(path + "/" + i.first)) {
sink << "entry" << "(" << "name" << i.first << "node";
- dump(path + "/" + i.second, sink, filter);
+ auto tmp_mtime = dump(path + "/" + i.second, sink, filter);
+ if (tmp_mtime > result) {
+ result = tmp_mtime;
+ }
sink << ")";
}
}
@@ -114,23 +118,30 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
else throw Error("file '%1%' has an unsupported type", path);
sink << ")";
+
+ return result;
}
-void dumpPath(const Path & path, Sink & sink, PathFilter & filter)
+time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter)
{
sink << narVersionMagic1;
- dump(path, sink, filter);
+ return dump(path, sink, filter);
+}
+
+void dumpPath(const Path & path, Sink & sink, PathFilter & filter)
+{
+ dumpPathAndGetMtime(path, sink, filter);
}
-void dumpString(const std::string & s, Sink & sink)
+void dumpString(std::string_view s, Sink & sink)
{
sink << narVersionMagic1 << "(" << "type" << "regular" << "contents" << s << ")";
}
-static SerialisationError badArchive(string s)
+static SerialisationError badArchive(const std::string & s)
{
return SerialisationError("bad archive: " + s);
}
@@ -171,7 +182,7 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path)
struct CaseInsensitiveCompare
{
- bool operator() (const string & a, const string & b) const
+ bool operator() (const std::string & a, const std::string & b) const
{
return strcasecmp(a.c_str(), b.c_str()) < 0;
}
@@ -180,7 +191,7 @@ struct CaseInsensitiveCompare
static void parse(ParseSink & sink, Source & source, const Path & path)
{
- string s;
+ std::string s;
s = readString(source);
if (s != "(") throw badArchive("expected open tag");
@@ -201,7 +212,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
else if (s == "type") {
if (type != tpUnknown)
throw badArchive("multiple type fields");
- string t = readString(source);
+ std::string t = readString(source);
if (t == "regular") {
type = tpRegular;
@@ -232,7 +243,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
}
else if (s == "entry" && type == tpDirectory) {
- string name, prevName;
+ std::string name, prevName;
s = readString(source);
if (s != "(") throw badArchive("expected open tag");
@@ -246,7 +257,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
break;
} else if (s == "name") {
name = readString(source);
- if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
+ if (name.empty() || name == "." || name == ".." || name.find('/') != std::string::npos || name.find((char) 0) != std::string::npos)
throw Error("NAR contains invalid file name '%1%'", name);
if (name <= prevName)
throw Error("NAR directory is not sorted");
@@ -269,7 +280,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
}
else if (s == "target" && type == tpSymlink) {
- string target = readString(source);
+ std::string target = readString(source);
sink.createSymlink(path, target);
}
@@ -281,7 +292,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
void parseDump(ParseSink & sink, Source & source)
{
- string version;
+ std::string version;
try {
version = readString(source, narVersionMagic1.size());
} catch (SerialisationError & e) {
@@ -345,7 +356,7 @@ struct RestoreSink : ParseSink
writeFull(fd.get(), data);
}
- void createSymlink(const Path & path, const string & target) override
+ void createSymlink(const Path & path, const std::string & target) override
{
Path p = dstPath + path;
nix::createSymlink(target, p);