aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstore/store-api.cc31
-rw-r--r--src/libstore/store-api.hh4
-rw-r--r--src/nix-store/nix-store.cc20
3 files changed, 55 insertions, 0 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 0f250a3c7..1a13e7ca3 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -258,6 +258,37 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
}
+void StoreAPI::serve(Source & in, Sink & out, bool sign)
+{
+ for (string cmd = readString(in); !cmd.empty(); cmd = readString(in)) {
+ if (cmd == "query") {
+ for (cmd = readString(in); !cmd.empty(); cmd = readString(in)) {
+ PathSet paths = readStrings<PathSet>(in);
+ if (cmd == "have") {
+ writeStrings(queryValidPaths(paths), out);
+ } else if (cmd == "info") {
+ // !!! Maybe we want a queryPathInfos?
+ foreach (PathSet::iterator, i, paths) {
+ ValidPathInfo info = 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);
+ } else
+ throw Error(format("Unknown serve query `%1%'") % cmd);
+ }
+ } else if (cmd == "substitute")
+ exportPath(readString(in), sign, out);
+ else
+ throw Error(format("Unknown serve command `%1%'") % cmd);
+ }
+}
+
+
ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
{
ValidPathInfo info;
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index a82fe3221..57cf51794 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -248,6 +248,10 @@ public:
`nix-store --register-validity'. */
string makeValidityRegistration(const PathSet & paths,
bool showDerivers, bool showHash);
+
+ /* Serve the store for ssh substituters by taking commands
+ * from in and printing results to out */
+ void serve(Source & in, Sink & out, bool sign);
};
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 69a98fe47..fb1d3f541 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -834,6 +834,24 @@ 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())
+ throw UsageError("no arguments expected");
+ // Could eventually take a username argument?
+ bool sign;
+ foreach (Strings::iterator, i, opFlags)
+ if (*i == "--sign") sign = true;
+ else throw UsageError(format("unknown flag `%1%'") % *i);
+
+ FdSource in(STDIN_FILENO);
+ FdSink out(STDOUT_FILENO);
+
+ store->serve(in, out, sign);
+}
+
+
/* 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 +922,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 */