summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/libstore/local-store.cc4
-rw-r--r--src/libutil/Makefile.am6
-rw-r--r--src/libutil/archive.cc88
-rw-r--r--src/libutil/archive.hh23
-rw-r--r--src/libutil/hash.cc2
-rw-r--r--src/libutil/serialise.cc87
-rw-r--r--src/libutil/serialise.hh71
-rw-r--r--src/nix-store/main.cc25
-rw-r--r--src/nix-worker/Makefile.am9
-rw-r--r--src/nix-worker/main.cc63
12 files changed, 255 insertions, 126 deletions
diff --git a/configure.ac b/configure.ac
index b5c0e61b59..8267cc83ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -266,6 +266,7 @@ AC_CONFIG_FILES([Makefile
    src/libexpr/Makefile
    src/nix-instantiate/Makefile
    src/nix-env/Makefile
+   src/nix-worker/Makefile
    src/nix-log2xml/Makefile
    src/bsdiff-4.3/Makefile
    scripts/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 2bf789fd3b..601e0726b9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
 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
 
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 2ae4437623..aa8166d7ee 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -173,7 +173,7 @@ void createStoreTransaction(Transaction & txn)
 
 /* Path copying. */
 
-struct CopySink : DumpSink
+struct CopySink : Sink
 {
     string s;
     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;
     unsigned int pos;
diff --git a/src/libutil/Makefile.am b/src/libutil/Makefile.am
index cf75be8a85..bd09965433 100644
--- a/src/libutil/Makefile.am
+++ b/src/libutil/Makefile.am
@@ -1,10 +1,12 @@
 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
 
-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
 libutil_la_SOURCES += \
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index 32c75fee5d..e3bd63db0b 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -18,41 +18,10 @@ namespace nix {
 static string archiveVersion1 = "nix-archive-1";
 
 
-static void writePadding(unsigned int len, DumpSink & 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)
-{
-    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 dump(const string & path, Sink & sink);
 
 
-static void dumpEntries(const Path & path, DumpSink & sink)
+static void dumpEntries(const Path & path, Sink & sink)
 {
     Strings names = readDirectory(path);
     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, 
-    DumpSink & sink)
+    Sink & sink)
 {
     writeString("contents", 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;
     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);
     dump(path, sink);
@@ -145,42 +114,7 @@ static Error badArchive(string s)
 }
 
 
-static void readPadding(unsigned int len, RestoreSource & 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)
+static void skipGeneric(Source & source)
 {
     if (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;
 
@@ -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 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;
 
@@ -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)
         throw badArchive("expected Nix archive");
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index f85d589c6b..c70ef3f1c8 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -2,6 +2,7 @@
 #define __ARCHIVE_H
 
 #include "types.hh"
+#include "serialise.hh"
 
 
 namespace nix {
@@ -44,27 +45,9 @@ namespace nix {
 
      `+' denotes string concatenation. */
 
-struct DumpSink 
-{
-    virtual ~DumpSink() { }
-    virtual void operator () (const unsigned char * data, unsigned int len) = 0;
-};
+void dumpPath(const Path & path, Sink & sink);
 
-void dumpPath(const Path & path, DumpSink & sink);
-
-
-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);
+void restorePath(const Path & path, Source & source);
 
  
 }
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 7381948f21..8dc33f5d0c 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -282,7 +282,7 @@ Hash hashFile(HashType ht, const Path & path)
 }
 
 
-struct HashSink : DumpSink
+struct HashSink : Sink
 {
     HashType ht;
     Ctx ctx;
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
new file mode 100644
index 0000000000..aa11c590af
--- /dev/null
+++ b/src/libutil/serialise.cc
@@ -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);
+}
+
+ 
+}
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
new file mode 100644
index 0000000000..459a693ee8
--- /dev/null
+++ b/src/libutil/serialise.hh
@@ -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 */
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index f31814881f..c3755c2a1e 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -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
    output. */
 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 (opArgs.size() != 1) throw UsageError("only one argument allowed");
 
-    StdoutSink sink;
+    FdSink sink(STDOUT_FILENO);
     string path = *opArgs.begin();
     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
    standard input. */
 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 (opArgs.size() != 1) throw UsageError("only one argument allowed");
 
-    StdinSource source;
+    FdSource source(STDIN_FILENO);
     restorePath(*opArgs.begin(), source);
 }
 
diff --git a/src/nix-worker/Makefile.am b/src/nix-worker/Makefile.am
new file mode 100644
index 0000000000..6f10efff5d
--- /dev/null
+++ b/src/nix-worker/Makefile.am
@@ -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
diff --git a/src/nix-worker/main.cc b/src/nix-worker/main.cc
new file mode 100644
index 0000000000..4fe92a85ad
--- /dev/null
+++ b/src/nix-worker/main.cc
@@ -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";