summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/local-store.cc31
-rw-r--r--src/libstore/remote-store.cc25
-rw-r--r--src/libstore/store-api.cc40
-rw-r--r--src/libstore/store-api.hh30
-rw-r--r--src/nix-worker/main.cc23
5 files changed, 116 insertions, 33 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index e3f22a9c9e..ed948cf4e5 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -625,29 +625,10 @@ Path LocalStore::_addToStore(bool fixed, bool recursive,
     Path srcPath(absPath(_srcPath));
     debug(format("adding `%1%' to the store") % srcPath);
 
-    Hash h(htSHA256);
-    {
-        SwitchToOriginalUser sw;
-        h = hashPath(htSHA256, srcPath);
-    }
-
-    string baseName = baseNameOf(srcPath);
-
-    Path dstPath;
-    
-    if (fixed) {
-
-        HashType ht(parseHashType(hashAlgo));
-        Hash h2(ht);
-        {
-            SwitchToOriginalUser sw;
-            h2 = recursive ? hashPath(ht, srcPath) : hashFile(ht, srcPath);
-        }
-        
-        dstPath = makeFixedOutputPath(recursive, hashAlgo, h2, baseName);
-    }
-        
-    else dstPath = makeStorePath("source", h, baseName);
+    std::pair<Path, Hash> pr =
+        computeStorePathForPath(fixed, recursive, hashAlgo, srcPath);
+    Path & dstPath(pr.first);
+    Hash & h(pr.second);
 
     if (!readOnlyMode) addTempRoot(dstPath);
 
@@ -698,9 +679,7 @@ Path LocalStore::addToStoreFixed(bool recursive, string hashAlgo, const Path & s
 Path LocalStore::addTextToStore(const string & suffix, const string & s,
     const PathSet & references)
 {
-    Hash hash = hashString(htSHA256, s);
-
-    Path dstPath = makeStorePath("text", hash, suffix);
+    Path dstPath = computeStorePathForText(suffix, s);
     
     if (!readOnlyMode) addTempRoot(dstPath);
 
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index ce09ddada0..e04bb67139 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -3,6 +3,7 @@
 #include "remote-store.hh"
 #include "worker-protocol.hh"
 #include "archive.hh"
+#include "globals.hh"
 
 #include <iostream>
 #include <unistd.h>
@@ -124,6 +125,12 @@ void RemoteStore::queryReferrers(const Path & path,
 
 Path RemoteStore::addToStore(const Path & srcPath)
 {
+    if (readOnlyMode) {
+        /* No sense in making a round trip, we can just compute the
+           path here. */
+        return computeStorePathForPath(false, false, "", srcPath).first;
+    }
+    
     writeInt(wopAddToStore, to);
     writeString(baseNameOf(srcPath), to);
     dumpPath(srcPath, to);
@@ -135,13 +142,29 @@ Path RemoteStore::addToStore(const Path & srcPath)
 Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo,
     const Path & srcPath)
 {
-    throw Error("not implemented 6");
+    if (readOnlyMode) {
+        /* No sense in making a round trip, we can just compute the
+           path here. */
+        return computeStorePathForPath(true, recursive, hashAlgo, srcPath).first;
+    }
+    
+    writeInt(wopAddToStoreFixed, to);
+    writeString(baseNameOf(srcPath), to);
+    writeInt(recursive ? 1 : 0, to);
+    writeString(hashAlgo, to);
+    dumpPath(srcPath, to);
+    Path path = readString(from);
+    return path;
 }
 
 
 Path RemoteStore::addTextToStore(const string & suffix, const string & s,
     const PathSet & references)
 {
+    if (readOnlyMode) {
+        return computeStorePathForText(suffix, s);
+    }
+    
     writeInt(wopAddTextToStore, to);
     writeString(suffix, to);
     writeString(s, to);
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index f1e7c35620..e00f01bfd4 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -92,7 +92,45 @@ Path makeFixedOutputPath(bool recursive,
     return makeStorePath("output:out", h, name);
 }
 
- 
+
+std::pair<Path, Hash> computeStorePathForPath(bool fixed, bool recursive,
+    string hashAlgo, const Path & srcPath)
+{
+    Hash h(htSHA256);
+    {
+        SwitchToOriginalUser sw;
+        h = hashPath(htSHA256, srcPath);
+    }
+
+    string baseName = baseNameOf(srcPath);
+
+    Path dstPath;
+    
+    if (fixed) {
+
+        HashType ht(parseHashType(hashAlgo));
+        Hash h2(ht);
+        {
+            SwitchToOriginalUser sw;
+            h2 = recursive ? hashPath(ht, srcPath) : hashFile(ht, srcPath);
+        }
+        
+        dstPath = makeFixedOutputPath(recursive, hashAlgo, h2, baseName);
+    }
+        
+    else dstPath = makeStorePath("source", h, baseName);
+
+    return std::pair<Path, Hash>(dstPath, h);
+}
+
+
+Path computeStorePathForText(const string & suffix, const string & s)
+{
+    Hash hash = hashString(htSHA256, s);
+    return makeStorePath("text", hash, suffix);
+}
+
+
 }
 
 
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 31e8152e86..cbf2f7ef29 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -54,12 +54,12 @@ public:
 
     /* Queries the set of outgoing FS references for a store path.
        The result is not cleared. */
-    virtual void queryReferences(const Path & storePath,
+    virtual void queryReferences(const Path & path,
         PathSet & references) = 0;
 
     /* Queries the set of incoming FS references for a store path.
        The result is not cleared. */
-    virtual void queryReferrers(const Path & storePath,
+    virtual void queryReferrers(const Path & path,
         PathSet & referrers) = 0;
 
     /* Copy the contents of a path to the store and register the
@@ -88,7 +88,7 @@ public:
     /* Ensure that a path is valid.  If it is not currently valid, it
        may be made valid by running a substitute (if defined for the
        path). */
-    virtual void ensurePath(const Path & storePath) = 0;
+    virtual void ensurePath(const Path & path) = 0;
 };
 
 
@@ -115,6 +115,30 @@ Path makeFixedOutputPath(bool recursive,
     string hashAlgo, Hash hash, string name);
 
 
+/* This is the preparatory part of addToStore() and addToStoreFixed();
+   it computes the store path to which srcPath is to be copied.
+   Returns the store path and the cryptographic hash of the
+   contents of srcPath. */
+std::pair<Path, Hash> computeStorePathForPath(bool fixed, bool recursive,
+    string hashAlgo, const Path & srcPath);
+
+/* Preparatory part of addTextToStore().
+
+   !!! Computation of the path should take the references given to
+   addTextToStore() into account, otherwise we have a (relatively
+   minor) security hole: a caller can register a source file with
+   bogus references.  If there are too many references, the path may
+   not be garbage collected when it has to be (not really a problem,
+   the caller could create a root anyway), or it may be garbage
+   collected when it shouldn't be (more serious).
+
+   Hashing the references would solve this (bogus references would
+   simply yield a different store path, so other users wouldn't be
+   affected), but it has some backwards compatibility issues (the
+   hashing scheme changes), so I'm not doing that for now. */
+Path computeStorePathForText(const string & suffix, const string & s);
+
+
 /* For now, there is a single global store API object, but we'll
    purify that in the future. */
 extern boost::shared_ptr<StoreAPI> store;
diff --git a/src/nix-worker/main.cc b/src/nix-worker/main.cc
index 8ac69561f0..5d57dd6b62 100644
--- a/src/nix-worker/main.cc
+++ b/src/nix-worker/main.cc
@@ -37,11 +37,15 @@ void processConnection(Source & from, Sink & to)
     debug("greeting exchanged");
 
     bool quit = false;
+
+    unsigned int opCount = 0;
     
     do {
         
         WorkerOp op = (WorkerOp) readInt(from);
 
+        opCount++;
+
         switch (op) {
 
         case wopQuit:
@@ -75,13 +79,26 @@ void processConnection(Source & from, Sink & to)
             break;
         }
 
-        case wopAddToStore: {
+        case wopAddToStore:
+        case wopAddToStoreFixed: {
             /* !!! uberquick hack */
             string baseName = readString(from);
+            bool recursive = false;
+            string hashAlgo;
+            if (op == wopAddToStoreFixed) {
+                recursive = readInt(from) == 1;
+                hashAlgo = readString(from);
+            }
+
             Path tmp = createTempDir();
             Path tmp2 = tmp + "/" + baseName;
             restorePath(tmp2, from);
-            writeString(store->addToStore(tmp2), to);
+
+            if (op == wopAddToStoreFixed)
+                writeString(store->addToStoreFixed(recursive, hashAlgo, tmp2), to);
+            else
+                writeString(store->addToStore(tmp2), to);
+            
             deletePath(tmp);
             break;
         }
@@ -113,6 +130,8 @@ void processConnection(Source & from, Sink & to)
         }
         
     } while (!quit);
+
+    printMsg(lvlError, format("%1% worker operations") % opCount);
 }