aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/normalise.cc
diff options
context:
space:
mode:
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 ebdf7fdca..64b116712 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);