diff --git a/.htaccess b/.htaccess
index c4e32bebaba2adb730c9f368ccdbb239b6456119..73b209cfa859360165b103997ce1e26c3777f9d5 100644
--- a/.htaccess
+++ b/.htaccess
@@ -7,26 +7,30 @@
   ForceType application/x-httpd-php
 </Files>
 
-# Protect .inc files:
-#  .inc files can be read from the web so make sure we keep it 
-#  away from the casual prying eyes.  Especially `config.inc'.
-<Files *.inc>
+# Protect includes-directory:
+<Files *includes>
   order deny,allow
   deny from all
 </Files>
 
-# Protect CVS directories:
-<Files *CVS>
+# Protect modules-directory:
+<Files *modules>
   order deny,allow
   deny from all
 </Files>
 
-# Protect theme directories:
+# Protect themes-directory:
 <Files *themes>
   order deny,allow
   deny from all
 </Files>
 
+# Protect CVS directories:
+<Files *CVS>
+  order deny,allow
+  deny from all
+</Files>
+
 # Customized server error messages:
 ErrorDocument 400 /error.php
 ErrorDocument 402 /error.php
@@ -47,4 +51,3 @@ ErrorDocument 500 /error.php
    php_value session.gc_maxlifetime  2000000
    php_value session.cache_expire    200000
 </IfModule>
-
diff --git a/account.php b/account.php
index 2e4ed875ac7fd66dd9985500b80bf45a89a6ab67..fd755d59c637a111fd9aa0f6e860a4ac9bb37b78 100644
--- a/account.php
+++ b/account.php
@@ -254,7 +254,7 @@ function account_user($uname) {
 
     $result = db_query("SELECT d.* FROM diaries d LEFT JOIN users u ON u.id = d.author WHERE u.userid = '$uname' AND d.timestamp > ". (time() - 1209600) ."  ORDER BY id DESC LIMIT 2");
     while ($diary = db_fetch_object($result)) {
-      $box3 .= "<DL><DT><B>". date("l, F jS", $diary->timestamp) .":</B></DT><DD><P>". check_output($diary->text) ."</P><P>[ <A HREF=\"diary.php?op=view&name=$uname\">more</A> ]</P></DD></DL>\n";
+      $box3 .= "<DL><DT><B>". date("l, F jS", $diary->timestamp) .":</B></DT><DD><P>". check_output($diary->text) ."</P><P>[ <A HREF=\"module.php?mod=diary&op=view&name=$uname\">more</A> ]</P></DD></DL>\n";
       $diaries++;
     }
     
diff --git a/admin.php b/admin.php
index df0478d233ad6b7945855c5dc9cdbaabfdc6e6e4..aa3c3ed71c3be386ea363ffbf6cc38b1284ed44b 100644
--- a/admin.php
+++ b/admin.php
@@ -4,6 +4,7 @@
 if (!$user->id || $user->id > 4) exit();
 
 include "includes/admin.inc";
+include "includes/cron.inc";
 
 // display admin header:
 admin_header();
@@ -17,6 +18,7 @@
     }
     else {
       include_once "modules/$filename.module";
+      if ($module["cron"] && !cron_get($filename)) cron_set($filename, 172800); 
       if ($module["admin"]) $output .= "<A HREF=\"admin.php?mod=$filename\">$filename</A> | ";
     }
   }
diff --git a/cron.php b/cron.php
index ebde1b30b21c08f90f4e20cc614c4bb635fc9766..376792366bbad14b4c1d191393607bf38703395b 100644
--- a/cron.php
+++ b/cron.php
@@ -1,12 +1,7 @@
 <?
 
-include "includes/theme.inc";
 include "includes/cron.inc";
 
-$result = db_query("SELECT * FROM cron");
-
-while ($cron = db_fetch_object($result)) {
-  if (time() - $cron->timestamp > $cron->scheduled) cron_execute($cron);
-}
+cron_run();
 
 ?>
diff --git a/diary.php b/diary.php
deleted file mode 100644
index 43f1d560088fdc542666c987e00daf809b225077..0000000000000000000000000000000000000000
--- a/diary.php
+++ /dev/null
@@ -1,186 +0,0 @@
-<?
-
-include "includes/theme.inc";
-
-function diary_overview($num = 20) {
-  global $theme, $user;
-
-  $result = db_query("SELECT d.*, u.userid FROM diaries d LEFT JOIN users u ON d.author = u.id ORDER BY d.timestamp DESC LIMIT $num");
-
-  $output .= "<P>This part of the website is dedicated to providing easy to write and easy to read online diaries or journals filled with daily thoughts, poetry, boneless blather, spiritual theories, intimate details, valuable experiences, cynical rants, semi-coherent comments, writing experiments, artistic babblings, critics on actuality, fresh insights, diverse dreams, chronicles and general madness available for general human consumption.</P>";
-
-  while ($diary = db_fetch_object($result)) {
-    if ($time != date("F jS", $diary->timestamp)) {
-      $output .= "<B>". date("l, F jS", $diary->timestamp) ."</B>\n";
-      $time = date("F jS", $diary->timestamp);
-    }
-    $output .= "<DL>\n";
-    $output .= " <DD><P><B>$diary->userid wrote:</B></P></DD>\n";
-    $output .= " <DL>\n";
-    $output .= "  <DD><P>". check_output($diary->text, 1) ."</P><P>[ <A HREF=\"diary.php?op=view&name=$diary->userid\">more</A> ]</P></DD>\n";
-    $output .= " </DL>\n";
-    $output .= "</DL>\n";
-  }
-
-  $theme->header();
-  $theme->box("Online diary", $output);
-  $theme->footer();
-
-}
-
-function diary_entry($timestamp, $text, $id = 0) {
-  if ($id) {
-    $output .= "<DL>\n";
-    $output .= " <DT><B>". date("l, F jS", $timestamp) .":</B> </DT>\n";
-    $output .= " <DD><P>[ <A HREF=\"diary.php?op=edit&id=$id\">edit</A> ]</P><P>". check_output($text, 1) ."</P></DD>\n";
-    $output .= "</DL>\n";
-  }
-  else {
-    $output .= "<DL>\n";
-    $output .= " <DT><B>". date("l, F jS", $timestamp) .":</B></DT>\n";
-    $output .= " <DD><P>". check_output($text, 1) ."</P></DD>\n";
-    $output .= "</DL>\n";
-  }
-  return $output;
-}
-
-function diary_display($username) {
-  global $theme, $user;
-
-  $result = db_query("SELECT d.*, u.userid FROM diaries d LEFT JOIN users u ON d.author = u.id WHERE u.userid = '$username' ORDER BY timestamp DESC");
-
-  if ($username == $user->userid) {
-    $output .= diary_entry(time(), "<BIG><A HREF=\"diary.php?op=add\">Add new diary entry!</A></BIG><P>");
-    while ($diary = db_fetch_object($result)) $output .= diary_entry($diary->timestamp, $diary->text, $diary->id);
-  }
-  else {
-    $output .= "<P>". format_username($username) ."'s diary:</P>\n";
-    while ($diary = db_fetch_object($result)) $output .= diary_entry($diary->timestamp, $diary->text);
-  }
-
-  $theme->header();
-  $theme->box("$username's online diary", $output);
-  $theme->footer();
-}
-
-function diary_add() {
-  global $theme, $user, $allowed_html;
-  
-  $output .= "<FORM ACTION=\"diary.php\" METHOD=\"post\">\n";
-
-  $output .= "<P>\n"; 
-  $output .= " <B>Enter new diary entry:</B><BR>\n";
-  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\" MAXLENGTH=\"20\"></TEXTAREA><BR>\n";
-  $output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
-  $output .= "</P>\n";
-
-  $output .= "<P>\n";
-  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview diary entry\">\n";
-  $output .= "</P>\n";
-
-  $output .= "</FORM>\n";
-  
-  $theme->header();
-  $theme->box("Online diary", $output);
-  $theme->footer();
-}
-
-function diary_edit($id) {
-  global $theme, $user, $allowed_html;
-
-  $result = db_query("SELECT * FROM diaries WHERE id = $id");
-  $diary = db_fetch_object($result);
-
-  $output .= diary_entry($diary->timestamp, $diary->text);
-
-  $output .= "<FORM ACTION=\"diary.php\" METHOD=\"post\">\n";
-
-  $output .= "<P>\n";
-  $output .= " <B>Edit diary entry:</B><BR>\n";
-  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_input($diary->text) ."</TEXTAREA><BR>\n";
-  $output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
-  $output .= "</P>\n";
-
-  $output .= "<P>\n";
-  $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$diary->id\">\n";
-  $output .= " <INPUT TYPE=\"hidden\" NAME=\"timestamp\" VALUE=\"$diary->timestamp\">\n";
-  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview diary entry\"> <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Submit diary entry\">\n";
-  $output .= "</P>\n";
-
-  $output .= "</FORM>\n";
-  
-  $theme->header();
-  $theme->box("Online diary", $output);
-  $theme->footer();
-}
-
-function diary_preview($text, $timestamp, $id = 0) {
-  global $theme, $user, $allowed_html;
-
-  $output .= diary_entry($timestamp, $text);
-
-  $output .= "<FORM ACTION=\"diary.php\" METHOD=\"post\">\n";
-
-  $output .= "<P>\n";
-  $output .= " <B>Preview diary entry:</B><BR>\n";
-  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_output($text) ."</TEXTAREA><BR>\n";
-  $output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
-  $output .= "</P>\n";
-
-  $output .= "<P>\n";
-  $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$id\">\n";
-  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview diary entry\">\n";
-  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Submit diary entry\">\n";
-  $output .= "</P>\n";
-
-  $output .= "</FORM>\n";
-
-  $theme->header();
-  $theme->box("Online diary", $output);
-  $theme->footer();
-}
-
-function diary_submit($text, $id = 0) {
-  global $user, $theme;
-
-  if ($id) {
-    watchdog("message", "old diary entry updated");
-    db_query("UPDATE diaries SET text =  '". check_input($text) ."' WHERE id = $id");
-  }
-  else {
-    watchdog("diary", "new diary entry added");
-    db_query("INSERT INTO diaries (author, text, timestamp) VALUES ('$user->id', '". check_input($text) ."', '". time() ."')");
-  }
-
-  header("Location: diary.php?op=view&name=$user->userid");
-}
-
-### Security check:
-if (strstr($id, " ") || strstr($name, " ")) {
-  watchdog("error", "diary: attempt to provide malicious input through URI");
-  exit();
-}
-
-switch($op) {
-  case "add":
-    diary_add();
-    break;
-  case "edit":
-    diary_edit($id);
-    break;
-  case "view":
-    diary_display($name);
-    break;
-  case "Preview diary entry":
-    if ($id) diary_preview($text, $timestamp, $id);
-    else diary_preview($text, time());
-    break;
-  case "Submit diary entry":
-    if ($id) diary_submit($text, $id);
-    else diary_submit($text);
-    break;
-  default:
-    diary_overview();
-}
-
-?>
diff --git a/error.php b/error.php
index cae1a1a6f00904fa8ecf531f40d94da884d78bea..c75e55edb15bb0577c4992bd124e5e459e388aaa 100644
--- a/error.php
+++ b/error.php
@@ -7,7 +7,7 @@ function error_flood() {
 } 
 
 function error_httpd() {
-  global $REDIRECT_STATUS, $REDIRECT_URL, $HTTP_REFERER;
+  global $REDIRECT_STATUS, $REDIRECT_URL, $HTTP_REFERER, $HTTP_USER_AGENT;
 
   switch($REDIRECT_STATUS) {
     case 500:
@@ -29,7 +29,7 @@ function error_httpd() {
       $message = "unknown error";
   }
 
-  watchdog("error", "message: `$message' - requested url: $REDIRECT_URL - referring url: $HTTP_REFERER");
+  watchdog("error", "message: `$message' - requested url: $REDIRECT_URL - referring url: $HTTP_REFERER - user agent: $HTTP_USER_AGENT");
  
   print "<PRE>\n";
   print "<H1>Oops, an error occured!</H1>\n";
diff --git a/includes/calendar.inc b/includes/calendar.inc
deleted file mode 100644
index 3748c36997eb0ed9ecb3a6be150719215b6f3d82..0000000000000000000000000000000000000000
--- a/includes/calendar.inc
+++ /dev/null
@@ -1,76 +0,0 @@
-<?
-
-class Calendar {
-  var $date;
-
-  function calendar($date) {
-    $this->date = $date;
-  }
-
-  function display() {
-    global $PHP_SELF;
-
-    ### Extract information from the given date:
-    $month  = date("n", $this->date);
-    $year = date("Y", $this->date);
-    $day = date("d", $this->date);
-
-    ### Extract first day of the month:
-    $first = date("w", mktime(0, 0, 0, $month, 1, $year));
-        
-    ### Extract last day of the month:
-    $last = date("t", mktime(0, 0, 0, $month, 1, $year));
-
-    ### Calculate previous and next months dates:
-    $prev = mktime(0, 0, 0, $month - 1, $day, $year);
-    $next = mktime(0, 0, 0, $month + 1, $day, $year);
-
-    ### Generate calendar header:
-    $output .= "\n<!-- calendar -->\n";
-    $output .= "<TABLE WIDTH=\"100%\" BORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"1\">\n";
-    $output .= " <TR><TD ALIGN=\"center\" COLSPAN=\"7\"><SMALL><A HREF=\"$PHP_SELF?date=$prev\">&lt;</A> &nbsp; ". date("F Y", $this->date) ." &nbsp; <A HREF=\"$PHP_SELF?date=$next\">&gt;</A></SMALL></TD></TR>\n";
-    $output .= " <TR><TD ALIGN=\"center\"><SMALL>S</SMALL></TD><TD ALIGN=\"center\"><SMALL>M</SMALL></TD><TD ALIGN=\"center\"><SMALL>T</SMALL></TD><TD ALIGN=\"center\"><SMALL>W</SMALL></TD><TD ALIGN=\"center\"><SMALL>T</SMALL></TD><TD ALIGN=\"center\"><SMALL>F</SMALL></TD><TD ALIGN=\"center\"><SMALL>S</SMALL></TD></TR>\n";
- 
-    ### Initialize temporary variables:
-    $nday = 1;
-    $sday = $first;
-   
-    ### Loop through all the days of the month:
-    while ($nday <= $last) {
-      ### Set up blank days for first week of the month:
-      if ($first) {
-        $output .= " <TR><TD COLSPAN=\"$first\">&nbsp</TD>\n";
-        $first = 0;
-      }
-        
-      ### Start every week on a new line:
-      if ($sday == 0) $output .=  " <TR>\n";
-    
-      ### Print one cell:
-      $date = mktime(24, 0, 0, $month, $nday, $year);
-      if ($nday == $day) $output .= "  <TD ALIGN=\"center\"><SMALL><B>$nday</B></SMALL></TD>\n";
-      else if ($date > time()) $output .= "  <TD ALIGN=\"center\"><SMALL>$nday</SMALL></TD>\n";
-      else $output .= "  <TD ALIGN=\"center\"><SMALL><A HREF=\"$PHP_SELF?date=$date\" STYLE=\"text-decoration: none;\">$nday</A></SMALL></TD>\n";
-     
-      ### Start every week on a new line:
-      if ($sday == 6) $output .=  " </TR>\n";
-        
-      ### Update temporary variables:
-      $sday++;
-      $sday = $sday % 7;
-      $nday++;
-    }
-    
-    ### Complete the calendar:
-    if ($sday) {
-      $end = 7 - $sday;
-      $output .= "  <TD COLSPAN=\"$end\">&nbsp;</TD>\n </TR>\n";
-    }
-    $output .= "</TABLE>\n\n";
-
-    ### Return calendar:
-    return $output;
-  }
-}
-
-?>
diff --git a/includes/cron.inc b/includes/cron.inc
index 59ff0a07cd32e8bfd531efd8d16e3d292302f073..4cfb74fb866ddd5f3b1868c4df1172ade62fd7d4 100644
--- a/includes/cron.inc
+++ b/includes/cron.inc
@@ -1,24 +1,41 @@
 <?
 
-function cron_add($name, $help, $code, $scheduled, $message = "") {
-  if (empty($name) || empty($code) || empty($scheduled)) {
+include "includes/theme.inc";
+
+function cron_set($module, $scheduled, $message = "") {
+  if (empty($module) || empty($scheduled)) {
     $message = "failed: information missing";
   }
+  else if (db_fetch_object(db_query("SELECT * FROM cron WHERE module = '$module'"))) {
+    db_query("UPDATE cron SET scheduled = $scheduled WHERE module = '$module'");
+  }
   else {
-    $result = db_query("INSERT INTO cron (name, help, code, scheduled) VALUES ('". check_input($name) ."', '". check_input($help) ."', '". check_code($code) ."', '". check_input($scheduled) ."')");
+    db_query("INSERT INTO cron (module, scheduled, timestamp) VALUES ('". check_input($module) ."', '". check_input($scheduled) ."', '42')");
   } 
 }
 
-function cron_delete($id) {
-  $result = db_query("DELETE FROM cron WHERE id = $id");
+function cron_get($module) {
+  return db_fetch_object(db_query("SELECT * FROM cron WHERE module = '$module'"), 0);
+}
+
+function cron_delete($module) {
+  $result = db_query("DELETE FROM cron WHERE module = '$module'");
 }
 
-function cron_execute($cron) {
-  eval($cron->code);
+function cron_run($cron) {
+  $time = time();
   
-  db_query("UPDATE cron SET timestamp = '". time() ."' WHERE id = $cron->id");
+  $result = db_query("SELECT * FROM cron WHERE $time - timestamp > scheduled");
+
+  while ($task = db_fetch_object($result)) {
+    include "modules/". $task->module .".module";
+    if ($function = $module["cron"]) {
+      watchdog("message", "cron: executed '". $task->module ."_cron()'"); 
+      $function();
+    }
+  }
 
-  watchdog("message", "cron: executed '$cron->name'"); 
+  db_query("UPDATE cron SET timestamp = $time WHERE $time - timestamp > scheduled");
 }
 
 ?>
diff --git a/includes/function.inc b/includes/function.inc
index 7c1afc7aed45aa05f7e9a0a38fb7979c0c9dd3bc..87fb0ee37abb8c5656ff4183b03162bdc82ab0ba 100644
--- a/includes/function.inc
+++ b/includes/function.inc
@@ -61,6 +61,25 @@ function format_plural($count, $singular, $plural) {
   return ($count == 1) ? "$count $singular" : "$count $plural";
 }
 
+function format_interval($timestamp) {
+  if ($timestamp > 86400) {
+    $output .= format_plural(floor($timestamp / 86400), "day ", "days ");
+    $timestamp = $timestamp % 86400;
+  }
+  if ($timestamp > 3600) {
+    $output .= format_plural(floor($timestamp / 3600), "hour ", "hours ");
+    $timestamp = $timestamp % 3600;
+  }
+  if ($timestamp > 60) {
+    $output .= floor($timestamp / 60) ." min ";
+    $timestamp = $timestamp % 60;
+  }
+  if ($timestamp > 0) {
+    $output .= floor($timestamp / 86400) ." sec";
+  }
+  return $output;
+}
+
 function format_date($timestamp, $type = "medium") {
   global $user;
 
diff --git a/includes/config.inc b/includes/hostname.conf
similarity index 85%
rename from includes/config.inc
rename to includes/hostname.conf
index 87726021f57463f9cfa998e2c599c547c1e11724..3afc805172c6a52765ebecd664bd353ce3dd85fc 100644
--- a/includes/config.inc
+++ b/includes/hostname.conf
@@ -4,23 +4,12 @@
 # Database settings:
 #
 
-### host: "http://www.drop.org/":
-$db_host = "zind.net";
-$db_name = "droporg";
-$db_pass = "DropIes";
-$db_name = "droporg";
-
-### host: "http://beta.drop.org/":
-#$db_host = "zind.net";
-#$db_name = "dries";
-#$db_pass = "Abc123";
-#$db_name = "dries";
-
 ### host: "http://localhost/":
-#$db_host = "localhost";
-#$db_name = "drop";
-#$db_pass = "drop";
-#$db_name = "drop";
+$db_host = "localhost";
+$db_name = "name";
+$db_pass = "pass";
+$db_name = "name";
+
 
 #
 # Administrative information
@@ -37,7 +26,6 @@
 #   represent the mathematical calculation to be performed 
 #   to update a comment's value.
 #
-
 $comment_votes = array("none" => "none", 
                        "-1"   => "- 1", 
                        "0"    => "+ 0",
@@ -78,18 +66,15 @@
 #   the first theme listed in this associative array will
 #   automatically become the default theme.
 #
-$themes = array("Marvin"  => array(
+$themes = array("UnConeD" => array(
+		   "themes/unconed/unconed.theme",
+		   "modern theme, gray and blue, high coolness factor"),
+                "Marvin"  => array(
                    "themes/marvin/marvin.theme", 
                    "classic theme, white, basic design with a fresh look"),
                 "Zaphod"  => array(
                    "themes/zaphod/zaphod.theme", 
-                   "classic theme, yellow, structured, advanced navigation"),
-                "Trillian"  => array(
-                   "themes/trillian/trillian.theme", 
-                   "simple, easy, black background"),
-		"UnConeD" => array(
-		   "themes/unconed/unconed.theme",
-		   "modern theme, gray and blue, high coolness factor"));
+                   "classic theme, yellow, structured, advanced navigation"));
 
 #
 # Submission moderation votes:
@@ -112,7 +97,7 @@
 #   story is pushed over the threshold and up it goes on the public 
 #   page.  On the other hand, when too many people voted to drop a 
 #   story, the story will get trashed.
-$submission_post_threshold = "3";
+$submission_post_threshold = "5";
 $submission_dump_threshold = "-2";
 
 #
diff --git a/includes/widget.inc b/includes/widget.inc
index b5891a57ea2e05374a5c3ce1c6a5b8a36c78355d..2ea57a2469ed28d1d1b72ccdd303c5d0d4c4afde 100644
--- a/includes/widget.inc
+++ b/includes/widget.inc
@@ -80,9 +80,9 @@ function display_new_diaries($theme, $num = 20) {
       $content .= "<P><B>". date("l, M jS", $diary->timestamp) ."</B></P>\n";
       $time = date("F jS", $diary->timestamp);
     }
-    $content .= "<LI><A HREF=\"diary.php?op=view&name=$diary->userid\">$diary->userid</A></LI>\n";
+    $content .= "<LI><A HREF=\"module.php?mod=diary&op=view&name=$diary->userid\">$diary->userid</A></LI>\n";
   }
-  $content .= "<P ALIGN=\"right\">[ <A HREF=\"diary.php\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>";
+  $content .= "<P ALIGN=\"right\">[ <A HREF=\"module.php?mod=diary\"><FONT COLOR=\"$theme->hlcolor2\">more</FONT></A> ]</P>";
   $theme->box("Recent diary entries", $content);
 }
 
@@ -96,12 +96,6 @@ function display_new_headlines($theme, $num = 10) {
   $theme->box("Latest headlines", $content);
 }
 
-function display_calendar($theme, $date) {
-  include "includes/calendar.inc";
-  $calendar = new Calendar($date);
-  $theme->box("Browse archives", $calendar->display());
-}
-
 function display_account($theme) {
   global $user, $site_name;
   
diff --git a/modules/account.module b/modules/account.module
index 7169da5ff7ce8b5adda712b4aab61554d4e54647..11f69fb16a51b37f586d5f1e9d2474fbf29cbb67 100644
--- a/modules/account.module
+++ b/modules/account.module
@@ -1,6 +1,11 @@
 <?
 
-$module = array("admin" => "account_admin");
+$module = array("cron"  => "account_cron",
+                "admin" => "account_admin");
+
+function account_cron() {
+  // clean-up user database
+}
 
 function account_display($order = "username") {
   $sort = array("ID" => "id", "fake e-mail address" => "fake_email", "homepage" => "url", "hostname" => "last_host", "last access date" => "last_access", "real e-mail address" => "real_email", "real name" => "name", "status" => "status", "theme" => "theme", "timezone" => "timezone", "username" => "userid");
@@ -122,4 +127,4 @@ function account_admin() {
   }
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/modules/backend.module b/modules/backend.module
index 003619e58c33cdca2e8574da78c330712ee3e1c6..43a2211a6ef6821ff574cc20b712fa33bf5b8fbd 100644
--- a/modules/backend.module
+++ b/modules/backend.module
@@ -1,6 +1,7 @@
 <?
 
 $module = array("page"  => "backend_page",
+                "cron"  => "backend_cron",
                 "admin" => "backend_admin");
 
 include "includes/theme.inc";
@@ -42,6 +43,9 @@ function backend_page() {
   $theme->footer();
 }
 
+function backend_cron() {
+  // update backends
+}
 
 function backend_admin_main() {
   global $theme;
@@ -50,7 +54,7 @@ function backend_admin_main() {
   $result = db_query("SELECT * FROM channel ORDER BY id");
 
   $output .= "<TABLE BORDER=\"1\" CELLSPADDING=\"2\" CELLSPACING=\"2\">\n";
-  $output .= " <TH>Site</TH><TH>Contact</TH><TH>Last updated</TH><TH COLSPAN=\"2\">Operations</TH></TR>\n";
+  $output .= " <TH>site</TH><TH>contact</TH><TH>last updated</TH><TH COLSPAN=\"2\">operations</TH></TR>\n";
 
   while ($channel = db_fetch_object($result)) {
     // Load backend from database:
diff --git a/modules/cron.module b/modules/cron.module
index b54b1fdcbe37399bfae4c57cc95475e0c60440fe..b242388dbed39168f5c416b88c47f3863c2606ed 100644
--- a/modules/cron.module
+++ b/modules/cron.module
@@ -2,23 +2,37 @@
 
 $module = array("admin" => "cron_admin");
 
-function cron_admin() {
+include_once "includes/function.inc";
+
+
+function cron_reset($name) {
+  cron_delete($name);
+}
+
+function cron_display() {
   // Perform query:
   $result = db_query("SELECT * FROM cron");
  
   // Generate output:
+  $output .= "<TABLE BORDER=\"1\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
+  $output .= " <TR><TH>module</TH><TH>interval</TH><TH>last exection</TH><TH COLSPAN=\"2\">operations</TH></TR>\n";
   while ($cron = db_fetch_object($result)) {
-    $output .= "<TABLE BORDER=\"1\" CELLPADDING=\"2\" CELLSPACING=\"2\">\n";
-    $output .= " <TR><TH VALIGN=\"top\">Name:</TH><TD>". check_output($cron->name) ."</TD></TR>\n";
-    $output .= " <TR><TH VALIGN=\"top\">Help:</TH><TD>". check_output($cron->help) ."</TD></TR>\n";
-    $output .= " <TR><TH VALIGN=\"top\">Code:</TH><TD><CODE>". nl2br($cron->code) ."</CODE></TD></TR>\n";
-    $output .= " <TR><TH VALIGN=\"top\">Last run:</TH><TD>". format_date($cron->timestamp) ."</TD></TR>\n";
-    $output .= " <TR><TH VALIGN=\"top\">Scheduled:</TH><TD>every $cron->scheduled seconds</TD></TR>\n";
-    $output .= "</TABLE>\n";
-    $output .= "<BR><BR>\n";
+    $output .= " <TR><TD>". check_output($cron->module) ."</TD><TD>every ". format_interval($cron->scheduled) ."</TD><TD>". format_interval(time() - $cron->timestamp) ." ago</TD><TD ALIGN=\"center\"><A HREF=\"cron.php\">execute</A></TD><TD><A HREF=\"admin.php?mod=cron&op=reset&name=$cron->module\">reset</A></TD></TR>\n";
   }
-
+  $output .= "</TABLE>\n";
   print $output;
 }
 
+function cron_admin() {
+  global $op, $name;
+
+  switch($op) {
+    case "reset":
+      cron_reset($name);
+      break;
+  }
+  
+  cron_display();
+}
+
 ?>
diff --git a/modules/diary.module b/modules/diary.module
index da92e746d2d76b9a21b324e57d03e271c0ed7db5..92c97d5f37b757b28e1ea1c59c23aa4a483c8e16 100644
--- a/modules/diary.module
+++ b/modules/diary.module
@@ -1,6 +1,197 @@
 <?
 
-function diary_edit($id) {
+$module = array("page"  => "diary_page",
+                "admin" => "diary_admin");
+
+
+include "includes/theme.inc";
+
+function diary_page_overview($num = 20) {
+  global $theme, $user;
+
+  $result = db_query("SELECT d.*, u.userid FROM diaries d LEFT JOIN users u ON d.author = u.id ORDER BY d.timestamp DESC LIMIT $num");
+
+  $output .= "<P>This part of the website is dedicated to providing easy to write and easy to read online diaries or journals filled with daily thoughts, poetry, boneless blather, spiritual theories, intimate details, valuable experiences, cynical rants, semi-coherent comments, writing experiments, artistic babblings, critics on actuality, fresh insights, diverse dreams, chronicles and general madness available for general human consumption.</P>";
+
+  while ($diary = db_fetch_object($result)) {
+    if ($time != date("F jS", $diary->timestamp)) {
+      $output .= "<B>". date("l, F jS", $diary->timestamp) ."</B>\n";
+      $time = date("F jS", $diary->timestamp);
+    }
+    $output .= "<DL>\n";
+    $output .= " <DD><P><B>$diary->userid wrote:</B></P></DD>\n";
+    $output .= " <DL>\n";
+    $output .= "  <DD><P>". check_output($diary->text, 1) ."</P><P>[ <A HREF=\"module.php?mod=diary&op=view&name=$diary->userid\">more</A> ]</P></DD>\n";
+    $output .= " </DL>\n";
+    $output .= "</DL>\n";
+  }
+
+  $theme->header();
+  $theme->box("Online diary", $output);
+  $theme->footer();
+
+}
+
+function diary_page_entry($timestamp, $text, $id = 0) {
+  if ($id) {
+    $output .= "<DL>\n";
+    $output .= " <DT><B>". date("l, F jS", $timestamp) .":</B> </DT>\n";
+    $output .= " <DD><P>[ <A HREF=\"module.php?mod=diary&op=edit&id=$id\">edit</A> ]</P><P>". check_output($text, 1) ."</P></DD>\n";
+    $output .= "</DL>\n";
+  }
+  else {
+    $output .= "<DL>\n";
+    $output .= " <DT><B>". date("l, F jS", $timestamp) .":</B></DT>\n";
+    $output .= " <DD><P>". check_output($text, 1) ."</P></DD>\n";
+    $output .= "</DL>\n";
+  }
+  return $output;
+}
+
+function diary_page_display($username) {
+  global $theme, $user;
+
+  $result = db_query("SELECT d.*, u.userid FROM diaries d LEFT JOIN users u ON d.author = u.id WHERE u.userid = '$username' ORDER BY timestamp DESC");
+
+  if ($username == $user->userid) {
+    $output .= diary_page_entry(time(), "<BIG><A HREF=\"module.php?mod=diary&op=add\">Add new diary entry!</A></BIG><P>");
+    while ($diary = db_fetch_object($result)) $output .= diary_page_entry($diary->timestamp, $diary->text, $diary->id);
+  }
+  else {
+    $output .= "<P>". format_username($username) ."'s diary:</P>\n";
+    while ($diary = db_fetch_object($result)) $output .= diary_page_entry($diary->timestamp, $diary->text);
+  }
+
+  $theme->header();
+  $theme->box("$username's online diary", $output);
+  $theme->footer();
+}
+
+function diary_page_add() {
+  global $theme, $user, $allowed_html;
+  
+  $output .= "<FORM ACTION=\"module.php?mod=diary\" METHOD=\"post\">\n";
+
+  $output .= "<P>\n"; 
+  $output .= " <B>Enter new diary entry:</B><BR>\n";
+  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\" MAXLENGTH=\"20\"></TEXTAREA><BR>\n";
+  $output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
+  $output .= "</P>\n";
+
+  $output .= "<P>\n";
+  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview diary entry\">\n";
+  $output .= "</P>\n";
+
+  $output .= "</FORM>\n";
+  
+  $theme->header();
+  $theme->box("Online diary", $output);
+  $theme->footer();
+}
+
+function diary_page_edit($id) {
+  global $theme, $user, $allowed_html;
+
+  $result = db_query("SELECT * FROM diaries WHERE id = $id");
+  $diary = db_fetch_object($result);
+
+  $output .= diary_page_entry($diary->timestamp, $diary->text);
+
+  $output .= "<FORM ACTION=\"module.php?mod=diary\" METHOD=\"post\">\n";
+
+  $output .= "<P>\n";
+  $output .= " <B>Edit diary entry:</B><BR>\n";
+  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_input($diary->text) ."</TEXTAREA><BR>\n";
+  $output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
+  $output .= "</P>\n";
+
+  $output .= "<P>\n";
+  $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$diary->id\">\n";
+  $output .= " <INPUT TYPE=\"hidden\" NAME=\"timestamp\" VALUE=\"$diary->timestamp\">\n";
+  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview diary entry\"> <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Submit diary entry\">\n";
+  $output .= "</P>\n";
+
+  $output .= "</FORM>\n";
+  
+  $theme->header();
+  $theme->box("Online diary", $output);
+  $theme->footer();
+}
+
+function diary_page_preview($text, $timestamp, $id = 0) {
+  global $theme, $user, $allowed_html;
+
+  $output .= diary_page_entry($timestamp, $text);
+
+  $output .= "<FORM ACTION=\"module.php?mod=diary\" METHOD=\"post\">\n";
+
+  $output .= "<P>\n";
+  $output .= " <B>Preview diary entry:</B><BR>\n";
+  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_output($text) ."</TEXTAREA><BR>\n";
+  $output .= " <SMALL><I>Allowed HTML tags: ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
+  $output .= "</P>\n";
+
+  $output .= "<P>\n";
+  $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$id\">\n";
+  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Preview diary entry\">\n";
+  $output .= " <INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Submit diary entry\">\n";
+  $output .= "</P>\n";
+
+  $output .= "</FORM>\n";
+
+  $theme->header();
+  $theme->box("Online diary", $output);
+  $theme->footer();
+}
+
+function diary_page_submit($text, $id = 0) {
+  global $user, $theme;
+
+  if ($id) {
+    watchdog("message", "old diary entry updated");
+    db_query("UPDATE diaries SET text =  '". check_input($text) ."' WHERE id = $id");
+  }
+  else {
+    watchdog("diary", "new diary entry added");
+    db_query("INSERT INTO diaries (author, text, timestamp) VALUES ('$user->id', '". check_input($text) ."', '". time() ."')");
+  }
+
+  header("Location: module.php?mod=diary&op=view&name=$user->userid");
+}
+
+function diary_page() {
+  global $op, $id, $name, $text, $timestamp;
+
+  // Security check:
+  if (strstr($id, " ") || strstr($name, " ")) {
+    watchdog("error", "diary: attempt to provide malicious input through URI");
+    exit();
+  }
+
+  switch($op) {
+    case "add":
+      diary_page_add();
+      break;
+   case "edit":
+      diary_page_edit($id);
+      break;
+    case "view":
+      diary_page_display($name);
+      break;
+    case "Preview diary entry":
+      if ($id) diary_page_preview($text, $timestamp, $id);
+      else diary_page_preview($text, time());
+      break;
+    case "Submit diary entry":
+      if ($id) diary_page_submit($text, $id);
+      else diary_page_submit($text);
+      break;
+    default:
+      diary_page_overview();
+  }
+}
+
+function diary_admin_edit($id) {
   $result = db_query("SELECT d.*, u.userid FROM diaries d LEFT JOIN users u ON d.author = u.id WHERE d.id = $id");
 
   $diary = db_fetch_object($result);
@@ -25,12 +216,12 @@ function diary_edit($id) {
   print $output;
 }
 
-function diary_save($id, $text) {
+function diary_admin_save($id, $text) {
   db_query("UPDATE diaries SET text = '". check_input($text) ."' WHERE id = $id");
   watchdog("message", "modified diary entry #$id.");
 }
 
-function diary_display($order = "date") {
+function diary_admin_display($order = "date") {
   // Initialize variables:
   $fields = array("author" => "author", "date" => "timestamp DESC");
 
@@ -59,7 +250,7 @@ function diary_display($order = "date") {
   $output .= " </TR>\n";
 
   while ($diary = db_fetch_object($result)) {
-    $output .= " <TR><TD><A HREF=\"diary.php?op=view&name=$diary->userid\">$diary->userid on ". format_date($diary->date, "small") ."</A></TD><TD>". format_username($diary->userid, 1) ."</TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=diary&op=edit&id=$diary->id\">edit</A></TD></TR>\n";
+    $output .= " <TR><TD><A HREF=\"module.php?mod=diary&op=view&name=$diary->userid\">$diary->userid on ". format_date($diary->date, "small") ."</A></TD><TD>". format_username($diary->userid, 1) ."</TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=diary&op=edit&id=$diary->id\">edit</A></TD></TR>\n";
   }
 
   $output .= "</TABLE>\n";
@@ -73,17 +264,17 @@ function diary_admin() {
  
   switch ($op) {
     case "edit":
-      diary_edit($id);
+      diary_admin_edit($id);
       break;
     case "Save diary entry":
-      diary_save($id, $text);
-      diary_edit($id);
+      diary_admin_save($id, $text);
+      diary_admin_edit($id);
       break;
     case "Update":
-      diary_display($order);
+      diary_admin_display($order);
       break;
     default:
-      diary_display();
+      diary_admin_display();
   }
 }
 
diff --git a/modules/documentation.module b/modules/documentation.module
index a72f2609b0236c4810c8403407f3f45c3050adca..268e49347ba84db703d8334b185a8e0a774995ab 100644
--- a/modules/documentation.module
+++ b/modules/documentation.module
@@ -32,7 +32,7 @@ function documentation_page() {
    -rw-rw-r--    1 drop    drop        includes/www.yourdomain1.com.conf
    -rw-rw-r--    1 drop    drop        includes/www.yourdomain2.com.conf
   </PRE>
-  <P>The only thing left to be done is to setup the corresponding vhosts in your Apache configuration file.  Note that the <CODE>DocumentRoot</CODE> points to the same source tree:</P>
+  <P>The only thing left to be done is to setup the corresponding vhosts in your Apache configuration file.  Note that the <CODE>DocumentRoot</CODE> points to the same source tree twice:</P>
   <PRE>
    NameVirtualHost 127.0.0.1
 
@@ -70,15 +70,15 @@ function documentation_page() {
    </TR>
    <TR>
     <TD VALIGN="top"><CODE>page</CODE></TD>
-    <TD VALIGN="top">If a module requires it's own page, typically exported as <CODE>http://www.yourdomain.com/module.php?mod=module</CODE>, the engine will invoke <CODE>module_page</CODE> to generate a modules page.</TD>
+    <TD VALIGN="top">If a module requires it's own page it should provide a function named <CODE>module_page</CODE>.  The page can then be publicly accessed via <CODE>http://www.yourdomain.com/module.php?mod=module</CODE> which will cause the engine to invoke <CODE>module_page</CODE> in order to generate the module's page.</TD>
    </TR>
    <TR>
-    <TD VALIGN="top"></TD>
-    <TD VALIGN="top"></TD>
+    <TD VALIGN="top"><CODE>cron</CODE></TD>
+    <TD VALIGN="top">Modules that require to schedule some commands to be executed on regular intervals can implement the <CODE>cron</CODE> interface: the engine will then call <CODE>module_cron</CODE> at the appropriate intervals defined by the administrator.  This interface is particulary handy to implement timers or to automate certain tasks like for instance database maintainance, recalculation of settings or parameters, automatic mailings and so on.</TD>
    </TR>
    <TR>
-    <TD VALIGN="top"></TD>
-    <TD VALIGN="top"></TD>
+    <TD VALIGN="top"><CODE>admin</CODE></TD>
+    <TD VALIGN="top">If a module requires a spot in the administrator section it should implement <CODE>module_admin</CODE>.  The engine will automatically add a link to the administration menus and will call <CODE>module_admin</CODE> when this link is followed.  In order to make virtually any module maintainer's life easier, you don't have to worry about access rights or permissions for that matter.  The engine will only allow priveleged users to call exported <CODE>admin</CODE> functions.</TD>
    </TR>
    <TR>
     <TD VALIGN="top"></TD>
@@ -101,7 +101,7 @@ function documentation_page() {
 
   <P>The site can be almost entirely configured through a web interface by using <I>droplets</I>.  Simply put, droplets are small bit of PHP code which will get plugged into the engine or modules powering the site.  Droplets are typically used to link modules with the mainstream engine or to customize various aspects of the engine itself.</P>
   <P>If you know how to script in PHP, droplets are pretty simple to create.  Don't get your panties in a knot if you are not confident with PHP: simply use the standard droplets (i.e. those available by default) as they are just fine or ask an expert dropletber to help you creating custom droplets that fit your need.</P>
-  <P>Each droplet consist of a key of maximum 255 characters and an associated block of PHP code which can be as long as you want it to be.  You can use any piece of PHP code to make up a droplet.  A droplet's code is stored in the database and the engine or a particular module will use the key to find the associated piece of PHP code which will then be dynamically embedded in the engine or the module just-in-time for execution.</P>
+  <P>Each droplet consists of a key of maximum 255 characters and an associated block of PHP code which can be as long as you want it to be.  You can use any piece of PHP code to make up a droplet.  A droplet's code is stored in the database and the engine or a particular module will use the key to find the associated piece of PHP code which will then be dynamically embedded in the engine or the module just-in-time for execution.</P>
   <P>There are however some factors to keep in mind when using and creating droplets: droplets can be extremly useful and flexible, yet be dangerous and insecure if not properly used.  If you are not confident with PHP, SQL or even with the site engine for that matter, avoid experimenting with droplets because you can - and you probably will - corrupt your database or even break your site!</P>
   <P>Remember that the code within each droplet must be valid PHP code, including things like terminating statements with a semicolon so the parser won't die.  Therefore, it is highly recommended to test your droplets seperatly using a simple test script on top of a test database before migrating to your production environment running your real database.</P>
   <P>Note that you can use any global variables, such as configuration parameters within the scope of a droplet and keep in mind that variables that have been given values in a droplet will retain these values in the engine or module afterwards.</P>
@@ -122,7 +122,22 @@ function documentation_page() {
   </PRE>
   <P>For more in depth example, we recommand you to check any of the available modules and to go from there.</P>
   <P>As said above, you can virtually use any piece of PHP code in a droplet: you can declare and use functions, consult the SQL database, access configuration settings and so on.</P>
-  <?
-}
+  
+  <H3>cron</H3>
+ 
+  <P>Cron (wich stands for chronograph) is a periodic command scheduler: it executes commands at intervals specified in seconds.  It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period of n seconds).   Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution.</P>
+  <P>Note that cron does not guarantee that the commands will be executed at the specified interval.  However, the engine will make sure that the commands are run at the specified intervals as closely as possible.</P>
+  <P>When <CODE>http://www.yourdomain.com/cron.php</CODE> is accessed, cron will run: it queries the database for the jobs cron controls, and their periods in seconds.  If a certain task wasn't executed in the last n seconds, where n is the period of that job, it will be executed.  It then records the date in the database so it can know when to run it again.  When all the executed commands terminate, cron is done.</P>
+  <P>Cron is handy to run daily, weekly and monthly tasks that
+take care of various "housekeeping chores" such as database maintainance,
+recalculating settings, periodic mailings, scheduled backups and so on.</P>
+  <P>The recommanded way to setup drop.org's cron job is to setup a real UNIX <CODE>crontab</CODE> that frequently visits <CODE>http://www.yourdomain.com/cron.php</CODE>: the more you visit the <CODE>cron.php</CODE>, the more accurate cron can and will be.  If your hosting company does not allow you to use <CODE>crontab</CODE>, you can always ask someone else to setup a <CODE>crontab</CODE> for you.  Afterall, virtually any host machine with access to the internet can run the <CODE>crontab</CODE> for you.<P>
+  <P>For the <CODE>crontab</CODE>, use a browser like <CODE>lynx</CODE> or <CODE>wget</CODE> but make sure the process terminates: either use <CODE>/usr/bin/lynx -source http://www.yourdomain.com/cron.php</CODE> or <CODE>/usr/bin/wgeti -O /dev/null http://www.yourdomain.com/cron.php</CODE>.  Take a look at the example scripts in the <CODE>scripts</CODE>-directory and make sure to adjust them to your needs.</P>
+  <P>A good <CODE>crontab</CODE>-line to run the <CODE>cron</CODE>-script once every hour would be:</P>
+  <PRE>
+    00 * * * * /home/www/drop/scripts/cron-lynx
+  </PRE>
 
+ <?
+ }
 ?>
diff --git a/modules/watchdog.module b/modules/watchdog.module
index f60e4eaeb4f12c0eb0bea5a5b607e2419145bd5b..1b10f672eea1d4dc6a541d8c2ad2b5c306328465 100644
--- a/modules/watchdog.module
+++ b/modules/watchdog.module
@@ -1,6 +1,11 @@
 <?
 
-$module = array("admin" => "watchdog_admin");
+$module = array("cron" => "watchdog_cron", 
+                "admin" => "watchdog_admin");
+
+function watchdog_cron() {
+  watchdog_clean();
+}
 
 function watchdog_display($order = "date") {
   $colors = array("#D8BFD8", "#6495ED", "#6A5ADF", "#FFFFFF", "#FFA500", "#FF3C3C");
@@ -31,7 +36,7 @@ function watchdog_display($order = "date") {
   $output .= " </TR>\n";
 
   while ($watchdog = db_fetch_object($result)) {
-    $output .= " <TR BGCOLOR=\"". $colors[$watchdog->level] ."\"><TD>". format_date($watchdog->timestamp) ."</TD><TD>". substr(check_output($watchdog->message), 0, 44) ."</TD><TD ALIGN=\"center\">". format_username($watchdog->userid, 1) ."</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=watchdog&op=view&id=$watchdog->id\">more</A></TD></TR>\n";
+    $output .= " <TR BGCOLOR=\"". $colors[$watchdog->level] ."\"><TD>". format_date($watchdog->timestamp) ."</TD><TD>". substr(check_output($watchdog->message), 0, 44) ."</TD><TD ALIGN=\"center\">". format_username($watchdog->userid, 1) ."</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=watchdog&op=view&id=$watchdog->id\">details</A></TD></TR>\n";
   }
 
   $output .= "</TABLE>\n";
diff --git a/modules/watchdog/watchdog.module b/modules/watchdog/watchdog.module
index f60e4eaeb4f12c0eb0bea5a5b607e2419145bd5b..1b10f672eea1d4dc6a541d8c2ad2b5c306328465 100644
--- a/modules/watchdog/watchdog.module
+++ b/modules/watchdog/watchdog.module
@@ -1,6 +1,11 @@
 <?
 
-$module = array("admin" => "watchdog_admin");
+$module = array("cron" => "watchdog_cron", 
+                "admin" => "watchdog_admin");
+
+function watchdog_cron() {
+  watchdog_clean();
+}
 
 function watchdog_display($order = "date") {
   $colors = array("#D8BFD8", "#6495ED", "#6A5ADF", "#FFFFFF", "#FFA500", "#FF3C3C");
@@ -31,7 +36,7 @@ function watchdog_display($order = "date") {
   $output .= " </TR>\n";
 
   while ($watchdog = db_fetch_object($result)) {
-    $output .= " <TR BGCOLOR=\"". $colors[$watchdog->level] ."\"><TD>". format_date($watchdog->timestamp) ."</TD><TD>". substr(check_output($watchdog->message), 0, 44) ."</TD><TD ALIGN=\"center\">". format_username($watchdog->userid, 1) ."</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=watchdog&op=view&id=$watchdog->id\">more</A></TD></TR>\n";
+    $output .= " <TR BGCOLOR=\"". $colors[$watchdog->level] ."\"><TD>". format_date($watchdog->timestamp) ."</TD><TD>". substr(check_output($watchdog->message), 0, 44) ."</TD><TD ALIGN=\"center\">". format_username($watchdog->userid, 1) ."</A></TD><TD ALIGN=\"center\"><A HREF=\"admin.php?mod=watchdog&op=view&id=$watchdog->id\">details</A></TD></TR>\n";
   }
 
   $output .= "</TABLE>\n";
diff --git a/modules/wishlist.module b/modules/wishlist.module
index cef706ccd0e6c920d5500db7d233f0954363b6ca..bbc9e31bdb9ea381a48b8544718b9ab02e4de33b 100644
--- a/modules/wishlist.module
+++ b/modules/wishlist.module
@@ -29,13 +29,6 @@ function wishlist_page() {
     <UL>
      <LI>blocks and flexible block placement strategies by means of "layout managers" (cfr. Java) and tightly integrated with the module support</LI>
      <LI>post/edit hash - magic cookie: to prevent malicious external access and to prevent duplicate posts because of hitting the "reload" button</LI>
-     <LI>cron job emulation:</LI>
-      <UL>
-       <LI>auto. set default theme according to popularity</LI>
-       <LI>auto. database clean-up (e.g. history field)</LI>
-       <LI>auto. recalculate adaptive/dynamic settings like thresholds</LI>
-       <LI>auto. mail digests</LI>
-      </UL>
      <LI>URL validator</LI>
      <LI>more adaptive submission queue</LI>
      <LI>archive function</LI>
@@ -60,6 +53,7 @@ function wishlist_page() {
      <LI>messaging system between users</LI>
      <LI>voting polls</LI>
      <LI>daily/weekly e-mail digest - mailing list</LI>
+     <LI>story overview grouped by category</LI>
      <LI>e-commerce/shop</LI> 
     </UL>
  
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f53798bb4fe33c86020be7f10c44f29486fd190
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/scripts/cron-lynx b/scripts/cron-lynx
new file mode 100644
index 0000000000000000000000000000000000000000..c17666d59690137d2f6d9d0393d8dc9a13f83693
--- /dev/null
+++ b/scripts/cron-lynx
@@ -0,0 +1,2 @@
+#!/bin/sh
+/usr/bin/lynx -source http://drop.org/cron.php > /dev/null 2>&1
diff --git a/submit.php b/submit.php
index 6e45129087697fe5a9f53ffa0c53f6a024fa3985..579f010fac723fa65ba7175789e094bda86a76ed 100644
--- a/submit.php
+++ b/submit.php
@@ -4,7 +4,7 @@ function submit_enter() {
   global $anonymous, $categories, $allowed_html, $theme, $user;
   
   ### Guidlines:
-  $output .= blob_get("submit_information");
+  $output .= droplet_get("submit_information");
 
   ### Submission form:
   $output .= "<FORM ACTION=\"submit.php\" METHOD=\"post\">\n";
@@ -135,7 +135,7 @@ function submit_submit($subject, $abstract, $article, $category) {
   
   ### Display confirmation message:
   $theme->header(); 
-  $theme->box("Thank you for your submission.", blob_get("sumbit_confirmation"));
+  $theme->box("Thank you for your submission.", droplet_get("submit_confirmation"));
   $theme->footer();
 }
 
diff --git a/themes/marvin/marvin.theme b/themes/marvin/marvin.theme
index 0ac8de30a4257ac4f2143372a0602e0be1363e74..076f0083a672694bdcce60c655e7ad31918adf2d 100644
--- a/themes/marvin/marvin.theme
+++ b/themes/marvin/marvin.theme
@@ -46,7 +46,7 @@ function header($title) {
         </TD>
        </TR>
        <TR>
-        <TD ALIGN="right" COLSPAN="2"><SMALL><A HREF="/">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="diary.php">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A></SMALL></TD>
+        <TD ALIGN="right" COLSPAN="2"><SMALL><A HREF="/">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="module.php?mod=diary">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A></SMALL></TD>
        </TR>
        <TR>
         <TD VALIGN="top" WIDTH="100%">
@@ -269,12 +269,9 @@ function footer() {
            ### Display account:
            display_account($this);
          }
-         elseif (strstr($PHP_SELF, "diary.php")) {
+         elseif (strstr($PHP_SELF, "module.php")) {
            ### Display account:
            display_account($this);
- 
-           ### Display new diary entries:
-           display_new_diaries($this);
          }
          elseif (strstr($PHP_SELF, "submission.php")) {
            ### Display account:
@@ -317,7 +314,7 @@ function footer() {
       </TR>
       <TR>
        <TD ALIGN="center" COLSPAN="3">
-        <SMALL>[ <A HREF="/">home</A> | <A HREF="moduled.php?mod=faq">faq</A> | <A HREF="diary.php">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A> ]</SMALL>
+        <SMALL>[ <A HREF="/">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="module.php?mod=diary">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A> ]</SMALL>
        </TD>
       </TR>
      </TABLE>
diff --git a/themes/unconed/unconed.theme b/themes/unconed/unconed.theme
index e6094b486b309723ba75ece0b836f6e17a160e5d..50c3166192b192bc979ffc0700ecb932a04cae32 100644
--- a/themes/unconed/unconed.theme
+++ b/themes/unconed/unconed.theme
@@ -57,7 +57,7 @@ function header($title) {
        </TR>
        <TR>
         <TD COLSPAN="2" ALIGN="CENTER">
-         <TABLE BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BGCOLOR="<? echo $this->brcolor1; ?>"><TR><TD ALIGN="CENTER"><TABLE BORDER="0" WIDTH="100%" CELLSPACING="1" CELLPADDING="4"><TR><TD ALIGN="CENTER" BGCOLOR="<? echo $this->bgcolor2; ?>"><BIG><A HREF="index.php">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="diary.php">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A></BIG></TD></TR></TABLE></TD></TR></TABLE>
+         <TABLE BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BGCOLOR="<? echo $this->brcolor1; ?>"><TR><TD ALIGN="CENTER"><TABLE BORDER="0" WIDTH="100%" CELLSPACING="1" CELLPADDING="4"><TR><TD ALIGN="CENTER" BGCOLOR="<? echo $this->bgcolor2; ?>"><BIG><A HREF="index.php">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="module.php?mod=diary">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A></BIG></TD></TR></TABLE></TD></TR></TABLE>
         </TD>
        </TR>
        <TR><TD COLSPAN="2"><?
@@ -316,7 +316,7 @@ function footer() {
            display_account($this);
 
            ### Display calendar:
-           display_calendar($this, $date);
+           $this->box("Browse archives", droplet_get("calendar"));
 
            ### Display calendar:
            display_old_headlines($this);
@@ -383,7 +383,7 @@ function footer() {
        ?></TD></TR>
       <TR>
        <TD COLSPAN="2">
-        <TABLE BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BGCOLOR="<? echo $this->brcolor1; ?>"><TR><TD ALIGN="CENTER"><TABLE BORDER="0" WIDTH="100%" CELLSPACING="1" CELLPADDING="4"><TR><TD ALIGN="CENTER" BGCOLOR="<? echo $this->bgcolor2; ?>"><BIG><A HREF="index.php">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="diary.php">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A></BIG></TD></TR></TABLE></TD></TR></TABLE>
+        <TABLE BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" BGCOLOR="<? echo $this->brcolor1; ?>"><TR><TD ALIGN="CENTER"><TABLE BORDER="0" WIDTH="100%" CELLSPACING="1" CELLPADDING="4"><TR><TD ALIGN="CENTER" BGCOLOR="<? echo $this->bgcolor2; ?>"><BIG><A HREF="index.php">home</A> | <A HREF="module.php?mod=faq">faq</A> | <A HREF="module.php?mod=diary">diary</A> | <A HREF="search.php">search</A> | <A HREF="submit.php">submit news</A> | <A HREF="account.php">user account</A></BIG></TD></TR></TABLE></TD></TR></TABLE>
        </TD>
       </TR>
      </TABLE>