about summary refs log tree commit diff
path: root/src/libstore/normalise.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-11-29T15·09+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-11-29T15·09+0000
commit4115d8d8ce29113d9cb4efe7018dfb11f8038978 (patch)
tree9f1aef9c66d75a3e03fb1955769e4e032f8dfd48 /src/libstore/normalise.cc
parent5d5318c2ff57a110883a0d404f3673c76cd491b4 (diff)
* Canonicalise metadata of all files in store paths (set the mtime to
  0, set the mode to either 444 or 555, set the group to the default).

Diffstat (limited to 'src/libstore/normalise.cc')
-rw-r--r--src/libstore/normalise.cc60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index ebdf7fdca224..64b116712a31 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -8,6 +8,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <utime.h>
 
 #include "normalise.hh"
 #include "references.hh"
@@ -298,6 +299,61 @@ Path queryNormalForm(const Path & nePath)
 }
 
 
+/* "Fix", or canonicalise, the meta-data of the files in a store path
+   after it has been built.  In particular:
+   - the last modification date on each file is set to 0 (i.e.,
+     00:00:00 1/1/1970 UTC)
+   - the permissions are set of 444 or 555 (i.e., read-only with or
+     without execute permission; setuid bits etc. are cleared)
+   - the owner and group are set to the Nix user and group, if we're
+     in a setuid Nix installation
+*/
+void canonicalisePathMetaData(const Path & path)
+{
+    checkInterrupt();
+
+    struct stat st;
+    if (lstat(path.c_str(), &st))
+	throw SysError(format("getting attributes of path `%1%'") % path);
+
+    cerr << "foo!" << path << "\n";
+    
+    if (!S_ISLNK(st.st_mode)) {
+
+        /* Mask out all type related bits. */
+        mode_t mode = st.st_mode & ~S_IFMT;
+        
+        if (mode != 0444 && mode != 0555) {
+            mode = (st.st_mode & S_IFMT)
+                 | 0444
+                 | (st.st_mode & S_IXUSR ? 0111 : 0);
+            if (chmod(path.c_str(), mode) == -1)
+                throw SysError(format("changing mode of `%1%' to %2$o") % path % mode);
+        }
+
+        if (st.st_uid != getuid() || st.st_gid != getgid()) {
+            if (chown(path.c_str(), getuid(), getgid()) == -1)
+                throw SysError(format("changing owner/group of `%1%' to %2%/%3%")
+                    % path % getuid() % getgid());
+        }
+    }
+
+    if (st.st_mtime != 0) {
+        struct utimbuf utimbuf;
+        utimbuf.actime = st.st_atime;
+        utimbuf.modtime = 0;
+        if (utime(path.c_str(), &utimbuf) == -1) 
+            throw SysError(format("changing modification time of `%1%'") % path);
+    }
+
+    if (S_ISDIR(st.st_mode)) {
+        Strings names = readDirectory(path);
+	for (Strings::iterator i = names.begin(); i != names.end(); ++i)
+	    canonicalisePathMetaData(path + "/" + *i);
+    }
+}
+
+
 
 //////////////////////////////////////////////////////////////////////
 
@@ -1009,7 +1065,7 @@ void NormalisationGoal::createClosure()
         }
         nf.closure.roots.insert(path);
 
-	makePathReadOnly(path);
+	canonicalisePathMetaData(path);
 
 	/* For this output path, find the references to other paths contained
 	   in it. */
@@ -1601,7 +1657,7 @@ void SubstitutionGoal::finished()
         return;
     }
 
-    makePathReadOnly(storePath);
+    canonicalisePathMetaData(storePath);
 
     Transaction txn;
     createStoreTransaction(txn);