about summary refs log tree commit diff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-02-22T21·14+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-02-22T21·14+0000
commit3a2c3f0cf265075b130d9d2a25b9c8334c560b33 (patch)
tree5647390d868e6ea2607d065974ec932e5dcb47f1 /src/libstore/build.cc
parenteda2c3c2537562e3b18c02a47b19e47ba3d37598 (diff)
* Support for fixed-output hashes over directory trees (i.e., over the
  NAR dump of the path).

Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc40
1 files changed, 26 insertions, 14 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 1ba521eb37..f6b081aafc 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1082,25 +1082,37 @@ void DerivationGoal::computeClosure()
            outputs (i.e., the content hash should match the specified
            hash). */ 
         if (i->second.hash != "") {
-            HashType ht = parseHashType(i->second.hashAlgo);
+
+            bool recursive = false;
+            string algo = i->second.hashAlgo;
+            
+            if (string(algo, 0, 2) == "r:") {
+                recursive = true;
+                algo = string(algo, 2);
+            }
+
+            if (!recursive) {
+                /* The output path should be a regular file without
+                   execute permission. */
+                struct stat st;
+                if (lstat(path.c_str(), &st))
+                    throw SysError(format("getting attributes of path `%1%'") % path);
+                if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
+                    throw Error(
+                        format("output path `%1% should be a non-executable regular file")
+                        % path);
+            }
+
+            /* Check the hash. */
+            HashType ht = parseHashType(algo);
             if (ht == htUnknown)
-                throw Error(format("unknown hash algorithm `%1%'") % i->second.hashAlgo);
+                throw Error(format("unknown hash algorithm `%1%'") % algo);
             Hash h = parseHash(ht, i->second.hash);
-            Hash h2 = hashFile(ht, path);
+            Hash h2 = recursive ? hashPath(ht, path) : hashFile(ht, path);
             if (h != h2)
                 throw Error(
                     format("output path `%1% should have %2% hash `%3%', instead has `%4%'")
-                    % path % i->second.hashAlgo % printHash(h) % printHash(h2));
-
-            /* Also, the output path should be a regular file withouth
-               execute permission. */
-            struct stat st;
-            if (lstat(path.c_str(), &st))
-                throw SysError(format("getting attributes of path `%1%'") % path);
-            if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
-                throw Error(
-                    format("output path `%1% should be a non-executable regular file")
-                    % path);
+                    % path % algo % printHash(h) % printHash(h2));
         }
 
 	canonicalisePathMetaData(path);