diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index 098e2a449..00c804209 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -30,8 +30,12 @@
TODO: now using Berkeley DB 4.5.
- Option in
+ TODO: option in
nix-store --register-validity.
+
+
+ TODO: magic exportReferencesGraph
+ attribute.
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 43ac5cf53..82f713c8c 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -901,6 +901,34 @@ string showPaths(const PathSet & paths)
}
+/* Return a string accepted by `nix-store --register-validity' that
+ registers the specified paths as valid. Note: it's the
+ responsibility of the caller to provide a closure. */
+static string makeValidityRegistration(const PathSet & paths,
+ bool showDerivers)
+{
+ string s = "";
+
+ for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i) {
+ s += *i + "\n";
+
+ Path deriver = showDerivers ? queryDeriver(noTxn, *i) : "";
+ s += deriver + "\n";
+
+ PathSet references;
+ queryReferences(noTxn, *i, references);
+
+ s += (format("%1%\n") % references.size()).str();
+
+ for (PathSet::iterator j = references.begin();
+ j != references.end(); ++j)
+ s += *j + "\n";
+ }
+
+ return s;
+}
+
+
DerivationGoal::HookReply DerivationGoal::tryBuildHook()
{
Path buildHook = getEnv("NIX_BUILD_HOOK");
@@ -1024,26 +1052,8 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook()
/* The `references' file has exactly the format accepted by
`nix-store --register-validity'. */
- s = "";
- for (PathSet::iterator i = allInputs.begin();
- i != allInputs.end(); ++i)
- {
- s += *i + "\n";
-
- Path deriver = queryDeriver(noTxn, *i);
- s += deriver + "\n";
-
- PathSet references;
- queryReferences(noTxn, *i, references);
-
- s += (format("%1%\n") % references.size()).str();
-
- for (PathSet::iterator j = references.begin();
- j != references.end(); ++j)
- s += *j + "\n";
- }
-
- writeStringToFile(referencesFN, s);
+ writeStringToFile(referencesFN,
+ makeValidityRegistration(allInputs, true));
/* Tell the hook to proceed. */
writeLine(toHook.writeSide, "okay");
@@ -1235,6 +1245,32 @@ void DerivationGoal::startBuilder()
env[*i] = getEnv(*i);
}
+ /* The `exportReferencesGraph' feature allows the references graph
+ to be passed to a builder. This attribute should be a list of
+ pairs [name1 path1 name2 path2 ...]. The references graph of
+ each `pathN' will be stored in a text file `nameN' in the
+ temporary build directory. The text files have the format used
+ by `nix-store --register-validity'. However, the deriver
+ fields are left empty. */
+ string s = drv.env["exportReferencesGraph"];
+ Strings ss = tokenizeString(s);
+ if (ss.size() % 2 != 0)
+ throw Error(format("odd number of tokens in `exportReferencesGraph': `%1%'") % s);
+ for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
+ string fileName = *i++;
+ Path storePath = *i++;
+ if (!isValidPath(storePath))
+ throw Error(format("`exportReferencesGraph' refers to an invalid path `%1%'")
+ % storePath);
+ checkStoreName(fileName); /* !!! abuse of this function */
+ PathSet refs;
+ computeFSClosure(storePath, refs);
+ /* !!! in secure Nix, the writing should be done on the
+ build uid for security (maybe). */
+ writeStringToFile(tmpDir + "/" + fileName,
+ makeValidityRegistration(refs, false));
+ }
+
/* If we are running as root, and the `build-allow-root' setting
is `false', then we have to build as one of the users listed in
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index f8441af9c..e073d64ad 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -259,6 +259,10 @@ Path toStorePath(const Path & path)
void checkStoreName(const string & name)
{
string validChars = "+-._?=";
+ /* Disallow names starting with a dot for possible security
+ reasons (e.g., "." and ".."). */
+ if (string(name, 0, 1) == ".")
+ throw Error(format("illegal name: `%1%'") % name);
for (string::const_iterator i = name.begin(); i != name.end(); ++i)
if (!((*i >= 'A' && *i <= 'Z') ||
(*i >= 'a' && *i <= 'z') ||