diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/download-via-ssh/download-via-ssh.cc | 8 | ||||
-rw-r--r-- | src/nix-store/nix-store.cc | 96 | ||||
-rw-r--r-- | src/nix-store/serve-protocol.hh | 15 |
3 files changed, 62 insertions, 57 deletions
diff --git a/src/download-via-ssh/download-via-ssh.cc b/src/download-via-ssh/download-via-ssh.cc index 6361e71e9927..6cbcd9891cf2 100644 --- a/src/download-via-ssh/download-via-ssh.cc +++ b/src/download-via-ssh/download-via-ssh.cc @@ -58,7 +58,7 @@ static std::pair<FdSink, FdSource> connect(const string & conn) static void substitute(std::pair<FdSink, FdSource> & pipes, Path storePath, Path destPath) { - writeInt(cmdSubstitute, pipes.first); + writeInt(cmdDumpStorePath, pipes.first); writeString(storePath, pipes.first); pipes.first.flush(); restorePath(destPath, pipes.second); @@ -68,20 +68,20 @@ static void substitute(std::pair<FdSink, FdSource> & pipes, Path storePath, Path static void query(std::pair<FdSink, FdSource> & pipes) { - writeInt(cmdQuery, pipes.first); for (string line; getline(std::cin, line);) { Strings tokenized = tokenizeString<Strings>(line); string cmd = tokenized.front(); tokenized.pop_front(); if (cmd == "have") { - writeInt(qCmdHave, pipes.first); + writeInt(cmdQueryValidPaths, pipes.first); + writeInt(0, pipes.first); // don't lock writeStrings(tokenized, pipes.first); pipes.first.flush(); PathSet paths = readStrings<PathSet>(pipes.second); foreach (PathSet::iterator, i, paths) std::cout << *i << std::endl; } else if (cmd == "info") { - writeInt(qCmdInfo, pipes.first); + writeInt(cmdQueryPathInfos, pipes.first); writeStrings(tokenized, pipes.first); pipes.first.flush(); while (1) { diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 5bcb82f324fa..849cb7e8a77b 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -869,8 +869,12 @@ 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"); + bool writeAllowed = false; + foreach (Strings::iterator, i, opFlags) + if (*i == "--write") writeAllowed = true; + else throw UsageError(format("unknown flag `%1%'") % *i); + + if (!opArgs.empty()) throw UsageError("no arguments expected"); FdSource in(STDIN_FILENO); FdSink out(STDOUT_FILENO); @@ -883,50 +887,56 @@ static void opServe(Strings opFlags, Strings opArgs) 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 = readStorePaths<PathSet>(in); - writeStrings(store->queryValidPaths(paths), out); - break; - } - case qCmdInfo: { - PathSet paths = readStorePaths<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); + while (true) { + ServeCommand cmd; + try { + cmd = (ServeCommand) readInt(in); + } catch (EndOfFile & e) { + break; + } + + switch (cmd) { + case cmdQueryValidPaths: { + bool lock = readInt(in); + PathSet paths = readStorePaths<PathSet>(in); + if (lock && writeAllowed) + for (auto & path : paths) + store->addTempRoot(path); + writeStrings(store->queryValidPaths(paths), out); + out.flush(); + break; + } + case cmdQueryPathInfos: { + PathSet paths = readStorePaths<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); out.flush(); + break; } - break; - case cmdSubstitute: - dumpPath(readStorePath(in), out); - break; - default: - throw Error(format("unknown serve command `%1%'") % cmd); + case cmdDumpStorePath: + dumpPath(readStorePath(in), out); + out.flush(); + break; + case cmdImportPaths: + if (!writeAllowed) throw Error("importing paths not allowed"); + store->importPaths(false, in); + writeInt(1, out); // indicate success + out.flush(); + break; + default: + throw Error(format("unknown serve command %1%") % cmd); + } } } diff --git a/src/nix-store/serve-protocol.hh b/src/nix-store/serve-protocol.hh index 69277bc1b99b..07ff4f7a7cc4 100644 --- a/src/nix-store/serve-protocol.hh +++ b/src/nix-store/serve-protocol.hh @@ -2,23 +2,18 @@ namespace nix { - #define SERVE_MAGIC_1 0x390c9deb #define SERVE_MAGIC_2 0x5452eecb -#define SERVE_PROTOCOL_VERSION 0x101 +#define SERVE_PROTOCOL_VERSION 0x200 #define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) #define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff) - typedef enum { - cmdQuery = 0, - cmdSubstitute = 1, + cmdQueryValidPaths = 1, + cmdQueryPathInfos = 2, + cmdDumpStorePath = 3, + cmdImportPaths = 4, } ServeCommand; -typedef enum { - qCmdHave = 0, - qCmdInfo = 1, -} QueryCommand; - } |