diff -Naur 711-1516.U007/src/config.h.in 711-1516.U007.sqlite/src/config.h.in
--- 711-1516.U007/src/config.h.in	2005-11-08 20:58:08.000000000 +0100
+++ 711-1516.U007.sqlite/src/config.h.in	2005-11-12 01:50:32.933417636 +0100
@@ -7,6 +7,8 @@
 #ifndef CONFIG_H__
 #define CONFIG_H__ 1
 
+#define USE_SQLITE
+
 /* ----------- Commandline Argument Defaults ----------
  * These options provide default settings for those options which can
  * also be set on the commandline.
diff -Naur 711-1516.U007/src/func_spec 711-1516.U007.sqlite/src/func_spec
--- 711-1516.U007/src/func_spec	2005-11-08 20:58:08.000000000 +0100
+++ 711-1516.U007.sqlite/src/func_spec	2005-11-11 23:51:51.000000000 +0100
@@ -722,6 +722,16 @@
 
 #endif /* USE_PGSQL */
 
+
+#ifdef USE_SQLITE
+
+int      sl_open(string);
+mixed    sl_exec(string, ...);
+int      sl_insert_id();
+void     sl_close();
+
+#endif /* USE_SQLITE */
+
 #ifdef USE_TLS
 
 int     tls_query_connection_state(object default: F_THIS_OBJECT);
diff -Naur 711-1516.U007/src/lex.c 711-1516.U007.sqlite/src/lex.c
--- 711-1516.U007/src/lex.c	2005-11-08 20:58:07.000000000 +0100
+++ 711-1516.U007.sqlite/src/lex.c	2005-11-11 22:26:13.000000000 +0100
@@ -824,6 +824,9 @@
 #ifdef USE_MYSQL
     add_permanent_define("__MYSQL__", -1, string_copy("1"), MY_FALSE);
 #endif
+#ifdef USE_SQLITE
+    add_permanent_define("__SQLITE__", -1, string_copy("1"), MY_FALSE);
+#endif
 #ifdef USE_PGSQL
     add_permanent_define("__PGSQL__", -1, string_copy("1"), MY_FALSE);
 #endif
diff -Naur 711-1516.U007/src/Makefile.in 711-1516.U007.sqlite/src/Makefile.in
--- 711-1516.U007/src/Makefile.in	2005-11-08 20:58:07.000000000 +0100
+++ 711-1516.U007.sqlite/src/Makefile.in	2005-11-12 01:49:59.149728934 +0100
@@ -74,7 +74,7 @@
 #
 CFLAGS= @EXTRA_CFLAGS@ $(OPTIMIZE) $(DEBUG) $(WARN) $(MPATH) $(PROFIL)
 #
-LIBS=@LIBS@ @PKGLIBS@
+LIBS=@LIBS@ @PKGLIBS@ -lsqlite3
 #
 LDFLAGS=$(PROFIL) @LDFLAGS@
 #
@@ -90,7 +90,7 @@
       lex.c main.c mapping.c md5.c mempools.c mregex.c mstrings.c object.c \
       otable.c\
       parser.c parse.c pkg-alists.c pkg-mccp.c pkg-mysql.c pkg-pcre.c \
-      pkg-pgsql.c pkg-tls.c \
+      pkg-pgsql.c pkg-tls.c pkg-sqlite.c \
       ptmalloc.c port.c ptrtable.c \
       random.c regexp.c sha1.c simulate.c simul_efun.c stdstrings.c \
       strfuns.c structs.c sprintf.c swap.c wiz_list.c xalloc.c 
@@ -101,7 +101,7 @@
       lex.o main.o mapping.o md5.o mempools.o mregex.o mstrings.o object.o \
       otable.o \
       parser.o parse.o pkg-alists.o pkg-mccp.o pkg-mysql.o pkg-pcre.o \
-      pkg-pgsql.o pkg-tls.o \
+      pkg-pgsql.o pkg-tls.o pkg-sqlite.o \
       ptmalloc.o port.o ptrtable.o \
       random.o regexp.o sha1.o simulate.o simul_efun.o stdstrings.o \
       strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@ 
diff -Naur 711-1516.U007/src/object.c 711-1516.U007.sqlite/src/object.c
--- 711-1516.U007/src/object.c	2005-11-08 20:58:07.000000000 +0100
+++ 711-1516.U007.sqlite/src/object.c	2005-11-11 22:26:13.000000000 +0100
@@ -43,6 +43,7 @@
  *       wiz_list_t    * user;
  *       wiz_list_t    * eff_user;
  *       int             extra_num_variables;  (ifdef DEBUG)
+ *       int             open_sqlite_db (ifdef USE_SQLITE)
  *       svalue_t      * variables;
  *       unsigned long   ticks, gigaticks;
  *   }
diff -Naur 711-1516.U007/src/object.h 711-1516.U007.sqlite/src/object.h
--- 711-1516.U007/src/object.h	2005-11-08 20:58:07.000000000 +0100
+++ 711-1516.U007.sqlite/src/object.h	2005-11-11 22:26:13.000000000 +0100
@@ -50,6 +50,9 @@
     int extra_num_variables;
     /* amylaar : used to determine where to check ref counts at all... */
 #endif
+#ifdef USE_SQLITE
+    int open_sqlite_db;   /* does this object have an open sqlite db */
+#endif 
     svalue_t *variables;
       /* All variables to this object: an array of svalues, allocated
        * in a separate block.
diff -Naur 711-1516.U007/src/pkg-sqlite.h 711-1516.U007.sqlite/src/pkg-sqlite.h
--- 711-1516.U007/src/pkg-sqlite.h	1970-01-01 01:00:00.000000000 +0100
+++ 711-1516.U007.sqlite/src/pkg-sqlite.h	2005-11-11 22:26:13.000000000 +0100
@@ -0,0 +1,2 @@
+
+int sl_close (object_t *ob);
diff -Naur 711-1516.U007/src/simulate.c 711-1516.U007.sqlite/src/simulate.c
--- 711-1516.U007/src/simulate.c	2005-11-08 20:58:08.000000000 +0100
+++ 711-1516.U007.sqlite/src/simulate.c	2005-11-11 22:26:13.000000000 +0100
@@ -53,6 +53,9 @@
 #include "mstrings.h"
 #include "object.h"
 #include "otable.h"
+#ifdef USE_SQLITE
+#include "pkg-sqlite.h"
+#endif
 #ifdef USE_TLS
 #include "pkg-tls.h"
 #endif
@@ -2050,6 +2053,9 @@
     ob->load_name = new_tabled(name);  /* but here it is */
     ob->prog = prog;
     ob->ticks = ob->gigaticks = 0;
+#ifdef USE_SQLITE
+    ob->open_sqlite_db=0;
+#endif
     ob->next_all = obj_list;
     ob->prev_all = NULL;
     if (obj_list)
@@ -2293,6 +2299,9 @@
     if (!current_object)
         fatal("clone_object() from no current_object !\n");
 #endif
+#ifdef USE_SQLITE
+    new_ob->open_sqlite_db=0;
+#endif
     new_ob->next_all = obj_list;
     new_ob->prev_all = NULL;
     if (obj_list)
@@ -2535,6 +2544,10 @@
 #ifdef CHECK_OBJECT_REF
     xallocate(shadow, sizeof(*shadow), "destructed object shadow");
 #endif /* CHECK_OBJECT_REF */
+
+#ifdef USE_SQLITE
+    if (ob->open_sqlite_db) sl_close(ob);
+#endif
     ob->time_reset = 0;
 
     /* We need the object in memory */
diff -Naur 711-1516.U007/src/string_spec 711-1516.U007.sqlite/src/string_spec
--- 711-1516.U007/src/string_spec	2005-11-08 20:58:08.000000000 +0100
+++ 711-1516.U007.sqlite/src/string_spec	2005-11-11 22:26:13.000000000 +0100
@@ -229,5 +229,8 @@
 SUCCESS         "success"
 
 #endif
+#ifdef USE_SQLITE
+SQLITE_OPEN	"sl_open"
+#endif
 
 /***************************************************************************/
diff -Nur 711-1516.U007/src/pkg-sqlite.c 711-1516.U007.sql/src/pkg-sqlite.c
--- 711-1516.U007/src/pkg-sqlite.c	1970-01-01 01:00:00.000000000 +0100
+++ 711-1516.U007.sql/src/pkg-sqlite.c	2005-11-12 03:22:22.835804032 +0100
@@ -0,0 +1,438 @@
+
+#include "config.h"
+#ifdef USE_SQLITE
+  
+#include <sqlite3.h>
+#include "typedefs.h"
+  
+#include "my-alloca.h"
+#include <errno.h>
+#include <stddef.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "array.h"
+#include "interpret.h"
+#include "mstrings.h"
+#include "simulate.h"
+#include "svalue.h"
+#include "xalloc.h"
+#include "object.h"
+#include "stdstrings.h"
+
+typedef struct sqlite_rows_s sqlite_rows_t;
+typedef struct sqlite_dbs_s sqlite_dbs_t;
+
+/* Since we don't know the number of rows while we retrieve the
+ * rows from a query we save the data in a single-linked list first
+ * and move them into an array after the retrieval has finished 
+ */ 
+struct sqlite_rows_s 
+{
+    vector_t * row;
+    sqlite_rows_t * last;
+};
+
+/* This structure is used for error handling. In case of an error
+ * our handler gets called with a pointer to this structure.
+ */
+struct sl_exec_cleanup_s
+{
+    svalue_t head; /* push_error_handler saves the link to our
+                      handler here. */
+
+    sqlite3_stmt *stmt;
+    sqlite_rows_t *rows;
+};
+
+/* Database connections should be bound to the object which opens 
+ * database file. We will store all database connections in a 
+ * linked list. 
+ */ 
+struct sqlite_dbs_s 
+{
+    sqlite3 * db;
+    object_t * obj;
+    sqlite_dbs_t * next;
+    sqlite_dbs_t * prev;
+};
+
+/* The list of database connections.
+ */ 
+static sqlite_dbs_t *head = NULL;
+  
+// HELPER FUNS
+sqlite_dbs_t *find_db (object_t * obj) 
+{
+    sqlite_dbs_t *tmp = head;
+
+    while (tmp)
+    {
+        if (tmp->obj==obj) return tmp;
+        tmp=tmp->prev;
+    }
+    return NULL;
+}
+
+sqlite_dbs_t * new_db()
+{
+    sqlite_dbs_t *tmp;
+    tmp = pxalloc (sizeof (*tmp));
+    if(!tmp) return NULL;
+   
+    tmp->db=NULL;
+    tmp->obj=NULL;
+    tmp->next=NULL;
+    tmp->prev=head;
+    if (head) head->next=tmp;
+    head=tmp;
+   
+    return tmp;
+}
+
+void remove_db(sqlite_dbs_t *db)
+{
+    if (db==head)
+    {
+   	if (head->prev) 
+   	{
+   	    head->prev->next=NULL;
+   	    head=head->prev;
+   	}
+        else
+        {
+   	    head=NULL;
+   	}
+    }
+    else
+    {
+   	if (db->next) db->next->prev=db->prev;
+   	if (db->prev) db->prev->next=db->next;
+    }
+    pfree(db);
+}
+
+static int
+my_sqlite3_authorizer(void* data, int what, const char* arg1, const char* arg2,
+        const char* dbname, const char* view)
+{
+    /* TODO: Check them via privilege_violation resp. valid_write.
+             (Don't know, whether sqlite can handle longjmps out of
+             its code in case of an error...)
+    */
+
+    switch(what)
+    {
+        case SQLITE_PRAGMA:
+	    if(!strcasecmp(arg1, "synchronous"))
+		return SQLITE_OK;
+            return SQLITE_DENY;
+
+        case SQLITE_ATTACH:
+        case SQLITE_DETACH:
+            return SQLITE_DENY;
+	
+        default:
+            return SQLITE_OK;
+    }
+}
+
+// EFUNS GO FROM HERE
+svalue_t * 
+f_sl_open (svalue_t *sp) 
+{
+    string_t *file;
+    sqlite3 *db;
+    sqlite_dbs_t *tmp;
+    int err;
+   
+    file = check_valid_path(sp->u.str, current_object, STR_SQLITE_OPEN , MY_TRUE);
+    if (!file)
+        errorf("Illegal use of sl_open('%s')\n", get_txt(sp->u.str));
+   
+    tmp = find_db (current_object);
+    if (tmp)
+    {
+        free_mstring(file);
+        errorf("The current object already has a database open.\n");
+    }
+
+    err = sqlite3_open (get_txt(file), &db);
+    free_mstring(file);
+    if (err)
+    {
+        const char* msg = sqlite3_errmsg(db);
+        sqlite3_close(db);
+        errorf("sl_open: %s\n", msg );
+        /* NOTREACHED */
+    }
+
+    /* create a new chain link and hang on the old chain */
+    tmp=new_db(); 
+    if(!tmp)
+    {
+        sqlite3_close(db);
+        errorf("(sl_open) Out of memory: (%lu bytes)\n",
+                (unsigned long) sizeof(*tmp));
+    }
+   
+    tmp->db = db;
+    tmp->obj = current_object;
+    current_object->open_sqlite_db=1;
+
+    /* Synchronous is damn slow. Forget it. */
+    sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, NULL);
+    sqlite3_set_authorizer(db, my_sqlite3_authorizer, NULL);
+  
+    free_string_svalue (sp);
+    put_number (sp, 1);
+    return sp;
+}
+
+static void
+sl_exec_cleanup (svalue_t * arg)
+{
+    sqlite_rows_t *row;
+    struct sl_exec_cleanup_s * data;
+    
+    data = (struct sl_exec_cleanup_s *)arg;
+    
+    if(data->stmt)
+        sqlite3_finalize(data->stmt);
+
+    row = data->rows;
+    while(row)
+    {
+        sqlite_rows_t *temp;
+
+        if(row->row)
+            free_array(row->row);
+        temp = row;
+        row = row->last;
+        pfree(temp);
+    }
+
+    xfree(data);
+}
+
+svalue_t * 
+v_sl_exec (svalue_t * sp, int num_arg) 
+{
+    svalue_t *argp;
+    sqlite_dbs_t *db;
+    sqlite3_stmt *stmt;
+    const char* tail;
+    int err, rows, cols, num;
+    struct sl_exec_cleanup_s * rec_data;
+    vector_t * result;
+
+    argp = sp - num_arg + 1; /* First argument: the SQL query */
+    
+    db = find_db (current_object);
+    if (!db)
+        errorf("The current object doesn't have a database open.\n");
+
+    err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str),
+        &stmt, &tail);
+    if(err)
+    {
+        const char* msg = sqlite3_errmsg(db->db);
+        if(stmt)
+            sqlite3_finalize(stmt);
+        errorf("sl_exec: %s\n", msg);
+        /* NOTREACHED */
+    }
+    
+    /* Now bind all parameters. */
+    for(argp++, num=1; argp <= sp; argp++, num++)
+    {
+        switch(argp->type)
+        {
+        default:
+            sqlite3_finalize(stmt);
+            errorf("Bad argument %d to sl_exec(): type %s\n",
+                num+1, typename(argp->type));
+            break; /* NOTREACHED */
+
+        case T_FLOAT:
+            sqlite3_bind_double(stmt, num, READ_DOUBLE(argp));
+            break;
+
+        case T_NUMBER:
+            sqlite3_bind_int(stmt, num, argp->u.number);
+            break;
+    
+        case T_STRING:
+            sqlite3_bind_text(stmt, num, get_txt(argp->u.str),
+                mstrsize(argp->u.str), SQLITE_STATIC);
+            break;
+        }
+    }
+    
+    rows = 0;
+    cols = sqlite3_column_count(stmt);
+
+    rec_data = xalloc(sizeof(*rec_data));
+    if(!rec_data)
+    {
+        sqlite3_finalize(stmt);
+        errorf("(sl_exec) Out of memory: (%lu bytes) for cleanup structure\n",
+            (unsigned long) sizeof(*rec_data));
+    }
+    rec_data->rows = NULL;
+    rec_data->stmt = stmt;
+    
+    push_error_handler(sl_exec_cleanup, &(rec_data->head));
+    sp = inter_sp;
+    
+    while((err = sqlite3_step(stmt)) == SQLITE_ROW)
+    {
+        int col;
+        sqlite_rows_t *this_row;
+
+        rows++;
+        this_row = pxalloc(sizeof(*this_row));
+        if(!this_row)
+            errorf("(sl_exec) Out of memory: (%lu bytes)\n",
+                (unsigned long) sizeof(*this_row));
+
+        this_row->last = rec_data->rows;
+        rec_data->rows = this_row;
+        this_row->row = NULL; /* Because allocate_array may throw an error. */
+
+        this_row->row = allocate_array(cols);
+        if(!this_row->row)
+            errorf("(sl_exec) Out of memory: row vector\n");
+    
+        for(col = 0; col < cols; col++)
+        {
+            STORE_DOUBLE_USED;
+            svalue_t * entry;
+
+            entry = this_row->row->item + col;
+
+            switch(sqlite3_column_type(stmt, col))
+            {
+            default:
+                errorf("sl_exec: Unknown type %d.\n",
+                    sqlite3_column_type(stmt, col));
+                break;
+
+            case SQLITE_BLOB:
+                errorf("sl_exec: Blob columns are not supported.\n");
+                break;
+
+            case SQLITE_INTEGER:
+                put_number(entry, sqlite3_column_int(stmt, col));
+                break;
+
+           case SQLITE_FLOAT:
+                entry->type = T_FLOAT;
+                STORE_DOUBLE(entry, sqlite3_column_double(stmt, col));
+                break;
+
+            case SQLITE_TEXT:
+                put_c_n_string(entry,
+                    sqlite3_column_text(stmt, col),
+                    sqlite3_column_bytes(stmt, col));
+                break;
+
+            case SQLITE_NULL:
+                /* All elements from this_row->row are initialized to 0. */
+                break;
+            }
+        }
+    }
+
+    sqlite3_finalize(stmt);
+    rec_data->stmt = NULL;
+    
+    switch(err)
+    {
+    default:
+        errorf("sl_exec: Unknown return code from sqlite3_step: %d.\n", err);
+        break;
+
+    case SQLITE_BUSY:
+        errorf("sl_exec: Database is locked.\n");
+        break;
+
+    case SQLITE_ERROR:
+        errorf("sl_exec: %s\n", sqlite3_errmsg(db->db));
+        break;
+
+    case SQLITE_MISUSE:
+        errorf("sl_exec: sqlite3_step was called inappropriately.\n");
+        break;
+
+    case SQLITE_DONE:
+        break;
+    }
+
+    if(rows)
+    {
+        sqlite_rows_t *this_row;
+
+        result = allocate_array(rows);
+        if(!result)
+            errorf("(sl_exec) Out of memory: result vector\n");
+
+        this_row = rec_data->rows;
+        while(rows--)
+        {
+            put_array(result->item + rows, this_row->row);
+            this_row->row = NULL;
+            this_row = this_row->last;
+        }
+    }
+    else
+        result = NULL;
+
+    // Pop arguments and our error handler.
+    // Our error handler gets called and cleans the row stuff.
+    sp = pop_n_elems(num_arg + 1, sp) + 1; 
+    	
+    if(rows)
+        put_array(sp,result);
+    else
+        put_number(sp, 0);
+
+    return sp;
+}
+
+int
+sl_close (object_t *ob)
+{
+    sqlite_dbs_t *db = find_db(ob);
+    if (!db) return 0;
+   
+    sqlite3_close(db->db);
+    ob->open_sqlite_db=0;
+    remove_db(db);
+    return 1;
+}
+
+svalue_t *
+f_sl_insert_id (svalue_t * sp)
+{
+    sqlite_dbs_t *db = find_db(current_object);
+    int id;
+   
+    if (!db)
+        errorf("The current object doesn't have a database open.\n");
+ 
+    id=sqlite3_last_insert_rowid(db->db);
+    sp++;
+    put_number(sp,id);
+    return sp;
+}
+
+svalue_t * 
+f_sl_close (svalue_t * sp) 
+{
+    if (!sl_close(current_object)) 
+        errorf("The current object doesn't have a database open.\n");
+    return sp;
+}
+
+#endif /* USE_SQLITE */
