aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-06-23 14:40:49 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-06-23 14:40:49 +0000
commit692b562342ac7ead43ef06497f6a8b4b6e724ae5 (patch)
tree4cd87673fff6af4c6c5501b274bfc1023246aaba
parentc0cbaef4bece0c2447828739dd9622c329948064 (diff)
* `nix --delete' command.
-rw-r--r--src/nix.cc14
-rw-r--r--src/test.cc4
-rw-r--r--src/util.cc29
-rw-r--r--src/util.hh5
-rw-r--r--src/values.cc12
-rw-r--r--src/values.hh4
6 files changed, 66 insertions, 2 deletions
diff --git a/src/nix.cc b/src/nix.cc
index bd3565810..9b21f0379 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -112,8 +112,20 @@ static void opEvaluate(Strings opFlags, Strings opArgs)
static void opDelete(Strings opFlags, Strings opArgs)
{
getArgType(opFlags);
+ if (!opFlags.empty()) throw UsageError("unknown flag");
- cerr << "delete!\n";
+ for (Strings::iterator it = opArgs.begin();
+ it != opArgs.end(); it++)
+ {
+ Hash hash;
+ if (argType == atpHash)
+ hash = parseHash(*it);
+ else if (argType == atpName)
+ throw Error("not implemented");
+ else
+ throw Error("invalid argument type");
+ deleteValue(hash);
+ }
}
diff --git a/src/test.cc b/src/test.cc
index c8e3292e3..268b35d89 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -68,7 +68,7 @@ void runTests()
#endif
/* Restoring. */
-#if 1
+#if 0
MySource source;
restorePath("outdir", source);
cout << (string) hashPath("outdir") << endl;
@@ -116,6 +116,8 @@ void runTests()
Expr e3 = ATmake("Deref(Hash(<str>))", ((string) h3).c_str());
evalTest(e3);
+
+ deleteValue(h3);
}
diff --git a/src/util.cc b/src/util.cc
index 8c397aace..4dada48ba 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -1,5 +1,10 @@
#include <iostream>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+
#include "util.hh"
@@ -49,6 +54,30 @@ string baseNameOf(string path)
}
+void deletePath(string path)
+{
+ struct stat st;
+ if (lstat(path.c_str(), &st))
+ throw SysError("getting attributes of path " + path);
+
+ if (S_ISDIR(st.st_mode)) {
+ DIR * dir = opendir(path.c_str());
+
+ struct dirent * dirent;
+ while (errno = 0, dirent = readdir(dir)) {
+ string name = dirent->d_name;
+ if (name == "." || name == "..") continue;
+ deletePath(path + "/" + name);
+ }
+
+ closedir(dir); /* !!! close on exception */
+ }
+
+ if (remove(path.c_str()) == -1)
+ throw SysError("cannot unlink " + path);
+}
+
+
void debug(string s)
{
cerr << "debug: " << s << endl;
diff --git a/src/util.hh b/src/util.hh
index 45719e701..7d5f00a2e 100644
--- a/src/util.hh
+++ b/src/util.hh
@@ -54,6 +54,11 @@ string dirOf(string path);
string baseNameOf(string path);
+/* Delete a path; i.e., in the case of a directory, it is deleted
+ recursively. Don't use this at home, kids. */
+void deletePath(string path);
+
+
void debug(string s);
diff --git a/src/values.cc b/src/values.cc
index 22f84c83e..c8a3b58cb 100644
--- a/src/values.cc
+++ b/src/values.cc
@@ -135,6 +135,18 @@ string fetchURL(string url)
#endif
+void deleteValue(Hash hash)
+{
+ string name;
+ if (queryDB(nixDB, dbRefs, hash, name)) {
+ string fn = absValuePath(name);
+ deletePath(fn);
+ delDB(nixDB, dbRefs, hash);
+ }
+}
+
+
+/* !!! bad name, "query" implies no side effect => getValuePath() */
string queryValuePath(Hash hash)
{
bool checkedNet = false;
diff --git a/src/values.hh b/src/values.hh
index 5dd7b89c4..d66ae770f 100644
--- a/src/values.hh
+++ b/src/values.hh
@@ -13,6 +13,10 @@ using namespace std;
Hash addValue(string pathName);
+/* Delete a value from the nixValues directory. */
+void deleteValue(Hash hash);
+
+
/* Obtain the path of a value with the given hash. If a file with
that hash is known to exist in the local file system (as indicated
by the dbRefs database), we use that. Otherwise, we attempt to