diff --git a/src/modules/spider/Makefile.in b/src/modules/spider/Makefile.in
index db8801b5aa389542c5395a117364692ed557814a..d432ac9f545e1ffd052c4f96de44792c97e65a26 100644
--- a/src/modules/spider/Makefile.in
+++ b/src/modules/spider/Makefile.in
@@ -4,7 +4,7 @@ PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
 CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
 
 FILES=spider.o discdate.o stardate.o sdebug.o tree.o lock.o streamed_parser.o\
-	http_parse.o encode_decode.o
+	http_parse.o encode_decode.o sharedmem.o
 
 spider.a: $(FILES)
 	-rm -f spider.a
diff --git a/src/modules/spider/configure b/src/modules/spider/configure
index 7ad5275798fc2731fefa0a8bdc60bcdcc76db1e0..190a91edf51fc88b9838ed6c9599ec4eb94920fb 100755
--- a/src/modules/spider/configure
+++ b/src/modules/spider/configure
@@ -754,8 +754,52 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
+echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
+ac_lib_var=`echo nsl'_'gethostbyname | tr './+\055' '__p_'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 766 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
 
-if test x$ac_cv_lib_thread_mutex_inlock = xno ;  then
+int main() { return 0; }
+int t() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo nsl | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lnsl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test x$ac_cv_lib_thread_mutex_unlock = xno ;  then
   echo $ac_n "checking for -lpthread""... $ac_c" 1>&6
 ac_lib_var=`echo pthread'_'pthread_mutex_unlock | tr './+\055' '__p_'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
@@ -764,7 +808,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 768 "configure"
+#line 812 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -776,7 +820,7 @@ int t() {
 pthread_mutex_unlock()
 ; return 0; }
 EOF
-if { (eval echo configure:780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -817,13 +861,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 821 "configure"
+#line 865 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:871: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -832,13 +876,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 836 "configure"
+#line 880 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:842: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -868,12 +912,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 872 "configure"
+#line 916 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:877: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:921: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -910,7 +954,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 914 "configure"
+#line 958 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -934,7 +978,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -966,12 +1010,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 970 "configure"
+#line 1014 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:975: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1019: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1002,7 +1046,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1006 "configure"
+#line 1050 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1026,7 +1070,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1059,7 +1103,7 @@ if eval "test \"`echo '$''{'lpc_cv_timezone'+set}'`\" = set"; then
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 1063 "configure"
+#line 1107 "configure"
 #include "confdefs.h"
 
 #include <time.h>
@@ -1076,7 +1120,7 @@ int t() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1124: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   lpc_cv_timezone='localtime'
 
diff --git a/src/modules/spider/configure.in b/src/modules/spider/configure.in
index df06fbc9380c59b61199db1f7fc49383452a53d3..0cfdbb6ec02daa6de13bc1f2608296894bbdd5f1 100644
--- a/src/modules/spider/configure.in
+++ b/src/modules/spider/configure.in
@@ -6,8 +6,9 @@ AC_PROG_RANLIB
 
 AC_CHECK_LIB(thread, mutex_unlock)
 AC_CHECK_LIB(socket, socket)
+AC_CHECK_LIB(nsl, gethostbyname)
 
-if test x$ac_cv_lib_thread_mutex_inlock = xno ;  then
+if test x$ac_cv_lib_thread_mutex_unlock = xno ;  then
   AC_CHECK_LIB(pthread, pthread_mutex_unlock)
 fi
 
diff --git a/src/modules/spider/dependencies b/src/modules/spider/dependencies
deleted file mode 100644
index 51cda8f59bcc2b8c3b85877e9a1daceb47d5369f..0000000000000000000000000000000000000000
--- a/src/modules/spider/dependencies
+++ /dev/null
@@ -1,39 +0,0 @@
-discdate.o: discdate.c stralloc.h types.h \
- machine.h global.h config.h port.h \
- macros.h object.h svalue.h add_efun.h \
- hashtable.h las.h dynamic_buffer.h program.h \
- interpret.h mapping.h array.h builtin_efuns.h \
- spider.h
-lock.o: lock.c stralloc.h types.h machine.h \
- global.h config.h port.h macros.h \
- object.h svalue.h add_efun.h hashtable.h \
- las.h dynamic_buffer.h program.h interpret.h \
- mapping.h array.h builtin_efuns.h
-sdebug.o: sdebug.c stralloc.h types.h machine.h \
- global.h config.h port.h macros.h \
- object.h svalue.h add_efun.h hashtable.h \
- las.h dynamic_buffer.h program.h interpret.h \
- mapping.h array.h builtin_efuns.h spider.h
-spider.o: spider.c machine.h stralloc.h types.h \
- global.h config.h port.h macros.h \
- object.h svalue.h add_efun.h hashtable.h \
- las.h dynamic_buffer.h program.h interpret.h \
- mapping.h array.h builtin_efuns.h spider.h conf.h \
- streamed_parser.h
-stardate.o: stardate.c stralloc.h types.h \
- machine.h global.h config.h port.h \
- macros.h object.h svalue.h add_efun.h \
- hashtable.h las.h dynamic_buffer.h program.h \
- interpret.h mapping.h array.h builtin_efuns.h \
- spider.h
-streamed_parser.o: streamed_parser.c stralloc.h types.h \
- machine.h global.h config.h port.h \
- macros.h object.h svalue.h add_efun.h \
- hashtable.h las.h dynamic_buffer.h program.h \
- interpret.h mapping.h array.h builtin_efuns.h \
- streamed_parser.h
-tree.o: tree.c machine.h stralloc.h types.h \
- global.h config.h port.h macros.h \
- object.h svalue.h add_efun.h hashtable.h \
- las.h dynamic_buffer.h program.h interpret.h \
- mapping.h array.h builtin_efuns.h spider.h
diff --git a/src/modules/spider/encode_decode.c b/src/modules/spider/encode_decode.c
index 4004593f3c5f33ad192bbe55441f49aad2f6a99f..3536893e3941450f03650d0db157bd6ac1203b9e 100644
--- a/src/modules/spider/encode_decode.c
+++ b/src/modules/spider/encode_decode.c
@@ -14,20 +14,64 @@
 
 #include "spider.h"
 
-#define strcat(buff, s, l) low_my_binary_strcat(s, l, buff)
-#define addchar(buff, t)   low_my_putchar(t,buff);
+#define strcat(buff, s, l) low_my_binary_strcat((s), (l), (buff))
+#define addchar(buff, t)   low_my_putchar((t),(buff))
 
-INLINE static void addint(dynamic_buffer *buff, int t)
+
+/*
+          byte 0          byte 1          byte 2          byte 3          byte 4     
+int x     8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1
+-----------------------------------------------------------------------------------------
+< 1<<7    1 x x x x x x x
+< 1<<8    0 0 0 0 0 0 0 1 x x x x x x x x
+< 1<<16   0 0 0 0 0 0 1 0 x x x x x x x x x x x x x x x x
+< 1<<24   0 0 0 0 0 0 1 1 x x x x x x x x x x x x x x x x x x x x x x x x
+< 1<<32   0 0 0 0 0 1 0 0 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
+
+
+< 0       0 0 0 0 1 as above
+*/
+
+INLINE static void add_int_to_buffer(dynamic_buffer *buff, INT32 t)
 {
-  t = htonl(t);
-  strcat(buff, (char *)(&t), sizeof(int));
-}
+  int negbit = 0;
 
+  if((unsigned INT32)t < 0x80)
+  {
+    addchar(buff, (unsigned char)((((unsigned INT32)t)|0x80)&0xff));
+    return;
+  }
 
-static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct processing *p)
+  if(t<0)
+  {
+    negbit = 8;
+    t = -t;
+  }
+  
+  if((unsigned INT32)t < 0x100) {
+    addchar(buff, 1|negbit);
+    addchar(buff, (t&255));
+  } else if((unsigned INT32)t < 0x10000) {
+    addchar(buff, 2|negbit);
+    addchar(buff, (t>>8)&255);
+    addchar(buff, t&255);
+  } else if((unsigned INT32)t < 0x1000000) {
+    addchar(buff, 3|negbit);
+    addchar(buff, (t>>16)&255);
+    addchar(buff, (t>>8)&255);
+    addchar(buff, t&255);
+  } else {
+    addchar(buff, 4|negbit);
+    t = htonl(t);
+    strcat(buff, (char *)(&t), 4);
+  }
+}
+
+static void rec_save_value(struct svalue *val, dynamic_buffer *buff,
+			   struct processing *p)
 {
   struct processing doing;
-  int i;
+  INT32 i;
   
   if((1<<val->type)&BIT_COMPLEX)
   {
@@ -41,15 +85,12 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc
   }
 
 
-#if 0
-  addchar(buff, ((unsigned char)(val->type)));
-#else
-  addint(buff, val->type);
-#endif
+  add_int_to_buffer(buff, val->type);
+
   switch(val->type)
   {
    case T_ARRAY:
-    addint(buff, val->u.array->size);
+     add_int_to_buffer(buff, val->u.array->size);
     for(i=0; i<val->u.array->size; i++)
       rec_save_value(ITEM(val->u.array)+i, buff, p);
     break;
@@ -61,7 +102,7 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc
     push_mapping(val->u.mapping);
     f_values(1);
     
-    addint(buff, sp[-2].u.array->size);
+    add_int_to_buffer(buff, sp[-2].u.array->size);
     for(i=0; i<sp[-2].u.array->size; i++)
     {
       rec_save_value(ITEM(sp[-2].u.array)+i, buff, p); /* indices */
@@ -71,7 +112,7 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc
     break;
 
    case T_LIST:
-    addint(buff, val->u.list->ind->size);
+    add_int_to_buffer(buff, val->u.list->ind->size);
     for(i=0; i<val->u.list->ind->size; i++)
       rec_save_value(ITEM(val->u.list->ind)+i, buff, p);
     break;
@@ -82,10 +123,10 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc
     APPLY_MASTER("nameof", 1);
     if(sp[-1].type == T_STRING)
     {
-      addint(buff, sp[-1].u.string->len);
+      add_int_to_buffer(buff, sp[-1].u.string->len);
       strcat(buff, sp[-1].u.string->str, sp[-1].u.string->len);
     } else {
-      addint(buff, 0);
+      add_int_to_buffer(buff, 0);
     }
     pop_stack();
     break;
@@ -99,10 +140,10 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc
     APPLY_MASTER("nameof", 1);
     if(sp[-1].type == T_STRING)
     {
-      addint(buff, sp[-1].u.string->len);
+      add_int_to_buffer(buff, sp[-1].u.string->len);
       strcat(buff, sp[-1].u.string->str, sp[-1].u.string->len);
     } else {
-      addint(buff, 0);
+      add_int_to_buffer(buff, 0);
     }
     pop_stack();
     break;
@@ -113,28 +154,28 @@ static void rec_save_value(struct svalue *val, dynamic_buffer *buff, struct proc
     APPLY_MASTER("nameof", 1);
     if(sp[-1].type == T_STRING)
     {
-      addint(buff, sp[-1].u.string->len);
+      add_int_to_buffer(buff, sp[-1].u.string->len);
       strcat(buff, sp[-1].u.string->str, sp[-1].u.string->len);
     } else {
-      addint(buff, 0);
+      add_int_to_buffer(buff, 0);
     }
     pop_stack();
     break;
 
    case T_STRING:
-    addint(buff, val->u.string->len);
+    add_int_to_buffer(buff, val->u.string->len);
     strcat(buff, val->u.string->str, val->u.string->len);
     break;
 
    case T_INT:
-    addint(buff, val->u.integer);    
+    add_int_to_buffer(buff, val->u.integer);    
     break;
     
    case T_FLOAT:
     /* How to encode a float _correctly_? */
-    if(sizeof(int) < sizeof(float))  /* FIXME FIXME FIXME FIXME */
+    if(sizeof(INT32) < sizeof(float))  /* FIXME FIXME FIXME FIXME */
       error("Float architecture not supported.\n"); 
-    addint(buff, val->u.integer);
+    add_int_to_buffer(buff, val->u.integer);
     break;
   }
 }
@@ -155,37 +196,62 @@ void f_encode_value(INT32 args)
   push_string(low_free_buf(&buff));
 }
 
-static int extract_int(char **v, unsigned int *l)
+static unsigned char extract_char(char **v, unsigned INT32 *l)
 {
-  unsigned int j;
-  int t=0;
-  char *c = (char *)(&t);
+  if(!*l) error("Format error, not enough place for char.\n");
+  else (*l)--;
+  (*v)++;
+  return ((unsigned char *)(*v))[-1];
+}
 
-  if(*l<sizeof(int))
-    error("Format error, not enough place for integer.\n");
 
-  for(j=0; j<sizeof(int); j++)
-    c[j] = ((*v)[j]);
+static INT32 extract_int(char **v, unsigned INT32 *l)
+{
+  unsigned INT32 j;
+  INT32 t=0;
+  char *c = (char *)(&t);
 
-  t = ntohl(t);
+  if(!*l)
+    error("Format error: not enough place for short integer.\n");
 
-  *l -= sizeof(int);
-  *v += sizeof(int);
+  if((**v) & 0x80) /* (very) Short int. */
+    return extract_char(v,l) & 0x7f;
 
-  return t;
-}
+  switch(extract_char(v,l))
+  {
+  case 1: /* char */
+    return extract_char(v,l);
+    
+  case 2: /* word */
+    return (extract_char(v,l)<<8) | (extract_char(v,l));
+    
+  case 3: /* 24 bit thingie */
+    return (extract_char(v,l)<<16) | (extract_char(v,l)<<8) | extract_char(v,l);
 
-static unsigned char extract_char(char **v, unsigned int *l)
-{
-  if(!*l) error("Format error, not enough place for char.\n");
-  else (*l)--;
-  *v++;
-  return (*v)[-1];
+  case 4: /* 32 bit number */
+    return (extract_char(v,l)<<24) |
+           (extract_char(v,l)<<16) | (extract_char(v,l)<<8) |
+            extract_char(v,l);
+    
+  case 9:  /* -char */
+    return -extract_char(v,l);
+  case 10: /* -word */
+    return -((extract_char(v,l)<<8) | (extract_char(v,l)));
+  case 11: /* -24 bit */
+    return -((extract_char(v,l)<<16) | (extract_char(v,l)<<8) | extract_char(v,l));
+  case 12: /* -32 bit thingie */
+    return -((extract_char(v,l)<<24) |
+	     (extract_char(v,l)<<16) | (extract_char(v,l)<<8) |
+	     extract_char(v,l));
+    
+  }
+  error("Format Error: Error in format string, invalid integer.\n");
+  return t;
 }
 
-static void rec_restore_value(char **v, int *l)
+static void rec_restore_value(char **v, INT32 *l)
 {
-  int t,i;
+  INT32 t,i;
 
   switch(extract_int(v,l))
   {
@@ -195,7 +261,7 @@ static void rec_restore_value(char **v, int *l)
     
    case T_FLOAT:
     /* How to encode a float _correctly_? */
-    if(sizeof(int) < sizeof(float))  /* FIXME FIXME FIXME FIXME */
+    if(sizeof(INT32) < sizeof(float))  /* FIXME FIXME FIXME FIXME */
       error("Float architecture not supported.\n"); 
     push_int(extract_int(v,l)); /* WARNING! */
     sp[-1].type = T_FLOAT;
@@ -205,7 +271,7 @@ static void rec_restore_value(char **v, int *l)
     t = extract_int(v,l);
     if(*l < t) error("Format error, string to short\n");
     push_string(make_shared_binary_string(*v, t));
-    *l-= t; *v+= t;
+    (*l)-= t; (*v)+= t;
     return;
     
    case T_ARRAY:
@@ -235,21 +301,21 @@ static void rec_restore_value(char **v, int *l)
    case T_OBJECT:
     t = extract_int(v,l);
     push_string(make_shared_binary_string(*v, t));
-    *l-= t; *v+= t;
+    (*l) -= t; (*v) += t;
     APPLY_MASTER("objectof", 1);
     return;
     
    case T_FUNCTION:
     t = extract_int(v,l);
     push_string(make_shared_binary_string(*v, t));
-    *l-= t; *v+= t;
+    (*l) -= t; (*v) += t;
     APPLY_MASTER("functionof", 1);
     return;
      
    case T_PROGRAM:
     t = extract_int(v,l);
     push_string(make_shared_binary_string(*v, t));
-    *l-= t; *v+= t;
+    (*l) -= t; (*v) += t;
     APPLY_MASTER("programof", 1);
     return;
     
@@ -262,7 +328,7 @@ void f_decode_value(INT32 args)
 {
   struct lpc_string *s;
   char *v;
-  int l;
+  INT32 l;
 
   if(args != 1 || (sp[-1].type != T_STRING))
     error("Illegal argument to restore_value(STRING)\n");
diff --git a/src/modules/spider/lock.c b/src/modules/spider/lock.c
index 771a109dca768ce789754f5d1100eef57af806dc..54c9642d5d6bf23e652d2683f0bc129bc261f5bd 100644
--- a/src/modules/spider/lock.c
+++ b/src/modules/spider/lock.c
@@ -32,59 +32,7 @@
 #include <sys/stat.h>
 
 #include <errno.h>
-
-#ifdef HAVE_MMAP
-char *my_shared_malloc(int size)
-{
-  int fd;
-  char *pointer;
-  char *scratch;
-
-  fd = open("/tmp/.spinnerlock", O_RDWR|O_CREAT, 0777);
-  if(fd == -1)
-  {
-    perror("my_shared_malloc::open");
-    error("my_shared_malloc(): Can't open() /tmp/.spinnerlock.\n");
-  }
-  unlink("/tmp/.spinnerlock");
-
-  scratch = malloc(size+sizeof(int));
-  write(fd, scratch, size+sizeof(int));
-  free(scratch);
-
-  pointer = mmap(NULL,(size+sizeof(int)),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
-  if(pointer==MAP_FAILED)
-  {
-    perror("my_shared_malloc::mmap");
-    error("my_shared_malloc(): Can't mmap() /tmp/.spinnerlock.\n");
-  }
-  close(fd);
-  ((int *)pointer)[0] = size;
-  return pointer + sizeof(int);
-}
-
-void *my_shared_free(char *pointer)
-{
-  int size;
-  pointer -= sizeof(int);
-  size = *(int *)pointer;
-  if(munmap( pointer, size ) < 0)
-    perror("my_shared_free::munmap");
-}
-
-#else
-/* Should look for shmop, probably */
-char *my_shared_malloc(int size)
-{
-  return malloc(size); /* Incorrect, really. */
-}
-
-void *my_shared_free(char *pointer)
-{
-  free(pointer);
-}
-#endif
-
+#include "sharedmem.h"
 
 #ifdef HAVE_THREAD_H
 typedef mutex_t mylock_t;
@@ -92,22 +40,27 @@ typedef mutex_t mylock_t;
 typedef pthread_mutex_t mylock_t;
 #endif
 
-
+#define LOCK_HASH_TABLE_SIZE ((1<<10)-1) /* MUST BE ((1<<n)-1), 1<n<30 */
+ 
 struct _lock {
   mylock_t lock; /* MUST BE FIRST IN THE STRUCT */
   int id;
   struct _lock *next;
+  struct _lock *next_hash;  
+  struct _lock *prev_hash;
   struct _lock *prev;
 } *first_lock=NULL, *last_lock=NULL;
 
+struct _lock *lock_hash_table[LOCK_HASH_TABLE_SIZE+1];
+
 mylock_t *findlock( int id )
 {
-  struct _lock *current = first_lock;
+  struct _lock *current = lock_hash_table[ id & LOCK_HASH_TABLE_SIZE ];
   while(current)
   {
     if(current->id == id)
       return &current->lock;
-    current = current->next;
+    current = current->next_hash;
   }
   return NULL;
 }
@@ -115,7 +68,8 @@ mylock_t *findlock( int id )
 mylock_t *newlock( int id )
 {
   struct _lock *lock;
-  lock = (struct _lock *)my_shared_malloc( sizeof( struct _lock ) );
+  struct _lock *tmp=NULL;
+  lock = (struct _lock *)shared_malloc( sizeof( struct _lock ) );
   lock->id = id;
   if(!first_lock)
   {
@@ -125,8 +79,15 @@ mylock_t *newlock( int id )
     lock->prev = last_lock;
     lock->next = NULL;
     last_lock->next = lock;
-    last_lock = NULL;
+    last_lock = lock;
   }
+  if( tmp = lock_hash_table[ id & LOCK_HASH_TABLE_SIZE] )
+    tmp->prev_hash = lock;
+
+  lock_hash_table[ id & LOCK_HASH_TABLE_SIZE] = lock;
+  lock->next_hash = tmp;
+  lock->prev_hash = NULL;
+
 #ifdef HAVE_MUTEX_UNLOCK
   mutex_init( &lock->lock, USYNC_PROCESS, 0 );
 #else
@@ -172,12 +133,19 @@ void freelock( mylock_t *lock )
   if(rlock == last_lock)
     last_lock = rlock->prev;
 
+  if(rlock->next_hash)
+    rlock->next_hash->prev_hash= rlock->prev_hash;
+  if(rlock->prev_hash)
+    rlock->prev_hash->next_hash= rlock->next_hash;
+  if(lock_hash_table[ rlock->id & LOCK_HASH_TABLE_SIZE] == rlock)
+    lock_hash_table[ rlock->id & LOCK_HASH_TABLE_SIZE] = rlock->next_hash;
+
 #ifdef HAVE_MUTEX_UNLOCK
   mutex_destroy( lock );
 #else
   pthread_mutex_destroy( lock );
 #endif
-  my_shared_free( (char *)lock );
+  shared_free( (char *)lock );
 }
 
 void f_lock(INT32 args)
@@ -206,18 +174,17 @@ void f_newlock(INT32 args)
 {
   int res;
   int id;
-  mylock_t *lock;
-  if(!args) 
-    error("You have to supply the lock-key.\n");
-  id = sp[-1].u.integer;
-  pop_n_elems(args);
-  if(lock = findlock( id ))
+  if(args) 
   {
-    push_int(0);
-    return;
-  }
-  lock = newlock( id );
-  push_int(id);
+    id = sp[-1].u.integer;
+    pop_n_elems(args);
+  } else
+    id = 0;
+  while(findlock( id )) 
+    id+=rand(); /* This should limit the number of times we have to try. */
+
+  newlock( id );
+  push_int( id );
 }
 
 
diff --git a/src/modules/spider/spider.c b/src/modules/spider/spider.c
index 78e29566fa599def691c5284311b7a52751b9239..ddb003b37bf3fab638ccad44f15e4bcf3bcf610f 100644
--- a/src/modules/spider/spider.c
+++ b/src/modules/spider/spider.c
@@ -1137,9 +1137,10 @@ void f_get_all_active_fd(INT32 args)
 {
   int i,fds;
   struct stat foo;
+  
   pop_n_elems(args);
   for (i=fds=0; i<MAX_OPEN_FILEDESCRIPTORS; i++)
-    if (!fstat(i,&foo))
+    if(!fstat(i,&foo))
     {
       push_int(i);
       fds++;
@@ -1190,39 +1191,54 @@ void f_mark_fd(INT32 args)
     struct sockaddr_in addr;
     char *tmp;
     char buf[20];
+    struct stat fs;
 
+    
     pop_stack();
-    if(fd_marks[fd])
+    if(!fstat(fd,&fs))
     {
-      fd_marks[fd]->refs++;
-      push_string(fd_marks[fd]);
+      if(fd_marks[fd])
+      {
+	fd_marks[fd]->refs++;
+	push_string(fd_marks[fd]);
+      } else {
+	push_text("");
+      }
+      
+      len=sizeof(addr);
+      if(! getsockname(fd, (struct sockaddr *) &addr, &len))
+      {
+	tmp=inet_ntoa(addr.sin_addr);
+	push_string(make_shared_string(" Local:"));
+	push_string(make_shared_string(tmp));
+	sprintf(buf,".%d",(int)(ntohs(addr.sin_port)));
+	push_string(make_shared_string(buf));
+	f_add(4);
+      }
+
+      if(! getpeername(fd, (struct sockaddr *) &addr, &len))
+      {
+	push_string(make_shared_string(" Remote:"));
+	tmp=inet_ntoa(addr.sin_addr);
+	push_string(make_shared_string(tmp));
+	sprintf(buf,".%d",(int)(ntohs(addr.sin_port)));
+	push_string(make_shared_string(buf));
+	f_add(4);
+      }
+      return;
     } else {
+      if(fd_marks[fd])
+      {
+	free_string(fd_marks[fd]);
+	fd_marks[fd]=0;
+      }
       push_int(0);
+      return;
     }
-
-    len=sizeof(addr);
-    if(! getsockname(fd, (struct sockaddr *) &addr, &len))
-    {
-      tmp=inet_ntoa(addr.sin_addr);
-      push_string(make_shared_string(" Local:"));
-      push_string(make_shared_string(tmp));
-      sprintf(buf,".%d",(int)(ntohs(addr.sin_port)));
-      push_string(make_shared_string(buf));
-      f_add(4);
-    }
-
-    if(! getpeername(fd, (struct sockaddr *) &addr, &len))
-    {
-      push_string(make_shared_string(" Remote:"));
-      tmp=inet_ntoa(addr.sin_addr);
-      push_string(make_shared_string(tmp));
-      sprintf(buf,".%d",(int)(ntohs(addr.sin_port)));
-      push_string(make_shared_string(buf));
-      f_add(4);
-    }
-
-    return;
   }
+  
+  
+  
   s=sp[-args+1].u.string;
   s->refs++;
   if(fd_marks[fd])
@@ -1537,6 +1553,32 @@ void f_alarm(INT32 args)
 }
 #endif
 
+void f_fcgi_create_listen_socket(INT32 args)
+{
+  int fd, true;
+  struct sockaddr_in addr;
+  if(!args)
+    error("No args?\n");
+  
+  true=1;
+  fd=socket(AF_INET, SOCK_STREAM, 0);
+  if(fd < 0)
+    error("socket() failed.\n");
+  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&true, sizeof(int));
+  get_inet_addr(&addr, "127.0.0.1");
+  addr.sin_port = htons( ((u_short)sp[-args].u.integer) );
+  if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 ||
+     listen(fd, 4) < 0 )
+    error("Failed to bind() or listen\n");
+  if(fd)
+  {
+    dup2(fd, 0);
+    close(fd);
+  }
+  pop_n_elems(args);
+  push_int(1);
+}
+
 void f_decode_value(INT32 args);
 void f_encode_value(INT32 args);
 
@@ -1552,11 +1594,15 @@ void init_spider_efuns(void)
   make_shared_string("POST");
 #endif
 
+  add_efun("fcgi_create_listen_socket", f_fcgi_create_listen_socket,
+	   "function(int:int)", OPT_SIDE_EFFECT);
+	   
+
 #if defined(HAVE_PTHREAD_MUTEX_UNLOCK) || defined(HAVE_MUTEX_UNLOCK)
   add_efun("_lock", f_lock, "function(int:int)", OPT_SIDE_EFFECT);
   add_efun("_unlock", f_unlock, "function(int:int)", OPT_SIDE_EFFECT);
   add_efun("_free_lock", f_freelock, "function(int:int)", OPT_SIDE_EFFECT);
-  add_efun("_new_lock", f_newlock, "function(int:int)", OPT_SIDE_EFFECT);
+  add_efun("_new_lock", f_newlock, "function(int|void:int)", OPT_SIDE_EFFECT);
 #endif
 
   add_efun("encode_value", f_encode_value, "function(mixed:string)",