diff -Nudrp djbdns-1.05_sighup/CHANGES djbdns-1.05_dumpcache/CHANGES
--- djbdns-1.05_sighup/CHANGES	2005-10-20 17:11:52.000000000 -0300
+++ djbdns-1.05_dumpcache/CHANGES	2005-10-20 17:10:55.000000000 -0300
@@ -380,3 +374,5 @@
 	ui: servers print starting message.
 	internal: some respond() declarations.
 	version: djbdns 1.05.
+20010313
+	patch: to dump and reload the cache
diff -Nudrp djbdns-1.05_sighup/Makefile djbdns-1.05_dumpcache/Makefile
--- djbdns-1.05_sighup/Makefile	2005-10-20 17:11:52.000000000 -0300
+++ djbdns-1.05_dumpcache/Makefile	2005-10-20 17:10:55.000000000 -0300
@@ -151,13 +151,13 @@
 
 cache.o: \
 compile cache.c alloc.h byte.h uint32.h exit.h tai.h uint64.h cache.h \
-uint32.h uint64.h
+uint32.h uint64.h env.h error.h open.h openreadclose.h
 	./compile cache.c
 
 cachetest: \
-load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a
-	./load cachetest cache.o libtai.a buffer.a alloc.a unix.a \
-	byte.a 
+load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a env.a
+	./load cachetest cache.o libtai.a buffer.a unix.a env.a \
+	alloc.a byte.a
 
 cachetest.o: \
 compile cachetest.c buffer.h exit.h cache.h uint32.h uint64.h str.h
diff -Nudrp djbdns-1.05_sighup/README djbdns-1.05_dumpcache/README
--- djbdns-1.05_sighup/README	2001-02-11 18:11:45.000000000 -0300
+++ djbdns-1.05_dumpcache/README	2005-10-20 17:10:55.000000000 -0300
@@ -1,3 +1,9 @@
+patchlevel fg1
+20010313
+by Florent Guillaume <florent.guillaume@mail.com>
+patch home page: http://efge.free.fr/djbdns/
+Uses parts of Felix von Leitner's djb-0.5.2 package: http://www.fefe.de/djb/
+
 djbdns 1.05
 20010211
 Copyright 2001
diff -Nudrp djbdns-1.05_sighup/VERSION djbdns-1.05_dumpcache/VERSION
--- djbdns-1.05_sighup/VERSION	2005-10-20 17:11:52.000000000 -0300
+++ djbdns-1.05_dumpcache/VERSION	2005-10-20 17:10:55.000000000 -0300
@@ -1 +1 @@
-djbdns 1.05-ma1
+djbdns 1.05-fg1
diff -Nudrp djbdns-1.05_sighup/cache.c djbdns-1.05_dumpcache/cache.c
--- djbdns-1.05_sighup/cache.c	2001-02-11 18:11:45.000000000 -0300
+++ djbdns-1.05_dumpcache/cache.c	2005-10-20 17:10:55.000000000 -0300
@@ -1,3 +1,11 @@
+#ifdef DUMPCACHE
+#include <stdio.h>
+#include <unistd.h>
+#include "env.h"
+#include "error.h"
+#include "open.h"
+#include "openreadclose.h"
+#endif
 #include "alloc.h"
 #include "byte.h"
 #include "uint32.h"
@@ -205,3 +213,97 @@ int cache_init(unsigned int cachesize)
 
   return 1;
 }
+
+#ifdef DUMPCACHE
+static int fd;
+
+static int cache_writeline(const char *buf, unsigned int len)
+{
+  int w;
+
+  while (len) {
+    w = write(fd,buf,len);
+    if (w == -1) {
+      if (errno == error_intr) continue;
+      close(fd);
+      return -1;
+    }
+    buf += w;
+    len -= w;
+  }
+  return 0;
+}
+
+int cache_dump(void)
+{
+  static char *fn;
+  static char *fntmp;
+  uint32 pos;
+  unsigned int len;
+
+  fn = env_get("DUMPCACHE");
+  if (!fn) return 999;
+  fntmp = env_get("DUMPCACHETMP");
+  if (!fntmp) return 999;
+  fd = open_trunc(fntmp);
+  if (fd == -1) return -1;
+
+  pos = oldest;
+  while (pos < unused) {
+    len = get4(pos + 4) + get4(pos + 8) + 16;
+    if (cache_writeline(x + pos + 4, len)) return -1;
+    pos += 4 + len;
+  }
+  pos = hsize;
+  while (pos < writer) {
+    len = get4(pos + 4) + get4(pos + 8) + 16;
+    if (cache_writeline(x + pos + 4, len)) return -1;
+    pos += 4 + len;
+  }
+
+  if (fsync(fd) == -1) return -1;
+  if (close(fd) == -1) return -1;
+  if (rename(fntmp,fn) == -1) return -1;
+  return 0;
+}
+
+int cache_slurp(const char *fn)
+{
+  static stralloc buf = {0};
+  char *p;
+  uint32 pos;
+  unsigned int len;
+  uint32 keylen;
+  uint32 datalen;
+  struct tai now;
+  struct tai expire;
+  int nb;
+
+  if (openreadclose(fn,&buf,16384) != 1) goto DIE;
+  tai_now(&now);
+  p = buf.s;
+  pos = 0;
+  len = buf.len;
+  nb = 0;
+  while (pos + 16 <= len) {
+    uint32_unpack(p + pos, &keylen);
+    uint32_unpack(p + pos + 4, &datalen);
+    tai_unpack(p + pos + 8, &expire);
+    pos += 16;
+    if (pos + keylen + datalen > len) break; /* missing data */
+    if (!tai_less(&expire,&now)) {
+      tai_sub(&expire,&expire,&now);
+      cache_set(p + pos, keylen, p + pos + keylen, datalen, (unsigned int)expire.x);
+    }
+    pos += keylen + datalen;
+    nb++;
+  }
+  alloc_free(buf.s); buf.s = 0;
+  return nb;
+
+ DIE:
+  alloc_free(buf.s); buf.s = 0;
+  if (errno == error_noent) return 0;
+  return -1;
+}
+#endif
diff -Nudrp djbdns-1.05_sighup/cache.h djbdns-1.05_dumpcache/cache.h
--- djbdns-1.05_sighup/cache.h	2001-02-11 18:11:45.000000000 -0300
+++ djbdns-1.05_dumpcache/cache.h	2005-10-20 17:10:55.000000000 -0300
@@ -8,5 +8,9 @@ extern uint64 cache_motion;
 extern int cache_init(unsigned int);
 extern void cache_set(const char *,unsigned int,const char *,unsigned int,uint32);
 extern char *cache_get(const char *,unsigned int,unsigned int *,uint32 *);
+#ifdef DUMPCACHE
+extern int cache_dump(void);
+extern int cache_slurp(const char *);
+#endif
 
 #endif
diff -Nudrp djbdns-1.05_sighup/conf-cc djbdns-1.05_dumpcache/conf-cc
--- djbdns-1.05_sighup/conf-cc	2001-02-11 18:11:45.000000000 -0300
+++ djbdns-1.05_dumpcache/conf-cc	2005-10-20 17:10:55.000000000 -0300
@@ -1,3 +1,3 @@
-gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings
+gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings -DDUMPCACHE
 
 This will be used to compile .c files.
diff -Nudrp djbdns-1.05_sighup/dnscache-conf.c djbdns-1.05_dumpcache/dnscache-conf.c
--- djbdns-1.05_sighup/dnscache-conf.c	2001-02-11 18:11:45.000000000 -0300
+++ djbdns-1.05_dumpcache/dnscache-conf.c	2005-10-20 17:10:55.000000000 -0300
@@ -32,6 +32,10 @@ char *dir;
 char *user;
 char *loguser;
 struct passwd *pw;
+#ifdef DUMPCACHE
+int useruid;
+int usergid;
+#endif
 const char *myip;
 
 uint32 seed[32];
@@ -81,6 +85,14 @@ int main(int argc,char **argv)
   myip = argv[4];
   if (!myip) myip = "127.0.0.1";
 
+#ifdef DUMPCACHE
+  pw = getpwnam(user);
+  seed_addtime();
+  if (!pw)
+    strerr_die3x(111,FATAL,"unknown account ",user);
+  useruid = pw->pw_uid;
+  usergid = pw->pw_gid;
+#endif
   pw = getpwnam(loguser);
   seed_addtime();
   if (!pw)
@@ -120,6 +132,14 @@ int main(int argc,char **argv)
   seed_addtime(); perm(0644);
   seed_addtime(); start("env/DATALIMIT"); outs("3000000\n"); finish();
   seed_addtime(); perm(0644);
+#ifdef DUMPCACHE
+  seed_addtime(); start("env/SLURPCACHE"); outs("dump/slurpcache\n"); finish();
+  seed_addtime(); perm(0644);
+  seed_addtime(); start("env/DUMPCACHE"); outs("dump/dumpcache\n"); finish();
+  seed_addtime(); perm(0644);
+  seed_addtime(); start("env/DUMPCACHETMP"); outs("dump/dumpcache.tmp\n"); finish();
+  seed_addtime(); perm(0644);
+#endif
   seed_addtime(); start("run");
   outs("#!/bin/sh\nexec 2>&1\nexec <seed\nexec envdir ./env sh -c '\n  exec envuidgid "); outs(user);
   outs(" softlimit -o250 -d \"$DATALIMIT\" ");
@@ -131,6 +151,11 @@ int main(int argc,char **argv)
   seed_addtime(); perm(0755);
   seed_addtime(); makedir("root");
   seed_addtime(); perm(02755);
+#ifdef DUMPCACHE
+  seed_addtime(); makedir("root/dump");
+  seed_addtime(); owner(useruid,usergid);
+  seed_addtime(); perm(02755);
+#endif
   seed_addtime(); makedir("root/ip");
   seed_addtime(); perm(02755);
   seed_addtime(); start("root/ip/127.0.0.1"); finish();
diff -Nudrp djbdns-1.05_sighup/dnscache.c djbdns-1.05_dumpcache/dnscache.c
--- djbdns-1.05_sighup/dnscache.c	2005-10-20 17:11:52.000000000 -0300
+++ djbdns-1.05_dumpcache/dnscache.c	2005-10-20 17:10:55.000000000 -0300
@@ -22,7 +22,9 @@
 #include "log.h"
 #include "okclient.h"
 #include "droproot.h"
+#ifdef DUMPCACHE
 #include "sig.h"
+#endif
 
 static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2])
 {
@@ -383,15 +385,18 @@ static void doit(void)
   }
 }
   
-#define FATAL "dnscache: fatal: "
-
-void hup_me()
+#ifdef DUMPCACHE
+static void do_dump(void)
 {
-  if (!roots_init())
-    strerr_die2sys(111,FATAL,"unable to read servers: ");
-
-  log_reread();
+  int r;
+  r = cache_dump();
+  if (r < 0)
+    r = errno;
+  log_dump(r);
 }
+#endif
+
+#define FATAL "dnscache: fatal: "
 
 char seed[128];
 
@@ -439,6 +444,16 @@ int main()
   scan_ulong(x,&cachesize);
   if (!cache_init(cachesize))
     strerr_die3x(111,FATAL,"not enough memory for cache of size ",x);
+#ifdef DUMPCACHE
+  x = env_get("SLURPCACHE");
+  if (x) {
+    int nb = cache_slurp(x);
+    if (nb < 0)
+      strerr_die4sys(111,FATAL,"unable to slurp cache ",x," : ");
+    else
+      log_slurp(nb);
+  }
+#endif
 
   if (env_get("HIDETTL"))
     response_hidettl();
@@ -451,7 +466,9 @@ int main()
   if (socket_listen(tcp53,20) == -1)
     strerr_die2sys(111,FATAL,"unable to listen on TCP socket: ");
 
-  sig_catch(sig_hangup, hup_me);
+#ifdef DUMPCACHE
+  sig_catch(sig_alarm,do_dump);
+#endif
 
   log_startup();
   doit();
diff -Nudrp djbdns-1.05_sighup/log.c djbdns-1.05_dumpcache/log.c
--- djbdns-1.05_sighup/log.c	2005-10-20 17:11:52.000000000 -0300
+++ djbdns-1.05_dumpcache/log.c	2005-10-20 17:10:55.000000000 -0300
@@ -88,17 +88,25 @@ static void name(const char *q)
   }
 }
 
-void log_reread(void)
+void log_startup(void)
 {
-  string("rereading servers configuration");
+  string("starting");
   line();
 }
 
-void log_startup(void)
+#ifdef DUMPCACHE
+void log_slurp(int nb)
 {
-  string("starting");
+  string("slurp "); number(nb);
+  line();
+}
+
+void log_dump(int err)
+{
+  string("dump err "); number(err);
   line();
 }
+#endif
 
 void log_query(uint64 *qnum,const char client[4],unsigned int port,const char id[2],const char *q,const char qtype[2])
 {
diff -Nudrp djbdns-1.05_sighup/log.h djbdns-1.05_dumpcache/log.h
--- djbdns-1.05_sighup/log.h	2001-02-11 18:11:45.000000000 -0300
+++ djbdns-1.05_dumpcache/log.h	2005-10-20 17:10:55.000000000 -0300
@@ -4,6 +4,10 @@
 #include "uint64.h"
 
 extern void log_startup(void);
+#ifdef DUMPCACHE
+extern void log_slurp(int);
+extern void log_dump(int);
+#endif
 
 extern void log_query(uint64 *,const char *,unsigned int,const char *,const char *,const char *);
 extern void log_querydrop(uint64 *);
