aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libmain/shared.cc7
-rw-r--r--src/libstore/store.cc38
-rw-r--r--src/nix-store/help.txt6
-rw-r--r--src/nix-store/main.cc31
4 files changed, 70 insertions, 12 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 32f4f8124..ec639052b 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -22,6 +22,13 @@ void sigintHandler(int signo)
processor. */
static void initAndRun(int argc, char * * argv)
{
+ char * root = getenv("NIX_ROOT");
+
+ if (root) {
+ if (chroot(root) != 0)
+ throw SysError(format("changing root to `%1%'") % root);
+ }
+
/* Setup Nix paths. */
nixStore = NIX_STORE_DIR;
nixDataDir = NIX_DATA_DIR;
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index 4cd77796e..d85b0608f 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -157,6 +157,22 @@ void copyPath(const Path & src, const Path & dst)
}
+static bool isInStore(const Path & path)
+{
+ return path[0] == '/'
+ && Path(path, 0, nixStore.size()) == nixStore
+ && path.size() > nixStore.size() + 1
+ && path[nixStore.size()] == '/';
+}
+
+
+static void assertStorePath(const Path & path)
+{
+ if (!isInStore(path))
+ throw Error(format("path `%1%' is not in the Nix store") % path);
+}
+
+
static bool isValidPathTxn(const Path & path, const Transaction & txn)
{
string s;
@@ -182,6 +198,9 @@ static bool isUsablePathTxn(const Path & path, const Transaction & txn)
void registerSuccessor(const Transaction & txn,
const Path & srcPath, const Path & sucPath)
{
+ assertStorePath(srcPath);
+ assertStorePath(sucPath);
+
if (!isUsablePathTxn(sucPath, txn)) throw Error(
format("path `%1%' cannot be a successor, since it is not usable")
% sucPath);
@@ -223,6 +242,9 @@ Paths queryPredecessors(const Path & sucPath)
void registerSubstitute(const Path & srcPath, const Path & subPath)
{
+ assertStorePath(srcPath);
+ assertStorePath(subPath);
+
if (!isValidPathTxn(subPath, noTxn)) throw Error(
format("path `%1%' cannot be a substitute, since it is not valid")
% subPath);
@@ -262,6 +284,7 @@ Paths querySubstitutes(const Path & srcPath)
void registerValidPath(const Transaction & txn, const Path & _path)
{
Path path(canonPath(_path));
+ assertStorePath(path);
debug(format("registering path `%1%'") % path);
nixDB.setString(txn, dbValidPaths, path, "");
}
@@ -312,13 +335,6 @@ static void invalidatePath(const Path & path, Transaction & txn)
}
-static bool isInPrefix(const string & path, const string & _prefix)
-{
- string prefix = canonPath(_prefix + "/");
- return string(path, 0, prefix.size()) == prefix;
-}
-
-
Path addToStore(const Path & _srcPath)
{
Path srcPath(absPath(_srcPath));
@@ -355,6 +371,8 @@ Path addToStore(const Path & _srcPath)
void addTextToStore(const Path & dstPath, const string & s)
{
+ assertStorePath(dstPath);
+
if (!isValidPath(dstPath)) {
PathSet lockPaths;
@@ -378,8 +396,7 @@ void deleteFromStore(const Path & _path)
{
Path path(canonPath(_path));
- if (!isInPrefix(path, nixStore))
- throw Error(format("path `%1%' is not in the store") % path);
+ assertStorePath(path);
Transaction txn(nixDB);
invalidatePath(path, txn);
@@ -402,6 +419,9 @@ void verifyStore()
if (!pathExists(path)) {
printMsg(lvlError, format("path `%1%' disappeared") % path);
invalidatePath(path, txn);
+ } else if (!isInStore(path)) {
+ printMsg(lvlError, format("path `%1%' is not in the Nix store") % path);
+ invalidatePath(path, txn);
} else
validPaths.insert(path);
}
diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt
index d7f977025..a3dcdebb6 100644
--- a/src/nix-store/help.txt
+++ b/src/nix-store/help.txt
@@ -9,8 +9,10 @@ Operations:
--add / -A: copy a path to the Nix store
--query / -q: query information
- --successor: register a successor expression
- --substitute: register a substitute expression
+ --successor: register a successor expression (dangerous!)
+ --substitute: register a substitute expression (dangerous!)
+ --validpath: register path validity (dangerous!)
+ --isvalid: check path validity
--dump: dump a path as a Nix archive
--restore: restore a path from a Nix archive
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index 078618a5d..4be8e8f44 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -185,6 +185,30 @@ static void opSubstitute(Strings opFlags, Strings opArgs)
}
+static void opValidPath(Strings opFlags, Strings opArgs)
+{
+ if (!opFlags.empty()) throw UsageError("unknown flag");
+
+ Transaction txn;
+ createStoreTransaction(txn);
+ for (Strings::iterator i = opArgs.begin();
+ i != opArgs.end(); ++i)
+ registerValidPath(txn, *i);
+ txn.commit();
+}
+
+
+static void opIsValid(Strings opFlags, Strings opArgs)
+{
+ if (!opFlags.empty()) throw UsageError("unknown flag");
+
+ for (Strings::iterator i = opArgs.begin();
+ i != opArgs.end(); ++i)
+ if (!isValidPath(*i))
+ throw Error(format("path `%1%' is not valid") % *i);
+}
+
+
/* A sink that writes dump output to stdout. */
struct StdoutSink : DumpSink
{
@@ -273,6 +297,10 @@ void run(Strings args)
op = opSuccessor;
else if (arg == "--substitute")
op = opSubstitute;
+ else if (arg == "--validpath")
+ op = opValidPath;
+ else if (arg == "--isvalid")
+ op = opIsValid;
else if (arg == "--dump")
op = opDump;
else if (arg == "--restore")
@@ -292,7 +320,8 @@ void run(Strings args)
if (!op) throw UsageError("no operation specified");
- openDB();
+ if (op != opDump && op != opRestore) /* !!! hack */
+ openDB();
op(opFlags, opArgs);
}