diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-02-14T10·42+0100 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-02-14T10·42+0100 |
commit | 61fd494d760d667649fa48665f9aa75ba88a1eb6 (patch) | |
tree | 2ce091b595c70f47af9eb50007fdcdcc0b032808 /src/nix-store | |
parent | f9fc6acbf4eadd2d9018d3da14394fdfbddde5f6 (diff) | |
parent | f67f52751f21b2fe70b5a7352053f130eb6f0f59 (diff) |
Merge remote-tracking branch 'shlevy/ssh-substituter'
Diffstat (limited to 'src/nix-store')
-rw-r--r-- | src/nix-store/nix-store.cc | 68 | ||||
-rw-r--r-- | src/nix-store/serve-protocol.hh | 24 |
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; + +} |