diff --git a/lib/modules/ADT.pmod/queue.pike b/lib/modules/ADT.pmod/queue.pike
new file mode 100644
index 0000000000000000000000000000000000000000..9e0ba58e974c5a33aa7f0b733497dc8270f756f4
--- /dev/null
+++ b/lib/modules/ADT.pmod/queue.pike
@@ -0,0 +1,50 @@
+/* queue.pike
+ *
+ * A FIFO queue. Used by connection*
+ */
+
+#define QUEUE_SIZE 100
+
+array l;
+int head;
+int tail;
+
+void create()
+{
+  l = allocate(QUEUE_SIZE);
+  head = tail = 0;
+}
+
+void put(mixed item)
+{
+  if (head == sizeof(l))
+  {
+    l = l[tail ..];
+    head -= tail;
+    tail = 0;
+    l += allocate(sizeof(l) + QUEUE_SIZE);
+  }
+  l[head++] = item;
+//  werror(sprintf("Queue->put: %O\n", l[tail..head-1]));
+}
+
+mixed get()
+{
+//  werror(sprintf("Queue->get: %O\n", l[tail..head-1]));
+  mixed res;
+  if (tail == head)
+    return 0;
+  res = l[tail];
+  l[tail++] = 0;
+  return res;
+}
+
+mixed peek()
+{
+  return (tail < head) && l[tail];
+}
+
+void flush()
+{
+  create();
+}
diff --git a/lib/modules/ADT.pmod/struct.pike b/lib/modules/ADT.pmod/struct.pike
new file mode 100644
index 0000000000000000000000000000000000000000..e6062ddbe2499befb2bde3b1e677d852e2c23c3f
--- /dev/null
+++ b/lib/modules/ADT.pmod/struct.pike
@@ -0,0 +1,160 @@
+/* struct.pike
+ *
+ * Read and write structures from strings.
+ */
+
+string buffer;
+int index;
+
+void create(void|string s)
+{
+  buffer = s || "";
+  index = 0;
+}
+
+void add_data(string s)
+{
+  buffer += s;
+}
+
+string pop_data()
+{
+  string res = buffer;
+  create();
+  return res;
+}
+  
+void put_int(int i, int len)
+{
+  add_data(sprintf("%*c", len, i));
+}
+
+void put_var_string(string s, int len)
+{
+  put_int(strlen(s), len);
+  add_data(s);
+}
+
+void put_fix_string(string s)
+{
+  add_data(s);
+}
+
+void put_fix_array(array(int) data, int item_size)
+{
+  foreach(data, int i)
+    put_int(i, item_size);
+}
+
+void put_var_array(array(int) data, int item_size, int len)
+{
+  put_int(sizeof(data), len);
+  put_fix_array(data, item_size);
+}
+
+mixed get_int(int len)
+{
+  mixed i;
+  if ( (strlen(buffer) - index) < len)
+    throw( ({ "SSL.struct->get_int: no data\n", backtrace() }) );
+  if (len <= 3)
+  {
+    sscanf(buffer, "%*" + (string) index +"s%" + (string) len + "c", i);
+  }
+  else
+    i = Gmp.mpz(buffer[index .. index+len-1], 256);
+  index += len;
+  return i;
+}
+
+string get_fix_string(int len)
+{
+  string res;
+  
+  if ((strlen(buffer) - index) < len)
+    throw( ({ "SSL.struct->get_fix_string: no data\n", backtrace() }) );
+  res = buffer[index .. index + len - 1];
+  index += len;
+  return res;
+}
+
+string get_var_string(int len)
+{
+  return get_fix_string(get_int(len));
+}
+
+array(mixed) get_fix_array(int item_size, int size)
+{
+  array(mixed) res = allocate(size);
+  for(int i = 0; i<size; i++)
+    res[i] = get_int(item_size);
+  return res;
+}
+
+array(mixed) get_var_array(int item_size, int len)
+{
+  return get_fix_array(item_size, get_int(len));
+}
+
+int is_empty()
+{
+  return (index == strlen(buffer));
+}
+	       
+#if 0
+
+constant FIELD_int = 1;
+constant FIELD_string = 2;
+
+class field
+{
+  string name;  /* Name of field */
+  int type;
+  int len;      /* For integers: length,
+		 * for strings: index to the field that holds the length */
+}
+
+
+
+array(object(field)) description;
+array(function) conversions;
+
+class parser
+{
+  string buffer = "";
+  object info;
+  int field; /* Field being read */
+  object o; /* The object to fill in */
+  object me;
+
+  mapping(int:function(string, object:void)) conversions;
+
+  create(object i)
+  {
+    info = i;
+    o = i->prog();
+    me = this_object();
+  }
+  
+  object|string recv(string data)
+  {
+    buffer += data;
+    while(strlen(buffer) >= info->needed_chars[field])
+    {
+      object err;
+      if (err = info->conversions[field](me))
+	return err;
+      field++;
+      if (field >= sizeof(info->description))
+	return buffer[info->needed_chars[field-1]..];
+    }
+    return 0;
+  }
+}
+
+array compile()
+{
+  conversions = 
+
+
+#endif
diff --git a/lib/modules/Crypto/randomness.pmod.pike b/lib/modules/Crypto/randomness.pmod.pike
new file mode 100644
index 0000000000000000000000000000000000000000..7a9d4d8d10241686d2a03b0d1cc8e31d9b6ccba3
--- /dev/null
+++ b/lib/modules/Crypto/randomness.pmod.pike
@@ -0,0 +1,122 @@
+/* randomness.pmod
+ *
+ * Assorted stronger or weaker randomnumber generators.
+ */
+
+/* These devices tries to collect entropy from the environment.
+ * They differ in behaviour when they run low on entropy, /dev/random
+ * will block if it can't provide enough random bits, while /dev/urandom
+ * will degenerate into a reasonably strong pseudo random generator */
+
+#define RANDOM_DEVICE "/dev/random"
+#define PRANDOM_DEVICE "/dev/urandom"
+
+/* Collect somewhat random data from the environment. Unfortunately,
+ * this is quite system dependent */
+#define PATH  "/usr/sbin:/usr/etc:/usr/bin/:/sbin/:/etc:/bin"
+#define SYSTEM_COMMANDS "rup & ping -s 255.255.255.255 256 30 &" \
+                        "uptime & ps -fel & vmstat -s & iostat -cdDItx &"
+			
+#define PRIVATE
+			
+PRIVATE object global_rc4;
+
+PRIVATE string some_entropy()
+{
+  object parent_pipe, child_pipe;
+
+  parent_pipe = Stdio.File();
+  child_pipe = parent_pipe->pipe();
+  if (!child_pipe)
+    throw( ({ "Crypto.random->popen: couldn't create pipe\n", backtrace() }) );
+
+  if (!fork())
+  { /* Child */
+    catch {
+      object stderr = Stdio.File();
+      object stdin = Stdio.File();
+      
+      destruct(parent_pipe);
+      
+      stderr->open("/dev/null", "w");
+      stderr->dup2(Stdio.File("stderr"));
+      
+      stdin->open("/dev/null", "r");
+      stdin->dup2(Stdio.File("stdin"));
+    
+      child_pipe->dup2(Stdio.File("stdout"));
+      catch(exece("/bin/sh", ({ "-c", SYSTEM_COMMANDS }), ([ "PATH" : PATH ]) ));
+    };
+    exit(17);
+  } else {
+    /* Parent */
+    string res;
+    destruct(child_pipe);
+    res = parent_pipe->read(0x7fffffff);
+    return res;
+  }
+}
+
+class pike_random {
+  string read(int len)
+  {
+    return sprintf("%@c", Array.map(allocate(len), lambda(int dummy)
+				    {
+				      return random(256);
+				    } ));
+  }
+}
+
+class rc4_random {
+  inherit Crypto.rc4 : rc4;
+
+  void create(string secret)
+  {
+    object hash = Crypto.sha();
+    hash->update(secret);
+    
+    rc4::set_encrypt_key(hash->digest());
+  }
+
+  string read(int len)
+  {
+    return rc4::crypt(replace(allocate(len), 0, "\47") * "");
+  }
+}
+
+object reasonably_random()
+{
+  if (file_stat(PRANDOM_DEVICE))
+  {
+    object res = Stdio.File();
+    if (res->open(PRANDOM_DEVICE, "r"))
+      return res;
+  }
+
+  if (global_rc4)
+    return global_rc4;
+  
+  string seed = some_entropy();
+  if (strlen(seed) > 2000)
+    return (global_rc4 = rc4_random(sprintf("%4c%O%s", time(), _memory_usage(), seed)));
+  
+  throw( ({ "Crypto.randomness.reasonably_random: No source found\n", backtrace() }) );
+}
+
+object really_random(int|void may_block)
+{
+  object res;
+  if (may_block && file_stat(RANDOM_DEVICE))
+  {
+    if (res->open(RANDOM_DEVICE, "r"))
+      return res;
+  }
+
+  if (file_stat(PRANDOM_DEVICE))
+  {
+    if (res->open(PRANDOM_DEVICE, "r"))
+      return res;
+  }
+    
+  throw( ({ "Crypto.randomness.really_random: No source found\n", backtrace() }) );
+}