diff --git a/src/Makefile.in b/src/Makefile.in
index 0ad2d9c259ea107337be4effcbb74f5b47d6e978..e65643b8684213cde6ce7f7b72a07bdbde9630e1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -182,9 +182,8 @@ install:
 	  if [ -f "$(exec_prefix)/pike" ]; then \
 	    echo Renaming old "$(exec_prefix)/pike" to "$(exec_prefix)/pike.old"; \
 	    mv -f "$(exec_prefix)/pike" "$(exec_prefix)/pike.old"; \
-	  else \
-	    echo "$(exec_prefix)/pike"; $(INSTALL) ./pike $(exec_prefix) ; \
-	  fi ; \
+	  else : fi ; \
+          echo "$(exec_prefix)/pike"; $(INSTALL) ./pike $(exec_prefix) ; \
 	fi
 	@if [ -f $(SRCDIR)/../bin/hilfe ]; then \
 	  echo ; echo "Installing $(exec_prefix)/hilfe..."; \
@@ -193,10 +192,10 @@ install:
 	    if [ -f $(exec_prefix)/hilfe ]; then \
 	      mv $(exec_prefix)/hilfe $(exec_prefix)/hilfe.old; \
 	    else : ; fi && \
-	    sed -e 's!/usr/local/bin!$(exec_prefix)!' <$(SRCDIR)/../bin/hilfe \
-	      >$(exec_prefix)/hilfe || exit 1\
+	    ( sed -e 's!/usr/local/bin!$(exec_prefix)!' <$(TMP_BINDIR)/hilfe \
+	      >./hilfe && chmod 755 ./hilfe && $(INSTALL) ./hilfe $(exec_prefix) || exit 1\
 	  else \
-	    $(INSTALL) $(SRCDIR)/../bin/hilfe $(exec_prefix) || exit 1; \
+	    $(INSTALL) $(TMP_BINDIR)/hilfe $(exec_prefix) || exit 1; \
 	  fi; \
 	  chmod a+rx $(exec_prefix)/hilfe; \
 	  chmod u+w $(exec_prefix)/hilfe; \
diff --git a/src/configure.in b/src/configure.in
index ff9b016154bb2dab5626088c3840c273a434b449..d07d64e4a0f635bb3bee20ac2f75ec133d899fa9 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.157 1998/02/05 02:57:37 hubbe Exp $")
+AC_REVISION("$Id: configure.in,v 1.158 1998/02/11 00:04:58 hubbe Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -639,9 +639,9 @@ AC_HEADER_STDC
 AC_CHECK_HEADERS(sys/rusage.h time.h sys/time.h sys/types.h unistd.h stdlib.h \
 memory.h values.h string.h strings.h fcntl.h sys/filio.h sys/sockio.h crypt.h \
 locale.h sys/resource.h sys/select.h sys/mman.h setjmp.h limits.h pthread.h \
-thread.h dlfcn.h dld.h sys/times.h sched.h sys/procfs.h sys/param.h winsock2.h \
+thread.h dlfcn.h dld.h sys/times.h sched.h sys/procfs.h sys/param.h winsock.h \
 sys/ioct.h sys/socket.h malloc.h netinet/in.h sys/wait.h winbase.h grp.h pwd.h \
-passwd.h group.h)
+passwd.h group.h winsock2.h)
 
 AC_CHECK_SIZEOF(char *,4)
 AC_CHECK_SIZEOF(long,4)
@@ -1141,10 +1141,10 @@ define(MY_CHECK_HEADERS,
 
 MY_CHECK_HEADERS(strchr,string.h unistd.h stdlib.h)
 MY_CHECK_HEADERS(malloc,memory.h unistd.h stdlib.h)
-MY_CHECK_HEADERS(getpeername,sys/socket.h sys/socketvar.h sys/socketio.h winsock2.h)
+MY_CHECK_HEADERS(getpeername,sys/socket.h sys/socketvar.h sys/socketio.h winsock.h winsock2.h)
 MY_CHECK_HEADERS(popen,stdio.h unistd.h)
 MY_CHECK_HEADERS(getenv,unistd.h stdlib.h)
-MY_CHECK_HEADERS(gethostname,unistd.h netdb.h winsock2.h)
+MY_CHECK_HEADERS(gethostname,unistd.h netdb.h winsock.h winsock2.h)
 
 AC_ALLOCA
 
diff --git a/src/dmalloc.h b/src/dmalloc.h
index f09fa2c49c4ba17b4050886756416aa8ce720359..91ccb74dac28a933612ad83dfdbfa5f349cdf05c 100644
--- a/src/dmalloc.h
+++ b/src/dmalloc.h
@@ -1,5 +1,15 @@
 #ifdef DEBUG_MALLOC
 
+struct memhdr;
+
+void dump_memhdr_locations(struct memhdr *from,
+			   struct memhdr *notfrom);
+struct memhdr *alloc_memhdr(void);
+void free_memhdr(struct memhdr *mh);
+void add_marks_to_memhdr(struct memhdr *to,void *ptr);
+void low_add_marks_to_memhdr(struct memhdr *to,
+			     struct memhdr *from);
+
 extern int verbose_debug_malloc;
 extern int verbose_debug_exit;
 extern void *debug_malloc(size_t, const char *, int);
diff --git a/src/fd_control.c b/src/fd_control.c
index 1318508ae368448a3776321214ba6417400542a2..030b8a84746a61d907ab62f1d4dd27fe9cfd3233 100644
--- a/src/fd_control.c
+++ b/src/fd_control.c
@@ -27,8 +27,8 @@
 #include <sys/socket.h>
 #endif
 
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
 #endif
 
 #ifdef HAVE_FCNTL_H
@@ -41,7 +41,7 @@
 #include <sys/sockio.h>
 #endif
 
-void set_nonblocking(int fd,int which)
+int set_nonblocking(int fd,int which)
 {
 #ifdef DEBUG
   if(fd<0 || fd >MAX_OPEN_FILEDESCRIPTORS)
@@ -49,19 +49,19 @@ void set_nonblocking(int fd,int which)
 #endif
 
 #if defined(USE_IOCTL_FIONBIO) || __NT__
-  fd_ioctl(fd, FIONBIO, &which);
+  return fd_ioctl(fd, FIONBIO, &which);
 #else
 
 #ifdef USE_FCNTL_O_NDELAY
-  fcntl(fd, F_SETFL, which?O_NDELAY:0);
+  return fcntl(fd, F_SETFL, which?O_NDELAY:0);
 #else
 
 #ifdef USE_FCNTL_O_NONBLOCK
-  fcntl(fd, F_SETFL, which?O_NONBLOCK:0);
+  return fcntl(fd, F_SETFL, which?O_NONBLOCK:0);
 #else
 
 #ifdef USE_FCNTL_FNDELAY
-  fcntl(fd, F_SETFL, which?FNDELAY:0);
+  return fcntl(fd, F_SETFL, which?FNDELAY:0);
 #else
 
 #error Do not know how to set your filedescriptors nonblocking.
@@ -108,7 +108,7 @@ int set_close_on_exec(int fd, int which)
 #ifdef TESTING
 
 
-#if defined(HAVE_WINSOCK2_H) && defined(USE_IOCTLSOCKET_FIONBIO)
+#if defined(HAVE_WINSOCK_H) && defined(USE_IOCTLSOCKET_FIONBIO)
 int main()
 {
   exit(0);
diff --git a/src/fd_control.h b/src/fd_control.h
index ce8146a8d851ace8214e039e77e35d7e6082b7cb..c0bb0e9d2df97d2662b0aa2eb7d4484730adb33e 100644
--- a/src/fd_control.h
+++ b/src/fd_control.h
@@ -7,7 +7,7 @@
 #define FD_CONTROL_H
 
 /* Prototypes begin here */
-void set_nonblocking(int fd,int which);
+int set_nonblocking(int fd,int which);
 int query_nonblocking(int fd);
 int set_close_on_exec(int fd, int which);
 /* Prototypes end here */
diff --git a/src/fdlib.c b/src/fdlib.c
index fb6ecc888dbc71f6a8192d528be53efd9cbd10e8..44ecdb7cc0177d924b0aea413c9967651a21ca57 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -2,7 +2,7 @@
 #include "error.h"
 #include <math.h>
 
-#ifdef HAVE_WINSOCK2_H
+#ifdef HAVE_WINSOCK_H
 
 #ifdef _REENTRANT
 #include "threads.h"
@@ -57,7 +57,7 @@ void fd_init()
   
   mt_init(&fd_mutex);
   mt_lock(&fd_mutex);
-  if(WSAStartup(MAKEWORD(2,0), &wsadata) != 0)
+  if(WSAStartup(MAKEWORD(1,1), &wsadata) != 0)
   {
     fatal("No winsock available.\n");
   }
@@ -620,7 +620,7 @@ FD fd_dup2(FD from, FD to)
   return to;
 }
 
-#endif /* HAVE_WINSOCK2_H */
+#endif /* HAVE_WINSOCK_H */
 
 #if 0
 
diff --git a/src/fdlib.h b/src/fdlib.h
index 50bbd8ae6b4af66b9072d9b879ce8c86c732da3e..94ed98239e84005ed7dd51c33d6e900ce65a1866 100644
--- a/src/fdlib.h
+++ b/src/fdlib.h
@@ -27,7 +27,7 @@
 #define fd_BUFFERED           8
 #define fd_BIDIRECTIONAL     16
 
-#ifdef HAVE_WINSOCK2_H
+#ifdef HAVE_WINSOCK_H
 
 
 #define FILE_CAPABILITIES (fd_INTERPROCESSABLE)
@@ -38,7 +38,7 @@
 #define FD_SETSIZE MAX_OPEN_FILEDESCRIPTORS
 #endif
 
-#include <winsock2.h>
+#include <winsock.h>
 #include <winbase.h>
 
 typedef int FD;
@@ -258,8 +258,8 @@ typedef struct my_fd_set_s
 #define fd_copy_my_fd_set_to_fd_set(TO,FROM,max) \
    MEMCPY((TO),&(FROM)->tmp,sizeof(*(TO)))
 
-#define FILE_CAPABILITIES (fd_INTERPROCESSABLE)
-#define PIPE_CAPABILITIES (fd_INTERPROCESSABLE | fd_BUFFERED)
+#define FILE_CAPABILITIES (fd_INTERPROCESSABLE | fd_CAN_NONBLOCK)
+#define PIPE_CAPABILITIES (fd_INTERPROCESSABLE | fd_BUFFERED | fd_CAN_NONBLOCK)
 #define UNIX_SOCKET_CAPABILITIES (fd_INTERPROCESSABLE | fd_BIDIRECTIONAL | fd_CAN_NONBLOCK)
 #define SOCKET_CAPABILITIES (fd_INTERPROCESSABLE | fd_BIDIRECTIONAL | fd_CAN_NONBLOCK | fd_CAN_SHUTDOWN)
 
diff --git a/src/main.c b/src/main.c
index c4652581533baca45d12345c2c4dc9319b8b30d9..4f6a80e22236837f3be87b863cd1e8324283d920 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: main.c,v 1.40 1998/02/03 05:29:26 hubbe Exp $");
+RCSID("$Id: main.c,v 1.41 1998/02/11 00:05:01 hubbe Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -331,6 +331,13 @@ void do_exit(int num) ATTRIBUTE((noreturn))
 
   exit_modules();
 
+#ifdef DEBUG_MALLOC
+  {
+    extern cleanup_memhdrs(void);
+    cleanup_memhdrs();
+  }
+#endif
+
   exit(num);
 }
 
@@ -379,6 +386,7 @@ void low_exit_main(void)
   if(verbose_debug_exit)
   {
     INT32 num,size,recount=0;
+    fprintf(stderr,"Exited normally, counting bytes.\n");
 
     count_memory_in_arrays(&num, &size);
     if(num)
diff --git a/src/mapping.c b/src/mapping.c
index 226ccc7f59f1330193b94ca10f264ec67c8deb0d..6f55a2f66d4555f36d4c5f4f458133b5666e9084 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.27 1998/01/25 08:25:10 hubbe Exp $");
+RCSID("$Id: mapping.c,v 1.28 1998/02/11 00:05:01 hubbe Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -565,6 +565,27 @@ struct array *mapping_values(struct mapping *m)
   return a;
 }
 
+struct array *mapping_to_array(struct mapping *m)
+{
+  INT32 e;
+  struct keypair *k;
+  struct array *a;
+  struct svalue *s;
+  a=allocate_array(m->size);
+  s=ITEM(a);
+  LOOP(m)
+    {
+      struct array *b=allocate_array(2);
+      assign_svalue(b->item+0, & k->ind);
+      assign_svalue(b->item+1, & k->val);
+      s->u.array=b;
+      s->type=T_ARRAY;
+    }
+  a->type_field = BIT_ARRAY;
+
+  return a;
+}
+
 void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to)
 {
   INT32 e;
diff --git a/src/pike_memory.c b/src/pike_memory.c
index 78625cd05b9a4641319002cd33933f6632f3108d..e00e4e814d28e382df234eb64daa779220e789cf 100644
--- a/src/pike_memory.c
+++ b/src/pike_memory.c
@@ -438,9 +438,9 @@ char *debug_xalloc(long size)
 
 #ifdef DEBUG_MALLOC
 
-#ifdef _REENTRANT
 #include "threads.h"
 
+#ifdef _REENTRANT
 static MUTEX_T debug_malloc_mutex;
 #endif
 
@@ -452,6 +452,9 @@ static MUTEX_T debug_malloc_mutex;
 #undef strdup
 #undef main
 
+static void add_location(struct memhdr *mh, const char *fn, int line);
+static struct memhdr *find_memhdr(void *p);
+
 int verbose_debug_malloc = 0;
 int verbose_debug_exit = 1;
 
@@ -468,6 +471,13 @@ struct memloc
   int times;
 };
 
+
+struct memloc_block
+{
+  struct memloc_block *next;
+  struct memloc memlocs[BSIZE];
+};
+
 struct memhdr
 {
   struct memhdr *next;
@@ -476,7 +486,6 @@ struct memhdr
   struct memloc *locations;
 };
 
-static struct memhdr *hash[HSIZE];
 
 struct memhdr_block
 {
@@ -484,10 +493,17 @@ struct memhdr_block
   struct memhdr memhdrs[BSIZE];
 };
 
+static struct memloc_block *memloc_blocks=0;
+static struct memloc *free_memlocs=0;
+static struct memhdr no_leak_memlocs;
+
+static struct memloc *mlhash[LHSIZE];
+static struct memhdr *hash[HSIZE];
+
 static struct memhdr_block *memhdr_blocks=0;
 static struct memhdr *free_memhdrs=0;
 
-static struct memhdr *alloc_memhdr(void)
+struct memhdr *alloc_memhdr(void)
 {
   struct memhdr *tmp;
   if(!free_memhdrs)
@@ -512,20 +528,54 @@ static struct memhdr *alloc_memhdr(void)
   }
 
   tmp=free_memhdrs;
+  tmp->locations=0;
   free_memhdrs=tmp->next;
   return tmp;
 }
 
-struct memloc_block
+void low_add_marks_to_memhdr(struct memhdr *to,
+				    struct memhdr *from)
 {
-  struct memloc_block *next;
-  struct memloc memlocs[BSIZE];
-};
+  struct memloc *l;
+  if(!from) return;
+  for(l=from->locations;l;l=l->next)
+    add_location(to, l->filename, l->line);
+}
 
-static struct memloc_block *memloc_blocks=0;
-static struct memloc *free_memlocs=0;
-static struct memhdr no_leak_memlocs;
-static struct memloc *mlhash[LHSIZE];
+void add_marks_to_memhdr(struct memhdr *to, void *ptr)
+{
+  low_add_marks_to_memhdr(to,find_memhdr(ptr));
+}
+
+static unsigned long lhash(struct memhdr *m,
+			   const char *fn,
+			   int line)
+{
+  unsigned long l;
+  l=(long)m;
+  l*=53;
+  l+=(long)fn;
+  l*=4711;
+  l+=line;
+  l%=LHSIZE;
+  return l;
+}
+
+void free_memhdr(struct memhdr *mh)
+{
+  struct memloc *ml;
+  while((ml=mh->locations))
+  {
+    unsigned long l=lhash(mh,ml->filename, ml->line);
+    if(mlhash[l]==ml) mlhash[l]=0;
+    
+    mh->locations=ml->next;
+    ml->next=free_memlocs;
+    free_memlocs=ml;
+  }
+  mh->next=free_memhdrs;
+  free_memhdrs=mh;
+}
 
 static struct memloc *alloc_memloc(void)
 {
@@ -567,19 +617,6 @@ static struct memhdr *find_memhdr(void *p)
   return NULL;
 }
 
-static unsigned long lhash(struct memhdr *m,
-			   const char *fn,
-			   int line)
-{
-  unsigned long l;
-  l=(long)m;
-  l*=53;
-  l+=(long)fn;
-  l*=4711;
-  l+=line;
-  l%=LHSIZE;
-  return l;
-}
 
 static void add_location(struct memhdr *mh, const char *fn, int line)
 {
@@ -660,20 +697,9 @@ static int remove_memhdr(void *p)
   {
     if(mh->data==p)
     {
-      struct memloc *ml;
-      while((ml=mh->locations))
-      {
-	unsigned long l=lhash(mh,ml->filename, ml->line);
-	if(mlhash[l]==ml) mlhash[l]=0;
-
-	add_location(&no_leak_memlocs, ml->filename, ml->line);
-	mh->locations=ml->next;
-	ml->next=free_memlocs;
-	free_memlocs=ml;
-      }
       *prev=mh->next;
-      mh->next=free_memhdrs;
-      free_memhdrs=mh;
+      low_add_marks_to_memhdr(&no_leak_memlocs, mh);
+      free_memhdr(mh);
       
       return 1;
     }
@@ -750,7 +776,20 @@ char *debug_strdup(const char *s, const char *fn, int line)
   return m;
 }
 
-static void cleanup_memhdrs()
+
+void dump_memhdr_locations(struct memhdr *from,
+			   struct memhdr *notfrom)
+{
+  struct memloc *l;
+  for(l=from->locations;l;l=l->next)
+  {
+    if(find_location(notfrom, l->filename, l->line))
+      continue;
+    fprintf(stderr," *** %s:%d (%d times)\n",l->filename,l->line,l->times);
+  }
+}
+
+void cleanup_memhdrs()
 {
   unsigned long h;
   mt_lock(&debug_malloc_mutex);
@@ -789,7 +828,6 @@ int main(int argc, char *argv[])
 {
   extern int dbm_main(int, char **);
   mt_init(&debug_malloc_mutex);
-  atexit(cleanup_memhdrs);
   return dbm_main(argc, argv);
 }
 
diff --git a/src/stralloc.c b/src/stralloc.c
index 3ceb865c4a0ad38e770eb7506d46f4f5e2abcb55..99fca6845e2042d2a41d034c6c8528b0782c0dd7 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -13,6 +13,8 @@
 #include "gc.h"
 #include "stuff.h"
 
+#include <ctype.h>
+
 #define BEGIN_HASH_SIZE 997
 #define MAX_AVG_LINK_LENGTH 3
 #define HASH_PREFIX 20
@@ -30,6 +32,37 @@ static unsigned int StrHash(const char *s,int len)
   return full_hash_value % htable_size;
 }
 
+#ifdef DEBUG_MALLOC
+static void locate_problem(int (*isproblem)(struct pike_string *))
+{
+  unsigned INT32 e;
+  struct pike_string *s;
+  struct memhdr *yes=alloc_memhdr();
+  struct memhdr *no=alloc_memhdr();
+
+  for(e=0;e<htable_size;e++)
+    for(s=base_table[e];s;s=s->next)
+      add_marks_to_memhdr(isproblem(s)?yes:no,s);
+
+  fprintf(stderr,"Plausible problem location(s):\n");
+  dump_memhdr_locations(yes,no);
+}
+
+static int has_zero_refs(struct pike_string *s)
+{
+  return s->refs<=0;
+}
+static int wrong_hash(struct pike_string *s)
+{
+  return s->hval != StrHash(s->str, s->len);
+}
+static int improper_zero_termination(struct pike_string *s)
+{
+  return s->str[s->len];
+}
+#else
+#define locate_problem(X)
+#endif
 
 /*** find a string in the shared string table. ***/
 static struct pike_string *internal_findstring(const char *s,int len,int h)
@@ -42,6 +75,7 @@ static struct pike_string *internal_findstring(const char *s,int len,int h)
     if(curr->refs<1)
     {
       debug_dump_pike_string(curr, 70);
+      locate_problem(has_zero_refs);
       fatal("String with no references.\n");
     }
 #endif
@@ -90,6 +124,7 @@ static struct pike_string *propagate_shared_string(const struct pike_string *s,i
     if(curr->refs<1)
     {
       debug_dump_pike_string(curr, 70);
+      locate_problem(has_zero_refs);
       fatal("String with no references.\n");
     }
 #endif
@@ -294,13 +329,19 @@ void check_string(struct pike_string *s)
 {
   StrHash(s->str, s->len);
   if(full_hash_value != s->hval)
+  {
+    locate_problem(wrong_hash);
     fatal("Hash value changed?\n");
+  }
 
   if(debug_findstring(s) !=s)
     fatal("Shared string not shared.\n");
 
   if(s->str[s->len])
+  {
+    locate_problem(improper_zero_termination);
     fatal("Shared string is not zero terminated properly.\n");
+  }
 }
 
 void verify_shared_strings_tables(void)
@@ -318,13 +359,22 @@ void verify_shared_strings_tables(void)
 	fatal("Shared string shorter than zero bytes.\n");
 
       if(s->refs <= 0)
+      {
+	locate_problem(has_zero_refs);
 	fatal("Shared string had too few references.\n");
+      }
 
       if(s->str[s->len])
+      {
+	locate_problem(improper_zero_termination);
 	fatal("Shared string didn't end with a zero.\n");
+      }
 
       if(StrHash(s->str, s->len) != e)
+      {
+	locate_problem(wrong_hash);
 	fatal("Shared string hashed to wrong place.\n");
+      }
 
       if(s->hval != full_hash_value)
 	fatal("Shared string hashed to other number.\n");
diff --git a/src/time_stuff.h b/src/time_stuff.h
index 528b0e9b1acaff6b9a19100dfc19a7e8341b46f5..459adef8d4bcfe7d823f0a308854484c34a3e95f 100644
--- a/src/time_stuff.h
+++ b/src/time_stuff.h
@@ -21,8 +21,8 @@
 # endif
 #endif
 
-#ifdef HAVE_WINSOCK2_H
-# include <winsock2.h>
+#ifdef HAVE_WINSOCK_H
+# include <winsock.h>
 #endif
 
 #undef HAVE_SYS_TIME_H