about summary refs log tree commit diff
path: root/src/nix-store
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-02-14T10·42+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-02-14T10·42+0100
commit61fd494d760d667649fa48665f9aa75ba88a1eb6 (patch)
tree2ce091b595c70f47af9eb50007fdcdcc0b032808 /src/nix-store
parentf9fc6acbf4eadd2d9018d3da14394fdfbddde5f6 (diff)
parentf67f52751f21b2fe70b5a7352053f130eb6f0f59 (diff)
Merge remote-tracking branch 'shlevy/ssh-substituter'
Diffstat (limited to 'src/nix-store')
-rw-r--r--src/nix-store/nix-store.cc68
-rw-r--r--src/nix-store/serve-protocol.hh24
2 files changed, 92 insertions, 0 deletions
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 69a98fe4726d..350a4ce0fa37 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -6,6 +6,7 @@
 #include "xmlgraph.hh"
 #include "local-store.hh"
 #include "util.hh"
+#include "serve-protocol.hh"
 
 #include <iostream>
 #include <algorithm>
@@ -834,6 +835,71 @@ static void opClearFailedPaths(Strings opFlags, Strings opArgs)
 }
 
 
+// Serve the nix store in a way usable by a restricted ssh user
+static void opServe(Strings opFlags, Strings opArgs)
+{
+    if (!opArgs.empty() || !opFlags.empty())
+        throw UsageError("no arguments or flags expected");
+
+    FdSource in(STDIN_FILENO);
+    FdSink out(STDOUT_FILENO);
+
+    /* Exchange the greeting. */
+    unsigned int magic = readInt(in);
+    if (magic != SERVE_MAGIC_1) throw Error("protocol mismatch");
+    writeInt(SERVE_MAGIC_2, out);
+    writeInt(SERVE_PROTOCOL_VERSION, out);
+    out.flush();
+    readInt(in); // Client version, unused for now
+
+    ServeCommand cmd = (ServeCommand) readInt(in);
+    switch (cmd) {
+        case cmdQuery:
+            while (true) {
+                QueryCommand qCmd;
+                try {
+                    qCmd = (QueryCommand) readInt(in);
+                } catch (EndOfFile & e) {
+                    break;
+                }
+                switch (qCmd) {
+                    case qCmdHave: {
+                        PathSet paths = readStrings<PathSet>(in);
+                        writeStrings(store->queryValidPaths(paths), out);
+                        break;
+                    }
+                    case qCmdInfo: {
+                        PathSet paths = readStrings<PathSet>(in);
+                        // !!! Maybe we want a queryPathInfos?
+                        foreach (PathSet::iterator, i, paths) {
+                            if (!store->isValidPath(*i))
+                                continue;
+                            ValidPathInfo info = store->queryPathInfo(*i);
+                            writeString(info.path, out);
+                            writeString(info.deriver, out);
+                            writeStrings(info.references, out);
+                            // !!! Maybe we want compression?
+                            writeLongLong(info.narSize, out); // downloadSize
+                            writeLongLong(info.narSize, out);
+                        }
+                        writeString("", out);
+                        break;
+                    }
+                    default:
+                        throw Error(format("unknown serve query `%1%'") % cmd);
+                }
+                out.flush();
+            }
+            break;
+        case cmdSubstitute:
+            dumpPath(readString(in), out);
+            break;
+        default:
+            throw Error(format("unknown serve command `%1%'") % cmd);
+    }
+}
+
+
 /* Scan the arguments; find the operation, set global flags, put all
    other flags in a list, and put all other arguments in another
    list. */
@@ -904,6 +970,8 @@ void run(Strings args)
             indirectRoot = true;
         else if (arg == "--no-output")
             noOutput = true;
+        else if (arg == "--serve")
+            op = opServe;
         else if (arg[0] == '-') {
             opFlags.push_back(arg);
             if (arg == "--max-freed" || arg == "--max-links" || arg == "--max-atime") { /* !!! hack */
diff --git a/src/nix-store/serve-protocol.hh b/src/nix-store/serve-protocol.hh
new file mode 100644
index 000000000000..69277bc1b99b
--- /dev/null
+++ b/src/nix-store/serve-protocol.hh
@@ -0,0 +1,24 @@
+#pragma once
+
+namespace nix {
+
+
+#define SERVE_MAGIC_1 0x390c9deb
+#define SERVE_MAGIC_2 0x5452eecb
+
+#define SERVE_PROTOCOL_VERSION 0x101
+#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
+#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
+
+
+typedef enum {
+    cmdQuery = 0,
+    cmdSubstitute = 1,
+} ServeCommand;
+
+typedef enum {
+    qCmdHave = 0,
+    qCmdInfo = 1,
+} QueryCommand;
+
+}