about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/remote-store.cc16
-rw-r--r--src/libstore/remote-store.hh2
-rw-r--r--src/libstore/worker-protocol.hh3
-rw-r--r--src/nix-worker/nix-worker.cc26
4 files changed, 42 insertions, 5 deletions
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 801df58ad9fe..dbeb7cf1227f 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -246,7 +246,11 @@ Path RemoteStore::addTextToStore(const string & suffix, const string & s,
 void RemoteStore::exportPath(const Path & path, bool sign,
     Sink & sink)
 {
-    throw Error("not implemented");
+    writeInt(wopExportPath, to);
+    writeString(path, to);
+    writeInt(sign ? 1 : 0, to);
+    processStderr(&sink); /* sink receives the actual data */
+    readInt(from);
 }
 
 
@@ -336,12 +340,16 @@ void RemoteStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
 }
 
 
-void RemoteStore::processStderr()
+void RemoteStore::processStderr(Sink * sink)
 {
     unsigned int msg;
-    while ((msg = readInt(from)) == STDERR_NEXT) {
+    while ((msg = readInt(from)) == STDERR_NEXT || msg == STDERR_DATA) {
         string s = readString(from);
-        writeToStderr((unsigned char *) s.c_str(), s.size());
+        if (msg == STDERR_DATA) {
+            if (!sink) throw Error("no sink");
+            (*sink)((const unsigned char *) s.c_str(), s.size());
+        }
+        else writeToStderr((const unsigned char *) s.c_str(), s.size());
     }
     if (msg == STDERR_ERROR)
         throw Error(readString(from));
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 4c594b606670..f57dcbd93866 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -70,7 +70,7 @@ private:
     FdSource from;
     Pid child;
 
-    void processStderr();
+    void processStderr(Sink * sink = 0);
 
     void forkSlave();
     
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index b3339101103b..e48fd5fe9708 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -26,10 +26,13 @@ typedef enum {
     wopSyncWithGC,
     wopFindRoots,
     wopCollectGarbage,
+    wopExportPath,
+    wopImportPath,
 } WorkerOp;
 
 
 #define STDERR_NEXT  0x6f6c6d67
+#define STDERR_DATA  0x64617461
 #define STDERR_LAST  0x616c7473
 #define STDERR_ERROR 0x63787470
 
diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc
index 17fbbf264693..04578a8b8794 100644
--- a/src/nix-worker/nix-worker.cc
+++ b/src/nix-worker/nix-worker.cc
@@ -178,6 +178,21 @@ static void stopWork(bool success = true, const string & msg = "")
 }
 
 
+struct TunnelSink : Sink
+{
+    Sink & to;
+    TunnelSink(Sink & to) : to(to)
+    {
+    }
+    virtual void operator ()
+        (const unsigned char * data, unsigned int len)
+    {
+        writeInt(STDERR_DATA, to);
+        writeString(string((const char *) data, len), to);
+    }
+};
+
+
 static void performOp(Source & from, Sink & to, unsigned int op)
 {
     switch (op) {
@@ -263,6 +278,17 @@ static void performOp(Source & from, Sink & to, unsigned int op)
         break;
     }
 
+    case wopExportPath: {
+        Path path = readStorePath(from);
+        bool sign = readInt(from) == 1;
+        startWork();
+        TunnelSink sink(to);
+        store->exportPath(path, sign, sink);
+        stopWork();
+        writeInt(1, to);
+        break;
+    }
+
     case wopBuildDerivations: {
         PathSet drvs = readStorePaths(from);
         startWork();