* Skeleton of the privileged worker program.
* Some refactoring: put the NAR archive integer/string serialisation code in a separate file so it can be reused by the worker protocol implementation.
This commit is contained in:
parent
9adc074dc3
commit
40b3f64b55
12 changed files with 255 additions and 126 deletions
|
@ -266,6 +266,7 @@ AC_CONFIG_FILES([Makefile
|
||||||
src/libexpr/Makefile
|
src/libexpr/Makefile
|
||||||
src/nix-instantiate/Makefile
|
src/nix-instantiate/Makefile
|
||||||
src/nix-env/Makefile
|
src/nix-env/Makefile
|
||||||
|
src/nix-worker/Makefile
|
||||||
src/nix-log2xml/Makefile
|
src/nix-log2xml/Makefile
|
||||||
src/bsdiff-4.3/Makefile
|
src/bsdiff-4.3/Makefile
|
||||||
scripts/Makefile
|
scripts/Makefile
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
|
SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \
|
||||||
libexpr nix-instantiate nix-env nix-log2xml bsdiff-4.3
|
libexpr nix-instantiate nix-env nix-worker nix-log2xml bsdiff-4.3
|
||||||
|
|
||||||
EXTRA_DIST = aterm-helper.pl
|
EXTRA_DIST = aterm-helper.pl
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ void createStoreTransaction(Transaction & txn)
|
||||||
|
|
||||||
/* Path copying. */
|
/* Path copying. */
|
||||||
|
|
||||||
struct CopySink : DumpSink
|
struct CopySink : Sink
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
virtual void operator () (const unsigned char * data, unsigned int len)
|
virtual void operator () (const unsigned char * data, unsigned int len)
|
||||||
|
@ -183,7 +183,7 @@ struct CopySink : DumpSink
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CopySource : RestoreSource
|
struct CopySource : Source
|
||||||
{
|
{
|
||||||
string & s;
|
string & s;
|
||||||
unsigned int pos;
|
unsigned int pos;
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
pkglib_LTLIBRARIES = libutil.la
|
pkglib_LTLIBRARIES = libutil.la
|
||||||
|
|
||||||
libutil_la_SOURCES = util.cc hash.cc archive.cc aterm.cc aterm-map.cc xml-writer.cc
|
libutil_la_SOURCES = util.cc hash.cc serialise.cc \
|
||||||
|
archive.cc aterm.cc aterm-map.cc xml-writer.cc
|
||||||
|
|
||||||
libutil_la_LIBADD = ../boost/format/libformat.la
|
libutil_la_LIBADD = ../boost/format/libformat.la
|
||||||
|
|
||||||
pkginclude_HEADERS = util.hh hash.hh archive.hh aterm.hh aterm-map.hh xml-writer.hh types.hh
|
pkginclude_HEADERS = util.hh hash.hh serialise.hh \
|
||||||
|
archive.hh aterm.hh aterm-map.hh xml-writer.hh types.hh
|
||||||
|
|
||||||
if !HAVE_OPENSSL
|
if !HAVE_OPENSSL
|
||||||
libutil_la_SOURCES += \
|
libutil_la_SOURCES += \
|
||||||
|
|
|
@ -18,41 +18,10 @@ namespace nix {
|
||||||
static string archiveVersion1 = "nix-archive-1";
|
static string archiveVersion1 = "nix-archive-1";
|
||||||
|
|
||||||
|
|
||||||
static void writePadding(unsigned int len, DumpSink & sink)
|
static void dump(const string & path, Sink & sink);
|
||||||
{
|
|
||||||
if (len % 8) {
|
|
||||||
unsigned char zero[8];
|
|
||||||
memset(zero, 0, sizeof(zero));
|
|
||||||
sink(zero, 8 - (len % 8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void writeInt(unsigned int n, DumpSink & sink)
|
static void dumpEntries(const Path & path, Sink & sink)
|
||||||
{
|
|
||||||
unsigned char buf[8];
|
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
buf[0] = n & 0xff;
|
|
||||||
buf[1] = (n >> 8) & 0xff;
|
|
||||||
buf[2] = (n >> 16) & 0xff;
|
|
||||||
buf[3] = (n >> 24) & 0xff;
|
|
||||||
sink(buf, sizeof(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void writeString(const string & s, DumpSink & sink)
|
|
||||||
{
|
|
||||||
unsigned int len = s.length();
|
|
||||||
writeInt(len, sink);
|
|
||||||
sink((const unsigned char *) s.c_str(), len);
|
|
||||||
writePadding(len, sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void dump(const string & path, DumpSink & sink);
|
|
||||||
|
|
||||||
|
|
||||||
static void dumpEntries(const Path & path, DumpSink & sink)
|
|
||||||
{
|
{
|
||||||
Strings names = readDirectory(path);
|
Strings names = readDirectory(path);
|
||||||
vector<string> names2(names.begin(), names.end());
|
vector<string> names2(names.begin(), names.end());
|
||||||
|
@ -73,7 +42,7 @@ static void dumpEntries(const Path & path, DumpSink & sink)
|
||||||
|
|
||||||
|
|
||||||
static void dumpContents(const Path & path, unsigned int size,
|
static void dumpContents(const Path & path, unsigned int size,
|
||||||
DumpSink & sink)
|
Sink & sink)
|
||||||
{
|
{
|
||||||
writeString("contents", sink);
|
writeString("contents", sink);
|
||||||
writeInt(size, sink);
|
writeInt(size, sink);
|
||||||
|
@ -95,7 +64,7 @@ static void dumpContents(const Path & path, unsigned int size,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dump(const Path & path, DumpSink & sink)
|
static void dump(const Path & path, Sink & sink)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
|
@ -132,7 +101,7 @@ static void dump(const Path & path, DumpSink & sink)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dumpPath(const Path & path, DumpSink & sink)
|
void dumpPath(const Path & path, Sink & sink)
|
||||||
{
|
{
|
||||||
writeString(archiveVersion1, sink);
|
writeString(archiveVersion1, sink);
|
||||||
dump(path, sink);
|
dump(path, sink);
|
||||||
|
@ -145,42 +114,7 @@ static Error badArchive(string s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void readPadding(unsigned int len, RestoreSource & source)
|
static void skipGeneric(Source & source)
|
||||||
{
|
|
||||||
if (len % 8) {
|
|
||||||
unsigned char zero[8];
|
|
||||||
unsigned int n = 8 - (len % 8);
|
|
||||||
source(zero, n);
|
|
||||||
for (unsigned int i = 0; i < n; i++)
|
|
||||||
if (zero[i]) throw badArchive("non-zero padding");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int readInt(RestoreSource & source)
|
|
||||||
{
|
|
||||||
unsigned char buf[8];
|
|
||||||
source(buf, sizeof(buf));
|
|
||||||
if (buf[4] || buf[5] || buf[6] || buf[7])
|
|
||||||
throw Error("implementation cannot deal with > 32-bit integers");
|
|
||||||
return
|
|
||||||
buf[0] |
|
|
||||||
(buf[1] << 8) |
|
|
||||||
(buf[2] << 16) |
|
|
||||||
(buf[3] << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static string readString(RestoreSource & source)
|
|
||||||
{
|
|
||||||
unsigned int len = readInt(source);
|
|
||||||
char buf[len];
|
|
||||||
source((unsigned char *) buf, len);
|
|
||||||
readPadding(len, source);
|
|
||||||
return string(buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void skipGeneric(RestoreSource & source)
|
|
||||||
{
|
{
|
||||||
if (readString(source) == "(") {
|
if (readString(source) == "(") {
|
||||||
while (readString(source) != ")")
|
while (readString(source) != ")")
|
||||||
|
@ -189,10 +123,10 @@ static void skipGeneric(RestoreSource & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void restore(const Path & path, RestoreSource & source);
|
static void restore(const Path & path, Source & source);
|
||||||
|
|
||||||
|
|
||||||
static void restoreEntry(const Path & path, RestoreSource & source)
|
static void restoreEntry(const Path & path, Source & source)
|
||||||
{
|
{
|
||||||
string s, name;
|
string s, name;
|
||||||
|
|
||||||
|
@ -219,7 +153,7 @@ static void restoreEntry(const Path & path, RestoreSource & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void restoreContents(int fd, const Path & path, RestoreSource & source)
|
static void restoreContents(int fd, const Path & path, Source & source)
|
||||||
{
|
{
|
||||||
unsigned int size = readInt(source);
|
unsigned int size = readInt(source);
|
||||||
unsigned int left = size;
|
unsigned int left = size;
|
||||||
|
@ -238,7 +172,7 @@ static void restoreContents(int fd, const Path & path, RestoreSource & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void restore(const Path & path, RestoreSource & source)
|
static void restore(const Path & path, Source & source)
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
|
|
||||||
|
@ -315,7 +249,7 @@ static void restore(const Path & path, RestoreSource & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void restorePath(const Path & path, RestoreSource & source)
|
void restorePath(const Path & path, Source & source)
|
||||||
{
|
{
|
||||||
if (readString(source) != archiveVersion1)
|
if (readString(source) != archiveVersion1)
|
||||||
throw badArchive("expected Nix archive");
|
throw badArchive("expected Nix archive");
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __ARCHIVE_H
|
#define __ARCHIVE_H
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
#include "serialise.hh"
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -44,27 +45,9 @@ namespace nix {
|
||||||
|
|
||||||
`+' denotes string concatenation. */
|
`+' denotes string concatenation. */
|
||||||
|
|
||||||
struct DumpSink
|
void dumpPath(const Path & path, Sink & sink);
|
||||||
{
|
|
||||||
virtual ~DumpSink() { }
|
|
||||||
virtual void operator () (const unsigned char * data, unsigned int len) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void dumpPath(const Path & path, DumpSink & sink);
|
void restorePath(const Path & path, Source & source);
|
||||||
|
|
||||||
|
|
||||||
struct RestoreSource
|
|
||||||
{
|
|
||||||
virtual ~RestoreSource() { }
|
|
||||||
|
|
||||||
/* The callee should store exactly *len bytes in the buffer
|
|
||||||
pointed to by data. It should block if that much data is not
|
|
||||||
yet available, or throw an error if it is not going to be
|
|
||||||
available. */
|
|
||||||
virtual void operator () (unsigned char * data, unsigned int len) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void restorePath(const Path & path, RestoreSource & source);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,7 @@ Hash hashFile(HashType ht, const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct HashSink : DumpSink
|
struct HashSink : Sink
|
||||||
{
|
{
|
||||||
HashType ht;
|
HashType ht;
|
||||||
Ctx ctx;
|
Ctx ctx;
|
||||||
|
|
87
src/libutil/serialise.cc
Normal file
87
src/libutil/serialise.cc
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#include "serialise.hh"
|
||||||
|
#include "util.hh"
|
||||||
|
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
void FdSink::operator () (const unsigned char * data, unsigned int len)
|
||||||
|
{
|
||||||
|
writeFull(fd, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FdSource::operator () (unsigned char * data, unsigned int len)
|
||||||
|
{
|
||||||
|
readFull(fd, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writePadding(unsigned int len, Sink & sink)
|
||||||
|
{
|
||||||
|
if (len % 8) {
|
||||||
|
unsigned char zero[8];
|
||||||
|
memset(zero, 0, sizeof(zero));
|
||||||
|
sink(zero, 8 - (len % 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeInt(unsigned int n, Sink & sink)
|
||||||
|
{
|
||||||
|
unsigned char buf[8];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
buf[0] = n & 0xff;
|
||||||
|
buf[1] = (n >> 8) & 0xff;
|
||||||
|
buf[2] = (n >> 16) & 0xff;
|
||||||
|
buf[3] = (n >> 24) & 0xff;
|
||||||
|
sink(buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeString(const string & s, Sink & sink)
|
||||||
|
{
|
||||||
|
unsigned int len = s.length();
|
||||||
|
writeInt(len, sink);
|
||||||
|
sink((const unsigned char *) s.c_str(), len);
|
||||||
|
writePadding(len, sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void readPadding(unsigned int len, Source & source)
|
||||||
|
{
|
||||||
|
if (len % 8) {
|
||||||
|
unsigned char zero[8];
|
||||||
|
unsigned int n = 8 - (len % 8);
|
||||||
|
source(zero, n);
|
||||||
|
for (unsigned int i = 0; i < n; i++)
|
||||||
|
if (zero[i]) throw Error("non-zero padding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int readInt(Source & source)
|
||||||
|
{
|
||||||
|
unsigned char buf[8];
|
||||||
|
source(buf, sizeof(buf));
|
||||||
|
if (buf[4] || buf[5] || buf[6] || buf[7])
|
||||||
|
throw Error("implementation cannot deal with > 32-bit integers");
|
||||||
|
return
|
||||||
|
buf[0] |
|
||||||
|
(buf[1] << 8) |
|
||||||
|
(buf[2] << 16) |
|
||||||
|
(buf[3] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string readString(Source & source)
|
||||||
|
{
|
||||||
|
unsigned int len = readInt(source);
|
||||||
|
char buf[len];
|
||||||
|
source((unsigned char *) buf, len);
|
||||||
|
readPadding(len, source);
|
||||||
|
return string(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
71
src/libutil/serialise.hh
Normal file
71
src/libutil/serialise.hh
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#ifndef __SERIALISE_H
|
||||||
|
#define __SERIALISE_H
|
||||||
|
|
||||||
|
#include "types.hh"
|
||||||
|
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
/* Abstract destination of binary data. */
|
||||||
|
struct Sink
|
||||||
|
{
|
||||||
|
virtual ~Sink() { }
|
||||||
|
virtual void operator () (const unsigned char * data, unsigned int len) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Abstract source of binary data. */
|
||||||
|
struct Source
|
||||||
|
{
|
||||||
|
virtual ~Source() { }
|
||||||
|
|
||||||
|
/* The callee should store exactly *len bytes in the buffer
|
||||||
|
pointed to by data. It should block if that much data is not
|
||||||
|
yet available, or throw an error if it is not going to be
|
||||||
|
available. */
|
||||||
|
virtual void operator () (unsigned char * data, unsigned int len) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* A sink that writes data to a file descriptor. */
|
||||||
|
struct FdSink : Sink
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
FdSink(int fd)
|
||||||
|
{
|
||||||
|
this->fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () (const unsigned char * data, unsigned int len);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* A source that reads data from a file descriptor. */
|
||||||
|
struct FdSource : Source
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
FdSource(int fd)
|
||||||
|
{
|
||||||
|
this->fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator () (unsigned char * data, unsigned int len);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void writePadding(unsigned int len, Sink & sink);
|
||||||
|
void writeInt(unsigned int n, Sink & sink);
|
||||||
|
void writeString(const string & s, Sink & sink);
|
||||||
|
|
||||||
|
void readPadding(unsigned int len, Source & source);
|
||||||
|
unsigned int readInt(Source & source);
|
||||||
|
string readString(Source & source);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__SERIALISE_H */
|
|
@ -607,17 +607,6 @@ static void opDelete(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A sink that writes dump output to stdout. */
|
|
||||||
struct StdoutSink : DumpSink
|
|
||||||
{
|
|
||||||
virtual void operator ()
|
|
||||||
(const unsigned char * data, unsigned int len)
|
|
||||||
{
|
|
||||||
writeFull(STDOUT_FILENO, data, len);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Dump a path as a Nix archive. The archive is written to standard
|
/* Dump a path as a Nix archive. The archive is written to standard
|
||||||
output. */
|
output. */
|
||||||
static void opDump(Strings opFlags, Strings opArgs)
|
static void opDump(Strings opFlags, Strings opArgs)
|
||||||
|
@ -625,22 +614,12 @@ static void opDump(Strings opFlags, Strings opArgs)
|
||||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||||
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
|
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
|
||||||
|
|
||||||
StdoutSink sink;
|
FdSink sink(STDOUT_FILENO);
|
||||||
string path = *opArgs.begin();
|
string path = *opArgs.begin();
|
||||||
dumpPath(path, sink);
|
dumpPath(path, sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A source that reads restore input from stdin. */
|
|
||||||
struct StdinSource : RestoreSource
|
|
||||||
{
|
|
||||||
virtual void operator () (unsigned char * data, unsigned int len)
|
|
||||||
{
|
|
||||||
readFull(STDIN_FILENO, data, len);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Restore a value from a Nix archive. The archive is read from
|
/* Restore a value from a Nix archive. The archive is read from
|
||||||
standard input. */
|
standard input. */
|
||||||
static void opRestore(Strings opFlags, Strings opArgs)
|
static void opRestore(Strings opFlags, Strings opArgs)
|
||||||
|
@ -648,7 +627,7 @@ static void opRestore(Strings opFlags, Strings opArgs)
|
||||||
if (!opFlags.empty()) throw UsageError("unknown flag");
|
if (!opFlags.empty()) throw UsageError("unknown flag");
|
||||||
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
|
if (opArgs.size() != 1) throw UsageError("only one argument allowed");
|
||||||
|
|
||||||
StdinSource source;
|
FdSource source(STDIN_FILENO);
|
||||||
restorePath(*opArgs.begin(), source);
|
restorePath(*opArgs.begin(), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
9
src/nix-worker/Makefile.am
Normal file
9
src/nix-worker/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
libexec_PROGRAMS = nix-worker
|
||||||
|
|
||||||
|
nix_worker_SOURCES = main.cc
|
||||||
|
nix_worker_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \
|
||||||
|
../boost/format/libformat.la ${bdb_lib} ${aterm_lib}
|
||||||
|
|
||||||
|
AM_CXXFLAGS = \
|
||||||
|
-I$(srcdir)/.. ${bdb_include} $(aterm_include) -I$(srcdir)/../libutil \
|
||||||
|
-I$(srcdir)/../libstore -I$(srcdir)/../libmain
|
63
src/nix-worker/main.cc
Normal file
63
src/nix-worker/main.cc
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "shared.hh"
|
||||||
|
#include "local-store.hh"
|
||||||
|
#include "util.hh"
|
||||||
|
|
||||||
|
using namespace nix;
|
||||||
|
|
||||||
|
|
||||||
|
/* !!! Mostly cut&pasted from util/archive.hh */
|
||||||
|
/* Use buffered reads. */
|
||||||
|
static unsigned int readInt(int fd)
|
||||||
|
{
|
||||||
|
unsigned char buf[8];
|
||||||
|
readFull(fd, buf, sizeof(buf));
|
||||||
|
if (buf[4] || buf[5] || buf[6] || buf[7])
|
||||||
|
throw Error("implementation cannot deal with > 32-bit integers");
|
||||||
|
return
|
||||||
|
buf[0] |
|
||||||
|
(buf[1] << 8) |
|
||||||
|
(buf[2] << 16) |
|
||||||
|
(buf[3] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void processConnection(int fdFrom, int fdTo)
|
||||||
|
{
|
||||||
|
store = openStore();
|
||||||
|
|
||||||
|
unsigned int magic = readInt(fdFrom);
|
||||||
|
if (magic != 0x6e697864) throw Error("protocol mismatch");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void run(Strings args)
|
||||||
|
{
|
||||||
|
bool slave = false;
|
||||||
|
bool daemon = false;
|
||||||
|
|
||||||
|
for (Strings::iterator i = args.begin(); i != args.end(); ) {
|
||||||
|
string arg = *i++;
|
||||||
|
if (arg == "--slave") slave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slave)
|
||||||
|
processConnection(STDIN_FILENO, STDOUT_FILENO);
|
||||||
|
|
||||||
|
else if (daemon)
|
||||||
|
throw Error("daemon mode not implemented");
|
||||||
|
|
||||||
|
else
|
||||||
|
throw Error("must be run in either --slave or --daemon mode");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printHelp()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string programId = "nix-store";
|
Loading…
Reference in a new issue