mirror of
https://github.com/NixOS/nix
synced 2025-06-29 10:31:15 +02:00
Merge branch 'ssh-store' of https://github.com/shlevy/nix
This commit is contained in:
commit
4b8f1b0ec0
15 changed files with 465 additions and 91 deletions
|
@ -22,6 +22,7 @@
|
|||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if __APPLE__ || __FreeBSD__
|
||||
#include <sys/ucred.h>
|
||||
|
@ -29,6 +30,25 @@
|
|||
|
||||
using namespace nix;
|
||||
|
||||
#ifndef __linux__
|
||||
#define SPLICE_F_MOVE 0
|
||||
static ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags)
|
||||
{
|
||||
/* We ignore most parameters, we just have them for conformance with the linux syscall */
|
||||
char buf[8192];
|
||||
auto read_count = read(fd_in, buf, sizeof(buf));
|
||||
if (read_count == -1)
|
||||
return read_count;
|
||||
auto write_count = decltype<read_count>(0);
|
||||
while (write_count < read_count) {
|
||||
auto res = write(fd_out, buf + write_count, read_count - write_count);
|
||||
if (res == -1)
|
||||
return res;
|
||||
write_count += res;
|
||||
}
|
||||
return read_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static FdSource from(STDIN_FILENO);
|
||||
static FdSink to(STDOUT_FILENO);
|
||||
|
@ -556,6 +576,37 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
break;
|
||||
}
|
||||
|
||||
case wopNarFromPath: {
|
||||
auto path = readStorePath(*store, from);
|
||||
startWork();
|
||||
stopWork();
|
||||
dumpPath(path, to);
|
||||
break;
|
||||
}
|
||||
|
||||
case wopAddToStoreNar: {
|
||||
ValidPathInfo info;
|
||||
info.path = readStorePath(*store, from);
|
||||
info.deriver = readString(from);
|
||||
if (!info.deriver.empty())
|
||||
store->assertStorePath(info.deriver);
|
||||
info.narHash = parseHash(htSHA256, readString(from));
|
||||
info.references = readStorePaths<PathSet>(*store, from);
|
||||
info.registrationTime = readInt(from);
|
||||
info.narSize = readLongLong(from);
|
||||
info.ultimate = readLongLong(from);
|
||||
info.sigs = readStrings<StringSet>(from);
|
||||
auto nar = make_ref<std::string>(readString(from));
|
||||
auto repair = readInt(from) ? true : false;
|
||||
auto dontCheckSigs = readInt(from) ? true : false;
|
||||
if (!trusted && dontCheckSigs)
|
||||
dontCheckSigs = false;
|
||||
startWork();
|
||||
store->addToStore(info, nar, repair, dontCheckSigs, nullptr);
|
||||
stopWork();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw Error(format("invalid operation %1%") % op);
|
||||
}
|
||||
|
@ -885,6 +936,8 @@ int main(int argc, char * * argv)
|
|||
return handleExceptions(argv[0], [&]() {
|
||||
initNix();
|
||||
|
||||
auto stdio = false;
|
||||
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--daemon")
|
||||
; /* ignored for backwards compatibility */
|
||||
|
@ -892,10 +945,62 @@ int main(int argc, char * * argv)
|
|||
showManPage("nix-daemon");
|
||||
else if (*arg == "--version")
|
||||
printVersion("nix-daemon");
|
||||
else if (*arg == "--stdio")
|
||||
stdio = true;
|
||||
else return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
daemonLoop(argv);
|
||||
if (stdio) {
|
||||
if (getStoreType() == tDaemon) {
|
||||
/* Forward on this connection to the real daemon */
|
||||
auto socketPath = settings.nixDaemonSocketFile;
|
||||
auto s = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (s == -1)
|
||||
throw SysError("creating Unix domain socket");
|
||||
|
||||
auto socketDir = dirOf(socketPath);
|
||||
if (chdir(socketDir.c_str()) == -1)
|
||||
throw SysError(format("changing to socket directory ‘%1%’") % socketDir);
|
||||
|
||||
auto socketName = baseNameOf(socketPath);
|
||||
auto addr = sockaddr_un{};
|
||||
addr.sun_family = AF_UNIX;
|
||||
if (socketName.size() + 1 >= sizeof(addr.sun_path))
|
||||
throw Error(format("socket name %1% is too long") % socketName);
|
||||
strcpy(addr.sun_path, socketName.c_str());
|
||||
|
||||
if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) == -1)
|
||||
throw SysError(format("cannot connect to daemon at %1%") % socketPath);
|
||||
|
||||
auto nfds = (s > STDIN_FILENO ? s : STDIN_FILENO) + 1;
|
||||
while (true) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(s, &fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
if (select(nfds, &fds, nullptr, nullptr, nullptr) == -1)
|
||||
throw SysError("waiting for data from client or server");
|
||||
if (FD_ISSET(s, &fds)) {
|
||||
auto res = splice(s, nullptr, STDOUT_FILENO, nullptr, SIZE_MAX, SPLICE_F_MOVE);
|
||||
if (res == -1)
|
||||
throw SysError("splicing data from daemon socket to stdout");
|
||||
else if (res == 0)
|
||||
throw EndOfFile("unexpected EOF from daemon socket");
|
||||
}
|
||||
if (FD_ISSET(STDIN_FILENO, &fds)) {
|
||||
auto res = splice(STDIN_FILENO, nullptr, s, nullptr, SIZE_MAX, SPLICE_F_MOVE);
|
||||
if (res == -1)
|
||||
throw SysError("splicing data from stdin to daemon socket");
|
||||
else if (res == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
processConnection(true);
|
||||
}
|
||||
} else {
|
||||
daemonLoop(argv);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue