New source folder layout

Sat, 14 Jan 2012 13:53:44 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 14 Jan 2012 13:53:44 +0100
changeset 14
b8bf95b39952
parent 13
1fdbf4170ef4
child 15
cff9c4101dd7

New source folder layout

src/server/LinkedList.hh file | annotate | diff | comparison | revisions
src/server/Makefile file | annotate | diff | comparison | revisions
src/server/conf.c file | annotate | diff | comparison | revisions
src/server/conf.h file | annotate | diff | comparison | revisions
src/server/daemon/Makefile file | annotate | diff | comparison | revisions
src/server/daemon/conf.c file | annotate | diff | comparison | revisions
src/server/daemon/conf.h file | annotate | diff | comparison | revisions
src/server/daemon/func.c file | annotate | diff | comparison | revisions
src/server/daemon/func.h file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.h file | annotate | diff | comparison | revisions
src/server/daemon/httpparser.c file | annotate | diff | comparison | revisions
src/server/daemon/httpparser.h file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.h file | annotate | diff | comparison | revisions
src/server/daemon/main.c file | annotate | diff | comparison | revisions
src/server/daemon/netsite.h file | annotate | diff | comparison | revisions
src/server/daemon/objs.mk file | annotate | diff | comparison | revisions
src/server/daemon/protocol.c file | annotate | diff | comparison | revisions
src/server/daemon/protocol.h file | annotate | diff | comparison | revisions
src/server/daemon/request.c file | annotate | diff | comparison | revisions
src/server/daemon/request.h file | annotate | diff | comparison | revisions
src/server/daemon/session.c file | annotate | diff | comparison | revisions
src/server/daemon/session.h file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.h file | annotate | diff | comparison | revisions
src/server/daemon/vserver.c file | annotate | diff | comparison | revisions
src/server/daemon/vserver.h file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
src/server/daemon/webserver.h file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/davparser.cpp file | annotate | diff | comparison | revisions
src/server/davparser.h file | annotate | diff | comparison | revisions
src/server/dlist.c file | annotate | diff | comparison | revisions
src/server/dlist.h file | annotate | diff | comparison | revisions
src/server/ereport.h file | annotate | diff | comparison | revisions
src/server/func.c file | annotate | diff | comparison | revisions
src/server/func.h file | annotate | diff | comparison | revisions
src/server/httplistener.c file | annotate | diff | comparison | revisions
src/server/httplistener.h file | annotate | diff | comparison | revisions
src/server/httpparser.c file | annotate | diff | comparison | revisions
src/server/httpparser.h file | annotate | diff | comparison | revisions
src/server/httprequest.c file | annotate | diff | comparison | revisions
src/server/httprequest.h file | annotate | diff | comparison | revisions
src/server/io.c file | annotate | diff | comparison | revisions
src/server/io.h file | annotate | diff | comparison | revisions
src/server/list.c file | annotate | diff | comparison | revisions
src/server/list.h file | annotate | diff | comparison | revisions
src/server/main.c file | annotate | diff | comparison | revisions
src/server/map.c file | annotate | diff | comparison | revisions
src/server/map.h file | annotate | diff | comparison | revisions
src/server/nametrans.c file | annotate | diff | comparison | revisions
src/server/nametrans.h file | annotate | diff | comparison | revisions
src/server/netbuf.c file | annotate | diff | comparison | revisions
src/server/netsite.h file | annotate | diff | comparison | revisions
src/server/nsapi.h file | annotate | diff | comparison | revisions
src/server/object.c file | annotate | diff | comparison | revisions
src/server/object.h file | annotate | diff | comparison | revisions
src/server/objecttype.c file | annotate | diff | comparison | revisions
src/server/objecttype.h file | annotate | diff | comparison | revisions
src/server/objs.mk file | annotate | diff | comparison | revisions
src/server/pblock.cpp file | annotate | diff | comparison | revisions
src/server/pblock.h file | annotate | diff | comparison | revisions
src/server/plist.c file | annotate | diff | comparison | revisions
src/server/plist.h file | annotate | diff | comparison | revisions
src/server/plist_pvt.h file | annotate | diff | comparison | revisions
src/server/plistdef.h file | annotate | diff | comparison | revisions
src/server/pool.c file | annotate | diff | comparison | revisions
src/server/pool.h file | annotate | diff | comparison | revisions
src/server/pool_pvt.h file | annotate | diff | comparison | revisions
src/server/protocol.c file | annotate | diff | comparison | revisions
src/server/protocol.h file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
src/server/request.c file | annotate | diff | comparison | revisions
src/server/request.h file | annotate | diff | comparison | revisions
src/server/safs/Makefile file | annotate | diff | comparison | revisions
src/server/safs/nametrans.c file | annotate | diff | comparison | revisions
src/server/safs/nametrans.h file | annotate | diff | comparison | revisions
src/server/safs/objecttype.c file | annotate | diff | comparison | revisions
src/server/safs/objecttype.h file | annotate | diff | comparison | revisions
src/server/safs/objs.mk file | annotate | diff | comparison | revisions
src/server/safs/service.c file | annotate | diff | comparison | revisions
src/server/safs/service.h file | annotate | diff | comparison | revisions
src/server/saxhandler.cpp file | annotate | diff | comparison | revisions
src/server/saxhandler.h file | annotate | diff | comparison | revisions
src/server/service.c file | annotate | diff | comparison | revisions
src/server/service.h file | annotate | diff | comparison | revisions
src/server/session.c file | annotate | diff | comparison | revisions
src/server/session.h file | annotate | diff | comparison | revisions
src/server/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/sessionhandler.h file | annotate | diff | comparison | revisions
src/server/shexp.c file | annotate | diff | comparison | revisions
src/server/shexp.h file | annotate | diff | comparison | revisions
src/server/sstring.c file | annotate | diff | comparison | revisions
src/server/sstring.h file | annotate | diff | comparison | revisions
src/server/strbuf.c file | annotate | diff | comparison | revisions
src/server/strbuf.h file | annotate | diff | comparison | revisions
src/server/system.c file | annotate | diff | comparison | revisions
src/server/systems.h file | annotate | diff | comparison | revisions
src/server/systhr.c file | annotate | diff | comparison | revisions
src/server/systhr.h file | annotate | diff | comparison | revisions
src/server/thrpool.c file | annotate | diff | comparison | revisions
src/server/thrpool.h file | annotate | diff | comparison | revisions
src/server/ucx.h file | annotate | diff | comparison | revisions
src/server/ucx/Makefile file | annotate | diff | comparison | revisions
src/server/ucx/dlist.c file | annotate | diff | comparison | revisions
src/server/ucx/dlist.h file | annotate | diff | comparison | revisions
src/server/ucx/objs.mk file | annotate | diff | comparison | revisions
src/server/ucx/sstring.c file | annotate | diff | comparison | revisions
src/server/ucx/sstring.h file | annotate | diff | comparison | revisions
src/server/ucx/ucx.h file | annotate | diff | comparison | revisions
src/server/uri.cpp file | annotate | diff | comparison | revisions
src/server/util.c file | annotate | diff | comparison | revisions
src/server/util.h file | annotate | diff | comparison | revisions
src/server/util/LinkedList.hh file | annotate | diff | comparison | revisions
src/server/util/Makefile file | annotate | diff | comparison | revisions
src/server/util/ereport.h file | annotate | diff | comparison | revisions
src/server/util/io.c file | annotate | diff | comparison | revisions
src/server/util/io.h file | annotate | diff | comparison | revisions
src/server/util/list.c file | annotate | diff | comparison | revisions
src/server/util/list.h file | annotate | diff | comparison | revisions
src/server/util/map.c file | annotate | diff | comparison | revisions
src/server/util/map.h file | annotate | diff | comparison | revisions
src/server/util/netbuf.c file | annotate | diff | comparison | revisions
src/server/util/object.c file | annotate | diff | comparison | revisions
src/server/util/object.h file | annotate | diff | comparison | revisions
src/server/util/objs.mk file | annotate | diff | comparison | revisions
src/server/util/pblock.cpp file | annotate | diff | comparison | revisions
src/server/util/pblock.h file | annotate | diff | comparison | revisions
src/server/util/plist.c file | annotate | diff | comparison | revisions
src/server/util/plist.h file | annotate | diff | comparison | revisions
src/server/util/plist_pvt.h file | annotate | diff | comparison | revisions
src/server/util/plistdef.h file | annotate | diff | comparison | revisions
src/server/util/pool.c file | annotate | diff | comparison | revisions
src/server/util/pool.h file | annotate | diff | comparison | revisions
src/server/util/pool_pvt.h file | annotate | diff | comparison | revisions
src/server/util/shexp.c file | annotate | diff | comparison | revisions
src/server/util/shexp.h file | annotate | diff | comparison | revisions
src/server/util/strbuf.c file | annotate | diff | comparison | revisions
src/server/util/strbuf.h file | annotate | diff | comparison | revisions
src/server/util/system.c file | annotate | diff | comparison | revisions
src/server/util/systems.h file | annotate | diff | comparison | revisions
src/server/util/systhr.c file | annotate | diff | comparison | revisions
src/server/util/systhr.h file | annotate | diff | comparison | revisions
src/server/util/thrpool.c file | annotate | diff | comparison | revisions
src/server/util/thrpool.h file | annotate | diff | comparison | revisions
src/server/util/uri.cpp file | annotate | diff | comparison | revisions
src/server/util/util.c file | annotate | diff | comparison | revisions
src/server/util/util.h file | annotate | diff | comparison | revisions
src/server/vserver.c file | annotate | diff | comparison | revisions
src/server/vserver.h file | annotate | diff | comparison | revisions
src/server/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav.h file | annotate | diff | comparison | revisions
src/server/webdav/Makefile file | annotate | diff | comparison | revisions
src/server/webdav/davparser.cpp file | annotate | diff | comparison | revisions
src/server/webdav/davparser.h file | annotate | diff | comparison | revisions
src/server/webdav/objs.mk file | annotate | diff | comparison | revisions
src/server/webdav/saxhandler.cpp file | annotate | diff | comparison | revisions
src/server/webdav/saxhandler.h file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.h file | annotate | diff | comparison | revisions
src/server/webserver.c file | annotate | diff | comparison | revisions
src/server/webserver.h file | annotate | diff | comparison | revisions
src/server/ws-fn.c file | annotate | diff | comparison | revisions
--- a/src/server/LinkedList.hh	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _LINKED_LIST_H_
-#define _LINKED_LIST_H_
-
-/*
- *   Provided a template implementation of a simple linked list. 
- * It is a reference based container (stores the pointers to the
- * objects contained) It doesn't check for duplicates etc and find
- * (delete) will find(delete) the first occurence of an element.
- *
- * Iterator class can be used for traversal using the "++" operator.
- */
-template <class C> class CList; // forward declaration
-template <class C> class CListIterator; // forward declaration
-template <class C> class CListConstIterator; // forward declaration
-
-template <class C> class CListElmt {
-  friend class CList<C>;
-  friend class CListIterator<C>;
-  friend class CListConstIterator<C>;
-  private:
-    CListElmt(C* refP, int id) : _refP(refP), _nextP(0), _prevP(0), _id(id)
-        {
-                // Nothing really has to be done here
-        };
-
-
-  private:
-    int       _id;    
-    C         *_refP;
-#if defined(AIX)
-    CListElmt<C> *_nextP;
-    CListElmt<C> *_prevP;
-#else
-    CListElmt *_nextP;
-    CListElmt *_prevP;
-#endif
-};
-
-//
-// NOTE : If you need the find functionality, make sure that 
-//  class C has "==" defined.
-//
-template <class C> class CList {
-  friend class CListIterator<C>;
-  friend class CListConstIterator<C>;
-  private:
-    CListElmt<C>* _headP;
-    CListElmt<C>* _tailP;
-    CListElmt<C>* Lookup(C * memberP)
-        {
-                CListElmt<C> *curEltP = _headP;
-                
-                while (curEltP)
-                {
-                        if (curEltP->_refP == memberP) 
-                                break;
-                        curEltP = curEltP->_nextP;
-                };
-                return(curEltP);
-        };
-    
-    int _nextId;
-    int _numElts;
-    int autoDestroy;
-    C* Remove(CListElmt<C> *elmtP)
-        {
-                C  *recP = NULL;
-                if (elmtP)
-                {
-                        if (elmtP->_nextP)
-                                elmtP->_nextP->_prevP = elmtP->_prevP;
-                        if (elmtP->_prevP)
-                                elmtP->_prevP->_nextP = elmtP->_nextP;
-                        if (elmtP == _tailP)
-                                _tailP = elmtP->_prevP;
-                        if (elmtP == _headP)
-                                _headP = _headP->_nextP;
-                        recP = elmtP->_refP;
-                        _numElts--;
-                        delete elmtP;
-                };
-                if ( (1==autoDestroy) && recP)
-                        delete recP;
-                
-                return(recP);
-        };
-    
-
-  public:
-    CList() :  _headP(0), _tailP(0), _nextId(0), _numElts(0), autoDestroy(0)
-        {
-                // Nothing really has to be done here
-        };
-        
-    void setAutoDestroy(int setting)
-        {
-                autoDestroy = setting;
-        };
-
-    virtual ~CList()
-        {
-                while (_headP)
-                        Remove(_headP);
-        };
-
-    int NextId()
-        {
-                return _nextId;
-        };
-
-    int Append(C* refP)
-        {
-                CListElmt<C> *newElmtP = new CListElmt<C>(refP, _nextId++);
-                newElmtP->_prevP = _tailP;
-                if (_tailP)
-                        _tailP->_nextP = newElmtP;
-                if (_headP == 0)
-                        _headP = newElmtP;
-                _tailP = newElmtP;
-                _numElts++;
-                return(newElmtP->_id);
-        };
-
-    int Member(C* memberP)
-        {
-                return(Lookup(memberP) != 0);
-        };
-    
-    int Delete(C* memberP)
-        {
-                CListElmt<C> *listElmtP = Lookup(memberP);
-                if (listElmtP)
-                {
-                        (void) Remove(listElmtP);
-                        return(1);
-                }
-                return(0);
-        };
-    
-    int NumEntries() const { return _numElts; }
-    C* Find(C* memberP) // Lookup based on == operator for class C
-        {
-                CListElmt<C> *curEltP = _headP;
-        
-                while (curEltP)
-                {
-                        if (curEltP->_refP == memberP) 
-                                break;
-                        curEltP = curEltP->_nextP;
-                };
-                return(curEltP ? curEltP->_refP : 0);
-        };
-    
-    C* First() { return(_headP ? _headP->_refP : 0); }
-    C* Last() { return(_tailP ? _tailP->_refP : 0); }
-};
-
-template <class C> class CListIterator {
-  private:
-    CList<C>* _listP;
-    int _curId;
-  public:
-    CListIterator(CList<C>* linkedListP) : _listP(linkedListP), _curId(-1)
-        {
-                // Nothing more to be done
-        };
-    
-    virtual ~CListIterator()
-        {
-                _listP = NULL;
-        };
-    
-    C* operator++() // Define ++ operator to move forward along the list.
-        {
-                C *valueP = NULL;
-                CListElmt<C> *curEltP = _listP->_headP;
-
-                while (curEltP)
-                {
-                        if (curEltP->_id > _curId)
-                        {
-                                _curId = curEltP->_id;
-                                return(curEltP->_refP);
-                        }
-                        curEltP = curEltP->_nextP;
-                }
-                _curId = -1;
-                return(NULL);
-        };
-    
-    void operator()() // Overload the function operator to reset the iterator
-        {
-                _curId = -1;
-        };
-    
-};
-
-template <class C> class CListConstIterator {
-  private:
-    const CList<C>* _listP;
-    int _curId;
-  public:
-    CListConstIterator(const CList<C>* linkedListP)
-        : _listP(linkedListP), _curId(-1)
-        {
-                // Nothing more to be done
-        };
-    
-    virtual ~CListConstIterator()
-        {
-                _listP = NULL;
-        };
-    
-    const C* operator++() // Define ++ operator to move forward along the list.
-        {
-                const C *valueP = NULL;
-                const CListElmt<C> *curEltP = _listP->_headP;
-
-                while (curEltP)
-                {
-                        if (curEltP->_id > _curId)
-                        {
-                                _curId = curEltP->_id;
-                                return(curEltP->_refP);
-                        }
-                        curEltP = curEltP->_nextP;
-                }
-                _curId = -1;
-                return(NULL);
-        };
-    
-    void operator()() // Overload the function operator to reset the iterator
-        {
-                _curId = -1;
-        };
-    
-};
-
-#endif // _LINKED_LIST_H_
--- a/src/server/Makefile	Sun Jan 08 15:46:47 2012 +0100
+++ b/src/server/Makefile	Sat Jan 14 13:53:44 2012 +0100
@@ -27,27 +27,43 @@
 #
 
 BUILD_ROOT = ../../
+
+LDFLAGS = -L/usr/lib/mps -R/usr/lib/mps -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lposix4  -lsocket -lnsl -lgen -lm -lsendfile -lxerces-c -pg
+
 OBJ_DIR = $(BUILD_ROOT)build/
 
-CFLAGS  = -I/usr/include/mps -g
-LDFLAGS = -L/usr/lib/mps -R/usr/lib/mps -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lposix4  -lsocket -lnsl -lgen -lm -lsendfile -lxerces-c -pg
-
 MAIN_TARGET = $(BUILD_ROOT)work/bin/webservd
 
-include objs.mk
-
 all: preparation $(MAIN_TARGET)
 
-preparation:
-	mkdir -p $(OBJPRE)
+include ucx/objs.mk
+include util/objs.mk
+include safs/objs.mk
+include webdav/objs.mk
+include daemon/objs.mk
+
+MAINOBJS = $(UCXOBJS) $(UTILOBJS) $(SAFOBJS) $(DAVOBJS) $(DAEMONOBJS)
+
+OBJ_DIRS = daemon safs ucx util webdav
+MK_OBJ_DIRS = $(OBJ_DIRS:%=$(OBJ_DIR)server/%)
+
+preparation: $(MK_OBJ_DIRS)
 	mkdir -p $(BUILD_ROOT)work/bin
+	
+$(MK_OBJ_DIRS):
+	mkdir -p $@
 
-$(MAIN_TARGET): $(MAINOBJS)
+$(MAIN_TARGET): $(DAEMONOBJS) $(UCXOBJS) $(UTILOBJS) $(SAFOBJS) $(DAVOBJS)
 	CC -o $(MAIN_TARGET) $(LDFLAGS) $(MAINOBJS)
 
-$(OBJPRE)%.o: %.c
-	cc -o $@ -c $(CFLAGS) $<
+$(DAEMONOBJS): $(UCXOBJS)
+	cd daemon; $(MAKE) all
+$(UCXOBJS):
+	cd ucx; $(MAKE) all
+$(UTILOBJS):
+	cd util; $(MAKE) all
+$(SAFOBJS):
+	cd safs; $(MAKE) all
+$(DAVOBJS):
+	cd webdav; $(MAKE) all
 
-$(OBJPRE)%.o: %.cpp
-	CC -o $@ -c $(CFLAGS) $<
-	
--- a/src/server/conf.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,457 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "nsapi.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include "sstring.h"
-
-#include "httplistener.h"
-#include "conf.h"
-#include "func.h"
-
-#include "vserver.h"
-#include "pblock.h"
-
-VirtualServer *default_vs;
-
-void load_init_conf(char *file) {
-    printf("load_init_conf\n");
-    if(1) {
-        return;
-    }
-
-    pool_handle_t *pool = pool_create();
-
-    FILE *in = fopen("conf/obj.conf", "r");
-    if(in == NULL) {
-        fprintf(stderr, "Cannot open conf/obj.conf\n");
-        return;
-    }
-
-    char buf[512];
-    int  len = 512;
-
-    while(!feof(in)) {
-        fgets(buf, len, in);
-
-        if(*buf == 0) {
-            continue;
-        }
-
-        char *ptr;
-        if((ptr = strrchr(buf, '\n'))) {
-            ptr[0] = 0;
-        }
-
-        sstr_t line = string_trim(sstr(buf));
-        if(line.length > 0) {
-            sstr_t type;
-            directive *d = parse_directive(pool, line, &type);
-            if(sstrcmp(type, sstr("Init"))) {
-                d->func->func(d->param, NULL, NULL);
-            }
-        }
-    }
-}
-
-void load_server_conf(char *file) {
-    printf("load_server_conf\n");
-    
-    ListenerConfig *conf = malloc(sizeof(ListenerConfig));
-    conf->port = 9090;
-    conf->nacceptors = 1;
-    conf->name = "default";
-
-    http_listener_new(conf);
-
-    // virtual server
-    default_vs = vs_new();
-    // load obj.conf
-    default_vs->objects = load_obj_conf("conf/obj.conf");
-    default_vs->default_obj_name = "default";
-
-    // begin objset test
-    /*
-    httpd_objset *objset = default_vs->objset;
-    for(int i=0;i<objset->pos;i++) {
-        httpd_object *obj = objset->obj[i];
-        printf("<object [%s]>\n", obj->name);
-        for(int j=0;j<obj->nd;j++) {
-            dtable *dt;
-            switch(j) {
-                case NSAPIAuthTrans: {
-                    printf("  Get AuthTrans Directives\n");
-                    dt = object_get_dtable(obj, NSAPIAuthTrans);
-                    break;
-                }
-                case NSAPINameTrans: {
-                    printf("  Get NameTrans Directives\n");
-                    dt = object_get_dtable(obj, NSAPINameTrans);
-                    break;
-                }
-                case NSAPIPathCheck: {
-                    printf("  Get PathCheck Directives\n");
-                    dt = object_get_dtable(obj, NSAPIPathCheck);
-                    break;
-                }
-                case NSAPIService: {
-                    printf("  Get Service Directives\n");
-                    dt = object_get_dtable(obj, NSAPIService);
-                    break;
-                }
-                default: {
-                    printf("j: %d\n", j);
-                    dt = object_get_dtable(obj, j);
-                    break;
-                }
-            }
-            if(dt != NULL) {
-                printf("  dtable[%d].length = %d\n", dt, dt->ndir);
-            } else {
-                continue;
-            }
-            for(int k=0;k<dt->ndir;k++) {
-                directive *d = dt->directive[k];
-                if(d == NULL) {
-                    printf("d is null\n");
-                } else {
-                    printf("    Directive[%d].name = %s\n", d, d->func->name);
-                }
-            }
-        }
-    }
-    */
-    // end objset test
-}
-
-VirtualServer* conf_get_default_vs() {
-    return default_vs;
-}
-
-HTTPObjectConfig* load_obj_conf(char *file) {
-    printf("load_obj_conf\n");
-
-    /* create object config */
-    ObjectConfParser parser;
-    HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
-    conf->pool = pool_create();   
-    parser.conf = conf;
-
-    FILE *in = fopen("conf/obj.conf", "r");
-    if(in == NULL) {
-        fprintf(stderr, "Cannot open conf/obj.conf\n");
-        return NULL;
-    }
-
-    char buf[512];
-    int  len = 512;
-
-    while(!feof(in)) {
-        fgets(buf, len, in);
-
-        if(*buf == 0) {
-            continue;
-        }
-
-        char *ptr;
-        if((ptr = strrchr(buf, '\n'))) {
-            ptr[0] = 0;
-        }
-
-        sstr_t line = string_trim(sstr(buf));
-        if(line.length > 0) {
-            obj_conf_parse_line(&parser, line);
-        }
-    }
-
-    
-
-    return conf;
-}
-
-void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line) {
-    //printf("{%s}[%d]\n", line.ptr, line.length);
-    if(line.ptr[0] == '#') {
-        return;
-    }
-
-    if(line.length < 3) {
-        // to short for everything
-        fprintf(stderr, "obj.conf: line to short \"%s\"\n", line.ptr);
-        return;
-    }
-
-    // TODO: ersetzen
-    if(line.ptr[0] == '<') {
-        if(line.ptr[1] == '/') {
-            // end tag
-            if(line.ptr[2] == 'O' && parser->obj != NULL) {
-                // end of Object
-                httpobjconf_add_object(parser->conf, parser->obj);
-                parser->obj = NULL;
-                return;
-            }
-        } else {
-            // new tag
-            httpd_object *obj = parse_new_object_tag(line);
-            parser->obj = obj;
-        }
-    } else {
-        // directive
-        sstr_t dtype;
-        directive *d = parse_directive(parser->conf->pool, line, &dtype);
-        int dt = get_directive_type_from_string(dtype);
-        object_add_directive(parser->obj, d, dt);
-    }
-}
-
-
-/* utils */
-
-sstr_t string_trim(sstr_t string) {
-    sstr_t newstr = string;
-    int nsoff = 0;
-    int l = 1;
-    for(int i=0;i<string.length;i++) {
-        char c = string.ptr[i];
-        if(l) {
-            /* leading whitespace */
-            if(c > 32) {
-                l = 0;
-                nsoff = i;
-                newstr.ptr = &string.ptr[i];
-                newstr.length = string.length - nsoff;
-            }
-        } else {
-            /* trailing whitespace */
-            if(c > 32) {
-                newstr.length = (i - nsoff) + 1;
-            }
-        }
-    }
-    return newstr;
-}
-
-httpd_object* parse_new_object_tag(sstr_t line) {
-    int i = 0;
-    int b = 0;
-    sstr_t name;
-    sstr_t value;
-
-    char *obj_name = NULL;
-    char *obj_ppath = NULL;
-    
-    for(;i<line.length;i++) {
-        if(line.ptr[i] < 33) {
-            b = 1;
-        } else if(b == 1) {
-            break;
-        }
-    }
-    if(!b || line.ptr[i] < 33) {
-        printf("1\n");
-        return NULL;
-    }
-    b = 0;
-    
-    /* parse name=value params */
-    for(;i<line.length;i++) {
-        if(line.ptr[i] == '>') {
-            break;
-        }
-        
-        /* get name */
-        name.ptr = line.ptr + i;
-        for(;i<line.length;i++) {
-            if(line.ptr[i] == '=') {
-                b = 1;
-                i++;
-                break;
-            }
-        }
-        if(!b) {
-            printf("2\n");
-            return NULL;
-        }
-        name.length = line.ptr + i - name.ptr - 1;
-
-        if(line.ptr[i] == '\"') {
-            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
-        }
-        value.ptr = line.ptr + i;
-        for(;i<line.length;i++) {
-            char c = line.ptr[i];
-            if(c < 33 || c == '\"' || c == '>') {
-                b = 1;
-                break;
-            }
-        }
-        if(!b) {
-            printf("3\n");
-            return NULL;
-        }
-        value.length = line.ptr + i - value.ptr;
-
-        if(sstrcmp(name, sstrn("name", 4)) == 0) {
-            obj_name = sstrdub(value).ptr;
-        } else if (sstrcmp(name, sstrn("ppath", 5)) == 0) {
-            obj_ppath = sstrdub(value).ptr;
-        }
-
-        /*
-        printf("name: [%d]{", name.length);
-        fwrite(name.ptr, 1, name.length, stdout);
-        printf("}\n");
-        printf("value: [%d]{", value.length);
-        fwrite(value.ptr, 1, value.length, stdout);
-        printf("}\n");
-        */
-
-        char c = line.ptr[i];
-        if(c == '>') {
-            break;
-        } else {
-            i++;
-        }
-    }
-
-    if(obj_name != NULL || obj_ppath != NULL) {
-        httpd_object *o = object_new(obj_name);
-        o->path = obj_ppath;
-        return o;
-    }
-
-    return NULL;
-}
-
-directive* parse_directive(pool_handle_t *pool, sstr_t line, sstr_t *type) {
-    int i = 0;
-    int b = 0;
-
-    sstr_t directive_type = line;
-    
-    directive *directive = malloc(sizeof(directive));
-    directive->cond = NULL;
-    directive->param = pblock_create_pool(pool, 8);
-
-    for(;i<line.length;i++) {
-        if(line.ptr[i] < 33) {
-            b = 1;
-            directive_type.length = i;
-            if(directive_type.length <= 0) {
-                fprintf(stderr, "parse error: cannot parse directive\n");
-                return NULL;
-            }
-        } else if(b == 1) {
-            break;
-        }
-    }
-    
-    /* parse name=value params */
-    sstr_t name;
-    sstr_t value;
-    for(;i<line.length;i++) {
-        /* get name */
-        name.ptr = line.ptr + i;
-        for(;i<line.length;i++) {
-            if(line.ptr[i] == '=') {
-                b = 1;
-                i++;
-                break;
-            }
-        }
-        if(!b) {
-            printf("2\n");
-            return NULL;
-        }
-        name.length = line.ptr + i - name.ptr - 1;
-
-        if(line.ptr[i] == '\"') {
-            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
-        }
-        value.ptr = line.ptr + i;
-        for(;i<line.length;i++) {
-            char c = line.ptr[i];
-            if(c < 33 || c == '\"') {
-                b = 1;
-                break;
-            }
-        }
-        if(!b) {
-            printf("3\n");
-            return NULL;
-        }
-        value.length = line.ptr + i - value.ptr;
-
-        name = string_trim(name);
-        value = string_trim(value);
-
-        /* insert name and value into directive pblock */
-        pblock_nvlinsert(
-                name.ptr,
-                name.length,
-                value.ptr,
-                value.length,
-                directive->param);
-    }
-
-    /* get function */
-    char *func_name = pblock_findval("fn", directive->param);
-    directive->func = get_function(func_name);
-
-    *type = directive_type;
-    return directive;
-}
-
-int get_directive_type_from_string(sstr_t type) {
-    /* get nsapi function type */
-    int dt = -1;
-    if(sstrcmp(type, sstr("AuthTrans")) == 0) {
-        dt = 0;
-    } else if(sstrcmp(type, sstr("NameTrans")) == 0) {
-        dt = 1;
-    } else if(sstrcmp(type, sstr("PathCheck")) == 0) {
-        dt = 2;
-    } else if(sstrcmp(type, sstr("ObjectType")) == 0) {
-        dt = 3;
-    } else if(sstrcmp(type, sstr("Service")) == 0) {
-        dt = 4;
-    } else if(sstrcmp(type, sstr("AddLog")) == 0) {
-        dt = 5;
-    }
-    return dt;
-}
--- a/src/server/conf.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CONF_H
-#define	CONF_H
-
-#include "object.h"
-
-#include "sstring.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct {
-    HTTPObjectConfig *conf;
-    httpd_object     *obj;
-} ObjectConfParser;
-
-void load_init_conf(char *file);
-
-void load_server_conf(char *file);
-
-VirtualServer* conf_get_default_vs();
-
-
-HTTPObjectConfig* load_obj_conf(char *file);
-
-void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line);
-
-
-/* utils */
-sstr_t string_trim(sstr_t string);
-
-httpd_object* parse_new_object_tag(sstr_t line);
-
-directive* parse_directive(pool_handle_t *pool, sstr_t line, sstr_t *type);
-
-int get_directive_type_from_string(sstr_t dt);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* CONF_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/Makefile	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,44 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BUILD_ROOT = ../../../
+OBJ_DIR = $(BUILD_ROOT)build/
+
+CFLAGS  = -I/usr/include/mps -g
+LDFLAGS = 
+
+include objs.mk
+
+all: $(DAEMONOBJS)
+
+$(DMN_OBJPRE)%.o: %.c
+	cc -o $@ -c $(CFLAGS) $<
+
+$(DMN_OBJPRE)%.o: %.cpp
+	CC -o $@ -c $(CFLAGS) $<
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/conf.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,455 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../public/nsapi.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include "../ucx/sstring.h"
+
+#include "httplistener.h"
+#include "conf.h"
+#include "func.h"
+
+#include "vserver.h"
+#include "../util/pblock.h"
+
+VirtualServer *default_vs;
+
+void load_init_conf(char *file) {
+    printf("load_init_conf\n");
+
+    pool_handle_t *pool = pool_create();
+
+    FILE *in = fopen("conf/init.conf", "r");
+    if(in == NULL) {
+        fprintf(stderr, "Cannot open conf/init.conf\n");
+        return;
+    }
+
+    char buf[512];
+    buf[0] = 0;
+    int  len = 512;
+
+    while(!feof(in)) {
+        fgets(buf, len, in);
+
+        if(*buf == 0) {
+            continue;
+        }
+
+        char *ptr;
+        if((ptr = strrchr(buf, '\n'))) {
+            ptr[0] = 0;
+        }
+        
+        sstr_t line = string_trim(sstr(buf));
+        if(line.length > 0) {
+            sstr_t type;
+            directive *d = parse_directive(pool, line, &type);
+            if(sstrcmp(type, sstr("Init"))) {
+                d->func->func(d->param, NULL, NULL);
+            }
+        }
+    }
+}
+
+void load_server_conf(char *file) {
+    printf("load_server_conf\n");
+    
+    ListenerConfig *conf = malloc(sizeof(ListenerConfig));
+    conf->port = 9090;
+    conf->nacceptors = 1;
+    conf->name = "default";
+
+    http_listener_new(conf);
+
+    // virtual server
+    default_vs = vs_new();
+    // load obj.conf
+    default_vs->objects = load_obj_conf("conf/obj.conf");
+    default_vs->default_obj_name = "default";
+
+    // begin objset test
+    /*
+    httpd_objset *objset = default_vs->objset;
+    for(int i=0;i<objset->pos;i++) {
+        httpd_object *obj = objset->obj[i];
+        printf("<object [%s]>\n", obj->name);
+        for(int j=0;j<obj->nd;j++) {
+            dtable *dt;
+            switch(j) {
+                case NSAPIAuthTrans: {
+                    printf("  Get AuthTrans Directives\n");
+                    dt = object_get_dtable(obj, NSAPIAuthTrans);
+                    break;
+                }
+                case NSAPINameTrans: {
+                    printf("  Get NameTrans Directives\n");
+                    dt = object_get_dtable(obj, NSAPINameTrans);
+                    break;
+                }
+                case NSAPIPathCheck: {
+                    printf("  Get PathCheck Directives\n");
+                    dt = object_get_dtable(obj, NSAPIPathCheck);
+                    break;
+                }
+                case NSAPIService: {
+                    printf("  Get Service Directives\n");
+                    dt = object_get_dtable(obj, NSAPIService);
+                    break;
+                }
+                default: {
+                    printf("j: %d\n", j);
+                    dt = object_get_dtable(obj, j);
+                    break;
+                }
+            }
+            if(dt != NULL) {
+                printf("  dtable[%d].length = %d\n", dt, dt->ndir);
+            } else {
+                continue;
+            }
+            for(int k=0;k<dt->ndir;k++) {
+                directive *d = dt->directive[k];
+                if(d == NULL) {
+                    printf("d is null\n");
+                } else {
+                    printf("    Directive[%d].name = %s\n", d, d->func->name);
+                }
+            }
+        }
+    }
+    */
+    // end objset test
+}
+
+VirtualServer* conf_get_default_vs() {
+    return default_vs;
+}
+
+HTTPObjectConfig* load_obj_conf(char *file) {
+    printf("load_obj_conf\n");
+
+    /* create object config */
+    ObjectConfParser parser;
+    HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1);
+    conf->pool = pool_create();   
+    parser.conf = conf;
+
+    FILE *in = fopen("conf/obj.conf", "r");
+    if(in == NULL) {
+        fprintf(stderr, "Cannot open conf/obj.conf\n");
+        return NULL;
+    }
+
+    char buf[512];
+    int  len = 512;
+
+    while(!feof(in)) {
+        fgets(buf, len, in);
+
+        if(*buf == 0) {
+            continue;
+        }
+
+        char *ptr;
+        if((ptr = strrchr(buf, '\n'))) {
+            ptr[0] = 0;
+        }
+
+        sstr_t line = string_trim(sstr(buf));
+        if(line.length > 0) {
+            obj_conf_parse_line(&parser, line);
+        }
+    }
+
+    
+
+    return conf;
+}
+
+void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line) {
+    //printf("{%s}[%d]\n", line.ptr, line.length);
+    if(line.ptr[0] == '#') {
+        return;
+    }
+
+    if(line.length < 3) {
+        // to short for everything
+        fprintf(stderr, "obj.conf: line to short \"%s\"\n", line.ptr);
+        return;
+    }
+
+    // TODO: ersetzen
+    if(line.ptr[0] == '<') {
+        if(line.ptr[1] == '/') {
+            // end tag
+            if(line.ptr[2] == 'O' && parser->obj != NULL) {
+                // end of Object
+                httpobjconf_add_object(parser->conf, parser->obj);
+                parser->obj = NULL;
+                return;
+            }
+        } else {
+            // new tag
+            httpd_object *obj = parse_new_object_tag(line);
+            parser->obj = obj;
+        }
+    } else {
+        // directive
+        sstr_t dtype;
+        directive *d = parse_directive(parser->conf->pool, line, &dtype);
+        int dt = get_directive_type_from_string(dtype);
+        object_add_directive(parser->obj, d, dt);
+    }
+}
+
+
+/* utils */
+
+sstr_t string_trim(sstr_t string) {
+    sstr_t newstr = string;
+    int nsoff = 0;
+    int l = 1;
+    for(int i=0;i<string.length;i++) {
+        char c = string.ptr[i];
+        if(l) {
+            /* leading whitespace */
+            if(c > 32) {
+                l = 0;
+                nsoff = i;
+                newstr.ptr = &string.ptr[i];
+                newstr.length = string.length - nsoff;
+            }
+        } else {
+            /* trailing whitespace */
+            if(c > 32) {
+                newstr.length = (i - nsoff) + 1;
+            }
+        }
+    }
+    return newstr;
+}
+
+httpd_object* parse_new_object_tag(sstr_t line) {
+    int i = 0;
+    int b = 0;
+    sstr_t name;
+    sstr_t value;
+
+    char *obj_name = NULL;
+    char *obj_ppath = NULL;
+    
+    for(;i<line.length;i++) {
+        if(line.ptr[i] < 33) {
+            b = 1;
+        } else if(b == 1) {
+            break;
+        }
+    }
+    if(!b || line.ptr[i] < 33) {
+        printf("1\n");
+        return NULL;
+    }
+    b = 0;
+    
+    /* parse name=value params */
+    for(;i<line.length;i++) {
+        if(line.ptr[i] == '>') {
+            break;
+        }
+        
+        /* get name */
+        name.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            if(line.ptr[i] == '=') {
+                b = 1;
+                i++;
+                break;
+            }
+        }
+        if(!b) {
+            printf("2\n");
+            return NULL;
+        }
+        name.length = line.ptr + i - name.ptr - 1;
+
+        if(line.ptr[i] == '\"') {
+            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
+        }
+        value.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            char c = line.ptr[i];
+            if(c < 33 || c == '\"' || c == '>') {
+                b = 1;
+                break;
+            }
+        }
+        if(!b) {
+            printf("3\n");
+            return NULL;
+        }
+        value.length = line.ptr + i - value.ptr;
+
+        if(sstrcmp(name, sstrn("name", 4)) == 0) {
+            obj_name = sstrdub(value).ptr;
+        } else if (sstrcmp(name, sstrn("ppath", 5)) == 0) {
+            obj_ppath = sstrdub(value).ptr;
+        }
+
+        /*
+        printf("name: [%d]{", name.length);
+        fwrite(name.ptr, 1, name.length, stdout);
+        printf("}\n");
+        printf("value: [%d]{", value.length);
+        fwrite(value.ptr, 1, value.length, stdout);
+        printf("}\n");
+        */
+
+        char c = line.ptr[i];
+        if(c == '>') {
+            break;
+        } else {
+            i++;
+        }
+    }
+
+    if(obj_name != NULL || obj_ppath != NULL) {
+        httpd_object *o = object_new(obj_name);
+        o->path = obj_ppath;
+        return o;
+    }
+
+    return NULL;
+}
+
+directive* parse_directive(pool_handle_t *pool, sstr_t line, sstr_t *type) {
+    int i = 0;
+    int b = 0;
+
+    sstr_t directive_type = line;
+    
+    directive *directive = malloc(sizeof(directive));
+    directive->cond = NULL;
+    directive->param = pblock_create_pool(pool, 8);
+
+    for(;i<line.length;i++) {
+        if(line.ptr[i] < 33) {
+            b = 1;
+            directive_type.length = i;
+            if(directive_type.length <= 0) {
+                fprintf(stderr, "parse error: cannot parse directive\n");
+                return NULL;
+            }
+        } else if(b == 1) {
+            break;
+        }
+    }
+    
+    /* parse name=value params */
+    sstr_t name;
+    sstr_t value;
+    for(;i<line.length;i++) {
+        /* get name */
+        name.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            if(line.ptr[i] == '=') {
+                b = 1;
+                i++;
+                break;
+            }
+        }
+        if(!b) {
+            printf("2\n");
+            return NULL;
+        }
+        name.length = line.ptr + i - name.ptr - 1;
+
+        if(line.ptr[i] == '\"') {
+            i++; // TODO: Bug wenn end of line - wird nicht erkannt!
+        }
+        value.ptr = line.ptr + i;
+        for(;i<line.length;i++) {
+            char c = line.ptr[i];
+            if(c < 33 || c == '\"') {
+                b = 1;
+                break;
+            }
+        }
+        if(!b) {
+            printf("3\n");
+            return NULL;
+        }
+        value.length = line.ptr + i - value.ptr;
+
+        name = string_trim(name);
+        value = string_trim(value);
+
+        /* insert name and value into directive pblock */
+        pblock_nvlinsert(
+                name.ptr,
+                name.length,
+                value.ptr,
+                value.length,
+                directive->param);
+    }
+
+    /* get function */
+    char *func_name = pblock_findval("fn", directive->param);
+    directive->func = get_function(func_name);
+
+    *type = directive_type;
+    return directive;
+}
+
+int get_directive_type_from_string(sstr_t type) {
+    /* get nsapi function type */
+    int dt = -1;
+    if(sstrcmp(type, sstr("AuthTrans")) == 0) {
+        dt = 0;
+    } else if(sstrcmp(type, sstr("NameTrans")) == 0) {
+        dt = 1;
+    } else if(sstrcmp(type, sstr("PathCheck")) == 0) {
+        dt = 2;
+    } else if(sstrcmp(type, sstr("ObjectType")) == 0) {
+        dt = 3;
+    } else if(sstrcmp(type, sstr("Service")) == 0) {
+        dt = 4;
+    } else if(sstrcmp(type, sstr("AddLog")) == 0) {
+        dt = 5;
+    }
+    return dt;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/conf.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,72 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CONF_H
+#define	CONF_H
+
+#include "../util/object.h"
+
+#include "../ucx/sstring.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    HTTPObjectConfig *conf;
+    httpd_object     *obj;
+} ObjectConfParser;
+
+void load_init_conf(char *file);
+
+void load_server_conf(char *file);
+
+VirtualServer* conf_get_default_vs();
+
+
+HTTPObjectConfig* load_obj_conf(char *file);
+
+void obj_conf_parse_line(ObjectConfParser *parser, sstr_t line);
+
+
+/* utils */
+sstr_t string_trim(sstr_t string);
+
+httpd_object* parse_new_object_tag(sstr_t line);
+
+directive* parse_directive(pool_handle_t *pool, sstr_t line, sstr_t *type);
+
+int get_directive_type_from_string(sstr_t dt);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* CONF_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/func.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdlib.h>
+
+#include "../public/nsapi.h"
+#include "../util/map.h"
+#include "func.h"
+
+hashmap_t *function_map;
+
+void func_init() {
+    function_map = hashmap_new(128);
+}
+
+void add_function(struct FuncStruct *func) {
+    printf("add function: %s\n", func->name);
+
+    struct FuncStruct *f = malloc(sizeof(FuncStruct));
+    *f = *func;
+    hashmap_put(function_map, sstr((char*)f->name), func);
+}
+
+void add_functions(struct FuncStruct *funcs) {
+    int i = 0;
+    while(funcs[i].func != NULL) {  
+        add_function(&funcs[i]);
+        i++;
+    }
+}
+
+FuncStruct* get_function(char *name) {
+    return hashmap_get(function_map, sstr(name));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/func.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FUNC_H
+#define	FUNC_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void func_init();
+
+void add_function(struct FuncStruct *func);
+
+void add_functions(struct FuncStruct *funcs);
+
+FuncStruct* get_function(char *name);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* FUNC_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/httplistener.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,178 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../public/nsapi.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <strings.h>
+#include <stdbool.h>
+#include <pthread.h>
+
+#include "../util/map.h"
+#include "httplistener.h"
+
+#include "session.h"
+
+hashmap_t *listener_map = NULL;
+
+
+int start_all_listener() {
+    HttpListener *listener = get_http_listener("default");
+    http_listener_start(listener); 
+
+    return 0;
+}
+
+HttpListener* get_http_listener(char *name) {
+    return hashmap_get(listener_map, sstr(name));
+}
+
+
+HttpListener* http_listener_new(ListenerConfig *conf) {
+    HttpListener *listener = malloc(sizeof(HttpListener));
+    listener->session_handler = create_basic_session_handler();
+    listener->nacceptors = conf->nacceptors;
+
+    struct sockaddr_in servaddr;   /* server address */
+
+    /* init address structure */
+    memset(&servaddr, 0, sizeof(servaddr));
+    servaddr.sin_family = AF_INET;
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    servaddr.sin_port = htons(conf->port);
+
+    /* create socket */
+    if((listener->server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+        perror("Error: http_listener_new: socket");
+        return NULL;
+    }
+
+    int o = 1;
+    setsockopt(
+            listener->server_socket,
+            SOL_SOCKET, SO_REUSEADDR,
+            &o,
+            sizeof(int));
+
+    /* bind server socket to address */
+    if(bind(listener->server_socket, (struct sockaddr*)&servaddr, sizeof(servaddr))){
+        perror("Error: http_listener_new: bind");
+        return NULL;
+    }
+
+    /* create acceptors */
+    listener->acceptors = calloc(listener->nacceptors, sizeof(void*));
+    for (int i=0;i<listener->nacceptors;i++) {
+        listener->acceptors[i] = acceptor_new(listener);
+    }
+
+    if(listener_map == NULL) {
+        listener_map = hashmap_new(8);
+    }
+    hashmap_put(listener_map, sstr(conf->name), listener);
+    return listener;
+}
+
+int http_listener_start(HttpListener *listener) {
+    printf("INFO: start listener\n");
+
+    if (listen(listener->server_socket, 16) == -1) {
+        perror("Error: http_listener_start: listen");
+        return -1;
+    }
+
+    /* start acceptor threads */
+    for (int i=0;i<listener->nacceptors;i++) {
+        acceptor_start(listener->acceptors[i]);
+    }
+}
+
+
+
+Acceptor* acceptor_new(HttpListener *listener) {
+    Acceptor *acceptor = malloc(sizeof(Acceptor));
+    acceptor->listener = listener;
+    return acceptor;
+}
+
+void acceptor_start(Acceptor *a) {
+    if(pthread_create(
+            &a->tid,
+            NULL,
+            (void*(*)(void*))acceptor_thread,
+            a) != 0)
+    {
+        perror("Error: acceptor_start: pthread_create");
+    }
+}
+
+void* acceptor_thread(Acceptor *acceptor) {
+    HttpListener *listener = acceptor->listener;
+
+    for (;;) {
+        /* accept connections */
+        struct sockaddr_in ca;
+        socklen_t length = sizeof(ca);
+        int clientfd;
+
+        /* accept a connection */
+        clientfd = accept(
+                listener->server_socket,
+                (struct sockaddr*)&ca,
+                &length);
+        if (clientfd == -1) {
+            perror("Error: acceptor_thread: accept");
+            continue;
+        }
+        
+        /* create Connection object */
+        Connection *conn = malloc(sizeof(Connection));
+        conn->address = ca;
+        conn->fd = clientfd;
+
+        /* enqueue the connection */
+        listener->session_handler->enqueue_connection(
+                listener->session_handler,
+                conn);
+
+        /* ready for new connection */
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/httplistener.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTTPLISTENER_H
+#define	HTTPLISTENER_H
+
+#include "sessionhandler.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct _http_listener    HttpListener;
+typedef struct _acceptor         Acceptor;
+typedef struct _listener_config  ListenerConfig;
+
+struct _listener_config {
+    char           *name;
+    char           *address;
+    int            port;
+    int            nacceptors;
+};
+
+struct _acceptor {
+    pthread_t      tid;
+    HttpListener   *listener;
+};
+
+struct _http_listener {
+    int              server_socket;
+    Acceptor         **acceptors;
+    int              nacceptors;
+    SessionHandler   *session_handler;
+};
+
+int start_all_listener();
+HttpListener* get_http_listener(char *name);
+
+
+HttpListener* http_listener_new(ListenerConfig *conf);
+
+int http_listener_start(HttpListener *listener);
+
+
+Acceptor* acceptor_new(HttpListener *listener);
+
+void acceptor_start(Acceptor *a);
+
+void* acceptor_thread(Acceptor *a);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* HTTPLISTENER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/httpparser.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,196 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "httpparser.h"
+#include "../public/nsapi.h"
+//include "request.h"
+
+
+HttpParser* http_parser_new(HTTPRequest *request) {
+    HttpParser *parser = malloc(sizeof(HttpParser));
+    parser->request = request;
+    
+    parser->state = 0;
+    parser->start_line.ptr = (char*)request->netbuf->inbuf;
+    parser->start_line.length = 0;
+
+    return parser;
+}
+
+void http_parser_free(HttpParser *parser) {
+    free(parser);
+}
+
+int http_parser_process(HttpParser *parser) {
+    switch(parser->state) {
+        case 0: {
+            int r = get_start_line(parser);
+            switch(r) {
+                case 0: break;
+                default: return r;
+            }
+            parse_request_line(parser);
+            parser->state++;
+        }
+        case 1: {
+            return http_parser_parse_header(parser);
+        }
+        case 2: {
+            return 0;
+        }
+    }
+}
+
+int get_start_line(HttpParser *parser) {
+    netbuf *buf = parser->request->netbuf;
+    while(buf->pos < buf->cursize) {
+        unsigned char c = buf->inbuf[buf->pos];
+        if(c == '\n') {
+            if(buf->pos <= 1) {
+                // insufficient chars for request, return error
+                return 2;
+            }
+            if(buf->inbuf[buf->pos - 1] == '\r') {
+                parser->start_line.length = buf->pos;
+            } else {
+                parser->start_line.length = buf->pos + 1;
+            }
+            parser->start_line.ptr = (char*)buf->inbuf;
+            buf->pos++;
+            return 0;
+        }
+        buf->pos++;
+    }
+    return 1;
+}
+
+int http_parser_parse_header(HttpParser *parser) {
+    netbuf *buf = parser->request->netbuf;
+
+    parser->offset = buf->pos; // line offset
+    parser->name.ptr = NULL;
+    parser->value.ptr = NULL;
+    while(1) {
+        if(buf->pos >= buf->cursize) {
+            return 1;
+        }
+        char c = (char)buf->inbuf[buf->pos++];
+
+        if(c > 32) {
+            parser->wl = 0;
+            if(c == ':' && parser->value.ptr == NULL) {
+                parser->name.ptr = (char*)buf->inbuf + parser->offset;
+                buf->inbuf[buf->pos-1] = 0;
+            } else if(parser->name.ptr != NULL && parser->value.ptr == NULL) {
+                parser->value.ptr = (char*)buf->inbuf + buf->pos - 1;
+            }
+        } else if(c == '\n') {
+            if(parser->wl) {
+                // line contains only white space -> end of request
+                parser->state++;
+                return 0;
+            } else {
+                parser->offset = buf->pos;
+                if(parser->value.ptr != NULL) {
+                    buf->inbuf[buf->pos-1] = 0;
+                    // add header
+                    header_add(
+                            parser->request->headers,
+                            parser->name.ptr,
+                            parser->value.ptr);
+                } else {
+                    // error: no value
+                    return 2;
+                }
+                parser->name.ptr = NULL;
+                parser->value.ptr = NULL;
+                parser->wl = 1;
+            }
+        }
+    }
+}
+
+int parse_request_line(HttpParser *parser) {
+    sstr_t line = parser->start_line;
+    parser->request->request_line = line;
+    
+    /*
+     * parse method, url and http version
+     */
+    
+    int i = 0;
+    int ns = 0;
+
+    parser->request->method.ptr = line.ptr;
+    for(;i<line.length;i++) {
+        if(!ns && line.ptr[i] == ' ') {
+            ns = 1;
+            //line.ptr[i] = 0; // TODO: remove
+            parser->request->method.length = i;
+        } else if(ns) {
+            if(line.ptr[i] != ' ') {
+                break;
+            }
+        }
+    }
+
+    parser->request->uri.ptr = line.ptr + i;
+    ns = 0;
+    int s = i;
+    for(;i<line.length;i++) {
+        if(!ns && line.ptr[i] < 33) {
+            ns = 1;
+            //line.ptr[i] = 0; // TODO: remove
+            parser->request->uri.length = i - s;
+        } else if(ns) {
+            if(line.ptr[i] > 32) {
+                break;
+            }
+        }
+    }
+
+    parser->request->httpv.ptr = line.ptr + i;
+    ns = 0;
+    s = i;
+    for(;i<line.length;i++) {
+        if(!ns && line.ptr[i] < 33) {
+            ns = 1;
+            //line.ptr[i] = 0; // TODO: remove
+            parser->request->httpv.length = i - s;
+        } else if(ns) {
+            if(line.ptr[i] > 32) {
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/httpparser.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,90 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTTPPARSER_H
+#define	HTTPPARSER_H
+
+
+#include "../ucx/sstring.h"
+#include "httprequest.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * http parser states
+ *
+ * 0: start line
+ * 1: header
+ * 2: finish
+ */
+
+typedef struct _http_parser {
+    HTTPRequest *request;
+
+    int state;
+    sstr_t start_line;
+
+    /* local parser varaibles */
+    int wl;       /* only white space */
+    int tk;       /* token: 0: header name 1: header value */
+    int offset;   /* offset of parsed string */
+    int strend;   /* end position */
+    sstr_t name;
+    sstr_t value;
+
+} HttpParser;
+
+HttpParser* http_parser_new(HTTPRequest *request);
+void http_parser_free(HttpParser *parser);
+
+/*
+ * process http parsing
+ *
+ * return
+ * 0: finish
+ * 1: need more data
+ * 2: error
+ */
+int http_parser_process(HttpParser *parser);
+
+int get_start_line(HttpParser *parser);
+int http_parser_parse_header(HttpParser *parser);
+
+int parse_request_line(HttpParser *parser);
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#endif	/* HTTPPARSER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/httprequest.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,532 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#include "../public/nsapi.h"
+#include "../util/pool.h"
+#include "../util/pblock.h"
+#include "../util/io.h"
+#include "../util/util.h"
+#include "httprequest.h"
+#include "conf.h"
+#include "vserver.h"
+
+HTTPRequest *http_request_new() {
+    HTTPRequest *req = malloc(sizeof(HTTPRequest));
+    req->connection = NULL;
+    req->uri.ptr = NULL;
+
+    HeaderArray *hd = malloc(sizeof(HeaderArray));
+    hd->next = NULL;
+    hd->len = 0;
+    hd->headers = calloc(16, sizeof(Header));
+    hd->alloc = 16;
+
+    req->headers = hd;
+
+    return req;
+}
+
+int handle_request(HTTPRequest *request) {
+    // handle nsapi request
+
+    // create pool
+    request->pool = pool_create();
+
+    // create nsapi data structures
+    NSAPISession *sn = malloc(sizeof(NSAPISession));
+    NSAPIRequest *rq = malloc(sizeof(NSAPIRequest));
+    request->rq = rq;
+    rq->phase = NSAPIAuthTrans;
+
+    // fill session structure
+    sn->sys_fd = request->connection->fd;
+    sn->sn.pool = pool_create();
+    sn->sn.csd = stream_new_from_fd(request->connection->fd);
+    sn->sn.client = pblock_create_pool(sn->sn.pool, 8);
+    sn->sn.next = NULL;
+    sn->sn.fill = 1;
+    sn->sn.subject = NULL;
+
+    /* add ip to sn->client pblock */
+    char ip_str[INET_ADDRSTRLEN];
+    if(inet_ntop(
+            AF_INET,
+            &request->connection->address.sin_addr,
+            ip_str,
+            INET_ADDRSTRLEN) != NULL)
+    {
+        pblock_kvinsert(pb_key_ip, ip_str, INET_ADDRSTRLEN, sn->sn.client);
+    }
+
+    // init NSAPI request structure
+    if(request_initialize(request->pool, request, rq) != 0) {
+        printf("Cannot initialize request structure\n");
+        return 1;
+    }
+
+    // set default virtual server
+    rq->vs = conf_get_default_vs();
+
+
+    /* Pass request line as "clf-request" */
+    pblock_kvinsert(
+            pb_key_clf_request,
+            request->request_line.ptr,
+            request->request_line.length,
+            rq->rq.reqpb);
+
+    /* Pass method as "method" in reqpb, and also as method_num */
+    pblock_kvinsert(
+            pb_key_method,
+            request->method.ptr,
+            request->method.length,
+            rq->rq.reqpb);
+    // TODO: method num
+    //rqRq.rq.method_num = rqHdr->GetMethodNumber();
+    //PR_ASSERT(rqRq.rq.method_num != -1 || iStatus);
+    
+    /* Pass protocol as "protocol" in reqpb, and also in protv_num */
+    pblock_kvinsert(
+            pb_key_protocol,
+            request->httpv.ptr,
+            request->httpv.length,
+            rq->rq.reqpb);
+    // TODO: protocol num
+
+    /* Pass any query as "query" in reqpb */
+    // TODO: query
+
+    /* Get abs_path part of request URI, and canonicalize the path */
+    sstr_t absPath = request->uri;
+    // TODO: get abs_path
+    absPath.ptr = util_canonicalize_uri(
+            request->pool,
+            absPath.ptr,
+            absPath.length,
+            (int*)&absPath.length);
+
+    /* Decode the abs_path */
+    // TODO: decode abs_path
+
+    /* Pass the abs_path as "uri" in reqpb */
+    // TODO: pass abs_path to reqpb
+    // TODO: replace this code
+    pblock_kvinsert(
+            pb_key_uri,
+            absPath.ptr,
+            absPath.length,
+            rq->rq.reqpb);
+
+    // pass http header to the NSAPI request structure
+    int         hlen = request->headers->len;
+    HeaderArray *ha  = request->headers;
+    for(int i=0;i<=hlen;i++) {
+        if(i == hlen) {
+            ha = ha->next;
+            if(ha == NULL) {
+                break;
+            }
+            i = 0;
+            hlen = ha->len;
+        }
+
+        if(ha->headers[i].name[0] < 90) {
+            ha->headers[i].name[0] += 32;
+        }
+        pblock_nvinsert(ha->headers[i].name, ha->headers[i].value, rq->rq.headers);
+    }
+
+    /* check for request body and prepare input buffer */
+    char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers);
+    if(ctlen_str) {
+        int ctlen = atoi(ctlen_str);
+        
+        printf("request body length: %d\n", ctlen);
+
+        netbuf *nb = request->netbuf;
+
+        /* create new netbuf */
+        NetIOStream *net_io = (NetIOStream*)net_stream_from_fd(
+                request->connection->fd);
+        net_io->max_read = ctlen;
+
+        sn->sn.inbuf = malloc(sizeof(netbuf));
+        sn->sn.inbuf->sd = net_io;
+        sn->sn.inbuf->pos = 0;
+        
+        /* prepare buffer */
+        int cur_input_len = nb->cursize - nb->pos;
+        if(cur_input_len >= ctlen) {
+
+            /*
+             * all data is already in the primary input buffer
+             * just link the new netbuf to the primary buffer
+             */
+            sn->sn.inbuf->maxsize = ctlen;
+            sn->sn.inbuf->cursize = ctlen;
+            sn->sn.inbuf->inbuf = nb->inbuf + nb->pos;
+        } else {
+            sn->sn.inbuf->maxsize = (ctlen > 2048) ? (2048) : (ctlen);
+            sn->sn.inbuf->inbuf = malloc(sizeof(sn->sn.inbuf->maxsize));
+
+            if(cur_input_len > 0) {
+                /* we have read a part of the request body -> copy to netbuf */
+                memcpy(sn->sn.inbuf->inbuf, nb->inbuf+nb->pos, cur_input_len);
+            }
+
+            sn->sn.inbuf->cursize = cur_input_len;
+        }
+    } else {
+        sn->sn.inbuf = NULL;
+    }
+
+
+    // Send the request to the NSAPI system
+    nsapi_handle_request(sn, rq);
+
+    return 0;
+}
+
+
+
+void header_add(HeaderArray *hd, char *name, char *value) {
+    while(hd->len >= hd->alloc) {
+        if(hd->next == NULL) {
+            HeaderArray *block = malloc(sizeof(HeaderArray));
+            block->next = NULL;
+            block->len = 0;
+            block->headers = calloc(16, sizeof(Header));
+            block->alloc = 16;
+            hd->next = block;
+        }
+        hd = hd->next;
+    }
+    hd->headers[hd->len].name = name;
+    hd->headers[hd->len].value = value;
+    hd->len++;
+}
+
+
+/*
+ * NSAPI Processing
+ * TODO: add this to new file
+ */
+
+int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq) {
+    // TODO: threadpool
+
+    int r = REQ_NOACTION;
+
+    do {
+        switch(rq->phase) {
+            case NSAPIAuthTrans: {
+                rq->phase++;
+                nsapi_context_next_stage(&rq->context);
+            }
+            case NSAPINameTrans: {
+                printf(">>> NameTrans\n");
+                r = nsapi_nametrans(sn, rq);
+                if(r != REQ_PROCEED) {
+                    break;
+                }
+                rq->phase++;
+                nsapi_context_next_stage(&rq->context);
+            }
+            case NSAPIPathCheck: {
+                printf(">>> PathCheck\n");
+                rq->phase++;
+                nsapi_context_next_stage(&rq->context);
+            }
+            case NSAPIObjectType: {
+                printf(">>> ObjectType\n");
+                r = nsapi_objecttype(sn, rq);
+                if(r != REQ_PROCEED) {
+                    break;
+                }
+                rq->phase++;
+                nsapi_context_next_stage(&rq->context);
+            }
+            case NSAPIService: {
+                printf(">>> Service\n");
+                r = nsapi_service(sn, rq);
+                if(r != REQ_PROCEED) {
+                    break;
+                }
+                rq->phase++;
+                nsapi_context_next_stage(&rq->context);
+            }
+            case NSAPIAddLog: {
+                printf(">>> AddLog\n");
+                rq->phase++;
+                nsapi_context_next_stage(&rq->context);
+            }
+            case REQ_FINISH: {
+                printf(">>> Finish\n");
+                r = nsapi_finish_request(sn, rq);
+            }
+        }
+    } while (r == REQ_RESTART);
+
+
+    return r;
+}
+
+int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) {
+    // TODO: free memory
+    close(sn->sys_fd);
+
+    return 0;
+}
+
+int nsapi_nametrans(NSAPISession *sn, NSAPIRequest *rq) {
+    HTTPObjectConfig *objconf = rq->vs->objects;
+    printf("nsapi_nametrans\n");
+    httpd_objset *objset = objset_create(sn->sn.pool);
+    rq->rq.os = objset;
+    /* first object in objconf is the default object  TODO: make sure it is */
+    objset_add_object(sn->sn.pool, objset, objconf->objects[0]);
+
+    httpd_object *obj = objset->obj[0]; /* nametrans only in default object */
+    dtable *dt = object_get_dtable(obj, NSAPINameTrans);
+
+    /* execute directives */
+    int ret = rq->context.last_req_code;
+    char *name = NULL;
+    char *ppath = NULL;
+    for(int i=NCX_DI(rq);i<dt->ndir;i++) {
+        directive *d = dt->dirs[i];
+
+        ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+
+        /* check for name or ppath */
+        name = pblock_findkeyval(pb_key_name, rq->rq.vars);
+        ppath = pblock_findkeyval(pb_key_ppath, rq->rq.vars);
+
+        /* add additional objects to the objset */
+        if(add_objects(objconf, objset, sn, rq, name, ppath) == REQ_ABORTED) {
+            fprintf(stderr, "add_objects failed\n");
+            return REQ_ABORTED;
+        }
+
+        if(ret != REQ_NOACTION) {
+            /*
+             * if a saf is still processing, we need to save the context, to
+             * process this object at a later time
+             */
+            if(ret == REQ_PROCESSING) {
+                /* save nsapi context */
+                /* add +1 to start next round with next function */
+                rq->context.dtable_index = i + 1;
+            }
+
+            return ret;
+        }
+    }
+
+    /* if no function has set the ppath var, translate it to docroot */
+    if(ret == REQ_NOACTION && ppath == NULL) {
+        sstr_t docroot = rq->vs->document_root;
+        if(docroot.length < 1) {
+            printf("docroot too short\n");
+            return REQ_ABORTED; /* docroot too short */
+        }
+        /* if there is a trailing '/', remove it */
+        if(docroot.ptr[docroot.length - 1] == '/') {
+            docroot.length--;
+        }
+
+        sstr_t uri = sstr(pblock_findkeyval(pb_key_uri, rq->rq.reqpb));
+
+        sstr_t translated;
+        translated.length = docroot.length + uri.length;
+        translated.ptr = alloca(translated.length + 1);
+        translated = sstrncat(2, translated, docroot, uri);
+
+        pblock_kvinsert(
+            pb_key_ppath,
+            translated.ptr,
+            translated.length,
+            rq->rq.vars);
+    }
+
+    return REQ_PROCEED;
+}
+
+int nsapi_objecttype(NSAPISession *sn, NSAPIRequest *rq) {
+    printf("nsapi_objecttype\n");
+    httpd_objset *objset = rq->rq.os;
+
+    if(NCX_OI(rq) == -1) {
+        /* object index is undefined -> define correct object index */
+        NCX_OI(rq) = objset->pos - 1;
+    }
+
+    int ret = rq->context.last_req_code;
+    for(int i=NCX_OI(rq);i>=0;i--) {
+        httpd_object *obj = objset->obj[i];
+        dtable *dt = object_get_dtable(obj, NSAPIObjectType);
+
+        // execute directives
+        for(int j=0;j<dt->ndir;j++) {
+            directive *d = dt->dirs[j];
+
+            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+            switch(ret) {
+                case REQ_PROCEED: {
+                    char *type = pblock_findkeyval(
+                            pb_key_content_type,
+                            rq->rq.srvhdrs);
+                    if(type == NULL) {
+                        ret = REQ_NOACTION;
+                        break;
+                    }
+                    return ret;
+                }
+                case REQ_PROCESSING: {
+                    /* save nsapi context */
+                    rq->context.objset_index = i;
+
+                    /* add +1 to start next round with next function */
+                    rq->context.dtable_index = j + 1;
+                    return ret;
+                }
+                case REQ_NOACTION: {
+                    break;
+                }
+                default: {
+                    return ret;
+                }
+            }
+        }
+    }
+
+    /*
+     * No function returned with REQ_PROCEED, but we need a content type.
+     * If the path ends with a '/', we set the content type to
+     * 'internal/directory' so that 'index-common' can serve the content.
+     * Otherwise we set the content type to text/plain
+     */
+    sstr_t path = sstr(pblock_findkeyval(pb_key_ppath, rq->rq.vars));
+    sstr_t ct;
+    if(path.ptr[path.length - 1] == '/') {
+        /* directory */
+        ct = sstrn("internal/directory", 18);
+    } else {
+        ct = sstrn("text/plain", 10);
+    }
+    pblock_kvinsert(pb_key_content_type, ct.ptr, ct.length, rq->rq.srvhdrs);
+
+    return REQ_PROCEED;
+}
+
+int nsapi_service(NSAPISession *sn, NSAPIRequest *rq) {
+    printf("nsapi_service\n");
+    httpd_objset *objset = rq->rq.os;
+
+    if(NCX_OI(rq) == -1) {
+        NCX_OI(rq) = objset->pos - 1;
+    }
+
+    int ret = rq->context.last_req_code;
+    char *content_type = NULL;
+    for(int i=NCX_OI(rq);i>=0;i--) {
+        httpd_object *obj = objset->obj[i];   
+        dtable *dt = object_get_dtable(obj, NSAPIService);
+
+        // execute directives
+        for(int j=0;j<dt->ndir;j++) {
+            directive *d = dt->dirs[j];
+
+            /* check type parameter */           
+            char *dtp = pblock_findkeyval(pb_key_type, d->param);
+            if(dtp) {
+                /* type parameter for directive */
+                if(!content_type) {
+                    content_type = pblock_findkeyval(
+                            pb_key_content_type,
+                            rq->rq.srvhdrs);
+                }
+                /* compare types */
+                if(strcmp(dtp, content_type) != 0) {
+                    continue;
+                }
+            }
+
+            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
+            if(ret != REQ_NOACTION) {
+                if(ret == REQ_PROCESSING) {
+                    /* save nsapi context */
+                    rq->context.objset_index = i;
+
+                    /* add +1 to start next round with next function */
+                    rq->context.dtable_index = j + 1;
+                }
+
+                return ret;
+            }
+        }
+    }
+
+    return ret;
+}
+
+/*
+ * adds objects with specific name or path to the httpd_objset
+ */
+int add_objects(
+        HTTPObjectConfig *objs,
+        httpd_objset *os,
+        NSAPISession *sn,
+        NSAPIRequest *rq,
+        char *name,
+        char *path)
+{
+    /* first, add all objects with a matching path */
+    /* TODO */
+
+
+    /* add object with object with matching name */
+    if(name == NULL) {
+        return REQ_PROCEED;
+    }
+
+    for(int i=0;i<objs->nobj;i++) {
+        httpd_object *obj = objs->objects[i];
+
+        if(obj->name && !strcmp(name, obj->name)) {
+            printf("name is %s -> add object %s\n", name, obj->name);
+            objset_add_object(sn->sn.pool, os, obj);
+        }
+    } 
+
+    return REQ_PROCEED;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/httprequest.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTTPREQUEST_H
+#define	HTTPREQUEST_H
+
+#include "../ucx/sstring.h"
+#include "sessionhandler.h"
+#include "../public/nsapi.h"
+#include "../util/pool.h"
+#include "session.h"
+#include "request.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct _http_request   HTTPRequest;
+typedef struct _header         Header;
+typedef struct _header_array   HeaderArray;
+
+struct _http_request {
+    Connection     *connection;
+    sstr_t         request_line;
+    sstr_t         method;
+    sstr_t         uri;
+    sstr_t         httpv;
+    HeaderArray    *headers;
+    netbuf         *netbuf;
+    NSAPISession   *sn;
+    NSAPIRequest   *rq;
+    pool_handle_t  *pool;
+};
+
+struct _header {
+    char *name;
+    char *value;
+};
+
+struct _header_array {
+    HeaderArray *next;
+    Header      *headers;
+    int         len;
+    int         alloc;
+};
+
+HTTPRequest *http_request_new();
+
+int handle_request(HTTPRequest *request);
+
+
+
+void header_add(HeaderArray *hd, char *name, char *value);
+
+int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq);
+int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq);
+int nsapi_nametrans(NSAPISession *sn, NSAPIRequest *rq);
+int nsapi_objecttype(NSAPISession *sn, NSAPIRequest *rq);
+int nsapi_service(NSAPISession *sn, NSAPIRequest *rq);
+
+
+int add_objects(
+        HTTPObjectConfig *objs,
+        httpd_objset *os,
+        NSAPISession *sn,
+        NSAPIRequest *rq,
+        char *name,
+        char *path);
+
+/* request.h functions */
+int request_initialize(
+        pool_handle_t *pool,
+        HTTPRequest *hrq,
+        NSAPIRequest *nrq);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* HTTPREQUEST_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/main.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../util/pool.h"
+#include "../public/nsapi.h"
+#include "../util/plist.h"
+
+#include "webserver.h"
+
+#include "httprequest.h"
+
+void test() {
+    
+}
+
+int main(int argc, char **argv) {
+    pool_init(NULL, NULL, NULL);
+
+    //test();
+
+    int status;
+    status = webserver_init();
+    if(status != 0) {
+        fprintf(stderr, "Cannot initialize server!\n");
+        return EXIT_FAILURE;
+    }
+
+    status = webserver_run();
+    if(status != 0) {
+        fprintf(stderr, "Cannot run server!\n");
+        return EXIT_FAILURE;
+    }
+
+    getchar();
+
+    return EXIT_SUCCESS;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/netsite.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,171 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NETSITE_H
+#define NETSITE_H
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * Standard defs for NetSite servers.
+ */
+
+#include <mps/nspr.h>
+
+#ifndef BASE_SYSTEMS_H
+#include "../util/systems.h"
+#endif /* !BASE_SYSTEMS_H */
+
+
+
+#define MAGNUS_VERSION_STRING INTsystem_version()
+#define MAGNUS_VERSION PRODUCT_VERSION_ID
+
+/* Include the public nsapi.h definitions */
+#ifndef PUBLIC_NETSITE_H
+#include "../public/nsapi.h"
+#endif /* PUBLIC_NETSITE_H */
+
+NSPR_BEGIN_EXTERN_C
+
+/*
+ * Only the mainline needs to set the malloc key.
+ */
+
+NSAPI_PUBLIC void InitThreadMallocKey(void);
+
+NSAPI_PUBLIC void system_set_temp_dir(const char *dir);
+
+NSAPI_PUBLIC const char *system_get_temp_dir(void);
+
+/* This probably belongs somewhere else, perhaps with a different name */
+NSAPI_PUBLIC char *INTdns_guess_domain(char * hname);
+
+/* --- Begin public functions --- */
+
+#ifdef INTNSAPI
+
+NSAPI_PUBLIC char *INTsystem_version(void);
+
+/*
+   Depending on the system, memory allocated via these macros may come from 
+   an arena. If these functions are called from within an Init function, they 
+   will be allocated from permanent storage. Otherwise, they will be freed 
+   when the current request is finished.
+ */
+
+#define MALLOC(size) INTsystem_malloc(size)
+NSAPI_PUBLIC void *INTsystem_malloc(int size);
+
+#define CALLOC(size) INTsystem_calloc(size)
+NSAPI_PUBLIC void *INTsystem_calloc(int size);
+
+#define REALLOC(ptr, size) INTsystem_realloc(ptr, size)
+NSAPI_PUBLIC void *INTsystem_realloc(void *ptr, int size);
+
+#define FREE(ptr) INTsystem_free(ptr)
+NSAPI_PUBLIC void INTsystem_free(void *ptr);
+
+#define STRDUP(ptr) INTsystem_strdup(ptr)
+NSAPI_PUBLIC char *INTsystem_strdup(const char *ptr);
+
+/*
+   These macros always provide permanent storage, for use in global variables
+   and such. They are checked at runtime to prevent them from returning NULL.
+ */
+
+#define PERM_MALLOC(size) INTsystem_malloc_perm(size)
+NSAPI_PUBLIC void *INTsystem_malloc_perm(int size);
+
+#define PERM_CALLOC(size) INTsystem_calloc_perm(size)
+NSAPI_PUBLIC void *INTsystem_calloc_perm(int size);
+
+#define PERM_REALLOC(ptr, size) INTsystem_realloc_perm(ptr, size)
+NSAPI_PUBLIC void *INTsystem_realloc_perm(void *ptr, int size);
+
+#define PERM_FREE(ptr) INTsystem_free_perm(ptr)
+NSAPI_PUBLIC void INTsystem_free_perm(void *ptr);
+
+#define PERM_STRDUP(ptr) INTsystem_strdup_perm(ptr)
+NSAPI_PUBLIC char *INTsystem_strdup_perm(const char *ptr);
+
+/* Thread-Private data key index for accessing the thread-private memory pool.
+ * Each thread creates its own pool for allocating data.  The MALLOC/FREE/etc
+ * macros have been defined to check the thread private data area with the
+ * thread_malloc_key index to find the address for the pool currently in use.
+ *
+ * If a thread wants to use a different pool, it must change the thread-local-
+ * storage[thread_malloc_key].
+ */
+
+NSAPI_PUBLIC int INTgetThreadMallocKey(void);
+
+NSAPI_PUBLIC pool_handle_t *INTsystem_pool(void);
+
+/* Not sure where to put this. */
+
+NSAPI_PUBLIC void INTsystem_setnewhandler(void);
+
+#endif /* INTNSAPI */
+
+/* --- End public functions --- */
+
+NSPR_END_EXTERN_C
+
+#ifdef INTNSAPI
+
+#define dns_guess_domain INTdns_guess_domain
+//define system_version INTsystem_version
+#define system_malloc INTsystem_malloc
+#define system_calloc INTsystem_calloc
+#define system_realloc INTsystem_realloc
+#define system_free INTsystem_free
+#define system_strdup INTsystem_strdup
+#define system_malloc_perm INTsystem_malloc_perm
+#define system_calloc_perm INTsystem_calloc_perm
+#define system_realloc_perm INTsystem_realloc_perm
+#define system_free_perm INTsystem_free_perm
+#define system_strdup_perm INTsystem_strdup_perm
+#define getThreadMallocKey INTgetThreadMallocKey
+#define system_pool INTsystem_pool
+#define system_setnewhandler INTsystem_setnewhandler
+
+#endif /* INTNSAPI */
+
+#ifndef HTTPS_ADMSERV 
+#define HTTPS_ADMSERV "https-admserv"
+#endif
+
+#endif /* NETSITE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/objs.mk	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,48 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+DMN_SRC_DIR = server/daemon/
+
+DMN_OBJPRE = $(OBJ_DIR)$(DMN_SRC_DIR)
+
+DAEMONOBJ = conf.o
+DAEMONOBJ += func.o
+DAEMONOBJ += httplistener.o
+DAEMONOBJ += httpparser.o
+DAEMONOBJ += httprequest.o
+DAEMONOBJ += main.o
+DAEMONOBJ += protocol.o
+DAEMONOBJ += request.o
+DAEMONOBJ += session.o
+DAEMONOBJ += sessionhandler.o
+DAEMONOBJ += vserver.o
+DAEMONOBJ += webserver.o
+DAEMONOBJ += ws-fn.o
+
+DAEMONOBJS = $(DAEMONOBJ:%=$(DMN_OBJPRE)%)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/protocol.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,315 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "protocol.h"
+
+#include "../util/pblock.h"
+#include "../util/pool.h"
+#include "session.h"
+#include "../util/io.h"
+
+#include "../util/strbuf.h"
+
+
+void protocol_status(Session *sn, Request *rq, int n, const char *m) {
+    rq->status_num = n;
+
+    const char *msg = m ? m : protocol_status_message(n);
+
+    pb_param *pp = pblock_removekey(pb_key_status, rq->srvhdrs);
+    if (pp != NULL) {
+        param_free(pp);
+    }
+
+    pp = pblock_key_param_create(rq->srvhdrs, pb_key_status, msg, strlen(msg));
+    pblock_kpinsert(pb_key_status, pp, rq->srvhdrs);
+}
+
+
+/*
+ * http_status_message from Open Webserver (frame/http.cpp)
+ * TODO: replace, use sstr_t
+ */
+NSAPI_PUBLIC const char * protocol_status_message (int code)
+{
+    const char *r;
+
+    switch (code)
+    {
+        case PROTOCOL_CONTINUE : // 100
+            r = "Continue";
+            break;
+        case PROTOCOL_SWITCHING: //101
+            r = "Switching Protocols";
+            break;
+        case PROTOCOL_OK: // 200
+            r = "OK";
+            break;
+        case PROTOCOL_CREATED: // 201
+            r = "Created";
+            break;
+        case PROTOCOL_ACCEPTED: // 202
+            r = "Accepted";
+            break;
+        case PROTOCOL_NONAUTHORITATIVE: // 203
+            r = "Non-Authoritative Information";
+            break;
+        case PROTOCOL_NO_CONTENT: //204
+        /* There is another define to PROTOCOL_NO_RESPONSE for 204 in nsapi.h
+           The spec maps this to No Content.
+           Hence cahnging this to No Content
+        */
+            r = "No Content";
+            break;
+        case PROTOCOL_RESET_CONTENT: // 205
+            r = "Reset Content";
+            break;
+        case PROTOCOL_PARTIAL_CONTENT: // 206
+            r = "Partial Content";
+            break;
+        case PROTOCOL_MULTI_STATUS: // 207
+            r = "Multi Status";
+            break;
+        case PROTOCOL_MULTIPLE_CHOICES: // 300
+            r = "Multiple Choices";
+            break;
+        case PROTOCOL_MOVED_PERMANENTLY: // 301
+            r = "Moved Permanently";
+            break;
+        case PROTOCOL_REDIRECT:          // 302
+            r = "Moved Temporarily"; /* The spec actually says "Found" */
+            break;
+        case PROTOCOL_SEE_OTHER:         // 303
+            r = "See Other";
+            break;
+        case PROTOCOL_NOT_MODIFIED:      // 304
+            r = "Use local copy";    /* The spec actually says "Not Modified" */
+            break;
+        case PROTOCOL_USE_PROXY:         // 305
+            r = "Use Proxy";
+            break;
+        case PROTOCOL_TEMPORARY_REDIRECT: // 307
+            r = "Temporary Redirect";
+            break;
+        case PROTOCOL_BAD_REQUEST:        // 400
+            r = "Bad request";
+            break;
+        case PROTOCOL_UNAUTHORIZED:       // 401
+            r = "Unauthorized";
+            break;
+        case PROTOCOL_PAYMENT_REQUIRED:   // 402
+            r = "Payment Required";
+            break;
+        case PROTOCOL_FORBIDDEN:          // 403
+            r = "Forbidden";
+            break;
+        case PROTOCOL_NOT_FOUND:         // 404
+            r = "Not found";
+            break;
+        case PROTOCOL_METHOD_NOT_ALLOWED: // 405                /* HTTP/1.1 */
+            r = "Method Not Allowed";
+            break;
+        case PROTOCOL_NOT_ACCEPTABLE: // 406                /* HTTP/1.1 */
+            r = "Not Acceptable";
+            break;
+        case PROTOCOL_PROXY_UNAUTHORIZED: // 407
+            r = "Proxy Authentication Required";
+            break;
+        case PROTOCOL_REQUEST_TIMEOUT:    // 408            /* HTTP/1.1 */
+            r = "Request Timeout";
+            break;
+        case PROTOCOL_CONFLICT:           // 409
+            r = "Conflict";                         /* HTTP/1.1 */
+            break;
+        case PROTOCOL_GONE:           // 410
+            r = "Gone";                         /* HTTP/1.1 */
+            break;
+        case PROTOCOL_LENGTH_REQUIRED:    // 411                /* HTTP/1.1 */
+            r = "Length Required";
+            break;
+        case PROTOCOL_PRECONDITION_FAIL:  // 412                /* HTTP/1.1 */
+            r = "Precondition Failed";
+            break;
+        case PROTOCOL_ENTITY_TOO_LARGE:   // 413                /* HTTP/1.1 */
+            r = "Request Entity Too Large";
+            break;
+        case PROTOCOL_URI_TOO_LARGE:      // 414                /* HTTP/1.1 */
+            r = "Request-URI Too Large";
+            break;
+        case PROTOCOL_UNSUPPORTED_MEDIA_TYPE: // 415
+            r = "Unsupported Media Type";
+            break;
+        case PROTOCOL_REQUESTED_RANGE_NOT_SATISFIABLE: // 416
+            r = "Requested range not satisfiable";
+            break;
+        case PROTOCOL_EXPECTATION_FAILED:     // 417
+            r = "Expectation Failed";
+            break;
+        case PROTOCOL_LOCKED:     // 423
+            r = "Locked";
+            break;
+        case PROTOCOL_FAILED_DEPENDENCY:     // 424
+            r = "Failed Dependency";
+            break;
+        case PROTOCOL_SERVER_ERROR:           // 500
+            r = "Server Error";           /* The spec actually says "Internal Server Error" */
+            break;
+        case PROTOCOL_NOT_IMPLEMENTED:        // 501
+            r = "Not Implemented";
+            break;
+        case PROTOCOL_BAD_GATEWAY:            // 502
+            r = "Bad Gateway";
+            break;
+        case PROTOCOL_SERVICE_UNAVAILABLE:    // 503
+            r = "Service Unavailable";
+            break;
+        case PROTOCOL_GATEWAY_TIMEOUT:        // 504            /* HTTP/1.1 */
+            r = "Gateway Timeout";
+            break;
+        case PROTOCOL_VERSION_NOT_SUPPORTED:  // 505            /* HTTP/1.1 */
+            r = "HTTP Version Not Supported";
+            break;
+        case PROTOCOL_INSUFFICIENT_STORAGE:  // 507
+            r = "Insufficient Storage";
+            break;
+        default:
+            switch (code / 100)
+            {
+                case 1:
+                    r = "Information";
+                    break;
+                case 2:
+                    r = "Success";
+                    break;
+                case 3:
+                    r = "Redirect";
+                    break;
+                case 4:
+                    r = "Client error";
+                    break;
+                case 5:
+                    r = "Server error";
+                    break;
+                default:
+                    r = "Unknown reason";
+                    break;
+            }
+            break;
+    }
+
+    return r;
+}
+
+
+void add_http_status_line(sbuf_t *out, pool_handle_t *pool, Request *rq) {
+    sbuf_write(out, "HTTP/1.1 ", 9);
+
+    char *status_code_str = pool_malloc(pool, 8);
+    int sc_len = snprintf(status_code_str, 8, "%d ", rq->status_num);
+    sbuf_write(out, status_code_str, sc_len);
+    
+    char *scmsg = pblock_findkeyval(pb_key_status, rq->srvhdrs);
+    sbuf_write(out, scmsg, strlen(scmsg));
+
+    sbuf_write(out, "\r\n", 2);
+}
+
+void add_http_response_header(sbuf_t *out, Request *rq) {
+    pblock   *h = rq->srvhdrs;
+    pb_entry *p;
+
+    for(int i=0;i<h->hsize;i++) {
+        p = h->ht[i];
+        while(p != NULL) {
+            /* from http.cpp */
+            const pb_key *key = PARAM_KEY(p->param);
+            if (key == pb_key_status || key == pb_key_server || key == pb_key_date) {
+                /* Skip internal Status:, Server:, and Date: information */
+                p = p->next;
+                continue;
+            }
+            /* end http.cpp */
+
+            char *name  = p->param->name;
+            char *value = p->param->value;
+
+            /* make first char of name uppercase */
+            if(name[0] > 90) {
+                name[0] -= 32;
+            }
+
+            sbuf_write(out, name, strlen(name));
+            sbuf_write(out, ": ", 2);
+            sbuf_write(out, value, strlen(value));
+            sbuf_write(out, "\r\n", 2);
+
+            p = p->next;
+        }
+    }
+}
+
+int http_start_response(Session *sn, Request *rq) {
+    int fd = ((SystemIOStream*)sn->csd)->fd;
+
+    /* set socket blocking */
+    int flags;
+    flags = fcntl(fd, F_GETFL, 0);
+    fcntl(fd, F_SETFL, flags ^ O_NONBLOCK);
+
+    /* iovec output buffer */
+    sbuf_t *out = sbuf_new(512);
+
+    /* add the http status line to the output buffer */
+    add_http_status_line(out, sn->pool, rq);
+
+    /* add server header */
+    sbuf_write(out, "Server: WS uap-dev\r\n", 20);
+
+    /* add header from rq->srvhdrs */
+    add_http_response_header(out, rq);
+
+    /* response header end */
+    sbuf_write(out, "\r\n", 2);
+
+    /* flush buffer to the socket */
+    write(fd, out->ptr, out->length);
+    sbuf_free(out);
+    
+    rq->senthdrs = 1;
+}
+
+int request_header(char *name, char **value, Session *sn, Request *rq) {
+    const pb_key *key = pblock_key(name);
+    pb_param *pp = pblock_findkey(key, rq->headers);
+    if(pp != NULL) {
+        value = &pp->value;
+        return REQ_PROCEED;
+    } else {
+        return REQ_ABORTED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/protocol.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,58 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTTP_H
+#define	HTTP_H
+
+#include "../public/nsapi.h"
+#include "../util/io.h"
+#include <sys/uio.h>
+#include "../util/strbuf.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void protocol_status(Session *sn, Request *rq, int n, const char *m);
+const char* protocol_status_message(int code);
+
+void add_http_status_line(sbuf_t *out, pool_handle_t *pool, Request *rq);
+void add_http_response_header(sbuf_t *out, Request *rq);
+
+int http_start_response(Session *sn, Request *rq);
+
+int request_header(char *name, char **value, Session *sn, Request *rq);
+
+#define sbuf_write(out, buf, len) sbuf_append(out, sstrn(buf, len))
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* HTTP_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/request.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "request.h"
+
+#include "../util/pblock.h"
+#include "httprequest.h"
+
+
+/* Code from req.cpp */
+/* fremden Code durch eigenen ersetzen */
+
+/* -------------------------- request_initialize -------------------------- */
+
+int request_initialize(
+        pool_handle_t *pool,
+        HTTPRequest *hrq,
+        NSAPIRequest *nrq)
+{
+    Request *rq = &nrq->rq;
+
+    rq->vars = pblock_create_pool(pool, REQ_HASHSIZE);
+    if (!rq->vars)
+        return 1;
+    rq->reqpb = pblock_create_pool(pool, REQ_HASHSIZE);
+    if (!rq->reqpb)
+        return 1;
+    rq->loadhdrs = 0;
+    rq->headers = pblock_create_pool(pool, REQ_HASHSIZE);
+    if (!rq->headers)
+        return 1;
+    rq->senthdrs = 0;
+    rq->srvhdrs = pblock_create_pool(pool, REQ_HASHSIZE);
+    if (!rq->srvhdrs)
+        return 1;
+
+    rq->os = NULL;
+    rq->tmpos = NULL;
+    rq->statpath = NULL;
+    rq->staterr = NULL;
+    rq->finfo = NULL;
+    rq->aclstate = 0;
+    rq->acldirno = 0;
+    rq->aclname = NULL;
+    rq->aclpb = NULL;
+    rq->acllist = NULL;
+    rq->request_is_cacheable = 0;
+    rq->directive_is_cacheable = 0;
+    rq->cached_headers = NULL;
+    rq->cached_headers_len = 0;
+    rq->unused = NULL;
+    //rq->req_start = ft_time(); // TODO: ft_time
+    rq->protv_num = 0;
+    rq->method_num = -1;
+    //PR_ASSERT(sizeof(rq->rq_attr) == sizeof(RQATTR)); // TODO: assert
+    *(RQATTR *) &rq->rq_attr = 0;
+    //rq->hostname = pool_strdup(pool, hostname); // TODO: hostname
+    rq->allowed = 0;
+    rq->byterange = 0;
+    rq->status_num = 0;
+    rq->staterrno = 0;
+    rq->orig_rq = rq;
+
+    // TODO: nrq
+
+    /* NSAPI execution context */
+    nrq->context.last_req_code = REQ_NOACTION;
+
+    nrq->context.objset_index = -1;
+    nrq->context.dtable_index = 0;
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/request.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef REQUEST_H
+#define	REQUEST_H
+
+#include "../public/nsapi.h"
+#include "../util/object.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct NSAPIRequest NSAPIRequest;
+
+struct NSAPIRequest {
+    Request        rq;
+    RequestPhase   phase;
+    VirtualServer  *vs;
+    NSAPIContext   context;
+};
+
+/* macros for short context access */
+#define NCX_OI(rq) rq->context.objset_index
+#define NCX_DI(rq) rq->context.dtable_index
+
+#define REQ_HASHSIZE 10
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* REQUEST_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/session.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../public/nsapi.h"
+
+#include "session.h"
+
+NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify) {
+    // TODO: implement
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/session.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,52 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SESSION_H
+#define	SESSION_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct NSAPISession NSAPISession;
+
+struct NSAPISession {
+    Session sn; /* public session structure */
+    int sys_fd; /* system file descriptor */
+};
+
+NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* SESSION_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/sessionhandler.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,103 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../public/nsapi.h"
+
+#include "sessionhandler.h"
+#include "httprequest.h"
+#include "httpparser.h"
+
+SessionHandler* create_basic_session_handler() {
+    BasicSessionHandler *handler = malloc(sizeof(BasicSessionHandler));
+    handler->threadpool = threadpool_new(8);
+    handler->sh.enqueue_connection = basic_enq_conn;
+
+
+    return (SessionHandler*)handler;
+}
+
+void basic_enq_conn(SessionHandler *handler, Connection *conn) {
+    BasicSessionHandler *sh = (BasicSessionHandler*)handler;
+    conn->session_handler = handler;
+    threadpool_run(sh->threadpool, basic_run_session, conn);
+}
+
+void* basic_run_session(void *data) {
+    Connection *conn = (Connection*)data;
+
+    HTTPRequest *request = http_request_new();
+    request->connection = conn;
+
+    // read request
+    netbuf *buf = malloc(sizeof(netbuf));
+    buf->rdtimeout = 120;
+    buf->pos = 0;
+    buf->cursize = 0;
+    buf->maxsize = 2048;
+    buf->sd = &conn->fd;
+    buf->inbuf = malloc(2048);
+    buf->errmsg = NULL;
+
+    request->netbuf = buf;
+
+    HttpParser *parser = http_parser_new(request);
+    int state;
+    int r;
+    r = read(conn->fd, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
+    if(r == -1) {
+         // TODO: error handling
+        fprintf(stderr, "%s\n", "Error: Cannot read from socket");
+        return NULL;
+    }
+    buf->cursize += r;
+    while((state = http_parser_process(parser)) != 0) {
+        if(state == 2) {
+            // TODO: error handling
+            fprintf(stderr, "%s\n", "Error: Cannot parse http request");
+            return NULL;
+        }
+        r = read(conn->fd, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
+        if(r == -1) {
+            // TODO: error handling
+            fprintf(stderr, "%s\n", "Error: Cannot read from socket");
+            return NULL;
+        }
+        buf->cursize += r;
+    }
+
+    // process request
+    r = handle_request(request);
+
+
+    return NULL;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/sessionhandler.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SESSIONHANDLER_H
+#define	SESSIONHANDLER_H
+
+#include "../util/thrpool.h"
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct _session_handler   SessionHandler;
+typedef struct _connection        Connection;
+
+struct _connection {
+    int fd;
+    struct sockaddr_in address;
+    SessionHandler *session_handler;
+};
+
+typedef void(*enqueue_connection_f)(SessionHandler*, Connection*);
+struct _session_handler {
+    enqueue_connection_f enqueue_connection;
+};
+
+/*
+ * BasicSessionHandler
+ *
+ * The BasicSessionHandler enqueues the connections to a threadpool. IO and
+ * request processing is handled by one thread.
+ */
+typedef struct _basic_session_handler {
+    SessionHandler sh;
+    threadpool_t   *threadpool;
+    
+} BasicSessionHandler;
+
+
+SessionHandler* create_basic_session_handler();
+
+void basic_enq_conn(SessionHandler *handler, Connection *conn);
+
+void* basic_run_session(void *data);
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* SESSIONHANDLER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/vserver.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vserver.h"
+
+VirtualServer* vs_new() {
+    VirtualServer *vs = malloc(sizeof(VirtualServer));
+    vs->default_obj_name = NULL;
+    vs->objects = NULL;
+    vs->document_root = sstr("docs");
+    return vs;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/vserver.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VSERVER_H
+#define	VSERVER_H
+
+#include "../util/object.h"
+#include "../public/nsapi.h"
+
+#include "../ucx/sstring.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct VirtualServer {
+    char              *default_obj_name;
+    HTTPObjectConfig  *objects;
+
+    sstr_t            document_root;
+};
+
+VirtualServer* vs_new();
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* VSERVER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/webserver.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h> 
+
+#include "../public/nsapi.h"
+#include "../util/systhr.h"
+
+#include "func.h"
+#include "conf.h"
+#include "httplistener.h"
+#include "webserver.h"
+
+
+extern struct FuncStruct webserver_funcs[];
+
+
+int webserver_init() {
+    // init NSPR
+    systhread_init("webserver");
+
+    // init NSAPI functions
+    func_init();
+    add_functions(webserver_funcs);
+
+    // load init.conf
+    load_init_conf(NULL);
+
+    // load server.conf
+    load_server_conf(NULL);
+
+    // init NSAPI functions
+
+
+    return 0;
+}
+
+int webserver_run() {
+    printf("webserver_run\n");
+
+    // start all http listener
+    if(start_all_listener() != 0) {
+        fprintf(stderr, "Error: Cannot start http listener\n");
+    }
+
+    return 0;
+}
+
+
+void webserver_atrestart(void (*fn)(void *), void *data) {
+    /*
+     * TODO: implement later
+     * only for mod_jk at this time
+     */
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/webserver.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WEBSERVER_H
+#define	WEBSERVER_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int webserver_init();
+int webserver_run();
+
+
+void webserver_atrestart(void (*fn)(void *), void *data);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* WEBSERVER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/ws-fn.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../public/nsapi.h"
+
+#include "../safs/nametrans.h"
+#include "../safs/objecttype.h"
+#include "../safs/service.h"
+#include "../webdav/webdav.h"
+
+struct FuncStruct webserver_funcs[] = {
+    { "test-nametrans", test_nametrans, NULL, 0 },
+    { "assign-name", assign_name, NULL, 0},
+    { "type-by-extension", object_type_by_extension, NULL, 0},
+    { "send-file", send_file, NULL, 0},
+    { "common-index", service_index, NULL, 0},
+    { "service-hello", service_hello, NULL, 0},
+    { "webdav-service", webdav_service, NULL, 0},
+    {NULL, NULL, NULL, 0}
+};
--- a/src/server/davparser.cpp	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "davparser.h"
-
-#include "pool.h"
-#include "pblock.h"
-
-#include "saxhandler.h"
-
-#include <xercesc/sax2/SAX2XMLReader.hpp>
-#include <xercesc/sax2/XMLReaderFactory.hpp>
-#include <xercesc/sax2/DefaultHandler.hpp>
-#include <xercesc/util/XMLString.hpp>
-#include <xercesc/framework/MemBufInputSource.hpp>
-
-XERCES_CPP_NAMESPACE_USE;
-
-int xcinit = 0;
-
-PropfindRequest* dav_parse_propfind(
-        Session *sn,
-        Request *rq,
-        char *xml,
-        size_t len)
-{
-    if(!xcinit) {
-        /* TODO: create webdav module init function */
-        XMLPlatformUtils::Initialize();
-        xcinit = 1;
-    }
-    PropfindRequest *davrq = (PropfindRequest*)pool_malloc(
-            sn->pool,
-            sizeof(PropfindRequest));
-    davrq->allprop = 0;
-    davrq->propname = 0;
-    davrq->properties = NULL;
-    // create xml parser
-    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
-    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
-
-    PropfindHandler handler(davrq, sn->pool);
-    parser->setContentHandler(&handler);
-    parser->setErrorHandler(&handler);
-
-    MemBufInputSource source((XMLByte*)xml, (XMLSize_t)len, "wsid");
-    try {
-        parser->parse(source);
-    }
-    catch (const XMLException& e) {
-        printf("XMLException\n");
-        
-    }
-    catch (const SAXParseException& e) {
-        printf("SAXParseException\n");
-        
-    }
-    catch (...) {
-        printf("davaparser Exception\n");
-    }
-
-    
-    
-
-    return davrq;
-}
--- a/src/server/davparser.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DAVPARSER_H
-#define	DAVPARSER_H
-
-#include "nsapi.h"
-
-#include "dlist.h"
-#include <inttypes.h>
-#include "webdav.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-PropfindRequest* dav_parse_propfind(
-        Session *sn,
-        Request *rq,
-        char *xml,
-        size_t len);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* DAVPARSER_H */
-
--- a/src/server/dlist.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-#include "dlist.h"
-
-void ucx_dlist_free(UcxDlist *l) {
-    UcxDlist *e = l, *f;
-    while (e != NULL) {
-        f = e;
-        e = e->next;
-        free(f);
-    }
-}
-
-UcxDlist *ucx_dlist_append(UcxDlist *l, void *data)  {
-    UcxDlist *nl = (UcxDlist*) malloc(sizeof(UcxDlist));
-    if (nl == NULL) return NULL;
-
-    nl->data = data;
-    nl->next = NULL;
-    if (l == NULL) {
-        return nl;
-    } else {
-        UcxDlist *t = ucx_dlist_last(l);
-        t->next = nl;
-        nl->prev = t;
-        return l;
-    }
-}
-
-UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data) {
-    UcxDlist *nl = ucx_dlist_append(NULL, data);
-    if (nl == NULL) return NULL;
-
-    if (l != NULL) {
-        nl->next = l;
-        l->prev = nl;
-    }
-    return nl;
-}
-
-UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2) {
-    if (l1 == NULL) {
-        return l2;
-    } else {
-        UcxDlist *last = ucx_dlist_last(l1);
-        last->next = l2;
-        l2->prev = last;
-        return l1;
-    }
-}
-
-UcxDlist *ucx_dlist_last(UcxDlist *l) {
-    if (l == NULL) return NULL;
-
-    UcxDlist *e = l;
-    while (e->next != NULL) {
-        e = e->next;
-    }
-    return e;
-}
-
-UcxDlist *ucx_dlist_get(UcxDlist *l, int index) {
-    if (l == NULL) return NULL;
-
-    UcxDlist *e = l;
-    while (e->next != NULL && index > 0) {
-        e = e->next;
-        index--;
-    }
-
-    return index == 0 ? e : NULL;
-}
-
-size_t ucx_dlist_size(UcxDlist *l) {
-    if (l == NULL) return 0;
-
-    UcxDlist *e = l;
-    size_t s = 1;
-    while (e->next != NULL) {
-        e = e->next;
-        s++;
-    }
-
-    return s;
-}
-
-void ucx_dlist_foreach(UcxDlist *l, ucx_callback fnc, void* data) {
-    UcxDlist *e = l;
-    while (e != NULL) {
-        fnc(e, data);
-        e = e->next;
-    }
-}
-
-/* dlist specific functions */
-UcxDlist *ucx_dlist_first(UcxDlist *l) {
-    if (l == NULL) return NULL;
-
-    UcxDlist *e = l;
-    while (e->prev != NULL) {
-        e = e->prev;
-    }
-    return e;
-}
--- a/src/server/dlist.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- *
- */
-
-#ifndef DLIST_H
-#define	DLIST_H
-
-#include "ucx.h"
-#include <stddef.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct UcxDlist UcxDlist;
-struct UcxDlist {
-    void     *data;
-    UcxDlist *next;
-    UcxDlist *prev;
-};
-
-void ucx_dlist_free(UcxDlist *l);
-UcxDlist *ucx_dlist_append(UcxDlist *l, void *data);
-UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data);
-UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2);
-UcxDlist *ucx_dlist_last(UcxDlist *l);
-UcxDlist *ucx_dlist_get(UcxDlist *l, int index);
-size_t ucx_dlist_size(UcxDlist *l);
-void ucx_dlist_foreach(UcxDlist *l, ucx_callback fnc, void* data);
-
-/* dlist specific functions */
-UcxDlist *ucx_dlist_first(UcxDlist *l);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* DLIST_H */
-
--- a/src/server/ereport.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_EREPORT_H
-#define BASE_EREPORT_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * ereport.h: Records transactions, reports errors to administrators, etc.
- * 
- * Rob McCool
- */
-
-#ifndef BASE_SESSION_H
-#include "session.h"
-#endif /* !BASE_SESSION_H */
-
-/* Pseudo-filename to enable logging to syslog */
-#define EREPORT_SYSLOG "SYSLOG"
-
-/* NSAPI degrees used by Java but not exposed in nsapi.h */
-#define LOG_FINER  7
-#define LOG_FINEST 8
-
-/* --- Begin function prototypes --- */
-
-#ifdef INTNSAPI
-
-NSPR_BEGIN_EXTERN_C
-
-/*
- * INTereport logs an error of the given degree and formats the arguments with 
- * the printf() style fmt. Returns whether the log was successful. Records 
- * the current date.
- */
-
-NSAPI_PUBLIC int INTereport(int degree, const char *fmt, ...);
-NSAPI_PUBLIC int INTereport_v(int degree, const char *fmt, va_list args);
-
-/*
- * INTereport_init initializes the error logging subsystem and opens the static
- * file descriptors. It returns NULL upon success and an error string upon
- * error. If a userpw is given, the logs will be chowned to that user.
- */
-
-NSAPI_PUBLIC
-char *INTereport_init(const char *err_fn, const char *email, struct passwd *pwuser, const char *version, int restarted);
-
-NSAPI_PUBLIC void INTereport_terminate(void);
-
-/* For restarts */
-NSAPI_PUBLIC SYS_FILE INTereport_getfd(void);
-
-NSPR_END_EXTERN_C
-
-#ifdef __cplusplus
-class EreportableException;
-NSAPI_PUBLIC int INTereport_exception(const EreportableException& e);
-#endif
-
-/* --- End function prototypes --- */
-
-#define ereport INTereport
-#define ereport_v INTereport_v
-#define ereport_init INTereport_init
-#define ereport_terminate INTereport_terminate
-#define ereport_getfd INTereport_getfd
-#define ereport_exception INTereport_exception
-
-typedef int (EreportFunc)(const VirtualServer* vs, int degree, const char *formatted, int formattedlen, const char *raw, int rawlen, void *data);
-
-void ereport_set_servername(const char* name);
-void ereport_set_logvsid(PRBool b);
-void ereport_set_logall(PRBool b);
-void ereport_set_alwaysreopen(PRBool b);
-void ereport_set_timefmt(const char* timeFmt);
-void ereport_set_degree(int degree);
-int ereport_level2degree(const char *level, int defdegree);
-PRBool ereport_can_log(int degree);
-int ereport_request(Request* rq, int degree, const char *fmt, ...);
-char *ereport_abs_filename(const char *filename);
-void ereport_rotate(const char* ext);
-void ereport_set_rotate_callback(void (*fn)(const char* filenameNew, const char* filenameOld));
-void ereport_reopen(void);
-void ereport_outofmemory(void);
-void ereport_disaster(int degree, const char *fmt, ...);
-NSAPI_PUBLIC int ereport_register_cb(EreportFunc* ereport_func, void* data);
-NSAPI_PUBLIC int ereport_register_thread_cb(EreportFunc* ereport_func, void* data);
-
-#endif /* INTNSAPI */
-
-#endif /* !BASE_EREPORT_H */
--- a/src/server/func.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <stdlib.h>
-
-#include "nsapi.h"
-#include "map.h"
-#include "func.h"
-
-hashmap_t *function_map;
-
-void func_init() {
-    function_map = hashmap_new(128);
-}
-
-void add_function(struct FuncStruct *func) {
-    printf("add function: %s\n", func->name);
-
-    struct FuncStruct *f = malloc(sizeof(FuncStruct));
-    *f = *func;
-    hashmap_put(function_map, sstr((char*)f->name), func);
-}
-
-void add_functions(struct FuncStruct *funcs) {
-    int i = 0;
-    while(funcs[i].func != NULL) {  
-        add_function(&funcs[i]);
-        i++;
-    }
-}
-
-FuncStruct* get_function(char *name) {
-    return hashmap_get(function_map, sstr(name));
-}
--- a/src/server/func.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef FUNC_H
-#define	FUNC_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-void func_init();
-
-void add_function(struct FuncStruct *func);
-
-void add_functions(struct FuncStruct *funcs);
-
-FuncStruct* get_function(char *name);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* FUNC_H */
-
--- a/src/server/httplistener.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "nsapi.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/shm.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <strings.h>
-#include <stdbool.h>
-#include <pthread.h>
-
-#include "map.h"
-#include "httplistener.h"
-
-#include "session.h"
-
-hashmap_t *listener_map = NULL;
-
-
-int start_all_listener() {
-    HttpListener *listener = get_http_listener("default");
-    http_listener_start(listener); 
-
-    return 0;
-}
-
-HttpListener* get_http_listener(char *name) {
-    return hashmap_get(listener_map, sstr(name));
-}
-
-
-HttpListener* http_listener_new(ListenerConfig *conf) {
-    HttpListener *listener = malloc(sizeof(HttpListener));
-    listener->session_handler = create_basic_session_handler();
-    listener->nacceptors = conf->nacceptors;
-
-    struct sockaddr_in servaddr;   /* server address */
-
-    /* init address structure */
-    memset(&servaddr, 0, sizeof(servaddr));
-    servaddr.sin_family = AF_INET;
-    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-    servaddr.sin_port = htons(conf->port);
-
-    /* create socket */
-    if((listener->server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-        perror("Error: http_listener_new: socket");
-        return NULL;
-    }
-
-    int o = 1;
-    setsockopt(
-            listener->server_socket,
-            SOL_SOCKET, SO_REUSEADDR,
-            &o,
-            sizeof(int));
-
-    /* bind server socket to address */
-    if(bind(listener->server_socket, (struct sockaddr*)&servaddr, sizeof(servaddr))){
-        perror("Error: http_listener_new: bind");
-        return NULL;
-    }
-
-    /* create acceptors */
-    listener->acceptors = calloc(listener->nacceptors, sizeof(void*));
-    for (int i=0;i<listener->nacceptors;i++) {
-        listener->acceptors[i] = acceptor_new(listener);
-    }
-
-    if(listener_map == NULL) {
-        listener_map = hashmap_new(8);
-    }
-    hashmap_put(listener_map, sstr(conf->name), listener);
-    return listener;
-}
-
-int http_listener_start(HttpListener *listener) {
-    printf("INFO: start listener\n");
-
-    if (listen(listener->server_socket, 16) == -1) {
-        perror("Error: http_listener_start: listen");
-        return -1;
-    }
-
-    /* start acceptor threads */
-    for (int i=0;i<listener->nacceptors;i++) {
-        acceptor_start(listener->acceptors[i]);
-    }
-}
-
-
-
-Acceptor* acceptor_new(HttpListener *listener) {
-    Acceptor *acceptor = malloc(sizeof(Acceptor));
-    acceptor->listener = listener;
-    return acceptor;
-}
-
-void acceptor_start(Acceptor *a) {
-    if(pthread_create(
-            &a->tid,
-            NULL,
-            (void*(*)(void*))acceptor_thread,
-            a) != 0)
-    {
-        perror("Error: acceptor_start: pthread_create");
-    }
-}
-
-void* acceptor_thread(Acceptor *acceptor) {
-    HttpListener *listener = acceptor->listener;
-
-    for (;;) {
-        /* accept connections */
-        struct sockaddr_in ca;
-        socklen_t length = sizeof(ca);
-        int clientfd;
-
-        /* accept a connection */
-        clientfd = accept(
-                listener->server_socket,
-                (struct sockaddr*)&ca,
-                &length);
-        if (clientfd == -1) {
-            perror("Error: acceptor_thread: accept");
-            continue;
-        }
-        
-        /* create Connection object */
-        Connection *conn = malloc(sizeof(Connection));
-        conn->address = ca;
-        conn->fd = clientfd;
-
-        /* enqueue the connection */
-        listener->session_handler->enqueue_connection(
-                listener->session_handler,
-                conn);
-
-        /* ready for new connection */
-    }
-}
--- a/src/server/httplistener.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTTPLISTENER_H
-#define	HTTPLISTENER_H
-
-#include "sessionhandler.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct _http_listener    HttpListener;
-typedef struct _acceptor         Acceptor;
-typedef struct _listener_config  ListenerConfig;
-
-struct _listener_config {
-    char           *name;
-    char           *address;
-    int            port;
-    int            nacceptors;
-};
-
-struct _acceptor {
-    pthread_t      tid;
-    HttpListener   *listener;
-};
-
-struct _http_listener {
-    int              server_socket;
-    Acceptor         **acceptors;
-    int              nacceptors;
-    SessionHandler   *session_handler;
-};
-
-int start_all_listener();
-HttpListener* get_http_listener(char *name);
-
-
-HttpListener* http_listener_new(ListenerConfig *conf);
-
-int http_listener_start(HttpListener *listener);
-
-
-Acceptor* acceptor_new(HttpListener *listener);
-
-void acceptor_start(Acceptor *a);
-
-void* acceptor_thread(Acceptor *a);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* HTTPLISTENER_H */
-
--- a/src/server/httpparser.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "httpparser.h"
-#include "nsapi.h"
-//include "request.h"
-
-
-HttpParser* http_parser_new(HTTPRequest *request) {
-    HttpParser *parser = malloc(sizeof(HttpParser));
-    parser->request = request;
-    
-    parser->state = 0;
-    parser->start_line.ptr = (char*)request->netbuf->inbuf;
-    parser->start_line.length = 0;
-
-    return parser;
-}
-
-void http_parser_free(HttpParser *parser) {
-    free(parser);
-}
-
-int http_parser_process(HttpParser *parser) {
-    switch(parser->state) {
-        case 0: {
-            int r = get_start_line(parser);
-            switch(r) {
-                case 0: break;
-                default: return r;
-            }
-            parse_request_line(parser);
-            parser->state++;
-        }
-        case 1: {
-            return http_parser_parse_header(parser);
-        }
-        case 2: {
-            return 0;
-        }
-    }
-}
-
-int get_start_line(HttpParser *parser) {
-    netbuf *buf = parser->request->netbuf;
-    while(buf->pos < buf->cursize) {
-        unsigned char c = buf->inbuf[buf->pos];
-        if(c == '\n') {
-            if(buf->pos <= 1) {
-                // insufficient chars for request, return error
-                return 2;
-            }
-            if(buf->inbuf[buf->pos - 1] == '\r') {
-                parser->start_line.length = buf->pos;
-            } else {
-                parser->start_line.length = buf->pos + 1;
-            }
-            parser->start_line.ptr = (char*)buf->inbuf;
-            buf->pos++;
-            return 0;
-        }
-        buf->pos++;
-    }
-    return 1;
-}
-
-int http_parser_parse_header(HttpParser *parser) {
-    netbuf *buf = parser->request->netbuf;
-
-    parser->offset = buf->pos; // line offset
-    parser->name.ptr = NULL;
-    parser->value.ptr = NULL;
-    while(1) {
-        if(buf->pos >= buf->cursize) {
-            return 1;
-        }
-        char c = (char)buf->inbuf[buf->pos++];
-
-        if(c > 32) {
-            parser->wl = 0;
-            if(c == ':' && parser->value.ptr == NULL) {
-                parser->name.ptr = (char*)buf->inbuf + parser->offset;
-                buf->inbuf[buf->pos-1] = 0;
-            } else if(parser->name.ptr != NULL && parser->value.ptr == NULL) {
-                parser->value.ptr = (char*)buf->inbuf + buf->pos - 1;
-            }
-        } else if(c == '\n') {
-            if(parser->wl) {
-                // line contains only white space -> end of request
-                parser->state++;
-                return 0;
-            } else {
-                parser->offset = buf->pos;
-                if(parser->value.ptr != NULL) {
-                    buf->inbuf[buf->pos-1] = 0;
-                    // add header
-                    header_add(
-                            parser->request->headers,
-                            parser->name.ptr,
-                            parser->value.ptr);
-                } else {
-                    // error: no value
-                    return 2;
-                }
-                parser->name.ptr = NULL;
-                parser->value.ptr = NULL;
-                parser->wl = 1;
-            }
-        }
-    }
-}
-
-int parse_request_line(HttpParser *parser) {
-    sstr_t line = parser->start_line;
-    parser->request->request_line = line;
-    
-    /*
-     * parse method, url and http version
-     */
-    
-    int i = 0;
-    int ns = 0;
-
-    parser->request->method.ptr = line.ptr;
-    for(;i<line.length;i++) {
-        if(!ns && line.ptr[i] == ' ') {
-            ns = 1;
-            //line.ptr[i] = 0; // TODO: remove
-            parser->request->method.length = i;
-        } else if(ns) {
-            if(line.ptr[i] != ' ') {
-                break;
-            }
-        }
-    }
-
-    parser->request->uri.ptr = line.ptr + i;
-    ns = 0;
-    int s = i;
-    for(;i<line.length;i++) {
-        if(!ns && line.ptr[i] < 33) {
-            ns = 1;
-            //line.ptr[i] = 0; // TODO: remove
-            parser->request->uri.length = i - s;
-        } else if(ns) {
-            if(line.ptr[i] > 32) {
-                break;
-            }
-        }
-    }
-
-    parser->request->httpv.ptr = line.ptr + i;
-    ns = 0;
-    s = i;
-    for(;i<line.length;i++) {
-        if(!ns && line.ptr[i] < 33) {
-            ns = 1;
-            //line.ptr[i] = 0; // TODO: remove
-            parser->request->httpv.length = i - s;
-        } else if(ns) {
-            if(line.ptr[i] > 32) {
-                break;
-            }
-        }
-    }
-
-    return 0;
-}
--- a/src/server/httpparser.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTTPPARSER_H
-#define	HTTPPARSER_H
-
-
-#include "sstring.h"
-#include "httprequest.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/*
- * http parser states
- *
- * 0: start line
- * 1: header
- * 2: finish
- */
-
-typedef struct _http_parser {
-    HTTPRequest *request;
-
-    int state;
-    sstr_t start_line;
-
-    /* local parser varaibles */
-    int wl;       /* only white space */
-    int tk;       /* token: 0: header name 1: header value */
-    int offset;   /* offset of parsed string */
-    int strend;   /* end position */
-    sstr_t name;
-    sstr_t value;
-
-} HttpParser;
-
-HttpParser* http_parser_new(HTTPRequest *request);
-void http_parser_free(HttpParser *parser);
-
-/*
- * process http parsing
- *
- * return
- * 0: finish
- * 1: need more data
- * 2: error
- */
-int http_parser_process(HttpParser *parser);
-
-int get_start_line(HttpParser *parser);
-int http_parser_parse_header(HttpParser *parser);
-
-int parse_request_line(HttpParser *parser);
-
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-
-#endif	/* HTTPPARSER_H */
-
--- a/src/server/httprequest.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,532 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#include "nsapi.h"
-#include "pool.h"
-#include "pblock.h"
-#include "io.h"
-#include "util.h"
-#include "httprequest.h"
-#include "conf.h"
-#include "vserver.h"
-
-HTTPRequest *http_request_new() {
-    HTTPRequest *req = malloc(sizeof(HTTPRequest));
-    req->connection = NULL;
-    req->uri.ptr = NULL;
-
-    HeaderArray *hd = malloc(sizeof(HeaderArray));
-    hd->next = NULL;
-    hd->len = 0;
-    hd->headers = calloc(16, sizeof(Header));
-    hd->alloc = 16;
-
-    req->headers = hd;
-
-    return req;
-}
-
-int handle_request(HTTPRequest *request) {
-    // handle nsapi request
-
-    // create pool
-    request->pool = pool_create();
-
-    // create nsapi data structures
-    NSAPISession *sn = malloc(sizeof(NSAPISession));
-    NSAPIRequest *rq = malloc(sizeof(NSAPIRequest));
-    request->rq = rq;
-    rq->phase = NSAPIAuthTrans;
-
-    // fill session structure
-    sn->sys_fd = request->connection->fd;
-    sn->sn.pool = pool_create();
-    sn->sn.csd = stream_new_from_fd(request->connection->fd);
-    sn->sn.client = pblock_create_pool(sn->sn.pool, 8);
-    sn->sn.next = NULL;
-    sn->sn.fill = 1;
-    sn->sn.subject = NULL;
-
-    /* add ip to sn->client pblock */
-    char ip_str[INET_ADDRSTRLEN];
-    if(inet_ntop(
-            AF_INET,
-            &request->connection->address.sin_addr,
-            ip_str,
-            INET_ADDRSTRLEN) != NULL)
-    {
-        pblock_kvinsert(pb_key_ip, ip_str, INET_ADDRSTRLEN, sn->sn.client);
-    }
-
-    // init NSAPI request structure
-    if(request_initialize(request->pool, request, rq) != 0) {
-        printf("Cannot initialize request structure\n");
-        return 1;
-    }
-
-    // set default virtual server
-    rq->vs = conf_get_default_vs();
-
-
-    /* Pass request line as "clf-request" */
-    pblock_kvinsert(
-            pb_key_clf_request,
-            request->request_line.ptr,
-            request->request_line.length,
-            rq->rq.reqpb);
-
-    /* Pass method as "method" in reqpb, and also as method_num */
-    pblock_kvinsert(
-            pb_key_method,
-            request->method.ptr,
-            request->method.length,
-            rq->rq.reqpb);
-    // TODO: method num
-    //rqRq.rq.method_num = rqHdr->GetMethodNumber();
-    //PR_ASSERT(rqRq.rq.method_num != -1 || iStatus);
-    
-    /* Pass protocol as "protocol" in reqpb, and also in protv_num */
-    pblock_kvinsert(
-            pb_key_protocol,
-            request->httpv.ptr,
-            request->httpv.length,
-            rq->rq.reqpb);
-    // TODO: protocol num
-
-    /* Pass any query as "query" in reqpb */
-    // TODO: query
-
-    /* Get abs_path part of request URI, and canonicalize the path */
-    sstr_t absPath = request->uri;
-    // TODO: get abs_path
-    absPath.ptr = util_canonicalize_uri(
-            request->pool,
-            absPath.ptr,
-            absPath.length,
-            (int*)&absPath.length);
-
-    /* Decode the abs_path */
-    // TODO: decode abs_path
-
-    /* Pass the abs_path as "uri" in reqpb */
-    // TODO: pass abs_path to reqpb
-    // TODO: replace this code
-    pblock_kvinsert(
-            pb_key_uri,
-            absPath.ptr,
-            absPath.length,
-            rq->rq.reqpb);
-
-    // pass http header to the NSAPI request structure
-    int         hlen = request->headers->len;
-    HeaderArray *ha  = request->headers;
-    for(int i=0;i<=hlen;i++) {
-        if(i == hlen) {
-            ha = ha->next;
-            if(ha == NULL) {
-                break;
-            }
-            i = 0;
-            hlen = ha->len;
-        }
-
-        if(ha->headers[i].name[0] < 90) {
-            ha->headers[i].name[0] += 32;
-        }
-        pblock_nvinsert(ha->headers[i].name, ha->headers[i].value, rq->rq.headers);
-    }
-
-    /* check for request body and prepare input buffer */
-    char *ctlen_str = pblock_findkeyval(pb_key_content_length, rq->rq.headers);
-    if(ctlen_str) {
-        int ctlen = atoi(ctlen_str);
-        
-        printf("request body length: %d\n", ctlen);
-
-        netbuf *nb = request->netbuf;
-
-        /* create new netbuf */
-        NetIOStream *net_io = (NetIOStream*)net_stream_from_fd(
-                request->connection->fd);
-        net_io->max_read = ctlen;
-
-        sn->sn.inbuf = malloc(sizeof(netbuf));
-        sn->sn.inbuf->sd = net_io;
-        sn->sn.inbuf->pos = 0;
-        
-        /* prepare buffer */
-        int cur_input_len = nb->cursize - nb->pos;
-        if(cur_input_len >= ctlen) {
-
-            /*
-             * all data is already in the primary input buffer
-             * just link the new netbuf to the primary buffer
-             */
-            sn->sn.inbuf->maxsize = ctlen;
-            sn->sn.inbuf->cursize = ctlen;
-            sn->sn.inbuf->inbuf = nb->inbuf + nb->pos;
-        } else {
-            sn->sn.inbuf->maxsize = (ctlen > 2048) ? (2048) : (ctlen);
-            sn->sn.inbuf->inbuf = malloc(sizeof(sn->sn.inbuf->maxsize));
-
-            if(cur_input_len > 0) {
-                /* we have read a part of the request body -> copy to netbuf */
-                memcpy(sn->sn.inbuf->inbuf, nb->inbuf+nb->pos, cur_input_len);
-            }
-
-            sn->sn.inbuf->cursize = cur_input_len;
-        }
-    } else {
-        sn->sn.inbuf = NULL;
-    }
-
-
-    // Send the request to the NSAPI system
-    nsapi_handle_request(sn, rq);
-
-    return 0;
-}
-
-
-
-void header_add(HeaderArray *hd, char *name, char *value) {
-    while(hd->len >= hd->alloc) {
-        if(hd->next == NULL) {
-            HeaderArray *block = malloc(sizeof(HeaderArray));
-            block->next = NULL;
-            block->len = 0;
-            block->headers = calloc(16, sizeof(Header));
-            block->alloc = 16;
-            hd->next = block;
-        }
-        hd = hd->next;
-    }
-    hd->headers[hd->len].name = name;
-    hd->headers[hd->len].value = value;
-    hd->len++;
-}
-
-
-/*
- * NSAPI Processing
- * TODO: add this to new file
- */
-
-int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq) {
-    // TODO: threadpool
-
-    int r = REQ_NOACTION;
-
-    do {
-        switch(rq->phase) {
-            case NSAPIAuthTrans: {
-                rq->phase++;
-                nsapi_context_next_stage(&rq->context);
-            }
-            case NSAPINameTrans: {
-                printf(">>> NameTrans\n");
-                r = nsapi_nametrans(sn, rq);
-                if(r != REQ_PROCEED) {
-                    break;
-                }
-                rq->phase++;
-                nsapi_context_next_stage(&rq->context);
-            }
-            case NSAPIPathCheck: {
-                printf(">>> PathCheck\n");
-                rq->phase++;
-                nsapi_context_next_stage(&rq->context);
-            }
-            case NSAPIObjectType: {
-                printf(">>> ObjectType\n");
-                r = nsapi_objecttype(sn, rq);
-                if(r != REQ_PROCEED) {
-                    break;
-                }
-                rq->phase++;
-                nsapi_context_next_stage(&rq->context);
-            }
-            case NSAPIService: {
-                printf(">>> Service\n");
-                r = nsapi_service(sn, rq);
-                if(r != REQ_PROCEED) {
-                    break;
-                }
-                rq->phase++;
-                nsapi_context_next_stage(&rq->context);
-            }
-            case NSAPIAddLog: {
-                printf(">>> AddLog\n");
-                rq->phase++;
-                nsapi_context_next_stage(&rq->context);
-            }
-            case REQ_FINISH: {
-                printf(">>> Finish\n");
-                r = nsapi_finish_request(sn, rq);
-            }
-        }
-    } while (r == REQ_RESTART);
-
-
-    return r;
-}
-
-int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq) {
-    // TODO: free memory
-    close(sn->sys_fd);
-
-    return 0;
-}
-
-int nsapi_nametrans(NSAPISession *sn, NSAPIRequest *rq) {
-    HTTPObjectConfig *objconf = rq->vs->objects;
-    printf("nsapi_nametrans\n");
-    httpd_objset *objset = objset_create(sn->sn.pool);
-    rq->rq.os = objset;
-    /* first object in objconf is the default object  TODO: make sure it is */
-    objset_add_object(sn->sn.pool, objset, objconf->objects[0]);
-
-    httpd_object *obj = objset->obj[0]; /* nametrans only in default object */
-    dtable *dt = object_get_dtable(obj, NSAPINameTrans);
-
-    /* execute directives */
-    int ret = rq->context.last_req_code;
-    char *name = NULL;
-    char *ppath = NULL;
-    for(int i=NCX_DI(rq);i<dt->ndir;i++) {
-        directive *d = dt->dirs[i];
-
-        ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
-
-        /* check for name or ppath */
-        name = pblock_findkeyval(pb_key_name, rq->rq.vars);
-        ppath = pblock_findkeyval(pb_key_ppath, rq->rq.vars);
-
-        /* add additional objects to the objset */
-        if(add_objects(objconf, objset, sn, rq, name, ppath) == REQ_ABORTED) {
-            fprintf(stderr, "add_objects failed\n");
-            return REQ_ABORTED;
-        }
-
-        if(ret != REQ_NOACTION) {
-            /*
-             * if a saf is still processing, we need to save the context, to
-             * process this object at a later time
-             */
-            if(ret == REQ_PROCESSING) {
-                /* save nsapi context */
-                /* add +1 to start next round with next function */
-                rq->context.dtable_index = i + 1;
-            }
-
-            return ret;
-        }
-    }
-
-    /* if no function has set the ppath var, translate it to docroot */
-    if(ret == REQ_NOACTION && ppath == NULL) {
-        sstr_t docroot = rq->vs->document_root;
-        if(docroot.length < 1) {
-            printf("docroot too short\n");
-            return REQ_ABORTED; /* docroot too short */
-        }
-        /* if there is a trailing '/', remove it */
-        if(docroot.ptr[docroot.length - 1] == '/') {
-            docroot.length--;
-        }
-
-        sstr_t uri = sstr(pblock_findkeyval(pb_key_uri, rq->rq.reqpb));
-
-        sstr_t translated;
-        translated.length = docroot.length + uri.length;
-        translated.ptr = alloca(translated.length + 1);
-        translated = sstrncat(2, translated, docroot, uri);
-
-        pblock_kvinsert(
-            pb_key_ppath,
-            translated.ptr,
-            translated.length,
-            rq->rq.vars);
-    }
-
-    return REQ_PROCEED;
-}
-
-int nsapi_objecttype(NSAPISession *sn, NSAPIRequest *rq) {
-    printf("nsapi_objecttype\n");
-    httpd_objset *objset = rq->rq.os;
-
-    if(NCX_OI(rq) == -1) {
-        /* object index is undefined -> define correct object index */
-        NCX_OI(rq) = objset->pos - 1;
-    }
-
-    int ret = rq->context.last_req_code;
-    for(int i=NCX_OI(rq);i>=0;i--) {
-        httpd_object *obj = objset->obj[i];
-        dtable *dt = object_get_dtable(obj, NSAPIObjectType);
-
-        // execute directives
-        for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->dirs[j];
-
-            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
-            switch(ret) {
-                case REQ_PROCEED: {
-                    char *type = pblock_findkeyval(
-                            pb_key_content_type,
-                            rq->rq.srvhdrs);
-                    if(type == NULL) {
-                        ret = REQ_NOACTION;
-                        break;
-                    }
-                    return ret;
-                }
-                case REQ_PROCESSING: {
-                    /* save nsapi context */
-                    rq->context.objset_index = i;
-
-                    /* add +1 to start next round with next function */
-                    rq->context.dtable_index = j + 1;
-                    return ret;
-                }
-                case REQ_NOACTION: {
-                    break;
-                }
-                default: {
-                    return ret;
-                }
-            }
-        }
-    }
-
-    /*
-     * No function returned with REQ_PROCEED, but we need a content type.
-     * If the path ends with a '/', we set the content type to
-     * 'internal/directory' so that 'index-common' can serve the content.
-     * Otherwise we set the content type to text/plain
-     */
-    sstr_t path = sstr(pblock_findkeyval(pb_key_ppath, rq->rq.vars));
-    sstr_t ct;
-    if(path.ptr[path.length - 1] == '/') {
-        /* directory */
-        ct = sstrn("internal/directory", 18);
-    } else {
-        ct = sstrn("text/plain", 10);
-    }
-    pblock_kvinsert(pb_key_content_type, ct.ptr, ct.length, rq->rq.srvhdrs);
-
-    return REQ_PROCEED;
-}
-
-int nsapi_service(NSAPISession *sn, NSAPIRequest *rq) {
-    printf("nsapi_service\n");
-    httpd_objset *objset = rq->rq.os;
-
-    if(NCX_OI(rq) == -1) {
-        NCX_OI(rq) = objset->pos - 1;
-    }
-
-    int ret = rq->context.last_req_code;
-    char *content_type = NULL;
-    for(int i=NCX_OI(rq);i>=0;i--) {
-        httpd_object *obj = objset->obj[i];   
-        dtable *dt = object_get_dtable(obj, NSAPIService);
-
-        // execute directives
-        for(int j=0;j<dt->ndir;j++) {
-            directive *d = dt->dirs[j];
-
-            /* check type parameter */           
-            char *dtp = pblock_findkeyval(pb_key_type, d->param);
-            if(dtp) {
-                /* type parameter for directive */
-                if(!content_type) {
-                    content_type = pblock_findkeyval(
-                            pb_key_content_type,
-                            rq->rq.srvhdrs);
-                }
-                /* compare types */
-                if(strcmp(dtp, content_type) != 0) {
-                    continue;
-                }
-            }
-
-            ret = d->func->func(d->param, (Session*)sn, (Request*)rq);
-            if(ret != REQ_NOACTION) {
-                if(ret == REQ_PROCESSING) {
-                    /* save nsapi context */
-                    rq->context.objset_index = i;
-
-                    /* add +1 to start next round with next function */
-                    rq->context.dtable_index = j + 1;
-                }
-
-                return ret;
-            }
-        }
-    }
-
-    return ret;
-}
-
-/*
- * adds objects with specific name or path to the httpd_objset
- */
-int add_objects(
-        HTTPObjectConfig *objs,
-        httpd_objset *os,
-        NSAPISession *sn,
-        NSAPIRequest *rq,
-        char *name,
-        char *path)
-{
-    /* first, add all objects with a matching path */
-    /* TODO */
-
-
-    /* add object with object with matching name */
-    if(name == NULL) {
-        return REQ_PROCEED;
-    }
-
-    for(int i=0;i<objs->nobj;i++) {
-        httpd_object *obj = objs->objects[i];
-
-        if(obj->name && !strcmp(name, obj->name)) {
-            printf("name is %s -> add object %s\n", name, obj->name);
-            objset_add_object(sn->sn.pool, os, obj);
-        }
-    } 
-
-    return REQ_PROCEED;
-}
--- a/src/server/httprequest.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTTPREQUEST_H
-#define	HTTPREQUEST_H
-
-#include "sstring.h"
-#include "sessionhandler.h"
-#include "nsapi.h"
-#include "pool.h"
-#include "session.h"
-#include "sstring.h"
-#include "request.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct _http_request   HTTPRequest;
-typedef struct _header         Header;
-typedef struct _header_array   HeaderArray;
-
-struct _http_request {
-    Connection     *connection;
-    sstr_t         request_line;
-    sstr_t         method;
-    sstr_t         uri;
-    sstr_t         httpv;
-    HeaderArray    *headers;
-    netbuf         *netbuf;
-    NSAPISession   *sn;
-    NSAPIRequest   *rq;
-    pool_handle_t  *pool;
-};
-
-struct _header {
-    char *name;
-    char *value;
-};
-
-struct _header_array {
-    HeaderArray *next;
-    Header      *headers;
-    int         len;
-    int         alloc;
-};
-
-HTTPRequest *http_request_new();
-
-int handle_request(HTTPRequest *request);
-
-
-
-void header_add(HeaderArray *hd, char *name, char *value);
-
-int nsapi_handle_request(NSAPISession *sn, NSAPIRequest *rq);
-int nsapi_finish_request(NSAPISession *sn, NSAPIRequest *rq);
-int nsapi_nametrans(NSAPISession *sn, NSAPIRequest *rq);
-int nsapi_objecttype(NSAPISession *sn, NSAPIRequest *rq);
-int nsapi_service(NSAPISession *sn, NSAPIRequest *rq);
-
-
-int add_objects(
-        HTTPObjectConfig *objs,
-        httpd_objset *os,
-        NSAPISession *sn,
-        NSAPIRequest *rq,
-        char *name,
-        char *path);
-
-/* request.h functions */
-int request_initialize(
-        pool_handle_t *pool,
-        HTTPRequest *hrq,
-        NSAPIRequest *nrq);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* HTTPREQUEST_H */
-
--- a/src/server/io.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/uio.h>
-
-#include "io.h"
-#include "pool.h"
-
-IOStream native_io_funcs = {
-    system_write,
-    system_read
-};
-
-IOStream net_io_funcs = {
-    net_stream_write,
-    net_stream_read
-};
-
-
-IOStream* stream_new_from_fd(int fd) {
-    SystemIOStream *st = malloc(sizeof(SystemIOStream));
-    st->st = native_io_funcs;
-    st->fd = fd;
-    return (IOStream*)st;
-}
-
-ssize_t system_write(IOStream *st, void *buf, size_t nbytes) {
-    return write(((SystemIOStream*)st)->fd, buf, nbytes);
-}
-
-ssize_t system_read(IOStream *st, void *buf, size_t nbytes) {
-    return read(((SystemIOStream*)st)->fd, buf, nbytes);
-}
-
-
-IOStream* net_stream_from_fd(int fd) {
-    NetIOStream *st = malloc(sizeof(NetIOStream));
-    st->st = net_io_funcs;
-    st->fd = fd;
-    st->max_read = 0;
-    st->rd = 0;
-}
-
-ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes) {
-    // TODO: implement
-}
-
-ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes) {
-    NetIOStream *n = (NetIOStream*)st;
-    if(n->max_read != 0 && n->rd >= n->max_read) {
-        return 0;
-    }
-    ssize_t r = read(n->fd, buf, nbytes);
-    n->rd += r;
-    return r;
-}
-
-
-ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) {
-    ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes);
-    if(r == 0) {
-        return IO_EOF;
-    }
-    return r;
-}
-
-ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) {
-    ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes);
-    if(r < 0) {
-        return IO_ERROR;
-    }
-    return r;
-}
-
-
-/* iovec buffer */
-iovec_buf_t *iovec_buf_create(pool_handle_t *pool) {
-    iovec_buf_t *buf = pool_malloc(pool, sizeof(iovec_buf_t));
-
-    buf->pool = pool;
-    buf->iov  = pool_calloc(pool, 32, sizeof(struct iovec));
-    buf->maxiovec = 32;
-    buf->iovctn = 0;
-
-    return buf;
-}
-
-void iovec_buf_write(iovec_buf_t *io, void *buf, size_t nbyte) {
-    if(io->iovctn >= io->maxiovec) {
-        io->iov = pool_realloc(
-                io->pool,
-                io->iov,
-                (io->maxiovec + 16) * sizeof(struct iovec));
-    }
-
-    io->iov[io->iovctn].iov_base = buf;
-    io->iov[io->iovctn].iov_len = nbyte;
-    io->iovctn++;
-}
-
-ssize_t iovec_buf_flush(iovec_buf_t *io, int fd) {
-    return writev(fd, io->iov, io->iovctn);
-}
--- a/src/server/io.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef IOSTREAM_H
-#define	IOSTREAM_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct io_stream IOStream;
-
-typedef ssize_t(*io_write_f)(IOStream *, void *, size_t);
-typedef ssize_t(*io_read_f)(IOStream *, void *, size_t);
-
-struct io_stream {
-    io_write_f write;
-    io_read_f  read;
-};
-
-typedef struct SystemIOStream {
-    IOStream st;
-    int      fd;
-} SystemIOStream;
-
-typedef struct NetIOStream {
-    IOStream st;
-    int      fd;
-    size_t   max_read;
-    size_t   rd;
-} NetIOStream;
-
-
-/* net_ functions */
-ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes);
-ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes);
-
-
-/* iovec buffer */
-typedef struct iovec_buf{
-    struct iovec   *iov;
-    int            iovctn;
-    int            maxiovec;
-    pool_handle_t  *pool;
-} iovec_buf_t;
-
-
-/* system stream */
-IOStream* stream_new_from_fd(int fd);
-
-ssize_t system_write(IOStream *st, void *buf, size_t nbytes);
-ssize_t system_read(IOStream *st, void *buf, size_t nbytes);
-
-/* net stream */
-IOStream* net_stream_from_fd(int fd);
-
-ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes);
-ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes);
-
-/* iovec buffer */
-iovec_buf_t *iovec_buf_create(pool_handle_t *pool);
-void iovec_buf_write(iovec_buf_t *io, void *buf, size_t nbyte);
-ssize_t iovec_buf_flush(iovec_buf_t *io, int fd);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* IOSTREAM_H */
-
--- a/src/server/list.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/* 
- * File:   list.c
- * Author: olaf
- *
- * Created on 18. Dezember 2010, 11:23
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "list.h"
-
-/* add functions */
-sdlist_t* sdlist_add(sdlist_t *list, void *data) {
-    sdlist_t *elm = malloc(sizeof(sdlist_t));
-    elm->data = data;
-    elm->next = NULL;
-
-    return sdlist_addl(list, elm);
-}
-
-sdlist_t* sdlist_addl(sdlist_t *list, sdlist_t *l) {
-    if (list != NULL) {
-        sdlist_t *end = sdlist_getlast(list);
-        end->next = l;
-        return list;
-    } else {
-        return l;
-    }
-}
-
-
-
-/* remove functions */
-sdlist_t* sdlist_remove(sdlist_t *list, void *data) {
-    sdlist_t *s = list;
-
-    sdlist_t *prev = NULL;
-    while (list != NULL) {
-        if (list->data == data) {
-            sdlist_t *nl =  sdlist_remove_elm(s, prev, list);
-            free(list);
-            return nl;
-        }
-
-        prev = list;
-        list = list->next;
-    }
-
-    return s;
-}
-
-sdlist_t* sdlist_removei(sdlist_t *list, int index) {
-    sdlist_t *s = list;
-
-    sdlist_t *prev = NULL;
-    int i = 0;
-    while (list != NULL) {
-        if (i == index) {
-            sdlist_t *nl =  sdlist_remove_elm(s, prev, list);
-            free(list);
-            return nl;
-        }
-
-        prev = list;
-        list = list->next;
-        i++;
-    }
-
-    return s;
-}
-
-sdlist_t* sdlist_removel(sdlist_t *list, sdlist_t *l) {
-    sdlist_t *s = list;
-
-    sdlist_t *prev = NULL;
-    while (list != NULL) {
-        if (list == l) {
-            return sdlist_remove_elm(s, prev, list);
-        }
-
-        prev = list;
-        list = list->next;
-    }
-
-    return s;
-}
-
-
-sdlist_t *sdlist_remove_elm(sdlist_t *list, sdlist_t *prev, sdlist_t *elm) {
-    if (elm == NULL) {
-        return list;
-    }
-
-    if (prev == NULL) {
-        return elm->next;
-    }
-
-    prev->next = elm->next;
-
-    return list;
-}
-
-
-
-/* insert functions */
-void sdlist_insert(sdlist_t *elm, void *data) {
-    sdlist_t *newelm = malloc(sizeof(sdlist_t));
-    newelm->data = data;
-    sdlist_insertl(elm, newelm);
-}
-
-void sdlist_insertl(sdlist_t *elm, sdlist_t *l) {
-    if (elm == NULL || l == NULL) {
-        return;
-    }
-    
-    l->next = elm->next;
-    elm->next = l;
-}
-
-
-/* get functions */
-sdlist_t* sdlist_get(sdlist_t *list, void *data) {
-    while (list != NULL) {
-        if (list->data == data) {
-            return list;
-        }
-        list = list->next;
-    }
-    return NULL;
-}
-
-sdlist_t* sdlist_geti(sdlist_t *list, int index) {
-    for (int i=0;i<index;i++) {
-        if (list == NULL) {
-            return NULL;
-        }
-        list = list->next;
-    }
-    return list;
-}
-
-sdlist_t* sdlist_getlast(sdlist_t *list) {
-    while(list->next != NULL) {
-        list = list->next;
-    }
-    return list;
-}
-
-
-
-/* miscellaneous functions */
-size_t sdlist_length(sdlist_t *list) {
-    int i = 0;
-    while(list->next != NULL) {
-        list = list->next;
-        i++;
-    }
-    return i;
-}
-
-void sdlist_free(sdlist_t *elm) {
-    free(elm);
-}
-
-void sdlist_foreach(sdlist_t *list, sdlist_iterator_func f, void *data) {
-    while(list != NULL) {
-        int r = f(list, data);
-        if (r) {
-            return;
-        }
-        list = list->next;
-    }
-}
--- a/src/server/list.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LIST_H
-#define	LIST_H
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct _util_slist sdlist_t;
-
-struct _util_slist {
-    void *data;
-    sdlist_t *next;
-};
-
-typedef int (*sdlist_iterator_func)(sdlist_t*, void*);
-
-
-/* single linked list */
-
-/*
- * sdlist_add/sdllist_addl
- *
- * append to the end of the list one element
- */
-sdlist_t* sdlist_add(sdlist_t *list, void *data);
-sdlist_t* sdlist_addl(sdlist_t *list, sdlist_t *l);
-    
-/*
- * sdlist_remove/sdlist_removei
- *
- * remove one element from the list and free the sdlist_t object
- * returns the first element of the new list
- */
-sdlist_t* sdlist_remove(sdlist_t *list, void *data);
-sdlist_t* sdlist_removei(sdlist_t *list, int index);
-
-/*
- * sdlist_removel
- *
- * remove element l from the list
- * returns the first element of the new list
- */
-sdlist_t* sdlist_removel(sdlist_t *list, sdlist_t *l);
-
-/*
- * removes one element from the list
- *
- * list:   list
- * prev:   previous to elm
- * elm:    element which should be removed
- *
- * returns the first element of the new list
- */
-sdlist_t *sdlist_remove_elm(sdlist_t *list, sdlist_t *prev, sdlist_t *elm);
-    
-
-/*
- * sdlist_insert
- *
- * insert one element after the element elm
- */
-void sdlist_insert(sdlist_t *elm, void *data);
-void sdlist_insertl(sdlist_t *elm, sdlist_t *l);
-
-sdlist_t* sdlist_get(sdlist_t *list, void *data);
-sdlist_t* sdlist_geti(sdlist_t *list, int index);
-sdlist_t* sdlist_getlast(sdlist_t *list);
-
-size_t sdlist_length(sdlist_t *list);
-void sdlist_free(sdlist_t *elm);
-void sdlist_foreach(sdlist_t *list, sdlist_iterator_func f, void *data);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* LIST_H */
-
--- a/src/server/main.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pool.h"
-#include "nsapi.h"
-#include "plist.h"
-
-#include "webserver.h"
-
-#include "httprequest.h"
-
-void test() {
-    
-}
-
-int main(int argc, char **argv) {
-    pool_init(NULL, NULL, NULL);
-
-    //test();
-
-    int status;
-    status = webserver_init();
-    if(status != 0) {
-        fprintf(stderr, "Cannot initialize server!\n");
-        return EXIT_FAILURE;
-    }
-
-    status = webserver_run();
-    if(status != 0) {
-        fprintf(stderr, "Cannot run server!\n");
-        return EXIT_FAILURE;
-    }
-
-    getchar();
-
-    return EXIT_SUCCESS;
-}
-
--- a/src/server/map.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "map.h"
-
-hashmap_t* hashmap_new(size_t size) {
-    hashmap_t *map = malloc(sizeof(hashmap_t));
-    map->map = calloc(size, sizeof(sdlist_t));
-    map->len = size;
-
-    return map;
-}
-
-void hashmap_free(hashmap_t *map) {
-    for(int i=0;i<map->len;i++) {
-        sdlist_t *list = map->map[0];
-        while(list != NULL) {
-            hashmap_elm_t *elm = (hashmap_elm_t*)list->data;
-            free(elm->key.ptr);
-            sdlist_t *l = list;
-            list = list->next;
-            free(elm);
-            free(l);
-        }
-    }
-    free(map->map);
-    free(map);
-}
-
-
-void hashmap_put(hashmap_t *map, sstr_t key, void *value) {
-    int hash = hashmap_hash(key.ptr, key.length);
-
-    sdlist_t *list = map->map[hash%map->len];
-
-    sstr_t k = sstrdub(key);
-
-    hashmap_elm_t *elm = malloc(sizeof(hashmap_elm_t));
-    elm->data = value;
-    elm->hash = hash;
-    elm->key = k;
-
-    map->map[hash%map->len] = sdlist_add(list, elm);
-}
-
-void* hashmap_get(hashmap_t *map, sstr_t key) {
-    int hash = hashmap_hash(key.ptr, key.length);
-    sdlist_t *list = map->map[hash%map->len];
-    void *value = NULL;
-
-    while (list != NULL) {
-        hashmap_elm_t *elm = list->data;
-        if (elm->hash == hash &&
-                strncmp(key.ptr, elm->key.ptr, key.length) == 0) {
-            value = elm->data;
-            break;
-        }
-        list = list->next;
-    }
-
-    return value;
-}
-
-
-
-
-/* hash function */
-int hashmap_hash(char *data, size_t len) {
-    /* murmur hash 2 */
-
-    int m = 0x5bd1e995;
-    int r = 24;
-
-    int h = 25 ^ len;
-
-    int i = 0;
-    while (len >= 4) {
-        int k = data[i + 0] & 0xFF;
-        k |= (data[i + 1] & 0xFF) << 8;
-        k |= (data[i + 2] & 0xFF) << 16;
-        k |= (data[i + 3] & 0xFF) << 24;
-
-        k *= m;
-        k ^= k >> r;
-        k *= m;
-
-        h *= m;
-        h ^= k;
-
-        i += 4;
-        len -= 4;
-    }
-
-    switch (len) {
-        case 3: h ^= (data[i + 2] & 0xFF) << 16;
-        case 2: h ^= (data[i + 1] & 0xFF) << 8;
-        case 1: h ^= (data[i + 0] & 0xFF); h *= m;
-    }
-
-    h ^= h >> 13;
-    h *= m;
-    h ^= h >> 15;
-
-    return h;
-}
--- a/src/server/map.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MAP_H
-#define	MAP_H
-
-#include "list.h"
-#include "sstring.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct _hashmap_elm {
-    int hash;
-    sstr_t key;
-
-    void *data;
-} hashmap_elm_t;
-
-typedef struct _util_hashmap {
-    sdlist_t **map;
-    size_t len;
-} hashmap_t;
-
-hashmap_t* hashmap_new(size_t size);
-void hashmap_free(hashmap_t *map);
-
-void hashmap_put(hashmap_t *map, sstr_t key, void *value);
-void* hashmap_get(hashmap_t *map, sstr_t key);
-
-int hashmap_hash(char *data, size_t len);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* MAP_H */
-
--- a/src/server/nametrans.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "nametrans.h"
-
-#include "pblock.h"
-
-int test_nametrans(pblock *pb, Session *sn, Request *rq) {
-    printf("test_nametrans...\n");
-
-    // set ppath
-    //char *ppath = "/export/home/olaf/Desktop/hello.txt";
-    //pblock_kvinsert(pb_key_ppath, ppath, strlen(ppath), rq->vars);
-
-    return REQ_NOACTION;
-}
-
-/*
- * assign_name
- *
- * Assigns the name specified by the name parameter if the uri has the
- * specified prefix.
- *
- * pblock parameter:
- * name     object name
- * from     optional uri prefix
- */
-int assign_name(pblock *pb, Session *sn, Request *rq) {
-    /* TODO: expression instead of simple prefix */
-
-    char *name = pblock_findkeyval(pb_key_name, pb);
-    char *from = pblock_findkeyval(pb_key_from, pb);
-
-    if(!name) {
-        /* TODO: add log */
-        protocol_status(sn, rq, 500, NULL);
-        return REQ_ABORTED;
-    }
-    
-    if(from) {
-        char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
-        char c;
-        int i = 0;
-        while((c = from[i]) != 0) {
-            if(c != uri[i]) {
-                return REQ_NOACTION;
-            }
-            i++;
-        }
-    }
-
-    /* add object to rq->vars */
-    pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
-
-    return REQ_NOACTION;
-}
--- a/src/server/nametrans.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NAMETRANS_H
-#define	NAMETRANS_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-int test_nametrans(pblock *pb, Session *sn, Request *rq);
-
-int assign_name(pblock *pb, Session *sn, Request *rq);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* NAMETRANS_H */
-
--- a/src/server/netbuf.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * netbuf.c: Handles buffered I/O on network sockets
- *
- * Rob McCool
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "nspr.h"
-#include "nsapi.h"
-#include "io.h"
-
-//include "buffer.h"
-
-
-#define NETBUF_RDTIMEOUT 120
-
-
-/* ----------------------------- netbuf_open ------------------------------ */
-
-
-NSAPI_PUBLIC netbuf *netbuf_open(SYS_NETFD sd, int sz) {
-    netbuf *buf = (netbuf *) malloc(sizeof(netbuf));
-
-    buf->rdtimeout = NETBUF_RDTIMEOUT;
-    buf->pos = sz;
-    buf->cursize = sz; /* force buffer_next on first getc */
-    buf->maxsize = sz;
-    buf->sd = sd;
-
-    buf->inbuf = NULL;
-    buf->errmsg = NULL;
-
-    return buf;
-}
-
-
-/* ----------------------------- netbuf_close ----------------------------- */
-
-
-NSAPI_PUBLIC void netbuf_close(netbuf *buf) {
-    if(buf->inbuf)
-        free(buf->inbuf);
-    free(buf);
-}
-
-
-/* ----------------------------- netbuf_replace --------------------------- */
-
-
-NSAPI_PUBLIC unsigned char * netbuf_replace(netbuf *buf,
-    unsigned char *inbuf, int pos, int cursize, int maxsize)
-{
-    unsigned char *oldbuf = buf->inbuf;
-
-    buf->inbuf = inbuf;
-    buf->pos = pos;
-    buf->cursize = cursize;
-    buf->maxsize = maxsize;
-
-    return oldbuf;
-}
-
-
-/* ----------------------------- netbuf_next ------------------------------ */
-
-
-NSAPI_PUBLIC int netbuf_next(netbuf *buf, int advance) {
-    int n;
-
-    if(!buf->inbuf)
-        buf->inbuf = (unsigned char *) malloc(buf->maxsize);
-
-    while(1) {
-        switch(n = net_read(buf->sd, (char *)(buf->inbuf), buf->maxsize)) {
-        //case IO_EOF:
-        case 0:
-            return IO_EOF;
-        case -1:
-            return IO_ERROR;
-        //case IO_ERROR:
-            //buf->errmsg = system_errmsg();
-        //    return IO_ERROR;
-        default:
-            buf->pos = advance;
-            buf->cursize = n;
-            return buf->inbuf[0];
-        }
-    }
-}
-
-NSAPI_PUBLIC int netbuf_getbytes(netbuf *buf, char *buffer, int size)
-{
-    int bytes;
-
-    if (!buf->inbuf) {
-        buf->inbuf = (unsigned char *) malloc(buf->maxsize);
-    } else {
-        if (buf->pos < buf->cursize) {
-            int bytes_in_buffer = buf->cursize - buf->pos;
-
-            if (bytes_in_buffer > size)
-                bytes_in_buffer = size;
-
-            memcpy(buffer, &(buf->inbuf[buf->pos]), bytes_in_buffer);
-
-            buf->pos += bytes_in_buffer;
-            return bytes_in_buffer;
-        }
-    }
-
-    /* The netbuf is empty.  Read data directly into the caller's buffer */
-    bytes = net_read(buf->sd, buffer, size);
-    if (bytes == 0)
-        return NETBUF_EOF;
-    if (bytes < 0) {
-        //buf->errmsg = system_errmsg();
-        return NETBUF_ERROR;
-    }
-    return bytes;
-}
-
-
-/* ----------------------------- netbuf_grab ------------------------------ */
-
-
-NSAPI_PUBLIC int netbuf_grab(netbuf *buf, int sz) {
-    int n;
-
-    if(!buf->inbuf) {
-        buf->inbuf = (unsigned char *) malloc(sz);
-        buf->maxsize = sz;
-    }
-    else if(sz > buf->maxsize) {
-        buf->inbuf = (unsigned char *) realloc(buf->inbuf, sz);
-        buf->maxsize = sz;
-    }
-
-    PR_ASSERT(buf->pos == buf->cursize);
-    buf->pos = 0;
-    buf->cursize = 0;
-
-    while(1) {
-        switch(n = net_read(buf->sd, (char *)(buf->inbuf), sz)) {
-        case 0:
-            return IO_EOF;
-        case -1: {
-            //buf->errmsg = system_errmsg();
-            return IO_ERROR;
-        }
-        default:
-            buf->cursize = n;
-            return n;
-        }
-    }
-}
--- a/src/server/netsite.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef NETSITE_H
-#define NETSITE_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * Standard defs for NetSite servers.
- */
-
-#include <mps/nspr.h>
-
-#ifndef BASE_SYSTEMS_H
-#include "systems.h"
-#endif /* !BASE_SYSTEMS_H */
-
-
-
-#define MAGNUS_VERSION_STRING INTsystem_version()
-#define MAGNUS_VERSION PRODUCT_VERSION_ID
-
-/* Include the public nsapi.h definitions */
-#ifndef PUBLIC_NETSITE_H
-#include "nsapi.h"
-#endif /* PUBLIC_NETSITE_H */
-
-NSPR_BEGIN_EXTERN_C
-
-/*
- * Only the mainline needs to set the malloc key.
- */
-
-NSAPI_PUBLIC void InitThreadMallocKey(void);
-
-NSAPI_PUBLIC void system_set_temp_dir(const char *dir);
-
-NSAPI_PUBLIC const char *system_get_temp_dir(void);
-
-/* This probably belongs somewhere else, perhaps with a different name */
-NSAPI_PUBLIC char *INTdns_guess_domain(char * hname);
-
-/* --- Begin public functions --- */
-
-#ifdef INTNSAPI
-
-NSAPI_PUBLIC char *INTsystem_version(void);
-
-/*
-   Depending on the system, memory allocated via these macros may come from 
-   an arena. If these functions are called from within an Init function, they 
-   will be allocated from permanent storage. Otherwise, they will be freed 
-   when the current request is finished.
- */
-
-#define MALLOC(size) INTsystem_malloc(size)
-NSAPI_PUBLIC void *INTsystem_malloc(int size);
-
-#define CALLOC(size) INTsystem_calloc(size)
-NSAPI_PUBLIC void *INTsystem_calloc(int size);
-
-#define REALLOC(ptr, size) INTsystem_realloc(ptr, size)
-NSAPI_PUBLIC void *INTsystem_realloc(void *ptr, int size);
-
-#define FREE(ptr) INTsystem_free(ptr)
-NSAPI_PUBLIC void INTsystem_free(void *ptr);
-
-#define STRDUP(ptr) INTsystem_strdup(ptr)
-NSAPI_PUBLIC char *INTsystem_strdup(const char *ptr);
-
-/*
-   These macros always provide permanent storage, for use in global variables
-   and such. They are checked at runtime to prevent them from returning NULL.
- */
-
-#define PERM_MALLOC(size) INTsystem_malloc_perm(size)
-NSAPI_PUBLIC void *INTsystem_malloc_perm(int size);
-
-#define PERM_CALLOC(size) INTsystem_calloc_perm(size)
-NSAPI_PUBLIC void *INTsystem_calloc_perm(int size);
-
-#define PERM_REALLOC(ptr, size) INTsystem_realloc_perm(ptr, size)
-NSAPI_PUBLIC void *INTsystem_realloc_perm(void *ptr, int size);
-
-#define PERM_FREE(ptr) INTsystem_free_perm(ptr)
-NSAPI_PUBLIC void INTsystem_free_perm(void *ptr);
-
-#define PERM_STRDUP(ptr) INTsystem_strdup_perm(ptr)
-NSAPI_PUBLIC char *INTsystem_strdup_perm(const char *ptr);
-
-/* Thread-Private data key index for accessing the thread-private memory pool.
- * Each thread creates its own pool for allocating data.  The MALLOC/FREE/etc
- * macros have been defined to check the thread private data area with the
- * thread_malloc_key index to find the address for the pool currently in use.
- *
- * If a thread wants to use a different pool, it must change the thread-local-
- * storage[thread_malloc_key].
- */
-
-NSAPI_PUBLIC int INTgetThreadMallocKey(void);
-
-NSAPI_PUBLIC pool_handle_t *INTsystem_pool(void);
-
-/* Not sure where to put this. */
-
-NSAPI_PUBLIC void INTsystem_setnewhandler(void);
-
-#endif /* INTNSAPI */
-
-/* --- End public functions --- */
-
-NSPR_END_EXTERN_C
-
-#ifdef INTNSAPI
-
-#define dns_guess_domain INTdns_guess_domain
-//define system_version INTsystem_version
-#define system_malloc INTsystem_malloc
-#define system_calloc INTsystem_calloc
-#define system_realloc INTsystem_realloc
-#define system_free INTsystem_free
-#define system_strdup INTsystem_strdup
-#define system_malloc_perm INTsystem_malloc_perm
-#define system_calloc_perm INTsystem_calloc_perm
-#define system_realloc_perm INTsystem_realloc_perm
-#define system_free_perm INTsystem_free_perm
-#define system_strdup_perm INTsystem_strdup_perm
-#define getThreadMallocKey INTgetThreadMallocKey
-#define system_pool INTsystem_pool
-#define system_setnewhandler INTsystem_setnewhandler
-
-#endif /* INTNSAPI */
-
-#ifndef HTTPS_ADMSERV 
-#define HTTPS_ADMSERV "https-admserv"
-#endif
-
-#endif /* NETSITE_H */
--- a/src/server/nsapi.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1342 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PUBLIC_NSAPI_H
-#define PUBLIC_NSAPI_H
-
-/*
- * File:        nsapi.h
- *
- * Description:
- *
- *      This file defines an interface for extending the server with
- *      in-process plug-ins.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NSAPI version defined by this header file */
-#define NSAPI_VERSION 303
-
-/* Define USE_NSAPI_VERSION to use a specific NSAPI version at compile time */
-#ifdef USE_NSAPI_VERSION
-#if USE_NSAPI_VERSION < 300 || USE_NSAPI_VERSION > NSAPI_VERSION
-#error This header file does not support the requested NSAPI version
-#else
-#undef NSAPI_VERSION
-#define NSAPI_VERSION USE_NSAPI_VERSION
-#endif
-#endif
-
-/* --- Begin native platform configuration definitions --- */
-
-#if !defined(XP_WIN32) && !defined(XP_UNIX)
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-#define XP_WIN32
-#else
-#define XP_UNIX
-#endif
-#endif
-
-#ifdef XP_UNIX
-#define NSAPI_PUBLIC
-#define ZERO(ptr, len) memset(ptr, 0, len)
-#ifdef AIX
-#define TCPLEN_T size_t
-#endif
-#ifdef HPUX
-#define TCPLEN_T int
-#endif
-#ifndef TCPLEN_T
-#define TCPLEN_T socklen_t
-#endif
-#endif /* XP_UNIX */
-
-#ifdef XP_WIN32
-#define NSAPI_PUBLIC __declspec(dllexport)
-struct iovec {
-    char *iov_base;
-    unsigned iov_len;
-};
-#ifndef S_ISDIR
-#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
-#endif
-#ifndef S_ISREG
-#define S_ISREG(mode) ((mode & S_IFMT) == S_IFREG)
-#endif
-#ifndef S_ISLNK
-#define S_ISLNK(x) (0)
-#endif
-#define caddr_t PCHAR
-#define NEED_STRCASECMP
-#define NEED_STRNCASECMP
-#define ZERO(ptr, len) ZeroMemory(ptr, len)
-#define TCPLEN_T int
-#endif /* XP_WIN32 */
-
-/* --- End native platform configuration definitions --- */
-
-/* --- Begin miscellaneous definitions --- */
-
-/* Used in some places as a length limit on error messages */
-#define MAGNUS_ERROR_LEN 1024
-
-/* Carriage return and line feed */
-#define CR 13
-#define LF 10
-#ifdef XP_WIN32
-#define ENDLINE "\r\n"
-#else
-#define ENDLINE "\n"
-#endif
-
-/* mime.types file identification line */
-#define NCC_MT_MAGIC "#--Netscape Communications Corporation MIME Information"
-#define NCC_MT_MAGIC_LEN 55
-
-/* The character which separates extensions with cinfo_find */
-#define CINFO_SEPARATOR '.'
-
-/* The maximum length of a line in a mime.types file */
-#define CINFO_MAX_LEN 1024
-
-/* The maximum length of an error message */
-#define MAX_ERROR_LEN 4096
-
-/*
- * A warning is a minor mishap, such as a 404 being issued.
- */
-#define LOG_WARN 0
-
-/* 
- * A misconfig is when there is a syntax error or permission violation in
- * a config file.
- */
-#define LOG_MISCONFIG 1
-
-/* 
- * Security warnings are issued when authentication fails, or a host is
- * given a 403 return code.
- */
-#define LOG_SECURITY 2
-
-/*
- * A failure is when a request could not be fulfilled due to an internal
- * problem, such as a CGI script exiting prematurely, or a filesystem 
- * permissions problem.
- */
-#define LOG_FAILURE 3
-
-/*
- * A catastrophe is a fatal server error such as running out of
- * memory or processes, or a system call failing, or even a server crash. 
- * The server child cannot recover from a catastrophe.
- */
-#define LOG_CATASTROPHE 4
-
-/*
- * Informational message, of no concern.
- */
-#define LOG_INFORM 5
-
-/*
- * Internal diagnostic message.
- */
-#define LOG_VERBOSE 6
-
-/*
- * The time format to use in the error log
- */
-#define ERR_TIMEFMT "[%d/%b/%Y:%H:%M:%S]"
-
-
-/* The fd you will get if you are reporting errors to SYSLOG */
-#define ERRORS_TO_SYSLOG NULL
-
-/* Return codes from file I/O routines */
-#define IO_OKAY 1
-#define IO_ERROR -1
-#define IO_EOF 0
-#define NETBUF_EOF      -1
-#define NETBUF_ERROR    -2
-#define NETBUF_FULL     -3
-
-/* The disk page size on this machine. */
-#define FILE_BUFFERSIZE 4096
-
-#ifdef XP_UNIX
-
-#define FILE_PATHSEP '/'
-#define FILE_PARENT "../"
-
-#elif defined(XP_WIN32)
-
-#define FILE_PATHSEP '/'
-#define FILE_PARENT "..\\"
-
-#endif /* XP_WIN32 */
-
-#define NET_INFINITE_TIMEOUT 0
-#define NET_ZERO_TIMEOUT -1
-
-#ifdef USE_REGEX
-/* WILDPAT uses regular expressions */
-#define WILDPAT_VALID(exp)              regexp_valid(exp)
-#define WILDPAT_MATCH(str, exp)         regexp_match(str, exp)
-#define WILDPAT_CMP(str, exp)           regexp_cmp(str, exp)
-#define WILDPAT_CASECMP(str, exp)       regexp_casecmp(str, exp)
-#define WILDPAT_USES_REGEXP              1
-#else
-/* WILDPAT uses shell expressions */
-#define WILDPAT_VALID(exp)              shexp_valid(exp)
-#define WILDPAT_MATCH(str, exp)         shexp_match(str, exp)
-#define WILDPAT_CMP(str, exp)           shexp_cmp(str, exp)
-#define WILDPAT_CASECMP(str, exp)       shexp_casecmp(str, exp)
-#define WILDPAT_USES_SHEXP              1
-#endif
-
-/* Define return codes from WILDPAT_VALID */
-#define NON_WILDPAT     -1              /* exp is ordinary string */
-#define INVALID_WILDPAT -2              /* exp is an invalid pattern */
-#define VALID_WILDPAT   1               /* exp is a valid pattern */
-
-/* Define return codes from regexp_valid and shexp_valid */
-#define NON_SXP         NON_WILDPAT     /* exp is an ordinary string */
-#define INVALID_SXP     INVALID_WILDPAT /* exp is an invalid shell exp */
-#define VALID_SXP       VALID_WILDPAT   /* exp is a valid shell exp */
-
-#define NON_REGEXP      NON_SXP
-#define INVALID_REGEXP  INVALID_SXP
-#define VALID_REGEXP    VALID_SXP
-
-#define SYSTHREAD_DEFAULT_PRIORITY 16
-
-/* The longest line in the configuration file */
-#define CONF_MAXLEN 16384
-
-#define HTTP_DATE_LEN 30
-#define HTTP_DATE_FMT "%a, %d %b %Y %T GMT"
-
-/* HTTP status codes */
-#define PROTOCOL_CONTINUE 100
-#define PROTOCOL_SWITCHING 101
-#define PROTOCOL_OK 200
-#define PROTOCOL_CREATED 201
-#define PROTOCOL_ACCEPTED 202
-#define PROTOCOL_NONAUTHORITATIVE 203
-#define PROTOCOL_NO_RESPONSE 204
-#define PROTOCOL_NO_CONTENT 204
-#define PROTOCOL_RESET_CONTENT 205
-#define PROTOCOL_PARTIAL_CONTENT 206
-#define PROTOCOL_MULTI_STATUS 207
-#define PROTOCOL_MULTIPLE_CHOICES 300
-#define PROTOCOL_MOVED_PERMANENTLY 301
-#define PROTOCOL_REDIRECT 302
-#define PROTOCOL_SEE_OTHER 303
-#define PROTOCOL_NOT_MODIFIED 304
-#define PROTOCOL_USE_PROXY 305
-#define PROTOCOL_TEMPORARY_REDIRECT 307
-#define PROTOCOL_BAD_REQUEST 400
-#define PROTOCOL_UNAUTHORIZED 401
-#define PROTOCOL_PAYMENT_REQUIRED 402
-#define PROTOCOL_FORBIDDEN 403
-#define PROTOCOL_NOT_FOUND 404
-#define PROTOCOL_METHOD_NOT_ALLOWED 405
-#define PROTOCOL_NOT_ACCEPTABLE 406
-#define PROTOCOL_PROXY_UNAUTHORIZED 407
-#define PROTOCOL_REQUEST_TIMEOUT 408
-#define PROTOCOL_CONFLICT 409
-#define PROTOCOL_GONE 410
-#define PROTOCOL_LENGTH_REQUIRED 411
-#define PROTOCOL_PRECONDITION_FAIL 412
-#define PROTOCOL_ENTITY_TOO_LARGE 413
-#define PROTOCOL_URI_TOO_LARGE 414
-#define PROTOCOL_UNSUPPORTED_MEDIA_TYPE 415
-#define PROTOCOL_REQUESTED_RANGE_NOT_SATISFIABLE 416
-#define PROTOCOL_EXPECTATION_FAILED 417
-#define PROTOCOL_LOCKED 423
-#define PROTOCOL_FAILED_DEPENDENCY 424
-#define PROTOCOL_SERVER_ERROR 500
-#define PROTOCOL_NOT_IMPLEMENTED 501
-#define PROTOCOL_BAD_GATEWAY 502
-#define PROTOCOL_SERVICE_UNAVAILABLE 503
-#define PROTOCOL_GATEWAY_TIMEOUT 504
-#define PROTOCOL_VERSION_NOT_SUPPORTED 505
-#define PROTOCOL_INSUFFICIENT_STORAGE 507
-
-#define PROTOCOL_VERSION_HTTP09 9
-#define PROTOCOL_VERSION_HTTP10 100
-#define PROTOCOL_VERSION_HTTP11 101
-#define CURRENT_PROTOCOL_VERSION PROTOCOL_VERSION_HTTP11
-
-/* Definitions for HTTP over SSL */
-#define HTTPS_PORT 443
-#define HTTPS_URL "https"
-
-/* Definitions for HTTP over TCP */
-#define HTTP_PORT 80
-#define HTTP_URL "http"
-
-
-#define REQ_MAX_LINE 4096
-    
-/*
- * The REQ_ return codes. These codes are used to determine what the server
- * should do after a particular module completes its task.
- *
- * Func type functions return these as do many internal functions.
- */
-
-/* The function performed its task, proceed with the request */
-#define REQ_PROCEED 0
-/* The entire request should be aborted: An error occurred */
-#define REQ_ABORTED -1
-/* The function performed no task, but proceed anyway */
-#define REQ_NOACTION -2
-/* Tear down the session and exit */
-#define REQ_EXIT -3
-/* Restart the entire request-response process */
-#define REQ_RESTART -4
-/* Too busy to execute this now */
-#define REQ_TOOBUSY -5
-
-
-/**** NSAPI extensions ****/
-
-/* The function is still in progress (async extension) */
-#define REQ_PROCESSING -8
-
-/**** END NSAPI extensions ****/
-
-
-/* --- End miscellaneous definitions --- */
-
-/* --- Begin native platform includes --- */
-
-#ifdef XP_UNIX
-#include <unistd.h>
-#include <sys/file.h>
-#include <alloca.h> /* new */
-#ifndef HPUX
-#include <sys/select.h>
-#endif
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <pwd.h>
-#include <netinet/in.h>
-#endif /* XP_UNIX */
-
-#ifdef XP_WIN32
-#include <wtypes.h>
-#include <winbase.h>
-#include <direct.h>
-#include <winsock.h>
-#endif /* XP_WIN32 */
-
-#include <sys/stat.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-
-/* --- End native platform includes --- */
-
-/* --- Begin type definitions --- */
-
-/* NOTE: both SYS_FILE and SYS_NETFD are actually NSPR PRFileDesc * and can */
-/*       be used with NSPR API calls (after casting them to PRFileDesc *) */
-
-#ifndef SYS_FILE_T
-typedef void *SYS_FILE;
-#define SYS_FILE_T void *
-#endif /* !SYS_FILE_T */
-
-#define SYS_ERROR_FD ((SYS_FILE)-1)
-
-#ifndef SYS_NETFD_T
-typedef void *SYS_NETFD;
-#define SYS_NETFD_T void *
-#endif /* !SYS_NETFD_T */
-
-/* Error value for a SYS_NETFD */
-#ifndef SYS_NET_ERRORFD
-#define SYS_NET_ERRORFD ((SYS_NETFD)-1)
-#endif /* !SYS_NET_ERRORFD */
-
-/*
- * These structures were originally defined in nsapi.h, but those definitions
- * were removed in iPlanet Web Server 4.0.  The contents of these structures
- * are now private to the server implementation and must not be accessed
- * directly.  Instead, use the objset_*, object_*, directive_table_*, and
- * directive_* accessor functions.
- */
-typedef struct directive directive;
-typedef struct dtable dtable;
-typedef struct httpd_object httpd_object;
-typedef struct httpd_objset httpd_objset;
-
-/*
- * Type:        filebuffer, filebuf_t
- *
- * Description:
- *
- *      This structure is used to represent a buffered file.  On some
- *      systems the file may be memory-mapped.  A filebuffer is created
- *      by filebuf_open(), and destroyed by filebuf_close().
- *
- * Notes:
- *
- *      Direct access to the members of this structure, not using
- *      macros defined here, is discouraged.
- *
- *      The filebuf alias that used to be defined for this type was
- *      found to conflict with a C++ class of the same name, so it
- *      has been renamed to filebuf_t.
- */
-typedef struct filebuffer filebuffer;
-
-/* Version of filebuffer when memory-mapped files are supported */
-struct filebuffer {
-    SYS_FILE fd;
-#ifdef XP_WIN32
-    HANDLE fdmap;
-#endif
-    caddr_t fp;
-    int len;
-
-    unsigned char *inbuf;
-    int cursize;
-
-    int pos;
-    const char *errmsg;
-};
-
-/* Return next character or IO_EOF */
-#define filebuf_getc(b) ((b)->pos == (b)->len ? IO_EOF : (int)((b)->fp)[(b)->pos++])
-
-#define filebuf_iseof(b) ((b)->pos == (b)->len)
-
-/* C++ streamio defines a filebuf class. */
-typedef filebuffer filebuf_t;
-
-#ifdef XP_WIN32
-/* Use a filebuffer to read data from a pipe */
-#define pipebuf_getc(b) \
- ((b)->pos != (b)->cursize ? (int)((b)->inbuf[(b)->pos++]) : pipebuf_next(b,1))
-#endif /* XP_WIN32 */
-
-/*
- * Type:        netbuf
- *
- * Description:
- *
- *      This structure is used to represent a buffered network socket.
- *      It is created by netbuf_open(), and destroyed by netbuf_close().
- *
- * Notes:
- *
- *      Direct access to the members of this structure, not using
- *      macros defined here, is discouraged.
- *
- *      The inbuf field used to be (unsigned char *), but is now
- *      simply (char *).  The value returned by the netbuf_getc()
- *      macro is (int).
- */
-typedef struct netbuf netbuf;
-struct netbuf {
-    SYS_NETFD sd;
-
-    int pos, cursize, maxsize, rdtimeout;
-#ifdef XP_WIN32
-    CHAR address[64];
-#endif /* XP_WIN32 */
-    unsigned char *inbuf;
-    char *errmsg;
-#ifndef XP_WIN32
-    char address[64];
-#endif /* !XP_WIN32 */
-};
-
-/*
- * netbuf_getc gets a character from the given network buffer and returns 
- * it (as an integer).
- * 
- * It will return (int) IO_ERROR for an error and (int) IO_EOF for
- * an error condition or EOF respectively.
- */
-#define netbuf_getc(b) \
- ((b)->pos != (b)->cursize ? (int)((b)->inbuf[(b)->pos++]) : netbuf_next(b,1))
-
-/*
- * buffer_error returns the last error that occurred with buffer.  Don't use
- * this unless you know an error occurred.  Independent of network/file type.
- */
-#define buffer_error(b) ((b)->errmsg)
-
-/*
- * Type:        sendfiledata
- *
- * Description:
- *
- *      This structure is used to pass arguments to the net_sendfile()
- *      function.  offset and len may be set to 0 to transmit a file in its
- *      entirety.
- */
-typedef struct sendfiledata sendfiledata;
-struct sendfiledata {
-    SYS_FILE fd;         /* file to send */
-    size_t offset;       /* offset in file to start sending from */
-    size_t len;          /* number of bytes to send from file */
-    const void *header;  /* data to send before file */
-    int hlen;            /* number of bytes to send before file */
-    const void *trailer; /* data to send after file */
-    int tlen;            /* number of bytes to send after file */
-};
-
-/*
- * Type:        NSAPIIOVec
- *
- * Description:
- *
- *      This structure is used to pass arguments to the net_writev()
- *      and FilterWritevFunc() functions.  
- */
-#ifdef _LP64
-typedef struct NSAPIIOVec NSAPIIOVec;
-struct NSAPIIOVec {
-    char *iov_base;
-    int iov_len;
-};
-#else
-typedef struct iovec NSAPIIOVec;
-#endif /* _LP64 */
-
-
-/*
- * Type:        cinfo
- *
- * Description:
- *
- *      This is a structure that captures the information in the name/value
- *      pairs on one line of a mime.types file.  A cinfo structure is
- *      stored in the memory-resident database, indexed by each of the
- *      file extensions specified in the "exts" name/value pair.  It
- *      defines various attributes of resources with names containing
- *      the specified file extensions.
- *
- * Notes:
- *
- *      Pointers to cinfo structures returned by this API may or may not
- *      need to freed by the caller.  See the individual function
- *      descriptions.
- *
- *      The strings referenced by the fields of cinfo structures returned
- *      by this API should be considered read-only, and do not need to be
- *      freed by the caller, even when the cinfo structure does.
- */
-typedef struct cinfo cinfo;
-struct cinfo {
-    char *type;
-    char *encoding;
-    char *language;
-};
-
-
-typedef void* CONDVAR;
-typedef void *COUNTING_SEMAPHORE;
-typedef void* CRITICAL;
-
-#ifdef XP_UNIX
-typedef DIR* SYS_DIR;
-typedef struct dirent SYS_DIRENT;
-#endif /* XP_UNIX */
-
-#ifdef XP_WIN32
-
-typedef struct dirent_s dirent_s;
-struct dirent_s {
-    char *d_name;
-};
-
-typedef struct dir_s dir_s;
-struct dir_s {
-    HANDLE dp;
-    WIN32_FIND_DATA fdata;
-    dirent_s de;
-};
-
-typedef dir_s* SYS_DIR;
-typedef dirent_s SYS_DIRENT;
-
-#endif /* XP_WIN32 */
-
-typedef struct pb_param pb_param;
-struct pb_param {
-    char *name,*value;
-};
-
-typedef struct pb_entry pb_entry;
-struct pb_entry {
-    pb_param *param;
-    struct pb_entry *next;
-};
-
-typedef struct pblock pblock;
-struct pblock {
-    int hsize;
-    struct pb_entry **ht;
-};
-
-#ifndef POOL_HANDLE_T
-#define POOL_HANDLE_T
-typedef void *pool_handle_t;
-#endif
-
-#ifndef SEMAPHORE_T
-typedef void *SEMAPHORE;
-#define SEMAPHORE_T void *
-#endif /* !SEMAPHORE_T */
-
-#define SESSION_HASHSIZE 5
-
-typedef struct PListStruct_s PListStruct_s;
-typedef struct ACLListHandle ACLListHandle;
-
-#ifndef PR_AF_INET
-typedef union PRNetAddr PRNetAddr;
-#endif
-
-typedef struct Session Session;
-typedef struct Request Request;
-struct Session {
-    pblock *client;     /* client-specific information */
-
-    SYS_NETFD csd;      /* client file descriptor */
-    netbuf *inbuf;      /* input buffer */
-    int csd_open;
-
-    struct in_addr iaddr;
-
-    pool_handle_t *pool;
-
-    void *clauth;       /* v2 ACL client authentication information */
-    struct Session *next;
-    int fill;
-    struct sockaddr_in local_addr;      /* local addr for this session */
-
-    PListStruct_s *subject;
-    int ssl;            /* 0 = SSL OFF, 1 = SSL ON */
-    int clientauth;     /* 0 = client auth OFF, 1 = client auth ON */
-
-    PRNetAddr *pr_client_addr;
-    PRNetAddr *pr_local_addr;
-};
-
-/*
- * FuncPtr is a pointer to an NSAPI SAF function
- */
-
-#ifdef XP_UNIX
-typedef int Func(pblock *, Session *, Request *);
-#else /* XP_WIN32 */
-typedef int _cdecl Func(pblock *, Session *, Request *);
-#endif /* XP_WIN32 */
-
-typedef Func *FuncPtr;
-
-/*
- * FuncStruct is a structure used in the static declaration of the 
- * functions.  This static declaration is parsed into a hash table at 
- * startup.
- */
-
-typedef struct FuncStruct FuncStruct;
-
-struct FuncStruct {
-    const char * name;
-    FuncPtr func;
-    struct FuncStruct *next;
-    unsigned flags;
-    unsigned poolID;
-    unsigned pool_resolved;
-};
-
-/*
- * VSInitFunc, VSDestroyFunc, VSDirectiveInitFunc and VSDirectiveDestroyFunc
- */
-typedef struct VirtualServer VirtualServer;
-typedef int VSInitFunc(VirtualServer *incoming, const VirtualServer *current);
-typedef void VSDestroyFunc(VirtualServer *outgoing);
-typedef VSInitFunc *VSInitFuncPtr;
-typedef VSDestroyFunc *VSDestroyFuncPtr;
-typedef int VSDirectiveInitFunc(const directive *dir, VirtualServer *incoming, const VirtualServer *current);
-typedef void VSDirectiveDestroyFunc(const directive *dir, VirtualServer *outgoing);
-typedef VSDirectiveInitFunc *VSDirectiveInitFuncPtr;
-typedef VSDirectiveDestroyFunc *VSDirectiveDestroyFuncPtr;
-
-/*
- * Filter is an opaque filter identifier
- */
-typedef struct Filter Filter;
-
-/*
- * FilterContext stores context associated with a particular filter layer
- */
-
-typedef struct FilterContext FilterContext;
-
-struct FilterContext {
-    pool_handle_t *pool; /* pool context was allocated from */
-    Session *sn;         /* session being processed */
-    Request *rq;         /* request being processed */
-    void *data;          /* filter-defined private data */
-};
-
-/*
- * FilterLayer represents one layer of a filter stack
- */
-
-typedef struct FilterLayer FilterLayer;
-
-struct FilterLayer {
-    Filter *filter;         /* the filter at this layer in the filter stack */
-    FilterContext *context; /* context for the filter */
-    SYS_NETFD lower;        /* access to the next filter layer in the stack */
-};
-
-/*
- * Function prototypes for filter methods
- */
-typedef int (FilterInsertFunc)(FilterLayer *layer, pblock *pb);
-typedef void (FilterRemoveFunc)(FilterLayer *layer);
-typedef int (FilterFlushFunc)(FilterLayer *layer);
-typedef int (FilterReadFunc)(FilterLayer *layer, void *buf, int amount, int timeout);
-typedef int (FilterWriteFunc)(FilterLayer *layer, const void *buf, int amount);
-typedef int (FilterWritevFunc)(FilterLayer *layer, const NSAPIIOVec *iov, int iov_size);
-typedef int (FilterSendfileFunc)(FilterLayer *layer, sendfiledata *sfd);
-
-/*
- * FilterMethods is passed to filter_create() to declare the filter methods for
- * a new filter.  Each instance of the FilterMethods structure should be
- * initialized using the FILTER_METHODS_INITIALIZER macro.
- */
-
-typedef struct FilterMethods FilterMethods;
-
-struct FilterMethods {
-    size_t size;
-#if NSAPI_VERSION >= 302
-    FilterInsertFunc *insert;
-    FilterRemoveFunc *remove;
-    FilterFlushFunc *flush;
-    FilterReadFunc *read;
-    FilterWriteFunc *write;
-    FilterWritevFunc *writev;
-    FilterSendfileFunc *sendfile;
-#else
-    void *reserved1;
-    void *reserved2;
-    void *reserved3;
-    void *reserved4;
-    void *reserved5;
-    void *reserved6;
-    void *reserved7;
-#endif /* NSAPI_VERSION >= 302 */
-};
-
-#define FILTER_METHODS_INITIALIZER \
-{                                  \
-    sizeof(FilterMethods),         \
-    NULL, /* insert */             \
-    NULL, /* remove */             \
-    NULL, /* flush */              \
-    NULL, /* read */               \
-    NULL, /* write */              \
-    NULL, /* writev */             \
-    NULL  /* sendfile */           \
-}
-
-/*
- * Filter order definitions for filter_create()
- */
-#define FILTER_CONTENT_GENERATION       0xf0000
-#define FILTER_CONTENT_TRANSLATION_HIGH 0xa0000
-#define FILTER_CONTENT_TRANSLATION      0x90000
-#define FILTER_CONTENT_TRANSLATION_LOW  0x80000
-#define FILTER_CONTENT_CODING           0x50000
-#define FILTER_TRANSFER_CODING          0x40000
-#define FILTER_MESSAGE_CODING           0x30000
-#define FILTER_TRANSPORT_CODING         0x20000
-#define FILTER_NETWORK                  0x10000
-
-typedef struct shmem_s shmem_s;
-struct shmem_s {
-    void *data;   /* the data */
-#ifdef XP_WIN32
-    HANDLE fdmap;
-#endif /* XP_WIN32 */
-    int size;     /* the maximum length of the data */
-
-    char *name;   /* internal use: filename to unlink if exposed */
-    SYS_FILE fd;  /* internal use: file descriptor for region */
-};
-
-/* Define a handle for a thread */
-typedef void* SYS_THREAD;
-
-/* Define an error value for the thread handle */
-#define SYS_THREAD_ERROR NULL
-
-
-typedef struct conf_global_vars_s conf_global_vars_s;
-struct conf_global_vars_s {
-
-    /* What port we listen to */
-    int Vport;                                  /* OBSOLETE */
-#define server_portnum 80
-
-    /* What address to bind to */
-    char *Vaddr;                                /* OBSOLETE */
-
-    /* User to run as */
-    struct passwd *Vuserpw;
-
-    /* Directory to chroot to */
-    char *Vchr;
-
-    /* Where to log our pid to */
-    char *Vpidfn;
-
-#define pool_max conf_getglobals()->Vpool_max
-    int Vpool_max;
-#define pool_min conf_getglobals()->Vpool_min
-    int Vpool_min;                              /* OBSOLETE */
-#define pool_life conf_getglobals()->Vpool_life
-    int Vpool_life;                             /* OBSOLETE */
-
-    /* For multiprocess UNIX servers, the maximum threads per process */
-#define pool_maxthreads conf_getglobals()->Vpool_maxthreads
-    int Vpool_maxthreads;
-
-#define pool_minthreads conf_getglobals()->Vpool_minthreads
-    int Vpool_minthreads;                       /* OBSOLETE */
-
-    char *Vsecure_keyfn;                        /* OBSOLETE */
-    char *Vsecure_certfn;                       /* OBSOLETE */
-
-#define security_active 0
-    int Vsecurity_active;
-    int Vssl3_active;                           /* OBSOLETE */
-    int Vssl2_active;                           /* OBSOLETE */
-    int Vsecure_auth;                           /* OBSOLETE */
-    int Vsecurity_session_timeout;
-    long Vssl3_session_timeout;
-
-    /* The server's hostname as should be reported in self-ref URLs */
-#define server_hostname "x4"
-    char *Vserver_hostname;
-
-    /* The main object from which all are derived */
-#define root_object conf_getglobals()->Vroot_object
-    char *Vroot_object;
-
-    /* The object set the administrator has asked us to load */
-#define std_os conf_getglobals()->Vstd_os
-    httpd_objset *Vstd_os;
-
-    /* The root of ACL data structures */
-    void *Vacl_root;
-
-    /* The main error log, where all errors are logged */
-    char *Vmaster_error_log;
-
-    /* The server root directory (contains instance subdirectories) */
-#define server_root conf_getglobals()->Vserver_root
-    char *Vserver_root;
-
-    /* This server's id */
-#define server_id conf_getglobals()->Vserver_id
-    char *Vserver_id;
-
-    /* Admin server users file */
-    char *Vadmin_users;
-
-    /* The installation directory (contains bin and lib subdirectories) */
-    char *Vnetsite_root;
-
-    /* Digest authentication stale nonce timeout value */
-    int digest_stale_timeout;
-
-    int single_accept;          /* OBSOLETE */
-    int num_keep_alives;        /* OBSOLETE */
-    int log_verbose;            /* OBSOLETE */
-    int mmap_flags;             /* OBSOLETE */
-    int mmap_prots;             /* OBSOLETE */
-    int unused1;
-    int unused2;
-
-    /* Begin Enterprise 3.0 fields */
-    int accept_language;        /* turn accept-language on/off */
-
-    char *mtahost;
-    char *nntphost;             /* OBSOLETE */
-
-    /* The root of ACL data structures */
-    void *Vacl_root_30;
-
-    char *agentFilePath;        /* OBSOLETE */
-
-    int Allowed;                /* OBSOLETE */
-
-    pblock *genericGlobals;     /* OBSOLETE */
-
-    char *agentsACLFile;        /* OBSOLETE */
-
-    int wait_for_cgi;           /* OBSOLETE */
-    int cgiwatch_timeout;       /* OBSOLETE */
-    int started_by_watchdog;
-    int restarted_by_watchdog;
-    int old_accel_cache_enabled; /* OBSOLETE */
-    int Vssl_cache_entries;
-    int blocking_listen_socket; /* OBSOLETE */
-    pblock **initfns;
-    char *vs_config_file;       /* OBSOLETE */
-};
-
-/* Type used for Request rq_attr bit flags */
-#ifdef AIX
-#define RQATTR unsigned
-#else
-#define RQATTR unsigned long
-#endif
-
-struct Request {
-    /* Server working variables */
-    pblock *vars;
-
-    /* The method, URI, and protocol revision of this request */
-    pblock *reqpb;
-    /* Protocol specific headers */
-    int loadhdrs;
-    pblock *headers;
-
-    /* Server's response headers */
-    int senthdrs;
-    pblock *srvhdrs;
-
-    /* The object set constructed to fulfill this request */
-    httpd_objset *os;
-    /* Array of objects that were created from .nsconfig files */
-    httpd_objset *tmpos;
-
-    /* The stat last returned by request_stat_path */
-    char *statpath;
-    char *staterr;
-    struct stat *finfo;
-
-    /* access control state */
-    int aclstate;               /* ACL decision state */
-    int acldirno;               /* deciding ACL directive number */
-    char *aclname;              /* name of deciding ACL */
-    pblock *aclpb;              /* OBSOLETE */
-    /* 3.0 ACL list pointer */
-    ACLListHandle *acllist;
-
-    int request_is_cacheable;   /* */
-    int directive_is_cacheable; /* set by SAFs with no external side effects that make decisions based solely on URI and path */
-
-    char *cached_headers;       /* OBSOLETE */
-    int cached_headers_len;     /* OBSOLETE */
-    char *unused;
-
-    /* HTTP/1.1 features */
-#define REQ_TIME(x)             (x)->req_start
-    time_t req_start;           /* time request arrived - used for selecting weak or strong cache validation */
-    short protv_num;            /* protocol version number */
-    short method_num;           /* method number */
-    struct rq_attr {
-        RQATTR abs_uri:1;               /* set if absolute URI was used */
-        RQATTR chunked:1;               /* chunked transfer-coding */
-        RQATTR keep_alive:1;            /* connection keep-alive */
-        RQATTR pipelined:1;             /* request packet is pipelined */
-        RQATTR internal_req:1;          /* this was an internal request */
-        RQATTR perm_req:1;              /* don't FREE() this request */
-        RQATTR header_file_present:1;   /* OBSOLETE */
-        RQATTR footer_file_present:1;   /* OBSOLETE */
-        RQATTR jvm_attached:1;          /* OBSOLETE */
-        RQATTR req_restarted:1;         /* request was restarted */
-        RQATTR jvm_request_locked:1;    /* used for first-request serialization on some platforms */
-        RQATTR default_type_set:1;      /* set if default types were set using set-default-type objecttype function */
-        RQATTR is_web_app:1;            /* OBSOLETE */
-        RQATTR ssl_unclean_shutdown:1;  /* set if browser requires unclean SSL shutdown */
-        RQATTR vary_accept_language:1;  /* set if request was restarted based on an accept-language header */
-        RQATTR reserved:17;             /* if you add a flag, make sure to subtract from this */
-    } rq_attr;
-    char *hostname;             /* hostname used to access server (always non-NULL) */
-    int allowed;                /* OBSOLETE */
-    int byterange;              /* OBSOLETE */
-    short status_num;           /* HTTP status code */
-
-    int staterrno;              /* used for rqstat */
-    Request *orig_rq;           /* original Request - used for internal redirects */
-};
-
-/* Request attribute macros */
-#define ABS_URI(x)                      (x)->rq_attr.abs_uri
-#define CHUNKED(x)                      (x)->rq_attr.chunked
-#define KEEP_ALIVE(x)                   (x)->rq_attr.keep_alive 
-#define PIPELINED(x)                    (x)->rq_attr.pipelined 
-#define INTERNAL_REQUEST(x)             (x)->rq_attr.internal_req 
-#define RESTARTED_REQUEST(x)            (x)->rq_attr.req_restarted
-#define PERM_REQUEST(x)                 (x)->rq_attr.perm_req
-#define JVM_REQUEST_LOCKED(x)           (x)->rq_attr.jvm_request_locked
-#define SSL_UNCLEAN_SHUTDOWN(x)         (x)->rq_attr.ssl_unclean_shutdown
-#define VARY_ACCEPT_LANGUAGE(x)         (x)->rq_attr.vary_accept_language
-
-/* Define methods for HTTP/1.1 */
-#define METHOD_HEAD     0
-#define METHOD_GET      1
-#define METHOD_PUT      2
-#define METHOD_POST     3
-#define METHOD_DELETE   4
-#define METHOD_TRACE    5
-#define METHOD_OPTIONS  6
-/* The following methods are Netscape method extensions */
-#define METHOD_MOVE     7
-#define METHOD_INDEX    8
-#define METHOD_MKDIR    9
-#define METHOD_RMDIR    10
-#define METHOD_COPY     11
-#define METHOD_MAX      12      /* Number of methods available on this server */
-
-#define ISMGET(r)       ((r)->method_num == METHOD_GET)
-#define ISMHEAD(r)      ((r)->method_num == METHOD_HEAD)
-#define ISMPUT(r)       ((r)->method_num == METHOD_PUT)
-#define ISMPOST(r)      ((r)->method_num == METHOD_POST)
-#define ISMDELETE(r)    ((r)->method_num == METHOD_DELETE)
-#define ISMMOVE(r)      ((r)->method_num == METHOD_MOVE)
-#define ISMINDEX(r)     ((r)->method_num == METHOD_INDEX)
-#define ISMMKDIR(r)     ((r)->method_num == METHOD_MKDIR)
-#define ISMRMDIR(r)     ((r)->method_num == METHOD_RMDIR)
-#define ISMCOPY(r)      ((r)->method_num == METHOD_COPY)
-#define ISMTRACE(r)     ((r)->method_num == METHOD_TRACE)
-#define ISMOPTIONS(r)   ((r)->method_num == METHOD_OPTIONS)
-
-
-/* --- End type definitions --- */
-
-/* --- Begin dispatch vector table definition --- */
-/* --- End dispatch vector table definition --- */
-
-/* --- Begin API macro definitions --- */
-
-#ifndef INTNSAPI
-
-#if NSAPI_VERSION >= 301
-
-/*
- * In Sun ONE Web Server 6.1 and higher, http_parse_request("", NULL, NULL)
- * returns the NSAPI version.  In previous releases, it returns -1.
- */
-#define __NSAPI_RUNTIME_VERSION \
-        ((*__nsapi30_table->f_http_parse_request)("", NULL, NULL))
-
-/*
- * NSAPI_RUNTIME_VERSION returns the NSAPI version the server implements.  The
- * returned NSAPI version number is reliable only in iPlanet Web Server 6.0,
- * Netscape Enterprise Server 6.0, and Sun ONE Web Server 6.0 and higher.
- */
-#define NSAPI_RUNTIME_VERSION \
-        (__NSAPI_RUNTIME_VERSION > 0 ? __NSAPI_RUNTIME_VERSION : 301)
-
-#endif /* NSAPI_VERSION >= 301 */
-
-#define system_version (*__nsapi30_table->f_system_version)
-
-/*
- * Depending on the system, memory allocated via these macros may come from 
- * an arena.  If these functions are called from within an Init function, they
- * will be allocated from permanent storage.  Otherwise, they will be freed 
- * when the current request is finished.
- */
-
-
-
-#endif /* !INTNSAPI */
-
-#ifdef XP_UNIX
-#define dir_open opendir
-#define dir_read readdir
-#define dir_close closedir
-#define dir_create(path) mkdir(path, 0755)
-#define dir_remove rmdir
-#define system_chdir chdir
-#define file_unix2local(path,p2) strcpy(p2,path)
-#endif /* XP_UNIX */
-
-#ifdef XP_WIN32
-#define dir_create _mkdir
-#define dir_remove _rmdir
-#define system_chdir SetCurrentDirectory
-#endif /* XP_WIN32 */
-
-/*
- * Thread-safe variants of localtime and gmtime
- */
-#define system_localtime(curtime, ret) util_localtime(curtime, ret)
-#define system_gmtime(curtime, ret) util_gmtime(curtime, ret)
-
-/* 
- * pblock_find finds the entry with the given name in pblock pb.
- *
- * If it is successful, it returns the param block.  If not, it returns NULL.
- */
-#define pblock_find(name, pb) (pblock_fr(name,pb,0))
-
-/*
- * pblock_remove behaves exactly like pblock_find, but removes the given
- * entry from pb.
- */
-#define pblock_remove(name, pb) (pblock_fr(name,pb,1))
-
-/*
- * session_dns returns the DNS hostname of the client of this session,
- * and inserts it into the client pblock.  Returns NULL if unavailable.
- */
-#define session_dns(sn) session_dns_lookup(sn, 0)
-
-/*
- * session_maxdns looks up a hostname from an IP address, and then verifies 
- * that the host is really who they claim to be. 
- */
-#define session_maxdns(sn) session_dns_lookup(sn, 1)
-
-
-/* nsapi functions */
-
-ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes);
-
-NSAPI_PUBLIC pb_param *INTparam_create(const char *name, const char *value);
-
-NSAPI_PUBLIC int INTparam_free(pb_param *pp);
-
-NSAPI_PUBLIC pblock *INTpblock_create(int n);
-
-NSAPI_PUBLIC void INTpblock_free(pblock *pb);
-
-NSAPI_PUBLIC char *INTpblock_findval(const char *name, const pblock *pb);
-
-NSAPI_PUBLIC pb_param *INTpblock_nvinsert(const char *name, const char *value, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb);
-
-NSAPI_PUBLIC pb_param *INTpblock_nninsert(const char *name, int value, pblock *pb);
-
-NSAPI_PUBLIC void INTpblock_pinsert(pb_param *pp, pblock *pb);
-
-NSAPI_PUBLIC int INTpblock_str2pblock(const char *str, pblock *pb);
-
-NSAPI_PUBLIC char *INTpblock_pblock2str(const pblock *pb, char *str);
-
-NSAPI_PUBLIC int INTpblock_copy(const pblock *src, pblock *dst);
-
-NSAPI_PUBLIC pblock *INTpblock_dup(const pblock *src);
-
-NSAPI_PUBLIC char **INTpblock_pb2env(const pblock *pb, char **env);
-
-NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value);
-
-NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n);
-
-NSAPI_PUBLIC pb_param *INTpblock_fr(const char *name, pblock *pb, int remove);
-
-NSAPI_PUBLIC char *INTpblock_replace(const char *name,char * new_value,pblock *pb);
-
-NSAPI_PUBLIC int INTpblock_str2pblock_lowercasename(const char *str, pblock *pb);
-
-//NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb);
-
-//NSAPI_PUBLIC const pb_key *pblock_key(const char *name);
-
-//NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen);
-
-//NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb);
-
-//NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb);
-
-//NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb);
-
-//NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb);
-
-//NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb);
-
-//NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb);
-
-//NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb);
-
-//NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, PRInt64 value, pblock *pb);
-
-#define param_create INTparam_create
-#define param_free INTparam_free
-#define pblock_create INTpblock_create
-#define pblock_free INTpblock_free
-#define pblock_findval INTpblock_findval
-#define pblock_nvinsert INTpblock_nvinsert
-#define pblock_nninsert INTpblock_nninsert
-#define pblock_pinsert INTpblock_pinsert
-#define pblock_str2pblock INTpblock_str2pblock
-#define pblock_pblock2str INTpblock_pblock2str
-#define pblock_copy INTpblock_copy
-#define pblock_dup INTpblock_dup
-#define pblock_pb2env INTpblock_pb2env
-#define pblock_fr INTpblock_fr
-#define pblock_replace INTpblock_replace
-
-
-
-void protocol_status(Session *sn, Request *rq, int n, const char *m);
-
-int http_start_response(Session *sn, Request *rq);
-#define protocol_start_response http_start_response
-int request_header(char *name, char **value, Session *sn, Request *rq);
-
-typedef void (*thrstartfunc)(void *);
-SYS_THREAD INTsysthread_start(int prio, int stksz, thrstartfunc fn, void *arg);
-NSAPI_PUBLIC void INTsysthread_sleep(int milliseconds);
-
-#define systhread_start INTsysthread_start
-#define systhread_sleep INTsysthread_sleep
-
-
-void webserver_atrestart(void (*fn)(void *), void *data);
-#define magnus_atrestart webserver_atrestart
-
-
-NSAPI_PUBLIC int INTshexp_match(const char *str, const char *exp);
-#define shexp_match INTshexp_match
-
-
-
-NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify);
-
-
-/* --- OBSOLETE ----------------------------------------------------------
- * The following macros/functions are obsolete and are only maintained for
- * compatibility.  Do not use them.
- * -----------------------------------------------------------------------
- */
-
-
-/* new macro and function definitions begin */
-
-/* netbuf functions */
-NSAPI_PUBLIC netbuf *netbuf_open(SYS_NETFD sd, int sz);
-
-NSAPI_PUBLIC void netbuf_close(netbuf *buf);
-
-NSAPI_PUBLIC unsigned char * netbuf_replace(netbuf *buf,
-    unsigned char *inbuf, int pos, int cursize, int maxsize);
-
-NSAPI_PUBLIC int netbuf_next(netbuf *buf, int advance);
-
-NSAPI_PUBLIC int netbuf_getbytes(netbuf *buf, char *buffer, int size);
-
-NSAPI_PUBLIC int netbuf_grab(netbuf *buf, int sz);
-
-/* end new macro and function definitions */
-
-#define SYS_STDERR STDERR_FILENO
-
-#ifdef XP_WIN32
-
-typedef HANDLE pid_t;
-
-#define ERROR_PIPE \
-        (ERROR_BROKEN_PIPE | ERROR_BAD_PIPE | \
-         ERROR_PIPE_BUSY | ERROR_PIPE_LISTENING | ERROR_PIPE_NOT_CONNECTED)
-#define CONVERT_TO_PRINTABLE_FORMAT(Filename)   \
-{                                               \
-        register char *s;                       \
-        if (Filename)                           \
-        for (s = Filename; *s; s++)             \
-                if ( *s == '\\')                \
-                        *s = '/';               \
-}
-#define CONVERT_TO_NATIVE_FS(Filename)          \
-{                                               \
-        register char *s;                       \
-        if (Filename)                           \
-                for (s = Filename; *s; s++)     \
-                        if ( *s == '/')         \
-                                *s = '\\';      \
-}                                                                        
-
-#ifdef INTNSAPI
-NSAPI_PUBLIC extern nsapi_dispatch_t *__nsapi30_table;
-#if NSAPI_VERSION >= 302
-NSAPI_PUBLIC extern nsapi302_dispatch_t *__nsapi302_table;
-#endif /* NSAPI_VERSION >= 302 */
-#if NSAPI_VERSION >= 303
-NSAPI_PUBLIC extern nsapi303_dispatch_t *__nsapi303_table;
-#endif /* NSAPI_VERSION >= 303 */
-#else
-__declspec(dllimport) nsapi_dispatch_t *__nsapi30_table;
-#if NSAPI_VERSION >= 302
-__declspec(dllimport) nsapi302_dispatch_t *__nsapi302_table;
-#endif /* NSAPI_VERSION >= 302 */
-#if NSAPI_VERSION >= 303
-__declspec(dllimport) nsapi303_dispatch_t *__nsapi303_table;
-#endif /* NSAPI_VERSION >= 303 */
-#endif /* INTNSAPI */
-
-#else /* !XP_WIN32 */
-
-
-#endif /* XP_WIN32 */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !PUBLIC_NSAPI_H */
--- a/src/server/object.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "nsapi.h"
-
-#include "object.h"
-
-#include "pool.h"
-#include "func.h"
-
-
-
-httpd_object* object_new(char *name) {
-    // TODO: Speicherverwaltung
-    httpd_object *obj = malloc(sizeof(httpd_object));
-    obj->name = name;
-    obj->path = NULL;
-
-    // create directive table
-    obj->dt = calloc(sizeof(struct dtable), NUM_NSAPI_TYPES - 1);
-    obj->nd = NUM_NSAPI_TYPES - 1;
-
-    return obj;
-}
-
-void object_free(httpd_object *obj) {
-    free(obj->name);
-    // TODO: free objects
-    free(obj->dt);
-}
-
-
-void object_add_directive(httpd_object *obj, directive *dir, int dt) {
-    dtable *l = object_get_dtable(obj, dt);
-    // allocate space for the new directive
-
-    //l->dirs = realloc(l->dirs, (l->ndir+1)*sizeof(void*));
-    /* TODO: aus irgend einem Grund funktioniert realloc nicht. warum?? */
-    
-    directive **drs = malloc((l->ndir+1)*sizeof(void*));
-    for(int i=0;i<l->ndir;i++) {
-        drs[i] = l->dirs[i];
-    }
-    if(l->dirs != NULL) {
-        free(l->dirs);
-    }
-    l->dirs = drs;
-
-    // add directive
-    l->dirs[l->ndir] = dir;
-    l->ndir++;
-}
-
-
-/* objset functions */
-httpd_objset* objset_create(pool_handle_t *pool) {
-    httpd_objset *os = pool_malloc(pool, sizeof(httpd_objset));
-
-    os->obj = pool_calloc(pool, 2, sizeof(void*));
-    os->pos = 0;
-
-    return os;
-}
-
-void objset_add_object(pool_handle_t *p, httpd_objset *os, httpd_object *obj) {
-    if(os->pos != 0 && os->pos % 2 == 0) {
-        os->obj = pool_realloc(p, os->obj, (os->pos + 2) * sizeof(void*));
-    }
-    os->obj[os->pos] = obj;
-    os->pos++;
-}
-
-
-
-
-httpd_objset* create_test_objset() {
-    httpd_objset *objset = malloc(sizeof(httpd_objset));
-    objset->obj = calloc(1, sizeof(httpd_object*));
-
-    httpd_object *obj = object_new("default");
-    objset->obj[0] = obj;
-    objset->pos = 1;
-    
-    directive *d1 = malloc(sizeof(directive));
-    d1->func = get_function("test-nametrans");
-    d1->param = NULL;
-    object_add_directive(obj, d1, NSAPINameTrans);
-
-    directive *d2 = malloc(sizeof(directive));
-    d2->func = get_function("test-service");
-    d2->param = NULL;
-    object_add_directive(obj, d2, NSAPIService);
-    
-    return objset;
-}
-
-
-void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj) {
-    conf->nobj++;
-    conf->objects = realloc(conf->objects, conf->nobj * sizeof(void*));
-    conf->objects[conf->nobj - 1] = obj;
-}
-
-
-void nsapi_context_next_stage(NSAPIContext *context) {
-    context->dtable_index  = 0;
-    context->objset_index  = -1;
-    context->last_req_code = REQ_NOACTION;
-}
--- a/src/server/object.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef OBJECT_H
-#define	OBJECT_H
-
-#include "nsapi.h"
-#include "pool.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-// TODO: Enum auslagern in andere Datei?
-enum RequestPhase {
-    NSAPIAuthTrans = 0,
-    NSAPINameTrans,
-    NSAPIPathCheck,
-    NSAPIObjectType,
-    NSAPIService,
-    NSAPIAddLog,
-    REQ_FINISH,
-    NUM_NSAPI_TYPES
-};
-typedef enum RequestPhase RequestPhase;
-
-typedef struct Condition          Condition;
-typedef int8_t                    ConditionResult;
-
-typedef struct NSAPIContext       NSAPIContext;
-typedef struct HTTPObjectConfig   HTTPObjectConfig;
-
-struct directive {
-    FuncStruct *func;
-    pblock     *param;
-    Condition  *cond;
-};
-
-struct dtable {
-    directive **dirs;
-    int       ndir;
-};
-
-struct httpd_object {
-    char   *name;
-    char   *path;
-    dtable *dt;
-    int    nd;
-};
-
-struct httpd_objset {
-    httpd_object **obj;
-    int pos;
-};
-
-struct Condition {
-    Condition  *parent;
-    int        expression;
-    int        index; /* used by NSAPIContext to link expression with result */
-};
-
-
-struct NSAPIContext{
-    HTTPObjectConfig  *conf;
-
-    ConditionResult   **results;
-    int               nres;
-
-    //httpd_objset      *objset;
-    int last_req_code;
-
-    int objset_index;
-    int dtable_index;
-};
-
-struct HTTPObjectConfig {
-    httpd_object  **objects;
-    int           nobj;
-    pool_handle_t *pool;
-};
-
-/*
- * creates a new httpd_object
- */
-httpd_object* object_new(char *name);
-
-/*
- * frees an httpd_object
- */
-void object_free(httpd_object *obj);
-
-/*
- * adds a directive to the object with the type dt (enum RequestPhase)
- */
-void object_add_directive(httpd_object *obj, directive *dir, int dt);
-
-/*
- * get a list of all directives with a specific type
- */
-#define object_get_dtable(obj,type) &obj->dt[type];
-
-
-
-/*
- * creates a new httpd_objset
- */
-httpd_objset* objset_create(pool_handle_t *pool);
-
-/*
- * adds a object to the objset
- */
-void objset_add_object(pool_handle_t *p, httpd_objset *os, httpd_object *obj);
-
-
-/*
- * creates a new HTTPObjectConfig
- */
-// TODO
-
-/*
- * adds an object to the object configuration
- */
-void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj);
-
-
-
-/*
- * prepares the NSAPI context for the next request stage
- */
-void nsapi_context_next_stage(NSAPIContext *context);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* OBJECT_H */
-
--- a/src/server/objecttype.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "objecttype.h"
-#include "pblock.h"
-
-#include "sstring.h"
-
-int object_type_by_extension(pblock *pb, Session *sn, Request *rq) {
-    sstr_t ppath = sstr(pblock_findkeyval(pb_key_ppath, rq->vars));
-    sstr_t ct;
-    if(ppath.ptr[ppath.length - 1] == '/') {
-        /* directory */
-        ct = sstrn("internal/directory", 18);
-    } else {
-        sstr_t ext;
-        ext.length = 0;
-        for(int i=ppath.length - 1;i>=0;i--) {
-            if(ppath.ptr[i] == '.') {
-                ext.ptr = ppath.ptr + i + 1;
-                ext.length = ppath.length - i - 1;
-            }
-        }
-
-        if(ext.length == 0) {
-            /* no extension, no type */
-            return REQ_NOACTION;
-        }
-
-        /* TODO: we need a map for extensions/types */
-        if(!sstrcmp(ext, sstrn("txt", 3))) {
-            ct = sstr("text/plain");
-        } else if(!sstrcmp(ext, sstrn("htm", 3))) {
-            ct = sstr("text/html");
-        } else if(!sstrcmp(ext, sstrn("html", 4))) {
-            ct = sstr("text/html");
-        } else if(!sstrcmp(ext, sstrn("xml", 3))) {
-            ct = sstr("text/xml");
-        }
-    }
-
-    pblock_kvinsert(pb_key_content_type, ct.ptr, ct.length, rq->srvhdrs);
-    return REQ_PROCEED;
-}
--- a/src/server/objecttype.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef OBJECTTYPE_H
-#define	OBJECTTYPE_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-int object_type_by_extension(pblock *pb, Session *sn, Request *rq);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* OBJECTTYPE_H */
-
--- a/src/server/objs.mk	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
-#
-# Copyright 2011 Olaf Wintermann. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-#   1. Redistributions of source code must retain the above copyright notice,
-#      this list of conditions and the following disclaimer.
-#
-#   2. Redistributions in binary form must reproduce the above copyright
-#      notice, this list of conditions and the following disclaimer in the
-#      documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-
-SRC_DIR = server/
-
-OBJPRE = $(OBJ_DIR)$(SRC_DIR)
-
-MOBJ = main.o
-MOBJ += webserver.o
-MOBJ += util.o
-MOBJ += uri.o
-MOBJ += systhr.o
-MOBJ += system.o
-MOBJ += pool.o
-MOBJ += plist.o
-MOBJ += pblock.o
-MOBJ += sstring.o
-MOBJ += list.o
-MOBJ += map.o
-MOBJ += func.o
-MOBJ += ws-fn.o
-MOBJ += conf.o
-MOBJ += httplistener.o
-MOBJ += session.o
-MOBJ += request.o
-MOBJ += io.o
-MOBJ += thrpool.o
-MOBJ += sessionhandler.o
-MOBJ += httpparser.o
-MOBJ += httprequest.o
-MOBJ += vserver.o
-MOBJ += object.o
-MOBJ += nametrans.o
-MOBJ += service.o
-MOBJ += protocol.o
-MOBJ += netbuf.o
-MOBJ += shexp.o
-MOBJ += objecttype.o
-MOBJ += strbuf.o
-MOBJ += webdav.o
-MOBJ += davparser.o
-MOBJ += dlist.o
-MOBJ += saxhandler.o
-
-MAINOBJS = $(MOBJ:%=$(OBJPRE)%)
-
--- a/src/server/pblock.cpp	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1211 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * pblock.c: Handles Parameter Blocks
- * 
- * See pblock.h for public documentation.
- * 
- * Rob McCool
- * 
- * This code uses property lists to implement pblocks.
- */
-
-
-#include <limits.h>
-#include "pblock.h"
-#include "plist_pvt.h"
-#include "plist.h"
-#include "LinkedList.hh"
-#include "util.h"   /* util_itoa */
-#include "pool.h"
-#include "systhr.h"
-
-#define MALLOC_POOL_HANDLE (thread_malloc_key != -1 ? (pool_handle_t *)systhread_getdata(thread_malloc_key) : getThreadMallocPool())
-
-static int thread_malloc_key = -1;
-static int _pblock_str2pblock(const char* str, pblock* pb, PRBool lowerCase);
-
-static pool_handle_t *getThreadMallocPool()
-{
-    pool_handle_t *thread_malloc_pool = 0;
-
-    thread_malloc_key = getThreadMallocKey();
-    if (thread_malloc_key != -1) {
-        thread_malloc_pool = (pool_handle_t *)systhread_getdata(thread_malloc_key);
-    }
-
-    return thread_malloc_pool;
-}
-
-/* ------------------------------- HashList ------------------------------- */
-
-template <class Name, class Value>
-class HashList {
-public:
-    HashList(int mask)
-    : _mask(mask),
-      _list(new CList<Value>[mask + 1])
-    { }
-
-    void Insert(Name name, Value *value)
-    {
-        _list[name & _mask].Append(value);
-    }
-
-    const CList<Value>& Find(Name name)
-    {
-        return _list[name & _mask];
-    }
-
-private:
-    CList<Value> *_list;
-    unsigned int _mask;
-};
-
-/* ---------------------- pb_key static initializers ---------------------- */
-
-/*
- * pb_key
- *
- * Contains a precomputed hash value for a specific pblock variable name.
- */
-typedef struct pb_key pb_key;
-struct pb_key {
-    const char *name;
-    int namelen; 
-    unsigned int hashval;
-    int sizendx;
-    int hashndx;
-};
-
-static HashList<unsigned int, pb_key> _hashKeys(0x7f);
-CList<pb_key> _listKeys;
-
-static const pb_key *const _create_key(const char *name, int sizendx = 0)
-{
-    /* Create a the new pb_key */
-    pb_key *key = (pb_key*)malloc(sizeof(pb_key));
-    key->name = STRDUP(name);
-    key->namelen = strlen(name);
-    key->hashval = PListHash(name);
-    key->sizendx = sizendx;
-    key->hashndx = key->hashval % PLSIZENDX(sizendx);
-
-    /* Group pb_keys by hashval for later retrieval */
-    _hashKeys.Insert(key->hashval, key);
-
-    /* Keep a list of all the registered keys */
-    _listKeys.Append(key);
-
-    return key;
-}
-
-const pb_key *const pb_key_accept = _create_key("accept");
-const pb_key *const pb_key_accept_charset = _create_key("accept-charset");
-const pb_key *const pb_key_accept_encoding = _create_key("accept-encoding");
-const pb_key *const pb_key_accept_language = _create_key("accept-language");
-const pb_key *const pb_key_accept_ranges = _create_key("accept-ranges");
-const pb_key *const pb_key_actual_route = _create_key("actual-route");
-const pb_key *const pb_key_age = _create_key("age");
-const pb_key *const pb_key_always_allow_chunked = _create_key("always-allow-chunked");
-const pb_key *const pb_key_always_use_keep_alive = _create_key("always-use-keep-alive");
-const pb_key *const pb_key_auth_cert = _create_key("auth-cert");
-const pb_key *const pb_key_auth_expiring = _create_key("auth-expiring");
-const pb_key *const pb_key_auth_group = _create_key("auth-group");
-const pb_key *const pb_key_auth_type = _create_key("auth-type");
-const pb_key *const pb_key_auth_user = _create_key("auth-user");
-const pb_key *const pb_key_authorization = _create_key("authorization");
-const pb_key *const pb_key_browser = _create_key("browser");
-const pb_key *const pb_key_c2p_cl = _create_key("c2p-cl");
-const pb_key *const pb_key_c2p_hl = _create_key("c2p-hl");
-const pb_key *const pb_key_cache_info = _create_key("cache-info");
-const pb_key *const pb_key_charset = _create_key("charset");
-const pb_key *const pb_key_check_http_server = _create_key("check-http-server");
-const pb_key *const pb_key_ChunkedRequestBufferSize = _create_key("ChunkedRequestBufferSize");
-const pb_key *const pb_key_ChunkedRequestTimeout = _create_key("ChunkedRequestTimeout");
-const pb_key *const pb_key_cipher = _create_key("cipher");
-const pb_key *const pb_key_clf_request = _create_key("clf-request");
-const pb_key *const pb_key_cli_status = _create_key("cli-status");
-const pb_key *const pb_key_client_cert_nickname = _create_key("client-cert-nickname");
-const pb_key *const pb_key_client_ip = _create_key("client-ip");
-const pb_key *const pb_key_close = _create_key("close");
-const pb_key *const pb_key_connect_timeout = _create_key("connect-timeout");
-const pb_key *const pb_key_connection = _create_key("connection");
-const pb_key *const pb_key_cont = _create_key("cont");
-const pb_key *const pb_key_content_encoding = _create_key("content-encoding");
-const pb_key *const pb_key_content_language = _create_key("content-language");
-const pb_key *const pb_key_content_length = _create_key("content-length");
-const pb_key *const pb_key_content_location = _create_key("content-location");
-const pb_key *const pb_key_content_md5 = _create_key("content-md5");
-const pb_key *const pb_key_content_range = _create_key("content-range");
-const pb_key *const pb_key_content_type = _create_key("content-type");
-const pb_key *const pb_key_cookie = _create_key("cookie");
-const pb_key *const pb_key_date = _create_key("date");
-const pb_key *const pb_key_DATE_GMT = _create_key("DATE_GMT");
-const pb_key *const pb_key_DATE_LOCAL = _create_key("DATE_LOCAL");
-const pb_key *const pb_key_dir = _create_key("dir");
-const pb_key *const pb_key_Directive = _create_key("Directive");
-const pb_key *const pb_key_dns = _create_key("dns");
-const pb_key *const pb_key_DOCUMENT_NAME = _create_key("DOCUMENT_NAME");
-const pb_key *const pb_key_DOCUMENT_URI = _create_key("DOCUMENT_URI");
-const pb_key *const pb_key_domain = _create_key("domain");
-const pb_key *const pb_key_enc = _create_key("enc");
-const pb_key *const pb_key_engine = _create_key("engine");
-const pb_key *const pb_key_error_action = _create_key("error-action");
-const pb_key *const pb_key_error_desc = _create_key("error-desc");
-const pb_key *const pb_key_error_fn = _create_key("error-fn");
-const pb_key *const pb_key_escape = _create_key("escape");
-const pb_key *const pb_key_escaped = _create_key("escaped");
-const pb_key *const pb_key_etag = _create_key("etag");
-const pb_key *const pb_key_expect = _create_key("expect");
-const pb_key *const pb_key_expires = _create_key("expires");
-const pb_key *const pb_key_expr = _create_key("expr");
-const pb_key *const pb_key_filter = _create_key("filter");
-const pb_key *const pb_key_find_pathinfo_forward = _create_key("find-pathinfo-forward");
-const pb_key *const pb_key_flushTimer = _create_key("flushTimer");
-const pb_key *const pb_key_fn = _create_key("fn");
-const pb_key *const pb_key_from = _create_key("from");
-const pb_key *const pb_key_full_headers = _create_key("full-headers");
-const pb_key *const pb_key_hdr = _create_key("hdr");
-const pb_key *const pb_key_host = _create_key("host");
-const pb_key *const pb_key_hostname = _create_key("hostname");
-const pb_key *const pb_key_if_match = _create_key("if-match");
-const pb_key *const pb_key_if_modified_since = _create_key("if-modified-since");
-const pb_key *const pb_key_if_none_match = _create_key("if-none-match");
-const pb_key *const pb_key_if_range = _create_key("if-range");
-const pb_key *const pb_key_if_unmodified_since = _create_key("if-unmodified-since");
-const pb_key *const pb_key_ip = _create_key("ip");
-const pb_key *const pb_key_iponly = _create_key("iponly");
-const pb_key *const pb_key_issuer_dn = _create_key("issuer_dn");
-const pb_key *const pb_key_jroute = _create_key("jroute");
-const pb_key *const pb_key_keep_alive = _create_key("keep-alive");
-const pb_key *const pb_key_keep_alive_timeout = _create_key("keep-alive-timeout");
-const pb_key *const pb_key_keysize = _create_key("keysize");
-const pb_key *const pb_key_lang = _create_key("lang");
-const pb_key *const pb_key_LAST_MODIFIED = _create_key("LAST_MODIFIED");
-const pb_key *const pb_key_last_modified = _create_key("last-modified");
-const pb_key *const pb_key_level = _create_key("level");
-const pb_key *const pb_key_location = _create_key("location");
-const pb_key *const pb_key_lock_owner = _create_key("lock-owner");
-const pb_key *const pb_key_magnus_charset = _create_key("magnus-charset");
-const pb_key *const pb_key_magnus_internal = _create_key("magnus-internal");
-const pb_key *const pb_key_magnus_internal_dav_src = _create_key("magnus-internal/dav-src");
-const pb_key *const pb_key_magnus_internal_default_acls_only = _create_key("magnus-internal/default-acls-only");
-const pb_key *const pb_key_magnus_internal_error_j2ee = _create_key("magnus-internal/error-j2ee");
-const pb_key *const pb_key_magnus_internal_j2ee_nsapi = _create_key("magnus-internal/j2ee-nsapi");
-const pb_key *const pb_key_magnus_internal_preserve_srvhdrs = _create_key("magnus-internal/preserve-srvhdrs-after-req-restart");
-const pb_key *const pb_key_magnus_internal_set_request_status = _create_key("magnus-internal/set-request-status");
-const pb_key *const pb_key_magnus_internal_set_response_status = _create_key("magnus-internal/set-response-status");
-const pb_key *const pb_key_magnus_internal_webapp_errordesc = _create_key("magnus-internal/webapp-errordesc");
-const pb_key *const pb_key_matched_browser = _create_key("matched-browser");
-const pb_key *const pb_key_max_age = _create_key("max-age");
-const pb_key *const pb_key_max_forwards = _create_key("max-forwards");
-const pb_key *const pb_key_message = _create_key("message");
-const pb_key *const pb_key_method = _create_key("method");
-const pb_key *const pb_key_name = _create_key("name");
-const pb_key *const pb_key_nocache = _create_key("nocache");
-const pb_key *const pb_key_nostat = _create_key("nostat");
-const pb_key *const pb_key_ntrans_base = _create_key("ntrans-base");
-const pb_key *const pb_key_offline_origin_addr = _create_key("offline-origin-addr");
-const pb_key *const pb_key_offline_proxy_addr = _create_key("offline-proxy-addr");
-const pb_key *const pb_key_origin_addr = _create_key("origin-addr");
-const pb_key *const pb_key_p2c_cl = _create_key("p2c-cl");
-const pb_key *const pb_key_p2c_hl = _create_key("p2c-hl");
-const pb_key *const pb_key_p2r_cl = _create_key("p2r-cl");
-const pb_key *const pb_key_p2r_hl = _create_key("p2r-hl");
-const pb_key *const pb_key_parse_timeout = _create_key("parse-timeout");
-const pb_key *const pb_key_password = _create_key("password");
-const pb_key *const pb_key_path = _create_key("path");
-const pb_key *const pb_key_PATH_INFO = _create_key("PATH_INFO");
-const pb_key *const pb_key_path_info = _create_key("path-info");
-const pb_key *const pb_key_pblock = _create_key("pblock");
-const pb_key *const pb_key_poll_interval = _create_key("poll-interval");
-const pb_key *const pb_key_port = _create_key("port");
-const pb_key *const pb_key_ppath = _create_key("ppath");
-const pb_key *const pb_key_pragma = _create_key("pragma");
-const pb_key *const pb_key_process_request_body = _create_key("process-request-body");
-const pb_key *const pb_key_process_response_body = _create_key("process-response-body");
-const pb_key *const pb_key_protocol = _create_key("protocol");
-const pb_key *const pb_key_proxy_addr = _create_key("proxy-addr");
-const pb_key *const pb_key_proxy_agent = _create_key("proxy-agent");
-const pb_key *const pb_key_proxy_auth_cert = _create_key("proxy-auth-cert");
-const pb_key *const pb_key_proxy_authorization = _create_key("proxy-authorization");
-const pb_key *const pb_key_proxy_cipher = _create_key("proxy-cipher");
-const pb_key *const pb_key_proxy_issuer_dn = _create_key("proxy-issuer-dn");
-const pb_key *const pb_key_proxy_jroute = _create_key("proxy-jroute");
-const pb_key *const pb_key_proxy_keysize = _create_key("proxy-keysize");
-const pb_key *const pb_key_proxy_ping = _create_key("proxy-ping");
-const pb_key *const pb_key_proxy_request = _create_key("proxy-request");
-const pb_key *const pb_key_proxy_secret_keysize = _create_key("proxy-secret-keysize");
-const pb_key *const pb_key_proxy_ssl_id = _create_key("proxy-ssl-id");
-const pb_key *const pb_key_proxy_user_dn = _create_key("proxy-user-dn");
-const pb_key *const pb_key_query = _create_key("query");
-const pb_key *const pb_key_QUERY_STRING = _create_key("QUERY_STRING");
-const pb_key *const pb_key_QUERY_STRING_UNESCAPED = _create_key("QUERY_STRING_UNESCAPED");
-const pb_key *const pb_key_r2p_cl = _create_key("r2p-cl");
-const pb_key *const pb_key_r2p_hl = _create_key("r2p-hl");
-const pb_key *const pb_key_range = _create_key("range");
-const pb_key *const pb_key_referer = _create_key("referer");
-const pb_key *const pb_key_reformat_request_headers = _create_key("reformat-request-headers");
-const pb_key *const pb_key_remote_status = _create_key("remote-status");
-const pb_key *const pb_key_request_jroute = _create_key("request-jroute");
-const pb_key *const pb_key_required_rights = _create_key("required-rights");
-const pb_key *const pb_key_retries = _create_key("retries");
-const pb_key *const pb_key_rewrite_content_location = _create_key("rewrite-content-location");
-const pb_key *const pb_key_rewrite_host = _create_key("rewrite-host");
-const pb_key *const pb_key_rewrite_location = _create_key("rewrite-location");
-const pb_key *const pb_key_rewrite_set_cookie = _create_key("rewrite-set-cookie");
-const pb_key *const pb_key_root = _create_key("root");
-const pb_key *const pb_key_route = _create_key("route");
-const pb_key *const pb_key_route_cookie = _create_key("route-cookie");
-const pb_key *const pb_key_route_hdr = _create_key("route-hdr");
-const pb_key *const pb_key_route_offline = _create_key("route-offline");
-const pb_key *const pb_key_script_name = _create_key("script-name");
-const pb_key *const pb_key_secret_keysize = _create_key("secret-keysize");
-const pb_key *const pb_key_secure = _create_key("secure");
-const pb_key *const pb_key_server = _create_key("server");
-const pb_key *const pb_key_set_cookie = _create_key("set-cookie");
-const pb_key *const pb_key_socks_addr = _create_key("socks_addr");
-const pb_key *const pb_key_ssl_id = _create_key("ssl-id");
-const pb_key *const pb_key_ssl_unclean_shutdown = _create_key("ssl-unclean-shutdown");
-const pb_key *const pb_key_status = _create_key("status");
-const pb_key *const pb_key_sticky_cookie = _create_key("sticky-cookie");
-const pb_key *const pb_key_sticky_param = _create_key("sticky-param");
-const pb_key *const pb_key_suppress_request_headers = _create_key("suppress-request-headers");
-const pb_key *const pb_key_svr_status = _create_key("svr-status");
-const pb_key *const pb_key_timeout = _create_key("timeout");
-const pb_key *const pb_key_to = _create_key("to");
-const pb_key *const pb_key_transfer_encoding = _create_key("transfer-encoding");
-const pb_key *const pb_key_transmit_timeout = _create_key("transmit-timeout");
-const pb_key *const pb_key_tunnel_non_http_response = _create_key("tunnel-non-http-response");
-const pb_key *const pb_key_type = _create_key("type");
-const pb_key *const pb_key_upstream_jroute = _create_key("upstream-jroute");
-const pb_key *const pb_key_uri = _create_key("uri");
-const pb_key *const pb_key_url = _create_key("url");
-const pb_key *const pb_key_url_prefix = _create_key("url-prefix");
-const pb_key *const pb_key_UseOutputStreamSize = _create_key("UseOutputStreamSize");
-const pb_key *const pb_key_user = _create_key("user");
-const pb_key *const pb_key_user_agent = _create_key("user-agent");
-const pb_key *const pb_key_user_dn = _create_key("user_dn");
-const pb_key *const pb_key_validate_server_cert = _create_key("validate-server-cert");
-const pb_key *const pb_key_value = _create_key("value");
-const pb_key *const pb_key_vary = _create_key("vary");
-const pb_key *const pb_key_via = _create_key("via");
-const pb_key *const pb_key_warning = _create_key("warning");
-
-
-/* ------------------------------ _find_key ------------------------------- */
-
-static inline const pb_key *_find_key(const char *name, unsigned int hashval)
-{
-    /* Check to see if name corresponds to a pb_key */
-    CListConstIterator<pb_key> iter(&_hashKeys.Find(hashval));
-    const pb_key *key;
-    while (key = ++iter) {
-        if (key->hashval == hashval && !strcmp(key->name, name))
-            return key;
-    }
-    return NULL;
-}
-
-
-/* --------------------------- _get_hash_index ---------------------------- */
-
-static inline int _get_hash_index(const PListStruct_t *pl, const pb_key *key)
-{
-    /* Get the hash index from the key.  Requires a symbol table. */
-    int i;
-    if (key->sizendx == pl->pl_symtab->pt_sizendx)
-        i = key->hashndx;
-    else
-        i = key->hashval % PLSIZENDX(pl->pl_symtab->pt_sizendx);
-    return i;
-}
-
-
-/* ---------------------------- _param_create ----------------------------- */
-
-static inline pb_param *_param_create(pool_handle_t *pool_handle, const char *name, int namelen, const char *value, int valuelen)
-{
-    PLValueStruct_t *ret;
-
-    ret = (PLValueStruct_t *)pool_malloc(pool_handle, sizeof(PLValueStruct_t));
-
-    ret->pv_pbentry.param = &ret->pv_pbparam;
-    ret->pv_pbentry.next = 0;
-    ret->pv_next = 0;
-    ret->pv_type = 0;
-    ret->pv_mempool = pool_handle;
-
-    if (name || namelen) {
-        ret->pv_name = (char*)pool_malloc(pool_handle, namelen + 1);
-        if (name) {
-            memcpy(ret->pv_name, name, namelen);
-            ret->pv_name[namelen] = '\0';
-        } else {
-            ret->pv_name[0] = '\0';
-        }
-    } else {
-        ret->pv_name = 0;
-    }
-
-    if (value || valuelen) {
-        ret->pv_value = (char*)pool_malloc(pool_handle, valuelen + 1);
-        if (value) {
-            memcpy(ret->pv_value, value, valuelen);
-            ret->pv_value[valuelen] = '\0';
-        } else {
-            ret->pv_value[0] = '\0';
-        }
-    } else {
-        ret->pv_value = 0;
-    }
-
-    return &ret->pv_pbparam;
-}
-
-
-/* ----------------------- pblock_key_param_create  ----------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen)
-{
-    /*
-     * Allocate a PLValueStruct_t from the property list's memory pool.
-     */
-    PListStruct_t *pl = PBTOPL(pb);
-    return _param_create(pl->pl_mempool, key->name, key->namelen, value, valuelen);
-}
-
-
-/* ------------------------- pblock_param_create -------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value)
-{
-    /*
-     * Allocate a PLValueStruct_t from the property list's memory pool.
-     */
-    PListStruct_t *pl = PBTOPL(pb);
-    return _param_create(pl->pl_mempool, name, name ? strlen(name) : 0, value, value ? strlen(value) : 0);
-}
-
-
-/* ----------------------------- param_create ----------------------------- */
-
-NSAPI_PUBLIC pb_param *param_create(const char *name, const char *value)
-{
-    /*
-     * Allocate a PLValueStruct_t containing the pb_param that will
-     * be returned.  Normally PLValueStruct_ts are allocated from the
-     * memory pool associated with a property list, but we don't have
-     * that here, so we just use the thread's pool and indicate we were
-     * allocated from a specific pool.
-     */
-    return _param_create(system_pool(), name, name ? strlen(name) : 0, value, value ? strlen(value) : 0);
-}
-
-
-/* ------------------------------ param_free ------------------------------ */
-
-NSAPI_PUBLIC int param_free(pb_param *pp)
-{
-    if (pp) {
-        PLValueStruct_t *pv = PATOPV(pp);
-
-        /* Don't bother if the pblock was allocated from a pool */
-        if (!pv->pv_mempool) {
-            pool_free(pv->pv_mempool, pv->pv_name);
-            pool_free(pv->pv_mempool, pv->pv_value);
-            pool_free(pv->pv_mempool, pv);
-        }
-
-        return 1;
-    }
-
-    return 0;
-}
-
-
-/* -------------------------- pblock_create_pool -------------------------- */
-
-NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n)
-{
-    /* Create a property list with n property indices */
-    PListStruct_t *plist = (PListStruct_t *)PListCreate(pool_handle, n, 0, 0);
-    if (!plist)
-        return NULL;
-
-    plist->pl_resvpi = 0;
-
-    return &plist->pl_pb;
-}
-
-
-/* ----------------------------- pblock_pool ------------------------------ */
-
-NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-    return pl->pl_mempool;
-}
-
-
-/* ---------------------------- pblock_create ----------------------------- */
-
-NSAPI_PUBLIC pblock *pblock_create(int n)
-{
-    return pblock_create_pool(MALLOC_POOL_HANDLE, n);
-}
-
-
-/* ----------------------------- pblock_free ------------------------------ */
-
-NSAPI_PUBLIC void pblock_free(pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int i;
-
-    if (!pb) {
-        return;
-    }
-
-    /* If the pools are enabled, this routine has no effect anyway, so 
-     * just return. 
-     */
-    if (pl->pl_mempool || pool_enabled()) {
-        return;
-    }
-
-    /* Free the property name symbol table if any */
-    if (pl->pl_symtab) {
-        pool_free(pl->pl_mempool, (void *)(pl->pl_symtab));
-    }
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Loop over the initialized property indices */
-    for (i = 0; i < pl->pl_initpi; ++i) {
-
-        /* Got a property here? */
-        pv = ppval[i];
-        if (pv) {
-
-            param_free(&pv->pv_pbparam);
-        }
-    }
-
-    /* Free the array of pointers to property values */
-    pool_free(pl->pl_mempool, (void *)ppval);
-
-    /* Free the property list head */
-    pool_free(pl->pl_mempool, (void *)pl);
-}
-
-
-/* ------------------------------ pblock_key ------------------------------ */
-
-NSAPI_PUBLIC const pb_key *pblock_key(const char *name)
-{
-    if (!name)
-        return NULL;
-
-    return _find_key(name, PListHash(name));
-}
-
-
-/* --------------------------- pblock_kpinsert ---------------------------- */
-
-NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-    PLValueStruct_t *pv = PATOPV(pp);
-
-    PR_ASSERT(pv->pv_mempool == pl->pl_mempool);
-
-    /* Check to see if the name corresponds to a pb_key */
-    unsigned int hashval;
-    if (!key) {
-        hashval = PListHash(pv->pv_name);
-        key = _find_key(pv->pv_name, hashval);
-    }
-
-    /* Find property index */
-    int pindex = PListGetFreeIndex(pl);
-    if (pindex < 1) {
-        /* Error - invalid property index */
-        printf("Error - invalid property index\n");
-        return;
-    }
-
-    /* Allocate/grow the symbol table as needed */
-    PLSymbolTable_t *pt = PListSymbolTable(pl);
-    if (!pt) {
-        printf("!pt\n");
-        return;
-    }
-
-    /* Add PLValueStruct_t to the property list */
-    PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
-    pv->pv_pbkey = key;
-    pv->pv_pi = pindex;
-    ppval[pv->pv_pi - 1] = pv;
-
-    /* Add name to symbol table */
-    int i = key ? _get_hash_index(pl, key) : (hashval % PLSIZENDX(pt->pt_sizendx));
-    pv->pv_next = pt->pt_hash[i];
-    pt->pt_hash[i] = pv;
-    pt->pt_nsyms++;
-
-    PR_ASSERT(param_key(pp) == key);
-}
-
-
-/* ---------------------------- pblock_pinsert ---------------------------- */
-
-NSAPI_PUBLIC void pblock_pinsert(pb_param *pp, pblock *pb)
-{
-    pblock_kpinsert(NULL, pp, pb);
-}
-
-
-/* --------------------------- pblock_nvinsert ---------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_nvinsert(const char *name, const char *value, pblock *pb)
-{
-    pb_param *pp = pblock_param_create(pb, name, value);
-    if (pp)
-        pblock_kpinsert(NULL, pp, pb);
-    return pp;
-}
-
-
-/* --------------------------- pblock_kvinsert ---------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb)
-{
-    pb_param *pp = pblock_key_param_create(pb, key, value, valuelen);
-    if (pp)
-        pblock_kpinsert(key, pp, pb);
-    return pp;
-}
-
-
-/* --------------------------- pblock_nninsert ---------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_nninsert(const char *name, int value, pblock *pb)
-{
-    char num[UTIL_ITOA_SIZE];
-
-    util_itoa(value, num);
-    return pblock_nvinsert(name, num, pb);
-}
-
-
-/* --------------------------- pblock_kninsert ---------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb)
-{
-    pb_param *pp = pblock_key_param_create(pb, key, NULL, UTIL_ITOA_SIZE);
-    if (pp) {
-        util_itoa(value, pp->value);
-        pblock_kpinsert(key, pp, pb);
-    }
-    return pp;
-}
-
-
-/* --------------------------- pblock_kllinsert --------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, PRInt64 value, pblock *pb)
-{
-    pb_param *pp = pblock_key_param_create(pb, key, NULL, UTIL_I64TOA_SIZE);
-    if (pp) {
-        util_i64toa(value, pp->value);
-        pblock_kpinsert(key, pp, pb);
-    }
-    return pp;
-}
-
-
-/* ---------------------------pblock_nvlinsert ---------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-
-    pb_param *pp = _param_create(pl->pl_mempool, name, namelen, value, valuelen);
-
-    if(pp) {
-        pblock_kpinsert(NULL, pp, pb);
-    }
-
-    return pp;
-}
-
-
-/* ---------------------------- pblock_findkey ---------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-
-    /* Lookup key by examining symbol table */
-    if (pl->pl_symtab) {
-        int i = _get_hash_index(pl, key);
-        PLValueStruct_t *pv;
-
-        /* Search hash collision list for matching name */
-        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
-            if (pv->pv_pbkey == key)
-                return &pv->pv_pbparam;
-        }
-    }
-
-    return NULL;
-}
-
-
-/* -------------------------- pblock_findkeyval --------------------------- */
-
-NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb)
-{
-    pb_param *pp = pblock_findkey(key, pb);
-    return pp ? pp->value : NULL;
-}
-
-
-/* ---------------------------- pblock_findval ---------------------------- */
-
-NSAPI_PUBLIC char *pblock_findval(const char *name, const pblock *pb)
-{
-    void *pvalue = 0;
-
-    (void)PListFindValue((PList_t)(PBTOPL(pb)), name, &pvalue, 0);
-
-    return (char *)pvalue;
-}
-
-
-/* ------------------------------ pblock_fr ------------------------------ */
-
-NSAPI_PUBLIC pb_param *pblock_fr(const char *name, pblock *pb, int remove)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-    PLValueStruct_t **ppval;
-    PLValueStruct_t **pvp;
-    PLValueStruct_t *pv = NULL;
-    int pindex;
-    int i;
-
-    if (pl->pl_symtab) {
-
-        /* Compute hash index of specified property name */
-        i = PListHashName(pl->pl_symtab, name);
-
-        /* Search hash collision list for matching name */
-        for (pvp = &pl->pl_symtab->pt_hash[i];
-             (pv = *pvp); pvp = &(*pvp)->pv_next) {
-
-            if (!strcmp(name, pv->pv_name)) {
-
-                if (remove) {
-                    /* Remove PLValueStruct_t from symbol table */
-                    *pvp = pv->pv_next;
-                    pl->pl_symtab->pt_nsyms--;
-
-                    /* Remove it from pl_ppval too */
-                    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-                    pindex = pv->pv_pi;
-                    ppval[pindex - 1] = 0;
-                }
-                break;
-            }
-        }
-    }
-
-    return (pv) ? &pv->pv_pbparam : NULL;
-}
-
-
-/* --------------------------- pblock_removekey --------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-    PLValueStruct_t **ppval;
-    PLValueStruct_t **pvp;
-    PLValueStruct_t *pv = NULL;
-    int pindex;
-    int i;
-
-    if (pl->pl_symtab) {
-        /* Lookup hash index for specified property key */
-        i = _get_hash_index(pl, key);
-
-        /* Search hash collision list for matching key */
-        for (pvp = &pl->pl_symtab->pt_hash[i]; (pv = *pvp); pvp = &pv->pv_next) {
-            /* If this value has the requested key... */
-            if (pv->pv_pbkey == key) {
-                /* Remove PLValueStruct_t from symbol table */
-                *pvp = pv->pv_next;
-                pl->pl_symtab->pt_nsyms--;
-
-                /* Remove it from pl_ppval too */
-                ppval = (PLValueStruct_t **)(pl->pl_ppval);
-                pindex = pv->pv_pi;
-                ppval[pindex - 1] = 0;
-
-                break;
-            }
-        }
-    }
-
-    return (pv) ? &pv->pv_pbparam : NULL;
-}
-
-
-/* -------------------------- pblock_removeone --------------------------- */
-
-NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-
-    if (pl && pl->pl_symtab) {
-        /* Search hash buckets */
-        for (int i = 0; i < PLSIZENDX(pl->pl_symtab->pt_sizendx); i++) {
-            /* Search hash collision list */
-            PLValueStruct_t *pv = pl->pl_symtab->pt_hash[i];
-            if (pv) {
-                /* Remove PLValueStruct_t from symbol table */
-                pl->pl_symtab->pt_hash[i] = pv->pv_next;
-                pl->pl_symtab->pt_nsyms--;
-
-                /* Remove it from pl_ppval too */
-                PLValueStruct_t **ppval = (PLValueStruct_t**)pl->pl_ppval;
-                ppval[pv->pv_pi - 1] = 0;
-
-                return &pv->pv_pbparam;
-            }
-        }
-    }
-
-    return NULL;
-}
-
-
-/* -------------------------- pblock_str2pblock --------------------------- */
-
-
-int _verify_pbstr(const char *str)
-{
-    const char *cp;
-    const char *scp;
-    int np;
-    int state;
-    int quote;
-
-    for(cp = str, np = 0, state = 0; *cp; ) {
-        switch (state) {
-        case 0:                 /* skipping leading spaces */
-
-            while (*cp && isspace(*cp)) ++cp;
-            if (*cp == '=') {
-                return -1;
-            }
-            if (*cp) state = 1;
-            break;
-
-        case 1:                 /* scanning parameter name */
-
-            scp = cp;
-            while (*cp && (*cp != '=') && !isspace(*cp)) ++cp;
-            if (*cp == '=') ++cp;
-            else cp = scp;
-            state = 2;
-            break;
-
-        case 2:                 /* scanning parameter value */
-            quote = 0;
-            if (*cp == '\"') {
-                quote = 1;
-                ++cp;
-            }
-            for (;;) {
-                if (*cp == '\\') {
-                    ++cp;
-                    if (*cp == 0) {
-                        return -1;
-                    }
-                }
-                else if (*cp == '\"') {
-                    if (!quote) {
-                        return -1;
-                    }
-                    ++np;
-                    ++cp;
-                    quote = 0;
-                    state = 0;
-                    break;
-                }
-                else if (!quote && (!*cp || isspace(*cp))) {
-                    ++np;
-                    if (*cp) ++cp;
-                    state = 0;
-                    break;
-                }
-                else if (*cp == 0) {
-                    return -1;
-                }
-                ++cp;
-            }
-            if (quote) {
-                return -1;
-            }
-            break;
-        }
-    }
-
-    return (state == 0) ? np : -1;
-}
-
-NSAPI_PUBLIC int
-INTpblock_str2pblock_lowercasename(const char *str, pblock *pb)
-{
-    return _pblock_str2pblock(str, pb, PR_TRUE);
-}
-
-NSAPI_PUBLIC int pblock_str2pblock(const char *str, pblock *pb)
-{
-    return _pblock_str2pblock(str, pb, PR_FALSE);
-}
-
-int
-_pblock_str2pblock(const char* str, pblock* pb, PRBool lowerCase)
-{
-    char *cpy;
-    char *cp;
-    char *dp;
-    char *pname;
-    char *pvalue;
-    int np;
-    int quote;
-    int state;
-    char numbuf[UTIL_ITOA_SIZE];
-
-    if((np = _verify_pbstr(str)) < 1)
-        return -1;
-
-    while (*str && isspace(*str)) ++str;
-
-    cpy = STRDUP(str);
-
-    for (np = 0, cp = cpy, state = 0; *cp; ) {
-        switch (state) {
-
-        case 0:                 /* skipping leading spaces */
-
-            while (*cp && isspace(*cp)) ++cp;
-            if (*cp) state = 1;
-            break;
-
-        case 1:                 /* scanning parameter name */
-
-            pname = cp;
-            while (*cp && (*cp != '=') && !isspace(*cp)) ++cp;
-            if (*cp == '=') {
-                *cp++ = 0;
-            }
-            else {
-                cp = pname;
-                pname = numbuf;
-                util_itoa(np+1, numbuf);
-            }
-            state = 2;
-            break;
-
-        case 2:                 /* scanning parameter value */
-            quote = 0;
-            if (*cp == '\"') {
-                quote = 1;
-                ++cp;
-            }
-            for (pvalue = cp, dp = cp; ; ++cp, ++dp) {
-                if (*cp == '\\') {
-                    ++cp;
-                }
-                else if (*cp == '\"') {
-                    ++np;
-                    ++cp;
-                    *dp = 0;
-                    quote = 0;
-                    state = 0;
-                    break;
-                }
-                else if (!quote && ((*cp == 0) || isspace(*cp))) {
-                    ++np;
-                    if (*cp != 0) {
-                        ++cp;
-                    }
-                    *dp = 0;
-                    state = 0;
-                    break;
-                }
-                if (cp != dp) *dp = *cp;
-            }
-            if (lowerCase == PR_TRUE) {
-                for (char* p = pname; *p; p++) {
-                    *p = tolower(*p);
-                }
-            }
-            pblock_nvinsert(pname, pvalue, pb);
-            break;
-        }
-    }
-
-    FREE(cpy);
-
-    return np;
-}
-
-
-/* -------------------------- pblock_pblock2str --------------------------- */
-
-
-NSAPI_PUBLIC char *pblock_pblock2str(const pblock *pb, char *str)
-{
-    register char *s = str, *t, *u;
-    PListStruct_t *pl = PBTOPL(pb);
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int i;
-    int sl;
-    int xlen;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Loop over the initialized property indices */
-    for (i = 0, xlen = 0; i < pl->pl_initpi; ++i) {
-
-        /* Got a property here? */
-        pv = ppval[i];
-        if (pv && pv->pv_name) {
-
-            int ln = strlen(pv->pv_name);
-            int lv = strlen((char *)(pv->pv_value));
-
-            /* Check for " or \ because we'll have to escape them */
-            for (t = (char *)(pv->pv_value); *t; ++t) {
-                if ((*t == '\"') || (*t == '\\')) ++lv;
-            }
-
-            /* 4: two quotes, =, and a null */
-            xlen += (ln + lv + 4);
-        }
-    }
-
-    /* Allocate string to hold parameter settings, or increase size */
-    if (!s) {
-        s = (char *)MALLOC(xlen);
-        s[0] = '\0';
-        t = &s[0];
-        sl = xlen;
-    }
-    else {
-        sl = strlen(s);
-        t = &s[sl];
-        sl += xlen;
-        s = (char *)REALLOC(s, sl);
-    }
-
-    /* Loop over the initialized property indices */
-    for (i = 0; i < pl->pl_initpi; ++i) {
-
-        /* Got a property here? */
-        pv = ppval[i];
-        if (pv && pv->pv_name) {
-
-            if (t != s) *t++ = ' ';
-
-            for (u = pv->pv_name; *u; ) *t++ = *u++;
-
-            *t++ = '=';
-            *t++ = '\"';
-
-            for (u = (char *)(pv->pv_value); *u; ) {
-                if ((*u == '\\') || (*u == '\"')) *t++ = '\\';
-                *t++ = *u++;
-            }
-
-            *t++ = '\"';
-            *t = '\0';
-        }
-    }
-
-    return s;
-}
-
-
-/* ----------------------------- pblock_copy ------------------------------ */
-
-
-NSAPI_PUBLIC int pblock_copy(const pblock *src, pblock *dst)
-{
-    PListStruct_t *pl = PBTOPL(src);
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int rv = 0;
-    int i;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    for (i = 0; i < pl->pl_initpi; ++i) {
-        pv = ppval[i];
-        if (pv) {
-            if (pv->pv_pbkey) {
-                if (pv->pv_pbkey != pb_key_magnus_internal) {
-                    if (!pblock_kvinsert(pv->pv_pbkey, (char *)(pv->pv_value), strlen(pv->pv_value), dst))
-                        rv = -1;
-                }
-            } else {
-                if (!pblock_nvinsert(pv->pv_name, (char *)(pv->pv_value), dst))
-                    rv = -1;
-            }
-        }
-    }
-
-    return rv;
-}
-
-/* ---------------------------- pblock_dup -------------------------------- */
-
-NSAPI_PUBLIC pblock *pblock_dup(const pblock *src)
-{
-    pblock *dst;
-
-    if (!src)
-        return NULL;
-
-    if ( (dst = pblock_create(src->hsize)) )
-        pblock_copy(src, dst);
-
-    return dst;
-}
-
-
-/* ---------------------------- pblock_pb2env ----------------------------- */
-
-/*
-NSAPI_PUBLIC char **pblock_pb2env(const pblock *pb, char **env)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int i;
-    int nval;
-    int pos;
-
-    /* Find out how many there are. */
-    /*
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    for (i = 0, nval = 0; i < pl->pl_initpi; ++i) {
-        if (ppval[i]) ++nval;
-    }
-
-    env = util_env_create(env, nval, &pos);
-
-    for (i = 0; i < pl->pl_initpi; ++i) {
-        pv = ppval[i];
-        if (pv) {
-            env[pos++] = util_env_str(pv->pv_name, (char *)(pv->pv_value));
-        }
-    }
-    env[pos] = NULL;
-
-    return env;
-}
-*/
-
-/* ---------------------------- pblock_replace ---------------------------- */
-
-NSAPI_PUBLIC char * pblock_replace(const char *name,
-                                   char * new_value, pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-
-    /* Replace an existing value */
-    pb_param *pp = pblock_find(name, pb);
-    if (!pp)
-        return NULL;
-    pool_free(pl->pl_mempool, pp->value);
-    pp->value = new_value;
-
-    return new_value;
-}
-
-
-/* --------------------------- pblock_nvreplace --------------------------- */
-
-NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-
-    /* Replace an existing value or insert a new value */
-    pb_param *pp = pblock_find(name, pb);
-    if (pp) {
-        pool_free(pl->pl_mempool, pp->value);
-        pp->value = pool_strdup(pl->pl_mempool, value);
-    } else {
-        pblock_nvinsert(name, value, pb);
-    }
-}
-
-
-/* --------------------------- pblock_kvreplace --------------------------- */
-
-NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb)
-{
-    PListStruct_t *pl = PBTOPL(pb);
-
-    /* Replace an existing value or insert a new value */
-    pb_param *pp = pblock_findkey(key, pb);
-    if (pp) {
-        pool_free(pl->pl_mempool, pp->value);
-        pp->value = (char*)pool_malloc(pl->pl_mempool, valuelen + 1);
-        memcpy(pp->value, value, valuelen + 1);
-    } else {
-        pblock_kvinsert(key, value, valuelen, pb);
-    }
-}
--- a/src/server/pblock.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_PBLOCK_H
-#define BASE_PBLOCK_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * pblock.h: Header for Parameter Block handling functions
- * 
- *
- * A parameter block is a set of name=value pairs which are generally used 
- * as parameters, but can be anything. They are kept in a hash table for 
- * reasonable speed, but if you are doing any intensive modification or
- * access of them you should probably make a local copy of each parameter
- * while working.
- *
- * Rob McCool
- * 
- */
-
-#ifndef NETSITE_H
-#include "nsapi.h"
-#include "netsite.h"
-#endif /* !NETSITE_H */
-
-#ifdef XP_WIN32
-#ifdef BUILD_DLL
-#define BASE_DLL _declspec(dllexport)
-#else
-#define BASE_DLL _declspec(dllimport)
-#endif
-#else
-#define BASE_DLL
-#endif
-
-#ifdef INTNSAPI
-
-/* --- Begin function prototypes --- */
-
-NSPR_BEGIN_EXTERN_C
-
-NSAPI_PUBLIC pb_param *INTparam_create(const char *name, const char *value);
-
-NSAPI_PUBLIC int INTparam_free(pb_param *pp);
-
-NSAPI_PUBLIC pblock *INTpblock_create(int n);
-
-NSAPI_PUBLIC void INTpblock_free(pblock *pb);
-
-NSAPI_PUBLIC char *INTpblock_findval(const char *name, const pblock *pb);
-
-NSAPI_PUBLIC pb_param *INTpblock_nvinsert(const char *name, const char *value, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb);
-
-NSAPI_PUBLIC pb_param *INTpblock_nninsert(const char *name, int value, pblock *pb);
-
-NSAPI_PUBLIC void INTpblock_pinsert(pb_param *pp, pblock *pb);
-
-NSAPI_PUBLIC int INTpblock_str2pblock(const char *str, pblock *pb);
-
-NSAPI_PUBLIC char *INTpblock_pblock2str(const pblock *pb, char *str);
-
-NSAPI_PUBLIC int INTpblock_copy(const pblock *src, pblock *dst);
-
-NSAPI_PUBLIC pblock *INTpblock_dup(const pblock *src);
-
-NSAPI_PUBLIC char **INTpblock_pb2env(const pblock *pb, char **env);
-
-NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb);
-
-/* --------------------------- Internal things ---------------------------- */
-
-typedef struct pb_key pb_key;
-
-BASE_DLL extern const pb_key *const pb_key_accept;
-BASE_DLL extern const pb_key *const pb_key_accept_charset;
-BASE_DLL extern const pb_key *const pb_key_accept_encoding;
-BASE_DLL extern const pb_key *const pb_key_accept_language;
-BASE_DLL extern const pb_key *const pb_key_accept_ranges;
-BASE_DLL extern const pb_key *const pb_key_actual_route;
-BASE_DLL extern const pb_key *const pb_key_age;
-BASE_DLL extern const pb_key *const pb_key_always_allow_chunked;
-BASE_DLL extern const pb_key *const pb_key_always_use_keep_alive;
-BASE_DLL extern const pb_key *const pb_key_auth_cert;
-BASE_DLL extern const pb_key *const pb_key_auth_expiring;
-BASE_DLL extern const pb_key *const pb_key_auth_group;
-BASE_DLL extern const pb_key *const pb_key_auth_type;
-BASE_DLL extern const pb_key *const pb_key_auth_user;
-BASE_DLL extern const pb_key *const pb_key_authorization;
-BASE_DLL extern const pb_key *const pb_key_browser;
-BASE_DLL extern const pb_key *const pb_key_c2p_cl;
-BASE_DLL extern const pb_key *const pb_key_c2p_hl;
-BASE_DLL extern const pb_key *const pb_key_cache_info;
-BASE_DLL extern const pb_key *const pb_key_charset;
-BASE_DLL extern const pb_key *const pb_key_check_http_server;
-BASE_DLL extern const pb_key *const pb_key_ChunkedRequestBufferSize;
-BASE_DLL extern const pb_key *const pb_key_ChunkedRequestTimeout;
-BASE_DLL extern const pb_key *const pb_key_cipher;
-BASE_DLL extern const pb_key *const pb_key_clf_request;
-BASE_DLL extern const pb_key *const pb_key_cli_status;
-BASE_DLL extern const pb_key *const pb_key_client_cert_nickname;
-BASE_DLL extern const pb_key *const pb_key_client_ip;
-BASE_DLL extern const pb_key *const pb_key_close;
-BASE_DLL extern const pb_key *const pb_key_connect_timeout;
-BASE_DLL extern const pb_key *const pb_key_connection;
-BASE_DLL extern const pb_key *const pb_key_cont;
-BASE_DLL extern const pb_key *const pb_key_content_encoding;
-BASE_DLL extern const pb_key *const pb_key_content_language;
-BASE_DLL extern const pb_key *const pb_key_content_length;
-BASE_DLL extern const pb_key *const pb_key_content_location;
-BASE_DLL extern const pb_key *const pb_key_content_md5;
-BASE_DLL extern const pb_key *const pb_key_content_range;
-BASE_DLL extern const pb_key *const pb_key_content_type;
-BASE_DLL extern const pb_key *const pb_key_cookie;
-BASE_DLL extern const pb_key *const pb_key_date;
-BASE_DLL extern const pb_key *const pb_key_DATE_GMT;
-BASE_DLL extern const pb_key *const pb_key_DATE_LOCAL;
-BASE_DLL extern const pb_key *const pb_key_dir;
-BASE_DLL extern const pb_key *const pb_key_Directive;
-BASE_DLL extern const pb_key *const pb_key_dns;
-BASE_DLL extern const pb_key *const pb_key_DOCUMENT_NAME;
-BASE_DLL extern const pb_key *const pb_key_DOCUMENT_URI;
-BASE_DLL extern const pb_key *const pb_key_domain;
-BASE_DLL extern const pb_key *const pb_key_enc;
-BASE_DLL extern const pb_key *const pb_key_engine;
-BASE_DLL extern const pb_key *const pb_key_error_action;
-BASE_DLL extern const pb_key *const pb_key_error_desc;
-BASE_DLL extern const pb_key *const pb_key_error_fn;
-BASE_DLL extern const pb_key *const pb_key_escape;
-BASE_DLL extern const pb_key *const pb_key_escaped;
-BASE_DLL extern const pb_key *const pb_key_etag;
-BASE_DLL extern const pb_key *const pb_key_expect;
-BASE_DLL extern const pb_key *const pb_key_expires;
-BASE_DLL extern const pb_key *const pb_key_expr;
-BASE_DLL extern const pb_key *const pb_key_filter;
-BASE_DLL extern const pb_key *const pb_key_find_pathinfo_forward;
-BASE_DLL extern const pb_key *const pb_key_flushTimer;
-BASE_DLL extern const pb_key *const pb_key_fn;
-BASE_DLL extern const pb_key *const pb_key_from;
-BASE_DLL extern const pb_key *const pb_key_full_headers;
-BASE_DLL extern const pb_key *const pb_key_hdr;
-BASE_DLL extern const pb_key *const pb_key_host;
-BASE_DLL extern const pb_key *const pb_key_hostname;
-BASE_DLL extern const pb_key *const pb_key_if_match;
-BASE_DLL extern const pb_key *const pb_key_if_modified_since;
-BASE_DLL extern const pb_key *const pb_key_if_none_match;
-BASE_DLL extern const pb_key *const pb_key_if_range;
-BASE_DLL extern const pb_key *const pb_key_if_unmodified_since;
-BASE_DLL extern const pb_key *const pb_key_ip;
-BASE_DLL extern const pb_key *const pb_key_iponly;
-BASE_DLL extern const pb_key *const pb_key_issuer_dn;
-BASE_DLL extern const pb_key *const pb_key_jroute;
-BASE_DLL extern const pb_key *const pb_key_keep_alive;
-BASE_DLL extern const pb_key *const pb_key_keep_alive_timeout;
-BASE_DLL extern const pb_key *const pb_key_keysize;
-BASE_DLL extern const pb_key *const pb_key_lang;
-BASE_DLL extern const pb_key *const pb_key_LAST_MODIFIED;
-BASE_DLL extern const pb_key *const pb_key_last_modified;
-BASE_DLL extern const pb_key *const pb_key_level;
-BASE_DLL extern const pb_key *const pb_key_location;
-BASE_DLL extern const pb_key *const pb_key_lock_owner;
-BASE_DLL extern const pb_key *const pb_key_magnus_charset;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_dav_src;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_default_acls_only;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_error_j2ee;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_j2ee_nsapi;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_preserve_srvhdrs;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_set_request_status;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_set_response_status;
-BASE_DLL extern const pb_key *const pb_key_magnus_internal_webapp_errordesc;
-BASE_DLL extern const pb_key *const pb_key_matched_browser;
-BASE_DLL extern const pb_key *const pb_key_max_age;
-BASE_DLL extern const pb_key *const pb_key_max_forwards;
-BASE_DLL extern const pb_key *const pb_key_message;
-BASE_DLL extern const pb_key *const pb_key_method;
-BASE_DLL extern const pb_key *const pb_key_name;
-BASE_DLL extern const pb_key *const pb_key_nocache;
-BASE_DLL extern const pb_key *const pb_key_nostat;
-BASE_DLL extern const pb_key *const pb_key_ntrans_base;
-BASE_DLL extern const pb_key *const pb_key_offline_origin_addr;
-BASE_DLL extern const pb_key *const pb_key_offline_proxy_addr;
-BASE_DLL extern const pb_key *const pb_key_origin_addr;
-BASE_DLL extern const pb_key *const pb_key_p2c_cl;
-BASE_DLL extern const pb_key *const pb_key_p2c_hl;
-BASE_DLL extern const pb_key *const pb_key_p2r_cl;
-BASE_DLL extern const pb_key *const pb_key_p2r_hl;
-BASE_DLL extern const pb_key *const pb_key_parse_timeout;
-BASE_DLL extern const pb_key *const pb_key_password;
-BASE_DLL extern const pb_key *const pb_key_path;
-BASE_DLL extern const pb_key *const pb_key_PATH_INFO;
-BASE_DLL extern const pb_key *const pb_key_path_info;
-BASE_DLL extern const pb_key *const pb_key_pblock;
-BASE_DLL extern const pb_key *const pb_key_poll_interval;
-BASE_DLL extern const pb_key *const pb_key_port;
-BASE_DLL extern const pb_key *const pb_key_ppath;
-BASE_DLL extern const pb_key *const pb_key_pragma;
-BASE_DLL extern const pb_key *const pb_key_process_request_body;
-BASE_DLL extern const pb_key *const pb_key_process_response_body;
-BASE_DLL extern const pb_key *const pb_key_protocol;
-BASE_DLL extern const pb_key *const pb_key_proxy_addr;
-BASE_DLL extern const pb_key *const pb_key_proxy_agent;
-BASE_DLL extern const pb_key *const pb_key_proxy_auth_cert;
-BASE_DLL extern const pb_key *const pb_key_proxy_authorization;
-BASE_DLL extern const pb_key *const pb_key_proxy_cipher;
-BASE_DLL extern const pb_key *const pb_key_proxy_issuer_dn;
-BASE_DLL extern const pb_key *const pb_key_proxy_jroute;
-BASE_DLL extern const pb_key *const pb_key_proxy_keysize;
-BASE_DLL extern const pb_key *const pb_key_proxy_ping;
-BASE_DLL extern const pb_key *const pb_key_proxy_request;
-BASE_DLL extern const pb_key *const pb_key_proxy_secret_keysize;
-BASE_DLL extern const pb_key *const pb_key_proxy_ssl_id;
-BASE_DLL extern const pb_key *const pb_key_proxy_user_dn;
-BASE_DLL extern const pb_key *const pb_key_query;
-BASE_DLL extern const pb_key *const pb_key_QUERY_STRING;
-BASE_DLL extern const pb_key *const pb_key_QUERY_STRING_UNESCAPED;
-BASE_DLL extern const pb_key *const pb_key_r2p_cl;
-BASE_DLL extern const pb_key *const pb_key_r2p_hl;
-BASE_DLL extern const pb_key *const pb_key_range;
-BASE_DLL extern const pb_key *const pb_key_referer;
-BASE_DLL extern const pb_key *const pb_key_reformat_request_headers;
-BASE_DLL extern const pb_key *const pb_key_remote_status;
-BASE_DLL extern const pb_key *const pb_key_request_jroute;
-BASE_DLL extern const pb_key *const pb_key_required_rights;
-BASE_DLL extern const pb_key *const pb_key_retries;
-BASE_DLL extern const pb_key *const pb_key_rewrite_content_location;
-BASE_DLL extern const pb_key *const pb_key_rewrite_host;
-BASE_DLL extern const pb_key *const pb_key_rewrite_location;
-BASE_DLL extern const pb_key *const pb_key_rewrite_set_cookie;
-BASE_DLL extern const pb_key *const pb_key_root;
-BASE_DLL extern const pb_key *const pb_key_route;
-BASE_DLL extern const pb_key *const pb_key_route_cookie;
-BASE_DLL extern const pb_key *const pb_key_route_hdr;
-BASE_DLL extern const pb_key *const pb_key_route_offline;
-BASE_DLL extern const pb_key *const pb_key_script_name;
-BASE_DLL extern const pb_key *const pb_key_secret_keysize;
-BASE_DLL extern const pb_key *const pb_key_secure;
-BASE_DLL extern const pb_key *const pb_key_server;
-BASE_DLL extern const pb_key *const pb_key_set_cookie;
-BASE_DLL extern const pb_key *const pb_key_socks_addr;
-BASE_DLL extern const pb_key *const pb_key_ssl_id;
-BASE_DLL extern const pb_key *const pb_key_ssl_unclean_shutdown;
-BASE_DLL extern const pb_key *const pb_key_status;
-BASE_DLL extern const pb_key *const pb_key_sticky_cookie;
-BASE_DLL extern const pb_key *const pb_key_sticky_param;
-BASE_DLL extern const pb_key *const pb_key_suppress_request_headers;
-BASE_DLL extern const pb_key *const pb_key_svr_status;
-BASE_DLL extern const pb_key *const pb_key_timeout;
-BASE_DLL extern const pb_key *const pb_key_to;
-BASE_DLL extern const pb_key *const pb_key_transfer_encoding;
-BASE_DLL extern const pb_key *const pb_key_transmit_timeout;
-BASE_DLL extern const pb_key *const pb_key_tunnel_non_http_response;
-BASE_DLL extern const pb_key *const pb_key_type;
-BASE_DLL extern const pb_key *const pb_key_upstream_jroute;
-BASE_DLL extern const pb_key *const pb_key_uri;
-BASE_DLL extern const pb_key *const pb_key_url;
-BASE_DLL extern const pb_key *const pb_key_url_prefix;
-BASE_DLL extern const pb_key *const pb_key_UseOutputStreamSize;
-BASE_DLL extern const pb_key *const pb_key_user;
-BASE_DLL extern const pb_key *const pb_key_user_agent;
-BASE_DLL extern const pb_key *const pb_key_user_dn;
-BASE_DLL extern const pb_key *const pb_key_validate_server_cert;
-BASE_DLL extern const pb_key *const pb_key_value;
-BASE_DLL extern const pb_key *const pb_key_vary;
-BASE_DLL extern const pb_key *const pb_key_via;
-BASE_DLL extern const pb_key *const pb_key_warning;
-
-NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value);
-
-NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n);
-
-NSAPI_PUBLIC pb_param *INTpblock_fr(const char *name, pblock *pb, int remove);
-
-NSAPI_PUBLIC char *INTpblock_replace(const char *name,char * new_value,pblock *pb);
-
-NSAPI_PUBLIC int INTpblock_str2pblock_lowercasename(const char *str, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb);
-
-NSAPI_PUBLIC const pb_key *pblock_key(const char *name);
-
-NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen);
-
-NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb);
-
-NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb);
-
-NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb);
-
-NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, PRInt64 value, pblock *pb);
-
-#ifdef __cplusplus
-inline const pb_key *param_key(pb_param *pp)
-{
-    return *(const pb_key **)(pp + 1); /* XXX see plist_pvt.h */
-}
-#endif
-
-#define PARAM_KEY(pp) *(const pb_key **)(pp + 1) /* new */
-
-NSPR_END_EXTERN_C
-
-#define param_create INTparam_create
-#define param_free INTparam_free
-#define pblock_create INTpblock_create
-#define pblock_free INTpblock_free
-#define pblock_findval INTpblock_findval
-#define pblock_nvinsert INTpblock_nvinsert
-#define pblock_nninsert INTpblock_nninsert
-#define pblock_pinsert INTpblock_pinsert
-#define pblock_str2pblock INTpblock_str2pblock
-#define pblock_pblock2str INTpblock_pblock2str
-#define pblock_copy INTpblock_copy
-#define pblock_dup INTpblock_dup
-#define pblock_pb2env INTpblock_pb2env
-#define pblock_fr INTpblock_fr
-#define pblock_replace INTpblock_replace
-
-#endif /* INTNSAPI */
-
-#endif /* !BASE_PBLOCK_H */
--- a/src/server/plist.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1273 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * MODULE:      plist.c
- *
- * DESCRIPTION:
- *
- *      This module implements property lists.  A property list is an
- *      ordered array of property values.  Each property value has an
- *      handle for some data item, and may have a reference to
- *      another property list which describes the type of the data
- *      item.  Each property value has a property index which specifies
- *      its position in the property list.  A property value may also
- *      have a name.  Since the data item associated with a property
- *      value may reference another property list, it is possible to
- *      construct arbitrary linked structures of property lists.
- *
- * IMPLEMENTATION NOTES:
- */
-
-#include "netsite.h"
-#include "plist.h"
-#include "plist_pvt.h"
-
-int plistHashSizes[] = PLSTSIZES;
-
-/*
- * FUNCTION:    PListAssignValue
- *
- * DESCRIPTION:
- *
- *      This function sets the value and/or type of a defined property
- *      in given property list.  If the property type is specified as
- *      NULL, it is unchanged.  However, the property value is always
- *      set to the specified value.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pname                   - the property name
- *      pvalue                  - the new property value
- *      ptype                   - the new property type, or NULL
- *
- * RETURNS:
- *
- *      If successful, the property index of the referenced property is
- *      returned as the function value.  Errors are indicated by a
- *      negative return code as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListAssignValue(PList_t plist, const char *pname,
-                 const void *pvalue, PList_t ptype)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t *pv;
-    int pindex;
-    int i;
-
-    if (!plist) return ERRPLUNDEF;
-
-    /* Got a symbol table for this property list? */
-    if (pl->pl_symtab) {
-
-        /* Yes, compute hash of specified name */
-        i = PListHashName(pl->pl_symtab, pname);
-
-        /* Search hash collision list for matching name */
-        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
-
-            if (!strcmp(pname, pv->pv_name)) {
-
-                /* Name match, get property index */
-                pindex = pv->pv_pi;
-
-                /* Set the new value */
-                pv->pv_value = (char *)pvalue;
-
-                /* Set type if type is given */
-                if (ptype) pv->pv_type = (PListStruct_t *)ptype;
-
-                /* Return the property index */
-                return pindex;
-            }
-        }
-    }
-
-    /* Error - specified property name is undefined */
-    return ERRPLUNDEF;
-}
-
-/*
- * FUNCTION:    PListCreate
- *
- * DESCRIPTION:
- *
- *      This function creates a new property list and returns a handle for
- *      it.  It allows the caller to reserve a specified number of
- *      property indices at the beginning of the list, and also to limit
- *      the total number of property values that may be added to the list.
- *
- * ARGUMENTS:
- *
- *      mempool                 - handle for a memory pool to be associated
- *                                with the new property list
- *      resvprop                - number of reserved property indices
- *      maxprop                 - maximum number of properties in list
- *                                (zero or negative imposes no limit)
- *      flags                   - unused, reserved, must be zero
- *
- * RETURNS:
- *
- *      If successful, the function return value is a handle for the new
- *      property list.  Otherwise NULL is returned.
- */
-
-NSAPI_PUBLIC PList_t
-PListCreate(pool_handle_t *mempool, int resvprop, int maxprop, int flags)
-{
-    PListStruct_t *plist;       /* pointer to property list structure */
-    int i;
-
-    plist = (PListStruct_t *)pool_malloc(mempool, sizeof(PListStruct_t));
-    if (plist) {
-
-        /* Negative maxprop is the same as zero, i.e. no limit */
-        if (maxprop < 0) maxprop = 0;
-
-        /* If resvprop and maxprop are both specified, limit resvprop */
-        if (resvprop > 0) {
-            if (maxprop && (resvprop > maxprop)) resvprop = maxprop;
-        }
-        else resvprop = 0;
-
-        /* Initialize property list structure */
-        plist->pl_mempool = mempool;
-        plist->pl_symtab = NULL;
-        plist->pl_maxprop = maxprop;
-        plist->pl_resvpi = resvprop;
-        plist->pl_initpi = resvprop;
-        plist->pl_lastpi = resvprop;
-
-        /* Set initialize size for array of property value pointers */
-        plist->pl_cursize = (resvprop) ? resvprop : PLIST_DEFSIZE;
-
-        /* Allocate the initial array of property value pointers */
-        plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
-                                   	           (plist->pl_cursize *
-                                                    sizeof(PLValueStruct_t *)));
-        if (!plist->pl_ppval) {
-
-            /* Failed - insufficient memory */
-            pool_free(mempool, (void *)plist);
-            plist = NULL;
-        }
-        else {
-            /* NULL out pointers in the reserved index range, if any */
-            for (i = 0; i < plist->pl_lastpi; ++i) {
-                plist->pl_ppval[i] = 0;
-            }
-        }
-    }
-
-    return (PList_t)plist;
-}
-
-/*
- * FUNCTION:    PListDefProp
- *
- * DESCRIPTION:
- *
- *      This function creates a new property in a specified property list.
- *      The 'pindex' argument may be used to request a particular property
- *      index for the new property.  If 'pindex' is greater than zero,
- *      the specified value is used as the new property's index, provided
- *      there is no property at that index already.  If 'pindex' is zero,
- *      then the next available property index is assigned to the new
- *      property.  A name may optionally be specified for the new property.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - new property index (or zero)
- *      pname                   - new property name (or NULL)
- *
- * RETURNS:
- *
- *      If successful, the index of the new property is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListDefProp(PList_t plist, int pindex, const char *pname, const int flags)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t *pv;
-
-    if (!plist) return ERRPLUNDEF;
-
-    /* Is pindex specified? */
-    if (pindex > 0) {
-
-        /* Yes, is it in the reserved range? */
-        if (flags != PLFLG_IGN_RES && pindex > pl->pl_resvpi) {
-            /* No, error */
-            return ERRPLINVPI;
-        }
-
-        PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
-        if (ppval[pindex - 1]) {
-            /* Error - property already exists at specified index */
-            return ERRPLEXIST;
-        }
-    }
-    else {
-
-        /* Look for a free property index */
-        pindex = PListGetFreeIndex(pl);
-        if (pindex < 1) {
-            /* Error - no free property index */
-            return pindex;
-        }
-    }
-
-    /* We have a property index.  Create a new property value */
-    pv = (PLValueStruct_t *)pool_calloc(pl->pl_mempool,
-                                        1, sizeof(PLValueStruct_t));
-    if (!pv) {
-
-        /* Error - insufficient memory */
-        return ERRPLNOMEM;
-    }
-
-    PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
-    pv->pv_pbentry.param = &pv->pv_pbparam;
-    pv->pv_pi = pindex;
-    pv->pv_mempool = pl->pl_mempool;
-    ppval[pindex - 1] = pv;
-
-    /* Name the property if the name was specified */
-    if (pname) {
-
-        /* XXX Maybe should delete property if naming fails */
-        return PListNameProp(plist, pindex, pname);
-    }
-
-    /* Return the property index of the new property */
-    return pindex;
-}
-
-/*
- * FUNCTION:    PListDeleteProp
- *
- * DESCRIPTION:
- *
- *      This function deletes a property from a specified property list.
- *      The property can be specified by its property index, using a
- *      pindex value greater than zero, or by its name, by specifying
- *      pindex as zero and pname as the property name.  This does not
- *      have any effect on the data referenced by the property value,
- *      if any, nor does it have any effect on the property list that
- *      describes the property value's type, if any.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - the property index, or zero
- *      pname                   - the property name, or NULL
- */
-
-NSAPI_PUBLIC const void *
-PListDeleteProp(PList_t plist, int pindex, const char *pname_in)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t **pvp;
-    PLValueStruct_t *pv = NULL;
-    int i;
-    const void *pvalue = NULL;
-    char *pname = (char *)pname_in;
-
-    if (!plist) return NULL;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Check for valid property index */
-    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
-
-        /* Get the pointer to the property structure */
-        pv = ppval[pindex - 1];
-	pname = 0;
-	if (pv) {
-	    pname = pv->pv_name;
-	}
-    }
-
-    if (pname && pl->pl_symtab) {
-
-        /* Compute hash of specified property name */
-        i = PListHashName(pl->pl_symtab, pname);
-
-        /* Search hash collision list for matching name */
-        for (pvp = &pl->pl_symtab->pt_hash[i]; *pvp; pvp = &(*pvp)->pv_next) {
-
-            pv = *pvp;
-            if (!strcmp(pname, pv->pv_name)) {
-
-                /* Found it.  Get its index and remove it. */
-                pindex = pv->pv_pi;
-                *pvp = pv->pv_next;
-                pl->pl_symtab->pt_nsyms--;
-                break;
-            }
-            pv = NULL;
-        }
-    }
-
-    /* Found the indicated property by index or name? */
-    if (pv) {
-
-        /* Yes, remove it from the property list */
-        ppval[pindex - 1] = NULL;
-
-        /* Free the property name, if any */
-        if (pv->pv_name) {
-            pool_free(pv->pv_mempool, (void *)(pv->pv_name));
-        }
-        pvalue = pv->pv_value;
-
-        /* Free the property */
-        pool_free(pv->pv_mempool, (void *)pv);
-    }
-    return(pvalue);
-}
-
-/*
- * FUNCTION:    PListFindValue
- *
- * DESCRIPTION:
- *
- *      This function retrieves the value and type of a property with a
- *      specified property name.  If the pvalue argument is non-NULL,
- *      it specifies a location in which to return the property value.
- *      Similarly, if ptype is non-NULL, it specifies where the property
- *      list describing the property type is to be returned.  If a
- *      property has no value, the value returned for pvalue is NULL.
- *      If a property has no type, the value returned for ptype is NULL.
- *      A property can have a value, a type, both, or neither.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pname                   - pointer to property name string
- *      pvalue                  - property value return pointer
- *      ptype                   - property type return pointer
- *
- * RETURNS:
- *
- *      If successful, the index of the referenced property is returned
- *      as the function value.  Errors are indicated by a negative
- *      return code as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListFindValue(PList_t plist, const char *pname, void **pvalue, PList_t *ptype)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t *pv;
-    int pindex;
-    int i;
-
-    if (!plist) return ERRPLUNDEF;
-
-    /* Got a symbol table for this property list? */
-    if (pl->pl_symtab) {
-
-        /* Yes, compute hash of specified name */
-        i = PListHashName(pl->pl_symtab, pname);
-
-        /* Search hash collision list for matching name */
-        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
-
-            if (!strcmp(pname, pv->pv_name)) {
-
-                /* Name match, get property index */
-                pindex = pv->pv_pi;
-
-                /* Return the value if requested */
-                if (pvalue) *pvalue = (void *)(pv->pv_value);
-
-                /* Return the type if requested */
-                if (ptype) *ptype = (PList_t)(pv->pv_type);
-
-                /* Return the property index */
-                return pindex;
-            }
-        }
-    }
-
-    /* Error - specified property name is undefined */
-    return ERRPLUNDEF;
-}
-
-/*
- * FUNCTION:    PListInitProp
- *
- * DESCRIPTION:
- *
- *      This function combines the functions of PListDefProp() and
- *      PListSetValue(), defining a new property and assigning it an
- *      initial value and optionally a type and/or a name.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - a reserved property index, or zero
- *      pname                   - the new property name, or NULL
- *      pvalue                  - the new property value
- *      ptype                   - the new property type, or NULL
- *
- * RETURNS:
- *
- *      If successful, the property index (pindex) is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListInitProp(PList_t plist, int pindex, const char *pname,
-              const void *pvalue, PList_t ptype)
-{
-    int rv;
-
-    if (!plist) return ERRPLUNDEF;
-
-    /* Create the property */
-    rv = PListDefProp(plist, pindex, pname, PLFLG_USE_RES);
-    if (rv > 0) {
-
-        /* If that worked, set the value and type */
-        rv = PListSetValue(plist, rv, pvalue, ptype);
-    }
-
-    return rv;
-}
-
-/*
- * FUNCTION:    PListNew
- *
- * DESCRIPTION:
- *
- *      This function creates a new property list, using the specified
- *      memory pool for allocating the internal data structures used to
- *      represent it.  If the mempool argument is NULL, the default
- *      memory pool is used.
- *
- * ARGUMENTS:
- *
- *      mempool                 - handle for a memory pool to be associated
- *                                with the new property list
- *
- * RETURNS:
- *
- *      If successful, the function return value is a handle for the new
- *      property list.  Otherwise NULL is returned.
- */
-
-NSAPI_PUBLIC PList_t
-PListNew(pool_handle_t *mempool)
-{
-    /* Just call PListCreate with default parameters */
-    return PListCreate(mempool, 0, 0, 0);
-}
-
-/*
- * FUNCTION:    PListDestroy
- *
- * DESCRIPTION:
- *
- *      This function destroys a specified property list.  This means
- *      that any dynamic memory which was allocated as a result of calls
- *      to the property list API is freed to the memory pool from which
- *      it was allocated.  Property value data is not freed, nor are
- *      any property lists associated with property types.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- */
-
-void
-PListDestroy(PList_t plist)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int i;
-
-    if (!plist) return;
-
-    /* Free the property name symbol table if any */
-    if (pl->pl_symtab) {
-        pool_free(pl->pl_mempool, (void *)(pl->pl_symtab));
-    }
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Loop over the initialized property indices */
-    for (i = 0; i < pl->pl_initpi; ++i) {
-
-        /* Got a property here? */
-        pv = ppval[i];
-        if (pv) {
-
-            /* Free the property name string if any */
-            if (pv->pv_name) {
-                pool_free(pv->pv_mempool, (void *)(pv->pv_name));
-            }
-
-            /* Free the property value structure */
-            pool_free(pv->pv_mempool, (void *)pv);
-        }
-    }
-
-    /* Free the array of pointers to property values */
-    pool_free(pl->pl_mempool, (void *)ppval);
-
-    /* Free the property list head */
-    pool_free(pl->pl_mempool, (void *)pl);
-}
-
-/*
- * FUNCTION:    PListGetValue
- *
- * DESCRIPTION:
- *
- *      This function retrieves the value and type of the property with
- *      the property index given by pindex in the specified property
- *      list.  The pindex argument must specify the index of a defined
- *      property.  If the pvalue argument is non-NULL, it specifies a
- *      location in which to return the property value.  Similarly, if
- *      ptype is non-NULL, it specifies where the property list
- *      describing the property type is to be returned.  If a property
- *      has no value, the value returned for pvalue is NULL.  If a
- *      property has no type, the value returned for ptype is NULL. A
- *      property can have a value, a type, both, or neither.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - the property index
- *      pvalue                  - property value return pointer
- *      ptype                   - property type return pointer
- *
- * RETURNS:
- *
- *      If successful, the property index (pindex) is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListGetValue(PList_t plist, int pindex, void **pvalue, PList_t *ptype)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-
-    if (!plist) return ERRPLUNDEF;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Check for valid property index */
-    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
-
-        /* Does the property exist? */
-        pv = ppval[pindex - 1];
-        if (pv) {
-
-            /* Yes, return the value if requested */
-            if (pvalue) *pvalue = (void *)(pv->pv_value);
-
-            /* Return the type if requested */
-            if (ptype) *ptype = (PList_t)(pv->pv_type);
-
-            /* Successful return */
-            return pindex;
-        }
-    }
-
-    /* Error - invalid property index or non-existent property */
-    return ERRPLINVPI;
-}
-
-/*
- * FUNCTION:    PListHash
- *
- * DESCRIPTION:
- *
- *      This function hashes a given string.
- *
- * ARGUMENTS:
- *
- *      string                  - pointer to the string to hash
- *
- * RETURNS:
- *
- *      The hash value is returned as the function value.
- */
-
-unsigned int
-PListHash(const char *string)
-{
-    unsigned int hashval = 0;           /* hash value */
-
-    while (*string) {
-        hashval = (hashval<<5) ^ (*string++ & 0x7f);
-    }
-
-    return hashval;
-}
-
-/*
- * FUNCTION:    PListHashName
- *
- * DESCRIPTION:
- *
- *      This function hashes a given property name for a specified
- *      symbol table.  It produces a value that can be used as an
- *      index in the pt_hash array associated with the symbol table.
- *
- * ARGUMENTS:
- *
- *      symtab                  - pointer to the symbol table
- *      pname                   - pointer to the property name string
- *
- * RETURNS:
- *
- *      The hash index is returned as the function value.
- */
-
-int
-PListHashName(PLSymbolTable_t *symtab, const char *pname)
-{
-    return PListHash(pname) % PLSIZENDX(symtab->pt_sizendx);
-}
-
-/*
- * FUNCTION:    PListNameProp
- *
- * DESCRIPTION:
- *
- *      This function assigns a name to a defined property with the
- *      property index, pindex.  If the property has an existing name,
- *      it will be replaced with the name specified by pname.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - the property index
- *      pname                   - the new property name
- *
- * RETURNS:
- *
- *      If successful, the property index (pindex) is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListNameProp(PList_t plist, int pindex, const char *pname)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t *pv;
-    PLSymbolTable_t *pt;
-    int i;
-
-    if (!plist) return ERRPLUNDEF;
-
-    pt = pl->pl_symtab;
-
-    /* Check for valid property index */
-    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
-
-        /* Does the property exist? */
-        pv = ((PLValueStruct_t **)(pl->pl_ppval))[pindex - 1];
-        if (pv) {
-
-            /* If it has a name already, unname it */
-            if (pv->pv_name) {
-                PLValueStruct_t **pvp;
-
-                /* Get hash bucket index */
-                i = PListHashName(pt, pv->pv_name);
-
-                /* Seach hash collision list for this property */
-                for (pvp = &pt->pt_hash[i];
-                     *pvp; pvp = &(*pvp)->pv_next) {
-
-                    if (*pvp == pv) {
-
-                        /* Remove it from the list */
-                        *pvp = pv->pv_next;
-                        pt->pt_nsyms--;
-                        break;
-                    }
-                }
-
-                /* Free the current name string */
-                pool_free(pv->pv_mempool, (void *)(pv->pv_name));
-            }
-
-            /* Got a new name? */
-            if (pname) {
-
-                /* Allocate/grow the symbol table as needed */
-                pt = PListSymbolTable(pl);
-                if (!pt) {
-                    return ERRPLNOMEM;
-                }
-
-                /* Duplicate the name string */
-                pv->pv_name = pool_strdup(pv->pv_mempool, (char *)pname);
-
-                /* Add name to symbol table */
-                i = PListHashName(pt, pname);
-                pv->pv_next = pt->pt_hash[i];
-                pt->pt_hash[i] = pv;
-                pt->pt_nsyms++;
-            }
-
-            /* Successful return */
-            return pindex;
-        }
-    }
-
-    /* Error - invalid property index or non-existent property */
-    return ERRPLINVPI;
-}
-
-/*
- * FUNCTION:    PListSetType
- *
- * DESCRIPTION:
- *
- *      This function sets the property type of the defined property
- *      with the property index, pindex.  The property list describing
- *      the property type is specified by ptype.  If ptype is NULL,
- *      the property type will be set to be undefined (NULL).
- *
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - the property index
- *      ptype                   - the new property type, or NULL
- *
- * RETURNS:
- *
- *      If successful, the property index (pindex) is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListSetType(PList_t plist, int pindex, PList_t ptype)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-
-    if (!plist) return ERRPLUNDEF;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Check for valid property index */
-    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
-
-        /* Does the property exist? */
-        pv = ppval[pindex - 1];
-        if (pv) {
-
-            /* Yes, set the new type */
-            pv->pv_type = ptype;
-
-            /* Successful return */
-            return pindex;
-        }
-    }
-
-    /* Error - invalid property index or non-existent property */
-    return ERRPLINVPI;
-}
-
-/*
- * FUNCTION:    PListSetValue
- *
- * DESCRIPTION:
- *
- *      This function sets the value and optionally the type of a
- *      defined property in a given property list.  The pindex argument
- *      specifies the property index, which must be greater than zero.
- *      The ptype argument specifies a property list that describes the
- *      property type.  If ptype is NULL, the property type, if any, is
- *      unchanged by this function.  However, the property value is
- *      always set to the value given by pvalue.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      pindex                  - the property index
- *      pvalue                  - the new property value
- *      ptype                   - the new property type, or NULL
- *
- * RETURNS:
- *
- *      If successful, the property index (pindex) is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-NSAPI_PUBLIC int
-PListSetValue(PList_t plist, int pindex, const void *pvalue, PList_t ptype)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-
-    if (!plist) return ERRPLUNDEF;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Check for valid property index */
-    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
-
-        /* Does the property exist? */
-        pv = ppval[pindex - 1];
-        if (pv) {
-
-            /* Yes, set the new value */
-            pv->pv_value = (char *)pvalue;
-
-            /* Set type if type is given */
-            if (ptype) pv->pv_type = (PListStruct_t *)ptype;
-
-            /* Successful return */
-            return pindex;
-        }
-    }
-
-    /* Error - invalid property index or non-existent property */
-    return ERRPLINVPI;
-}
-
-/*
- * FUNCTION:    PListEnumerate
- *
- * DESCRIPTION:
- *
- *      This function walks through a specified property list
- *	calling a user supplied function with the property
- *	name and value as parameters.  
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      user_func               - handle for the user function 
- */
-
-NSAPI_PUBLIC void
-PListEnumerate(PList_t plist, PListFunc_t *user_func, void *user_data)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int i;
-
-    if (!plist) return;
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Loop over the initialized property indices */
-    for (i = 0; i < pl->pl_initpi; ++i) {
-
-        /* Got a property here? */
-        pv = ppval[i];
-        if (pv) {
-            (*user_func)(pv->pv_name, pv->pv_value, user_data);
-        }
-
-    }
-
-}
-
-/*
- * FUNCTION:    PListCreateDuplicate
- *
- * DESCRIPTION:
- *
- *      This function creates a new property list and returns a handle for
- *      it.  The source plist provides the new plists parameters.
- *
- * ARGUMENTS:
- *
- *	src_plist		- source plist to duplicate
- *      mempool                 - handle for a memory pool to be associated
- *                                with the new property list, only
- *				  used if flags is set to PLFLG_NEW_MPOOL
- *      flags                   - if PLFLG_NEW_MPOOL uses new_mempool
- *				  parameter
- *
- * RETURNS:
- *
- *      If successful, the function return value is a handle for the new
- *      property list.  Otherwise NULL is returned.
- */
-
-static PList_t
-PListCreateDuplicate(PList_t src_plist, pool_handle_t *new_mempool, int flags)
-{
-    PListStruct_t *plist;       /* pointer to property list structure */
-    int i;
-    pool_handle_t *mempool;
-
-    mempool = (flags == PLFLG_NEW_MPOOL) ? new_mempool : src_plist->pl_mempool;
-
-    plist = (PListStruct_t *)pool_malloc(mempool, sizeof(PListStruct_t));
-    if (plist) {
-
-        /* Initialize property list structure */
-        plist->pl_mempool = mempool;
-        plist->pl_symtab = NULL;
-        plist->pl_maxprop = src_plist->pl_maxprop;
-        plist->pl_resvpi = src_plist->pl_resvpi;
-        plist->pl_initpi = src_plist->pl_initpi;
-        plist->pl_lastpi = src_plist->pl_lastpi;
-
-        /* Set initialize size for array of property value pointers */
-        plist->pl_cursize = src_plist->pl_cursize; 
-
-        /* Allocate the initial array of property value pointers */
-        plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
-                                                   (plist->pl_cursize *
-                                                    sizeof(PLValueStruct_t *)));
-        if (!plist->pl_ppval) {
-
-            /* Failed - insufficient memory */
-            pool_free(mempool, (void *)plist);
-            plist = NULL;
-        }
-        else {
-            /* NULL out pointers in the reserved index range, if any */
-            for (i = 0; i < plist->pl_lastpi; ++i) {
-                plist->pl_ppval[i] = 0;
-            }
-        }
-    }
-
-    return (PList_t)plist;
-}
-
-
-/*
- * FUNCTION:    PListDuplicate
- *
- * DESCRIPTION:
- *
- *      This function duplicates a specified PList_t.  
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *      mempool                 - handle for a memory pool to be associated
- *                                with the new property list
- *      resvprop                - number of reserved property indices
- *      maxprop                 - maximum number of properties in list
- *                                (zero or negative imposes no limit)
- *      flags                   - unused, reserved, must be zero
- *
- * RETURNS:
- *
- *      If successful, the function return value is a handle for the new
- *      property list.  Otherwise NULL is returned.
- */
-
-NSAPI_PUBLIC PList_t
-PListDuplicate(PList_t plist, pool_handle_t *new_mempool, int flags)
-{
-    PListStruct_t *pl = (PListStruct_t *)plist;
-    PLValueStruct_t **ppval;
-    PLValueStruct_t *pv;
-    int i;
-    int rv = 0;
-    PList_t new_plist;
-
-    if (!plist) return NULL;
-
-    new_plist = PListCreateDuplicate(plist, new_mempool, flags);
-    if (new_plist == NULL) {
-        return(NULL);
-    }
-
-    ppval = (PLValueStruct_t **)(pl->pl_ppval);
-
-    /* Loop over the initialized property indices */
-    for (i = 0; i < pl->pl_initpi; ++i) {
-
-        /* Got a property here? */
-        pv = ppval[i];
-        if (pv) {
-            /* Create the property */
-            rv = PListDefProp(new_plist, i + 1, pv->pv_name, PLFLG_IGN_RES);
-            if (rv > 0) {
-        
-                /* If that worked, set the value and type */
-                rv = PListSetValue(new_plist, rv, pv->pv_value, pv->pv_type);
-            }
-        
-            if ( rv <= 0 ) {
-                PListDestroy(new_plist);
-                return(NULL);
-            }
-        }
-
-    }
-
-    return(new_plist);
-}
-
-/*
- * FUNCTION:    PListGetPool
- *
- * DESCRIPTION:
- *
- *      This function returns the memory pool the PList is allocated from.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *
- * RETURNS:
- *
- *      The memory pool address, which can be NULL.
- */
-
-NSAPI_PUBLIC pool_handle_t *
-PListGetPool(PList_t plist)
-{
-    if (!plist) return NULL;
-
-    return(plist->pl_mempool);
-}
-
-/*
- * FUNCTION:    PListGetFreeIndex
- *
- * DESCRIPTION:
- *
- *      This function returns an available property index.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *
- * RETURNS:
- *
- *      If successful, an available property index is returned as the
- *      function value.  Errors are indicated by a negative return code
- *      as defined in plist.h.
- */
-
-int
-PListGetFreeIndex(PListStruct_t *pl)
-{
-    PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
-    int wrapped;
-    int i;
-
-    /*
-     * Look for a free property index, starting at pl_lastpi + 1.
-     * (Note that i is the property index - 1)
-     */
-    for (wrapped = 0, i = pl->pl_lastpi; ;) {
-
-        /* Are we in an initialized part of the array? */
-        if (i < pl->pl_initpi) {
-
-            /* Yes, use this index if it's free */
-            if (ppval[i] == 0) break;
-
-            /* Otherwise step to the next one */
-            ++i;
-        }
-        else {
-
-            /* Have we reached the end yet? */
-            if (i < pl->pl_cursize) {
-
-                /*
-                 * We are above the highest initialized index, but
-                 * still within the allocated size.  An index in
-                 * this range can be used with no further checks.
-                 */
-                ppval[i] = 0;
-            }
-            else {
-
-                /*
-                 * It's looking like time to grow the array, but
-                 * first go back and look for an unused, unreserved
-                 * index that might have been freed.
-                 */
-                if (!wrapped) {
-
-                    i = pl->pl_resvpi;
-                    wrapped = 1;
-                    continue;
-                }
-
-                /*
-                 * Grow the array unless there is a specified maximum
-                 * size and we've reached it.
-                 */
-                i = pl->pl_cursize;
-                if (pl->pl_maxprop && (i > pl->pl_maxprop)) {
-
-                    /* Error - property list is full */
-                    return ERRPLFULL;
-                }
-
-                /* Increase planned size of list */
-                int cursize = i + PLIST_DEFGROW;
-
-                /* Reallocate the array of property value pointers */
-                ppval = (PLValueStruct_t **)pool_realloc(pl->pl_mempool,
-                                   (void *)ppval,
-                                   (cursize * sizeof(PLValueStruct_t *)));
-                if (!ppval) {
-
-                    /* Error - insufficient memory */
-                    return ERRPLNOMEM;
-                }
-
-                /* Initialize the first new entry and select it */
-                ppval[i] = NULL;
-                pl->pl_ppval = (pb_entry **)ppval;
-                pl->pl_cursize = cursize;
-            }
-
-            /* Update the highest initialized index value */
-            pl->pl_initpi = i + 1;
-            break;
-        }
-    }
-
-    /* Set the starting point for the next allocation */
-    pl->pl_lastpi = i + 1;
-
-    return i + 1;
-}
-
-/*
- * FUNCTION:    PListSymbolTable
- *
- * DESCRIPTION:
- *
- *      This function allocates or grows a property list's symbol table as
- *      needed.
- *
- * ARGUMENTS:
- *
- *      plist                   - handle for the property list
- *
- * RETURNS:
- *
- *      If successful, a pointer to the symbol table is returned as the
- *      function value.  Errors are indicated by a NULL return code.
- */
-
-PLSymbolTable_t *
-PListSymbolTable(PListStruct_t *pl)
-{
-    PLSymbolTable_t *pt;
-    int i;
-
-    pt = pl->pl_symtab;
-
-    /* Is there a hash table? */
-    if (!pl->pl_symtab) {
-
-        /* No, create one */
-        pt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(0));
-
-        pl->pl_symtab = pt;
-    }
-    else {
-
-        /* Is it time to grow the hash table? */
-        i = PLSIZENDX(pt->pt_sizendx);
-        if ((pt->pt_sizendx < PLMAXSIZENDX) && pt->pt_nsyms >= (i + i)) {
-
-            PLSymbolTable_t *npt;
-
-            /* Yes, allocate the new table */
-            npt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1,
-                                                 PLHASHSIZE(pt->pt_sizendx+1));
-            if (npt) {
-                npt->pt_sizendx = pt->pt_sizendx + 1;
-                npt->pt_nsyms = pt->pt_nsyms;
-
-                /* Rehash all the names into the new table, preserving order */
-                for (i = 0; i < PLSIZENDX(pt->pt_sizendx); ++i) {
-                    /* While there are names at this hash index... */
-                    while (pt->pt_hash[i]) {
-                        PLValueStruct_t **pvp;
-                        int j;
-
-                        /* Find the last name at this hash index */
-                        for (pvp = &pt->pt_hash[i]; (*pvp)->pv_next; pvp = &(*pvp)->pv_next);
-                        
-                        /* Move the name to the new table */
-                        j = PListHashName(npt, (*pvp)->pv_name);
-                        (*pvp)->pv_next = npt->pt_hash[j];
-                        npt->pt_hash[j] = (*pvp);
-
-                        /* Remove the name from the old table */
-                        *pvp = NULL;
-                    }
-                }
-
-                pl->pl_symtab = npt;
-
-                /* Free the old symbol table */
-                pool_free(pl->pl_mempool, (void *)pt);
-                pt = npt;
-            }
-        }
-    }
-
-    return pl->pl_symtab;
-}
--- a/src/server/plist.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PLIST_H
-#define _PLIST_H
-
-#ifndef NOINTNSACL
-#define INTNSACL
-#endif /* !NOINTNSACL */
-
-/*
- * TYPE:        PList_t
- *
- * DESCRIPTION:
- *
- *      This type defines a handle for a property list.
- */
-
-#include "pool.h"
-#include "mps/nspr.h"
-#include "nsapi.h"
-#include "plist_pvt.h"
-
-#ifndef PUBLIC_NSACL_PLISTDEF_H
-#include "plistdef.h"
-#endif /* !PUBLIC_NSACL_PLISTDEF_H */
-
-#ifdef INTNSACL
-
-/* Functions in plist.c */
-NSPR_BEGIN_EXTERN_C
-
-NSAPI_PUBLIC extern int PListAssignValue(PList_t plist, const char *pname,
-                            const void *pvalue, PList_t ptype);
-NSAPI_PUBLIC extern PList_t PListCreate(pool_handle_t *mempool,
-                           int resvprop, int maxprop, int flags);
-NSAPI_PUBLIC extern int PListDefProp(PList_t plist, int pindex, 
-                        const char *pname, const int flags);
-NSAPI_PUBLIC extern const void * PListDeleteProp(PList_t plist, int pindex, const char *pname);
-NSAPI_PUBLIC extern int PListFindValue(PList_t plist,
-                          const char *pname, void **pvalue, PList_t *type);
-NSAPI_PUBLIC extern int PListInitProp(PList_t plist, int pindex, const char *pname,
-                         const void *pvalue, PList_t ptype);
-NSAPI_PUBLIC extern PList_t PListNew(pool_handle_t *mempool);
-NSAPI_PUBLIC extern void PListDestroy(PList_t plist);
-NSAPI_PUBLIC extern int PListGetValue(PList_t plist,
-                         int pindex, void **pvalue, PList_t *type);
-NSAPI_PUBLIC extern int PListNameProp(PList_t plist, int pindex, const char *pname);
-NSAPI_PUBLIC extern int PListSetType(PList_t plist, int pindex, PList_t type);
-NSAPI_PUBLIC extern int PListSetValue(PList_t plist,
-                         int pindex, const void *pvalue, PList_t type);
-NSAPI_PUBLIC extern void PListEnumerate(PList_t plist, PListFunc_t *user_func, 
-                           void *user_data);
-NSAPI_PUBLIC extern PList_t
-PListDuplicate(PList_t plist, pool_handle_t *new_mempool, int flags);
-NSAPI_PUBLIC extern pool_handle_t *PListGetPool(PList_t plist);
-NSAPI_PUBLIC extern int PListDefKey(PList_t plist, pb_key *key, const char *pname, const int flags);
-NSAPI_PUBLIC extern int PListInitKey(PList_t plist, pb_key *key, const void *pvalue, PList_t ptype);
-
-NSPR_END_EXTERN_C
-
-#endif /* INTNSACL */
-
-#endif /* _PLIST_H */
--- a/src/server/plist_pvt.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PLIST_PVT_H
-#define _PLIST_PVT_H
-
-/*
- * FILE:        plist_pvt.h
- *
- * DESCRIPTION:
- *
- *      This file contains private definitions for the property list
- *      utility implementation.
- */
-
-#include "nsapi.h"
-#include "pool.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Forward declarations */
-typedef struct PLValueStruct_s PLValueStruct_t;
-typedef struct PLSymbol_s PLSymbol_t;
-typedef struct PLSymbolTable_s PLSymbolTable_t;
-typedef struct PListStruct_s PListStruct_t;
-
-/*
- * TYPE:        PLValueStruct_t
- *
- * DESCRIPTION:
- *
- *      This type represents a property value. It is dynamically
- *      allocated when a new property is added to a property list.
- *      It contains a reference to a property list that contains
- *      information about the property value, and a reference to
- *      the property value data.
- */
-
-#ifndef PBLOCK_H
-#include "pblock.h"
-#endif /* PBLOCK_H */
-
-struct PLValueStruct_s {
-    pb_entry pv_pbentry;	/* used for pblock compatibility */
-    pb_param pv_pbparam;	/* property name and value pointers */
-    const pb_key *pv_pbkey;     /* property pb_key pointer (optional) */
-    PLValueStruct_t *pv_next;   /* property name hash collision link */
-    PListStruct_t *pv_type;     /* property value type reference */
-    int pv_pi;                  /* property index */
-    pool_handle_t *pv_mempool;  /* pool we were allocated from */
-};
-
-#define pv_name pv_pbparam.name
-#define pv_value pv_pbparam.value
-
-/* Offset to pv_pbparam in PLValueStruct_t */
-#define PVPBOFFSET ((char *)&((PLValueStruct_t *)0)->pv_pbparam)
-
-/* Convert pb_param pointer to PLValueStruct_t pointer */
-#define PATOPV(p) ((PLValueStruct_t *)((char *)(p) - PVPBOFFSET))
-
-/*
- * TYPE:        PLSymbolTable_t
- *
- * DESCRIPTION:
- *
- *      This type represents a symbol table that maps property names
- *      to properties.  It is dynamically allocated the first time a
- *      property is named.
- */
-
-#define PLSTSIZES       {7, 19, 31, 67, 123, 257, 513}
-#define PLMAXSIZENDX    (sizeof(plistHashSizes)/sizeof(plistHashSizes[0]) - 1)
-
-struct PLSymbolTable_s {
-    int pt_sizendx;             /* pt_hash size, as an index in PLSTSIZES */
-    int pt_nsyms;               /* number of symbols in table */
-    PLValueStruct_t *pt_hash[1];/* variable-length array */
-};
-
-/*
- * TYPE:        PListStruct_t
- *
- * DESCRIPTION:
- *
- *      This type represents the top-level of a property list structure.
- *      It is dynamically allocated when a property list is created, and
- *      freed when the property list is destroyed.  It references a
- *      dynamically allocated array of pointers to property value
- *      structures (PLValueStruct_t).
- */
-
-#define PLIST_DEFSIZE   8       /* default initial entries in pl_ppval */
-#define PLIST_DEFGROW   16      /* default incremental entries for pl_ppval */
-
-struct PListStruct_s {
-    pblock pl_pb;		/* pblock subset of property list head */
-    PLSymbolTable_t *pl_symtab; /* property name to index symbol table */
-    pool_handle_t *pl_mempool;  /* associated memory pool handle */
-    int pl_maxprop;             /* maximum number of properties */
-    int pl_resvpi;              /* number of reserved property indices */
-    int pl_lastpi;              /* last allocated property index */
-    int pl_cursize;             /* current size of pl_ppval in entries */
-};
-
-#define pl_initpi pl_pb.hsize    /* number of pl_ppval entries initialized */
-#define pl_ppval pl_pb.ht	/* pointer to array of value pointers */
-
-/* Convert pblock pointer to PListStruct_t pointer */
-#define PBTOPL(p) ((PListStruct_t *)(p))
-
-#define PLSIZENDX(i) (plistHashSizes[i])
-#define PLHASHSIZE(i) (sizeof(PLSymbolTable_t) + \
-                       (PLSIZENDX(i) - 1)*sizeof(PLValueStruct_t *))
-
-extern int plistHashSizes[7];
-
-unsigned int PListHash(const char *string);
-
-int PListHashName(PLSymbolTable_t *symtab, const char *pname);
-
-int PListGetFreeIndex(PListStruct_t *pl);
-
-PLSymbolTable_t *PListSymbolTable(PListStruct_t *pl);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif /* _PLIST_PVT_H */
--- a/src/server/plistdef.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PUBLIC_NSACL_PLISTDEF_H
-#define PUBLIC_NSACL_PLISTDEF_H
-
-/*
- * File:        plistdef.h
- *
- * Description:
- *
- *      This file defines the interface to property lists.  Property
- *      lists are a generalization of parameter blocks (pblocks).
- */
-
-#ifndef PUBLIC_NSAPI_H
-#include "nsapi.h"
-#endif /* !PUBLIC_NSAPI_H */
-
-typedef struct PListStruct_s *PList_t;
-
-/* Define error codes returned from property list routines */
-
-#define ERRPLINVPI      -1      /* invalid property index */
-#define ERRPLEXIST      -2      /* property already exists */
-#define ERRPLFULL       -3      /* property list is full */
-#define ERRPLNOMEM      -4      /* insufficient dynamic memory */
-#define ERRPLUNDEF      -5      /* undefined property name */
-
-#define PLFLG_OLD_MPOOL	0	/* use the plist memory pool */
-#define PLFLG_NEW_MPOOL	1	/* use the input memory pool */
-#define PLFLG_IGN_RES	2	/* ignore the reserved properties */
-#define PLFLG_USE_RES	3	/* use the reserved properties */
-
-#ifdef __cplusplus
-typedef void (PListFunc_t)(char*, const void*, void*);
-#else
-typedef void (PListFunc_t)();
-#endif
-
-#ifndef INTNSACL
-
-
-
-#endif /* !INTNSACL */
-
-#endif /* !PUBLIC_NSACL_PLISTDEF_H */
--- a/src/server/pool.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,699 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Generic pool handling routines.
- *
- * These routines reduce contention on the heap and guard against
- * memory leaks.
- *
- * Thread warning:
- *     This implementation is thread safe.  However, simultaneous 
- *     mallocs/frees to the same "pool" are not safe.  Do not share
- *     pools across multiple threads without providing your own
- *     synchronization.
- *
- * Mike Belshe
- * 11-20-95
- *
- */
-
-//include "netsite.h"
-//include "systems.h"
-#include "systhr.h"
-#include "pool_pvt.h"
-#include "ereport.h"
-//include "base/session.h"
-//include "frame/req.h"
-//include "frame/http.h"
-#include "util.h"
-//include "base/crit.h"
-
-//include "base/dbtbase.h"
-
-
-
-#include <stdlib.h>
-#include <string.h>
-//define PERM_MALLOC   malloc
-//define PERM_FREE     free
-//define PERM_REALLOC  realloc
-//define PERM_CALLOC   calloc
-//define PERM_STRDUP   strdup
-
-/* Pool configuration parameters */
-static pool_config_t pool_config = POOL_CONFIG_INIT;
-
-/* Pool global statistics */
-static pool_global_stats_t pool_global_stats;
-
-static int 
-pool_internal_init()
-{
-    if (pool_global_stats.lock == NULL) {
-        pool_global_stats.lock = PR_NewLock();
-    }
-
-    if (pool_config.block_size == 0) {
-        //ereport(LOG_INFORM, XP_GetAdminStr(DBT_poolInitInternalAllocatorDisabled_));
-    }
-
-    return 0;
-}
-
-NSAPI_PUBLIC int
-pool_init(pblock *pb, Session *sn, Request *rq)
-{
-    //char *str_block_size = pblock_findval("block-size", pb);
-    //char *str_pool_disable = pblock_findval("disable", pb);
-    char *str_block_size = "16384";
-    char *str_pool_disable = "false";
-    int n;
-
-    //printf("standard block size: %d\n", pool_config.block_size);
-
-    if (str_block_size != NULL) {
-        n = atoi(str_block_size);
-        if (n > 0)
-            pool_config.block_size = n;
-    }
-
-    if (str_pool_disable && util_getboolean(str_pool_disable, PR_TRUE)) {
-        /* We'll call PERM_MALLOC() on each pool_malloc() call */
-        pool_config.block_size = 0;
-        pool_config.retain_size = 0;
-        pool_config.retain_num = 0;
-    }
-
-    pool_internal_init();
-
-    return REQ_PROCEED;
-}
-
-static block_t *
-_create_block(pool_t *pool, int size)
-{
-    block_t *newblock;
-    char *newdata;
-    block_t **blk_ptr;
-    long blen;
-
-    /* Does the pool have any retained blocks on its free list? */
-    for (blk_ptr = &pool->free_blocks;
-         (newblock = *blk_ptr) != NULL; blk_ptr = &newblock->next) {
-
-        /* Yes, is this block large enough? */
-        blen = newblock->end - newblock->data;
-        if (blen >= size) {
-
-            /* Yes, take it off the free list */
-            *blk_ptr = newblock->next;
-            pool->free_size -= blen;
-            --pool->free_num;
-
-            /* Give the block to the caller */
-            newblock->start = newblock->data;
-            goto done;
-        }
-    }
-
-    newblock = (block_t *)PERM_MALLOC(sizeof(block_t));
-    newdata = (char *)PERM_MALLOC(size);
-    if (newblock == NULL || (newdata == NULL && size != 0)) {
-        //ereport(LOG_CATASTROPHE,
-        //        XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_));
-        PERM_FREE(newblock);
-        PERM_FREE(newdata);
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-        return NULL;
-    }
-    newblock->data = newdata;
-    newblock->start = newblock->data;
-    newblock->end   = newblock->data + size;
-    newblock->next  = NULL;
-    blen = size;
-
-#ifdef POOL_GLOBAL_STATISTICS
-    PR_AtomicIncrement((PRInt32 *)&pool_global_stats.blkAlloc);
-#endif /* POOL_GLOBAL_STATISTICS */
-
-  done:
-
-#ifdef PER_POOL_STATISTICS
-    ++pool->stats.blkAlloc;
-#endif /* PER_POOL_STATISTICS */
-
-    return newblock;
-}
-
-static void 
-_free_block(block_t *block)
-{
-    long blen = block->end - block->data;
-
-#ifdef POOL_ZERO_DEBUG
-    memset(block->data, POOL_ZERO_DEBUG, blen);
-#endif /* POOL_ZERO_DEBUG */
-
-    PERM_FREE(block->data);
-
-#ifdef POOL_ZERO_DEBUG
-    memset(block, POOL_ZERO_DEBUG, sizeof(block));
-#endif /* POOL_ZERO_DEBUG */
-
-    PERM_FREE(block);
-
-#ifdef POOL_GLOBAL_STATISTICS
-    PR_AtomicIncrement((PRInt32 *)&pool_global_stats.blkFree);
-#endif /* POOL_GLOBAL_STATISTICS */
-}
-
-/* ptr_in_pool()
- * Checks to see if the given pointer is in the given pool.
- * If true, returns a ptr to the block_t containing the ptr;
- * otherwise returns NULL
- */
-block_t * 
-_ptr_in_pool(pool_t *pool, const void *ptr)
-{
-    block_t *block_ptr = NULL;
-
-    /* try to find a block which contains this ptr */
-
-    if (POOL_PTR_IN_BLOCK(pool->curr_block, ptr)) {
-        block_ptr = pool->curr_block;
-    }
-    else {
-        for (block_ptr = pool->used_blocks; block_ptr; block_ptr = block_ptr->next) {
-            if (POOL_PTR_IN_BLOCK(block_ptr, ptr))
-                break;
-        }
-    }
-    return block_ptr;
-}
-
-
-NSAPI_PUBLIC pool_handle_t *
-pool_create()
-{
-    pool_t *newpool;
-
-    newpool = (pool_t *)PERM_MALLOC(sizeof(pool_t));
-
-    if (newpool) {
-        /* Have to initialize now, as pools get created sometimes
-         * before pool_init can be called...
-         */
-        if (pool_global_stats.lock == NULL) {
-            pool_internal_init();
-        }
-
-        newpool->used_blocks = NULL;
-        newpool->free_blocks = NULL;
-        newpool->free_size = 0;
-        newpool->free_num = 0;
-        newpool->size = 0;
-        newpool->next = NULL;
-
-#ifdef PER_POOL_STATISTICS
-        /* Initial per pool statistics */
-        memset((void *)(&newpool->stats), 0, sizeof(newpool->stats));
-        newpool->stats.thread = PR_GetCurrentThread();
-        newpool->stats.created = PR_Now();
-#endif /* PER_POOL_STATISTICS */
-
-        /* No need to lock, since pool has not been exposed yet */
-        newpool->curr_block =_create_block(newpool, pool_config.block_size);
-        if (newpool->curr_block == NULL) {
-            //ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_));
-            pool_destroy((pool_handle_t *)newpool);
-            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-            return NULL;
-        }
-
-        /* Add to known pools list */
-        PR_Lock(pool_global_stats.lock);
-        newpool->next = pool_global_stats.poolList;
-        pool_global_stats.poolList = newpool;
-        ++pool_global_stats.createCnt;
-#ifdef PER_POOL_STATISTICS
-        newpool->stats.poolId = pool_global_stats.createCnt;
-#endif /* PER_POOL_STATISTICS */
-        PR_Unlock(pool_global_stats.lock);
-
-    }
-    else {
-        //ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_1));
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-
-    return (pool_handle_t *)newpool;
-}
-
-/*
- * pool_mark - get mark for subsequent recycle
- *
- * This function returns a value that can be used to free all pool
- * memory which is subsequently allocated, without freeing memory
- * that has already been allocated when pool_mark() is called.
- * The pool_recycle() function is used to free the memory allocated
- * since pool_mark() was called.
- *
- * This function may be called several times before pool_recycle()
- * is called, but some care must be taken not to pass an invalid
- * mark value to pool_recycle(), which would cause all pool memory
- * to be freed.  A mark value becomes invalid when pool_recycle is
- * called with a previously returned mark value.
- */
-NSAPI_PUBLIC void *
-pool_mark(pool_handle_t *pool_handle)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-
-    PR_ASSERT(pool != NULL);
-
-    if (pool == NULL)
-        return NULL;
-
-#ifdef PER_POOL_STATISTICS
-    pool->stats.thread = PR_GetCurrentThread();
-#endif /* PER_POOL_STATISTICS */
-
-    /* Never return end as it points outside the block */
-    if (pool->curr_block->start == pool->curr_block->end)
-        return pool->curr_block;
-
-    return (void *)(pool->curr_block->start);
-}
-
-/*
- * pool_recycle - recycle memory in a pool
- *
- * This function returns all the allocated memory for a pool back to
- * a free list associated with the pool. It is like pool_destroy() in
- * the sense that all data structures previously allocated from the
- * pool are freed, but it keeps the memory associated with the pool,
- * and doesn't actually destroy the pool.
- *
- * The "mark" argument can be a value previously returned by
- * pool_mark(), in which case the pool is returned to the state it
- * was in when pool_mark() was called, or it can be NULL, in which
- * case the pool is completely recycled.
- */
-NSAPI_PUBLIC void
-pool_recycle(pool_handle_t *pool_handle, void *mark)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-    block_t *tmp_blk;
-    unsigned long blen;
-
-    PR_ASSERT(pool != NULL);
-
-    if (pool == NULL)
-        return;
-
-    /* Fix up curr_block.  There should always be a curr_block. */
-    tmp_blk = pool->curr_block;
-    PR_ASSERT(tmp_blk != NULL);
-
-    /* Start with curr_block, then scan blocks on used_blocks list */
-    for (;;) {
-
-        /* Check if the mark is at the end of this block */
-        if (tmp_blk == mark) {
-            pool->curr_block = tmp_blk;
-            break;
-        }
-
-        /* Look for a block containing the mark */
-        if (POOL_PTR_IN_BLOCK(tmp_blk, mark)) {
-
-            /* Reset block start pointer to marked spot */
-            if (tmp_blk == pool->curr_block) {
-                blen = tmp_blk->start - (char *)mark;
-            } else {
-                blen = tmp_blk->end - (char *)mark;
-            }
-            pool->size -= blen;
-            PR_ASSERT(pool->size >= 0);
-            tmp_blk->start = (char *)mark;
-            pool->curr_block = tmp_blk;
-            break;
-        }
-
-        /* Reset block start pointer to base of block */
-        if (tmp_blk == pool->curr_block) {
-            /* Count just the allocated length in the current block */
-            blen = tmp_blk->start - tmp_blk->data;
-        }
-        else {
-            /* Count the entire size of a used_block */
-            blen = tmp_blk->end - tmp_blk->data;
-        }
-        tmp_blk->start = tmp_blk->data;
-        pool->size -= blen;
-        PR_ASSERT(pool->size >= 0);
-
-        /*
-         * If there are no more used blocks after this one, then set
-         * this block up as the current block and return.
-         */
-        if (pool->used_blocks == NULL) {
-            PR_ASSERT(mark == NULL);
-            pool->curr_block = tmp_blk;
-            break;
-        }
-
-        /* Otherwise free this block one way or another */
-
-        /* Add block length to total retained length and check limit */
-        if ((pool->free_size + blen) <= pool_config.retain_size &&
-            pool->free_num < pool_config.retain_num) {
-
-            /* Retain block on pool free list */
-            /*
-             * XXX hep - could sort blocks on free list in order
-             * ascending size to get "best fit" allocation in
-             * _create_block(), but the default block size is large
-             * enough that fit should rarely be an issue.
-             */
-            tmp_blk->next = pool->free_blocks;
-            pool->free_blocks = tmp_blk;
-            pool->free_size += blen;
-            ++pool->free_num;
-        }
-        else {
-            /* Limit exceeded - free block */
-            _free_block(tmp_blk);
-        }
-
-#ifdef PER_POOL_STATISTICS
-        ++pool->stats.blkFree;
-#endif /* PER_POOL_STATISTICS */
-
-        /* Remove next block from used blocks list */
-        tmp_blk = pool->used_blocks;
-        pool->used_blocks = tmp_blk->next;
-    }
-}
-
-NSAPI_PUBLIC void
-pool_destroy(pool_handle_t *pool_handle)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-    block_t *tmp_blk;
-
-    PR_ASSERT(pool != NULL);
-
-    if (pool == NULL)
-        return;
-
-    if (pool->curr_block)
-        _free_block(pool->curr_block);
-
-    while(pool->used_blocks) {
-        tmp_blk = pool->used_blocks;
-        pool->used_blocks = tmp_blk->next;
-        _free_block(tmp_blk);
-    }
-
-    while(pool->free_blocks) {
-        tmp_blk = pool->free_blocks;
-        pool->free_blocks = tmp_blk->next;
-        _free_block(tmp_blk);
-    }
-
-    {
-        pool_t **ppool;
-
-        /* Remove from the known pools list */
-        PR_Lock(pool_global_stats.lock);
-        for (ppool = &pool_global_stats.poolList;
-             *ppool; ppool = &(*ppool)->next) {
-            if (*ppool == pool) {
-                ++pool_global_stats.destroyCnt;
-                *ppool = pool->next;
-                break;
-            }
-        }
-        PR_Unlock(pool_global_stats.lock);
-    }
-
-#ifdef POOL_ZERO_DEBUG
-    memset(pool, POOL_ZERO_DEBUG, sizeof(pool));
-#endif /* POOL_ZERO_DEBUG */
-
-    PERM_FREE(pool);
-
-    return;
-}
-
-
-NSAPI_PUBLIC void *
-pool_malloc(pool_handle_t *pool_handle, size_t size)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-    block_t *curr_block;
-    long reqsize, blocksize;
-    char *ptr;
-
-    if (pool == NULL)
-        return PERM_MALLOC(size);
-
-    reqsize = ALIGN(size);
-    if (reqsize == 0) {
-        /* Assign a unique address to each 0-byte allocation */
-        reqsize = WORD_SIZE;
-    }
-
-    curr_block = pool->curr_block;
-    ptr = curr_block->start;
-    curr_block->start += reqsize;
-
-    /* does this fit into the last allocated block? */
-    if (curr_block->start > curr_block->end) {
-
-        /* Did not fit; time to allocate a new block */
-
-        curr_block->start -= reqsize;  /* keep structs in tact */
-
-        /* Count unallocated bytes in current block in pool size */
-        pool->size += curr_block->end - curr_block->start;
-        PR_ASSERT(pool->size >= 0);
-#ifdef PER_POOL_STATISTICS
-        if (pool->size > pool->stats.maxAlloc) {
-            pool->stats.maxAlloc = pool->size;
-        }
-#endif /* PER_POOL_STATISTICS */
-
-        /* Move current block to used block list */
-        curr_block->next = pool->used_blocks;
-        pool->used_blocks = curr_block;
-
-        /* Allocate a chunk of memory which is at least block_size bytes */
-        blocksize = reqsize;
-        if (blocksize < pool_config.block_size)
-            blocksize = pool_config.block_size;
-
-        curr_block = _create_block(pool, blocksize);
-        pool->curr_block = curr_block;
-
-        if (curr_block == NULL) {
-            //ereport(LOG_CATASTROPHE,
-            //        XP_GetAdminStr(DBT_poolMallocOutOfMemory_));
-            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-            return NULL;
-        }
-
-        ptr = curr_block->start;
-        curr_block->start += reqsize;
-    }
-
-    pool->size += reqsize;
-    PR_ASSERT(pool->size >= 0);
-
-#ifdef PER_POOL_STATISTICS
-    if (pool->size > pool->stats.maxAlloc) {
-        pool->stats.maxAlloc = pool->size;
-    }
-    ++pool->stats.allocCnt;
-    pool->stats.thread = PR_GetCurrentThread();
-#endif /* PER_POOL_STATISTICS */
-
-    return ptr;
-}
-
-NSAPI_PUBLIC void
-pool_free(pool_handle_t *pool_handle, void *ptr)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-
-    if (ptr == NULL)
-        return;
-
-    if (pool == NULL) {
-        PERM_FREE(ptr);
-        return;
-    }
-
-    PR_ASSERT(_ptr_in_pool(pool, ptr));
-
-#ifdef PER_POOL_STATISTICS
-
-    ++pool->stats.freeCnt;
-    pool->stats.thread = PR_GetCurrentThread();
-
-#endif /* PER_POOL_STATISTICS */
-
-    return;
-}
-
-NSAPI_PUBLIC void *
-pool_calloc(pool_handle_t *pool_handle, size_t nelem, size_t elsize)
-{
-    void *ptr;
-
-    if (pool_handle == NULL)
-        return calloc(1, elsize * nelem);
-
-    ptr = pool_malloc(pool_handle, elsize * nelem);
-    if (ptr)
-        memset(ptr, 0, elsize * nelem);
-    return ptr;
-}
-
-NSAPI_PUBLIC void *
-pool_realloc(pool_handle_t *pool_handle, void *ptr, size_t size)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-    void *newptr;
-    block_t *block_ptr;
-    size_t oldsize;
-
-    if (pool == NULL)
-        return PERM_REALLOC(ptr, size);
-
-    if ( (newptr = pool_malloc(pool_handle, size)) == NULL) 
-        return NULL;
-
-    /* With our structure we don't know exactly where the end
-     * of the original block is.  But we do know an upper bound
-     * which is a valid ptr.  Search the outstanding blocks
-     * for the block which contains this ptr, and copy...
-     */
-
-    if ( !(block_ptr = _ptr_in_pool(pool, ptr)) ) {
-        /* User is trying to realloc nonmalloc'd space! */
-        return newptr;
-    }
-
-    oldsize = block_ptr->end - (char *)ptr ;
-    if (oldsize > size)
-        oldsize = size;
-    memmove((char *)newptr, (char *)ptr, oldsize);
-
-    return newptr;
-}
-
-NSAPI_PUBLIC char *
-pool_strdup(pool_handle_t *pool_handle, const char *orig_str)
-{
-    char *new_str;
-    int len = strlen(orig_str);
-
-    if (pool_handle == NULL)
-        return PERM_STRDUP(orig_str);
-
-    new_str = (char *)pool_malloc(pool_handle, len+1);
-
-    if (new_str) 
-        memcpy(new_str, orig_str, len+1);
-
-    return new_str;
-}
-
-NSAPI_PUBLIC long
-pool_space(pool_handle_t *pool_handle)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-
-    return pool->size;
-}
-
-NSAPI_PUBLIC int pool_enabled()
-{
-    if (getThreadMallocKey() == -1)
-        return 0;
-
-    if (!systhread_getdata(getThreadMallocKey()))
-        return 0;
-
-    return 1;
-}
-
-#ifdef DEBUG
-NSAPI_PUBLIC void INTpool_assert(pool_handle_t *pool_handle, const void *ptr)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-
-    if (pool == NULL)
-        return;
-
-    PR_ASSERT(_ptr_in_pool(pool, ptr));
-}
-#endif
-
-NSAPI_PUBLIC pool_config_t *pool_getConfig(void)
-{
-    return &pool_config;
-}
-
-#ifdef POOL_GLOBAL_STATISTICS
-NSAPI_PUBLIC pool_global_stats_t *pool_getGlobalStats(void)
-{
-    return &pool_global_stats;
-}
-#endif /* POOL_GLOBAL_STATISTICS */
-
-#ifdef PER_POOL_STATISTICS
-NSAPI_PUBLIC pool_stats_t *pool_getPoolStats(pool_handle_t *pool_handle)
-{
-    pool_t *pool = (pool_t *)pool_handle;
-
-    if (pool == NULL)
-        return NULL;
-
-    return &pool->stats;
-}
-#endif /* PER_POOL_STATISTICS */
-
--- a/src/server/pool.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_POOL_H
-#define BASE_POOL_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * pool.h
- *
- * Module for handling memory allocations.
- *
- * Notes:
- * This module is used instead of the NSPR prarena module because the prarenas
- * did not fit as cleanly into the existing server.
- *
- * Mike Belshe
- * 10-02-95
- *
- */
-
-#ifndef NETSITE_H
-//include "netsite.h"
-#include "nsapi.h"
-#include "nspr.h"
-#endif /* !NETSITE_H */
-
-#ifndef BASE_PBLOCK_H
-//include "pblock.h"
-#endif /* !BASE_PBLOCK_H */
-
-#ifndef BASE_SESSION_H
-//#include "session.h"
-#endif /* !BASE_SESSION_H */
-
-#ifndef FRAME_REQ_H
-//include "frame/req.h"
-#endif /* !FRAME_REQ_H */
-
-/* --- Begin function prototypes --- */
-
-#ifdef INTNSAPI
-
-NSPR_BEGIN_EXTERN_C
-
-NSAPI_PUBLIC int INTpool_init(pblock *pb, Session *sn, Request *rq);
-
-#ifdef DEBUG_CACHES
-NSAPI_PUBLIC int INTpool_service_debug(pblock *pb, Session *sn, Request *rq);
-#endif
-
-NSAPI_PUBLIC pool_handle_t *INTpool_create(void);
-
-NSAPI_PUBLIC void *INTpool_mark(pool_handle_t *pool_handle);
-
-NSAPI_PUBLIC void INTpool_recycle(pool_handle_t *pool_handle, void *mark);
-
-NSAPI_PUBLIC void INTpool_destroy(pool_handle_t *pool_handle);
-
-NSAPI_PUBLIC int INTpool_enabled(void);
-
-NSAPI_PUBLIC void *INTpool_malloc(pool_handle_t *pool_handle, size_t size );
-
-NSAPI_PUBLIC void INTpool_free(pool_handle_t *pool_handle, void *ptr );
-
-NSAPI_PUBLIC 
-void *INTpool_calloc(pool_handle_t *pool_handle, size_t nelem, size_t elsize);
-
-NSAPI_PUBLIC 
-void *INTpool_realloc(pool_handle_t *pool_handle, void *ptr, size_t size );
-
-NSAPI_PUBLIC
-char *INTpool_strdup(pool_handle_t *pool_handle, const char *orig_str );
-
-#ifdef DEBUG
-NSAPI_PUBLIC void INTpool_assert(pool_handle_t *pool_handle, const void *ptr);
-#endif
-
-NSPR_END_EXTERN_C
-
-#define pool_init INTpool_init
-
-#ifdef DEBUG_CACHES
-#define pool_service_debug INTpool_service_debug
-#endif /* DEBUG_CACHES */
-
-#ifdef DEBUG
-#define POOL_ASSERT(pool, ptr) INTpool_assert(pool, ptr);
-#else
-#define POOL_ASSERT(pool, ptr)
-#endif
-
-#define pool_create INTpool_create
-#define pool_mark INTpool_mark
-#define pool_recycle INTpool_recycle
-#define pool_destroy INTpool_destroy
-#define pool_enabled INTpool_enabled
-#define pool_malloc INTpool_malloc
-#define pool_free INTpool_free
-#define pool_calloc INTpool_calloc
-#define pool_realloc INTpool_realloc
-#define pool_strdup INTpool_strdup
-
-#endif /* INTNSAPI */
-
-#endif /* !BASE_POOL_H_ */
--- a/src/server/pool_pvt.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_POOL_PVT_H
-#define BASE_POOL_PVT_H
-
-#ifndef BASE_POOL_H
-#include "pool.h"
-#endif /* BASE_POOL_H */
-
-/*
- * pool_pvt.h - private definitions for memory pools
- */
-
-/* Definitions */
-
-/*
- * Define PER_POOL_STATISTICS to get detailed statistics for each
- * pool.
- */
-#ifdef DEBUG
-#define PER_POOL_STATISTICS
-#endif
-
-/* Define POOL_GLOBAL_STATISTICS to get global pool statistics */
-#define POOL_GLOBAL_STATISTICS
-
-/*
- * When POOL_ZERO_DEBUG is defined, overwrite the contents of freed
- * pool data structures and memory with the POOL_ZERO_DEBUG byte value.
- */
-#ifdef DEBUG
-#define POOL_ZERO_DEBUG 0xa
-#endif
-
-/*
- * DEFAULT_BLOCK_SIZE specifies the minimum granularity, in bytes, used
- * in allocating memory from the heap for use with a pool.  A request
- * for more than DEFAULT_BLOCK_SIZE bytes from a pool will cause a block
- * of that size to be allocated from the heap.
- */
-#define DEFAULT_BLOCK_SIZE      (32 * 1024)
-
-/*
- * The pool_recycle() mechanism keeps a list of free blocks associated
- * with each pool, in order to avoid global locking when doing the
- * pool_recycle() operation, or when subsequently allocating memory
- * from the pool.  DEFAULT_RETENTION_SIZE and DEFAULT_RETENTION_NUM
- * specify the maximum number of bytes and blocks, respectively, that
- * will be kept on a per-pool free list.
- */
-#define DEFAULT_RETENTION_SIZE  (DEFAULT_BLOCK_SIZE * 2)
-#define DEFAULT_RETENTION_NUM   2
-
-/* WORD_SIZE 8 sets us up for 8 byte alignment. */
-#define WORD_SIZE       8   
-#undef  ALIGN
-#define ALIGN(x)        ( (x + WORD_SIZE-1) & (~(WORD_SIZE-1)) )
-
-/* Types */
-
-/*
- * pool_stats_t
- * This structure contains per pool statistics.
- */
-#ifdef PER_POOL_STATISTICS
-typedef struct pool_stats_t pool_stats_t;
-struct pool_stats_t {
-    PRUint32  poolId;      /* pool id */
-    PRUint32  maxAlloc;    /* maximum bytes ever used from pool */
-    PRUint32  allocCnt;    /* count of memory allocations from pool */
-    PRUint32  freeCnt;     /* count of pool memory free operations */
-    PRUint32  blkAlloc;    /* count of block allocations */
-    PRUint32  blkFree;     /* count of blocks freed (on pool_recycle) */
-    PRThread *thread;      /* last thread to use pool */
-    PRTime    created;     /* time of pool creation */
-};
-#endif /* PER_POOL_STATISTICS */
-
-typedef struct pool_config_t pool_config_t;
-struct pool_config_t {
-    PRUint32 block_size;   /* size of blocks to allocate */
-    PRUint32 retain_size;  /* maximum bytes kept on per-pool free list */
-    PRUint32 retain_num;   /* maximum blocks kept on per-pool free list */
-};
-
-#define POOL_CONFIG_INIT { \
-                           DEFAULT_BLOCK_SIZE,     /* block_size */ \
-                           DEFAULT_RETENTION_SIZE, /* retain_size */ \
-                           DEFAULT_RETENTION_NUM,  /* retain_num */ \
-                         }
-
-/*
- * block_t
- * When the user allocates space, a DEFAULT_BLOCK_SIZE (or larger) block
- * is created in the pool.  This block is used until all the space is
- * eaten within it.  When all the space is gone, a new block is created.
- */
-typedef struct block_t block_t;
-struct block_t {
-    char    *data;              /* the real alloc'd space */
-    char    *start;             /* first free byte in block */
-    char    *end;               /* ptr to end of block */
-    block_t *next;              /* ptr to next block */
-};
-
-#define POOL_PTR_IN_BLOCK(blk, ptr) \
-    (((char *)(ptr) < (blk)->end) && ((char *)(ptr) >= (blk)->data))
-
-/*
- * pool_t
- * A pool is a collection of blocks.  The blocks consist of multiple 
- * allocations of memory, but a single allocation cannot be freed by
- * itself.  Once the memory is allocated it is allocated until the
- * entire pool is freed.
- */
-typedef struct pool_t pool_t;
-struct pool_t {
-    block_t  *curr_block;       /* current block being used */
-    block_t  *used_blocks;      /* blocks that are all used up */
-    block_t  *free_blocks;      /* blocks that are free */
-    PRUint32  free_size;        /* number of bytes in free_blocks */
-    PRUint32  free_num;         /* number of blocks in free_blocks */
-    size_t    size;             /* size of memory in pool */
-    pool_t   *next;             /* known_pools list */
-#ifdef PER_POOL_STATISTICS
-    pool_stats_t stats;         /* statistics for this pool */
-#endif /* PER_POOL_STATISTICS */
-};
-
-typedef struct pool_global_stats_t pool_global_stats_t;
-struct pool_global_stats_t {
-    PRLock   *lock;        /* lock for access to poolList */
-    pool_t   *poolList;    /* list of known pools */
-    PRUint32  createCnt;   /* count of pools created */
-    PRUint32  destroyCnt;  /* count of pools destroyed */
-#ifdef POOL_GLOBAL_STATISTICS
-    PRUint32  blkAlloc;    /* count of block allocations from heap */
-    PRUint32  blkFree;     /* count of blocks freed to heap */
-#endif /* POOL_GLOBAL_STATISTICS */
-};
-
-/* Private functions for inspecting pool configuration/statistics */
-
-NSAPI_PUBLIC pool_config_t *pool_getConfig(void);
-
-NSAPI_PUBLIC pool_global_stats_t *pool_getGlobalStats(void);
-
-#ifdef PER_POOL_STATISTICS
-NSAPI_PUBLIC pool_stats_t *pool_getPoolStats(pool_handle_t *pool_handle);
-#endif
-
-#endif /* BASE_POOL_PVT_H */
--- a/src/server/protocol.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "protocol.h"
-
-#include "pblock.h"
-#include "pool.h"
-#include "session.h"
-#include "io.h"
-
-#include "strbuf.h"
-
-
-void protocol_status(Session *sn, Request *rq, int n, const char *m) {
-    rq->status_num = n;
-
-    const char *msg = m ? m : protocol_status_message(n);
-
-    pb_param *pp = pblock_removekey(pb_key_status, rq->srvhdrs);
-    if (pp != NULL) {
-        param_free(pp);
-    }
-
-    pp = pblock_key_param_create(rq->srvhdrs, pb_key_status, msg, strlen(msg));
-    pblock_kpinsert(pb_key_status, pp, rq->srvhdrs);
-}
-
-
-/*
- * http_status_message from Open Webserver (frame/http.cpp)
- * TODO: replace, use sstr_t
- */
-NSAPI_PUBLIC const char * protocol_status_message (int code)
-{
-    const char *r;
-
-    switch (code)
-    {
-        case PROTOCOL_CONTINUE : // 100
-            r = "Continue";
-            break;
-        case PROTOCOL_SWITCHING: //101
-            r = "Switching Protocols";
-            break;
-        case PROTOCOL_OK: // 200
-            r = "OK";
-            break;
-        case PROTOCOL_CREATED: // 201
-            r = "Created";
-            break;
-        case PROTOCOL_ACCEPTED: // 202
-            r = "Accepted";
-            break;
-        case PROTOCOL_NONAUTHORITATIVE: // 203
-            r = "Non-Authoritative Information";
-            break;
-        case PROTOCOL_NO_CONTENT: //204
-        /* There is another define to PROTOCOL_NO_RESPONSE for 204 in nsapi.h
-           The spec maps this to No Content.
-           Hence cahnging this to No Content
-        */
-            r = "No Content";
-            break;
-        case PROTOCOL_RESET_CONTENT: // 205
-            r = "Reset Content";
-            break;
-        case PROTOCOL_PARTIAL_CONTENT: // 206
-            r = "Partial Content";
-            break;
-        case PROTOCOL_MULTI_STATUS: // 207
-            r = "Multi Status";
-            break;
-        case PROTOCOL_MULTIPLE_CHOICES: // 300
-            r = "Multiple Choices";
-            break;
-        case PROTOCOL_MOVED_PERMANENTLY: // 301
-            r = "Moved Permanently";
-            break;
-        case PROTOCOL_REDIRECT:          // 302
-            r = "Moved Temporarily"; /* The spec actually says "Found" */
-            break;
-        case PROTOCOL_SEE_OTHER:         // 303
-            r = "See Other";
-            break;
-        case PROTOCOL_NOT_MODIFIED:      // 304
-            r = "Use local copy";    /* The spec actually says "Not Modified" */
-            break;
-        case PROTOCOL_USE_PROXY:         // 305
-            r = "Use Proxy";
-            break;
-        case PROTOCOL_TEMPORARY_REDIRECT: // 307
-            r = "Temporary Redirect";
-            break;
-        case PROTOCOL_BAD_REQUEST:        // 400
-            r = "Bad request";
-            break;
-        case PROTOCOL_UNAUTHORIZED:       // 401
-            r = "Unauthorized";
-            break;
-        case PROTOCOL_PAYMENT_REQUIRED:   // 402
-            r = "Payment Required";
-            break;
-        case PROTOCOL_FORBIDDEN:          // 403
-            r = "Forbidden";
-            break;
-        case PROTOCOL_NOT_FOUND:         // 404
-            r = "Not found";
-            break;
-        case PROTOCOL_METHOD_NOT_ALLOWED: // 405                /* HTTP/1.1 */
-            r = "Method Not Allowed";
-            break;
-        case PROTOCOL_NOT_ACCEPTABLE: // 406                /* HTTP/1.1 */
-            r = "Not Acceptable";
-            break;
-        case PROTOCOL_PROXY_UNAUTHORIZED: // 407
-            r = "Proxy Authentication Required";
-            break;
-        case PROTOCOL_REQUEST_TIMEOUT:    // 408            /* HTTP/1.1 */
-            r = "Request Timeout";
-            break;
-        case PROTOCOL_CONFLICT:           // 409
-            r = "Conflict";                         /* HTTP/1.1 */
-            break;
-        case PROTOCOL_GONE:           // 410
-            r = "Gone";                         /* HTTP/1.1 */
-            break;
-        case PROTOCOL_LENGTH_REQUIRED:    // 411                /* HTTP/1.1 */
-            r = "Length Required";
-            break;
-        case PROTOCOL_PRECONDITION_FAIL:  // 412                /* HTTP/1.1 */
-            r = "Precondition Failed";
-            break;
-        case PROTOCOL_ENTITY_TOO_LARGE:   // 413                /* HTTP/1.1 */
-            r = "Request Entity Too Large";
-            break;
-        case PROTOCOL_URI_TOO_LARGE:      // 414                /* HTTP/1.1 */
-            r = "Request-URI Too Large";
-            break;
-        case PROTOCOL_UNSUPPORTED_MEDIA_TYPE: // 415
-            r = "Unsupported Media Type";
-            break;
-        case PROTOCOL_REQUESTED_RANGE_NOT_SATISFIABLE: // 416
-            r = "Requested range not satisfiable";
-            break;
-        case PROTOCOL_EXPECTATION_FAILED:     // 417
-            r = "Expectation Failed";
-            break;
-        case PROTOCOL_LOCKED:     // 423
-            r = "Locked";
-            break;
-        case PROTOCOL_FAILED_DEPENDENCY:     // 424
-            r = "Failed Dependency";
-            break;
-        case PROTOCOL_SERVER_ERROR:           // 500
-            r = "Server Error";           /* The spec actually says "Internal Server Error" */
-            break;
-        case PROTOCOL_NOT_IMPLEMENTED:        // 501
-            r = "Not Implemented";
-            break;
-        case PROTOCOL_BAD_GATEWAY:            // 502
-            r = "Bad Gateway";
-            break;
-        case PROTOCOL_SERVICE_UNAVAILABLE:    // 503
-            r = "Service Unavailable";
-            break;
-        case PROTOCOL_GATEWAY_TIMEOUT:        // 504            /* HTTP/1.1 */
-            r = "Gateway Timeout";
-            break;
-        case PROTOCOL_VERSION_NOT_SUPPORTED:  // 505            /* HTTP/1.1 */
-            r = "HTTP Version Not Supported";
-            break;
-        case PROTOCOL_INSUFFICIENT_STORAGE:  // 507
-            r = "Insufficient Storage";
-            break;
-        default:
-            switch (code / 100)
-            {
-                case 1:
-                    r = "Information";
-                    break;
-                case 2:
-                    r = "Success";
-                    break;
-                case 3:
-                    r = "Redirect";
-                    break;
-                case 4:
-                    r = "Client error";
-                    break;
-                case 5:
-                    r = "Server error";
-                    break;
-                default:
-                    r = "Unknown reason";
-                    break;
-            }
-            break;
-    }
-
-    return r;
-}
-
-
-void add_http_status_line(sbuf_t *out, pool_handle_t *pool, Request *rq) {
-    sbuf_write(out, "HTTP/1.1 ", 9);
-
-    char *status_code_str = pool_malloc(pool, 8);
-    int sc_len = snprintf(status_code_str, 8, "%d ", rq->status_num);
-    sbuf_write(out, status_code_str, sc_len);
-    
-    char *scmsg = pblock_findkeyval(pb_key_status, rq->srvhdrs);
-    sbuf_write(out, scmsg, strlen(scmsg));
-
-    sbuf_write(out, "\r\n", 2);
-}
-
-void add_http_response_header(sbuf_t *out, Request *rq) {
-    pblock   *h = rq->srvhdrs;
-    pb_entry *p;
-
-    for(int i=0;i<h->hsize;i++) {
-        p = h->ht[i];
-        while(p != NULL) {
-            /* from http.cpp */
-            const pb_key *key = PARAM_KEY(p->param);
-            if (key == pb_key_status || key == pb_key_server || key == pb_key_date) {
-                /* Skip internal Status:, Server:, and Date: information */
-                p = p->next;
-                continue;
-            }
-            /* end http.cpp */
-
-            char *name  = p->param->name;
-            char *value = p->param->value;
-
-            /* make first char of name uppercase */
-            if(name[0] > 90) {
-                name[0] -= 32;
-            }
-
-            sbuf_write(out, name, strlen(name));
-            sbuf_write(out, ": ", 2);
-            sbuf_write(out, value, strlen(value));
-            sbuf_write(out, "\r\n", 2);
-
-            p = p->next;
-        }
-    }
-}
-
-int http_start_response(Session *sn, Request *rq) {
-    int fd = ((SystemIOStream*)sn->csd)->fd;
-
-    /* set socket blocking */
-    int flags;
-    flags = fcntl(fd, F_GETFL, 0);
-    fcntl(fd, F_SETFL, flags ^ O_NONBLOCK);
-
-    /* iovec output buffer */
-    sbuf_t *out = sbuf_new(512);
-
-    /* add the http status line to the output buffer */
-    add_http_status_line(out, sn->pool, rq);
-
-    /* add server header */
-    sbuf_write(out, "Server: WS uap-dev\r\n", 20);
-
-    /* add header from rq->srvhdrs */
-    add_http_response_header(out, rq);
-
-    /* response header end */
-    sbuf_write(out, "\r\n", 2);
-
-    /* flush buffer to the socket */
-    write(fd, out->ptr, out->length);
-    sbuf_free(out);
-    
-    rq->senthdrs = 1;
-}
-
-int request_header(char *name, char **value, Session *sn, Request *rq) {
-    const pb_key *key = pblock_key(name);
-    pb_param *pp = pblock_findkey(key, rq->headers);
-    if(pp != NULL) {
-        value = &pp->value;
-        return REQ_PROCEED;
-    } else {
-        return REQ_ABORTED;
-    }
-}
--- a/src/server/protocol.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTTP_H
-#define	HTTP_H
-
-#include "nsapi.h"
-#include "io.h"
-#include <sys/uio.h>
-#include "strbuf.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-void protocol_status(Session *sn, Request *rq, int n, const char *m);
-const char* protocol_status_message(int code);
-
-void add_http_status_line(sbuf_t *out, pool_handle_t *pool, Request *rq);
-void add_http_response_header(sbuf_t *out, Request *rq);
-
-int http_start_response(Session *sn, Request *rq);
-
-int request_header(char *name, char **value, Session *sn, Request *rq);
-
-#define sbuf_write(out, buf, len) sbuf_append(out, sstrn(buf, len))
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* HTTP_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/public/nsapi.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,1342 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PUBLIC_NSAPI_H
+#define PUBLIC_NSAPI_H
+
+/*
+ * File:        nsapi.h
+ *
+ * Description:
+ *
+ *      This file defines an interface for extending the server with
+ *      in-process plug-ins.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* NSAPI version defined by this header file */
+#define NSAPI_VERSION 303
+
+/* Define USE_NSAPI_VERSION to use a specific NSAPI version at compile time */
+#ifdef USE_NSAPI_VERSION
+#if USE_NSAPI_VERSION < 300 || USE_NSAPI_VERSION > NSAPI_VERSION
+#error This header file does not support the requested NSAPI version
+#else
+#undef NSAPI_VERSION
+#define NSAPI_VERSION USE_NSAPI_VERSION
+#endif
+#endif
+
+/* --- Begin native platform configuration definitions --- */
+
+#if !defined(XP_WIN32) && !defined(XP_UNIX)
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+#define XP_WIN32
+#else
+#define XP_UNIX
+#endif
+#endif
+
+#ifdef XP_UNIX
+#define NSAPI_PUBLIC
+#define ZERO(ptr, len) memset(ptr, 0, len)
+#ifdef AIX
+#define TCPLEN_T size_t
+#endif
+#ifdef HPUX
+#define TCPLEN_T int
+#endif
+#ifndef TCPLEN_T
+#define TCPLEN_T socklen_t
+#endif
+#endif /* XP_UNIX */
+
+#ifdef XP_WIN32
+#define NSAPI_PUBLIC __declspec(dllexport)
+struct iovec {
+    char *iov_base;
+    unsigned iov_len;
+};
+#ifndef S_ISDIR
+#define S_ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(mode) ((mode & S_IFMT) == S_IFREG)
+#endif
+#ifndef S_ISLNK
+#define S_ISLNK(x) (0)
+#endif
+#define caddr_t PCHAR
+#define NEED_STRCASECMP
+#define NEED_STRNCASECMP
+#define ZERO(ptr, len) ZeroMemory(ptr, len)
+#define TCPLEN_T int
+#endif /* XP_WIN32 */
+
+/* --- End native platform configuration definitions --- */
+
+/* --- Begin miscellaneous definitions --- */
+
+/* Used in some places as a length limit on error messages */
+#define MAGNUS_ERROR_LEN 1024
+
+/* Carriage return and line feed */
+#define CR 13
+#define LF 10
+#ifdef XP_WIN32
+#define ENDLINE "\r\n"
+#else
+#define ENDLINE "\n"
+#endif
+
+/* mime.types file identification line */
+#define NCC_MT_MAGIC "#--Netscape Communications Corporation MIME Information"
+#define NCC_MT_MAGIC_LEN 55
+
+/* The character which separates extensions with cinfo_find */
+#define CINFO_SEPARATOR '.'
+
+/* The maximum length of a line in a mime.types file */
+#define CINFO_MAX_LEN 1024
+
+/* The maximum length of an error message */
+#define MAX_ERROR_LEN 4096
+
+/*
+ * A warning is a minor mishap, such as a 404 being issued.
+ */
+#define LOG_WARN 0
+
+/* 
+ * A misconfig is when there is a syntax error or permission violation in
+ * a config file.
+ */
+#define LOG_MISCONFIG 1
+
+/* 
+ * Security warnings are issued when authentication fails, or a host is
+ * given a 403 return code.
+ */
+#define LOG_SECURITY 2
+
+/*
+ * A failure is when a request could not be fulfilled due to an internal
+ * problem, such as a CGI script exiting prematurely, or a filesystem 
+ * permissions problem.
+ */
+#define LOG_FAILURE 3
+
+/*
+ * A catastrophe is a fatal server error such as running out of
+ * memory or processes, or a system call failing, or even a server crash. 
+ * The server child cannot recover from a catastrophe.
+ */
+#define LOG_CATASTROPHE 4
+
+/*
+ * Informational message, of no concern.
+ */
+#define LOG_INFORM 5
+
+/*
+ * Internal diagnostic message.
+ */
+#define LOG_VERBOSE 6
+
+/*
+ * The time format to use in the error log
+ */
+#define ERR_TIMEFMT "[%d/%b/%Y:%H:%M:%S]"
+
+
+/* The fd you will get if you are reporting errors to SYSLOG */
+#define ERRORS_TO_SYSLOG NULL
+
+/* Return codes from file I/O routines */
+#define IO_OKAY 1
+#define IO_ERROR -1
+#define IO_EOF 0
+#define NETBUF_EOF      -1
+#define NETBUF_ERROR    -2
+#define NETBUF_FULL     -3
+
+/* The disk page size on this machine. */
+#define FILE_BUFFERSIZE 4096
+
+#ifdef XP_UNIX
+
+#define FILE_PATHSEP '/'
+#define FILE_PARENT "../"
+
+#elif defined(XP_WIN32)
+
+#define FILE_PATHSEP '/'
+#define FILE_PARENT "..\\"
+
+#endif /* XP_WIN32 */
+
+#define NET_INFINITE_TIMEOUT 0
+#define NET_ZERO_TIMEOUT -1
+
+#ifdef USE_REGEX
+/* WILDPAT uses regular expressions */
+#define WILDPAT_VALID(exp)              regexp_valid(exp)
+#define WILDPAT_MATCH(str, exp)         regexp_match(str, exp)
+#define WILDPAT_CMP(str, exp)           regexp_cmp(str, exp)
+#define WILDPAT_CASECMP(str, exp)       regexp_casecmp(str, exp)
+#define WILDPAT_USES_REGEXP              1
+#else
+/* WILDPAT uses shell expressions */
+#define WILDPAT_VALID(exp)              shexp_valid(exp)
+#define WILDPAT_MATCH(str, exp)         shexp_match(str, exp)
+#define WILDPAT_CMP(str, exp)           shexp_cmp(str, exp)
+#define WILDPAT_CASECMP(str, exp)       shexp_casecmp(str, exp)
+#define WILDPAT_USES_SHEXP              1
+#endif
+
+/* Define return codes from WILDPAT_VALID */
+#define NON_WILDPAT     -1              /* exp is ordinary string */
+#define INVALID_WILDPAT -2              /* exp is an invalid pattern */
+#define VALID_WILDPAT   1               /* exp is a valid pattern */
+
+/* Define return codes from regexp_valid and shexp_valid */
+#define NON_SXP         NON_WILDPAT     /* exp is an ordinary string */
+#define INVALID_SXP     INVALID_WILDPAT /* exp is an invalid shell exp */
+#define VALID_SXP       VALID_WILDPAT   /* exp is a valid shell exp */
+
+#define NON_REGEXP      NON_SXP
+#define INVALID_REGEXP  INVALID_SXP
+#define VALID_REGEXP    VALID_SXP
+
+#define SYSTHREAD_DEFAULT_PRIORITY 16
+
+/* The longest line in the configuration file */
+#define CONF_MAXLEN 16384
+
+#define HTTP_DATE_LEN 30
+#define HTTP_DATE_FMT "%a, %d %b %Y %T GMT"
+
+/* HTTP status codes */
+#define PROTOCOL_CONTINUE 100
+#define PROTOCOL_SWITCHING 101
+#define PROTOCOL_OK 200
+#define PROTOCOL_CREATED 201
+#define PROTOCOL_ACCEPTED 202
+#define PROTOCOL_NONAUTHORITATIVE 203
+#define PROTOCOL_NO_RESPONSE 204
+#define PROTOCOL_NO_CONTENT 204
+#define PROTOCOL_RESET_CONTENT 205
+#define PROTOCOL_PARTIAL_CONTENT 206
+#define PROTOCOL_MULTI_STATUS 207
+#define PROTOCOL_MULTIPLE_CHOICES 300
+#define PROTOCOL_MOVED_PERMANENTLY 301
+#define PROTOCOL_REDIRECT 302
+#define PROTOCOL_SEE_OTHER 303
+#define PROTOCOL_NOT_MODIFIED 304
+#define PROTOCOL_USE_PROXY 305
+#define PROTOCOL_TEMPORARY_REDIRECT 307
+#define PROTOCOL_BAD_REQUEST 400
+#define PROTOCOL_UNAUTHORIZED 401
+#define PROTOCOL_PAYMENT_REQUIRED 402
+#define PROTOCOL_FORBIDDEN 403
+#define PROTOCOL_NOT_FOUND 404
+#define PROTOCOL_METHOD_NOT_ALLOWED 405
+#define PROTOCOL_NOT_ACCEPTABLE 406
+#define PROTOCOL_PROXY_UNAUTHORIZED 407
+#define PROTOCOL_REQUEST_TIMEOUT 408
+#define PROTOCOL_CONFLICT 409
+#define PROTOCOL_GONE 410
+#define PROTOCOL_LENGTH_REQUIRED 411
+#define PROTOCOL_PRECONDITION_FAIL 412
+#define PROTOCOL_ENTITY_TOO_LARGE 413
+#define PROTOCOL_URI_TOO_LARGE 414
+#define PROTOCOL_UNSUPPORTED_MEDIA_TYPE 415
+#define PROTOCOL_REQUESTED_RANGE_NOT_SATISFIABLE 416
+#define PROTOCOL_EXPECTATION_FAILED 417
+#define PROTOCOL_LOCKED 423
+#define PROTOCOL_FAILED_DEPENDENCY 424
+#define PROTOCOL_SERVER_ERROR 500
+#define PROTOCOL_NOT_IMPLEMENTED 501
+#define PROTOCOL_BAD_GATEWAY 502
+#define PROTOCOL_SERVICE_UNAVAILABLE 503
+#define PROTOCOL_GATEWAY_TIMEOUT 504
+#define PROTOCOL_VERSION_NOT_SUPPORTED 505
+#define PROTOCOL_INSUFFICIENT_STORAGE 507
+
+#define PROTOCOL_VERSION_HTTP09 9
+#define PROTOCOL_VERSION_HTTP10 100
+#define PROTOCOL_VERSION_HTTP11 101
+#define CURRENT_PROTOCOL_VERSION PROTOCOL_VERSION_HTTP11
+
+/* Definitions for HTTP over SSL */
+#define HTTPS_PORT 443
+#define HTTPS_URL "https"
+
+/* Definitions for HTTP over TCP */
+#define HTTP_PORT 80
+#define HTTP_URL "http"
+
+
+#define REQ_MAX_LINE 4096
+    
+/*
+ * The REQ_ return codes. These codes are used to determine what the server
+ * should do after a particular module completes its task.
+ *
+ * Func type functions return these as do many internal functions.
+ */
+
+/* The function performed its task, proceed with the request */
+#define REQ_PROCEED 0
+/* The entire request should be aborted: An error occurred */
+#define REQ_ABORTED -1
+/* The function performed no task, but proceed anyway */
+#define REQ_NOACTION -2
+/* Tear down the session and exit */
+#define REQ_EXIT -3
+/* Restart the entire request-response process */
+#define REQ_RESTART -4
+/* Too busy to execute this now */
+#define REQ_TOOBUSY -5
+
+
+/**** NSAPI extensions ****/
+
+/* The function is still in progress (async extension) */
+#define REQ_PROCESSING -8
+
+/**** END NSAPI extensions ****/
+
+
+/* --- End miscellaneous definitions --- */
+
+/* --- Begin native platform includes --- */
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#include <sys/file.h>
+#include <alloca.h> /* new */
+#ifndef HPUX
+#include <sys/select.h>
+#endif
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <netinet/in.h>
+#endif /* XP_UNIX */
+
+#ifdef XP_WIN32
+#include <wtypes.h>
+#include <winbase.h>
+#include <direct.h>
+#include <winsock.h>
+#endif /* XP_WIN32 */
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+/* --- End native platform includes --- */
+
+/* --- Begin type definitions --- */
+
+/* NOTE: both SYS_FILE and SYS_NETFD are actually NSPR PRFileDesc * and can */
+/*       be used with NSPR API calls (after casting them to PRFileDesc *) */
+
+#ifndef SYS_FILE_T
+typedef void *SYS_FILE;
+#define SYS_FILE_T void *
+#endif /* !SYS_FILE_T */
+
+#define SYS_ERROR_FD ((SYS_FILE)-1)
+
+#ifndef SYS_NETFD_T
+typedef void *SYS_NETFD;
+#define SYS_NETFD_T void *
+#endif /* !SYS_NETFD_T */
+
+/* Error value for a SYS_NETFD */
+#ifndef SYS_NET_ERRORFD
+#define SYS_NET_ERRORFD ((SYS_NETFD)-1)
+#endif /* !SYS_NET_ERRORFD */
+
+/*
+ * These structures were originally defined in nsapi.h, but those definitions
+ * were removed in iPlanet Web Server 4.0.  The contents of these structures
+ * are now private to the server implementation and must not be accessed
+ * directly.  Instead, use the objset_*, object_*, directive_table_*, and
+ * directive_* accessor functions.
+ */
+typedef struct directive directive;
+typedef struct dtable dtable;
+typedef struct httpd_object httpd_object;
+typedef struct httpd_objset httpd_objset;
+
+/*
+ * Type:        filebuffer, filebuf_t
+ *
+ * Description:
+ *
+ *      This structure is used to represent a buffered file.  On some
+ *      systems the file may be memory-mapped.  A filebuffer is created
+ *      by filebuf_open(), and destroyed by filebuf_close().
+ *
+ * Notes:
+ *
+ *      Direct access to the members of this structure, not using
+ *      macros defined here, is discouraged.
+ *
+ *      The filebuf alias that used to be defined for this type was
+ *      found to conflict with a C++ class of the same name, so it
+ *      has been renamed to filebuf_t.
+ */
+typedef struct filebuffer filebuffer;
+
+/* Version of filebuffer when memory-mapped files are supported */
+struct filebuffer {
+    SYS_FILE fd;
+#ifdef XP_WIN32
+    HANDLE fdmap;
+#endif
+    caddr_t fp;
+    int len;
+
+    unsigned char *inbuf;
+    int cursize;
+
+    int pos;
+    const char *errmsg;
+};
+
+/* Return next character or IO_EOF */
+#define filebuf_getc(b) ((b)->pos == (b)->len ? IO_EOF : (int)((b)->fp)[(b)->pos++])
+
+#define filebuf_iseof(b) ((b)->pos == (b)->len)
+
+/* C++ streamio defines a filebuf class. */
+typedef filebuffer filebuf_t;
+
+#ifdef XP_WIN32
+/* Use a filebuffer to read data from a pipe */
+#define pipebuf_getc(b) \
+ ((b)->pos != (b)->cursize ? (int)((b)->inbuf[(b)->pos++]) : pipebuf_next(b,1))
+#endif /* XP_WIN32 */
+
+/*
+ * Type:        netbuf
+ *
+ * Description:
+ *
+ *      This structure is used to represent a buffered network socket.
+ *      It is created by netbuf_open(), and destroyed by netbuf_close().
+ *
+ * Notes:
+ *
+ *      Direct access to the members of this structure, not using
+ *      macros defined here, is discouraged.
+ *
+ *      The inbuf field used to be (unsigned char *), but is now
+ *      simply (char *).  The value returned by the netbuf_getc()
+ *      macro is (int).
+ */
+typedef struct netbuf netbuf;
+struct netbuf {
+    SYS_NETFD sd;
+
+    int pos, cursize, maxsize, rdtimeout;
+#ifdef XP_WIN32
+    CHAR address[64];
+#endif /* XP_WIN32 */
+    unsigned char *inbuf;
+    char *errmsg;
+#ifndef XP_WIN32
+    char address[64];
+#endif /* !XP_WIN32 */
+};
+
+/*
+ * netbuf_getc gets a character from the given network buffer and returns 
+ * it (as an integer).
+ * 
+ * It will return (int) IO_ERROR for an error and (int) IO_EOF for
+ * an error condition or EOF respectively.
+ */
+#define netbuf_getc(b) \
+ ((b)->pos != (b)->cursize ? (int)((b)->inbuf[(b)->pos++]) : netbuf_next(b,1))
+
+/*
+ * buffer_error returns the last error that occurred with buffer.  Don't use
+ * this unless you know an error occurred.  Independent of network/file type.
+ */
+#define buffer_error(b) ((b)->errmsg)
+
+/*
+ * Type:        sendfiledata
+ *
+ * Description:
+ *
+ *      This structure is used to pass arguments to the net_sendfile()
+ *      function.  offset and len may be set to 0 to transmit a file in its
+ *      entirety.
+ */
+typedef struct sendfiledata sendfiledata;
+struct sendfiledata {
+    SYS_FILE fd;         /* file to send */
+    size_t offset;       /* offset in file to start sending from */
+    size_t len;          /* number of bytes to send from file */
+    const void *header;  /* data to send before file */
+    int hlen;            /* number of bytes to send before file */
+    const void *trailer; /* data to send after file */
+    int tlen;            /* number of bytes to send after file */
+};
+
+/*
+ * Type:        NSAPIIOVec
+ *
+ * Description:
+ *
+ *      This structure is used to pass arguments to the net_writev()
+ *      and FilterWritevFunc() functions.  
+ */
+#ifdef _LP64
+typedef struct NSAPIIOVec NSAPIIOVec;
+struct NSAPIIOVec {
+    char *iov_base;
+    int iov_len;
+};
+#else
+typedef struct iovec NSAPIIOVec;
+#endif /* _LP64 */
+
+
+/*
+ * Type:        cinfo
+ *
+ * Description:
+ *
+ *      This is a structure that captures the information in the name/value
+ *      pairs on one line of a mime.types file.  A cinfo structure is
+ *      stored in the memory-resident database, indexed by each of the
+ *      file extensions specified in the "exts" name/value pair.  It
+ *      defines various attributes of resources with names containing
+ *      the specified file extensions.
+ *
+ * Notes:
+ *
+ *      Pointers to cinfo structures returned by this API may or may not
+ *      need to freed by the caller.  See the individual function
+ *      descriptions.
+ *
+ *      The strings referenced by the fields of cinfo structures returned
+ *      by this API should be considered read-only, and do not need to be
+ *      freed by the caller, even when the cinfo structure does.
+ */
+typedef struct cinfo cinfo;
+struct cinfo {
+    char *type;
+    char *encoding;
+    char *language;
+};
+
+
+typedef void* CONDVAR;
+typedef void *COUNTING_SEMAPHORE;
+typedef void* CRITICAL;
+
+#ifdef XP_UNIX
+typedef DIR* SYS_DIR;
+typedef struct dirent SYS_DIRENT;
+#endif /* XP_UNIX */
+
+#ifdef XP_WIN32
+
+typedef struct dirent_s dirent_s;
+struct dirent_s {
+    char *d_name;
+};
+
+typedef struct dir_s dir_s;
+struct dir_s {
+    HANDLE dp;
+    WIN32_FIND_DATA fdata;
+    dirent_s de;
+};
+
+typedef dir_s* SYS_DIR;
+typedef dirent_s SYS_DIRENT;
+
+#endif /* XP_WIN32 */
+
+typedef struct pb_param pb_param;
+struct pb_param {
+    char *name,*value;
+};
+
+typedef struct pb_entry pb_entry;
+struct pb_entry {
+    pb_param *param;
+    struct pb_entry *next;
+};
+
+typedef struct pblock pblock;
+struct pblock {
+    int hsize;
+    struct pb_entry **ht;
+};
+
+#ifndef POOL_HANDLE_T
+#define POOL_HANDLE_T
+typedef void *pool_handle_t;
+#endif
+
+#ifndef SEMAPHORE_T
+typedef void *SEMAPHORE;
+#define SEMAPHORE_T void *
+#endif /* !SEMAPHORE_T */
+
+#define SESSION_HASHSIZE 5
+
+typedef struct PListStruct_s PListStruct_s;
+typedef struct ACLListHandle ACLListHandle;
+
+#ifndef PR_AF_INET
+typedef union PRNetAddr PRNetAddr;
+#endif
+
+typedef struct Session Session;
+typedef struct Request Request;
+struct Session {
+    pblock *client;     /* client-specific information */
+
+    SYS_NETFD csd;      /* client file descriptor */
+    netbuf *inbuf;      /* input buffer */
+    int csd_open;
+
+    struct in_addr iaddr;
+
+    pool_handle_t *pool;
+
+    void *clauth;       /* v2 ACL client authentication information */
+    struct Session *next;
+    int fill;
+    struct sockaddr_in local_addr;      /* local addr for this session */
+
+    PListStruct_s *subject;
+    int ssl;            /* 0 = SSL OFF, 1 = SSL ON */
+    int clientauth;     /* 0 = client auth OFF, 1 = client auth ON */
+
+    PRNetAddr *pr_client_addr;
+    PRNetAddr *pr_local_addr;
+};
+
+/*
+ * FuncPtr is a pointer to an NSAPI SAF function
+ */
+
+#ifdef XP_UNIX
+typedef int Func(pblock *, Session *, Request *);
+#else /* XP_WIN32 */
+typedef int _cdecl Func(pblock *, Session *, Request *);
+#endif /* XP_WIN32 */
+
+typedef Func *FuncPtr;
+
+/*
+ * FuncStruct is a structure used in the static declaration of the 
+ * functions.  This static declaration is parsed into a hash table at 
+ * startup.
+ */
+
+typedef struct FuncStruct FuncStruct;
+
+struct FuncStruct {
+    const char * name;
+    FuncPtr func;
+    struct FuncStruct *next;
+    unsigned flags;
+    unsigned poolID;
+    unsigned pool_resolved;
+};
+
+/*
+ * VSInitFunc, VSDestroyFunc, VSDirectiveInitFunc and VSDirectiveDestroyFunc
+ */
+typedef struct VirtualServer VirtualServer;
+typedef int VSInitFunc(VirtualServer *incoming, const VirtualServer *current);
+typedef void VSDestroyFunc(VirtualServer *outgoing);
+typedef VSInitFunc *VSInitFuncPtr;
+typedef VSDestroyFunc *VSDestroyFuncPtr;
+typedef int VSDirectiveInitFunc(const directive *dir, VirtualServer *incoming, const VirtualServer *current);
+typedef void VSDirectiveDestroyFunc(const directive *dir, VirtualServer *outgoing);
+typedef VSDirectiveInitFunc *VSDirectiveInitFuncPtr;
+typedef VSDirectiveDestroyFunc *VSDirectiveDestroyFuncPtr;
+
+/*
+ * Filter is an opaque filter identifier
+ */
+typedef struct Filter Filter;
+
+/*
+ * FilterContext stores context associated with a particular filter layer
+ */
+
+typedef struct FilterContext FilterContext;
+
+struct FilterContext {
+    pool_handle_t *pool; /* pool context was allocated from */
+    Session *sn;         /* session being processed */
+    Request *rq;         /* request being processed */
+    void *data;          /* filter-defined private data */
+};
+
+/*
+ * FilterLayer represents one layer of a filter stack
+ */
+
+typedef struct FilterLayer FilterLayer;
+
+struct FilterLayer {
+    Filter *filter;         /* the filter at this layer in the filter stack */
+    FilterContext *context; /* context for the filter */
+    SYS_NETFD lower;        /* access to the next filter layer in the stack */
+};
+
+/*
+ * Function prototypes for filter methods
+ */
+typedef int (FilterInsertFunc)(FilterLayer *layer, pblock *pb);
+typedef void (FilterRemoveFunc)(FilterLayer *layer);
+typedef int (FilterFlushFunc)(FilterLayer *layer);
+typedef int (FilterReadFunc)(FilterLayer *layer, void *buf, int amount, int timeout);
+typedef int (FilterWriteFunc)(FilterLayer *layer, const void *buf, int amount);
+typedef int (FilterWritevFunc)(FilterLayer *layer, const NSAPIIOVec *iov, int iov_size);
+typedef int (FilterSendfileFunc)(FilterLayer *layer, sendfiledata *sfd);
+
+/*
+ * FilterMethods is passed to filter_create() to declare the filter methods for
+ * a new filter.  Each instance of the FilterMethods structure should be
+ * initialized using the FILTER_METHODS_INITIALIZER macro.
+ */
+
+typedef struct FilterMethods FilterMethods;
+
+struct FilterMethods {
+    size_t size;
+#if NSAPI_VERSION >= 302
+    FilterInsertFunc *insert;
+    FilterRemoveFunc *remove;
+    FilterFlushFunc *flush;
+    FilterReadFunc *read;
+    FilterWriteFunc *write;
+    FilterWritevFunc *writev;
+    FilterSendfileFunc *sendfile;
+#else
+    void *reserved1;
+    void *reserved2;
+    void *reserved3;
+    void *reserved4;
+    void *reserved5;
+    void *reserved6;
+    void *reserved7;
+#endif /* NSAPI_VERSION >= 302 */
+};
+
+#define FILTER_METHODS_INITIALIZER \
+{                                  \
+    sizeof(FilterMethods),         \
+    NULL, /* insert */             \
+    NULL, /* remove */             \
+    NULL, /* flush */              \
+    NULL, /* read */               \
+    NULL, /* write */              \
+    NULL, /* writev */             \
+    NULL  /* sendfile */           \
+}
+
+/*
+ * Filter order definitions for filter_create()
+ */
+#define FILTER_CONTENT_GENERATION       0xf0000
+#define FILTER_CONTENT_TRANSLATION_HIGH 0xa0000
+#define FILTER_CONTENT_TRANSLATION      0x90000
+#define FILTER_CONTENT_TRANSLATION_LOW  0x80000
+#define FILTER_CONTENT_CODING           0x50000
+#define FILTER_TRANSFER_CODING          0x40000
+#define FILTER_MESSAGE_CODING           0x30000
+#define FILTER_TRANSPORT_CODING         0x20000
+#define FILTER_NETWORK                  0x10000
+
+typedef struct shmem_s shmem_s;
+struct shmem_s {
+    void *data;   /* the data */
+#ifdef XP_WIN32
+    HANDLE fdmap;
+#endif /* XP_WIN32 */
+    int size;     /* the maximum length of the data */
+
+    char *name;   /* internal use: filename to unlink if exposed */
+    SYS_FILE fd;  /* internal use: file descriptor for region */
+};
+
+/* Define a handle for a thread */
+typedef void* SYS_THREAD;
+
+/* Define an error value for the thread handle */
+#define SYS_THREAD_ERROR NULL
+
+
+typedef struct conf_global_vars_s conf_global_vars_s;
+struct conf_global_vars_s {
+
+    /* What port we listen to */
+    int Vport;                                  /* OBSOLETE */
+#define server_portnum 80
+
+    /* What address to bind to */
+    char *Vaddr;                                /* OBSOLETE */
+
+    /* User to run as */
+    struct passwd *Vuserpw;
+
+    /* Directory to chroot to */
+    char *Vchr;
+
+    /* Where to log our pid to */
+    char *Vpidfn;
+
+#define pool_max conf_getglobals()->Vpool_max
+    int Vpool_max;
+#define pool_min conf_getglobals()->Vpool_min
+    int Vpool_min;                              /* OBSOLETE */
+#define pool_life conf_getglobals()->Vpool_life
+    int Vpool_life;                             /* OBSOLETE */
+
+    /* For multiprocess UNIX servers, the maximum threads per process */
+#define pool_maxthreads conf_getglobals()->Vpool_maxthreads
+    int Vpool_maxthreads;
+
+#define pool_minthreads conf_getglobals()->Vpool_minthreads
+    int Vpool_minthreads;                       /* OBSOLETE */
+
+    char *Vsecure_keyfn;                        /* OBSOLETE */
+    char *Vsecure_certfn;                       /* OBSOLETE */
+
+#define security_active 0
+    int Vsecurity_active;
+    int Vssl3_active;                           /* OBSOLETE */
+    int Vssl2_active;                           /* OBSOLETE */
+    int Vsecure_auth;                           /* OBSOLETE */
+    int Vsecurity_session_timeout;
+    long Vssl3_session_timeout;
+
+    /* The server's hostname as should be reported in self-ref URLs */
+#define server_hostname "x4"
+    char *Vserver_hostname;
+
+    /* The main object from which all are derived */
+#define root_object conf_getglobals()->Vroot_object
+    char *Vroot_object;
+
+    /* The object set the administrator has asked us to load */
+#define std_os conf_getglobals()->Vstd_os
+    httpd_objset *Vstd_os;
+
+    /* The root of ACL data structures */
+    void *Vacl_root;
+
+    /* The main error log, where all errors are logged */
+    char *Vmaster_error_log;
+
+    /* The server root directory (contains instance subdirectories) */
+#define server_root conf_getglobals()->Vserver_root
+    char *Vserver_root;
+
+    /* This server's id */
+#define server_id conf_getglobals()->Vserver_id
+    char *Vserver_id;
+
+    /* Admin server users file */
+    char *Vadmin_users;
+
+    /* The installation directory (contains bin and lib subdirectories) */
+    char *Vnetsite_root;
+
+    /* Digest authentication stale nonce timeout value */
+    int digest_stale_timeout;
+
+    int single_accept;          /* OBSOLETE */
+    int num_keep_alives;        /* OBSOLETE */
+    int log_verbose;            /* OBSOLETE */
+    int mmap_flags;             /* OBSOLETE */
+    int mmap_prots;             /* OBSOLETE */
+    int unused1;
+    int unused2;
+
+    /* Begin Enterprise 3.0 fields */
+    int accept_language;        /* turn accept-language on/off */
+
+    char *mtahost;
+    char *nntphost;             /* OBSOLETE */
+
+    /* The root of ACL data structures */
+    void *Vacl_root_30;
+
+    char *agentFilePath;        /* OBSOLETE */
+
+    int Allowed;                /* OBSOLETE */
+
+    pblock *genericGlobals;     /* OBSOLETE */
+
+    char *agentsACLFile;        /* OBSOLETE */
+
+    int wait_for_cgi;           /* OBSOLETE */
+    int cgiwatch_timeout;       /* OBSOLETE */
+    int started_by_watchdog;
+    int restarted_by_watchdog;
+    int old_accel_cache_enabled; /* OBSOLETE */
+    int Vssl_cache_entries;
+    int blocking_listen_socket; /* OBSOLETE */
+    pblock **initfns;
+    char *vs_config_file;       /* OBSOLETE */
+};
+
+/* Type used for Request rq_attr bit flags */
+#ifdef AIX
+#define RQATTR unsigned
+#else
+#define RQATTR unsigned long
+#endif
+
+struct Request {
+    /* Server working variables */
+    pblock *vars;
+
+    /* The method, URI, and protocol revision of this request */
+    pblock *reqpb;
+    /* Protocol specific headers */
+    int loadhdrs;
+    pblock *headers;
+
+    /* Server's response headers */
+    int senthdrs;
+    pblock *srvhdrs;
+
+    /* The object set constructed to fulfill this request */
+    httpd_objset *os;
+    /* Array of objects that were created from .nsconfig files */
+    httpd_objset *tmpos;
+
+    /* The stat last returned by request_stat_path */
+    char *statpath;
+    char *staterr;
+    struct stat *finfo;
+
+    /* access control state */
+    int aclstate;               /* ACL decision state */
+    int acldirno;               /* deciding ACL directive number */
+    char *aclname;              /* name of deciding ACL */
+    pblock *aclpb;              /* OBSOLETE */
+    /* 3.0 ACL list pointer */
+    ACLListHandle *acllist;
+
+    int request_is_cacheable;   /* */
+    int directive_is_cacheable; /* set by SAFs with no external side effects that make decisions based solely on URI and path */
+
+    char *cached_headers;       /* OBSOLETE */
+    int cached_headers_len;     /* OBSOLETE */
+    char *unused;
+
+    /* HTTP/1.1 features */
+#define REQ_TIME(x)             (x)->req_start
+    time_t req_start;           /* time request arrived - used for selecting weak or strong cache validation */
+    short protv_num;            /* protocol version number */
+    short method_num;           /* method number */
+    struct rq_attr {
+        RQATTR abs_uri:1;               /* set if absolute URI was used */
+        RQATTR chunked:1;               /* chunked transfer-coding */
+        RQATTR keep_alive:1;            /* connection keep-alive */
+        RQATTR pipelined:1;             /* request packet is pipelined */
+        RQATTR internal_req:1;          /* this was an internal request */
+        RQATTR perm_req:1;              /* don't FREE() this request */
+        RQATTR header_file_present:1;   /* OBSOLETE */
+        RQATTR footer_file_present:1;   /* OBSOLETE */
+        RQATTR jvm_attached:1;          /* OBSOLETE */
+        RQATTR req_restarted:1;         /* request was restarted */
+        RQATTR jvm_request_locked:1;    /* used for first-request serialization on some platforms */
+        RQATTR default_type_set:1;      /* set if default types were set using set-default-type objecttype function */
+        RQATTR is_web_app:1;            /* OBSOLETE */
+        RQATTR ssl_unclean_shutdown:1;  /* set if browser requires unclean SSL shutdown */
+        RQATTR vary_accept_language:1;  /* set if request was restarted based on an accept-language header */
+        RQATTR reserved:17;             /* if you add a flag, make sure to subtract from this */
+    } rq_attr;
+    char *hostname;             /* hostname used to access server (always non-NULL) */
+    int allowed;                /* OBSOLETE */
+    int byterange;              /* OBSOLETE */
+    short status_num;           /* HTTP status code */
+
+    int staterrno;              /* used for rqstat */
+    Request *orig_rq;           /* original Request - used for internal redirects */
+};
+
+/* Request attribute macros */
+#define ABS_URI(x)                      (x)->rq_attr.abs_uri
+#define CHUNKED(x)                      (x)->rq_attr.chunked
+#define KEEP_ALIVE(x)                   (x)->rq_attr.keep_alive 
+#define PIPELINED(x)                    (x)->rq_attr.pipelined 
+#define INTERNAL_REQUEST(x)             (x)->rq_attr.internal_req 
+#define RESTARTED_REQUEST(x)            (x)->rq_attr.req_restarted
+#define PERM_REQUEST(x)                 (x)->rq_attr.perm_req
+#define JVM_REQUEST_LOCKED(x)           (x)->rq_attr.jvm_request_locked
+#define SSL_UNCLEAN_SHUTDOWN(x)         (x)->rq_attr.ssl_unclean_shutdown
+#define VARY_ACCEPT_LANGUAGE(x)         (x)->rq_attr.vary_accept_language
+
+/* Define methods for HTTP/1.1 */
+#define METHOD_HEAD     0
+#define METHOD_GET      1
+#define METHOD_PUT      2
+#define METHOD_POST     3
+#define METHOD_DELETE   4
+#define METHOD_TRACE    5
+#define METHOD_OPTIONS  6
+/* The following methods are Netscape method extensions */
+#define METHOD_MOVE     7
+#define METHOD_INDEX    8
+#define METHOD_MKDIR    9
+#define METHOD_RMDIR    10
+#define METHOD_COPY     11
+#define METHOD_MAX      12      /* Number of methods available on this server */
+
+#define ISMGET(r)       ((r)->method_num == METHOD_GET)
+#define ISMHEAD(r)      ((r)->method_num == METHOD_HEAD)
+#define ISMPUT(r)       ((r)->method_num == METHOD_PUT)
+#define ISMPOST(r)      ((r)->method_num == METHOD_POST)
+#define ISMDELETE(r)    ((r)->method_num == METHOD_DELETE)
+#define ISMMOVE(r)      ((r)->method_num == METHOD_MOVE)
+#define ISMINDEX(r)     ((r)->method_num == METHOD_INDEX)
+#define ISMMKDIR(r)     ((r)->method_num == METHOD_MKDIR)
+#define ISMRMDIR(r)     ((r)->method_num == METHOD_RMDIR)
+#define ISMCOPY(r)      ((r)->method_num == METHOD_COPY)
+#define ISMTRACE(r)     ((r)->method_num == METHOD_TRACE)
+#define ISMOPTIONS(r)   ((r)->method_num == METHOD_OPTIONS)
+
+
+/* --- End type definitions --- */
+
+/* --- Begin dispatch vector table definition --- */
+/* --- End dispatch vector table definition --- */
+
+/* --- Begin API macro definitions --- */
+
+#ifndef INTNSAPI
+
+#if NSAPI_VERSION >= 301
+
+/*
+ * In Sun ONE Web Server 6.1 and higher, http_parse_request("", NULL, NULL)
+ * returns the NSAPI version.  In previous releases, it returns -1.
+ */
+#define __NSAPI_RUNTIME_VERSION \
+        ((*__nsapi30_table->f_http_parse_request)("", NULL, NULL))
+
+/*
+ * NSAPI_RUNTIME_VERSION returns the NSAPI version the server implements.  The
+ * returned NSAPI version number is reliable only in iPlanet Web Server 6.0,
+ * Netscape Enterprise Server 6.0, and Sun ONE Web Server 6.0 and higher.
+ */
+#define NSAPI_RUNTIME_VERSION \
+        (__NSAPI_RUNTIME_VERSION > 0 ? __NSAPI_RUNTIME_VERSION : 301)
+
+#endif /* NSAPI_VERSION >= 301 */
+
+#define system_version (*__nsapi30_table->f_system_version)
+
+/*
+ * Depending on the system, memory allocated via these macros may come from 
+ * an arena.  If these functions are called from within an Init function, they
+ * will be allocated from permanent storage.  Otherwise, they will be freed 
+ * when the current request is finished.
+ */
+
+
+
+#endif /* !INTNSAPI */
+
+#ifdef XP_UNIX
+#define dir_open opendir
+#define dir_read readdir
+#define dir_close closedir
+#define dir_create(path) mkdir(path, 0755)
+#define dir_remove rmdir
+#define system_chdir chdir
+#define file_unix2local(path,p2) strcpy(p2,path)
+#endif /* XP_UNIX */
+
+#ifdef XP_WIN32
+#define dir_create _mkdir
+#define dir_remove _rmdir
+#define system_chdir SetCurrentDirectory
+#endif /* XP_WIN32 */
+
+/*
+ * Thread-safe variants of localtime and gmtime
+ */
+#define system_localtime(curtime, ret) util_localtime(curtime, ret)
+#define system_gmtime(curtime, ret) util_gmtime(curtime, ret)
+
+/* 
+ * pblock_find finds the entry with the given name in pblock pb.
+ *
+ * If it is successful, it returns the param block.  If not, it returns NULL.
+ */
+#define pblock_find(name, pb) (pblock_fr(name,pb,0))
+
+/*
+ * pblock_remove behaves exactly like pblock_find, but removes the given
+ * entry from pb.
+ */
+#define pblock_remove(name, pb) (pblock_fr(name,pb,1))
+
+/*
+ * session_dns returns the DNS hostname of the client of this session,
+ * and inserts it into the client pblock.  Returns NULL if unavailable.
+ */
+#define session_dns(sn) session_dns_lookup(sn, 0)
+
+/*
+ * session_maxdns looks up a hostname from an IP address, and then verifies 
+ * that the host is really who they claim to be. 
+ */
+#define session_maxdns(sn) session_dns_lookup(sn, 1)
+
+
+/* nsapi functions */
+
+ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes);
+
+NSAPI_PUBLIC pb_param *INTparam_create(const char *name, const char *value);
+
+NSAPI_PUBLIC int INTparam_free(pb_param *pp);
+
+NSAPI_PUBLIC pblock *INTpblock_create(int n);
+
+NSAPI_PUBLIC void INTpblock_free(pblock *pb);
+
+NSAPI_PUBLIC char *INTpblock_findval(const char *name, const pblock *pb);
+
+NSAPI_PUBLIC pb_param *INTpblock_nvinsert(const char *name, const char *value, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb);
+
+NSAPI_PUBLIC pb_param *INTpblock_nninsert(const char *name, int value, pblock *pb);
+
+NSAPI_PUBLIC void INTpblock_pinsert(pb_param *pp, pblock *pb);
+
+NSAPI_PUBLIC int INTpblock_str2pblock(const char *str, pblock *pb);
+
+NSAPI_PUBLIC char *INTpblock_pblock2str(const pblock *pb, char *str);
+
+NSAPI_PUBLIC int INTpblock_copy(const pblock *src, pblock *dst);
+
+NSAPI_PUBLIC pblock *INTpblock_dup(const pblock *src);
+
+NSAPI_PUBLIC char **INTpblock_pb2env(const pblock *pb, char **env);
+
+NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value);
+
+NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n);
+
+NSAPI_PUBLIC pb_param *INTpblock_fr(const char *name, pblock *pb, int remove);
+
+NSAPI_PUBLIC char *INTpblock_replace(const char *name,char * new_value,pblock *pb);
+
+NSAPI_PUBLIC int INTpblock_str2pblock_lowercasename(const char *str, pblock *pb);
+
+//NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb);
+
+//NSAPI_PUBLIC const pb_key *pblock_key(const char *name);
+
+//NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen);
+
+//NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb);
+
+//NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb);
+
+//NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb);
+
+//NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb);
+
+//NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb);
+
+//NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb);
+
+//NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb);
+
+//NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, PRInt64 value, pblock *pb);
+
+#define param_create INTparam_create
+#define param_free INTparam_free
+#define pblock_create INTpblock_create
+#define pblock_free INTpblock_free
+#define pblock_findval INTpblock_findval
+#define pblock_nvinsert INTpblock_nvinsert
+#define pblock_nninsert INTpblock_nninsert
+#define pblock_pinsert INTpblock_pinsert
+#define pblock_str2pblock INTpblock_str2pblock
+#define pblock_pblock2str INTpblock_pblock2str
+#define pblock_copy INTpblock_copy
+#define pblock_dup INTpblock_dup
+#define pblock_pb2env INTpblock_pb2env
+#define pblock_fr INTpblock_fr
+#define pblock_replace INTpblock_replace
+
+
+
+void protocol_status(Session *sn, Request *rq, int n, const char *m);
+
+int http_start_response(Session *sn, Request *rq);
+#define protocol_start_response http_start_response
+int request_header(char *name, char **value, Session *sn, Request *rq);
+
+typedef void (*thrstartfunc)(void *);
+SYS_THREAD INTsysthread_start(int prio, int stksz, thrstartfunc fn, void *arg);
+NSAPI_PUBLIC void INTsysthread_sleep(int milliseconds);
+
+#define systhread_start INTsysthread_start
+#define systhread_sleep INTsysthread_sleep
+
+
+void webserver_atrestart(void (*fn)(void *), void *data);
+#define magnus_atrestart webserver_atrestart
+
+
+NSAPI_PUBLIC int INTshexp_match(const char *str, const char *exp);
+#define shexp_match INTshexp_match
+
+
+
+NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify);
+
+
+/* --- OBSOLETE ----------------------------------------------------------
+ * The following macros/functions are obsolete and are only maintained for
+ * compatibility.  Do not use them.
+ * -----------------------------------------------------------------------
+ */
+
+
+/* new macro and function definitions begin */
+
+/* netbuf functions */
+NSAPI_PUBLIC netbuf *netbuf_open(SYS_NETFD sd, int sz);
+
+NSAPI_PUBLIC void netbuf_close(netbuf *buf);
+
+NSAPI_PUBLIC unsigned char * netbuf_replace(netbuf *buf,
+    unsigned char *inbuf, int pos, int cursize, int maxsize);
+
+NSAPI_PUBLIC int netbuf_next(netbuf *buf, int advance);
+
+NSAPI_PUBLIC int netbuf_getbytes(netbuf *buf, char *buffer, int size);
+
+NSAPI_PUBLIC int netbuf_grab(netbuf *buf, int sz);
+
+/* end new macro and function definitions */
+
+#define SYS_STDERR STDERR_FILENO
+
+#ifdef XP_WIN32
+
+typedef HANDLE pid_t;
+
+#define ERROR_PIPE \
+        (ERROR_BROKEN_PIPE | ERROR_BAD_PIPE | \
+         ERROR_PIPE_BUSY | ERROR_PIPE_LISTENING | ERROR_PIPE_NOT_CONNECTED)
+#define CONVERT_TO_PRINTABLE_FORMAT(Filename)   \
+{                                               \
+        register char *s;                       \
+        if (Filename)                           \
+        for (s = Filename; *s; s++)             \
+                if ( *s == '\\')                \
+                        *s = '/';               \
+}
+#define CONVERT_TO_NATIVE_FS(Filename)          \
+{                                               \
+        register char *s;                       \
+        if (Filename)                           \
+                for (s = Filename; *s; s++)     \
+                        if ( *s == '/')         \
+                                *s = '\\';      \
+}                                                                        
+
+#ifdef INTNSAPI
+NSAPI_PUBLIC extern nsapi_dispatch_t *__nsapi30_table;
+#if NSAPI_VERSION >= 302
+NSAPI_PUBLIC extern nsapi302_dispatch_t *__nsapi302_table;
+#endif /* NSAPI_VERSION >= 302 */
+#if NSAPI_VERSION >= 303
+NSAPI_PUBLIC extern nsapi303_dispatch_t *__nsapi303_table;
+#endif /* NSAPI_VERSION >= 303 */
+#else
+__declspec(dllimport) nsapi_dispatch_t *__nsapi30_table;
+#if NSAPI_VERSION >= 302
+__declspec(dllimport) nsapi302_dispatch_t *__nsapi302_table;
+#endif /* NSAPI_VERSION >= 302 */
+#if NSAPI_VERSION >= 303
+__declspec(dllimport) nsapi303_dispatch_t *__nsapi303_table;
+#endif /* NSAPI_VERSION >= 303 */
+#endif /* INTNSAPI */
+
+#else /* !XP_WIN32 */
+
+
+#endif /* XP_WIN32 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !PUBLIC_NSAPI_H */
--- a/src/server/request.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "request.h"
-
-#include "pblock.h"
-#include "httprequest.h"
-
-
-/* Code from req.cpp */
-/* fremden Code durch eigenen ersetzen */
-
-/* -------------------------- request_initialize -------------------------- */
-
-int request_initialize(
-        pool_handle_t *pool,
-        HTTPRequest *hrq,
-        NSAPIRequest *nrq)
-{
-    Request *rq = &nrq->rq;
-
-    rq->vars = pblock_create_pool(pool, REQ_HASHSIZE);
-    if (!rq->vars)
-        return 1;
-    rq->reqpb = pblock_create_pool(pool, REQ_HASHSIZE);
-    if (!rq->reqpb)
-        return 1;
-    rq->loadhdrs = 0;
-    rq->headers = pblock_create_pool(pool, REQ_HASHSIZE);
-    if (!rq->headers)
-        return 1;
-    rq->senthdrs = 0;
-    rq->srvhdrs = pblock_create_pool(pool, REQ_HASHSIZE);
-    if (!rq->srvhdrs)
-        return 1;
-
-    rq->os = NULL;
-    rq->tmpos = NULL;
-    rq->statpath = NULL;
-    rq->staterr = NULL;
-    rq->finfo = NULL;
-    rq->aclstate = 0;
-    rq->acldirno = 0;
-    rq->aclname = NULL;
-    rq->aclpb = NULL;
-    rq->acllist = NULL;
-    rq->request_is_cacheable = 0;
-    rq->directive_is_cacheable = 0;
-    rq->cached_headers = NULL;
-    rq->cached_headers_len = 0;
-    rq->unused = NULL;
-    //rq->req_start = ft_time(); // TODO: ft_time
-    rq->protv_num = 0;
-    rq->method_num = -1;
-    //PR_ASSERT(sizeof(rq->rq_attr) == sizeof(RQATTR)); // TODO: assert
-    *(RQATTR *) &rq->rq_attr = 0;
-    //rq->hostname = pool_strdup(pool, hostname); // TODO: hostname
-    rq->allowed = 0;
-    rq->byterange = 0;
-    rq->status_num = 0;
-    rq->staterrno = 0;
-    rq->orig_rq = rq;
-
-    // TODO: nrq
-
-    /* NSAPI execution context */
-    nrq->context.last_req_code = REQ_NOACTION;
-
-    nrq->context.objset_index = -1;
-    nrq->context.dtable_index = 0;
-
-    return 0;
-}
--- a/src/server/request.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef REQUEST_H
-#define	REQUEST_H
-
-#include "nsapi.h"
-#include "object.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct NSAPIRequest NSAPIRequest;
-
-struct NSAPIRequest {
-    Request        rq;
-    RequestPhase   phase;
-    VirtualServer  *vs;
-    NSAPIContext   context;
-};
-
-/* macros for short context access */
-#define NCX_OI(rq) rq->context.objset_index
-#define NCX_DI(rq) rq->context.dtable_index
-
-#define REQ_HASHSIZE 10
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* REQUEST_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/Makefile	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,44 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BUILD_ROOT = ../../../
+OBJ_DIR = $(BUILD_ROOT)build/
+
+CFLAGS  = -I/usr/include/mps -g
+LDFLAGS = 
+
+include objs.mk
+
+all: $(SAFOBJS)
+
+$(SAFS_OBJPRE)%.o: %.c
+	cc -o $@ -c $(CFLAGS) $<
+
+$(SAFS_OBJPRE)%.o: %.cpp
+	CC -o $@ -c $(CFLAGS) $<
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/nametrans.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "nametrans.h"
+
+#include "../util/pblock.h"
+
+int test_nametrans(pblock *pb, Session *sn, Request *rq) {
+    printf("test_nametrans...\n");
+
+    // set ppath
+    //char *ppath = "/export/home/olaf/Desktop/hello.txt";
+    //pblock_kvinsert(pb_key_ppath, ppath, strlen(ppath), rq->vars);
+
+    return REQ_NOACTION;
+}
+
+/*
+ * assign_name
+ *
+ * Assigns the name specified by the name parameter if the uri has the
+ * specified prefix.
+ *
+ * pblock parameter:
+ * name     object name
+ * from     optional uri prefix
+ */
+int assign_name(pblock *pb, Session *sn, Request *rq) {
+    /* TODO: expression instead of simple prefix */
+
+    char *name = pblock_findkeyval(pb_key_name, pb);
+    char *from = pblock_findkeyval(pb_key_from, pb);
+
+    if(!name) {
+        /* TODO: add log */
+        protocol_status(sn, rq, 500, NULL);
+        return REQ_ABORTED;
+    }
+    
+    if(from) {
+        char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+        char c;
+        int i = 0;
+        while((c = from[i]) != 0) {
+            if(c != uri[i]) {
+                return REQ_NOACTION;
+            }
+            i++;
+        }
+    }
+
+    /* add object to rq->vars */
+    pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
+
+    return REQ_NOACTION;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/nametrans.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,47 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NAMETRANS_H
+#define	NAMETRANS_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int test_nametrans(pblock *pb, Session *sn, Request *rq);
+
+int assign_name(pblock *pb, Session *sn, Request *rq);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* NAMETRANS_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/objecttype.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "objecttype.h"
+#include "../util/pblock.h"
+
+#include "../ucx/sstring.h"
+
+int object_type_by_extension(pblock *pb, Session *sn, Request *rq) {
+    sstr_t ppath = sstr(pblock_findkeyval(pb_key_ppath, rq->vars));
+    sstr_t ct;
+    if(ppath.ptr[ppath.length - 1] == '/') {
+        /* directory */
+        ct = sstrn("internal/directory", 18);
+    } else {
+        sstr_t ext;
+        ext.length = 0;
+        for(int i=ppath.length - 1;i>=0;i--) {
+            if(ppath.ptr[i] == '.') {
+                ext.ptr = ppath.ptr + i + 1;
+                ext.length = ppath.length - i - 1;
+            }
+        }
+
+        if(ext.length == 0) {
+            /* no extension, no type */
+            return REQ_NOACTION;
+        }
+
+        /* TODO: we need a map for extensions/types */
+        if(!sstrcmp(ext, sstrn("txt", 3))) {
+            ct = sstr("text/plain");
+        } else if(!sstrcmp(ext, sstrn("htm", 3))) {
+            ct = sstr("text/html");
+        } else if(!sstrcmp(ext, sstrn("html", 4))) {
+            ct = sstr("text/html");
+        } else if(!sstrcmp(ext, sstrn("xml", 3))) {
+            ct = sstr("text/xml");
+        }
+    }
+
+    pblock_kvinsert(pb_key_content_type, ct.ptr, ct.length, rq->srvhdrs);
+    return REQ_PROCEED;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/objecttype.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OBJECTTYPE_H
+#define	OBJECTTYPE_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int object_type_by_extension(pblock *pb, Session *sn, Request *rq);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* OBJECTTYPE_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/objs.mk	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,38 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+SAFS_SRC_DIR = server/safs/
+
+SAFS_OBJPRE = $(OBJ_DIR)$(SAFS_SRC_DIR)
+
+SAFOBJ = nametrans.o
+SAFOBJ += objecttype.o
+SAFOBJ += service.o
+
+SAFOBJS = $(SAFOBJ:%=$(SAFS_OBJPRE)%)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/service.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,227 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include "service.h"
+#include "../util/io.h"
+#include "../util/pblock.h"
+#include "../daemon/protocol.h"
+
+#include <sys/sendfile.h>
+#include "../util/strbuf.h"
+
+// TODO: system sendfile Abstraktionen in neue Datei auslagern
+/*
+ssize_t sys_sendfile(int out_fd, int in_fd, off_t *off, size_t len) {
+    
+}
+*/
+#define sys_sendfile sendfile
+
+
+/*
+ * prepares for servicing a file
+ *
+ * adds content-length header and starts the response
+ *
+ * return the file descriptor or an error code
+ */
+int prepare_service_file(Session *sn, Request *rq) {
+    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
+
+    /* open the file */
+    int fd = open(ppath, O_RDONLY);
+    if(fd < 0) {
+        perror("prepare_service_file: open");
+
+        int status = 500;
+        switch(errno) {
+            case EACCES: {
+                status = 403;
+                break;
+            }
+            case ENOENT: {
+                status = 404;
+                break;
+            }
+        }
+        protocol_status(sn, rq, status, NULL);
+        return -1;
+    }
+
+    /* get stat */
+    struct stat stat;
+    if (fstat(fd, &stat) != 0) {
+        perror("prepare_service_file: stat");
+
+        protocol_status(sn, rq, 500, NULL);
+        return -1;
+    }
+
+    /* add content-length header*/
+    char contentLength[32];
+    int len = snprintf(contentLength, 32, "%d", stat.st_size);
+
+    pblock_kvinsert(pb_key_content_length, contentLength, len, rq->srvhdrs);
+
+    /* start response */
+    protocol_status(sn, rq, 200, NULL);
+    http_start_response(sn, rq);
+
+    return fd;
+}
+
+int send_file(pblock *pb, Session *sn, Request *rq) {
+    printf("test_service\n");
+
+    // request body test begin
+    char *ctval = pblock_findkeyval(pb_key_content_length, rq->headers);
+    if(ctval != NULL) {
+        printf("read request body\n");
+
+        printf("netbuf{%d}\n", sn->inbuf);
+
+        int c;
+        while((c = netbuf_getc(sn->inbuf)) != IO_EOF) {
+            putchar(c);
+        }
+        printf("\n");
+    }
+
+
+    // end test
+
+    int fd = prepare_service_file(sn, rq);
+    if(fd < 0) {
+        /* TODO: service error */
+        http_start_response(sn, rq);
+        return REQ_PROCEED;
+    }
+
+    /* send file*/
+    SystemIOStream *io = (SystemIOStream*) sn->csd;
+
+    off_t fileoffset = 0;
+    int len = atoi(pblock_findkeyval(pb_key_content_length, rq->srvhdrs));
+    printf("content-length: %d\n", len);
+    sendfile(io->fd, fd, &fileoffset, len);
+
+    close(fd);
+
+    return REQ_PROCEED;
+}
+
+int service_hello(pblock *pb, Session *sn, Request *rq) {
+    pblock_nninsert("content-length", 13, rq->srvhdrs);
+    protocol_status(sn, rq, 200, NULL);
+    http_start_response(sn, rq);
+    net_write(sn->csd, "Hello World!\n", 13);
+    return REQ_PROCEED;
+}
+
+int service_index(pblock *pb, Session *sn, Request *rq) {
+    printf("service_index\n");
+
+    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
+    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+
+    sstr_t r_uri = sstr(uri);
+
+    /* open the file */
+    int fd = open(ppath, O_RDONLY);
+    if(fd < 0) {
+        perror("service_index: open");
+
+        int status = 500;
+        switch(errno) {
+            case EACCES: {
+                status = 403;
+                break;
+            }
+            case ENOENT: {
+                status = 404;
+                break;
+            }
+        }
+        protocol_status(sn, rq, status, NULL);
+        printf("REQ_ABORTED\n");
+        return REQ_ABORTED;
+    }
+
+    DIR *dir = fdopendir(fd);
+    if(dir == NULL) {
+        protocol_status(sn, rq, 500, NULL);
+        printf("DIR is null\n");
+        return REQ_ABORTED;
+    }
+
+    sbuf_t *out = sbuf_new(1024); /* output buffer */
+
+    /* write html header  */
+    sbuf_puts(out, "<html>\n<head>\n<title>Index of ");
+    sbuf_puts(out, uri);
+    sbuf_puts(out, "</title>\n</head><body>\n<h1>Index of ");
+    sbuf_puts(out, uri);
+    sbuf_puts(out, "</h1><hr>\n\n");
+
+    struct dirent *f;
+    while((f = readdir(dir)) != NULL) {
+        if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
+            continue;
+        }
+
+        sstr_t filename = sstr(f->d_name);
+
+        sbuf_puts(out, "<a href=\"");
+        sbuf_append(out, r_uri);
+        sbuf_append(out, filename);
+        sbuf_puts(out, "\">");
+        sbuf_append(out, filename);
+        sbuf_puts(out, "</a><br>\n");
+    }
+
+    sbuf_puts(out, "\n</body>\n</html>\n");
+
+    /* send stuff to client */
+    pblock_removekey(pb_key_content_type, rq->srvhdrs);
+    pblock_kvinsert(pb_key_content_type, "text/html", 9, rq->srvhdrs);
+    pblock_nninsert("content-length", out->length, rq->srvhdrs);
+    protocol_status(sn, rq, 200, NULL);
+    http_start_response(sn, rq);
+
+    net_write(sn->csd, out->ptr, out->length);
+
+    /* close */
+    closedir(dir);
+
+    return REQ_PROCEED;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/safs/service.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SERVICE_H
+#define	SERVICE_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int send_file(pblock *pb, Session *sn, Request *rq);
+
+int service_hello(pblock *pb, Session *sn, Request *rq);
+
+int service_index(pblock *pb, Session *sn, Request *rq);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* SERVICE_H */
+
--- a/src/server/saxhandler.cpp	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "sstring.h"
-#include "dlist.h"
-#include "pool.h"
-
-#include "saxhandler.h"
-
-using std;
-
-PropfindHandler::PropfindHandler(PropfindRequest *rq, pool_handle_t *p) {
-    davrq = rq;
-    pool  = p;
-
-    davPropTag = false;
-    property = NULL;
-}
-
-PropfindHandler::~PropfindHandler() {
-    
-}
-
-void PropfindHandler::startElement(
-        const XMLCh *const uri,
-        const XMLCh* const localname,
-        const XMLCh* const qname,
-        const Attributes& attrs)
-{
-    char *ns  = XMLString::transcode(uri);
-    char *name = XMLString::transcode(localname);
-    
-    if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
-        davPropTag = true;
-    } else if(davPropTag && property == NULL) {
-        //property = (DavProperty*)pool_malloc(pool, sizeof(DavProperty));
-        property = (DavProperty*)malloc(sizeof(DavProperty));
-        /* Ultra TODO: pool_malloc makes big mistakes!! */
-
-        size_t nslen = strlen(ns);
-        size_t namelen = strlen(name);
-        if(nslen > 0) {
-            property->xmlns = (char*)pool_malloc(pool, nslen + 1);
-            property->xmlns[nslen] = 0;
-            memcpy(property->xmlns, ns, nslen);
-        } else {
-            property->xmlns = NULL;
-        }
-
-        if(namelen > 0) {
-            property->name = (char*)pool_malloc(pool, namelen + 1);
-            property->name[namelen] = 0;
-            memcpy(property->name, name, namelen);
-        } else {
-            property->name = NULL;
-        }
-    }
-
-    XMLString::release(&ns);
-    XMLString::release(&name);
-}
-
-
-void PropfindHandler::endElement(
-        const XMLCh* const   uri,
-        const XMLCh* const   localname,
-        const XMLCh* const   qname)
-{
-    char *ns  = XMLString::transcode(uri);
-    char *name = XMLString::transcode(localname);
-
-    if(property != NULL) {
-        const char *xmlns = (property->xmlns) ? property->xmlns : "";
-        
-        if(!strcmp(ns, xmlns) && !strcmp(name, property->name)) {
-            // add property to DavRequest
-            UcxDlist *elm = (UcxDlist*)pool_malloc(pool, sizeof(UcxDlist));
-            elm->prev = NULL;
-            elm->next = NULL;
-            elm->data = property;
-            //printf("saxhandler: add property: {%s}\n", property->name);
-            davrq->properties = ucx_dlist_concat(davrq->properties, elm);
-            
-            property = NULL;
-        }
-    }
-
-    XMLString::release(&ns);
-    XMLString::release(&name);
-}
-
-void PropfindHandler::startDocument() {
-    
-}
-
-void PropfindHandler::endDocument() {
-
-}
-
--- a/src/server/saxhandler.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SAXHANDLER_H
-#define	SAXHANDLER_H
-
-#include "davparser.h"
-
-#include <xercesc/sax2/DefaultHandler.hpp>
-
-using namespace xercesc;
-
-class PropfindHandler : public DefaultHandler {
-public:
-    PropfindHandler(PropfindRequest *rq, pool_handle_t *p);
-    virtual ~PropfindHandler();
-
-    void startElement(
-        const XMLCh* const   uri,
-        const XMLCh* const   localname,
-        const XMLCh* const   qname,
-        const Attributes&    attrs);
-    
-    void endElement(
-        const XMLCh* const   uri,
-        const XMLCh* const   localname,
-        const XMLCh* const   qname);
-
-    void startDocument();
-
-    void endDocument();
-
-private:
-    PropfindRequest *davrq;
-    pool_handle_t   *pool;
-
-    bool            davPropTag;
-    DavProperty     *property;
-};
-
-#endif	/* SAXHANDLER_H */
-
--- a/src/server/service.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include "service.h"
-#include "io.h"
-#include "pblock.h"
-#include "protocol.h"
-
-#include <sys/sendfile.h>
-#include "strbuf.h"
-
-// TODO: system sendfile Abstraktionen in neue Datei auslagern
-/*
-ssize_t sys_sendfile(int out_fd, int in_fd, off_t *off, size_t len) {
-    
-}
-*/
-#define sys_sendfile sendfile
-
-
-/*
- * prepares for servicing a file
- *
- * adds content-length header and starts the response
- *
- * return the file descriptor or an error code
- */
-int prepare_service_file(Session *sn, Request *rq) {
-    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
-
-    /* open the file */
-    int fd = open(ppath, O_RDONLY);
-    if(fd < 0) {
-        perror("prepare_service_file: open");
-
-        int status = 500;
-        switch(errno) {
-            case EACCES: {
-                status = 403;
-                break;
-            }
-            case ENOENT: {
-                status = 404;
-                break;
-            }
-        }
-        protocol_status(sn, rq, status, NULL);
-        return -1;
-    }
-
-    /* get stat */
-    struct stat stat;
-    if (fstat(fd, &stat) != 0) {
-        perror("prepare_service_file: stat");
-
-        protocol_status(sn, rq, 500, NULL);
-        return -1;
-    }
-
-    /* add content-length header*/
-    char contentLength[32];
-    int len = snprintf(contentLength, 32, "%d", stat.st_size);
-
-    pblock_kvinsert(pb_key_content_length, contentLength, len, rq->srvhdrs);
-
-    /* start response */
-    protocol_status(sn, rq, 200, NULL);
-    http_start_response(sn, rq);
-
-    return fd;
-}
-
-int send_file(pblock *pb, Session *sn, Request *rq) {
-    printf("test_service\n");
-
-    // request body test begin
-    char *ctval = pblock_findkeyval(pb_key_content_length, rq->headers);
-    if(ctval != NULL) {
-        printf("read request body\n");
-
-        printf("netbuf{%d}\n", sn->inbuf);
-
-        int c;
-        while((c = netbuf_getc(sn->inbuf)) != IO_EOF) {
-            putchar(c);
-        }
-        printf("\n");
-    }
-
-
-    // end test
-
-    int fd = prepare_service_file(sn, rq);
-    if(fd < 0) {
-        /* TODO: service error */
-        http_start_response(sn, rq);
-        return REQ_PROCEED;
-    }
-
-    /* send file*/
-    SystemIOStream *io = (SystemIOStream*) sn->csd;
-
-    off_t fileoffset = 0;
-    int len = atoi(pblock_findkeyval(pb_key_content_length, rq->srvhdrs));
-    printf("content-length: %d\n", len);
-    sendfile(io->fd, fd, &fileoffset, len);
-
-    close(fd);
-
-    return REQ_PROCEED;
-}
-
-int service_hello(pblock *pb, Session *sn, Request *rq) {
-    pblock_nninsert("content-length", 13, rq->srvhdrs);
-    protocol_status(sn, rq, 200, NULL);
-    http_start_response(sn, rq);
-    net_write(sn->csd, "Hello World!\n", 13);
-    return REQ_PROCEED;
-}
-
-int service_index(pblock *pb, Session *sn, Request *rq) {
-    printf("service_index\n");
-
-    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
-    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
-
-    sstr_t r_uri = sstr(uri);
-
-    /* open the file */
-    int fd = open(ppath, O_RDONLY);
-    if(fd < 0) {
-        perror("service_index: open");
-
-        int status = 500;
-        switch(errno) {
-            case EACCES: {
-                status = 403;
-                break;
-            }
-            case ENOENT: {
-                status = 404;
-                break;
-            }
-        }
-        protocol_status(sn, rq, status, NULL);
-        printf("REQ_ABORTED\n");
-        return REQ_ABORTED;
-    }
-
-    DIR *dir = fdopendir(fd);
-    if(dir == NULL) {
-        protocol_status(sn, rq, 500, NULL);
-        printf("DIR is null\n");
-        return REQ_ABORTED;
-    }
-
-    sbuf_t *out = sbuf_new(1024); /* output buffer */
-
-    /* write html header  */
-    sbuf_puts(out, "<html>\n<head>\n<title>Index of ");
-    sbuf_puts(out, uri);
-    sbuf_puts(out, "</title>\n</head><body>\n<h1>Index of ");
-    sbuf_puts(out, uri);
-    sbuf_puts(out, "</h1><hr>\n\n");
-
-    struct dirent *f;
-    while((f = readdir(dir)) != NULL) {
-        if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
-            continue;
-        }
-
-        sstr_t filename = sstr(f->d_name);
-
-        sbuf_puts(out, "<a href=\"");
-        sbuf_append(out, r_uri);
-        sbuf_append(out, filename);
-        sbuf_puts(out, "\">");
-        sbuf_append(out, filename);
-        sbuf_puts(out, "</a><br>\n");
-    }
-
-    sbuf_puts(out, "\n</body>\n</html>\n");
-
-    /* send stuff to client */
-    pblock_removekey(pb_key_content_type, rq->srvhdrs);
-    pblock_kvinsert(pb_key_content_type, "text/html", 9, rq->srvhdrs);
-    pblock_nninsert("content-length", out->length, rq->srvhdrs);
-    protocol_status(sn, rq, 200, NULL);
-    http_start_response(sn, rq);
-
-    net_write(sn->csd, out->ptr, out->length);
-
-    /* close */
-    closedir(dir);
-
-    return REQ_PROCEED;
-}
--- a/src/server/service.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SERVICE_H
-#define	SERVICE_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-int send_file(pblock *pb, Session *sn, Request *rq);
-
-int service_hello(pblock *pb, Session *sn, Request *rq);
-
-int service_index(pblock *pb, Session *sn, Request *rq);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* SERVICE_H */
-
--- a/src/server/session.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "nsapi.h"
-
-#include "session.h"
-
-NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify) {
-    // TODO: implement
-    return NULL;
-}
--- a/src/server/session.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SESSION_H
-#define	SESSION_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct NSAPISession NSAPISession;
-
-struct NSAPISession {
-    Session sn; /* public session structure */
-    int sys_fd; /* system file descriptor */
-};
-
-NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* SESSION_H */
-
--- a/src/server/sessionhandler.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "nsapi.h"
-
-#include "sessionhandler.h"
-#include "httprequest.h"
-#include "httpparser.h"
-
-SessionHandler* create_basic_session_handler() {
-    BasicSessionHandler *handler = malloc(sizeof(BasicSessionHandler));
-    handler->threadpool = threadpool_new(8);
-    handler->sh.enqueue_connection = basic_enq_conn;
-
-
-    return (SessionHandler*)handler;
-}
-
-void basic_enq_conn(SessionHandler *handler, Connection *conn) {
-    BasicSessionHandler *sh = (BasicSessionHandler*)handler;
-    conn->session_handler = handler;
-    threadpool_run(sh->threadpool, basic_run_session, conn);
-}
-
-void* basic_run_session(void *data) {
-    Connection *conn = (Connection*)data;
-
-    HTTPRequest *request = http_request_new();
-    request->connection = conn;
-
-    // read request
-    netbuf *buf = malloc(sizeof(netbuf));
-    buf->rdtimeout = 120;
-    buf->pos = 0;
-    buf->cursize = 0;
-    buf->maxsize = 2048;
-    buf->sd = &conn->fd;
-    buf->inbuf = malloc(2048);
-    buf->errmsg = NULL;
-
-    request->netbuf = buf;
-
-    HttpParser *parser = http_parser_new(request);
-    int state;
-    int r;
-    r = read(conn->fd, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
-    if(r == -1) {
-         // TODO: error handling
-        fprintf(stderr, "%s\n", "Error: Cannot read from socket");
-        return NULL;
-    }
-    buf->cursize += r;
-    while((state = http_parser_process(parser)) != 0) {
-        if(state == 2) {
-            // TODO: error handling
-            fprintf(stderr, "%s\n", "Error: Cannot parse http request");
-            return NULL;
-        }
-        r = read(conn->fd, buf->inbuf + buf->pos, buf->maxsize - buf->pos);
-        if(r == -1) {
-            // TODO: error handling
-            fprintf(stderr, "%s\n", "Error: Cannot read from socket");
-            return NULL;
-        }
-        buf->cursize += r;
-    }
-
-    // process request
-    r = handle_request(request);
-
-
-    return NULL;
-}
-
-
--- a/src/server/sessionhandler.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SESSIONHANDLER_H
-#define	SESSIONHANDLER_H
-
-#include "thrpool.h"
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct _session_handler   SessionHandler;
-typedef struct _connection        Connection;
-
-struct _connection {
-    int fd;
-    struct sockaddr_in address;
-    SessionHandler *session_handler;
-};
-
-typedef void(*enqueue_connection_f)(SessionHandler*, Connection*);
-struct _session_handler {
-    enqueue_connection_f enqueue_connection;
-};
-
-/*
- * BasicSessionHandler
- *
- * The BasicSessionHandler enqueues the connections to a threadpool. IO and
- * request processing is handled by one thread.
- */
-typedef struct _basic_session_handler {
-    SessionHandler sh;
-    threadpool_t   *threadpool;
-    
-} BasicSessionHandler;
-
-
-SessionHandler* create_basic_session_handler();
-
-void basic_enq_conn(SessionHandler *handler, Connection *conn);
-
-void* basic_run_session(void *data);
-
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* SESSIONHANDLER_H */
-
--- a/src/server/shexp.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,496 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * shexp.c: shell-like wildcard match routines
- *
- *
- * See shexp.h for public documentation.
- *
- * Rob McCool
- *
- */
-
-#include <ctype.h>    /* isalpha, tolower */
-
-#include "shexp.h"
-
-
-/*
- * The observant engineer will notice 2 distinct sets of functions here.
- * All of the noicmp flavor of functions do case sensitive compares on all
- * platforms.  The other set (public set) does case insensitive compares on NT.
- */
-int _shexp_match_noicmp(const char *str, const char *exp) ;
-
-
-/* ----------------------------- shexp_valid ------------------------------ */
-
-
-int valid_subexp(const char *exp, char stop)
-{
-    register int x,y,t;
-    int nsc,np,tld;
-
-    x=0;nsc=0;tld=0;
-
-    while(exp[x] && (exp[x] != stop)) {
-        switch(exp[x]) {
-          case '~':
-            if(tld) return INVALID_SXP;
-            else ++tld;
-          case '*':
-          case '?':
-          case '^':
-          case '$':
-            ++nsc;
-            break;
-          case '[':
-            ++nsc;
-            if((!exp[++x]) || (exp[x] == ']'))
-                return INVALID_SXP;
-            for(++x;exp[x] && (exp[x] != ']');++x)
-                if(exp[x] == '\\')
-                    if(!exp[++x])
-                        return INVALID_SXP;
-            if(!exp[x])
-                return INVALID_SXP;
-            break;
-          case '(':
-            ++nsc;
-            while(1) {
-                if(exp[++x] == ')')
-                    return INVALID_SXP;
-                for(y=x;(exp[y]) && (exp[y] != '|') && (exp[y] != ')');++y)
-                    if(exp[y] == '\\')
-                        if(!exp[++y])
-                            return INVALID_SXP;
-                if(!exp[y])
-                    return INVALID_SXP;
-                t = valid_subexp(&exp[x],exp[y]);
-                if(t == INVALID_SXP)
-                    return INVALID_SXP;
-                x+=t;
-                if(exp[x] == ')') {
-                    break;
-                }
-            }
-            break;
-          case ')':
-          case ']':
-            return INVALID_SXP;
-          case '\\':
-            if(!exp[++x])
-                return INVALID_SXP;
-          default:
-            break;
-        }
-        ++x;
-    }
-    if((!stop) && (!nsc))
-        return NON_SXP;
-    return ((exp[x] == stop) ? x : INVALID_SXP);
-}
-
-NSAPI_PUBLIC int shexp_valid(const char *exp) {
-    int x;
-
-    x = valid_subexp(exp, '\0');
-    if (x < 0) {
-        if (x == INVALID_SXP) {
-            //NsprError::setError(PR_INVALID_ARGUMENT_ERROR,
-            //                    XP_GetAdminStr(DBT_invalidshexp));
-            // TODO
-        }
-        return x;
-    }
-    return VALID_SXP;
-}
-
-
-/* ----------------------------- shexp_match ----------------------------- */
-
-
-#define MATCH 0
-#define NOMATCH 1
-#define ABORTED -1
-
-int _shexp_match(const char *str, const char *exp);
-
-int handle_union(const char *str, const char *exp)
-{
-    char *e2 = (char *) MALLOC(sizeof(char)*strlen(exp));
-    register int t,p2,p1 = 1;
-    int cp;
-
-    while(1) {
-        for(cp=1;exp[cp] != ')';cp++)
-            if(exp[cp] == '\\')
-                ++cp;
-        for(p2 = 0;(exp[p1] != '|') && (p1 != cp);p1++,p2++) {
-            if(exp[p1] == '\\')
-                e2[p2++] = exp[p1++];
-            e2[p2] = exp[p1];
-        }
-        for(t=cp+1;(e2[p2] = exp[t]);++t,++p2);
-        if(_shexp_match(str,e2) == MATCH) {
-            FREE(e2);
-            return MATCH;
-        }
-        if(p1 == cp) {
-            FREE(e2);
-            return NOMATCH;
-        }
-        else ++p1;
-    }
-}
-
-int handle_union_noicmp(const char *str, const char *exp)
-{
-    char *e2 = (char *) MALLOC(sizeof(char)*strlen(exp));
-    register int t,p2,p1 = 1;
-    int cp;
-
-    while(1) {
-        for(cp=1;exp[cp] != ')';cp++)
-            if(exp[cp] == '\\')
-                ++cp;
-        for(p2 = 0;(exp[p1] != '|') && (p1 != cp);p1++,p2++) {
-            if(exp[p1] == '\\')
-                e2[p2++] = exp[p1++];
-            e2[p2] = exp[p1];
-        }
-        for(t=cp+1;(e2[p2] = exp[t]);++t,++p2);
-        if(_shexp_match_noicmp(str,e2) == MATCH) {
-            FREE(e2);
-            return MATCH;
-        }
-        if(p1 == cp) {
-            FREE(e2);
-            return NOMATCH;
-        }
-        else ++p1;
-    }
-}
-
-int _shexp_match(const char *str, const char *exp)
-{
-    register int x,y;
-    int ret,neg;
-
-    ret = 0;
-    for(x=0,y=0;exp[y];++y,++x) {
-        if((!str[x]) && (exp[y] != '(') && (exp[y] != '$') && (exp[y] != '*'))
-            ret = ABORTED;
-        else {
-            switch(exp[y]) {
-              case '$':
-                if( (str[x]) )
-                    ret = NOMATCH;
-                else
-                    --x;             /* we don't want loop to increment x */
-                break;
-              case '*':
-                while(exp[++y] == '*');
-                if(!exp[y])
-                    return MATCH;
-                while(str[x]) {
-                    switch(_shexp_match(&str[x++],&exp[y])) {
-                    case NOMATCH:
-                        continue;
-                    case ABORTED:
-                        ret = ABORTED;
-                        break;
-                    default:
-                        return MATCH;
-                    }
-                    break;
-                }
-                if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
-                    return MATCH;
-                else
-                    ret = ABORTED;
-                break;
-              case '[':
-                if((neg = ((exp[++y] == '^') && (exp[y+1] != ']'))))
-                    ++y;
-
-                if((isalnum(exp[y])) && (exp[y+1] == '-') &&
-                   (isalnum(exp[y+2])) && (exp[y+3] == ']'))
-                    {
-                        int start = exp[y], end = exp[y+2];
-
-                        /* Droolproofing for pinheads not included */
-                        if(neg ^ ((str[x] < start) || (str[x] > end))) {
-                            ret = NOMATCH;
-                            break;
-                        }
-                        y+=3;
-                    }
-                else {
-                    int matched;
-
-                    for(matched=0;exp[y] != ']';y++)
-                        matched |= (str[x] == exp[y]);
-                    if(neg ^ (!matched))
-                        ret = NOMATCH;
-                }
-                break;
-              case '(':
-                return handle_union(&str[x],&exp[y]);
-                break;
-              case '?':
-                break;
-              case '\\':
-                ++y;
-              default:
-#ifdef XP_UNIX
-                if(str[x] != exp[y])
-#else /* XP_WIN32 */
-                if(strnicmp(str + x, exp + y, 1))
-#endif /* XP_WIN32 */
-                    ret = NOMATCH;
-                break;
-            }
-        }
-        if(ret)
-            break;
-    }
-    return (ret ? ret : (str[x] ? NOMATCH : MATCH));
-}
-
-int _shexp_match_noicmp(const char *str, const char *exp)
-{
-    register int x,y;
-    int ret,neg;
-
-    ret = 0;
-    for(x=0,y=0;exp[y];++y,++x) {
-        if((!str[x]) && (exp[y] != '(') && (exp[y] != '$') && (exp[y] != '*'))
-            ret = ABORTED;
-        else {
-            switch(exp[y]) {
-              case '$':
-                if( (str[x]) )
-                    ret = NOMATCH;
-                else
-                    --x;             /* we don't want loop to increment x */
-                break;
-              case '*':
-                while(exp[++y] == '*');
-                if(!exp[y])
-                    return MATCH;
-                while(str[x]) {
-                    switch(_shexp_match_noicmp(&str[x++],&exp[y])) {
-                    case NOMATCH:
-                        continue;
-                    case ABORTED:
-                        ret = ABORTED;
-                        break;
-                    default:
-                        return MATCH;
-                    }
-                    break;
-                }
-                if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
-                    return MATCH;
-                else
-                    ret = ABORTED;
-                break;
-              case '[':
-                if((neg = ((exp[++y] == '^') && (exp[y+1] != ']'))))
-                    ++y;
-
-                if((isalnum(exp[y])) && (exp[y+1] == '-') &&
-                   (isalnum(exp[y+2])) && (exp[y+3] == ']'))
-                    {
-                        int start = exp[y], end = exp[y+2];
-
-                        /* Droolproofing for pinheads not included */
-                        if(neg ^ ((str[x] < start) || (str[x] > end))) {
-                            ret = NOMATCH;
-                            break;
-                        }
-                        y+=3;
-                    }
-                else {
-                    int matched;
-
-                    for(matched=0;exp[y] != ']';y++)
-                        matched |= (str[x] == exp[y]);
-                    if(neg ^ (!matched))
-                        ret = NOMATCH;
-                }
-                break;
-              case '(':
-                return handle_union_noicmp(&str[x],&exp[y]);
-                break;
-              case '?':
-                break;
-              case '\\':
-                ++y;
-              default:
-                if(str[x] != exp[y])
-                    ret = NOMATCH;
-                break;
-            }
-        }
-        if(ret)
-            break;
-    }
-    return (ret ? ret : (str[x] ? NOMATCH : MATCH));
-}
-
-NSAPI_PUBLIC int shexp_match(const char *str, const char *exp)
-{
-    register int x;
-    char *expbase = NULL;
-
-    for(x=strlen(exp)-1;x;--x) {
-        if((exp[x] == '~') && (exp[x-1] != '\\')) {
-            /* we're done if the negative subexp matches */
-            if(_shexp_match(str,&exp[x+1]) == MATCH)
-                return 1;
-            /* we're done if the only thing in front of the subexp is '*' */
-            if (x == 1 && exp[0] == '*')
-                return 0;
-            /* create a copy so we can strip off the subexp */
-            expbase = STRDUP(exp);
-            expbase[x] = '\0';
-            exp = expbase;
-            break;
-        }
-    }
-    if(_shexp_match(str,exp) == MATCH) {
-        if (expbase)
-            FREE(expbase);
-        return 0;
-    }
-
-    if (expbase)
-        FREE(expbase);
-    return 1;
-}
-
-NSAPI_PUBLIC int shexp_match_noicmp(const char *str, const char *exp)
-{
-    register int x;
-    char *expbase = NULL;
-
-    for(x=strlen(exp)-1;x;--x) {
-        if((exp[x] == '~') && (exp[x-1] != '\\')) {
-            /* we're done if the negative subexp matches */
-            if(_shexp_match_noicmp(str,&exp[x+1]) == MATCH)
-                return 1;
-            /* we're done if the only thing in front of the subexp is '*' */
-            if (x == 1 && exp[0] == '*')
-                return 0;
-            /* create a copy so we can strip off the subexp */
-            expbase = STRDUP(exp);
-            expbase[x] = '\0';
-            exp = expbase;
-            break;
-        }
-    }
-    if(_shexp_match_noicmp(str,exp) == MATCH) {
-        if (expbase)
-            FREE(expbase);
-        return 0;
-    }
-
-    if (expbase)
-        FREE(expbase);
-    return 1;
-}
-
-/* ------------------------------ shexp_cmp ------------------------------- */
-
-
-NSAPI_PUBLIC int shexp_cmp(const char *str, const char *exp)
-{
-    switch(shexp_valid(exp)) {
-      case INVALID_SXP:
-        return -1;
-      case NON_SXP:
-#ifdef XP_UNIX
-        return (strcmp(exp,str) ? 1 : 0);
-#else  /* XP_WIN32 */
-        return (stricmp(exp,str) ? 1 : 0);
-#endif /* XP_WIN32 */
-      default:
-        return shexp_match(str, exp);
-    }
-}
-
-/* ------------------------------ shexp_cmp ------------------------------- */
-
-NSAPI_PUBLIC int shexp_noicmp(const char *str, const char *exp)
-{
-    switch(shexp_valid(exp)) {
-      case INVALID_SXP:
-        return -1;
-      case NON_SXP:
-        return (strcmp(exp,str) ? 1 : 0);
-      default:
-        return shexp_match_noicmp(str, exp);
-    }
-}
-
-/* ---------------------------- shexp_casecmp ----------------------------- */
-
-
-NSAPI_PUBLIC int shexp_casecmp(const char *str, const char *exp)
-{
-    char *lstr = STRDUP(str), *lexp = STRDUP(exp), *t;
-    int ret;
-
-    for(t = lstr; *t; t++)
-        if(isalpha(*t)) *t = tolower(*t);
-    for(t = lexp; *t; t++)
-        if(isalpha(*t)) *t = tolower(*t);
-
-    switch(shexp_valid(lexp)) {
-      case INVALID_SXP:
-        ret = -1;
-        break;
-      case NON_SXP:
-        ret = (strcmp(lexp, lstr) ? 1 : 0);
-        break;
-      default:
-        ret = shexp_match(lstr, lexp);
-    }
-    FREE(lstr);
-    FREE(lexp);
-    return ret;
-}
-
--- a/src/server/shexp.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_SHEXP_H
-#define BASE_SHEXP_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * shexp.h: Defines and prototypes for shell exp. match routines
- *
- *
- * This routine will match a string with a shell expression. The expressions
- * accepted are based loosely on the expressions accepted by zsh.
- *
- * o * matches anything
- * o ? matches one character
- * o \ will escape a special character
- * o $ matches the end of the string
- * o [abc] matches one occurence of a, b, or c. The only character that needs
- *         to be escaped in this is ], all others are not special.
- * o [a-z] matches any character between a and z
- * o [^az] matches any character except a or z
- * o ~ followed by another shell expression will remove any pattern
- *     matching the shell expression from the match list
- * o (foo|bar) will match either the substring foo, or the substring bar.
- *             These can be shell expressions as well.
- *
- * The public interface to these routines is documented in
- * public/base/shexp.h.
- *
- * Rob McCool
- *
- */
-
-/*
- * Requires that the macro MALLOC be set to a "safe" malloc that will
- * exit if no memory is available. If not under MCC httpd, define MALLOC
- * to be the real malloc and play with fire, or make your own function.
- */
-
-#ifndef NETSITE_H
-#include "netsite.h"
-#endif /* !NETSITE_H */
-
-#ifndef OS_CTYPE_H
-#include <ctype.h>  /* isalnum */
-#define OS_CTYPE_H
-#endif /* !OS_CTYPE_H */
-
-#ifndef OS_STRING_H
-#include <string.h> /* strlen */
-#define OS_STRING_H
-#endif /* !OS_STRING_H */
-
-/* See public/base/shexp.h or public/base/regexp.h concerning USE_REGEX */
-
-/*
- * This little bit of nonsense is because USE_REGEX is currently
- * supposed to be recognized only by the proxy.  If that's the
- * case, only the proxy should define USE_REGEX, but I'm playing
- * it safe.  XXXHEP 12/96
- */
-#ifndef MCC_PROXY
-#ifdef USE_REGEX
-#define SAVED_USE_REGEX USE_REGEX
-#undef USE_REGEX
-#endif /* USE_REGEX */
-#endif /* !MCC_PROXY */
-
-/* --- Begin function prototypes --- */
-
-#ifdef INTNSAPI
-
-NSPR_BEGIN_EXTERN_C
-
-NSAPI_PUBLIC int INTshexp_valid(const char *exp);
-
-NSAPI_PUBLIC int INTshexp_match(const char *str, const char *exp);
-
-NSAPI_PUBLIC int INTshexp_cmp(const char *str, const char *exp);
-
-NSAPI_PUBLIC int INTshexp_noicmp(const char *str, const char *exp);
-
-NSAPI_PUBLIC int INTshexp_casecmp(const char *str, const char *exp);
-
-NSPR_END_EXTERN_C
-
-/* --- End function prototypes --- */
-
-#define shexp_valid INTshexp_valid
-#define shexp_match INTshexp_match
-#define shexp_cmp INTshexp_cmp
-#define shexp_noicmp INTshexp_noicmp
-#define shexp_casecmp INTshexp_casecmp
-
-#endif /* INTNSAPI */
-
-/* Restore USE_REGEX definition for non-proxy.  See above. */
-#ifdef SAVED_USE_REGEX
-#define USE_REGEX SAVED_USE_REGEX
-#undef SAVED_USE_REGEX
-#endif /* SAVED_USE_REGEX */
-
-#ifdef USE_REGEX
-#include "base/regexp.h"
-#endif /* USE_REGEX */
-
-#endif /* !BASE_SHEXP_H */
--- a/src/server/sstring.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include "sstring.h"
-
-sstr_t sstr (char *s) {
-    sstr_t string;
-    string.ptr = s;
-    string.length = strlen(s);
-    return string;
-}
-
-sstr_t sstrn (char *s, size_t n) {
-    sstr_t string;
-    string.ptr = s;
-    string.length = n;
-    return string;
-}
-
-size_t sstrnlen (size_t n, sstr_t s, ...) {
-    va_list ap;
-    size_t size = s.length;
-    va_start(ap, s);
-
-    for (int i=0;i<n-1;i++) {
-        sstr_t str = va_arg(ap, sstr_t);
-        size += str.length;
-    }
-
-    return size;
-}
-
-sstr_t sstrcat (sstr_t s, ...) {
-    va_list ap;
-    va_start(ap, s);
-    s.ptr[0] = 0;
-
-    sstr_t str = va_arg (ap, sstr_t);
-    while (str.ptr != NULL) {
-        s.ptr = strncat (s.ptr, str.ptr, s.length);
-        str = va_arg (ap, sstr_t);
-    }
-    
-    return s;
-}
-
-sstr_t sstrncat (size_t n, sstr_t s, sstr_t c1, ...) {
-    va_list ap;
-    va_start(ap, c1);
-    s.ptr[0] = 0;
-
-    s.ptr = strncat (s.ptr, c1.ptr, s.length);
-    for (int i=0;i<n-1;i++) {
-        sstr_t str = va_arg (ap, sstr_t);
-        s.ptr = strncat (s.ptr, str.ptr, s.length);
-    }
-
-    return s;
-}
-
-sstr_t sstrsubs (sstr_t s, size_t start) {
-    return sstrsubsl (s, start, s.length-start);
-}
-
-sstr_t sstrsubsl (sstr_t s, size_t start, size_t length) {
-    sstr_t new_sstr;
-    if (start < 0 || start >= s.length || length < 0) {
-        return s;
-    }
-    if (length > s.length-start) {
-        length = s.length-start;
-    }
-    new_sstr.ptr = &s.ptr[start];
-    new_sstr.length = length;
-    return new_sstr;
-}
-
-int sstrcmp(sstr_t s1, sstr_t s2) {
-    return strncmp(s1.ptr, s2.ptr, s1.length>s2.length ? s2.length: s1.length);
-}
-
-sstr_t sstrdub(sstr_t s) {
-    sstr_t newstring;
-    newstring.ptr = malloc(s.length + 1);
-    newstring.length = s.length;
-    newstring.ptr[newstring.length] = 0;
-
-    memcpy(newstring.ptr, s.ptr, s.length);
-
-    return newstring;
-}
--- a/src/server/sstring.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SSTRING_H
-#define	_SSTRING_H
-
-#define S(s) { s, sizeof(s)-1 }
-#define ST(s) sstrn(s, sizeof(s)-1)
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct sstring {
-    char   *ptr;
-    size_t length;
-} sstr_t;
-
-/*
- * creates a new sstr_t from a null terminated string
- *
- * s  null terminated string
- */
-sstr_t sstr (char *s);
-
-/*
- * creates a new sstr_t from a string and length
- *
- * s  string
- * n  length of string
- */
-sstr_t sstrn (char *s, size_t n);
-
-
-/*
- * gets the length of n sstr_t strings
- *
- * n    number of strings
- * s    string
- * ...  strings
- */
-size_t sstrnlen (size_t n, sstr_t s, ...);
-
-
-/*
- * concatenates n strings
- *
- * n    number of strings
- * s    new string with enough memory allocated
- * ...  strings
- */
-sstr_t sstrncat (size_t n, sstr_t s, sstr_t c1, ...);
-
-
-/*
- * 
- */
-sstr_t sstrsubs (sstr_t s, size_t start);
-
-/*
- * 
- */
-sstr_t sstrsubsl (sstr_t s, size_t start, size_t end);
-
-
-int sstrcmp(sstr_t s1, sstr_t s2);
-
-sstr_t sstrdub(sstr_t s);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* _SSTRING_H */
-
--- a/src/server/strbuf.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "strbuf.h"
-#include "sstring.h"
-
-sbuf_t* sbuf_new(size_t size) {
-    sbuf_t *buf = malloc(sizeof(sbuf_t));
-
-    buf->ptr = malloc(size);
-    buf->ptr[0] = 0;
-    buf->size = size;
-    buf->length = 0;
-
-    return buf;
-}
-
-void sbuf_puts(sbuf_t *buf, char *str) {
-    sbuf_append(buf, sstr(str));
-}
-
-void sbuf_put(sbuf_t *buf, char chr) {
-    sbuf_append(buf, sstrn(&chr, 1));
-}
-
-void sbuf_append(sbuf_t *buf, sstr_t str) {
-    if (buf->length + str.length >= buf->size) {
-        buf->size *= 2;
-        buf->ptr = realloc(buf->ptr, buf->size);
-        sbuf_append(buf, str);
-        return;
-    }
-
-    memcpy(&buf->ptr[buf->length], str.ptr, str.length);
-    buf->length += str.length;
-    buf->ptr[buf->length] = 0;
-}
-
-void sbuf_free(sbuf_t *buf) {
-    free(buf->ptr);
-    free(buf);
-}
--- a/src/server/strbuf.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef STRBUF_H
-#define	STRBUF_H
-
-#include "sstring.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/* string buffer */
-typedef struct _strbuf {
-    char *ptr;
-    size_t length;  /* length of string */
-    size_t size;    /* allocated size */
-} sbuf_t;
-
-sbuf_t* sbuf_new(size_t size);
-
-void sbuf_puts(sbuf_t *buf, char *str);
-
-void sbuf_put(sbuf_t *buf, char chr);
-
-void sbuf_append(sbuf_t *buf, sstr_t str);
-
-void sbuf_free(sbuf_t *buf);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* STRBUF_H */
--- a/src/server/system.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * system.c: A grab bag of system-level abstractions
- * 
- * Many authors
- */
-
-#if (defined(__GNUC__) && (__GNUC__ > 2))
-#include <new>
-using namespace std;
-#else
-//include <new.h>
-#endif
-#include "netsite.h"
-#include "ereport.h"
-
-#ifdef XP_WIN32
-#include <windows.h>
-#include <process.h>
-#endif
-
-static int thread_malloc_key = -1;
-
-static char* temp_dir = NULL;
-
-#ifdef XP_WIN32
-_PNH original_newhandler = 0;
-#else
-typedef void (newhandler)(void);
-static newhandler *original_newhandler = 0;
-#endif
-
-#include "pool.h"
-#include "systhr.h"
-
-#define MALLOC_KEY \
-    ((pool_handle_t *)(thread_malloc_key != -1 ? systhread_getdata(thread_malloc_key) : NULL))
-
-
-#ifdef MCC_DEBUG
-#define DEBUG_MALLOC
-#endif
-
-#ifdef DEBUG_MALLOC
-
-/* The debug malloc routines provide several functions:
- *
- *  - detect allocated memory overflow/underflow
- *  - detect multiple frees
- *  - intentionally clobbers malloc'd buffers
- *  - intentionally clobbers freed buffers
- */
-#define DEBUG_MAGIC 0x12345678
-#define DEBUG_MARGIN 32
-#define DEBUG_MARGIN_CHAR '*'
-#define DEBUG_MALLOC_CHAR '.'
-#define DEBUG_FREE_CHAR   'X'
-#endif /* DEBUG_MALLOC */
-
-NSAPI_PUBLIC char *system_version()
-{
-    //return PRODUCT_ID"/"PRODUCT_VERSION_ID;
-    return "Solaris 11 Express";
-}
-
-NSAPI_PUBLIC pool_handle_t *system_pool(void)
-{
-    return MALLOC_KEY;
-}
-
-NSAPI_PUBLIC void *system_malloc(int size)
-{
-    void *ret;
-    ret = pool_malloc(MALLOC_KEY, size);
-    if (!ret) {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-    return ret;
-}
-
-
-NSAPI_PUBLIC void *system_calloc(int size)
-{
-    void *ret;
-    ret = pool_malloc(MALLOC_KEY, size);
-    if(ret) {
-        ZERO(ret, size);
-    } else {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-    return ret;
-}
-
-
-NSAPI_PUBLIC void *system_realloc(void *ptr, int size)
-{
-    void *ret;
-    ret = pool_realloc(MALLOC_KEY, ptr, size);
-    if (!ret) {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-    return ret;
-}
-
-
-NSAPI_PUBLIC void system_free(void *ptr)
-{
-    pool_free(MALLOC_KEY, ptr);
-}
-
-NSAPI_PUBLIC char *system_strdup(const char *ptr)
-{
-    //NS_ASSERT(ptr);
-    char *ret;
-    ret = pool_strdup(MALLOC_KEY, ptr);
-    if (!ret) {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-    return ret;
-}
-
-
-NSAPI_PUBLIC void *system_malloc_perm(int size)
-{
-    void *ret;
-#ifndef DEBUG_MALLOC
-    ret = malloc(size);
-#else
-    char *ptr = (char *)malloc(size + 2*DEBUG_MARGIN+2*sizeof(int));
-    char *real_ptr;
-    int *magic;
-    int *length;
-  
-    magic = (int *)ptr;
-    *magic = DEBUG_MAGIC;
-    ptr += sizeof(int);
-    length = (int *)ptr;
-    *length = size;
-    ptr += sizeof(int);
-    memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN);
-    ptr += DEBUG_MARGIN;
-    memset(ptr, DEBUG_MALLOC_CHAR, size);
-    real_ptr = ptr;
-    ptr += size;
-    memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN);
-
-    ret = real_ptr;
-#endif
-    if (!ret) {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-    return ret;
-}
-
-NSAPI_PUBLIC void *system_calloc_perm(int size)
-{
-    void *ret = system_malloc_perm(size);
-    if(ret)
-        ZERO(ret, size);
-    return ret;
-}
-
-NSAPI_PUBLIC void *system_realloc_perm(void *ptr, int size)
-{
-    void *ret;
-
-#ifndef DEBUG_MALLOC
-    ret = realloc(ptr, size);
-#else
-    int *magic, *length;
-    char *baseptr;
-    char *cptr;
-
-    /* realloc semantics allow realloc(NULL, size) */
-    if (ptr == NULL)
-        return system_malloc_perm(size);
-
-    cptr = (char *)ptr - DEBUG_MARGIN - 2 * sizeof(int);
-    magic = (int *)cptr;
-    if (*magic == DEBUG_MAGIC) {
-        cptr += sizeof(int);
-        length = (int *)cptr;
-        if (*length < size) {
-            char *newptr = (char *)system_malloc_perm(size);
-            memcpy(newptr, ptr, *length);
-            system_free_perm(ptr);
-
-            ret = newptr;
-        }else {
-            ret = ptr;
-        }
-    } else {
-        ereport(LOG_WARN, XP_GetAdminString(DBT_systemReallocSmallerSize));
-        ret = realloc(ptr, size);
-    }
-#endif
-
-    if (!ret) {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-
-    return ret;
-}
-
-NSAPI_PUBLIC void system_free_perm(void *ptr)
-{
-#ifdef DEBUG_MALLOC
-    int *length, *magic;
-    char *baseptr, *cptr;
-    int index;
-
-    NS_ASSERT(ptr);
-
-    cptr = baseptr = ((char *)ptr) - DEBUG_MARGIN - 2*sizeof(int);
-
-    magic = (int *)cptr;
-    if (*magic == DEBUG_MAGIC) {
-        cptr += sizeof(int);
-
-        length = (int *)cptr;
-
-        cptr += sizeof(int); 
-        for (index=0; index<DEBUG_MARGIN; index++)
-            if (cptr[index] != DEBUG_MARGIN_CHAR) {
-                ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeCorruptMemoryPre));
-                break;
-            }
-
-        cptr += DEBUG_MARGIN + *length;
-        for (index=0; index<DEBUG_MARGIN; index++)
-            if (cptr[index] != DEBUG_MARGIN_CHAR) {
-                ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeCorruptMemoryPost));
-                break;
-            }
-
-        memset(baseptr, DEBUG_FREE_CHAR, *length + 2*DEBUG_MARGIN+sizeof(int));
-    } else {
-        ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeUnallocatedMem));
-    }
-    free(baseptr);
-#else
-    free(ptr);
-#endif
-}
-
-NSAPI_PUBLIC char *system_strdup_perm(const char *ptr)
-{
-    char *ret;
-
-#ifndef DEBUG_MALLOC
-    //NS_ASSERT(ptr);
-    ret = strdup(ptr);
-#else
-    int len = strlen(ptr);
-    char *nptr = (char *)system_malloc_perm(len+1);
-    memcpy(nptr, ptr, len);
-    nptr[len] = '\0';
-    ret = nptr;
-#endif
-
-    if (!ret) {
-        //ereport_outofmemory();
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-    }
-
-    return ret;
-}
-
-NSAPI_PUBLIC void system_set_temp_dir(const char *dir)
-{
-    // Leak any previously-allocated dir in case someone still has a reference
-    temp_dir = STRDUP(dir);
-}
-
-NSAPI_PUBLIC const char *system_get_temp_dir(void)
-{
-    char* dir = temp_dir;
-
-    if (!dir) {
-#ifdef XP_WIN32
-        dir = getenv("TEMP");
-        if (!dir) dir = getenv("TMP");
-        if (!dir) dir = "C:\\TEMP";
-#else
-        dir = "/tmp";
-#endif
-    }
-
-    return dir;
-}
-
-NSAPI_PUBLIC int 
-getThreadMallocKey(void)
-{
-    return thread_malloc_key;
-}
-
-NSAPI_PUBLIC void
-InitThreadMallocKey(void)
-{
-    PR_NewThreadPrivateIndex((unsigned int *)&thread_malloc_key, NULL);
-    PR_ASSERT(thread_malloc_key);
-}
-
-#ifdef XP_WIN32
-static int _cdecl system_newhandler(unsigned int size)
-{
-    //ereport_outofmemory();
-
-    if (original_newhandler) {
-        // Let original handler deal with things
-        return (*original_newhandler)(size);
-    }
-
-    // Tell new not to retry the allocation
-    return 0;
-}
-#else
-static void system_newhandler()
-{
-    // We want to preserve the original new semantics, but we don't know what
-    // those semantics are.  Some platforms throw xalloc while others throw
-    // bad_alloc.
-
-    //ereport_outofmemory();
-
-    if (original_newhandler) {
-        // Let original handler deal with things
-        (*original_newhandler)();
-    } else {
-        // No original handler to call; try to remove all handlers
-        static PRBool flagRemovedHandler = PR_FALSE;
-        if (flagRemovedHandler) {
-            abort();
-        }
-        //set_new_handler(0); // TODO: set_new_handler
-        flagRemovedHandler = PR_TRUE;
-    }
-}
-#endif
-
-NSAPI_PUBLIC void system_setnewhandler(void)
-{
-#ifdef XP_WIN32
-    original_newhandler = _set_new_handler(system_newhandler);
-#else
-    //original_newhandler = set_new_handler(system_newhandler); // TODO: ...
-#endif
-}
--- a/src/server/systems.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,541 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_SYSTEMS_H
-#define BASE_SYSTEMS_H
-
-#include <nspr.h>
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * systems.h: Lists of defines for systems
- * 
- * This sets what general flavor the system is (UNIX, etc.), 
- * and defines what extra functions your particular system needs.
- */
-
-
-/* --- Begin common definitions for all supported platforms --- */
-
-#define DAEMON_ANY
-#define DAEMON_STATS
-
-/* --- End common definitions for all supported platforms --- */
-
-/* --- Begin platform-specific definitions --- */
-
-#if defined(AIX)
-
-#define HAS_IPV6
-#define AUTH_DBM
-#define BSD_RLIMIT
-#undef BSD_SIGNALS
-//define DAEMON_NEEDS_SEMAPHORE
-//define DAEMON_UNIX_MOBRULE
-//define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW|RTLD_GLOBAL
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATFS
-#define HAVE_ATEXIT
-#define HAVE_STRERROR_R
-#define HAVE_STRTOK_R
-#define HAVE_TIME_R 2 /* arg count */
-#define HAVE_STRFTIME /* no cftime */
-#define JAVA_STATIC_LINK
-#undef NEED_CRYPT_H
-#define NEED_STRINGS_H /* for strcasecmp */
-#define NET_SOCKETS
-#define SA_HANDLER_T(x) (void (*)(int))x
-#ifdef NS_OLDES3X
-#define SA_NOCLDWAIT 0 /* AIX don't got this */
-#endif
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-#ifdef HW_THREADS
-#define THREAD_ANY
-#endif
-#elif defined(BSDI)
-
-#define AUTH_DBM
-#define BSD_MAIL
-#define BSD_RLIMIT
-#define BSD_SIGNALS
-#define BSD_TIME
-#define DAEMON_UNIX_MOBRULE
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS (MAP_FILE | MAP_SHARED)
-#define HAS_STATFS
-#define HAVE_ATEXIT
-#undef NEED_CRYPT_PROTO
-#define NET_SOCKETS
-#define NO_DOMAINNAME
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-#define JAVA_STATIC_LINK
-
-#elif defined(HPUX)
-
-#define HAVE_TIME_R 2 /* arg count */
-#define AUTH_DBM
-#undef BSD_RLIMIT
-#undef BSD_SIGNALS
-#ifdef MCC_PROXY
-#define DAEMON_NEEDS_SEMAPHORE
-#else
-#define DAEMON_NEEDS_SEMAPHORE
-#endif
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_HPSHL
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_PRIVATE
-#define HAS_STATFS
-#define HAVE_ATEXIT
-#define HAVE_STRFTIME
-#define JAVA_STATIC_LINK
-#undef NEED_CRYPT_H
-#define NET_SOCKETS
-#define SA_HANDLER_T(x) (void (*)(int))x
-#define SEM_FLOCK
-/* warning: mmap doesn't work under 9.04 */
-#define SHMEM_MMAP_FLAGS MAP_FILE | MAP_VARIABLE | MAP_SHARED
-
-#elif defined (IRIX)
-
-#define AUTH_DBM
-#define BSD_RLIMIT
-#undef BSD_SIGNALS
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define HAVE_STRTOK_R
-#define HAVE_TIME_R 2 /* arg count */
-#define JAVA_STATIC_LINK
-#define NEED_CRYPT_H
-#define NET_SOCKETS
-#define SA_HANDLER_T(x) (void (*)(int))x
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-#define THROW_HACK throw()
-
-#elif defined(Linux)
-
-#define HAS_IPV6
-#define AUTH_DBM
-#define BSD_RLIMIT
-#undef BSD_SIGNALS
-#define DAEMON_NEEDS_SEMAPHORE
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define HAVE_STRTOK_R
-#define HAVE_TIME_R 2 /* arg count */
-#define NEED_CRYPT_H
-#undef NEED_FILIO
-#define NEED_GHN_PROTO
-#define NET_SOCKETS
-#define SA_HANDLER_T(x) (void (*)(int))x
-#undef NEED_GHN_PROTO 
-
-#elif defined(NCR)
-
-#define AUTH_DBM
-#undef BSD_RLIMIT
-/* #define DAEMON_NEEDS_SEMAPHORE */
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define HAVE_STRTOK_R
-#define JAVA_STATIC_LINK
-#define NEED_CRYPT_H
-#define NEED_FILIO
-#define NEED_GHN_PROTO
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#elif defined(NEC)
-
-#define DNS_CACHE
-#define AUTH_DBM
-#undef BSD_RLIMIT
-#define DAEMON_NEEDS_SEMAPHORE
-#define DAEMON_UNIX_MOBRULE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DLL_CAPABLE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define HAVE_STRTOK_R
-#define HAVE_TIME_R 2 /* arg count */
-#define JAVA_STATIC_LINK
-#define NEED_CRYPT_H
-#define NEED_FILIO
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#elif defined(OSF1)
-
-#define HAS_IPV6
-#define AUTH_DBM
-#define BSD_RLIMIT
-#undef BSD_SIGNALS
-#define BSD_TIME
-#define DAEMON_UNIX_MOBRULE
-#define DAEMON_NEEDS_SEMAPHORE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAVE_ATEXIT
-#define HAVE_STRFTIME /* no cftime */
-#define HAVE_TIME_R 2 /* ctime_r arg count */
-#define NET_SOCKETS
-#define SA_HANDLER_T(x) (void (*)(int))x
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#elif defined(SCO)
-
-#define AUTH_DBM
-#undef BSD_RLIMIT
-#undef BSD_SIGNALS
-#define DAEMON_NEEDS_SEMAPHORE
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#undef NEED_CRYPT_H
-#undef NEED_FILIO
-#undef NEED_GHN_PROTO
-#undef NEED_SETEID_PROTO /* setegid, seteuid */
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-#define SA_HANDLER_T(x) (void (*)(int))x
-
-
-#elif defined(SNI)
-
-#define AUTH_DBM
-#undef BSD_RLIMIT
-#define DAEMON_NEEDS_SEMAPHORE
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define JAVA_STATIC_LINK
-#define NEED_CRYPT_H
-#define NEED_FILIO
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-#define USE_PIPE
-
-#elif defined(SOLARIS)
-
-#if defined(ENABLE_IPV6)
-#define HAS_IPV6
-#endif
-#define AUTH_DBM
-#define BSD_RLIMIT
-#undef BSD_SIGNALS
-#define DAEMON_NEEDS_SEMAPHORE
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW|RTLD_FIRST
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define HAVE_STRTOK_R
-#define HAVE_TIME_R 3 /* arg count */
-#define NEED_CRYPT_H
-#define NEED_FILIO
-#define NEED_GHN_PROTO
-#define NET_SOCKETS
-#if OSVERSION > 504 
-#define SA_HANDLER_T(x) x 
-#endif
-#if OSVERSION >= 506 
-#undef NEED_GHN_PROTO 
-#endif
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#elif defined (SONY)
-
-#define AUTH_DBM
-#undef BSD_RLIMIT
-#define DAEMON_NEEDS_SEMAPHORE
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAVE_ATEXIT
-#define NEED_CRYPT_H
-#define NEED_FILIO
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#elif defined(SUNOS4)
-
-#define AUTH_DBM
-#define BSD_MAIL
-#define BSD_RLIMIT
-#define BSD_SIGNALS
-#define BSD_TIME
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS 1
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATFS
-#undef HAVE_ATEXIT
-#undef NEED_CRYPT_H
-#define NEED_CRYPT_PROTO
-#define NEED_FILIO
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#elif defined(UNIXWARE)
-
-#define AUTH_DBM
-#undef BSD_RLIMIT
-#define DAEMON_UNIX_MOBRULE
-#define DLL_CAPABLE
-#define DLL_DLOPEN
-#define DLL_DLOPEN_FLAGS RTLD_NOW
-#define DNS_CACHE
-#define FILE_INHERIT_FCNTL
-#define FILE_MMAP_FLAGS MAP_SHARED
-#define HAS_STATVFS
-#define HAVE_ATEXIT
-#define NEED_CRYPT_H
-#define NEED_FILIO
-#define NEED_GHN_PROTO
-#define NEED_SETEID_PROTO /* setegid, seteuid */
-#define NET_SOCKETS
-#define SEM_FLOCK
-#define SHMEM_MMAP_FLAGS MAP_SHARED
-
-#ifndef boolean
-#define boolean boolean
-#endif
-
-#elif defined (XP_WIN32)      /* Windows NT */
-
-#include <wtypes.h>
-#include <winbase.h>
-
-#define AUTH_DBM
-#define DAEMON_WIN32
-#define DLL_CAPABLE
-#define DLL_WIN32
-#define DNS_CACHE
-#define LOG_BUFFERING
-#define HAVE_STRFTIME /* no cftime */
-#define NEED_CRYPT_PROTO
-#define NEEDS_WRITEV
-#define NET_SOCKETS
-#define NO_DOMAINNAME
-#ifdef BUILD_DLL
-#if defined (NSAPI_PUBLIC)
-#undef  NSAPI_PUBLIC
-#endif
-#define NSAPI_PUBLIC __declspec(dllexport)
-#else
-#if defined (NSAPI_PUBLIC)
-#undef  NSAPI_PUBLIC
-#endif
-#define NSAPI_PUBLIC
-#endif /* BUILD_DLL */
-#define SEM_WIN32
-#define THREAD_ANY
-#define THREAD_NSPR_KERNEL
-#define USE_NSPR
-#define USE_STRFTIME /* no cftime */
-#define FILE_DEV_NULL "\\\\.\NUL"
-
-#endif	/* Windows NT */
-
-/* --- Begin defaults for values not defined above --- */
-
-#ifndef DAEMON_LISTEN_SIZE
-#define DAEMON_LISTEN_SIZE 128
-#endif /* !DAEMON_LISTEN_SIZE */
-
-#ifndef NSAPI_PUBLIC
-#define NSAPI_PUBLIC
-#endif
-
-#ifndef SA_HANDLER_T
-#define SA_HANDLER_T(x) (void (*)())x 
-#endif
-
-#ifndef THROW_HACK
-#define THROW_HACK /* as nothing */
-#endif
-
-#ifndef FILE_DEV_NULL
-#define FILE_DEV_NULL "/dev/null"
-#endif
-
-/* --- End defaults for values not defined above --- */
-
-/* --- Begin the great debate --- */
-
-/* NS_MAIL builds sec-key.c which calls systhread_init, which requires */
-/* that USE_NSPR is defined when systhr.c is compiled.  --lachman */
-/* MCC_PROXY does the same thing now --nbreslow -- LIKE HELL --ari */
-#if (defined(MCC_HTTPD) || defined(MCC_ADMSERV) || defined(MCC_PROXY) || defined(NS_MAIL)) && defined(XP_UNIX)
-#define USE_NSPR
-/* XXXrobm This is UNIX-only for the moment */
-#define LOG_BUFFERING
-#ifdef SW_THREADS
-#define THREAD_NSPR_USER
-#else
-#define THREAD_NSPR_KERNEL
-#endif
-#define THREAD_ANY
-#endif
-
-/* --- End the great debate --- */
-
-#ifndef APSTUDIO_READONLY_SYMBOLS
-
-#ifndef NSPR_PRIO_H
-//include "prio.h"
-#define NSPR_PRIO_H
-#endif /* !NSPR_PRIO_H */
-
-/*
- * These types have to be defined early, because they are defined
- * as (void *) in the public API.
- */
-
-#ifndef SYS_FILE_T
-typedef PRFileDesc *SYS_FILE;
-#define SYS_FILE_T PRFileDesc *
-#endif /* !SYS_FILE_T */
-
-#ifndef SYS_NETFD_T
-typedef PRFileDesc *SYS_NETFD;
-#define SYS_NETFD_T PRFileDesc *
-#endif /* !SYS_NETFD_T */
-
-#ifdef SEM_WIN32
-
-typedef HANDLE SEMAPHORE;
-#define SEMAPHORE_T HANDLE
-#define SEM_ERROR NULL
-/* That oughta hold them (I hope) */
-#define SEM_MAXVALUE 32767
-
-#elif defined(SEM_FLOCK)
-
-//define SEMAPHORE_T int
-//typedef int SEMAPHORE;
-//define SEM_ERROR -1
-
-#elif defined(SEM_POSIX)
-
-#define SEM_ERROR ((void *)(-1))
-typedef	void* SEMAPHORE_T;
-
-#else /* ! SEM_WIN32 */
-
-typedef int SEMAPHORE;
-#define SEMAPHORE_T int
-#define SEM_ERROR -1
-
-#endif /* SEM_WIN32 */
-
-#endif /* !APSTUDIO_READONLY_SYMBOLS */
-
-#ifndef XP_CPLUSPLUS
-#ifdef __cplusplus
-#define XP_CPLUSPLUS
-#endif /* __cplusplus */
-#endif /* !XP_CPLUSPLUS */
-
-#endif /* BASE_SYSTEMS_H */
--- a/src/server/systhr.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * systhr.c: Abstracted threading mechanisms
- * 
- * Rob McCool
- */
-
-
-#include "systhr.h"
-#include "ereport.h"
-
-#include "prinit.h"
-#include "prthread.h"
-#include "private/pprthred.h"
-
-#include "systems.h"
-
-#ifdef XP_UNIX
-#include <poll.h>
-#endif
-
-#ifdef THREAD_WIN32
-#include <process.h>
-
-typedef struct {
-    HANDLE hand;
-    DWORD id;
-} sys_thread_s;
-
-#endif
-
-#define DEFAULT_STACKSIZE (64*1024)
-
-static unsigned long _systhr_stacksize = DEFAULT_STACKSIZE;
-
-NSAPI_PUBLIC 
-void systhread_set_default_stacksize(unsigned long size)
-{
-	_systhr_stacksize = size;
-}
-
-NSAPI_PUBLIC 
-SYS_THREAD systhread_start(int prio, int stksz, thrstartfunc fn, void *arg)
-{
-    PRThread *ret = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))fn,
-				    (void *)arg, (PRThreadPriority)prio, 
-				    PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
-                                    stksz ? stksz : _systhr_stacksize);
-    return (void *) ret;
-}
-
-
-NSAPI_PUBLIC SYS_THREAD systhread_current(void)
-{
-    return PR_GetCurrentThread();
-}
-
-NSAPI_PUBLIC void systhread_yield(void)
-{
-    PR_Sleep(PR_INTERVAL_NO_WAIT);
-}
-
-
-NSAPI_PUBLIC void systhread_timerset(int usec)
-{
-   /* This is an interesting problem.  If you ever do turn on interrupts
-    * on the server, you're in for lots of fun with NSPR Threads
-   PR_StartEvents(usec); */
-}
-
-
-NSAPI_PUBLIC 
-SYS_THREAD systhread_attach(void)
-{
-    PRThread *ret;
-    ret = PR_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL);
-
-    return (void *) ret;
-}
-
-NSAPI_PUBLIC
-void systhread_detach(SYS_THREAD thr)
-{
-    /* XXXMB - this is not correct! */
-    PR_DetachThread();
-}
-
-NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
-{
-    PR_Interrupt((PRThread *)thr);
-}
-
-NSAPI_PUBLIC void systhread_sleep(int milliseconds)
-{
-#ifdef XP_WIN32
-    PR_Sleep(PR_MillisecondsToInterval(milliseconds));
-#else
-    /* poll() is more efficient than PR_Sleep() */
-    if (milliseconds > 0)
-        poll(NULL, NULL, milliseconds);
-#endif
-}
-
-NSAPI_PUBLIC void systhread_init(char *name)
-{
-    if (!PR_Initialized()) {
-        PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
-    }
-    // XXX: ruslan - this bug can potentially exist on all plafroms due to
-    //	possible priority inversion on NSPR spin locks. This code will
-    //	need to be remove as we get new NSPR drop
-    // <WORKAROUND>
-    /* VB: This is to fix bug# 364813 coupled with NSPR not wanting to patch
-           their problems. The fix is to prevent NSPR itself from
-           using atomic stacks.
-    */
-    // ruslan: this problem exists on DEC also. We will roll it back when
-    //	we have the right fix from NSPR group. It has smth. to do with
-    //	atomic operations on DEC, it's an assembly code which is different
-    //	for every platform. NSPR_FD_CACHE_SIZE_HIGH env var will cause the
-    //	same effect as this fix. Debug version of NSPR always works as it doesn't
-    //  have FD stack.
-
-    int maxPRFdCache = 8192;
-    PR_SetFDCacheSize(0, maxPRFdCache);
-    // </WORKAROUND>
-}
-
-
-NSAPI_PUBLIC int systhread_newkey()
-{
-    uintn newkey;
-
-    PR_NewThreadPrivateIndex(&newkey, NULL);
-    return (newkey);
-}
-
-NSAPI_PUBLIC void *systhread_getdata(int key)
-{
-    return PR_GetThreadPrivate(key);
-}
-
-NSAPI_PUBLIC void systhread_setdata(int key, void *data)
-{
-    PR_SetThreadPrivate(key, data);
-}
-
-NSAPI_PUBLIC void systhread_dummy(void)
-{
-}
--- a/src/server/systhr.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_SYSTHR_H
-#define BASE_SYSTHR_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * systhr.h: Abstracted threading mechanisms
- * 
- * Rob McCool
- */
-
-#ifndef NETSITE_H
-#include "netsite.h"
-#include "nsapi.h"
-#include "nspr.h"
-#endif /* !NETSITE_H */
-
-#define THREAD_ANY
-#ifdef THREAD_ANY
-
-/* --- Begin function prototypes --- */
-
-#define INTNSAPI
-#ifdef INTNSAPI
-
-NSPR_BEGIN_EXTERN_C
-
-NSAPI_PUBLIC
-SYS_THREAD INTsysthread_start(int prio, int stksz, thrstartfunc fn, void *arg);
-
-NSAPI_PUBLIC SYS_THREAD INTsysthread_current(void);
-
-NSAPI_PUBLIC void INTsysthread_yield(void);
-
-NSAPI_PUBLIC SYS_THREAD INTsysthread_attach(void);
-
-NSAPI_PUBLIC void INTsysthread_detach(SYS_THREAD thr);
-
-NSAPI_PUBLIC void INTsysthread_terminate(SYS_THREAD thr);
-
-NSAPI_PUBLIC void INTsysthread_sleep(int milliseconds);
-
-NSAPI_PUBLIC void INTsysthread_init(char *name);
-
-NSAPI_PUBLIC void INTsysthread_timerset(int usec);
-
-NSAPI_PUBLIC int INTsysthread_newkey(void);
-
-NSAPI_PUBLIC void *INTsysthread_getdata(int key);
-
-NSAPI_PUBLIC void INTsysthread_setdata(int key, void *data);
-
-NSAPI_PUBLIC 
-void INTsysthread_set_default_stacksize(unsigned long size);
-
-NSPR_END_EXTERN_C
-
-/* --- End function prototypes --- */
-
-#define systhread_start INTsysthread_start
-#define systhread_current INTsysthread_current
-#define systhread_yield INTsysthread_yield
-#define systhread_attach INTsysthread_attach
-#define systhread_detach INTsysthread_detach
-#define systhread_terminate INTsysthread_terminate
-#define systhread_sleep INTsysthread_sleep
-#define systhread_init INTsysthread_init
-#define systhread_timerset INTsysthread_timerset
-#define systhread_newkey INTsysthread_newkey
-#define systhread_getdata INTsysthread_getdata
-#define systhread_setdata INTsysthread_setdata
-#define systhread_set_default_stacksize INTsysthread_set_default_stacksize
-
-#endif /* INTNSAPI */
-
-#endif /* THREAD_ANY */
-
-#endif /* !BASE_SYSTHR_H */
--- a/src/server/thrpool.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "thrpool.h"
-
-
-
-threadpool_t* threadpool_new(int n) {
-    threadpool_t *pool = malloc(sizeof(threadpool_t));
-    pool->queue = NULL;
-    pool->queue_len = 0;
-
-    pthread_mutex_init(&pool->queue_lock, NULL);
-    pthread_mutex_init(&pool->avlbl_lock, NULL);
-    pthread_cond_init(&pool->available, NULL);
-
-    /* create pool threads */
-    for(int i=0;i<n;i++) {
-        pthread_t t;
-        if (pthread_create(&t, NULL, threadpool_func, pool) != 0) {
-            perror("Error: threadpool_new: pthread_create");
-            return NULL;
-        }
-    }
-
-    return pool;
-}
-
-void* threadpool_func(void *data) {
-    threadpool_t *pool = (threadpool_t*)data;
-
-    for(;;) {
-        threadpool_job *job = threadpool_get_job(pool);
-        if(job == NULL) {
-            break;
-        }
-
-        job->callback(job->data);
-
-        free(job);
-    }
-    return NULL;
-}
-
-threadpool_job* threadpool_get_job(threadpool_t *pool) {
-    pthread_mutex_lock(&pool->queue_lock);
-
-    threadpool_job *job = NULL;
-    while(job == NULL) {
-        if(pool->queue_len == 0) {
-            pthread_cond_wait(&pool->available, &pool->queue_lock);
-            continue;
-        } else {
-            pool_queue_t *q = pool->queue;
-            job = q->job;
-            pool->queue = q->next;
-            pool->queue_len--;
-            free(q);
-        }
-    }
-
-    pthread_mutex_unlock(&pool->queue_lock);
-
-    return job;
-}
-
-void threadpool_run(threadpool_t *pool, job_callback_f func, void *data) {
-    threadpool_job *job = malloc(sizeof(threadpool_job));
-    job->callback = func;
-    job->data = data;
-
-    pool_queue_t *q = malloc(sizeof(pool_queue_t));
-    q->job = job;
-    q->next = NULL;
-
-    pthread_mutex_lock(&pool->queue_lock);
-    if(pool->queue == NULL) {
-        pool->queue = q;
-    } else {
-        pool_queue_t *last_elem = pool->queue;
-        while(last_elem->next != NULL) {
-            last_elem = last_elem->next;
-        }
-        last_elem->next = q;
-    }
-    pool->queue_len++;
-
-    if(pool->queue_len == 1) {
-        pthread_cond_signal(&pool->available);
-    }
-
-    pthread_mutex_unlock(&pool->queue_lock);
-
-}
--- a/src/server/thrpool.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THREADPOOL_H
-#define	THREADPOOL_H
-
-#include <pthread.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct _pool_queue pool_queue_t;
-typedef struct _thread_pool {
-    pthread_mutex_t queue_lock;
-    pthread_mutex_t avlbl_lock;
-    pthread_cond_t  available;
-    int             queue_len;
-    pool_queue_t    *queue;
-} threadpool_t;
-
-typedef void*(*job_callback_f)(void *data);
-typedef struct _threadpool_job {
-    job_callback_f  callback;
-    void            *data;
-} threadpool_job;
-
-struct _pool_queue {
-    threadpool_job   *job;
-    pool_queue_t     *next;
-};
-
-
-threadpool_t* threadpool_new(int n);
-
-void* threadpool_func(void *data);
-
-threadpool_job* threadpool_get_job(threadpool_t *pool);
-
-void threadpool_run(threadpool_t *pool, job_callback_f func, void *data);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* THREADPOOL_H */
--- a/src/server/ucx.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * File:   ucx.h
- * Author: olaf
- *
- * Created on 31. Dezember 2011, 17:17
- */
-
-#ifndef UCX_H
-#define	UCX_H
-
-#include <stdlib.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef int(*ucx_callback)(void*,void*);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/Makefile	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,44 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BUILD_ROOT = ../../../
+OBJ_DIR = $(BUILD_ROOT)build/
+
+CFLAGS  = -g
+LDFLAGS = 
+
+include objs.mk
+
+all: $(UCXOBJS)
+
+$(UCX_OBJPRE)%.o: %.c
+	cc -o $@ -c $(CFLAGS) $<
+
+$(UCX_OBJPRE)%.o: %.cpp
+	CC -o $@ -c $(CFLAGS) $<
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/dlist.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,102 @@
+#include "dlist.h"
+
+void ucx_dlist_free(UcxDlist *l) {
+    UcxDlist *e = l, *f;
+    while (e != NULL) {
+        f = e;
+        e = e->next;
+        free(f);
+    }
+}
+
+UcxDlist *ucx_dlist_append(UcxDlist *l, void *data)  {
+    UcxDlist *nl = (UcxDlist*) malloc(sizeof(UcxDlist));
+    if (nl == NULL) return NULL;
+
+    nl->data = data;
+    nl->next = NULL;
+    if (l == NULL) {
+        return nl;
+    } else {
+        UcxDlist *t = ucx_dlist_last(l);
+        t->next = nl;
+        nl->prev = t;
+        return l;
+    }
+}
+
+UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data) {
+    UcxDlist *nl = ucx_dlist_append(NULL, data);
+    if (nl == NULL) return NULL;
+
+    if (l != NULL) {
+        nl->next = l;
+        l->prev = nl;
+    }
+    return nl;
+}
+
+UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2) {
+    if (l1 == NULL) {
+        return l2;
+    } else {
+        UcxDlist *last = ucx_dlist_last(l1);
+        last->next = l2;
+        l2->prev = last;
+        return l1;
+    }
+}
+
+UcxDlist *ucx_dlist_last(UcxDlist *l) {
+    if (l == NULL) return NULL;
+
+    UcxDlist *e = l;
+    while (e->next != NULL) {
+        e = e->next;
+    }
+    return e;
+}
+
+UcxDlist *ucx_dlist_get(UcxDlist *l, int index) {
+    if (l == NULL) return NULL;
+
+    UcxDlist *e = l;
+    while (e->next != NULL && index > 0) {
+        e = e->next;
+        index--;
+    }
+
+    return index == 0 ? e : NULL;
+}
+
+size_t ucx_dlist_size(UcxDlist *l) {
+    if (l == NULL) return 0;
+
+    UcxDlist *e = l;
+    size_t s = 1;
+    while (e->next != NULL) {
+        e = e->next;
+        s++;
+    }
+
+    return s;
+}
+
+void ucx_dlist_foreach(UcxDlist *l, ucx_callback fnc, void* data) {
+    UcxDlist *e = l;
+    while (e != NULL) {
+        fnc(e, data);
+        e = e->next;
+    }
+}
+
+/* dlist specific functions */
+UcxDlist *ucx_dlist_first(UcxDlist *l) {
+    if (l == NULL) return NULL;
+
+    UcxDlist *e = l;
+    while (e->prev != NULL) {
+        e = e->prev;
+    }
+    return e;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/dlist.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ *
+ */
+
+#ifndef DLIST_H
+#define	DLIST_H
+
+#include "ucx.h"
+#include <stddef.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct UcxDlist UcxDlist;
+struct UcxDlist {
+    void     *data;
+    UcxDlist *next;
+    UcxDlist *prev;
+};
+
+void ucx_dlist_free(UcxDlist *l);
+UcxDlist *ucx_dlist_append(UcxDlist *l, void *data);
+UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data);
+UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2);
+UcxDlist *ucx_dlist_last(UcxDlist *l);
+UcxDlist *ucx_dlist_get(UcxDlist *l, int index);
+size_t ucx_dlist_size(UcxDlist *l);
+void ucx_dlist_foreach(UcxDlist *l, ucx_callback fnc, void* data);
+
+/* dlist specific functions */
+UcxDlist *ucx_dlist_first(UcxDlist *l);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* DLIST_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/objs.mk	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,37 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+UCX_SRC_DIR = server/ucx/
+
+UCX_OBJPRE = $(OBJ_DIR)$(UCX_SRC_DIR)
+
+UCXOBJ = dlist.o
+UCXOBJ += sstring.o
+
+UCXOBJS = $(UCXOBJ:%=$(UCX_OBJPRE)%)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/sstring.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,125 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "sstring.h"
+
+sstr_t sstr (char *s) {
+    sstr_t string;
+    if(s == NULL) {
+        string.length = 0;
+        string.ptr = NULL;
+    } else {
+        string.ptr = s;
+        string.length = strlen(s);
+    }
+    return string;
+}
+
+sstr_t sstrn (char *s, size_t n) {
+    sstr_t string;
+    string.ptr = s;
+    string.length = n;
+    return string;
+}
+
+size_t sstrnlen (size_t n, sstr_t s, ...) {
+    va_list ap;
+    size_t size = s.length;
+    va_start(ap, s);
+
+    for (int i=0;i<n-1;i++) {
+        sstr_t str = va_arg(ap, sstr_t);
+        size += str.length;
+    }
+
+    return size;
+}
+
+sstr_t sstrcat (sstr_t s, ...) {
+    va_list ap;
+    va_start(ap, s);
+    s.ptr[0] = 0;
+
+    sstr_t str = va_arg (ap, sstr_t);
+    while (str.ptr != NULL) {
+        s.ptr = strncat (s.ptr, str.ptr, s.length);
+        str = va_arg (ap, sstr_t);
+    }
+    
+    return s;
+}
+
+sstr_t sstrncat (size_t n, sstr_t s, sstr_t c1, ...) {
+    va_list ap;
+    va_start(ap, c1);
+    s.ptr[0] = 0;
+
+    s.ptr = strncat (s.ptr, c1.ptr, s.length);
+    for (int i=0;i<n-1;i++) {
+        sstr_t str = va_arg (ap, sstr_t);
+        s.ptr = strncat (s.ptr, str.ptr, s.length);
+    }
+
+    return s;
+}
+
+sstr_t sstrsubs (sstr_t s, size_t start) {
+    return sstrsubsl (s, start, s.length-start);
+}
+
+sstr_t sstrsubsl (sstr_t s, size_t start, size_t length) {
+    sstr_t new_sstr;
+    if (start < 0 || start >= s.length || length < 0) {
+        return s;
+    }
+    if (length > s.length-start) {
+        length = s.length-start;
+    }
+    new_sstr.ptr = &s.ptr[start];
+    new_sstr.length = length;
+    return new_sstr;
+}
+
+int sstrcmp(sstr_t s1, sstr_t s2) {
+    return strncmp(s1.ptr, s2.ptr, s1.length>s2.length ? s2.length: s1.length);
+}
+
+sstr_t sstrdub(sstr_t s) {
+    sstr_t newstring;
+    newstring.ptr = malloc(s.length + 1);
+    newstring.length = s.length;
+    newstring.ptr[newstring.length] = 0;
+
+    memcpy(newstring.ptr, s.ptr, s.length);
+
+    return newstring;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/sstring.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,100 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SSTRING_H
+#define	_SSTRING_H
+
+#define S(s) { s, sizeof(s)-1 }
+#define ST(s) sstrn(s, sizeof(s)-1)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct sstring {
+    char   *ptr;
+    size_t length;
+} sstr_t;
+
+/*
+ * creates a new sstr_t from a null terminated string
+ *
+ * s  null terminated string
+ */
+sstr_t sstr (char *s);
+
+/*
+ * creates a new sstr_t from a string and length
+ *
+ * s  string
+ * n  length of string
+ */
+sstr_t sstrn (char *s, size_t n);
+
+
+/*
+ * gets the length of n sstr_t strings
+ *
+ * n    number of strings
+ * s    string
+ * ...  strings
+ */
+size_t sstrnlen (size_t n, sstr_t s, ...);
+
+
+/*
+ * concatenates n strings
+ *
+ * n    number of strings
+ * s    new string with enough memory allocated
+ * ...  strings
+ */
+sstr_t sstrncat (size_t n, sstr_t s, sstr_t c1, ...);
+
+
+/*
+ * 
+ */
+sstr_t sstrsubs (sstr_t s, size_t start);
+
+/*
+ * 
+ */
+sstr_t sstrsubsl (sstr_t s, size_t start, size_t end);
+
+
+int sstrcmp(sstr_t s1, sstr_t s2);
+
+sstr_t sstrdub(sstr_t s);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SSTRING_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/ucx/ucx.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,24 @@
+/*
+ * File:   ucx.h
+ * Author: olaf
+ *
+ * Created on 31. Dezember 2011, 17:17
+ */
+
+#ifndef UCX_H
+#define	UCX_H
+
+#include <stdlib.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef int(*ucx_callback)(void*,void*);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* UCX_H */
+
--- a/src/server/uri.cpp	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,561 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef XP_WIN32
-#define _MBCS
-#include <windows.h>
-#include <mbctype.h>
-#endif
-
-#include "util.h"
-#include "pool.h"
-//include "frame/conf_api.h"
-//include "support/stringvalue.h"
-
-#ifdef XP_WIN32
-static PRBool _getfullpathname = -1;
-#endif /* XP_WIN32 */
-
-/* --------------------------- util_uri_is_evil --------------------------- */
-
-static inline int allow_dbcs_uri()
-{
-    /*
-    static int flagDbcsUri = -1;
-    if (flagDbcsUri == -1) {
-        flagDbcsUri = StringValue::getBoolean(conf_findGlobal("DbcsUri"));
-    }
-    return flagDbcsUri;
-    */
-    return PR_FALSE;
-}
-
-#ifdef XP_WIN32
-void set_fullpathname(PRBool b)
-{
-    _getfullpathname = b;
-}
-#endif  /*XP_WIN32*/
-
-NSAPI_PUBLIC int util_uri_is_evil_internal(const char *t, int allow_tilde, int allow_dot_dir)
-{
-#ifdef XP_WIN32
-    int flagDbcsUri = allow_dbcs_uri();
-#endif // XP_WIN32
-    PRBool flagEmptySegment = PR_FALSE;
-    register int x;
-
-    for (x = 0; t[x]; ++x) {
-        if (t[x] == '/') {
-            if (flagEmptySegment)
-                return 1; // "/;a/b"
-#ifdef XP_WIN32
-            if (t[x+1] == '/' && x != 0)
-#else
-            if (t[x+1] == '/')
-#endif
-                return 1;
-            if (t[x+1] == ';')
-                flagEmptySegment = PR_TRUE; // "/;a/b" is evil, "/a/;b" is not
-            if (t[x+1] == '.') {
-                /* "." at end of line is always prohibited */
-                if (t[x+2] == '\0')
-                    return 1;
-
-                /* "." as a path segment is prohibited conditionally */
-                if (!allow_dot_dir && (t[x+2] == '/' || t[x+2] == ';'))
-                    return 1;
-
-                /* ".." as a path segment is always prohibited */
-                if (t[x+2] == '.' && (t[x+3] == '/' || t[x+3] == ';' || t[x+3] == '\0'))
-                    return 1;
-            }
-        }
-#ifdef XP_WIN32
-        // Don't allow '~' in the filename.  On some filesystems a long name
-        // (e.g. longfilename.htm) can be accessed using '~' bypassing any ACL
-        // checks (e.g. longfi~1.htm).
-        if (!allow_tilde && (t[x] == '~')) {
-            return 1;
-        }
-
-        // Do not allow ':' apart from drive letter. Windows filestream
-        // will treat filename::$DATA as a plain file & display content.
-        // So block it to prevent source viewing vulnerability.
-        if ((t[x] == ':') && x > 1) {
-            return 1;
-        }
-
-        // On NT, the directory "abc...." is the same as "abc"
-        // The only cheap way to catch this globally is to disallow
-        // names with the trailing "."s.  Hopefully this is not over
-        // restrictive.
-        // Also trailing spaces in names can wreak havoc on ACL checks
-        // and name resolution.  Therefore, ban them on the end of a
-        // name.
-        if (((t[x] == '.') || (t[x] == ' ')) &&
-            ((t[x+1] == ';') || (t[x+1] == '/') || (t[x+1] == '\0')))
-        {
-            return 1;
-        }
-
-        // Skip past the second byte of two byte DBCS characters.  Bug 353999
-        if (flagDbcsUri && t[x+1] && IsDBCSLeadByte(t[x])) x++;
-#endif // XP_WIN32
-    }
-    return 0;
-}
-
-NSAPI_PUBLIC int util_uri_is_evil(const char *t)
-{
-    return util_uri_is_evil_internal(t, 0, 0);
-}
-
-
-/* -------------------- util_uri_unescape_and_normalize -------------------- */
-
-#ifdef XP_WIN32
-/* The server calls this function to unescape the URI and also normalize
- * the uri.  Normalizing the uri converts all "\" characters in the URI
- * and pathinfo portion to "/".  Does not touch "\" in query strings.
- */
-NSAPI_PUBLIC
-int util_uri_unescape_and_normalize(pool_handle_t *pool, char *s, char *unnormalized)
-{
-    if(!(util_uri_unescape_strict(s)))
-        return 0;
-
-    if (unnormalized) strcpy(unnormalized, s);
-
-    if (_getfullpathname == -1)
-        _getfullpathname = (_getmbcp() != 0);
-
-    /* Get canonical filename Bugid: 4672869 */
-    if(_getfullpathname && strcmp(s, "*") && (*s == '/' ) ) {
-        char *pzAbsPath = NULL;
-        int pathlen = 0;
-        int len = 0;
-        int ret = 0;
-        if(!(pzAbsPath = util_canonicalize_uri(pool, s, strlen(s), NULL))) {
-            //Error canonicalizing; possibly pointing out of docroot
-            return 0;
-        }
-        char *pzPath = (char *)MALLOC(MAX_PATH + 1); /* reserved byte for trailing slash */
-        char *pzFilename = NULL;
-
-        /* If required length of the buffer(pzPath) is more than the allocated one i.e. MAX_PATH(neglecting the reserved byte for trailing slash), return BAD REQUEST. This will happen if length of uri is more than the specified uri length(257) for MBCS windows */
-        if(!(ret = GetFullPathName(pzAbsPath, MAX_PATH, pzPath, &pzFilename)) || ( ret > MAX_PATH)){
-            FREE(pzAbsPath);
-            FREE(pzPath);
-            return 0;
-        }
-        len = strlen(pzAbsPath);
-        pathlen = strlen( pzPath );
-
-        /*  GetFullPathName behaves differently in case of WINNT and WIN2K */
-        /* o/p string doesn't contain the trailing slash in case of WINNT */
-        /* if i/p is /foo/, we get o/p as c:\foo instead of c:\foo\ */
-        /* Checking if i/p has trailing slash and o/p doesn't have, then */
-        /* adding slash */
-        if ( pzAbsPath[len-1] == '/' && pzPath[pathlen-1] != '\\')
-            strcat( pzPath, "\\");
-        FREE(pzAbsPath);
-        pzFilename = strchr(pzPath, '\\');
-        if(!pzFilename) {
-            FREE(pzPath);
-            return 0;
-        }
-        strcpy(s, pzFilename);
-        FREE(pzPath);
-    }
-
-    util_uri_normalize_slashes(s);
-
-    return 1;
-}
-#endif /* XP_WIN32 */
-
-
-/* ---------------------- util_uri_normalize_slashes ---------------------- */
-
-void util_uri_normalize_slashes(char *s)
-{
-#ifdef XP_WIN32
-    int flagDbcsUri = allow_dbcs_uri();
-
-    while (*s) {
-        if (*s == '\\') {
-            // Normalize '\\' to '/'
-            *s = '/';
-        } else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0])) {
-            // Skip past two byte DBCS characters.  Bug 353999
-            s++;
-        }
-        s++;
-    }
-#endif
-}
-
-
-/* --------------------------- util_uri_escape ---------------------------- */
-/*
-NSAPI_PUBLIC char *util_uri_escape(char *od, const char *s)
-{
-    int flagDbcsUri = allow_dbcs_uri();
-    char *d;
-
-    if (!od)
-        od = (char *) MALLOC((strlen(s)*3) + 1);
-    d = od;
-
-    while (*s) {
-        if (strchr("% ?#:+&*\"'<>\r\n", *s)) {
-            util_sprintf(d, "%%%02x", (unsigned char)*s);
-            ++s; d += 3;
-        }
-#ifdef XP_WIN32
-        else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
-#else
-        // Treat any character with the high bit set as a DBCS lead byte
-        else if (flagDbcsUri && s[1] && (s[0] & 0x80))
-#endif
-	{
-            // Escape the second byte of DBCS characters.  The first byte will
-            // have been escaped already.  IE translates all unescaped '\\'s
-            // into '/'.
-            // Bug 353999
-            util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
-            s += 2; d += 6;
-        }
-        else if (0x80 & *s) {
-            util_sprintf(d, "%%%02x", (unsigned char)*s);
-            ++s; d += 3;
-        } else {
-            *d++ = *s++;
-        }
-    }
-    *d = '\0';
-    return od;
-}
-*/
-
-
-/* --------------------------- util_url_escape ---------------------------- */
-/*
-NSAPI_PUBLIC char *util_url_escape(char *od, const char *s)
-{
-    int flagDbcsUri = allow_dbcs_uri();
-    char *d;
-
-    if (!od)
-        od = (char *) MALLOC((strlen(s)*3) + 1);
-    d = od;
-
-    while (*s) {
-        if (strchr("% +*\"'<>\r\n", *s)) {
-            util_sprintf(d, "%%%02x", (unsigned char)*s);
-            ++s; d += 3;
-        }
-#ifdef XP_WIN32
-        else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
-#else
-        // Treat any character with the high bit set as a DBCS lead byte
-        else if (flagDbcsUri && s[1] && (s[0] & 0x80))
-#endif
-	{
-            // Escape the second byte of DBCS characters.  The first byte will
-            // have been escaped already.  IE translates all unescaped '\\'s
-            // into '/'.
-            // Bug 353999
-            util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
-            s += 2; d += 6;
-        }
-        else if (0x80 & *s) {
-            util_sprintf(d, "%%%02x", (unsigned char)*s);
-            ++s; d += 3;
-        } else {
-            *d++ = *s++;
-        }
-    }
-    *d = '\0';
-    return od;
-}
-*/
-
-/* ------------------------- util_uri_strip_params ------------------------- */
-
-NSAPI_PUBLIC char* util_uri_strip_params(char *uri)
-{
-    // As per RFC2396, URI path segments can contain parameters beginning with
-    // ';'.  These parameters must be removed from the ppath.  Bug 418271
-    char* out;
-    if (out = strchr(uri, ';')) {
-        char* in = out;
-        while (*in) {
-            if (*in == ';') {
-                // Skip past parameter
-                do in++; while (*in && *in != '/');
-            } else {
-                // Copy non-parameter path data
-                *out++ = *in++;
-            }
-        }
-        *out = 0;
-    }
-    return uri;
-}
-
-
-/* ------------------------ util_canonicalize_uri ------------------------- */
-
-/*
- * rewrite rules:
- *   //                       ->  '/'
- *   /./                      ->  '/'
- *   /.\0                     ->  '/'
- *   /foo/../                 ->  '/'
- *   /foo/..\0                ->  '/'
- *
- * Allocate a new string, as otherwise replacing in-line would impact the
- * RequestURI, i.e. original URI in the request.
- * Some guidelines in: http://www.ietf.org/rfc/rfc2396.txt
- *      Uniform Resource Identifiers (URI): Generic Syntax
- */
-NSAPI_PUBLIC char* util_canonicalize_uri(pool_handle_t *pool, const char *uri, int len, int *pcanonlen)
-{
-    PRBool success = PR_TRUE;
-    const char *in_ptr = uri;
-    int in = 0;
-    int in_len = len;
-
-    PR_ASSERT(uri != NULL);
-
-    char* canonPath = (char *)pool_malloc(pool, in_len+1);
-    char* out_ptr = canonPath;
-
-    if (!canonPath) {
-        success = PR_FALSE;
-        goto done;
-    }
-
-
-    /* in goes from 0 .. sURIPath.len-1; out_ptr points to
-     * space where next char from input would be copied to
-     */
-    while (in < in_len) {
-
-        /* If the character isn't '/' then copy it out and move on*/
-        if (in_ptr[0] != '/') {
-            *out_ptr++ = *in_ptr++;
-            in++;
-            continue;
-        }
-
-        /* found '/' and reached end of sURIPath, done */
-        if (in+1 >= in_len) {
-            *out_ptr++ = *in_ptr++;
-            in++;
-            break;
-        }
-
-        /* we have '/' and there are more chars in the string */
-        switch(in_ptr[1]) {
-        case '/':
-            /*  '//' => '/'  */
-            in_ptr++;
-            in++;
-            break;
-
-        case '.':
-            /* we have "/." so far */
-            if (in+2 >= in_len) {
-                /*  the string ends after this; basically ignore '.'
-                 *  make sure the ending / is transferred to output.
-                 */
-                *out_ptr++ = *in_ptr++;
-                goto done;
-            }
-
-            /* more chars after "/."; see if it is a '/' */
-            if (in_ptr[2] == '/') {
-                /* in deed, compact "/./" => "/"; */
-                in_ptr += 2;
-                in += 2;
-                break;
-            }
-
-            if (in_ptr[2] != '.') {
-                /* "/.x" where x is not '.'; copy as is */
-                *out_ptr++ = *in_ptr++;
-                in++;
-                break;
-            }
-
-            /* we have "/.." so far. see if we have either string
-             * ending after this or '/' following.
-             */
-            if (in+3 < in_len && in_ptr[3] != '/' && in_ptr[3] != ';') {
-                /* we have "/..x" here; so copy as is */
-                *out_ptr++ = *in_ptr++;
-                in++;
-            }
-            else {
-                /* we have "foo/../" or "foo/.." at the end; */
-                if (out_ptr == canonPath) {
-                    /* oops, we found "/../" pointing out of docroot */
-                    success = PR_FALSE;
-                    goto done;
-                }
-
-                /* remove the previous segment in the output */
-                for (out_ptr--;
-                     out_ptr != canonPath && out_ptr[0] != '/';
-                     out_ptr--); /* Empty Loop */
-
-                /* point to '/' if the last segment ended with .. then
-                 * leave the '/' before the previous segment.
-                 */
-                if(in+3 == in_len)
-                    out_ptr++;
-
-                /* skip the input as well */
-                in_ptr += 3;
-                in += 3;
-            }
-            break;
-
-        default:
-            /* If we already have '/' at out_ptr we donot need to copy */
-            if (out_ptr == canonPath || *(out_ptr-1) != '/')
-                *out_ptr++ = *in_ptr;
-            in_ptr++; in++;
-            break;
-        }
-    }
-
-done:
-    int canonLen = 0;
-
-    if (success) {
-        /* the path looks fine; return the canonicalized form */
-        canonLen = out_ptr - canonPath;
-        canonPath[canonLen] = '\0';
-    } else {
-        /* error canonicalizing */
-        pool_free(pool, canonPath);
-        canonPath = NULL;
-    }
-
-    if (pcanonlen)
-        *pcanonlen = canonLen;
-
-    return canonPath;
-}
-
-
-/* ---------------------- util_canonicalize_redirect ---------------------- */
-
-NSAPI_PUBLIC char* util_canonicalize_redirect(pool_handle_t *pool, const char *baseUri, const char *newUri)
-{
-    PR_ASSERT(baseUri != NULL);
-
-    if (*newUri == '/')
-        return util_canonicalize_uri(pool, newUri, strlen(newUri), NULL);
-
-    int bLen = strlen(baseUri);
-    if (bLen > 0 && baseUri[bLen - 1] != '/') {
-        while (bLen > 0 && baseUri[bLen - 1] != '/')
-            bLen--;
-    }
-
-    int pLen = strlen(newUri) + bLen + 1; // 1 for slash
-    char *pUri = (char *)pool_malloc(pool, pLen + 1);
-    if (!pUri)
-        return PR_FALSE;
-
-    memcpy(pUri, baseUri, bLen);
-    pUri[bLen] = '/';
-    strcpy(pUri + bLen + 1, newUri);
-
-    char *rval = util_canonicalize_uri(pool, pUri, pLen, NULL);
-    pool_free(pool, pUri);
-
-    return rval;
-}
-
-
-/* ------------------------ util_host_port_suffix ------------------------- */
-
-NSAPI_PUBLIC char *util_host_port_suffix(char *h)
-{
-    return (char *)util_host_port_suffix((const char *)h);
-}
-
-const char *util_host_port_suffix(const char *h)
-{
-    /* Return a pointer to the colon preceding the port number in a hostname.
-     *
-     * util_host_port_suffix("foo.com:80") = ":80"
-     * util_host_port_suffix("foo.com") = NULL
-     * util_host_port_suffix("[::]:80") = ":80"
-     * util_host_port_suffix("[::]") = NULL
-     */
-
-    if (h == NULL)
-        return h;
-
-    for (;;) {
-        /* Find end of host, beginning of ":port", or an IPv6 address */
-        for (;;) {
-            register char c = *h;
-
-            if (c == '\0')
-                return NULL; /* end of host, no port found */
-
-            if (c == '/')
-                return NULL; /* end of host, no port found */
-
-            if (c == ':')
-                return h; /* found port */
-
-            if (c == '[')
-                break; /* skip IPv6 address */
-
-            h++;
-        }
-
-        /* Skip IPv6 address */
-        while (*h != '\0' && *h != ']')
-            h++;
-    }
-}
--- a/src/server/util.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * util.c: A hodge podge of utility functions and standard functions which 
- *         are unavailable on certain systems
- * 
- * Rob McCool
- */
-
-#ifdef XP_UNIX
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-#include "prthread.h"
-#endif /* XP_UNIX */
-
-
-#include "nspr.h"
-#include "nsapi.h"
-
-#include "util.h"
-
-/*
-NSAPI_PUBLIC int util_getboolean(const char *v, int def) {
-    if(v[0] == 'T' || v[0] == 't') {
-        return 1;
-    }
-    if(v[0] == 'F' || v[0] == 'f') {
-        return 0;
-    }
-    return def;
-}
-*/
-
-NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def) {
-    if(v[0] == 'T' || v[0] == 't') {
-        return 1;
-    }
-    if(v[0] == 'F' || v[0] == 'f') {
-        return 0;
-    }
-    return def;
-}
-
-
-/* ------------------------------ util_itoa ------------------------------- */
-/*
-NSAPI_PUBLIC int util_itoa(int i, char *a)
-{
-    int len = util_i64toa(i, a);
-
-    PR_ASSERT(len < UTIL_ITOA_SIZE);
-
-    return len;
-}
-*/
-NSAPI_PUBLIC int INTutil_itoa(int i, char *a) {
-    return INTutil_i64toa(i, a);
-}
-
-
-/* ----------------------------- util_i64toa ------------------------------ */
-
-/*
- * Assumption: Reversing the digits will be faster in the general case
- * than doing a log10 or some nasty trick to find the # of digits.
- */
-
-NSAPI_PUBLIC int INTutil_i64toa(PRInt64 i, char *a)
-{
-    register int x, y, p;
-    register char c;
-    int negative;
-
-    negative = 0;
-    if(i < 0) {
-        *a++ = '-';
-        negative = 1;
-        i = -i;
-    }
-    p = 0;
-    while(i > 9) {
-        a[p++] = (i%10) + '0';
-        i /= 10;
-    }
-    a[p++] = i + '0';
-
-    if(p > 1) {
-        for(x = 0, y = p - 1; x < y; ++x, --y) {
-            c = a[x];
-            a[x] = a[y];
-            a[y] = c;
-        }
-    }
-    a[p] = '\0';
-
-    //PR_ASSERT(p + negative < UTIL_I64TOA_SIZE);
-
-    return p + negative;
-}
--- a/src/server/util.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_UTIL_H
-#define BASE_UTIL_H
-
-#include "netsite.h"
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * util.h: A hodge podge of utility functions and standard functions which 
- *         are unavailable on certain systems
- * 
- * Rob McCool
- */
-
-/* Needed for various reentrant functions */
-#define DEF_CTIMEBUF 26
-#define DEF_ERRBUF 256
-#define DEF_PWBUF 1024
-
-#ifndef BASE_BUFFER_H
-//include "buffer.h"    /* filebuf for getline */
-#endif /* !BASE_BUFFER_H */
-
-/*
- * UTIL_ITOA_SIZE is the minimum size for buffers passed to util_itoa().
- */
-#define UTIL_ITOA_SIZE 12
-
-/*
- * UTIL_I64TOA_SIZE is the minimum size for buffers passed to util_i64toa().
- */
-#define UTIL_I64TOA_SIZE 21
-
-/* --- Begin common function prototypes --- */
-
-#ifdef INTNSAPI
-
-NSPR_BEGIN_EXTERN_C
-
-NSAPI_PUBLIC
-int INTutil_init_PRNetAddr(PRNetAddr * naddr, char * ipstr, int iplen, int type);
-
-NSAPI_PUBLIC
-int INTutil_getline(filebuffer *buf, int lineno, int maxlen, char *l);
-
-NSAPI_PUBLIC char **INTutil_env_create(char **env, int n, int *pos);
-
-NSAPI_PUBLIC char *INTutil_env_str(const char *name, const char *value);
-
-NSAPI_PUBLIC void INTutil_env_replace(char **env, const char *name, const char *value);
-
-NSAPI_PUBLIC void INTutil_env_free(char **env);
-
-NSAPI_PUBLIC char **INTutil_env_copy(char **src, char **dst);
-
-NSAPI_PUBLIC char *INTutil_env_find(char **env, const char *name);
-
-NSAPI_PUBLIC char **util_argv_parse(const char *cmdline);
-
-NSAPI_PUBLIC char *INTutil_hostname(void);
-
-NSAPI_PUBLIC int INTutil_chdir2path(char *path);
-
-NSAPI_PUBLIC int INTutil_chdir(const char *path);
-
-NSAPI_PUBLIC char *INTutil_getcwd(void);
-
-NSAPI_PUBLIC int INTutil_is_mozilla(char *ua, char *major, char *minor);
-
-NSAPI_PUBLIC int INTutil_is_url(const char *url);
-
-NSAPI_PUBLIC int INTutil_mstr2num(const char *s);
-
-NSAPI_PUBLIC int INTutil_later_than(const struct tm *lms, const char *ims);
-
-NSAPI_PUBLIC int INTutil_time_equal(const struct tm *lms, const char *ims);
-
-NSAPI_PUBLIC int INTutil_str_time_equal(const char *t1, const char *t2);
-
-NSAPI_PUBLIC int INTutil_uri_is_evil(const char *t);
-
-NSAPI_PUBLIC int INTutil_uri_is_evil_internal(const char *t, int, int);
-
-NSAPI_PUBLIC void INTutil_uri_parse(char *uri);
-
-#ifdef XP_WIN32
-NSAPI_PUBLIC int INTutil_uri_unescape_and_normalize(pool_handle_t *pool, char *s, char *unnormalized);
-#endif /* XP_WIN32 */
-
-NSAPI_PUBLIC void INTutil_uri_normalize_slashes(char *s);
-
-NSAPI_PUBLIC void INTutil_uri_unescape		(char *s);
-
-NSAPI_PUBLIC int INTutil_uri_unescape_strict		(char *s);
-
-NSAPI_PUBLIC int  INTutil_uri_unescape_plus (const char *src, char *trg, int len);
-
-NSAPI_PUBLIC char *INTutil_uri_escape(char *d, const char *s);
-
-NSAPI_PUBLIC char *INTutil_uri_strip_params(char *uri);
-
-NSAPI_PUBLIC char* util_canonicalize_uri(pool_handle_t *pool, const char *uri, int len, int *pcanonlen);
-
-NSAPI_PUBLIC char* util_canonicalize_redirect(pool_handle_t *pool, const char *baseUri, const char *newUri);
-
-NSAPI_PUBLIC char *INTutil_url_escape(char *d, const char *s);
-
-NSAPI_PUBLIC char *INTutil_sh_escape(char *s);
-
-NSAPI_PUBLIC int INTutil_mime_separator(char *sep);
-
-NSAPI_PUBLIC int INTutil_itoa(int i, char *a);
-
-NSAPI_PUBLIC int INTutil_i64toa(PRInt64 i, char *a);
-
-
-NSAPI_PUBLIC
-int INTutil_vsprintf(char *s, register const char *fmt, va_list args);
-
-NSAPI_PUBLIC int INTutil_sprintf(char *s, const char *fmt, ...);
-
-NSAPI_PUBLIC int INTutil_vsnprintf(char *s, int n, register const char *fmt, 
-                                  va_list args);
-
-NSAPI_PUBLIC int INTutil_snprintf(char *s, int n, const char *fmt, ...);
-
-NSAPI_PUBLIC int util_strlftime(char *dst, size_t dstsize, const char *format, const struct tm *t);
-
-NSAPI_PUBLIC int INTutil_strftime(char *s, const char *format, const struct tm *t);
-
-NSAPI_PUBLIC char *INTutil_strtok(char *s1, const char *s2, char **lasts);
-
-NSAPI_PUBLIC struct tm *INTutil_localtime(const time_t *clock, struct tm *res);
-
-NSAPI_PUBLIC char *INTutil_ctime(const time_t *clock, char *buf, int buflen);
-
-NSAPI_PUBLIC char *INTutil_strerror(int errnum, char *msg, int buflen);
-
-NSAPI_PUBLIC struct tm *INTutil_gmtime(const time_t *clock, struct tm *res);
-
-NSAPI_PUBLIC char *INTutil_asctime(const struct tm *tm,char *buf, int buflen);
-
-NSAPI_PUBLIC char *INTutil_cookie_find(char *cookie, const char *name);
-
-NSAPI_PUBLIC char *INTutil_cookie_next(char *cookie, char **name, char **value);
-
-NSAPI_PUBLIC char *INTutil_cookie_next_av_pair(char *cookie, char **name, char **value);
-
-NSAPI_PUBLIC void INTutil_random(void *buf, size_t sz);
-
-NSAPI_PUBLIC PRBool INTutil_format_http_version(const char *v, int *protv_num, char *buffer, int size);
-
-NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def);
-NSAPI_PUBLIC PRIntervalTime INTutil_getinterval(const char *v, PRIntervalTime def);
-
-#ifdef NEED_STRCASECMP
-NSAPI_PUBLIC int INTutil_strcasecmp(const char *one, const char *two);
-#endif /* NEED_STRCASECMP */
-
-#ifdef NEED_STRNCASECMP
-NSAPI_PUBLIC int INTutil_strncasecmp(const char *one, const char *two, int n);
-#endif /* NEED_STRNCASECMP */
-
-NSAPI_PUBLIC char *INTutil_strcasestr(char *str, const char *substr);
-
-NSAPI_PUBLIC size_t util_strlcpy(char *dst, const char *src, size_t dstsize);
-
-NSAPI_PUBLIC size_t util_strlcat(char *dst, const char *src, size_t dstsize);
-
-NSAPI_PUBLIC char *INTutil_uuencode(const char *src, int len);
-
-NSAPI_PUBLIC char *INTutil_uudecode(const char *src);
-
-NSAPI_PUBLIC char *util_strlower(char *s);
-
-NSAPI_PUBLIC char *util_decrement_string(char *s);
-
-NSAPI_PUBLIC PRInt64 util_atoi64(const char *a);
-
-NSAPI_PUBLIC char *util_html_escape(const char *s);
-
-NSAPI_PUBLIC int util_qtoi(const char *q, const char **p);
-
-/* --- End common function prototypes --- */
-
-/* --- Begin Unix-only function prototypes --- */
-
-#ifdef XP_UNIX
-
-NSAPI_PUBLIC int INTutil_can_exec(struct stat *finfo, uid_t uid, gid_t gid);
-
-NSAPI_PUBLIC
-struct passwd *INTutil_getpwnam(const char *name, struct passwd *result,
-                               char *buffer,  int buflen);
-
-NSAPI_PUBLIC
-struct passwd *INTutil_getpwuid(uid_t uid, struct passwd *result,
-                                char *buffer, int buflen);
-
-NSAPI_PUBLIC pid_t INTutil_waitpid(pid_t pid, int *statptr, int options);
-
-#endif /* XP_UNIX */
-
-/* --- End Unix-only function prototypes --- */
-
-/* --- Begin Windows-only function prototypes --- */
-
-#ifdef XP_WIN32
-
-NSAPI_PUBLIC
-VOID INTutil_delete_directory(char *FileName, BOOL delete_directory);
-
-#endif /* XP_WIN32 */
-
-/* --- End Windows-only function prototypes --- */
-
-NSPR_END_EXTERN_C
-
-#ifdef __cplusplus
-
-NSAPI_PUBLIC char *util_host_port_suffix(char *h);
-
-NSAPI_PUBLIC const char *util_host_port_suffix(const char *h);
-
-#endif
-
-#define util_init_PRNetAddr INTutil_init_PRNetAddr
-#define util_getline INTutil_getline
-#define util_env_create INTutil_env_create
-#define util_env_str INTutil_env_str
-#define util_env_replace INTutil_env_replace
-#define util_env_free INTutil_env_free
-#define util_env_copy INTutil_env_copy
-#define util_env_find INTutil_env_find
-#define util_hostname INTutil_hostname
-#define util_chdir2path INTutil_chdir2path
-#define util_chdir INTutil_chdir
-#define util_getcwd INTutil_getcwd
-#define util_is_mozilla INTutil_is_mozilla
-#define util_is_url INTutil_is_url
-#define util_mstr2num INTutil_mstr2num
-#define util_later_than INTutil_later_than
-#define util_time_equal INTutil_time_equal
-#define util_str_time_equal INTutil_str_time_equal
-#define util_uri_is_evil INTutil_uri_is_evil
-#define util_uri_is_evil_internal INTutil_uri_is_evil_internal
-#define util_uri_parse INTutil_uri_parse
-#ifdef XP_WIN32
-#define util_uri_unescape_and_normalize INTutil_uri_unescape_and_normalize
-#endif /* XP_WIN32 */
-#define util_uri_normalize_slashes INTutil_uri_normalize_slashes
-#define util_uri_unescape	   INTutil_uri_unescape
-#define util_uri_unescape_strict	   INTutil_uri_unescape_strict
-#define util_uri_unescape_plus INTutil_uri_unescape_plus
-
-#define util_uri_escape INTutil_uri_escape
-#define util_uri_strip_params INTutil_uri_strip_params
-#define util_url_escape INTutil_url_escape
-#define util_sh_escape INTutil_sh_escape
-#define util_mime_separator INTutil_mime_separator
-#define util_itoa INTutil_itoa
-#define util_i64toa INTutil_i64toa
-#define util_vsprintf INTutil_vsprintf
-#define util_sprintf INTutil_sprintf
-#define util_vsnprintf INTutil_vsnprintf
-#define util_snprintf INTutil_snprintf
-#define util_strftime INTutil_strftime
-#define util_strcasecmp INTutil_strcasecmp
-#define util_strncasecmp INTutil_strncasecmp
-#define util_strcasestr INTutil_strcasestr
-#define util_strtok INTutil_strtok
-#define util_localtime INTutil_localtime
-#define util_ctime INTutil_ctime
-#define util_strerror INTutil_strerror
-#define util_gmtime INTutil_gmtime
-#define util_asctime INTutil_asctime
-#define util_uuencode INTutil_uuencode
-#define util_uudecode INTutil_uudecode
-
-#ifdef XP_UNIX
-#define util_can_exec INTutil_can_exec
-#define util_getpwnam INTutil_getpwnam
-#define util_getpwuid INTutil_getpwuid
-#define util_waitpid INTutil_waitpid
-#endif /* XP_UNIX */
-
-#ifdef XP_WIN32
-#define util_delete_directory INTutil_delete_directory
-#endif /* XP_WIN32 */
-
-#ifdef NEED_STRCASECMP
-#define util_strcasecmp INTutil_strcasecmp
-#define strcasecmp INTutil_strcasecmp
-#endif /* NEED_STRCASECMP */
-
-#ifdef NEED_STRINGS_H /* usually for strcasecmp */
-#include <strings.h>
-#endif
-
-#ifdef NEED_STRNCASECMP
-#define util_strncasecmp INTutil_strncasecmp
-#define strncasecmp INTutil_strncasecmp
-#endif /* NEED_STRNCASECMP */
-
-#define util_cookie_find INTutil_cookie_find
-#define util_cookie_next INTutil_cookie_next
-#define util_cookie_next_av_pair INTutil_cookie_next_av_pair
-
-#define util_random INTutil_random
-#define util_format_http_version INTutil_format_http_version
-#define util_getboolean INTutil_getboolean
-#define util_getinterval INTutil_getinterval
-
-#ifdef XP_WIN32
-void set_fullpathname(PRBool b);
-#endif /* XP_WIN32 */
-#endif /* INTNSAPI */
-
-#endif /* !BASE_UTIL_H */
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/LinkedList.hh	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,272 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINKED_LIST_H_
+#define _LINKED_LIST_H_
+
+/*
+ *   Provided a template implementation of a simple linked list. 
+ * It is a reference based container (stores the pointers to the
+ * objects contained) It doesn't check for duplicates etc and find
+ * (delete) will find(delete) the first occurence of an element.
+ *
+ * Iterator class can be used for traversal using the "++" operator.
+ */
+template <class C> class CList; // forward declaration
+template <class C> class CListIterator; // forward declaration
+template <class C> class CListConstIterator; // forward declaration
+
+template <class C> class CListElmt {
+  friend class CList<C>;
+  friend class CListIterator<C>;
+  friend class CListConstIterator<C>;
+  private:
+    CListElmt(C* refP, int id) : _refP(refP), _nextP(0), _prevP(0), _id(id)
+        {
+                // Nothing really has to be done here
+        };
+
+
+  private:
+    int       _id;    
+    C         *_refP;
+#if defined(AIX)
+    CListElmt<C> *_nextP;
+    CListElmt<C> *_prevP;
+#else
+    CListElmt *_nextP;
+    CListElmt *_prevP;
+#endif
+};
+
+//
+// NOTE : If you need the find functionality, make sure that 
+//  class C has "==" defined.
+//
+template <class C> class CList {
+  friend class CListIterator<C>;
+  friend class CListConstIterator<C>;
+  private:
+    CListElmt<C>* _headP;
+    CListElmt<C>* _tailP;
+    CListElmt<C>* Lookup(C * memberP)
+        {
+                CListElmt<C> *curEltP = _headP;
+                
+                while (curEltP)
+                {
+                        if (curEltP->_refP == memberP) 
+                                break;
+                        curEltP = curEltP->_nextP;
+                };
+                return(curEltP);
+        };
+    
+    int _nextId;
+    int _numElts;
+    int autoDestroy;
+    C* Remove(CListElmt<C> *elmtP)
+        {
+                C  *recP = NULL;
+                if (elmtP)
+                {
+                        if (elmtP->_nextP)
+                                elmtP->_nextP->_prevP = elmtP->_prevP;
+                        if (elmtP->_prevP)
+                                elmtP->_prevP->_nextP = elmtP->_nextP;
+                        if (elmtP == _tailP)
+                                _tailP = elmtP->_prevP;
+                        if (elmtP == _headP)
+                                _headP = _headP->_nextP;
+                        recP = elmtP->_refP;
+                        _numElts--;
+                        delete elmtP;
+                };
+                if ( (1==autoDestroy) && recP)
+                        delete recP;
+                
+                return(recP);
+        };
+    
+
+  public:
+    CList() :  _headP(0), _tailP(0), _nextId(0), _numElts(0), autoDestroy(0)
+        {
+                // Nothing really has to be done here
+        };
+        
+    void setAutoDestroy(int setting)
+        {
+                autoDestroy = setting;
+        };
+
+    virtual ~CList()
+        {
+                while (_headP)
+                        Remove(_headP);
+        };
+
+    int NextId()
+        {
+                return _nextId;
+        };
+
+    int Append(C* refP)
+        {
+                CListElmt<C> *newElmtP = new CListElmt<C>(refP, _nextId++);
+                newElmtP->_prevP = _tailP;
+                if (_tailP)
+                        _tailP->_nextP = newElmtP;
+                if (_headP == 0)
+                        _headP = newElmtP;
+                _tailP = newElmtP;
+                _numElts++;
+                return(newElmtP->_id);
+        };
+
+    int Member(C* memberP)
+        {
+                return(Lookup(memberP) != 0);
+        };
+    
+    int Delete(C* memberP)
+        {
+                CListElmt<C> *listElmtP = Lookup(memberP);
+                if (listElmtP)
+                {
+                        (void) Remove(listElmtP);
+                        return(1);
+                }
+                return(0);
+        };
+    
+    int NumEntries() const { return _numElts; }
+    C* Find(C* memberP) // Lookup based on == operator for class C
+        {
+                CListElmt<C> *curEltP = _headP;
+        
+                while (curEltP)
+                {
+                        if (curEltP->_refP == memberP) 
+                                break;
+                        curEltP = curEltP->_nextP;
+                };
+                return(curEltP ? curEltP->_refP : 0);
+        };
+    
+    C* First() { return(_headP ? _headP->_refP : 0); }
+    C* Last() { return(_tailP ? _tailP->_refP : 0); }
+};
+
+template <class C> class CListIterator {
+  private:
+    CList<C>* _listP;
+    int _curId;
+  public:
+    CListIterator(CList<C>* linkedListP) : _listP(linkedListP), _curId(-1)
+        {
+                // Nothing more to be done
+        };
+    
+    virtual ~CListIterator()
+        {
+                _listP = NULL;
+        };
+    
+    C* operator++() // Define ++ operator to move forward along the list.
+        {
+                C *valueP = NULL;
+                CListElmt<C> *curEltP = _listP->_headP;
+
+                while (curEltP)
+                {
+                        if (curEltP->_id > _curId)
+                        {
+                                _curId = curEltP->_id;
+                                return(curEltP->_refP);
+                        }
+                        curEltP = curEltP->_nextP;
+                }
+                _curId = -1;
+                return(NULL);
+        };
+    
+    void operator()() // Overload the function operator to reset the iterator
+        {
+                _curId = -1;
+        };
+    
+};
+
+template <class C> class CListConstIterator {
+  private:
+    const CList<C>* _listP;
+    int _curId;
+  public:
+    CListConstIterator(const CList<C>* linkedListP)
+        : _listP(linkedListP), _curId(-1)
+        {
+                // Nothing more to be done
+        };
+    
+    virtual ~CListConstIterator()
+        {
+                _listP = NULL;
+        };
+    
+    const C* operator++() // Define ++ operator to move forward along the list.
+        {
+                const C *valueP = NULL;
+                const CListElmt<C> *curEltP = _listP->_headP;
+
+                while (curEltP)
+                {
+                        if (curEltP->_id > _curId)
+                        {
+                                _curId = curEltP->_id;
+                                return(curEltP->_refP);
+                        }
+                        curEltP = curEltP->_nextP;
+                }
+                _curId = -1;
+                return(NULL);
+        };
+    
+    void operator()() // Overload the function operator to reset the iterator
+        {
+                _curId = -1;
+        };
+    
+};
+
+#endif // _LINKED_LIST_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/Makefile	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,44 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BUILD_ROOT = ../../../
+OBJ_DIR = $(BUILD_ROOT)build/
+
+CFLAGS  = -I/usr/include/mps -g
+LDFLAGS = 
+
+include objs.mk
+
+all: $(UTILOBJS)
+
+$(UTIL_OBJPRE)%.o: %.c
+	cc -o $@ -c $(CFLAGS) $<
+
+$(UTIL_OBJPRE)%.o: %.cpp
+	CC -o $@ -c $(CFLAGS) $<
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/ereport.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,125 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_EREPORT_H
+#define BASE_EREPORT_H
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * ereport.h: Records transactions, reports errors to administrators, etc.
+ * 
+ * Rob McCool
+ */
+
+#ifndef BASE_SESSION_H
+#include "../daemon/session.h"
+#endif /* !BASE_SESSION_H */
+
+/* Pseudo-filename to enable logging to syslog */
+#define EREPORT_SYSLOG "SYSLOG"
+
+/* NSAPI degrees used by Java but not exposed in nsapi.h */
+#define LOG_FINER  7
+#define LOG_FINEST 8
+
+/* --- Begin function prototypes --- */
+
+#ifdef INTNSAPI
+
+NSPR_BEGIN_EXTERN_C
+
+/*
+ * INTereport logs an error of the given degree and formats the arguments with 
+ * the printf() style fmt. Returns whether the log was successful. Records 
+ * the current date.
+ */
+
+NSAPI_PUBLIC int INTereport(int degree, const char *fmt, ...);
+NSAPI_PUBLIC int INTereport_v(int degree, const char *fmt, va_list args);
+
+/*
+ * INTereport_init initializes the error logging subsystem and opens the static
+ * file descriptors. It returns NULL upon success and an error string upon
+ * error. If a userpw is given, the logs will be chowned to that user.
+ */
+
+NSAPI_PUBLIC
+char *INTereport_init(const char *err_fn, const char *email, struct passwd *pwuser, const char *version, int restarted);
+
+NSAPI_PUBLIC void INTereport_terminate(void);
+
+/* For restarts */
+NSAPI_PUBLIC SYS_FILE INTereport_getfd(void);
+
+NSPR_END_EXTERN_C
+
+#ifdef __cplusplus
+class EreportableException;
+NSAPI_PUBLIC int INTereport_exception(const EreportableException& e);
+#endif
+
+/* --- End function prototypes --- */
+
+#define ereport INTereport
+#define ereport_v INTereport_v
+#define ereport_init INTereport_init
+#define ereport_terminate INTereport_terminate
+#define ereport_getfd INTereport_getfd
+#define ereport_exception INTereport_exception
+
+typedef int (EreportFunc)(const VirtualServer* vs, int degree, const char *formatted, int formattedlen, const char *raw, int rawlen, void *data);
+
+void ereport_set_servername(const char* name);
+void ereport_set_logvsid(PRBool b);
+void ereport_set_logall(PRBool b);
+void ereport_set_alwaysreopen(PRBool b);
+void ereport_set_timefmt(const char* timeFmt);
+void ereport_set_degree(int degree);
+int ereport_level2degree(const char *level, int defdegree);
+PRBool ereport_can_log(int degree);
+int ereport_request(Request* rq, int degree, const char *fmt, ...);
+char *ereport_abs_filename(const char *filename);
+void ereport_rotate(const char* ext);
+void ereport_set_rotate_callback(void (*fn)(const char* filenameNew, const char* filenameOld));
+void ereport_reopen(void);
+void ereport_outofmemory(void);
+void ereport_disaster(int degree, const char *fmt, ...);
+NSAPI_PUBLIC int ereport_register_cb(EreportFunc* ereport_func, void* data);
+NSAPI_PUBLIC int ereport_register_thread_cb(EreportFunc* ereport_func, void* data);
+
+#endif /* INTNSAPI */
+
+#endif /* !BASE_EREPORT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/io.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,130 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/uio.h>
+
+#include "io.h"
+#include "pool.h"
+
+IOStream native_io_funcs = {
+    system_write,
+    system_read
+};
+
+IOStream net_io_funcs = {
+    net_stream_write,
+    net_stream_read
+};
+
+
+IOStream* stream_new_from_fd(int fd) {
+    SystemIOStream *st = malloc(sizeof(SystemIOStream));
+    st->st = native_io_funcs;
+    st->fd = fd;
+    return (IOStream*)st;
+}
+
+ssize_t system_write(IOStream *st, void *buf, size_t nbytes) {
+    return write(((SystemIOStream*)st)->fd, buf, nbytes);
+}
+
+ssize_t system_read(IOStream *st, void *buf, size_t nbytes) {
+    return read(((SystemIOStream*)st)->fd, buf, nbytes);
+}
+
+
+IOStream* net_stream_from_fd(int fd) {
+    NetIOStream *st = malloc(sizeof(NetIOStream));
+    st->st = net_io_funcs;
+    st->fd = fd;
+    st->max_read = 0;
+    st->rd = 0;
+}
+
+ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes) {
+    // TODO: implement
+}
+
+ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes) {
+    NetIOStream *n = (NetIOStream*)st;
+    if(n->max_read != 0 && n->rd >= n->max_read) {
+        return 0;
+    }
+    ssize_t r = read(n->fd, buf, nbytes);
+    n->rd += r;
+    return r;
+}
+
+
+ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) {
+    ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes);
+    if(r == 0) {
+        return IO_EOF;
+    }
+    return r;
+}
+
+ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) {
+    ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes);
+    if(r < 0) {
+        return IO_ERROR;
+    }
+    return r;
+}
+
+
+/* iovec buffer */
+iovec_buf_t *iovec_buf_create(pool_handle_t *pool) {
+    iovec_buf_t *buf = pool_malloc(pool, sizeof(iovec_buf_t));
+
+    buf->pool = pool;
+    buf->iov  = pool_calloc(pool, 32, sizeof(struct iovec));
+    buf->maxiovec = 32;
+    buf->iovctn = 0;
+
+    return buf;
+}
+
+void iovec_buf_write(iovec_buf_t *io, void *buf, size_t nbyte) {
+    if(io->iovctn >= io->maxiovec) {
+        io->iov = pool_realloc(
+                io->pool,
+                io->iov,
+                (io->maxiovec + 16) * sizeof(struct iovec));
+    }
+
+    io->iov[io->iovctn].iov_base = buf;
+    io->iov[io->iovctn].iov_len = nbyte;
+    io->iovctn++;
+}
+
+ssize_t iovec_buf_flush(iovec_buf_t *io, int fd) {
+    return writev(fd, io->iov, io->iovctn);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/io.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,98 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IOSTREAM_H
+#define	IOSTREAM_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct io_stream IOStream;
+
+typedef ssize_t(*io_write_f)(IOStream *, void *, size_t);
+typedef ssize_t(*io_read_f)(IOStream *, void *, size_t);
+
+struct io_stream {
+    io_write_f write;
+    io_read_f  read;
+};
+
+typedef struct SystemIOStream {
+    IOStream st;
+    int      fd;
+} SystemIOStream;
+
+typedef struct NetIOStream {
+    IOStream st;
+    int      fd;
+    size_t   max_read;
+    size_t   rd;
+} NetIOStream;
+
+
+/* net_ functions */
+ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes);
+ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes);
+
+
+/* iovec buffer */
+typedef struct iovec_buf{
+    struct iovec   *iov;
+    int            iovctn;
+    int            maxiovec;
+    pool_handle_t  *pool;
+} iovec_buf_t;
+
+
+/* system stream */
+IOStream* stream_new_from_fd(int fd);
+
+ssize_t system_write(IOStream *st, void *buf, size_t nbytes);
+ssize_t system_read(IOStream *st, void *buf, size_t nbytes);
+
+/* net stream */
+IOStream* net_stream_from_fd(int fd);
+
+ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes);
+ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes);
+
+/* iovec buffer */
+iovec_buf_t *iovec_buf_create(pool_handle_t *pool);
+void iovec_buf_write(iovec_buf_t *io, void *buf, size_t nbyte);
+ssize_t iovec_buf_flush(iovec_buf_t *io, int fd);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* IOSTREAM_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/list.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,175 @@
+/* 
+ * File:   list.c
+ * Author: olaf
+ *
+ * Created on 18. Dezember 2010, 11:23
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "list.h"
+
+/* add functions */
+sdlist_t* sdlist_add(sdlist_t *list, void *data) {
+    sdlist_t *elm = malloc(sizeof(sdlist_t));
+    elm->data = data;
+    elm->next = NULL;
+
+    return sdlist_addl(list, elm);
+}
+
+sdlist_t* sdlist_addl(sdlist_t *list, sdlist_t *l) {
+    if (list != NULL) {
+        sdlist_t *end = sdlist_getlast(list);
+        end->next = l;
+        return list;
+    } else {
+        return l;
+    }
+}
+
+
+
+/* remove functions */
+sdlist_t* sdlist_remove(sdlist_t *list, void *data) {
+    sdlist_t *s = list;
+
+    sdlist_t *prev = NULL;
+    while (list != NULL) {
+        if (list->data == data) {
+            sdlist_t *nl =  sdlist_remove_elm(s, prev, list);
+            free(list);
+            return nl;
+        }
+
+        prev = list;
+        list = list->next;
+    }
+
+    return s;
+}
+
+sdlist_t* sdlist_removei(sdlist_t *list, int index) {
+    sdlist_t *s = list;
+
+    sdlist_t *prev = NULL;
+    int i = 0;
+    while (list != NULL) {
+        if (i == index) {
+            sdlist_t *nl =  sdlist_remove_elm(s, prev, list);
+            free(list);
+            return nl;
+        }
+
+        prev = list;
+        list = list->next;
+        i++;
+    }
+
+    return s;
+}
+
+sdlist_t* sdlist_removel(sdlist_t *list, sdlist_t *l) {
+    sdlist_t *s = list;
+
+    sdlist_t *prev = NULL;
+    while (list != NULL) {
+        if (list == l) {
+            return sdlist_remove_elm(s, prev, list);
+        }
+
+        prev = list;
+        list = list->next;
+    }
+
+    return s;
+}
+
+
+sdlist_t *sdlist_remove_elm(sdlist_t *list, sdlist_t *prev, sdlist_t *elm) {
+    if (elm == NULL) {
+        return list;
+    }
+
+    if (prev == NULL) {
+        return elm->next;
+    }
+
+    prev->next = elm->next;
+
+    return list;
+}
+
+
+
+/* insert functions */
+void sdlist_insert(sdlist_t *elm, void *data) {
+    sdlist_t *newelm = malloc(sizeof(sdlist_t));
+    newelm->data = data;
+    sdlist_insertl(elm, newelm);
+}
+
+void sdlist_insertl(sdlist_t *elm, sdlist_t *l) {
+    if (elm == NULL || l == NULL) {
+        return;
+    }
+    
+    l->next = elm->next;
+    elm->next = l;
+}
+
+
+/* get functions */
+sdlist_t* sdlist_get(sdlist_t *list, void *data) {
+    while (list != NULL) {
+        if (list->data == data) {
+            return list;
+        }
+        list = list->next;
+    }
+    return NULL;
+}
+
+sdlist_t* sdlist_geti(sdlist_t *list, int index) {
+    for (int i=0;i<index;i++) {
+        if (list == NULL) {
+            return NULL;
+        }
+        list = list->next;
+    }
+    return list;
+}
+
+sdlist_t* sdlist_getlast(sdlist_t *list) {
+    while(list->next != NULL) {
+        list = list->next;
+    }
+    return list;
+}
+
+
+
+/* miscellaneous functions */
+size_t sdlist_length(sdlist_t *list) {
+    int i = 0;
+    while(list->next != NULL) {
+        list = list->next;
+        i++;
+    }
+    return i;
+}
+
+void sdlist_free(sdlist_t *elm) {
+    free(elm);
+}
+
+void sdlist_foreach(sdlist_t *list, sdlist_iterator_func f, void *data) {
+    while(list != NULL) {
+        int r = f(list, data);
+        if (r) {
+            return;
+        }
+        list = list->next;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/list.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,106 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIST_H
+#define	LIST_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct _util_slist sdlist_t;
+
+struct _util_slist {
+    void *data;
+    sdlist_t *next;
+};
+
+typedef int (*sdlist_iterator_func)(sdlist_t*, void*);
+
+
+/* single linked list */
+
+/*
+ * sdlist_add/sdllist_addl
+ *
+ * append to the end of the list one element
+ */
+sdlist_t* sdlist_add(sdlist_t *list, void *data);
+sdlist_t* sdlist_addl(sdlist_t *list, sdlist_t *l);
+    
+/*
+ * sdlist_remove/sdlist_removei
+ *
+ * remove one element from the list and free the sdlist_t object
+ * returns the first element of the new list
+ */
+sdlist_t* sdlist_remove(sdlist_t *list, void *data);
+sdlist_t* sdlist_removei(sdlist_t *list, int index);
+
+/*
+ * sdlist_removel
+ *
+ * remove element l from the list
+ * returns the first element of the new list
+ */
+sdlist_t* sdlist_removel(sdlist_t *list, sdlist_t *l);
+
+/*
+ * removes one element from the list
+ *
+ * list:   list
+ * prev:   previous to elm
+ * elm:    element which should be removed
+ *
+ * returns the first element of the new list
+ */
+sdlist_t *sdlist_remove_elm(sdlist_t *list, sdlist_t *prev, sdlist_t *elm);
+    
+
+/*
+ * sdlist_insert
+ *
+ * insert one element after the element elm
+ */
+void sdlist_insert(sdlist_t *elm, void *data);
+void sdlist_insertl(sdlist_t *elm, sdlist_t *l);
+
+sdlist_t* sdlist_get(sdlist_t *list, void *data);
+sdlist_t* sdlist_geti(sdlist_t *list, int index);
+sdlist_t* sdlist_getlast(sdlist_t *list);
+
+size_t sdlist_length(sdlist_t *list);
+void sdlist_free(sdlist_t *elm);
+void sdlist_foreach(sdlist_t *list, sdlist_iterator_func f, void *data);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* LIST_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/map.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,134 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "map.h"
+
+hashmap_t* hashmap_new(size_t size) {
+    hashmap_t *map = malloc(sizeof(hashmap_t));
+    map->map = calloc(size, sizeof(sdlist_t));
+    map->len = size;
+
+    return map;
+}
+
+void hashmap_free(hashmap_t *map) {
+    for(int i=0;i<map->len;i++) {
+        sdlist_t *list = map->map[0];
+        while(list != NULL) {
+            hashmap_elm_t *elm = (hashmap_elm_t*)list->data;
+            free(elm->key.ptr);
+            sdlist_t *l = list;
+            list = list->next;
+            free(elm);
+            free(l);
+        }
+    }
+    free(map->map);
+    free(map);
+}
+
+
+void hashmap_put(hashmap_t *map, sstr_t key, void *value) {
+    int hash = hashmap_hash(key.ptr, key.length);
+
+    sdlist_t *list = map->map[hash%map->len];
+
+    sstr_t k = sstrdub(key);
+
+    hashmap_elm_t *elm = malloc(sizeof(hashmap_elm_t));
+    elm->data = value;
+    elm->hash = hash;
+    elm->key = k;
+
+    map->map[hash%map->len] = sdlist_add(list, elm);
+}
+
+void* hashmap_get(hashmap_t *map, sstr_t key) {
+    int hash = hashmap_hash(key.ptr, key.length);
+    sdlist_t *list = map->map[hash%map->len];
+    void *value = NULL;
+
+    while (list != NULL) {
+        hashmap_elm_t *elm = list->data;
+        if (elm->hash == hash &&
+                strncmp(key.ptr, elm->key.ptr, key.length) == 0) {
+            value = elm->data;
+            break;
+        }
+        list = list->next;
+    }
+
+    return value;
+}
+
+
+
+
+/* hash function */
+int hashmap_hash(char *data, size_t len) {
+    /* murmur hash 2 */
+
+    int m = 0x5bd1e995;
+    int r = 24;
+
+    int h = 25 ^ len;
+
+    int i = 0;
+    while (len >= 4) {
+        int k = data[i + 0] & 0xFF;
+        k |= (data[i + 1] & 0xFF) << 8;
+        k |= (data[i + 2] & 0xFF) << 16;
+        k |= (data[i + 3] & 0xFF) << 24;
+
+        k *= m;
+        k ^= k >> r;
+        k *= m;
+
+        h *= m;
+        h ^= k;
+
+        i += 4;
+        len -= 4;
+    }
+
+    switch (len) {
+        case 3: h ^= (data[i + 2] & 0xFF) << 16;
+        case 2: h ^= (data[i + 1] & 0xFF) << 8;
+        case 1: h ^= (data[i + 0] & 0xFF); h *= m;
+    }
+
+    h ^= h >> 13;
+    h *= m;
+    h ^= h >> 15;
+
+    return h;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/map.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,64 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAP_H
+#define	MAP_H
+
+#include "list.h"
+#include "../ucx/sstring.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct _hashmap_elm {
+    int hash;
+    sstr_t key;
+
+    void *data;
+} hashmap_elm_t;
+
+typedef struct _util_hashmap {
+    sdlist_t **map;
+    size_t len;
+} hashmap_t;
+
+hashmap_t* hashmap_new(size_t size);
+void hashmap_free(hashmap_t *map);
+
+void hashmap_put(hashmap_t *map, sstr_t key, void *value);
+void* hashmap_get(hashmap_t *map, sstr_t key);
+
+int hashmap_hash(char *data, size_t len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* MAP_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/netbuf.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,191 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * netbuf.c: Handles buffered I/O on network sockets
+ *
+ * Rob McCool
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "nspr.h"
+#include "../public/nsapi.h"
+#include "io.h"
+
+//include "buffer.h"
+
+
+#define NETBUF_RDTIMEOUT 120
+
+
+/* ----------------------------- netbuf_open ------------------------------ */
+
+
+NSAPI_PUBLIC netbuf *netbuf_open(SYS_NETFD sd, int sz) {
+    netbuf *buf = (netbuf *) malloc(sizeof(netbuf));
+
+    buf->rdtimeout = NETBUF_RDTIMEOUT;
+    buf->pos = sz;
+    buf->cursize = sz; /* force buffer_next on first getc */
+    buf->maxsize = sz;
+    buf->sd = sd;
+
+    buf->inbuf = NULL;
+    buf->errmsg = NULL;
+
+    return buf;
+}
+
+
+/* ----------------------------- netbuf_close ----------------------------- */
+
+
+NSAPI_PUBLIC void netbuf_close(netbuf *buf) {
+    if(buf->inbuf)
+        free(buf->inbuf);
+    free(buf);
+}
+
+
+/* ----------------------------- netbuf_replace --------------------------- */
+
+
+NSAPI_PUBLIC unsigned char * netbuf_replace(netbuf *buf,
+    unsigned char *inbuf, int pos, int cursize, int maxsize)
+{
+    unsigned char *oldbuf = buf->inbuf;
+
+    buf->inbuf = inbuf;
+    buf->pos = pos;
+    buf->cursize = cursize;
+    buf->maxsize = maxsize;
+
+    return oldbuf;
+}
+
+
+/* ----------------------------- netbuf_next ------------------------------ */
+
+
+NSAPI_PUBLIC int netbuf_next(netbuf *buf, int advance) {
+    int n;
+
+    if(!buf->inbuf)
+        buf->inbuf = (unsigned char *) malloc(buf->maxsize);
+
+    while(1) {
+        switch(n = net_read(buf->sd, (char *)(buf->inbuf), buf->maxsize)) {
+        //case IO_EOF:
+        case 0:
+            return IO_EOF;
+        case -1:
+            return IO_ERROR;
+        //case IO_ERROR:
+            //buf->errmsg = system_errmsg();
+        //    return IO_ERROR;
+        default:
+            buf->pos = advance;
+            buf->cursize = n;
+            return buf->inbuf[0];
+        }
+    }
+}
+
+NSAPI_PUBLIC int netbuf_getbytes(netbuf *buf, char *buffer, int size)
+{
+    int bytes;
+
+    if (!buf->inbuf) {
+        buf->inbuf = (unsigned char *) malloc(buf->maxsize);
+    } else {
+        if (buf->pos < buf->cursize) {
+            int bytes_in_buffer = buf->cursize - buf->pos;
+
+            if (bytes_in_buffer > size)
+                bytes_in_buffer = size;
+
+            memcpy(buffer, &(buf->inbuf[buf->pos]), bytes_in_buffer);
+
+            buf->pos += bytes_in_buffer;
+            return bytes_in_buffer;
+        }
+    }
+
+    /* The netbuf is empty.  Read data directly into the caller's buffer */
+    bytes = net_read(buf->sd, buffer, size);
+    if (bytes == 0)
+        return NETBUF_EOF;
+    if (bytes < 0) {
+        //buf->errmsg = system_errmsg();
+        return NETBUF_ERROR;
+    }
+    return bytes;
+}
+
+
+/* ----------------------------- netbuf_grab ------------------------------ */
+
+
+NSAPI_PUBLIC int netbuf_grab(netbuf *buf, int sz) {
+    int n;
+
+    if(!buf->inbuf) {
+        buf->inbuf = (unsigned char *) malloc(sz);
+        buf->maxsize = sz;
+    }
+    else if(sz > buf->maxsize) {
+        buf->inbuf = (unsigned char *) realloc(buf->inbuf, sz);
+        buf->maxsize = sz;
+    }
+
+    PR_ASSERT(buf->pos == buf->cursize);
+    buf->pos = 0;
+    buf->cursize = 0;
+
+    while(1) {
+        switch(n = net_read(buf->sd, (char *)(buf->inbuf), sz)) {
+        case 0:
+            return IO_EOF;
+        case -1: {
+            //buf->errmsg = system_errmsg();
+            return IO_ERROR;
+        }
+        default:
+            buf->cursize = n;
+            return n;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/object.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,134 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "../public/nsapi.h"
+
+#include "object.h"
+
+#include "pool.h"
+#include "../daemon/func.h"
+
+
+
+httpd_object* object_new(char *name) {
+    // TODO: Speicherverwaltung
+    httpd_object *obj = malloc(sizeof(httpd_object));
+    obj->name = name;
+    obj->path = NULL;
+
+    // create directive table
+    obj->dt = calloc(sizeof(struct dtable), NUM_NSAPI_TYPES - 1);
+    obj->nd = NUM_NSAPI_TYPES - 1;
+
+    return obj;
+}
+
+void object_free(httpd_object *obj) {
+    free(obj->name);
+    // TODO: free objects
+    free(obj->dt);
+}
+
+
+void object_add_directive(httpd_object *obj, directive *dir, int dt) {
+    dtable *l = object_get_dtable(obj, dt);
+    // allocate space for the new directive
+
+    //l->dirs = realloc(l->dirs, (l->ndir+1)*sizeof(void*));
+    /* TODO: aus irgend einem Grund funktioniert realloc nicht. warum?? */
+    
+    directive **drs = malloc((l->ndir+1)*sizeof(void*));
+    for(int i=0;i<l->ndir;i++) {
+        drs[i] = l->dirs[i];
+    }
+    if(l->dirs != NULL) {
+        free(l->dirs);
+    }
+    l->dirs = drs;
+
+    // add directive
+    l->dirs[l->ndir] = dir;
+    l->ndir++;
+}
+
+
+/* objset functions */
+httpd_objset* objset_create(pool_handle_t *pool) {
+    httpd_objset *os = pool_malloc(pool, sizeof(httpd_objset));
+
+    os->obj = pool_calloc(pool, 2, sizeof(void*));
+    os->pos = 0;
+
+    return os;
+}
+
+void objset_add_object(pool_handle_t *p, httpd_objset *os, httpd_object *obj) {
+    if(os->pos != 0 && os->pos % 2 == 0) {
+        os->obj = pool_realloc(p, os->obj, (os->pos + 2) * sizeof(void*));
+    }
+    os->obj[os->pos] = obj;
+    os->pos++;
+}
+
+
+
+
+httpd_objset* create_test_objset() {
+    httpd_objset *objset = malloc(sizeof(httpd_objset));
+    objset->obj = calloc(1, sizeof(httpd_object*));
+
+    httpd_object *obj = object_new("default");
+    objset->obj[0] = obj;
+    objset->pos = 1;
+    
+    directive *d1 = malloc(sizeof(directive));
+    d1->func = get_function("test-nametrans");
+    d1->param = NULL;
+    object_add_directive(obj, d1, NSAPINameTrans);
+
+    directive *d2 = malloc(sizeof(directive));
+    d2->func = get_function("test-service");
+    d2->param = NULL;
+    object_add_directive(obj, d2, NSAPIService);
+    
+    return objset;
+}
+
+
+void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj) {
+    conf->nobj++;
+    conf->objects = realloc(conf->objects, conf->nobj * sizeof(void*));
+    conf->objects[conf->nobj - 1] = obj;
+}
+
+
+void nsapi_context_next_stage(NSAPIContext *context) {
+    context->dtable_index  = 0;
+    context->objset_index  = -1;
+    context->last_req_code = REQ_NOACTION;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/object.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,163 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OBJECT_H
+#define	OBJECT_H
+
+#include "../public/nsapi.h"
+#include "pool.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+// TODO: Enum auslagern in andere Datei?
+enum RequestPhase {
+    NSAPIAuthTrans = 0,
+    NSAPINameTrans,
+    NSAPIPathCheck,
+    NSAPIObjectType,
+    NSAPIService,
+    NSAPIAddLog,
+    REQ_FINISH,
+    NUM_NSAPI_TYPES
+};
+typedef enum RequestPhase RequestPhase;
+
+typedef struct Condition          Condition;
+typedef int8_t                    ConditionResult;
+
+typedef struct NSAPIContext       NSAPIContext;
+typedef struct HTTPObjectConfig   HTTPObjectConfig;
+
+struct directive {
+    FuncStruct *func;
+    pblock     *param;
+    Condition  *cond;
+};
+
+struct dtable {
+    directive **dirs;
+    int       ndir;
+};
+
+struct httpd_object {
+    char   *name;
+    char   *path;
+    dtable *dt;
+    int    nd;
+};
+
+struct httpd_objset {
+    httpd_object **obj;
+    int pos;
+};
+
+struct Condition {
+    Condition  *parent;
+    int        expression;
+    int        index; /* used by NSAPIContext to link expression with result */
+};
+
+
+struct NSAPIContext{
+    HTTPObjectConfig  *conf;
+
+    ConditionResult   **results;
+    int               nres;
+
+    //httpd_objset      *objset;
+    int last_req_code;
+
+    int objset_index;
+    int dtable_index;
+};
+
+struct HTTPObjectConfig {
+    httpd_object  **objects;
+    int           nobj;
+    pool_handle_t *pool;
+};
+
+/*
+ * creates a new httpd_object
+ */
+httpd_object* object_new(char *name);
+
+/*
+ * frees an httpd_object
+ */
+void object_free(httpd_object *obj);
+
+/*
+ * adds a directive to the object with the type dt (enum RequestPhase)
+ */
+void object_add_directive(httpd_object *obj, directive *dir, int dt);
+
+/*
+ * get a list of all directives with a specific type
+ */
+#define object_get_dtable(obj,type) &obj->dt[type];
+
+
+
+/*
+ * creates a new httpd_objset
+ */
+httpd_objset* objset_create(pool_handle_t *pool);
+
+/*
+ * adds a object to the objset
+ */
+void objset_add_object(pool_handle_t *p, httpd_objset *os, httpd_object *obj);
+
+
+/*
+ * creates a new HTTPObjectConfig
+ */
+// TODO
+
+/*
+ * adds an object to the object configuration
+ */
+void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj);
+
+
+
+/*
+ * prepares the NSAPI context for the next request stage
+ */
+void nsapi_context_next_stage(NSAPIContext *context);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* OBJECT_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/objs.mk	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,50 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+UTIL_SRC_DIR = server/util/
+
+UTIL_OBJPRE = $(OBJ_DIR)$(UTIL_SRC_DIR)
+
+UTILOBJ = io.o
+UTILOBJ += list.o
+UTILOBJ += map.o
+UTILOBJ += netbuf.o
+UTILOBJ += object.o
+UTILOBJ += pblock.o
+UTILOBJ += plist.o
+UTILOBJ += pool.o
+UTILOBJ += shexp.o
+UTILOBJ += strbuf.o
+UTILOBJ += system.o
+UTILOBJ += systhr.o
+UTILOBJ += thrpool.o
+UTILOBJ += uri.o
+UTILOBJ += util.o
+
+UTILOBJS = $(UTILOBJ:%=$(UTIL_OBJPRE)%)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/pblock.cpp	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,1211 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * pblock.c: Handles Parameter Blocks
+ * 
+ * See pblock.h for public documentation.
+ * 
+ * Rob McCool
+ * 
+ * This code uses property lists to implement pblocks.
+ */
+
+
+#include <limits.h>
+#include "pblock.h"
+#include "plist_pvt.h"
+#include "plist.h"
+#include "LinkedList.hh"
+#include "util.h"   /* util_itoa */
+#include "pool.h"
+#include "systhr.h"
+
+#define MALLOC_POOL_HANDLE (thread_malloc_key != -1 ? (pool_handle_t *)systhread_getdata(thread_malloc_key) : getThreadMallocPool())
+
+static int thread_malloc_key = -1;
+static int _pblock_str2pblock(const char* str, pblock* pb, PRBool lowerCase);
+
+static pool_handle_t *getThreadMallocPool()
+{
+    pool_handle_t *thread_malloc_pool = 0;
+
+    thread_malloc_key = getThreadMallocKey();
+    if (thread_malloc_key != -1) {
+        thread_malloc_pool = (pool_handle_t *)systhread_getdata(thread_malloc_key);
+    }
+
+    return thread_malloc_pool;
+}
+
+/* ------------------------------- HashList ------------------------------- */
+
+template <class Name, class Value>
+class HashList {
+public:
+    HashList(int mask)
+    : _mask(mask),
+      _list(new CList<Value>[mask + 1])
+    { }
+
+    void Insert(Name name, Value *value)
+    {
+        _list[name & _mask].Append(value);
+    }
+
+    const CList<Value>& Find(Name name)
+    {
+        return _list[name & _mask];
+    }
+
+private:
+    CList<Value> *_list;
+    unsigned int _mask;
+};
+
+/* ---------------------- pb_key static initializers ---------------------- */
+
+/*
+ * pb_key
+ *
+ * Contains a precomputed hash value for a specific pblock variable name.
+ */
+typedef struct pb_key pb_key;
+struct pb_key {
+    const char *name;
+    int namelen; 
+    unsigned int hashval;
+    int sizendx;
+    int hashndx;
+};
+
+static HashList<unsigned int, pb_key> _hashKeys(0x7f);
+CList<pb_key> _listKeys;
+
+static const pb_key *const _create_key(const char *name, int sizendx = 0)
+{
+    /* Create a the new pb_key */
+    pb_key *key = (pb_key*)malloc(sizeof(pb_key));
+    key->name = STRDUP(name);
+    key->namelen = strlen(name);
+    key->hashval = PListHash(name);
+    key->sizendx = sizendx;
+    key->hashndx = key->hashval % PLSIZENDX(sizendx);
+
+    /* Group pb_keys by hashval for later retrieval */
+    _hashKeys.Insert(key->hashval, key);
+
+    /* Keep a list of all the registered keys */
+    _listKeys.Append(key);
+
+    return key;
+}
+
+const pb_key *const pb_key_accept = _create_key("accept");
+const pb_key *const pb_key_accept_charset = _create_key("accept-charset");
+const pb_key *const pb_key_accept_encoding = _create_key("accept-encoding");
+const pb_key *const pb_key_accept_language = _create_key("accept-language");
+const pb_key *const pb_key_accept_ranges = _create_key("accept-ranges");
+const pb_key *const pb_key_actual_route = _create_key("actual-route");
+const pb_key *const pb_key_age = _create_key("age");
+const pb_key *const pb_key_always_allow_chunked = _create_key("always-allow-chunked");
+const pb_key *const pb_key_always_use_keep_alive = _create_key("always-use-keep-alive");
+const pb_key *const pb_key_auth_cert = _create_key("auth-cert");
+const pb_key *const pb_key_auth_expiring = _create_key("auth-expiring");
+const pb_key *const pb_key_auth_group = _create_key("auth-group");
+const pb_key *const pb_key_auth_type = _create_key("auth-type");
+const pb_key *const pb_key_auth_user = _create_key("auth-user");
+const pb_key *const pb_key_authorization = _create_key("authorization");
+const pb_key *const pb_key_browser = _create_key("browser");
+const pb_key *const pb_key_c2p_cl = _create_key("c2p-cl");
+const pb_key *const pb_key_c2p_hl = _create_key("c2p-hl");
+const pb_key *const pb_key_cache_info = _create_key("cache-info");
+const pb_key *const pb_key_charset = _create_key("charset");
+const pb_key *const pb_key_check_http_server = _create_key("check-http-server");
+const pb_key *const pb_key_ChunkedRequestBufferSize = _create_key("ChunkedRequestBufferSize");
+const pb_key *const pb_key_ChunkedRequestTimeout = _create_key("ChunkedRequestTimeout");
+const pb_key *const pb_key_cipher = _create_key("cipher");
+const pb_key *const pb_key_clf_request = _create_key("clf-request");
+const pb_key *const pb_key_cli_status = _create_key("cli-status");
+const pb_key *const pb_key_client_cert_nickname = _create_key("client-cert-nickname");
+const pb_key *const pb_key_client_ip = _create_key("client-ip");
+const pb_key *const pb_key_close = _create_key("close");
+const pb_key *const pb_key_connect_timeout = _create_key("connect-timeout");
+const pb_key *const pb_key_connection = _create_key("connection");
+const pb_key *const pb_key_cont = _create_key("cont");
+const pb_key *const pb_key_content_encoding = _create_key("content-encoding");
+const pb_key *const pb_key_content_language = _create_key("content-language");
+const pb_key *const pb_key_content_length = _create_key("content-length");
+const pb_key *const pb_key_content_location = _create_key("content-location");
+const pb_key *const pb_key_content_md5 = _create_key("content-md5");
+const pb_key *const pb_key_content_range = _create_key("content-range");
+const pb_key *const pb_key_content_type = _create_key("content-type");
+const pb_key *const pb_key_cookie = _create_key("cookie");
+const pb_key *const pb_key_date = _create_key("date");
+const pb_key *const pb_key_DATE_GMT = _create_key("DATE_GMT");
+const pb_key *const pb_key_DATE_LOCAL = _create_key("DATE_LOCAL");
+const pb_key *const pb_key_dir = _create_key("dir");
+const pb_key *const pb_key_Directive = _create_key("Directive");
+const pb_key *const pb_key_dns = _create_key("dns");
+const pb_key *const pb_key_DOCUMENT_NAME = _create_key("DOCUMENT_NAME");
+const pb_key *const pb_key_DOCUMENT_URI = _create_key("DOCUMENT_URI");
+const pb_key *const pb_key_domain = _create_key("domain");
+const pb_key *const pb_key_enc = _create_key("enc");
+const pb_key *const pb_key_engine = _create_key("engine");
+const pb_key *const pb_key_error_action = _create_key("error-action");
+const pb_key *const pb_key_error_desc = _create_key("error-desc");
+const pb_key *const pb_key_error_fn = _create_key("error-fn");
+const pb_key *const pb_key_escape = _create_key("escape");
+const pb_key *const pb_key_escaped = _create_key("escaped");
+const pb_key *const pb_key_etag = _create_key("etag");
+const pb_key *const pb_key_expect = _create_key("expect");
+const pb_key *const pb_key_expires = _create_key("expires");
+const pb_key *const pb_key_expr = _create_key("expr");
+const pb_key *const pb_key_filter = _create_key("filter");
+const pb_key *const pb_key_find_pathinfo_forward = _create_key("find-pathinfo-forward");
+const pb_key *const pb_key_flushTimer = _create_key("flushTimer");
+const pb_key *const pb_key_fn = _create_key("fn");
+const pb_key *const pb_key_from = _create_key("from");
+const pb_key *const pb_key_full_headers = _create_key("full-headers");
+const pb_key *const pb_key_hdr = _create_key("hdr");
+const pb_key *const pb_key_host = _create_key("host");
+const pb_key *const pb_key_hostname = _create_key("hostname");
+const pb_key *const pb_key_if_match = _create_key("if-match");
+const pb_key *const pb_key_if_modified_since = _create_key("if-modified-since");
+const pb_key *const pb_key_if_none_match = _create_key("if-none-match");
+const pb_key *const pb_key_if_range = _create_key("if-range");
+const pb_key *const pb_key_if_unmodified_since = _create_key("if-unmodified-since");
+const pb_key *const pb_key_ip = _create_key("ip");
+const pb_key *const pb_key_iponly = _create_key("iponly");
+const pb_key *const pb_key_issuer_dn = _create_key("issuer_dn");
+const pb_key *const pb_key_jroute = _create_key("jroute");
+const pb_key *const pb_key_keep_alive = _create_key("keep-alive");
+const pb_key *const pb_key_keep_alive_timeout = _create_key("keep-alive-timeout");
+const pb_key *const pb_key_keysize = _create_key("keysize");
+const pb_key *const pb_key_lang = _create_key("lang");
+const pb_key *const pb_key_LAST_MODIFIED = _create_key("LAST_MODIFIED");
+const pb_key *const pb_key_last_modified = _create_key("last-modified");
+const pb_key *const pb_key_level = _create_key("level");
+const pb_key *const pb_key_location = _create_key("location");
+const pb_key *const pb_key_lock_owner = _create_key("lock-owner");
+const pb_key *const pb_key_magnus_charset = _create_key("magnus-charset");
+const pb_key *const pb_key_magnus_internal = _create_key("magnus-internal");
+const pb_key *const pb_key_magnus_internal_dav_src = _create_key("magnus-internal/dav-src");
+const pb_key *const pb_key_magnus_internal_default_acls_only = _create_key("magnus-internal/default-acls-only");
+const pb_key *const pb_key_magnus_internal_error_j2ee = _create_key("magnus-internal/error-j2ee");
+const pb_key *const pb_key_magnus_internal_j2ee_nsapi = _create_key("magnus-internal/j2ee-nsapi");
+const pb_key *const pb_key_magnus_internal_preserve_srvhdrs = _create_key("magnus-internal/preserve-srvhdrs-after-req-restart");
+const pb_key *const pb_key_magnus_internal_set_request_status = _create_key("magnus-internal/set-request-status");
+const pb_key *const pb_key_magnus_internal_set_response_status = _create_key("magnus-internal/set-response-status");
+const pb_key *const pb_key_magnus_internal_webapp_errordesc = _create_key("magnus-internal/webapp-errordesc");
+const pb_key *const pb_key_matched_browser = _create_key("matched-browser");
+const pb_key *const pb_key_max_age = _create_key("max-age");
+const pb_key *const pb_key_max_forwards = _create_key("max-forwards");
+const pb_key *const pb_key_message = _create_key("message");
+const pb_key *const pb_key_method = _create_key("method");
+const pb_key *const pb_key_name = _create_key("name");
+const pb_key *const pb_key_nocache = _create_key("nocache");
+const pb_key *const pb_key_nostat = _create_key("nostat");
+const pb_key *const pb_key_ntrans_base = _create_key("ntrans-base");
+const pb_key *const pb_key_offline_origin_addr = _create_key("offline-origin-addr");
+const pb_key *const pb_key_offline_proxy_addr = _create_key("offline-proxy-addr");
+const pb_key *const pb_key_origin_addr = _create_key("origin-addr");
+const pb_key *const pb_key_p2c_cl = _create_key("p2c-cl");
+const pb_key *const pb_key_p2c_hl = _create_key("p2c-hl");
+const pb_key *const pb_key_p2r_cl = _create_key("p2r-cl");
+const pb_key *const pb_key_p2r_hl = _create_key("p2r-hl");
+const pb_key *const pb_key_parse_timeout = _create_key("parse-timeout");
+const pb_key *const pb_key_password = _create_key("password");
+const pb_key *const pb_key_path = _create_key("path");
+const pb_key *const pb_key_PATH_INFO = _create_key("PATH_INFO");
+const pb_key *const pb_key_path_info = _create_key("path-info");
+const pb_key *const pb_key_pblock = _create_key("pblock");
+const pb_key *const pb_key_poll_interval = _create_key("poll-interval");
+const pb_key *const pb_key_port = _create_key("port");
+const pb_key *const pb_key_ppath = _create_key("ppath");
+const pb_key *const pb_key_pragma = _create_key("pragma");
+const pb_key *const pb_key_process_request_body = _create_key("process-request-body");
+const pb_key *const pb_key_process_response_body = _create_key("process-response-body");
+const pb_key *const pb_key_protocol = _create_key("protocol");
+const pb_key *const pb_key_proxy_addr = _create_key("proxy-addr");
+const pb_key *const pb_key_proxy_agent = _create_key("proxy-agent");
+const pb_key *const pb_key_proxy_auth_cert = _create_key("proxy-auth-cert");
+const pb_key *const pb_key_proxy_authorization = _create_key("proxy-authorization");
+const pb_key *const pb_key_proxy_cipher = _create_key("proxy-cipher");
+const pb_key *const pb_key_proxy_issuer_dn = _create_key("proxy-issuer-dn");
+const pb_key *const pb_key_proxy_jroute = _create_key("proxy-jroute");
+const pb_key *const pb_key_proxy_keysize = _create_key("proxy-keysize");
+const pb_key *const pb_key_proxy_ping = _create_key("proxy-ping");
+const pb_key *const pb_key_proxy_request = _create_key("proxy-request");
+const pb_key *const pb_key_proxy_secret_keysize = _create_key("proxy-secret-keysize");
+const pb_key *const pb_key_proxy_ssl_id = _create_key("proxy-ssl-id");
+const pb_key *const pb_key_proxy_user_dn = _create_key("proxy-user-dn");
+const pb_key *const pb_key_query = _create_key("query");
+const pb_key *const pb_key_QUERY_STRING = _create_key("QUERY_STRING");
+const pb_key *const pb_key_QUERY_STRING_UNESCAPED = _create_key("QUERY_STRING_UNESCAPED");
+const pb_key *const pb_key_r2p_cl = _create_key("r2p-cl");
+const pb_key *const pb_key_r2p_hl = _create_key("r2p-hl");
+const pb_key *const pb_key_range = _create_key("range");
+const pb_key *const pb_key_referer = _create_key("referer");
+const pb_key *const pb_key_reformat_request_headers = _create_key("reformat-request-headers");
+const pb_key *const pb_key_remote_status = _create_key("remote-status");
+const pb_key *const pb_key_request_jroute = _create_key("request-jroute");
+const pb_key *const pb_key_required_rights = _create_key("required-rights");
+const pb_key *const pb_key_retries = _create_key("retries");
+const pb_key *const pb_key_rewrite_content_location = _create_key("rewrite-content-location");
+const pb_key *const pb_key_rewrite_host = _create_key("rewrite-host");
+const pb_key *const pb_key_rewrite_location = _create_key("rewrite-location");
+const pb_key *const pb_key_rewrite_set_cookie = _create_key("rewrite-set-cookie");
+const pb_key *const pb_key_root = _create_key("root");
+const pb_key *const pb_key_route = _create_key("route");
+const pb_key *const pb_key_route_cookie = _create_key("route-cookie");
+const pb_key *const pb_key_route_hdr = _create_key("route-hdr");
+const pb_key *const pb_key_route_offline = _create_key("route-offline");
+const pb_key *const pb_key_script_name = _create_key("script-name");
+const pb_key *const pb_key_secret_keysize = _create_key("secret-keysize");
+const pb_key *const pb_key_secure = _create_key("secure");
+const pb_key *const pb_key_server = _create_key("server");
+const pb_key *const pb_key_set_cookie = _create_key("set-cookie");
+const pb_key *const pb_key_socks_addr = _create_key("socks_addr");
+const pb_key *const pb_key_ssl_id = _create_key("ssl-id");
+const pb_key *const pb_key_ssl_unclean_shutdown = _create_key("ssl-unclean-shutdown");
+const pb_key *const pb_key_status = _create_key("status");
+const pb_key *const pb_key_sticky_cookie = _create_key("sticky-cookie");
+const pb_key *const pb_key_sticky_param = _create_key("sticky-param");
+const pb_key *const pb_key_suppress_request_headers = _create_key("suppress-request-headers");
+const pb_key *const pb_key_svr_status = _create_key("svr-status");
+const pb_key *const pb_key_timeout = _create_key("timeout");
+const pb_key *const pb_key_to = _create_key("to");
+const pb_key *const pb_key_transfer_encoding = _create_key("transfer-encoding");
+const pb_key *const pb_key_transmit_timeout = _create_key("transmit-timeout");
+const pb_key *const pb_key_tunnel_non_http_response = _create_key("tunnel-non-http-response");
+const pb_key *const pb_key_type = _create_key("type");
+const pb_key *const pb_key_upstream_jroute = _create_key("upstream-jroute");
+const pb_key *const pb_key_uri = _create_key("uri");
+const pb_key *const pb_key_url = _create_key("url");
+const pb_key *const pb_key_url_prefix = _create_key("url-prefix");
+const pb_key *const pb_key_UseOutputStreamSize = _create_key("UseOutputStreamSize");
+const pb_key *const pb_key_user = _create_key("user");
+const pb_key *const pb_key_user_agent = _create_key("user-agent");
+const pb_key *const pb_key_user_dn = _create_key("user_dn");
+const pb_key *const pb_key_validate_server_cert = _create_key("validate-server-cert");
+const pb_key *const pb_key_value = _create_key("value");
+const pb_key *const pb_key_vary = _create_key("vary");
+const pb_key *const pb_key_via = _create_key("via");
+const pb_key *const pb_key_warning = _create_key("warning");
+
+
+/* ------------------------------ _find_key ------------------------------- */
+
+static inline const pb_key *_find_key(const char *name, unsigned int hashval)
+{
+    /* Check to see if name corresponds to a pb_key */
+    CListConstIterator<pb_key> iter(&_hashKeys.Find(hashval));
+    const pb_key *key;
+    while (key = ++iter) {
+        if (key->hashval == hashval && !strcmp(key->name, name))
+            return key;
+    }
+    return NULL;
+}
+
+
+/* --------------------------- _get_hash_index ---------------------------- */
+
+static inline int _get_hash_index(const PListStruct_t *pl, const pb_key *key)
+{
+    /* Get the hash index from the key.  Requires a symbol table. */
+    int i;
+    if (key->sizendx == pl->pl_symtab->pt_sizendx)
+        i = key->hashndx;
+    else
+        i = key->hashval % PLSIZENDX(pl->pl_symtab->pt_sizendx);
+    return i;
+}
+
+
+/* ---------------------------- _param_create ----------------------------- */
+
+static inline pb_param *_param_create(pool_handle_t *pool_handle, const char *name, int namelen, const char *value, int valuelen)
+{
+    PLValueStruct_t *ret;
+
+    ret = (PLValueStruct_t *)pool_malloc(pool_handle, sizeof(PLValueStruct_t));
+
+    ret->pv_pbentry.param = &ret->pv_pbparam;
+    ret->pv_pbentry.next = 0;
+    ret->pv_next = 0;
+    ret->pv_type = 0;
+    ret->pv_mempool = pool_handle;
+
+    if (name || namelen) {
+        ret->pv_name = (char*)pool_malloc(pool_handle, namelen + 1);
+        if (name) {
+            memcpy(ret->pv_name, name, namelen);
+            ret->pv_name[namelen] = '\0';
+        } else {
+            ret->pv_name[0] = '\0';
+        }
+    } else {
+        ret->pv_name = 0;
+    }
+
+    if (value || valuelen) {
+        ret->pv_value = (char*)pool_malloc(pool_handle, valuelen + 1);
+        if (value) {
+            memcpy(ret->pv_value, value, valuelen);
+            ret->pv_value[valuelen] = '\0';
+        } else {
+            ret->pv_value[0] = '\0';
+        }
+    } else {
+        ret->pv_value = 0;
+    }
+
+    return &ret->pv_pbparam;
+}
+
+
+/* ----------------------- pblock_key_param_create  ----------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen)
+{
+    /*
+     * Allocate a PLValueStruct_t from the property list's memory pool.
+     */
+    PListStruct_t *pl = PBTOPL(pb);
+    return _param_create(pl->pl_mempool, key->name, key->namelen, value, valuelen);
+}
+
+
+/* ------------------------- pblock_param_create -------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value)
+{
+    /*
+     * Allocate a PLValueStruct_t from the property list's memory pool.
+     */
+    PListStruct_t *pl = PBTOPL(pb);
+    return _param_create(pl->pl_mempool, name, name ? strlen(name) : 0, value, value ? strlen(value) : 0);
+}
+
+
+/* ----------------------------- param_create ----------------------------- */
+
+NSAPI_PUBLIC pb_param *param_create(const char *name, const char *value)
+{
+    /*
+     * Allocate a PLValueStruct_t containing the pb_param that will
+     * be returned.  Normally PLValueStruct_ts are allocated from the
+     * memory pool associated with a property list, but we don't have
+     * that here, so we just use the thread's pool and indicate we were
+     * allocated from a specific pool.
+     */
+    return _param_create(system_pool(), name, name ? strlen(name) : 0, value, value ? strlen(value) : 0);
+}
+
+
+/* ------------------------------ param_free ------------------------------ */
+
+NSAPI_PUBLIC int param_free(pb_param *pp)
+{
+    if (pp) {
+        PLValueStruct_t *pv = PATOPV(pp);
+
+        /* Don't bother if the pblock was allocated from a pool */
+        if (!pv->pv_mempool) {
+            pool_free(pv->pv_mempool, pv->pv_name);
+            pool_free(pv->pv_mempool, pv->pv_value);
+            pool_free(pv->pv_mempool, pv);
+        }
+
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/* -------------------------- pblock_create_pool -------------------------- */
+
+NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n)
+{
+    /* Create a property list with n property indices */
+    PListStruct_t *plist = (PListStruct_t *)PListCreate(pool_handle, n, 0, 0);
+    if (!plist)
+        return NULL;
+
+    plist->pl_resvpi = 0;
+
+    return &plist->pl_pb;
+}
+
+
+/* ----------------------------- pblock_pool ------------------------------ */
+
+NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+    return pl->pl_mempool;
+}
+
+
+/* ---------------------------- pblock_create ----------------------------- */
+
+NSAPI_PUBLIC pblock *pblock_create(int n)
+{
+    return pblock_create_pool(MALLOC_POOL_HANDLE, n);
+}
+
+
+/* ----------------------------- pblock_free ------------------------------ */
+
+NSAPI_PUBLIC void pblock_free(pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int i;
+
+    if (!pb) {
+        return;
+    }
+
+    /* If the pools are enabled, this routine has no effect anyway, so 
+     * just return. 
+     */
+    if (pl->pl_mempool || pool_enabled()) {
+        return;
+    }
+
+    /* Free the property name symbol table if any */
+    if (pl->pl_symtab) {
+        pool_free(pl->pl_mempool, (void *)(pl->pl_symtab));
+    }
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Loop over the initialized property indices */
+    for (i = 0; i < pl->pl_initpi; ++i) {
+
+        /* Got a property here? */
+        pv = ppval[i];
+        if (pv) {
+
+            param_free(&pv->pv_pbparam);
+        }
+    }
+
+    /* Free the array of pointers to property values */
+    pool_free(pl->pl_mempool, (void *)ppval);
+
+    /* Free the property list head */
+    pool_free(pl->pl_mempool, (void *)pl);
+}
+
+
+/* ------------------------------ pblock_key ------------------------------ */
+
+NSAPI_PUBLIC const pb_key *pblock_key(const char *name)
+{
+    if (!name)
+        return NULL;
+
+    return _find_key(name, PListHash(name));
+}
+
+
+/* --------------------------- pblock_kpinsert ---------------------------- */
+
+NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+    PLValueStruct_t *pv = PATOPV(pp);
+
+    PR_ASSERT(pv->pv_mempool == pl->pl_mempool);
+
+    /* Check to see if the name corresponds to a pb_key */
+    unsigned int hashval;
+    if (!key) {
+        hashval = PListHash(pv->pv_name);
+        key = _find_key(pv->pv_name, hashval);
+    }
+
+    /* Find property index */
+    int pindex = PListGetFreeIndex(pl);
+    if (pindex < 1) {
+        /* Error - invalid property index */
+        printf("Error - invalid property index\n");
+        return;
+    }
+
+    /* Allocate/grow the symbol table as needed */
+    PLSymbolTable_t *pt = PListSymbolTable(pl);
+    if (!pt) {
+        printf("!pt\n");
+        return;
+    }
+
+    /* Add PLValueStruct_t to the property list */
+    PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
+    pv->pv_pbkey = key;
+    pv->pv_pi = pindex;
+    ppval[pv->pv_pi - 1] = pv;
+
+    /* Add name to symbol table */
+    int i = key ? _get_hash_index(pl, key) : (hashval % PLSIZENDX(pt->pt_sizendx));
+    pv->pv_next = pt->pt_hash[i];
+    pt->pt_hash[i] = pv;
+    pt->pt_nsyms++;
+
+    PR_ASSERT(param_key(pp) == key);
+}
+
+
+/* ---------------------------- pblock_pinsert ---------------------------- */
+
+NSAPI_PUBLIC void pblock_pinsert(pb_param *pp, pblock *pb)
+{
+    pblock_kpinsert(NULL, pp, pb);
+}
+
+
+/* --------------------------- pblock_nvinsert ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_nvinsert(const char *name, const char *value, pblock *pb)
+{
+    pb_param *pp = pblock_param_create(pb, name, value);
+    if (pp)
+        pblock_kpinsert(NULL, pp, pb);
+    return pp;
+}
+
+
+/* --------------------------- pblock_kvinsert ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb)
+{
+    pb_param *pp = pblock_key_param_create(pb, key, value, valuelen);
+    if (pp)
+        pblock_kpinsert(key, pp, pb);
+    return pp;
+}
+
+
+/* --------------------------- pblock_nninsert ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_nninsert(const char *name, int value, pblock *pb)
+{
+    char num[UTIL_ITOA_SIZE];
+
+    util_itoa(value, num);
+    return pblock_nvinsert(name, num, pb);
+}
+
+
+/* --------------------------- pblock_kninsert ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb)
+{
+    pb_param *pp = pblock_key_param_create(pb, key, NULL, UTIL_ITOA_SIZE);
+    if (pp) {
+        util_itoa(value, pp->value);
+        pblock_kpinsert(key, pp, pb);
+    }
+    return pp;
+}
+
+
+/* --------------------------- pblock_kllinsert --------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, PRInt64 value, pblock *pb)
+{
+    pb_param *pp = pblock_key_param_create(pb, key, NULL, UTIL_I64TOA_SIZE);
+    if (pp) {
+        util_i64toa(value, pp->value);
+        pblock_kpinsert(key, pp, pb);
+    }
+    return pp;
+}
+
+
+/* ---------------------------pblock_nvlinsert ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    pb_param *pp = _param_create(pl->pl_mempool, name, namelen, value, valuelen);
+
+    if(pp) {
+        pblock_kpinsert(NULL, pp, pb);
+    }
+
+    return pp;
+}
+
+
+/* ---------------------------- pblock_findkey ---------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    /* Lookup key by examining symbol table */
+    if (pl->pl_symtab) {
+        int i = _get_hash_index(pl, key);
+        PLValueStruct_t *pv;
+
+        /* Search hash collision list for matching name */
+        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
+            if (pv->pv_pbkey == key)
+                return &pv->pv_pbparam;
+        }
+    }
+
+    return NULL;
+}
+
+
+/* -------------------------- pblock_findkeyval --------------------------- */
+
+NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb)
+{
+    pb_param *pp = pblock_findkey(key, pb);
+    return pp ? pp->value : NULL;
+}
+
+
+/* ---------------------------- pblock_findval ---------------------------- */
+
+NSAPI_PUBLIC char *pblock_findval(const char *name, const pblock *pb)
+{
+    void *pvalue = 0;
+
+    (void)PListFindValue((PList_t)(PBTOPL(pb)), name, &pvalue, 0);
+
+    return (char *)pvalue;
+}
+
+
+/* ------------------------------ pblock_fr ------------------------------ */
+
+NSAPI_PUBLIC pb_param *pblock_fr(const char *name, pblock *pb, int remove)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+    PLValueStruct_t **ppval;
+    PLValueStruct_t **pvp;
+    PLValueStruct_t *pv = NULL;
+    int pindex;
+    int i;
+
+    if (pl->pl_symtab) {
+
+        /* Compute hash index of specified property name */
+        i = PListHashName(pl->pl_symtab, name);
+
+        /* Search hash collision list for matching name */
+        for (pvp = &pl->pl_symtab->pt_hash[i];
+             (pv = *pvp); pvp = &(*pvp)->pv_next) {
+
+            if (!strcmp(name, pv->pv_name)) {
+
+                if (remove) {
+                    /* Remove PLValueStruct_t from symbol table */
+                    *pvp = pv->pv_next;
+                    pl->pl_symtab->pt_nsyms--;
+
+                    /* Remove it from pl_ppval too */
+                    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+                    pindex = pv->pv_pi;
+                    ppval[pindex - 1] = 0;
+                }
+                break;
+            }
+        }
+    }
+
+    return (pv) ? &pv->pv_pbparam : NULL;
+}
+
+
+/* --------------------------- pblock_removekey --------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+    PLValueStruct_t **ppval;
+    PLValueStruct_t **pvp;
+    PLValueStruct_t *pv = NULL;
+    int pindex;
+    int i;
+
+    if (pl->pl_symtab) {
+        /* Lookup hash index for specified property key */
+        i = _get_hash_index(pl, key);
+
+        /* Search hash collision list for matching key */
+        for (pvp = &pl->pl_symtab->pt_hash[i]; (pv = *pvp); pvp = &pv->pv_next) {
+            /* If this value has the requested key... */
+            if (pv->pv_pbkey == key) {
+                /* Remove PLValueStruct_t from symbol table */
+                *pvp = pv->pv_next;
+                pl->pl_symtab->pt_nsyms--;
+
+                /* Remove it from pl_ppval too */
+                ppval = (PLValueStruct_t **)(pl->pl_ppval);
+                pindex = pv->pv_pi;
+                ppval[pindex - 1] = 0;
+
+                break;
+            }
+        }
+    }
+
+    return (pv) ? &pv->pv_pbparam : NULL;
+}
+
+
+/* -------------------------- pblock_removeone --------------------------- */
+
+NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    if (pl && pl->pl_symtab) {
+        /* Search hash buckets */
+        for (int i = 0; i < PLSIZENDX(pl->pl_symtab->pt_sizendx); i++) {
+            /* Search hash collision list */
+            PLValueStruct_t *pv = pl->pl_symtab->pt_hash[i];
+            if (pv) {
+                /* Remove PLValueStruct_t from symbol table */
+                pl->pl_symtab->pt_hash[i] = pv->pv_next;
+                pl->pl_symtab->pt_nsyms--;
+
+                /* Remove it from pl_ppval too */
+                PLValueStruct_t **ppval = (PLValueStruct_t**)pl->pl_ppval;
+                ppval[pv->pv_pi - 1] = 0;
+
+                return &pv->pv_pbparam;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+
+/* -------------------------- pblock_str2pblock --------------------------- */
+
+
+int _verify_pbstr(const char *str)
+{
+    const char *cp;
+    const char *scp;
+    int np;
+    int state;
+    int quote;
+
+    for(cp = str, np = 0, state = 0; *cp; ) {
+        switch (state) {
+        case 0:                 /* skipping leading spaces */
+
+            while (*cp && isspace(*cp)) ++cp;
+            if (*cp == '=') {
+                return -1;
+            }
+            if (*cp) state = 1;
+            break;
+
+        case 1:                 /* scanning parameter name */
+
+            scp = cp;
+            while (*cp && (*cp != '=') && !isspace(*cp)) ++cp;
+            if (*cp == '=') ++cp;
+            else cp = scp;
+            state = 2;
+            break;
+
+        case 2:                 /* scanning parameter value */
+            quote = 0;
+            if (*cp == '\"') {
+                quote = 1;
+                ++cp;
+            }
+            for (;;) {
+                if (*cp == '\\') {
+                    ++cp;
+                    if (*cp == 0) {
+                        return -1;
+                    }
+                }
+                else if (*cp == '\"') {
+                    if (!quote) {
+                        return -1;
+                    }
+                    ++np;
+                    ++cp;
+                    quote = 0;
+                    state = 0;
+                    break;
+                }
+                else if (!quote && (!*cp || isspace(*cp))) {
+                    ++np;
+                    if (*cp) ++cp;
+                    state = 0;
+                    break;
+                }
+                else if (*cp == 0) {
+                    return -1;
+                }
+                ++cp;
+            }
+            if (quote) {
+                return -1;
+            }
+            break;
+        }
+    }
+
+    return (state == 0) ? np : -1;
+}
+
+NSAPI_PUBLIC int
+INTpblock_str2pblock_lowercasename(const char *str, pblock *pb)
+{
+    return _pblock_str2pblock(str, pb, PR_TRUE);
+}
+
+NSAPI_PUBLIC int pblock_str2pblock(const char *str, pblock *pb)
+{
+    return _pblock_str2pblock(str, pb, PR_FALSE);
+}
+
+int
+_pblock_str2pblock(const char* str, pblock* pb, PRBool lowerCase)
+{
+    char *cpy;
+    char *cp;
+    char *dp;
+    char *pname;
+    char *pvalue;
+    int np;
+    int quote;
+    int state;
+    char numbuf[UTIL_ITOA_SIZE];
+
+    if((np = _verify_pbstr(str)) < 1)
+        return -1;
+
+    while (*str && isspace(*str)) ++str;
+
+    cpy = STRDUP(str);
+
+    for (np = 0, cp = cpy, state = 0; *cp; ) {
+        switch (state) {
+
+        case 0:                 /* skipping leading spaces */
+
+            while (*cp && isspace(*cp)) ++cp;
+            if (*cp) state = 1;
+            break;
+
+        case 1:                 /* scanning parameter name */
+
+            pname = cp;
+            while (*cp && (*cp != '=') && !isspace(*cp)) ++cp;
+            if (*cp == '=') {
+                *cp++ = 0;
+            }
+            else {
+                cp = pname;
+                pname = numbuf;
+                util_itoa(np+1, numbuf);
+            }
+            state = 2;
+            break;
+
+        case 2:                 /* scanning parameter value */
+            quote = 0;
+            if (*cp == '\"') {
+                quote = 1;
+                ++cp;
+            }
+            for (pvalue = cp, dp = cp; ; ++cp, ++dp) {
+                if (*cp == '\\') {
+                    ++cp;
+                }
+                else if (*cp == '\"') {
+                    ++np;
+                    ++cp;
+                    *dp = 0;
+                    quote = 0;
+                    state = 0;
+                    break;
+                }
+                else if (!quote && ((*cp == 0) || isspace(*cp))) {
+                    ++np;
+                    if (*cp != 0) {
+                        ++cp;
+                    }
+                    *dp = 0;
+                    state = 0;
+                    break;
+                }
+                if (cp != dp) *dp = *cp;
+            }
+            if (lowerCase == PR_TRUE) {
+                for (char* p = pname; *p; p++) {
+                    *p = tolower(*p);
+                }
+            }
+            pblock_nvinsert(pname, pvalue, pb);
+            break;
+        }
+    }
+
+    FREE(cpy);
+
+    return np;
+}
+
+
+/* -------------------------- pblock_pblock2str --------------------------- */
+
+
+NSAPI_PUBLIC char *pblock_pblock2str(const pblock *pb, char *str)
+{
+    register char *s = str, *t, *u;
+    PListStruct_t *pl = PBTOPL(pb);
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int i;
+    int sl;
+    int xlen;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Loop over the initialized property indices */
+    for (i = 0, xlen = 0; i < pl->pl_initpi; ++i) {
+
+        /* Got a property here? */
+        pv = ppval[i];
+        if (pv && pv->pv_name) {
+
+            int ln = strlen(pv->pv_name);
+            int lv = strlen((char *)(pv->pv_value));
+
+            /* Check for " or \ because we'll have to escape them */
+            for (t = (char *)(pv->pv_value); *t; ++t) {
+                if ((*t == '\"') || (*t == '\\')) ++lv;
+            }
+
+            /* 4: two quotes, =, and a null */
+            xlen += (ln + lv + 4);
+        }
+    }
+
+    /* Allocate string to hold parameter settings, or increase size */
+    if (!s) {
+        s = (char *)MALLOC(xlen);
+        s[0] = '\0';
+        t = &s[0];
+        sl = xlen;
+    }
+    else {
+        sl = strlen(s);
+        t = &s[sl];
+        sl += xlen;
+        s = (char *)REALLOC(s, sl);
+    }
+
+    /* Loop over the initialized property indices */
+    for (i = 0; i < pl->pl_initpi; ++i) {
+
+        /* Got a property here? */
+        pv = ppval[i];
+        if (pv && pv->pv_name) {
+
+            if (t != s) *t++ = ' ';
+
+            for (u = pv->pv_name; *u; ) *t++ = *u++;
+
+            *t++ = '=';
+            *t++ = '\"';
+
+            for (u = (char *)(pv->pv_value); *u; ) {
+                if ((*u == '\\') || (*u == '\"')) *t++ = '\\';
+                *t++ = *u++;
+            }
+
+            *t++ = '\"';
+            *t = '\0';
+        }
+    }
+
+    return s;
+}
+
+
+/* ----------------------------- pblock_copy ------------------------------ */
+
+
+NSAPI_PUBLIC int pblock_copy(const pblock *src, pblock *dst)
+{
+    PListStruct_t *pl = PBTOPL(src);
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int rv = 0;
+    int i;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    for (i = 0; i < pl->pl_initpi; ++i) {
+        pv = ppval[i];
+        if (pv) {
+            if (pv->pv_pbkey) {
+                if (pv->pv_pbkey != pb_key_magnus_internal) {
+                    if (!pblock_kvinsert(pv->pv_pbkey, (char *)(pv->pv_value), strlen(pv->pv_value), dst))
+                        rv = -1;
+                }
+            } else {
+                if (!pblock_nvinsert(pv->pv_name, (char *)(pv->pv_value), dst))
+                    rv = -1;
+            }
+        }
+    }
+
+    return rv;
+}
+
+/* ---------------------------- pblock_dup -------------------------------- */
+
+NSAPI_PUBLIC pblock *pblock_dup(const pblock *src)
+{
+    pblock *dst;
+
+    if (!src)
+        return NULL;
+
+    if ( (dst = pblock_create(src->hsize)) )
+        pblock_copy(src, dst);
+
+    return dst;
+}
+
+
+/* ---------------------------- pblock_pb2env ----------------------------- */
+
+/*
+NSAPI_PUBLIC char **pblock_pb2env(const pblock *pb, char **env)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int i;
+    int nval;
+    int pos;
+
+    /* Find out how many there are. */
+    /*
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    for (i = 0, nval = 0; i < pl->pl_initpi; ++i) {
+        if (ppval[i]) ++nval;
+    }
+
+    env = util_env_create(env, nval, &pos);
+
+    for (i = 0; i < pl->pl_initpi; ++i) {
+        pv = ppval[i];
+        if (pv) {
+            env[pos++] = util_env_str(pv->pv_name, (char *)(pv->pv_value));
+        }
+    }
+    env[pos] = NULL;
+
+    return env;
+}
+*/
+
+/* ---------------------------- pblock_replace ---------------------------- */
+
+NSAPI_PUBLIC char * pblock_replace(const char *name,
+                                   char * new_value, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    /* Replace an existing value */
+    pb_param *pp = pblock_find(name, pb);
+    if (!pp)
+        return NULL;
+    pool_free(pl->pl_mempool, pp->value);
+    pp->value = new_value;
+
+    return new_value;
+}
+
+
+/* --------------------------- pblock_nvreplace --------------------------- */
+
+NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    /* Replace an existing value or insert a new value */
+    pb_param *pp = pblock_find(name, pb);
+    if (pp) {
+        pool_free(pl->pl_mempool, pp->value);
+        pp->value = pool_strdup(pl->pl_mempool, value);
+    } else {
+        pblock_nvinsert(name, value, pb);
+    }
+}
+
+
+/* --------------------------- pblock_kvreplace --------------------------- */
+
+NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb)
+{
+    PListStruct_t *pl = PBTOPL(pb);
+
+    /* Replace an existing value or insert a new value */
+    pb_param *pp = pblock_findkey(key, pb);
+    if (pp) {
+        pool_free(pl->pl_mempool, pp->value);
+        pp->value = (char*)pool_malloc(pl->pl_mempool, valuelen + 1);
+        memcpy(pp->value, value, valuelen + 1);
+    } else {
+        pblock_kvinsert(key, value, valuelen, pb);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/pblock.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,366 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_PBLOCK_H
+#define BASE_PBLOCK_H
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * pblock.h: Header for Parameter Block handling functions
+ * 
+ *
+ * A parameter block is a set of name=value pairs which are generally used 
+ * as parameters, but can be anything. They are kept in a hash table for 
+ * reasonable speed, but if you are doing any intensive modification or
+ * access of them you should probably make a local copy of each parameter
+ * while working.
+ *
+ * Rob McCool
+ * 
+ */
+
+#ifndef NETSITE_H
+#include "../public/nsapi.h"
+#include "../daemon/netsite.h"
+#endif /* !NETSITE_H */
+
+#ifdef XP_WIN32
+#ifdef BUILD_DLL
+#define BASE_DLL _declspec(dllexport)
+#else
+#define BASE_DLL _declspec(dllimport)
+#endif
+#else
+#define BASE_DLL
+#endif
+
+#ifdef INTNSAPI
+
+/* --- Begin function prototypes --- */
+
+NSPR_BEGIN_EXTERN_C
+
+NSAPI_PUBLIC pb_param *INTparam_create(const char *name, const char *value);
+
+NSAPI_PUBLIC int INTparam_free(pb_param *pp);
+
+NSAPI_PUBLIC pblock *INTpblock_create(int n);
+
+NSAPI_PUBLIC void INTpblock_free(pblock *pb);
+
+NSAPI_PUBLIC char *INTpblock_findval(const char *name, const pblock *pb);
+
+NSAPI_PUBLIC pb_param *INTpblock_nvinsert(const char *name, const char *value, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_nvlinsert(const char *name, int namelen, const char *value, int valuelen, pblock *pb);
+
+NSAPI_PUBLIC pb_param *INTpblock_nninsert(const char *name, int value, pblock *pb);
+
+NSAPI_PUBLIC void INTpblock_pinsert(pb_param *pp, pblock *pb);
+
+NSAPI_PUBLIC int INTpblock_str2pblock(const char *str, pblock *pb);
+
+NSAPI_PUBLIC char *INTpblock_pblock2str(const pblock *pb, char *str);
+
+NSAPI_PUBLIC int INTpblock_copy(const pblock *src, pblock *dst);
+
+NSAPI_PUBLIC pblock *INTpblock_dup(const pblock *src);
+
+NSAPI_PUBLIC char **INTpblock_pb2env(const pblock *pb, char **env);
+
+NSAPI_PUBLIC void pblock_nvreplace (const char *name, const char *value, pblock *pb);
+
+/* --------------------------- Internal things ---------------------------- */
+
+typedef struct pb_key pb_key;
+
+BASE_DLL extern const pb_key *const pb_key_accept;
+BASE_DLL extern const pb_key *const pb_key_accept_charset;
+BASE_DLL extern const pb_key *const pb_key_accept_encoding;
+BASE_DLL extern const pb_key *const pb_key_accept_language;
+BASE_DLL extern const pb_key *const pb_key_accept_ranges;
+BASE_DLL extern const pb_key *const pb_key_actual_route;
+BASE_DLL extern const pb_key *const pb_key_age;
+BASE_DLL extern const pb_key *const pb_key_always_allow_chunked;
+BASE_DLL extern const pb_key *const pb_key_always_use_keep_alive;
+BASE_DLL extern const pb_key *const pb_key_auth_cert;
+BASE_DLL extern const pb_key *const pb_key_auth_expiring;
+BASE_DLL extern const pb_key *const pb_key_auth_group;
+BASE_DLL extern const pb_key *const pb_key_auth_type;
+BASE_DLL extern const pb_key *const pb_key_auth_user;
+BASE_DLL extern const pb_key *const pb_key_authorization;
+BASE_DLL extern const pb_key *const pb_key_browser;
+BASE_DLL extern const pb_key *const pb_key_c2p_cl;
+BASE_DLL extern const pb_key *const pb_key_c2p_hl;
+BASE_DLL extern const pb_key *const pb_key_cache_info;
+BASE_DLL extern const pb_key *const pb_key_charset;
+BASE_DLL extern const pb_key *const pb_key_check_http_server;
+BASE_DLL extern const pb_key *const pb_key_ChunkedRequestBufferSize;
+BASE_DLL extern const pb_key *const pb_key_ChunkedRequestTimeout;
+BASE_DLL extern const pb_key *const pb_key_cipher;
+BASE_DLL extern const pb_key *const pb_key_clf_request;
+BASE_DLL extern const pb_key *const pb_key_cli_status;
+BASE_DLL extern const pb_key *const pb_key_client_cert_nickname;
+BASE_DLL extern const pb_key *const pb_key_client_ip;
+BASE_DLL extern const pb_key *const pb_key_close;
+BASE_DLL extern const pb_key *const pb_key_connect_timeout;
+BASE_DLL extern const pb_key *const pb_key_connection;
+BASE_DLL extern const pb_key *const pb_key_cont;
+BASE_DLL extern const pb_key *const pb_key_content_encoding;
+BASE_DLL extern const pb_key *const pb_key_content_language;
+BASE_DLL extern const pb_key *const pb_key_content_length;
+BASE_DLL extern const pb_key *const pb_key_content_location;
+BASE_DLL extern const pb_key *const pb_key_content_md5;
+BASE_DLL extern const pb_key *const pb_key_content_range;
+BASE_DLL extern const pb_key *const pb_key_content_type;
+BASE_DLL extern const pb_key *const pb_key_cookie;
+BASE_DLL extern const pb_key *const pb_key_date;
+BASE_DLL extern const pb_key *const pb_key_DATE_GMT;
+BASE_DLL extern const pb_key *const pb_key_DATE_LOCAL;
+BASE_DLL extern const pb_key *const pb_key_dir;
+BASE_DLL extern const pb_key *const pb_key_Directive;
+BASE_DLL extern const pb_key *const pb_key_dns;
+BASE_DLL extern const pb_key *const pb_key_DOCUMENT_NAME;
+BASE_DLL extern const pb_key *const pb_key_DOCUMENT_URI;
+BASE_DLL extern const pb_key *const pb_key_domain;
+BASE_DLL extern const pb_key *const pb_key_enc;
+BASE_DLL extern const pb_key *const pb_key_engine;
+BASE_DLL extern const pb_key *const pb_key_error_action;
+BASE_DLL extern const pb_key *const pb_key_error_desc;
+BASE_DLL extern const pb_key *const pb_key_error_fn;
+BASE_DLL extern const pb_key *const pb_key_escape;
+BASE_DLL extern const pb_key *const pb_key_escaped;
+BASE_DLL extern const pb_key *const pb_key_etag;
+BASE_DLL extern const pb_key *const pb_key_expect;
+BASE_DLL extern const pb_key *const pb_key_expires;
+BASE_DLL extern const pb_key *const pb_key_expr;
+BASE_DLL extern const pb_key *const pb_key_filter;
+BASE_DLL extern const pb_key *const pb_key_find_pathinfo_forward;
+BASE_DLL extern const pb_key *const pb_key_flushTimer;
+BASE_DLL extern const pb_key *const pb_key_fn;
+BASE_DLL extern const pb_key *const pb_key_from;
+BASE_DLL extern const pb_key *const pb_key_full_headers;
+BASE_DLL extern const pb_key *const pb_key_hdr;
+BASE_DLL extern const pb_key *const pb_key_host;
+BASE_DLL extern const pb_key *const pb_key_hostname;
+BASE_DLL extern const pb_key *const pb_key_if_match;
+BASE_DLL extern const pb_key *const pb_key_if_modified_since;
+BASE_DLL extern const pb_key *const pb_key_if_none_match;
+BASE_DLL extern const pb_key *const pb_key_if_range;
+BASE_DLL extern const pb_key *const pb_key_if_unmodified_since;
+BASE_DLL extern const pb_key *const pb_key_ip;
+BASE_DLL extern const pb_key *const pb_key_iponly;
+BASE_DLL extern const pb_key *const pb_key_issuer_dn;
+BASE_DLL extern const pb_key *const pb_key_jroute;
+BASE_DLL extern const pb_key *const pb_key_keep_alive;
+BASE_DLL extern const pb_key *const pb_key_keep_alive_timeout;
+BASE_DLL extern const pb_key *const pb_key_keysize;
+BASE_DLL extern const pb_key *const pb_key_lang;
+BASE_DLL extern const pb_key *const pb_key_LAST_MODIFIED;
+BASE_DLL extern const pb_key *const pb_key_last_modified;
+BASE_DLL extern const pb_key *const pb_key_level;
+BASE_DLL extern const pb_key *const pb_key_location;
+BASE_DLL extern const pb_key *const pb_key_lock_owner;
+BASE_DLL extern const pb_key *const pb_key_magnus_charset;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_dav_src;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_default_acls_only;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_error_j2ee;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_j2ee_nsapi;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_preserve_srvhdrs;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_set_request_status;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_set_response_status;
+BASE_DLL extern const pb_key *const pb_key_magnus_internal_webapp_errordesc;
+BASE_DLL extern const pb_key *const pb_key_matched_browser;
+BASE_DLL extern const pb_key *const pb_key_max_age;
+BASE_DLL extern const pb_key *const pb_key_max_forwards;
+BASE_DLL extern const pb_key *const pb_key_message;
+BASE_DLL extern const pb_key *const pb_key_method;
+BASE_DLL extern const pb_key *const pb_key_name;
+BASE_DLL extern const pb_key *const pb_key_nocache;
+BASE_DLL extern const pb_key *const pb_key_nostat;
+BASE_DLL extern const pb_key *const pb_key_ntrans_base;
+BASE_DLL extern const pb_key *const pb_key_offline_origin_addr;
+BASE_DLL extern const pb_key *const pb_key_offline_proxy_addr;
+BASE_DLL extern const pb_key *const pb_key_origin_addr;
+BASE_DLL extern const pb_key *const pb_key_p2c_cl;
+BASE_DLL extern const pb_key *const pb_key_p2c_hl;
+BASE_DLL extern const pb_key *const pb_key_p2r_cl;
+BASE_DLL extern const pb_key *const pb_key_p2r_hl;
+BASE_DLL extern const pb_key *const pb_key_parse_timeout;
+BASE_DLL extern const pb_key *const pb_key_password;
+BASE_DLL extern const pb_key *const pb_key_path;
+BASE_DLL extern const pb_key *const pb_key_PATH_INFO;
+BASE_DLL extern const pb_key *const pb_key_path_info;
+BASE_DLL extern const pb_key *const pb_key_pblock;
+BASE_DLL extern const pb_key *const pb_key_poll_interval;
+BASE_DLL extern const pb_key *const pb_key_port;
+BASE_DLL extern const pb_key *const pb_key_ppath;
+BASE_DLL extern const pb_key *const pb_key_pragma;
+BASE_DLL extern const pb_key *const pb_key_process_request_body;
+BASE_DLL extern const pb_key *const pb_key_process_response_body;
+BASE_DLL extern const pb_key *const pb_key_protocol;
+BASE_DLL extern const pb_key *const pb_key_proxy_addr;
+BASE_DLL extern const pb_key *const pb_key_proxy_agent;
+BASE_DLL extern const pb_key *const pb_key_proxy_auth_cert;
+BASE_DLL extern const pb_key *const pb_key_proxy_authorization;
+BASE_DLL extern const pb_key *const pb_key_proxy_cipher;
+BASE_DLL extern const pb_key *const pb_key_proxy_issuer_dn;
+BASE_DLL extern const pb_key *const pb_key_proxy_jroute;
+BASE_DLL extern const pb_key *const pb_key_proxy_keysize;
+BASE_DLL extern const pb_key *const pb_key_proxy_ping;
+BASE_DLL extern const pb_key *const pb_key_proxy_request;
+BASE_DLL extern const pb_key *const pb_key_proxy_secret_keysize;
+BASE_DLL extern const pb_key *const pb_key_proxy_ssl_id;
+BASE_DLL extern const pb_key *const pb_key_proxy_user_dn;
+BASE_DLL extern const pb_key *const pb_key_query;
+BASE_DLL extern const pb_key *const pb_key_QUERY_STRING;
+BASE_DLL extern const pb_key *const pb_key_QUERY_STRING_UNESCAPED;
+BASE_DLL extern const pb_key *const pb_key_r2p_cl;
+BASE_DLL extern const pb_key *const pb_key_r2p_hl;
+BASE_DLL extern const pb_key *const pb_key_range;
+BASE_DLL extern const pb_key *const pb_key_referer;
+BASE_DLL extern const pb_key *const pb_key_reformat_request_headers;
+BASE_DLL extern const pb_key *const pb_key_remote_status;
+BASE_DLL extern const pb_key *const pb_key_request_jroute;
+BASE_DLL extern const pb_key *const pb_key_required_rights;
+BASE_DLL extern const pb_key *const pb_key_retries;
+BASE_DLL extern const pb_key *const pb_key_rewrite_content_location;
+BASE_DLL extern const pb_key *const pb_key_rewrite_host;
+BASE_DLL extern const pb_key *const pb_key_rewrite_location;
+BASE_DLL extern const pb_key *const pb_key_rewrite_set_cookie;
+BASE_DLL extern const pb_key *const pb_key_root;
+BASE_DLL extern const pb_key *const pb_key_route;
+BASE_DLL extern const pb_key *const pb_key_route_cookie;
+BASE_DLL extern const pb_key *const pb_key_route_hdr;
+BASE_DLL extern const pb_key *const pb_key_route_offline;
+BASE_DLL extern const pb_key *const pb_key_script_name;
+BASE_DLL extern const pb_key *const pb_key_secret_keysize;
+BASE_DLL extern const pb_key *const pb_key_secure;
+BASE_DLL extern const pb_key *const pb_key_server;
+BASE_DLL extern const pb_key *const pb_key_set_cookie;
+BASE_DLL extern const pb_key *const pb_key_socks_addr;
+BASE_DLL extern const pb_key *const pb_key_ssl_id;
+BASE_DLL extern const pb_key *const pb_key_ssl_unclean_shutdown;
+BASE_DLL extern const pb_key *const pb_key_status;
+BASE_DLL extern const pb_key *const pb_key_sticky_cookie;
+BASE_DLL extern const pb_key *const pb_key_sticky_param;
+BASE_DLL extern const pb_key *const pb_key_suppress_request_headers;
+BASE_DLL extern const pb_key *const pb_key_svr_status;
+BASE_DLL extern const pb_key *const pb_key_timeout;
+BASE_DLL extern const pb_key *const pb_key_to;
+BASE_DLL extern const pb_key *const pb_key_transfer_encoding;
+BASE_DLL extern const pb_key *const pb_key_transmit_timeout;
+BASE_DLL extern const pb_key *const pb_key_tunnel_non_http_response;
+BASE_DLL extern const pb_key *const pb_key_type;
+BASE_DLL extern const pb_key *const pb_key_upstream_jroute;
+BASE_DLL extern const pb_key *const pb_key_uri;
+BASE_DLL extern const pb_key *const pb_key_url;
+BASE_DLL extern const pb_key *const pb_key_url_prefix;
+BASE_DLL extern const pb_key *const pb_key_UseOutputStreamSize;
+BASE_DLL extern const pb_key *const pb_key_user;
+BASE_DLL extern const pb_key *const pb_key_user_agent;
+BASE_DLL extern const pb_key *const pb_key_user_dn;
+BASE_DLL extern const pb_key *const pb_key_validate_server_cert;
+BASE_DLL extern const pb_key *const pb_key_value;
+BASE_DLL extern const pb_key *const pb_key_vary;
+BASE_DLL extern const pb_key *const pb_key_via;
+BASE_DLL extern const pb_key *const pb_key_warning;
+
+NSAPI_PUBLIC pool_handle_t *pblock_pool(pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_param_create(pblock *pb, const char *name, const char *value);
+
+NSAPI_PUBLIC pblock *pblock_create_pool(pool_handle_t *pool_handle, int n);
+
+NSAPI_PUBLIC pb_param *INTpblock_fr(const char *name, pblock *pb, int remove);
+
+NSAPI_PUBLIC char *INTpblock_replace(const char *name,char * new_value,pblock *pb);
+
+NSAPI_PUBLIC int INTpblock_str2pblock_lowercasename(const char *str, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_removeone(pblock *pb);
+
+NSAPI_PUBLIC const pb_key *pblock_key(const char *name);
+
+NSAPI_PUBLIC pb_param *pblock_key_param_create(pblock *pb, const pb_key *key, const char *value, int valuelen);
+
+NSAPI_PUBLIC char *pblock_findkeyval(const pb_key *key, const pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_findkey(const pb_key *key, const pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_removekey(const pb_key *key, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_kvinsert(const pb_key *key, const char *value, int valuelen, pblock *pb);
+
+NSAPI_PUBLIC void pblock_kpinsert(const pb_key *key, pb_param *pp, pblock *pb);
+
+NSAPI_PUBLIC void pblock_kvreplace(const pb_key *key, const char *value, int valuelen, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_kninsert(const pb_key *key, int value, pblock *pb);
+
+NSAPI_PUBLIC pb_param *pblock_kllinsert(const pb_key *key, PRInt64 value, pblock *pb);
+
+#ifdef __cplusplus
+inline const pb_key *param_key(pb_param *pp)
+{
+    return *(const pb_key **)(pp + 1); /* XXX see plist_pvt.h */
+}
+#endif
+
+#define PARAM_KEY(pp) *(const pb_key **)(pp + 1) /* new */
+
+NSPR_END_EXTERN_C
+
+#define param_create INTparam_create
+#define param_free INTparam_free
+#define pblock_create INTpblock_create
+#define pblock_free INTpblock_free
+#define pblock_findval INTpblock_findval
+#define pblock_nvinsert INTpblock_nvinsert
+#define pblock_nninsert INTpblock_nninsert
+#define pblock_pinsert INTpblock_pinsert
+#define pblock_str2pblock INTpblock_str2pblock
+#define pblock_pblock2str INTpblock_pblock2str
+#define pblock_copy INTpblock_copy
+#define pblock_dup INTpblock_dup
+#define pblock_pb2env INTpblock_pb2env
+#define pblock_fr INTpblock_fr
+#define pblock_replace INTpblock_replace
+
+#endif /* INTNSAPI */
+
+#endif /* !BASE_PBLOCK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/plist.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,1273 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * MODULE:      plist.c
+ *
+ * DESCRIPTION:
+ *
+ *      This module implements property lists.  A property list is an
+ *      ordered array of property values.  Each property value has an
+ *      handle for some data item, and may have a reference to
+ *      another property list which describes the type of the data
+ *      item.  Each property value has a property index which specifies
+ *      its position in the property list.  A property value may also
+ *      have a name.  Since the data item associated with a property
+ *      value may reference another property list, it is possible to
+ *      construct arbitrary linked structures of property lists.
+ *
+ * IMPLEMENTATION NOTES:
+ */
+
+#include "../daemon/netsite.h"
+#include "plist.h"
+#include "plist_pvt.h"
+
+int plistHashSizes[] = PLSTSIZES;
+
+/*
+ * FUNCTION:    PListAssignValue
+ *
+ * DESCRIPTION:
+ *
+ *      This function sets the value and/or type of a defined property
+ *      in given property list.  If the property type is specified as
+ *      NULL, it is unchanged.  However, the property value is always
+ *      set to the specified value.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pname                   - the property name
+ *      pvalue                  - the new property value
+ *      ptype                   - the new property type, or NULL
+ *
+ * RETURNS:
+ *
+ *      If successful, the property index of the referenced property is
+ *      returned as the function value.  Errors are indicated by a
+ *      negative return code as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListAssignValue(PList_t plist, const char *pname,
+                 const void *pvalue, PList_t ptype)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t *pv;
+    int pindex;
+    int i;
+
+    if (!plist) return ERRPLUNDEF;
+
+    /* Got a symbol table for this property list? */
+    if (pl->pl_symtab) {
+
+        /* Yes, compute hash of specified name */
+        i = PListHashName(pl->pl_symtab, pname);
+
+        /* Search hash collision list for matching name */
+        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
+
+            if (!strcmp(pname, pv->pv_name)) {
+
+                /* Name match, get property index */
+                pindex = pv->pv_pi;
+
+                /* Set the new value */
+                pv->pv_value = (char *)pvalue;
+
+                /* Set type if type is given */
+                if (ptype) pv->pv_type = (PListStruct_t *)ptype;
+
+                /* Return the property index */
+                return pindex;
+            }
+        }
+    }
+
+    /* Error - specified property name is undefined */
+    return ERRPLUNDEF;
+}
+
+/*
+ * FUNCTION:    PListCreate
+ *
+ * DESCRIPTION:
+ *
+ *      This function creates a new property list and returns a handle for
+ *      it.  It allows the caller to reserve a specified number of
+ *      property indices at the beginning of the list, and also to limit
+ *      the total number of property values that may be added to the list.
+ *
+ * ARGUMENTS:
+ *
+ *      mempool                 - handle for a memory pool to be associated
+ *                                with the new property list
+ *      resvprop                - number of reserved property indices
+ *      maxprop                 - maximum number of properties in list
+ *                                (zero or negative imposes no limit)
+ *      flags                   - unused, reserved, must be zero
+ *
+ * RETURNS:
+ *
+ *      If successful, the function return value is a handle for the new
+ *      property list.  Otherwise NULL is returned.
+ */
+
+NSAPI_PUBLIC PList_t
+PListCreate(pool_handle_t *mempool, int resvprop, int maxprop, int flags)
+{
+    PListStruct_t *plist;       /* pointer to property list structure */
+    int i;
+
+    plist = (PListStruct_t *)pool_malloc(mempool, sizeof(PListStruct_t));
+    if (plist) {
+
+        /* Negative maxprop is the same as zero, i.e. no limit */
+        if (maxprop < 0) maxprop = 0;
+
+        /* If resvprop and maxprop are both specified, limit resvprop */
+        if (resvprop > 0) {
+            if (maxprop && (resvprop > maxprop)) resvprop = maxprop;
+        }
+        else resvprop = 0;
+
+        /* Initialize property list structure */
+        plist->pl_mempool = mempool;
+        plist->pl_symtab = NULL;
+        plist->pl_maxprop = maxprop;
+        plist->pl_resvpi = resvprop;
+        plist->pl_initpi = resvprop;
+        plist->pl_lastpi = resvprop;
+
+        /* Set initialize size for array of property value pointers */
+        plist->pl_cursize = (resvprop) ? resvprop : PLIST_DEFSIZE;
+
+        /* Allocate the initial array of property value pointers */
+        plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
+                                   	           (plist->pl_cursize *
+                                                    sizeof(PLValueStruct_t *)));
+        if (!plist->pl_ppval) {
+
+            /* Failed - insufficient memory */
+            pool_free(mempool, (void *)plist);
+            plist = NULL;
+        }
+        else {
+            /* NULL out pointers in the reserved index range, if any */
+            for (i = 0; i < plist->pl_lastpi; ++i) {
+                plist->pl_ppval[i] = 0;
+            }
+        }
+    }
+
+    return (PList_t)plist;
+}
+
+/*
+ * FUNCTION:    PListDefProp
+ *
+ * DESCRIPTION:
+ *
+ *      This function creates a new property in a specified property list.
+ *      The 'pindex' argument may be used to request a particular property
+ *      index for the new property.  If 'pindex' is greater than zero,
+ *      the specified value is used as the new property's index, provided
+ *      there is no property at that index already.  If 'pindex' is zero,
+ *      then the next available property index is assigned to the new
+ *      property.  A name may optionally be specified for the new property.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - new property index (or zero)
+ *      pname                   - new property name (or NULL)
+ *
+ * RETURNS:
+ *
+ *      If successful, the index of the new property is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListDefProp(PList_t plist, int pindex, const char *pname, const int flags)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t *pv;
+
+    if (!plist) return ERRPLUNDEF;
+
+    /* Is pindex specified? */
+    if (pindex > 0) {
+
+        /* Yes, is it in the reserved range? */
+        if (flags != PLFLG_IGN_RES && pindex > pl->pl_resvpi) {
+            /* No, error */
+            return ERRPLINVPI;
+        }
+
+        PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
+        if (ppval[pindex - 1]) {
+            /* Error - property already exists at specified index */
+            return ERRPLEXIST;
+        }
+    }
+    else {
+
+        /* Look for a free property index */
+        pindex = PListGetFreeIndex(pl);
+        if (pindex < 1) {
+            /* Error - no free property index */
+            return pindex;
+        }
+    }
+
+    /* We have a property index.  Create a new property value */
+    pv = (PLValueStruct_t *)pool_calloc(pl->pl_mempool,
+                                        1, sizeof(PLValueStruct_t));
+    if (!pv) {
+
+        /* Error - insufficient memory */
+        return ERRPLNOMEM;
+    }
+
+    PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
+    pv->pv_pbentry.param = &pv->pv_pbparam;
+    pv->pv_pi = pindex;
+    pv->pv_mempool = pl->pl_mempool;
+    ppval[pindex - 1] = pv;
+
+    /* Name the property if the name was specified */
+    if (pname) {
+
+        /* XXX Maybe should delete property if naming fails */
+        return PListNameProp(plist, pindex, pname);
+    }
+
+    /* Return the property index of the new property */
+    return pindex;
+}
+
+/*
+ * FUNCTION:    PListDeleteProp
+ *
+ * DESCRIPTION:
+ *
+ *      This function deletes a property from a specified property list.
+ *      The property can be specified by its property index, using a
+ *      pindex value greater than zero, or by its name, by specifying
+ *      pindex as zero and pname as the property name.  This does not
+ *      have any effect on the data referenced by the property value,
+ *      if any, nor does it have any effect on the property list that
+ *      describes the property value's type, if any.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - the property index, or zero
+ *      pname                   - the property name, or NULL
+ */
+
+NSAPI_PUBLIC const void *
+PListDeleteProp(PList_t plist, int pindex, const char *pname_in)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t **pvp;
+    PLValueStruct_t *pv = NULL;
+    int i;
+    const void *pvalue = NULL;
+    char *pname = (char *)pname_in;
+
+    if (!plist) return NULL;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Check for valid property index */
+    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
+
+        /* Get the pointer to the property structure */
+        pv = ppval[pindex - 1];
+	pname = 0;
+	if (pv) {
+	    pname = pv->pv_name;
+	}
+    }
+
+    if (pname && pl->pl_symtab) {
+
+        /* Compute hash of specified property name */
+        i = PListHashName(pl->pl_symtab, pname);
+
+        /* Search hash collision list for matching name */
+        for (pvp = &pl->pl_symtab->pt_hash[i]; *pvp; pvp = &(*pvp)->pv_next) {
+
+            pv = *pvp;
+            if (!strcmp(pname, pv->pv_name)) {
+
+                /* Found it.  Get its index and remove it. */
+                pindex = pv->pv_pi;
+                *pvp = pv->pv_next;
+                pl->pl_symtab->pt_nsyms--;
+                break;
+            }
+            pv = NULL;
+        }
+    }
+
+    /* Found the indicated property by index or name? */
+    if (pv) {
+
+        /* Yes, remove it from the property list */
+        ppval[pindex - 1] = NULL;
+
+        /* Free the property name, if any */
+        if (pv->pv_name) {
+            pool_free(pv->pv_mempool, (void *)(pv->pv_name));
+        }
+        pvalue = pv->pv_value;
+
+        /* Free the property */
+        pool_free(pv->pv_mempool, (void *)pv);
+    }
+    return(pvalue);
+}
+
+/*
+ * FUNCTION:    PListFindValue
+ *
+ * DESCRIPTION:
+ *
+ *      This function retrieves the value and type of a property with a
+ *      specified property name.  If the pvalue argument is non-NULL,
+ *      it specifies a location in which to return the property value.
+ *      Similarly, if ptype is non-NULL, it specifies where the property
+ *      list describing the property type is to be returned.  If a
+ *      property has no value, the value returned for pvalue is NULL.
+ *      If a property has no type, the value returned for ptype is NULL.
+ *      A property can have a value, a type, both, or neither.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pname                   - pointer to property name string
+ *      pvalue                  - property value return pointer
+ *      ptype                   - property type return pointer
+ *
+ * RETURNS:
+ *
+ *      If successful, the index of the referenced property is returned
+ *      as the function value.  Errors are indicated by a negative
+ *      return code as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListFindValue(PList_t plist, const char *pname, void **pvalue, PList_t *ptype)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t *pv;
+    int pindex;
+    int i;
+
+    if (!plist) return ERRPLUNDEF;
+
+    /* Got a symbol table for this property list? */
+    if (pl->pl_symtab) {
+
+        /* Yes, compute hash of specified name */
+        i = PListHashName(pl->pl_symtab, pname);
+
+        /* Search hash collision list for matching name */
+        for (pv = pl->pl_symtab->pt_hash[i]; pv; pv = pv->pv_next) {
+
+            if (!strcmp(pname, pv->pv_name)) {
+
+                /* Name match, get property index */
+                pindex = pv->pv_pi;
+
+                /* Return the value if requested */
+                if (pvalue) *pvalue = (void *)(pv->pv_value);
+
+                /* Return the type if requested */
+                if (ptype) *ptype = (PList_t)(pv->pv_type);
+
+                /* Return the property index */
+                return pindex;
+            }
+        }
+    }
+
+    /* Error - specified property name is undefined */
+    return ERRPLUNDEF;
+}
+
+/*
+ * FUNCTION:    PListInitProp
+ *
+ * DESCRIPTION:
+ *
+ *      This function combines the functions of PListDefProp() and
+ *      PListSetValue(), defining a new property and assigning it an
+ *      initial value and optionally a type and/or a name.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - a reserved property index, or zero
+ *      pname                   - the new property name, or NULL
+ *      pvalue                  - the new property value
+ *      ptype                   - the new property type, or NULL
+ *
+ * RETURNS:
+ *
+ *      If successful, the property index (pindex) is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListInitProp(PList_t plist, int pindex, const char *pname,
+              const void *pvalue, PList_t ptype)
+{
+    int rv;
+
+    if (!plist) return ERRPLUNDEF;
+
+    /* Create the property */
+    rv = PListDefProp(plist, pindex, pname, PLFLG_USE_RES);
+    if (rv > 0) {
+
+        /* If that worked, set the value and type */
+        rv = PListSetValue(plist, rv, pvalue, ptype);
+    }
+
+    return rv;
+}
+
+/*
+ * FUNCTION:    PListNew
+ *
+ * DESCRIPTION:
+ *
+ *      This function creates a new property list, using the specified
+ *      memory pool for allocating the internal data structures used to
+ *      represent it.  If the mempool argument is NULL, the default
+ *      memory pool is used.
+ *
+ * ARGUMENTS:
+ *
+ *      mempool                 - handle for a memory pool to be associated
+ *                                with the new property list
+ *
+ * RETURNS:
+ *
+ *      If successful, the function return value is a handle for the new
+ *      property list.  Otherwise NULL is returned.
+ */
+
+NSAPI_PUBLIC PList_t
+PListNew(pool_handle_t *mempool)
+{
+    /* Just call PListCreate with default parameters */
+    return PListCreate(mempool, 0, 0, 0);
+}
+
+/*
+ * FUNCTION:    PListDestroy
+ *
+ * DESCRIPTION:
+ *
+ *      This function destroys a specified property list.  This means
+ *      that any dynamic memory which was allocated as a result of calls
+ *      to the property list API is freed to the memory pool from which
+ *      it was allocated.  Property value data is not freed, nor are
+ *      any property lists associated with property types.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ */
+
+void
+PListDestroy(PList_t plist)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int i;
+
+    if (!plist) return;
+
+    /* Free the property name symbol table if any */
+    if (pl->pl_symtab) {
+        pool_free(pl->pl_mempool, (void *)(pl->pl_symtab));
+    }
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Loop over the initialized property indices */
+    for (i = 0; i < pl->pl_initpi; ++i) {
+
+        /* Got a property here? */
+        pv = ppval[i];
+        if (pv) {
+
+            /* Free the property name string if any */
+            if (pv->pv_name) {
+                pool_free(pv->pv_mempool, (void *)(pv->pv_name));
+            }
+
+            /* Free the property value structure */
+            pool_free(pv->pv_mempool, (void *)pv);
+        }
+    }
+
+    /* Free the array of pointers to property values */
+    pool_free(pl->pl_mempool, (void *)ppval);
+
+    /* Free the property list head */
+    pool_free(pl->pl_mempool, (void *)pl);
+}
+
+/*
+ * FUNCTION:    PListGetValue
+ *
+ * DESCRIPTION:
+ *
+ *      This function retrieves the value and type of the property with
+ *      the property index given by pindex in the specified property
+ *      list.  The pindex argument must specify the index of a defined
+ *      property.  If the pvalue argument is non-NULL, it specifies a
+ *      location in which to return the property value.  Similarly, if
+ *      ptype is non-NULL, it specifies where the property list
+ *      describing the property type is to be returned.  If a property
+ *      has no value, the value returned for pvalue is NULL.  If a
+ *      property has no type, the value returned for ptype is NULL. A
+ *      property can have a value, a type, both, or neither.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - the property index
+ *      pvalue                  - property value return pointer
+ *      ptype                   - property type return pointer
+ *
+ * RETURNS:
+ *
+ *      If successful, the property index (pindex) is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListGetValue(PList_t plist, int pindex, void **pvalue, PList_t *ptype)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+
+    if (!plist) return ERRPLUNDEF;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Check for valid property index */
+    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
+
+        /* Does the property exist? */
+        pv = ppval[pindex - 1];
+        if (pv) {
+
+            /* Yes, return the value if requested */
+            if (pvalue) *pvalue = (void *)(pv->pv_value);
+
+            /* Return the type if requested */
+            if (ptype) *ptype = (PList_t)(pv->pv_type);
+
+            /* Successful return */
+            return pindex;
+        }
+    }
+
+    /* Error - invalid property index or non-existent property */
+    return ERRPLINVPI;
+}
+
+/*
+ * FUNCTION:    PListHash
+ *
+ * DESCRIPTION:
+ *
+ *      This function hashes a given string.
+ *
+ * ARGUMENTS:
+ *
+ *      string                  - pointer to the string to hash
+ *
+ * RETURNS:
+ *
+ *      The hash value is returned as the function value.
+ */
+
+unsigned int
+PListHash(const char *string)
+{
+    unsigned int hashval = 0;           /* hash value */
+
+    while (*string) {
+        hashval = (hashval<<5) ^ (*string++ & 0x7f);
+    }
+
+    return hashval;
+}
+
+/*
+ * FUNCTION:    PListHashName
+ *
+ * DESCRIPTION:
+ *
+ *      This function hashes a given property name for a specified
+ *      symbol table.  It produces a value that can be used as an
+ *      index in the pt_hash array associated with the symbol table.
+ *
+ * ARGUMENTS:
+ *
+ *      symtab                  - pointer to the symbol table
+ *      pname                   - pointer to the property name string
+ *
+ * RETURNS:
+ *
+ *      The hash index is returned as the function value.
+ */
+
+int
+PListHashName(PLSymbolTable_t *symtab, const char *pname)
+{
+    return PListHash(pname) % PLSIZENDX(symtab->pt_sizendx);
+}
+
+/*
+ * FUNCTION:    PListNameProp
+ *
+ * DESCRIPTION:
+ *
+ *      This function assigns a name to a defined property with the
+ *      property index, pindex.  If the property has an existing name,
+ *      it will be replaced with the name specified by pname.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - the property index
+ *      pname                   - the new property name
+ *
+ * RETURNS:
+ *
+ *      If successful, the property index (pindex) is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListNameProp(PList_t plist, int pindex, const char *pname)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t *pv;
+    PLSymbolTable_t *pt;
+    int i;
+
+    if (!plist) return ERRPLUNDEF;
+
+    pt = pl->pl_symtab;
+
+    /* Check for valid property index */
+    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
+
+        /* Does the property exist? */
+        pv = ((PLValueStruct_t **)(pl->pl_ppval))[pindex - 1];
+        if (pv) {
+
+            /* If it has a name already, unname it */
+            if (pv->pv_name) {
+                PLValueStruct_t **pvp;
+
+                /* Get hash bucket index */
+                i = PListHashName(pt, pv->pv_name);
+
+                /* Seach hash collision list for this property */
+                for (pvp = &pt->pt_hash[i];
+                     *pvp; pvp = &(*pvp)->pv_next) {
+
+                    if (*pvp == pv) {
+
+                        /* Remove it from the list */
+                        *pvp = pv->pv_next;
+                        pt->pt_nsyms--;
+                        break;
+                    }
+                }
+
+                /* Free the current name string */
+                pool_free(pv->pv_mempool, (void *)(pv->pv_name));
+            }
+
+            /* Got a new name? */
+            if (pname) {
+
+                /* Allocate/grow the symbol table as needed */
+                pt = PListSymbolTable(pl);
+                if (!pt) {
+                    return ERRPLNOMEM;
+                }
+
+                /* Duplicate the name string */
+                pv->pv_name = pool_strdup(pv->pv_mempool, (char *)pname);
+
+                /* Add name to symbol table */
+                i = PListHashName(pt, pname);
+                pv->pv_next = pt->pt_hash[i];
+                pt->pt_hash[i] = pv;
+                pt->pt_nsyms++;
+            }
+
+            /* Successful return */
+            return pindex;
+        }
+    }
+
+    /* Error - invalid property index or non-existent property */
+    return ERRPLINVPI;
+}
+
+/*
+ * FUNCTION:    PListSetType
+ *
+ * DESCRIPTION:
+ *
+ *      This function sets the property type of the defined property
+ *      with the property index, pindex.  The property list describing
+ *      the property type is specified by ptype.  If ptype is NULL,
+ *      the property type will be set to be undefined (NULL).
+ *
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - the property index
+ *      ptype                   - the new property type, or NULL
+ *
+ * RETURNS:
+ *
+ *      If successful, the property index (pindex) is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListSetType(PList_t plist, int pindex, PList_t ptype)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+
+    if (!plist) return ERRPLUNDEF;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Check for valid property index */
+    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
+
+        /* Does the property exist? */
+        pv = ppval[pindex - 1];
+        if (pv) {
+
+            /* Yes, set the new type */
+            pv->pv_type = ptype;
+
+            /* Successful return */
+            return pindex;
+        }
+    }
+
+    /* Error - invalid property index or non-existent property */
+    return ERRPLINVPI;
+}
+
+/*
+ * FUNCTION:    PListSetValue
+ *
+ * DESCRIPTION:
+ *
+ *      This function sets the value and optionally the type of a
+ *      defined property in a given property list.  The pindex argument
+ *      specifies the property index, which must be greater than zero.
+ *      The ptype argument specifies a property list that describes the
+ *      property type.  If ptype is NULL, the property type, if any, is
+ *      unchanged by this function.  However, the property value is
+ *      always set to the value given by pvalue.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      pindex                  - the property index
+ *      pvalue                  - the new property value
+ *      ptype                   - the new property type, or NULL
+ *
+ * RETURNS:
+ *
+ *      If successful, the property index (pindex) is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+NSAPI_PUBLIC int
+PListSetValue(PList_t plist, int pindex, const void *pvalue, PList_t ptype)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+
+    if (!plist) return ERRPLUNDEF;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Check for valid property index */
+    if ((pindex > 0) && (pindex <= pl->pl_initpi)) {
+
+        /* Does the property exist? */
+        pv = ppval[pindex - 1];
+        if (pv) {
+
+            /* Yes, set the new value */
+            pv->pv_value = (char *)pvalue;
+
+            /* Set type if type is given */
+            if (ptype) pv->pv_type = (PListStruct_t *)ptype;
+
+            /* Successful return */
+            return pindex;
+        }
+    }
+
+    /* Error - invalid property index or non-existent property */
+    return ERRPLINVPI;
+}
+
+/*
+ * FUNCTION:    PListEnumerate
+ *
+ * DESCRIPTION:
+ *
+ *      This function walks through a specified property list
+ *	calling a user supplied function with the property
+ *	name and value as parameters.  
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      user_func               - handle for the user function 
+ */
+
+NSAPI_PUBLIC void
+PListEnumerate(PList_t plist, PListFunc_t *user_func, void *user_data)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int i;
+
+    if (!plist) return;
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Loop over the initialized property indices */
+    for (i = 0; i < pl->pl_initpi; ++i) {
+
+        /* Got a property here? */
+        pv = ppval[i];
+        if (pv) {
+            (*user_func)(pv->pv_name, pv->pv_value, user_data);
+        }
+
+    }
+
+}
+
+/*
+ * FUNCTION:    PListCreateDuplicate
+ *
+ * DESCRIPTION:
+ *
+ *      This function creates a new property list and returns a handle for
+ *      it.  The source plist provides the new plists parameters.
+ *
+ * ARGUMENTS:
+ *
+ *	src_plist		- source plist to duplicate
+ *      mempool                 - handle for a memory pool to be associated
+ *                                with the new property list, only
+ *				  used if flags is set to PLFLG_NEW_MPOOL
+ *      flags                   - if PLFLG_NEW_MPOOL uses new_mempool
+ *				  parameter
+ *
+ * RETURNS:
+ *
+ *      If successful, the function return value is a handle for the new
+ *      property list.  Otherwise NULL is returned.
+ */
+
+static PList_t
+PListCreateDuplicate(PList_t src_plist, pool_handle_t *new_mempool, int flags)
+{
+    PListStruct_t *plist;       /* pointer to property list structure */
+    int i;
+    pool_handle_t *mempool;
+
+    mempool = (flags == PLFLG_NEW_MPOOL) ? new_mempool : src_plist->pl_mempool;
+
+    plist = (PListStruct_t *)pool_malloc(mempool, sizeof(PListStruct_t));
+    if (plist) {
+
+        /* Initialize property list structure */
+        plist->pl_mempool = mempool;
+        plist->pl_symtab = NULL;
+        plist->pl_maxprop = src_plist->pl_maxprop;
+        plist->pl_resvpi = src_plist->pl_resvpi;
+        plist->pl_initpi = src_plist->pl_initpi;
+        plist->pl_lastpi = src_plist->pl_lastpi;
+
+        /* Set initialize size for array of property value pointers */
+        plist->pl_cursize = src_plist->pl_cursize; 
+
+        /* Allocate the initial array of property value pointers */
+        plist->pl_ppval = (pb_entry **)pool_malloc(mempool,
+                                                   (plist->pl_cursize *
+                                                    sizeof(PLValueStruct_t *)));
+        if (!plist->pl_ppval) {
+
+            /* Failed - insufficient memory */
+            pool_free(mempool, (void *)plist);
+            plist = NULL;
+        }
+        else {
+            /* NULL out pointers in the reserved index range, if any */
+            for (i = 0; i < plist->pl_lastpi; ++i) {
+                plist->pl_ppval[i] = 0;
+            }
+        }
+    }
+
+    return (PList_t)plist;
+}
+
+
+/*
+ * FUNCTION:    PListDuplicate
+ *
+ * DESCRIPTION:
+ *
+ *      This function duplicates a specified PList_t.  
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *      mempool                 - handle for a memory pool to be associated
+ *                                with the new property list
+ *      resvprop                - number of reserved property indices
+ *      maxprop                 - maximum number of properties in list
+ *                                (zero or negative imposes no limit)
+ *      flags                   - unused, reserved, must be zero
+ *
+ * RETURNS:
+ *
+ *      If successful, the function return value is a handle for the new
+ *      property list.  Otherwise NULL is returned.
+ */
+
+NSAPI_PUBLIC PList_t
+PListDuplicate(PList_t plist, pool_handle_t *new_mempool, int flags)
+{
+    PListStruct_t *pl = (PListStruct_t *)plist;
+    PLValueStruct_t **ppval;
+    PLValueStruct_t *pv;
+    int i;
+    int rv = 0;
+    PList_t new_plist;
+
+    if (!plist) return NULL;
+
+    new_plist = PListCreateDuplicate(plist, new_mempool, flags);
+    if (new_plist == NULL) {
+        return(NULL);
+    }
+
+    ppval = (PLValueStruct_t **)(pl->pl_ppval);
+
+    /* Loop over the initialized property indices */
+    for (i = 0; i < pl->pl_initpi; ++i) {
+
+        /* Got a property here? */
+        pv = ppval[i];
+        if (pv) {
+            /* Create the property */
+            rv = PListDefProp(new_plist, i + 1, pv->pv_name, PLFLG_IGN_RES);
+            if (rv > 0) {
+        
+                /* If that worked, set the value and type */
+                rv = PListSetValue(new_plist, rv, pv->pv_value, pv->pv_type);
+            }
+        
+            if ( rv <= 0 ) {
+                PListDestroy(new_plist);
+                return(NULL);
+            }
+        }
+
+    }
+
+    return(new_plist);
+}
+
+/*
+ * FUNCTION:    PListGetPool
+ *
+ * DESCRIPTION:
+ *
+ *      This function returns the memory pool the PList is allocated from.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *
+ * RETURNS:
+ *
+ *      The memory pool address, which can be NULL.
+ */
+
+NSAPI_PUBLIC pool_handle_t *
+PListGetPool(PList_t plist)
+{
+    if (!plist) return NULL;
+
+    return(plist->pl_mempool);
+}
+
+/*
+ * FUNCTION:    PListGetFreeIndex
+ *
+ * DESCRIPTION:
+ *
+ *      This function returns an available property index.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *
+ * RETURNS:
+ *
+ *      If successful, an available property index is returned as the
+ *      function value.  Errors are indicated by a negative return code
+ *      as defined in plist.h.
+ */
+
+int
+PListGetFreeIndex(PListStruct_t *pl)
+{
+    PLValueStruct_t **ppval = (PLValueStruct_t **)(pl->pl_ppval);
+    int wrapped;
+    int i;
+
+    /*
+     * Look for a free property index, starting at pl_lastpi + 1.
+     * (Note that i is the property index - 1)
+     */
+    for (wrapped = 0, i = pl->pl_lastpi; ;) {
+
+        /* Are we in an initialized part of the array? */
+        if (i < pl->pl_initpi) {
+
+            /* Yes, use this index if it's free */
+            if (ppval[i] == 0) break;
+
+            /* Otherwise step to the next one */
+            ++i;
+        }
+        else {
+
+            /* Have we reached the end yet? */
+            if (i < pl->pl_cursize) {
+
+                /*
+                 * We are above the highest initialized index, but
+                 * still within the allocated size.  An index in
+                 * this range can be used with no further checks.
+                 */
+                ppval[i] = 0;
+            }
+            else {
+
+                /*
+                 * It's looking like time to grow the array, but
+                 * first go back and look for an unused, unreserved
+                 * index that might have been freed.
+                 */
+                if (!wrapped) {
+
+                    i = pl->pl_resvpi;
+                    wrapped = 1;
+                    continue;
+                }
+
+                /*
+                 * Grow the array unless there is a specified maximum
+                 * size and we've reached it.
+                 */
+                i = pl->pl_cursize;
+                if (pl->pl_maxprop && (i > pl->pl_maxprop)) {
+
+                    /* Error - property list is full */
+                    return ERRPLFULL;
+                }
+
+                /* Increase planned size of list */
+                int cursize = i + PLIST_DEFGROW;
+
+                /* Reallocate the array of property value pointers */
+                ppval = (PLValueStruct_t **)pool_realloc(pl->pl_mempool,
+                                   (void *)ppval,
+                                   (cursize * sizeof(PLValueStruct_t *)));
+                if (!ppval) {
+
+                    /* Error - insufficient memory */
+                    return ERRPLNOMEM;
+                }
+
+                /* Initialize the first new entry and select it */
+                ppval[i] = NULL;
+                pl->pl_ppval = (pb_entry **)ppval;
+                pl->pl_cursize = cursize;
+            }
+
+            /* Update the highest initialized index value */
+            pl->pl_initpi = i + 1;
+            break;
+        }
+    }
+
+    /* Set the starting point for the next allocation */
+    pl->pl_lastpi = i + 1;
+
+    return i + 1;
+}
+
+/*
+ * FUNCTION:    PListSymbolTable
+ *
+ * DESCRIPTION:
+ *
+ *      This function allocates or grows a property list's symbol table as
+ *      needed.
+ *
+ * ARGUMENTS:
+ *
+ *      plist                   - handle for the property list
+ *
+ * RETURNS:
+ *
+ *      If successful, a pointer to the symbol table is returned as the
+ *      function value.  Errors are indicated by a NULL return code.
+ */
+
+PLSymbolTable_t *
+PListSymbolTable(PListStruct_t *pl)
+{
+    PLSymbolTable_t *pt;
+    int i;
+
+    pt = pl->pl_symtab;
+
+    /* Is there a hash table? */
+    if (!pl->pl_symtab) {
+
+        /* No, create one */
+        pt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1, PLHASHSIZE(0));
+
+        pl->pl_symtab = pt;
+    }
+    else {
+
+        /* Is it time to grow the hash table? */
+        i = PLSIZENDX(pt->pt_sizendx);
+        if ((pt->pt_sizendx < PLMAXSIZENDX) && pt->pt_nsyms >= (i + i)) {
+
+            PLSymbolTable_t *npt;
+
+            /* Yes, allocate the new table */
+            npt = (PLSymbolTable_t *)pool_calloc(pl->pl_mempool, 1,
+                                                 PLHASHSIZE(pt->pt_sizendx+1));
+            if (npt) {
+                npt->pt_sizendx = pt->pt_sizendx + 1;
+                npt->pt_nsyms = pt->pt_nsyms;
+
+                /* Rehash all the names into the new table, preserving order */
+                for (i = 0; i < PLSIZENDX(pt->pt_sizendx); ++i) {
+                    /* While there are names at this hash index... */
+                    while (pt->pt_hash[i]) {
+                        PLValueStruct_t **pvp;
+                        int j;
+
+                        /* Find the last name at this hash index */
+                        for (pvp = &pt->pt_hash[i]; (*pvp)->pv_next; pvp = &(*pvp)->pv_next);
+                        
+                        /* Move the name to the new table */
+                        j = PListHashName(npt, (*pvp)->pv_name);
+                        (*pvp)->pv_next = npt->pt_hash[j];
+                        npt->pt_hash[j] = (*pvp);
+
+                        /* Remove the name from the old table */
+                        *pvp = NULL;
+                    }
+                }
+
+                pl->pl_symtab = npt;
+
+                /* Free the old symbol table */
+                pool_free(pl->pl_mempool, (void *)pt);
+                pt = npt;
+            }
+        }
+    }
+
+    return pl->pl_symtab;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/plist.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PLIST_H
+#define _PLIST_H
+
+#ifndef NOINTNSACL
+#define INTNSACL
+#endif /* !NOINTNSACL */
+
+/*
+ * TYPE:        PList_t
+ *
+ * DESCRIPTION:
+ *
+ *      This type defines a handle for a property list.
+ */
+
+#include "pool.h"
+#include "mps/nspr.h"
+#include "../public/nsapi.h"
+#include "plist_pvt.h"
+
+#ifndef PUBLIC_NSACL_PLISTDEF_H
+#include "plistdef.h"
+#endif /* !PUBLIC_NSACL_PLISTDEF_H */
+
+#ifdef INTNSACL
+
+/* Functions in plist.c */
+NSPR_BEGIN_EXTERN_C
+
+NSAPI_PUBLIC extern int PListAssignValue(PList_t plist, const char *pname,
+                            const void *pvalue, PList_t ptype);
+NSAPI_PUBLIC extern PList_t PListCreate(pool_handle_t *mempool,
+                           int resvprop, int maxprop, int flags);
+NSAPI_PUBLIC extern int PListDefProp(PList_t plist, int pindex, 
+                        const char *pname, const int flags);
+NSAPI_PUBLIC extern const void * PListDeleteProp(PList_t plist, int pindex, const char *pname);
+NSAPI_PUBLIC extern int PListFindValue(PList_t plist,
+                          const char *pname, void **pvalue, PList_t *type);
+NSAPI_PUBLIC extern int PListInitProp(PList_t plist, int pindex, const char *pname,
+                         const void *pvalue, PList_t ptype);
+NSAPI_PUBLIC extern PList_t PListNew(pool_handle_t *mempool);
+NSAPI_PUBLIC extern void PListDestroy(PList_t plist);
+NSAPI_PUBLIC extern int PListGetValue(PList_t plist,
+                         int pindex, void **pvalue, PList_t *type);
+NSAPI_PUBLIC extern int PListNameProp(PList_t plist, int pindex, const char *pname);
+NSAPI_PUBLIC extern int PListSetType(PList_t plist, int pindex, PList_t type);
+NSAPI_PUBLIC extern int PListSetValue(PList_t plist,
+                         int pindex, const void *pvalue, PList_t type);
+NSAPI_PUBLIC extern void PListEnumerate(PList_t plist, PListFunc_t *user_func, 
+                           void *user_data);
+NSAPI_PUBLIC extern PList_t
+PListDuplicate(PList_t plist, pool_handle_t *new_mempool, int flags);
+NSAPI_PUBLIC extern pool_handle_t *PListGetPool(PList_t plist);
+NSAPI_PUBLIC extern int PListDefKey(PList_t plist, pb_key *key, const char *pname, const int flags);
+NSAPI_PUBLIC extern int PListInitKey(PList_t plist, pb_key *key, const void *pvalue, PList_t ptype);
+
+NSPR_END_EXTERN_C
+
+#endif /* INTNSACL */
+
+#endif /* _PLIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/plist_pvt.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,162 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PLIST_PVT_H
+#define _PLIST_PVT_H
+
+/*
+ * FILE:        plist_pvt.h
+ *
+ * DESCRIPTION:
+ *
+ *      This file contains private definitions for the property list
+ *      utility implementation.
+ */
+
+#include "../public/nsapi.h"
+#include "pool.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+typedef struct PLValueStruct_s PLValueStruct_t;
+typedef struct PLSymbol_s PLSymbol_t;
+typedef struct PLSymbolTable_s PLSymbolTable_t;
+typedef struct PListStruct_s PListStruct_t;
+
+/*
+ * TYPE:        PLValueStruct_t
+ *
+ * DESCRIPTION:
+ *
+ *      This type represents a property value. It is dynamically
+ *      allocated when a new property is added to a property list.
+ *      It contains a reference to a property list that contains
+ *      information about the property value, and a reference to
+ *      the property value data.
+ */
+
+#ifndef PBLOCK_H
+#include "pblock.h"
+#endif /* PBLOCK_H */
+
+struct PLValueStruct_s {
+    pb_entry pv_pbentry;	/* used for pblock compatibility */
+    pb_param pv_pbparam;	/* property name and value pointers */
+    const pb_key *pv_pbkey;     /* property pb_key pointer (optional) */
+    PLValueStruct_t *pv_next;   /* property name hash collision link */
+    PListStruct_t *pv_type;     /* property value type reference */
+    int pv_pi;                  /* property index */
+    pool_handle_t *pv_mempool;  /* pool we were allocated from */
+};
+
+#define pv_name pv_pbparam.name
+#define pv_value pv_pbparam.value
+
+/* Offset to pv_pbparam in PLValueStruct_t */
+#define PVPBOFFSET ((char *)&((PLValueStruct_t *)0)->pv_pbparam)
+
+/* Convert pb_param pointer to PLValueStruct_t pointer */
+#define PATOPV(p) ((PLValueStruct_t *)((char *)(p) - PVPBOFFSET))
+
+/*
+ * TYPE:        PLSymbolTable_t
+ *
+ * DESCRIPTION:
+ *
+ *      This type represents a symbol table that maps property names
+ *      to properties.  It is dynamically allocated the first time a
+ *      property is named.
+ */
+
+#define PLSTSIZES       {7, 19, 31, 67, 123, 257, 513}
+#define PLMAXSIZENDX    (sizeof(plistHashSizes)/sizeof(plistHashSizes[0]) - 1)
+
+struct PLSymbolTable_s {
+    int pt_sizendx;             /* pt_hash size, as an index in PLSTSIZES */
+    int pt_nsyms;               /* number of symbols in table */
+    PLValueStruct_t *pt_hash[1];/* variable-length array */
+};
+
+/*
+ * TYPE:        PListStruct_t
+ *
+ * DESCRIPTION:
+ *
+ *      This type represents the top-level of a property list structure.
+ *      It is dynamically allocated when a property list is created, and
+ *      freed when the property list is destroyed.  It references a
+ *      dynamically allocated array of pointers to property value
+ *      structures (PLValueStruct_t).
+ */
+
+#define PLIST_DEFSIZE   8       /* default initial entries in pl_ppval */
+#define PLIST_DEFGROW   16      /* default incremental entries for pl_ppval */
+
+struct PListStruct_s {
+    pblock pl_pb;		/* pblock subset of property list head */
+    PLSymbolTable_t *pl_symtab; /* property name to index symbol table */
+    pool_handle_t *pl_mempool;  /* associated memory pool handle */
+    int pl_maxprop;             /* maximum number of properties */
+    int pl_resvpi;              /* number of reserved property indices */
+    int pl_lastpi;              /* last allocated property index */
+    int pl_cursize;             /* current size of pl_ppval in entries */
+};
+
+#define pl_initpi pl_pb.hsize    /* number of pl_ppval entries initialized */
+#define pl_ppval pl_pb.ht	/* pointer to array of value pointers */
+
+/* Convert pblock pointer to PListStruct_t pointer */
+#define PBTOPL(p) ((PListStruct_t *)(p))
+
+#define PLSIZENDX(i) (plistHashSizes[i])
+#define PLHASHSIZE(i) (sizeof(PLSymbolTable_t) + \
+                       (PLSIZENDX(i) - 1)*sizeof(PLValueStruct_t *))
+
+extern int plistHashSizes[7];
+
+unsigned int PListHash(const char *string);
+
+int PListHashName(PLSymbolTable_t *symtab, const char *pname);
+
+int PListGetFreeIndex(PListStruct_t *pl);
+
+PLSymbolTable_t *PListSymbolTable(PListStruct_t *pl);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _PLIST_PVT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/plistdef.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PUBLIC_NSACL_PLISTDEF_H
+#define PUBLIC_NSACL_PLISTDEF_H
+
+/*
+ * File:        plistdef.h
+ *
+ * Description:
+ *
+ *      This file defines the interface to property lists.  Property
+ *      lists are a generalization of parameter blocks (pblocks).
+ */
+
+#ifndef PUBLIC_NSAPI_H
+#include "../public/nsapi.h"
+#endif /* !PUBLIC_NSAPI_H */
+
+typedef struct PListStruct_s *PList_t;
+
+/* Define error codes returned from property list routines */
+
+#define ERRPLINVPI      -1      /* invalid property index */
+#define ERRPLEXIST      -2      /* property already exists */
+#define ERRPLFULL       -3      /* property list is full */
+#define ERRPLNOMEM      -4      /* insufficient dynamic memory */
+#define ERRPLUNDEF      -5      /* undefined property name */
+
+#define PLFLG_OLD_MPOOL	0	/* use the plist memory pool */
+#define PLFLG_NEW_MPOOL	1	/* use the input memory pool */
+#define PLFLG_IGN_RES	2	/* ignore the reserved properties */
+#define PLFLG_USE_RES	3	/* use the reserved properties */
+
+#ifdef __cplusplus
+typedef void (PListFunc_t)(char*, const void*, void*);
+#else
+typedef void (PListFunc_t)();
+#endif
+
+#ifndef INTNSACL
+
+
+
+#endif /* !INTNSACL */
+
+#endif /* !PUBLIC_NSACL_PLISTDEF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/pool.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,699 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Generic pool handling routines.
+ *
+ * These routines reduce contention on the heap and guard against
+ * memory leaks.
+ *
+ * Thread warning:
+ *     This implementation is thread safe.  However, simultaneous 
+ *     mallocs/frees to the same "pool" are not safe.  Do not share
+ *     pools across multiple threads without providing your own
+ *     synchronization.
+ *
+ * Mike Belshe
+ * 11-20-95
+ *
+ */
+
+//include "netsite.h"
+//include "systems.h"
+#include "systhr.h"
+#include "pool_pvt.h"
+#include "ereport.h"
+//include "base/session.h"
+//include "frame/req.h"
+//include "frame/http.h"
+#include "util.h"
+//include "base/crit.h"
+
+//include "base/dbtbase.h"
+
+
+
+#include <stdlib.h>
+#include <string.h>
+//define PERM_MALLOC   malloc
+//define PERM_FREE     free
+//define PERM_REALLOC  realloc
+//define PERM_CALLOC   calloc
+//define PERM_STRDUP   strdup
+
+/* Pool configuration parameters */
+static pool_config_t pool_config = POOL_CONFIG_INIT;
+
+/* Pool global statistics */
+static pool_global_stats_t pool_global_stats;
+
+static int 
+pool_internal_init()
+{
+    if (pool_global_stats.lock == NULL) {
+        pool_global_stats.lock = PR_NewLock();
+    }
+
+    if (pool_config.block_size == 0) {
+        //ereport(LOG_INFORM, XP_GetAdminStr(DBT_poolInitInternalAllocatorDisabled_));
+    }
+
+    return 0;
+}
+
+NSAPI_PUBLIC int
+pool_init(pblock *pb, Session *sn, Request *rq)
+{
+    //char *str_block_size = pblock_findval("block-size", pb);
+    //char *str_pool_disable = pblock_findval("disable", pb);
+    char *str_block_size = "16384";
+    char *str_pool_disable = "false";
+    int n;
+
+    //printf("standard block size: %d\n", pool_config.block_size);
+
+    if (str_block_size != NULL) {
+        n = atoi(str_block_size);
+        if (n > 0)
+            pool_config.block_size = n;
+    }
+
+    if (str_pool_disable && util_getboolean(str_pool_disable, PR_TRUE)) {
+        /* We'll call PERM_MALLOC() on each pool_malloc() call */
+        pool_config.block_size = 0;
+        pool_config.retain_size = 0;
+        pool_config.retain_num = 0;
+    }
+
+    pool_internal_init();
+
+    return REQ_PROCEED;
+}
+
+static block_t *
+_create_block(pool_t *pool, int size)
+{
+    block_t *newblock;
+    char *newdata;
+    block_t **blk_ptr;
+    long blen;
+
+    /* Does the pool have any retained blocks on its free list? */
+    for (blk_ptr = &pool->free_blocks;
+         (newblock = *blk_ptr) != NULL; blk_ptr = &newblock->next) {
+
+        /* Yes, is this block large enough? */
+        blen = newblock->end - newblock->data;
+        if (blen >= size) {
+
+            /* Yes, take it off the free list */
+            *blk_ptr = newblock->next;
+            pool->free_size -= blen;
+            --pool->free_num;
+
+            /* Give the block to the caller */
+            newblock->start = newblock->data;
+            goto done;
+        }
+    }
+
+    newblock = (block_t *)PERM_MALLOC(sizeof(block_t));
+    newdata = (char *)PERM_MALLOC(size);
+    if (newblock == NULL || (newdata == NULL && size != 0)) {
+        //ereport(LOG_CATASTROPHE,
+        //        XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_));
+        PERM_FREE(newblock);
+        PERM_FREE(newdata);
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    newblock->data = newdata;
+    newblock->start = newblock->data;
+    newblock->end   = newblock->data + size;
+    newblock->next  = NULL;
+    blen = size;
+
+#ifdef POOL_GLOBAL_STATISTICS
+    PR_AtomicIncrement((PRInt32 *)&pool_global_stats.blkAlloc);
+#endif /* POOL_GLOBAL_STATISTICS */
+
+  done:
+
+#ifdef PER_POOL_STATISTICS
+    ++pool->stats.blkAlloc;
+#endif /* PER_POOL_STATISTICS */
+
+    return newblock;
+}
+
+static void 
+_free_block(block_t *block)
+{
+    long blen = block->end - block->data;
+
+#ifdef POOL_ZERO_DEBUG
+    memset(block->data, POOL_ZERO_DEBUG, blen);
+#endif /* POOL_ZERO_DEBUG */
+
+    PERM_FREE(block->data);
+
+#ifdef POOL_ZERO_DEBUG
+    memset(block, POOL_ZERO_DEBUG, sizeof(block));
+#endif /* POOL_ZERO_DEBUG */
+
+    PERM_FREE(block);
+
+#ifdef POOL_GLOBAL_STATISTICS
+    PR_AtomicIncrement((PRInt32 *)&pool_global_stats.blkFree);
+#endif /* POOL_GLOBAL_STATISTICS */
+}
+
+/* ptr_in_pool()
+ * Checks to see if the given pointer is in the given pool.
+ * If true, returns a ptr to the block_t containing the ptr;
+ * otherwise returns NULL
+ */
+block_t * 
+_ptr_in_pool(pool_t *pool, const void *ptr)
+{
+    block_t *block_ptr = NULL;
+
+    /* try to find a block which contains this ptr */
+
+    if (POOL_PTR_IN_BLOCK(pool->curr_block, ptr)) {
+        block_ptr = pool->curr_block;
+    }
+    else {
+        for (block_ptr = pool->used_blocks; block_ptr; block_ptr = block_ptr->next) {
+            if (POOL_PTR_IN_BLOCK(block_ptr, ptr))
+                break;
+        }
+    }
+    return block_ptr;
+}
+
+
+NSAPI_PUBLIC pool_handle_t *
+pool_create()
+{
+    pool_t *newpool;
+
+    newpool = (pool_t *)PERM_MALLOC(sizeof(pool_t));
+
+    if (newpool) {
+        /* Have to initialize now, as pools get created sometimes
+         * before pool_init can be called...
+         */
+        if (pool_global_stats.lock == NULL) {
+            pool_internal_init();
+        }
+
+        newpool->used_blocks = NULL;
+        newpool->free_blocks = NULL;
+        newpool->free_size = 0;
+        newpool->free_num = 0;
+        newpool->size = 0;
+        newpool->next = NULL;
+
+#ifdef PER_POOL_STATISTICS
+        /* Initial per pool statistics */
+        memset((void *)(&newpool->stats), 0, sizeof(newpool->stats));
+        newpool->stats.thread = PR_GetCurrentThread();
+        newpool->stats.created = PR_Now();
+#endif /* PER_POOL_STATISTICS */
+
+        /* No need to lock, since pool has not been exposed yet */
+        newpool->curr_block =_create_block(newpool, pool_config.block_size);
+        if (newpool->curr_block == NULL) {
+            //ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_));
+            pool_destroy((pool_handle_t *)newpool);
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return NULL;
+        }
+
+        /* Add to known pools list */
+        PR_Lock(pool_global_stats.lock);
+        newpool->next = pool_global_stats.poolList;
+        pool_global_stats.poolList = newpool;
+        ++pool_global_stats.createCnt;
+#ifdef PER_POOL_STATISTICS
+        newpool->stats.poolId = pool_global_stats.createCnt;
+#endif /* PER_POOL_STATISTICS */
+        PR_Unlock(pool_global_stats.lock);
+
+    }
+    else {
+        //ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_1));
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+
+    return (pool_handle_t *)newpool;
+}
+
+/*
+ * pool_mark - get mark for subsequent recycle
+ *
+ * This function returns a value that can be used to free all pool
+ * memory which is subsequently allocated, without freeing memory
+ * that has already been allocated when pool_mark() is called.
+ * The pool_recycle() function is used to free the memory allocated
+ * since pool_mark() was called.
+ *
+ * This function may be called several times before pool_recycle()
+ * is called, but some care must be taken not to pass an invalid
+ * mark value to pool_recycle(), which would cause all pool memory
+ * to be freed.  A mark value becomes invalid when pool_recycle is
+ * called with a previously returned mark value.
+ */
+NSAPI_PUBLIC void *
+pool_mark(pool_handle_t *pool_handle)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+
+    PR_ASSERT(pool != NULL);
+
+    if (pool == NULL)
+        return NULL;
+
+#ifdef PER_POOL_STATISTICS
+    pool->stats.thread = PR_GetCurrentThread();
+#endif /* PER_POOL_STATISTICS */
+
+    /* Never return end as it points outside the block */
+    if (pool->curr_block->start == pool->curr_block->end)
+        return pool->curr_block;
+
+    return (void *)(pool->curr_block->start);
+}
+
+/*
+ * pool_recycle - recycle memory in a pool
+ *
+ * This function returns all the allocated memory for a pool back to
+ * a free list associated with the pool. It is like pool_destroy() in
+ * the sense that all data structures previously allocated from the
+ * pool are freed, but it keeps the memory associated with the pool,
+ * and doesn't actually destroy the pool.
+ *
+ * The "mark" argument can be a value previously returned by
+ * pool_mark(), in which case the pool is returned to the state it
+ * was in when pool_mark() was called, or it can be NULL, in which
+ * case the pool is completely recycled.
+ */
+NSAPI_PUBLIC void
+pool_recycle(pool_handle_t *pool_handle, void *mark)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+    block_t *tmp_blk;
+    unsigned long blen;
+
+    PR_ASSERT(pool != NULL);
+
+    if (pool == NULL)
+        return;
+
+    /* Fix up curr_block.  There should always be a curr_block. */
+    tmp_blk = pool->curr_block;
+    PR_ASSERT(tmp_blk != NULL);
+
+    /* Start with curr_block, then scan blocks on used_blocks list */
+    for (;;) {
+
+        /* Check if the mark is at the end of this block */
+        if (tmp_blk == mark) {
+            pool->curr_block = tmp_blk;
+            break;
+        }
+
+        /* Look for a block containing the mark */
+        if (POOL_PTR_IN_BLOCK(tmp_blk, mark)) {
+
+            /* Reset block start pointer to marked spot */
+            if (tmp_blk == pool->curr_block) {
+                blen = tmp_blk->start - (char *)mark;
+            } else {
+                blen = tmp_blk->end - (char *)mark;
+            }
+            pool->size -= blen;
+            PR_ASSERT(pool->size >= 0);
+            tmp_blk->start = (char *)mark;
+            pool->curr_block = tmp_blk;
+            break;
+        }
+
+        /* Reset block start pointer to base of block */
+        if (tmp_blk == pool->curr_block) {
+            /* Count just the allocated length in the current block */
+            blen = tmp_blk->start - tmp_blk->data;
+        }
+        else {
+            /* Count the entire size of a used_block */
+            blen = tmp_blk->end - tmp_blk->data;
+        }
+        tmp_blk->start = tmp_blk->data;
+        pool->size -= blen;
+        PR_ASSERT(pool->size >= 0);
+
+        /*
+         * If there are no more used blocks after this one, then set
+         * this block up as the current block and return.
+         */
+        if (pool->used_blocks == NULL) {
+            PR_ASSERT(mark == NULL);
+            pool->curr_block = tmp_blk;
+            break;
+        }
+
+        /* Otherwise free this block one way or another */
+
+        /* Add block length to total retained length and check limit */
+        if ((pool->free_size + blen) <= pool_config.retain_size &&
+            pool->free_num < pool_config.retain_num) {
+
+            /* Retain block on pool free list */
+            /*
+             * XXX hep - could sort blocks on free list in order
+             * ascending size to get "best fit" allocation in
+             * _create_block(), but the default block size is large
+             * enough that fit should rarely be an issue.
+             */
+            tmp_blk->next = pool->free_blocks;
+            pool->free_blocks = tmp_blk;
+            pool->free_size += blen;
+            ++pool->free_num;
+        }
+        else {
+            /* Limit exceeded - free block */
+            _free_block(tmp_blk);
+        }
+
+#ifdef PER_POOL_STATISTICS
+        ++pool->stats.blkFree;
+#endif /* PER_POOL_STATISTICS */
+
+        /* Remove next block from used blocks list */
+        tmp_blk = pool->used_blocks;
+        pool->used_blocks = tmp_blk->next;
+    }
+}
+
+NSAPI_PUBLIC void
+pool_destroy(pool_handle_t *pool_handle)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+    block_t *tmp_blk;
+
+    PR_ASSERT(pool != NULL);
+
+    if (pool == NULL)
+        return;
+
+    if (pool->curr_block)
+        _free_block(pool->curr_block);
+
+    while(pool->used_blocks) {
+        tmp_blk = pool->used_blocks;
+        pool->used_blocks = tmp_blk->next;
+        _free_block(tmp_blk);
+    }
+
+    while(pool->free_blocks) {
+        tmp_blk = pool->free_blocks;
+        pool->free_blocks = tmp_blk->next;
+        _free_block(tmp_blk);
+    }
+
+    {
+        pool_t **ppool;
+
+        /* Remove from the known pools list */
+        PR_Lock(pool_global_stats.lock);
+        for (ppool = &pool_global_stats.poolList;
+             *ppool; ppool = &(*ppool)->next) {
+            if (*ppool == pool) {
+                ++pool_global_stats.destroyCnt;
+                *ppool = pool->next;
+                break;
+            }
+        }
+        PR_Unlock(pool_global_stats.lock);
+    }
+
+#ifdef POOL_ZERO_DEBUG
+    memset(pool, POOL_ZERO_DEBUG, sizeof(pool));
+#endif /* POOL_ZERO_DEBUG */
+
+    PERM_FREE(pool);
+
+    return;
+}
+
+
+NSAPI_PUBLIC void *
+pool_malloc(pool_handle_t *pool_handle, size_t size)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+    block_t *curr_block;
+    long reqsize, blocksize;
+    char *ptr;
+
+    if (pool == NULL)
+        return PERM_MALLOC(size);
+
+    reqsize = ALIGN(size);
+    if (reqsize == 0) {
+        /* Assign a unique address to each 0-byte allocation */
+        reqsize = WORD_SIZE;
+    }
+
+    curr_block = pool->curr_block;
+    ptr = curr_block->start;
+    curr_block->start += reqsize;
+
+    /* does this fit into the last allocated block? */
+    if (curr_block->start > curr_block->end) {
+
+        /* Did not fit; time to allocate a new block */
+
+        curr_block->start -= reqsize;  /* keep structs in tact */
+
+        /* Count unallocated bytes in current block in pool size */
+        pool->size += curr_block->end - curr_block->start;
+        PR_ASSERT(pool->size >= 0);
+#ifdef PER_POOL_STATISTICS
+        if (pool->size > pool->stats.maxAlloc) {
+            pool->stats.maxAlloc = pool->size;
+        }
+#endif /* PER_POOL_STATISTICS */
+
+        /* Move current block to used block list */
+        curr_block->next = pool->used_blocks;
+        pool->used_blocks = curr_block;
+
+        /* Allocate a chunk of memory which is at least block_size bytes */
+        blocksize = reqsize;
+        if (blocksize < pool_config.block_size)
+            blocksize = pool_config.block_size;
+
+        curr_block = _create_block(pool, blocksize);
+        pool->curr_block = curr_block;
+
+        if (curr_block == NULL) {
+            //ereport(LOG_CATASTROPHE,
+            //        XP_GetAdminStr(DBT_poolMallocOutOfMemory_));
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return NULL;
+        }
+
+        ptr = curr_block->start;
+        curr_block->start += reqsize;
+    }
+
+    pool->size += reqsize;
+    PR_ASSERT(pool->size >= 0);
+
+#ifdef PER_POOL_STATISTICS
+    if (pool->size > pool->stats.maxAlloc) {
+        pool->stats.maxAlloc = pool->size;
+    }
+    ++pool->stats.allocCnt;
+    pool->stats.thread = PR_GetCurrentThread();
+#endif /* PER_POOL_STATISTICS */
+
+    return ptr;
+}
+
+NSAPI_PUBLIC void
+pool_free(pool_handle_t *pool_handle, void *ptr)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+
+    if (ptr == NULL)
+        return;
+
+    if (pool == NULL) {
+        PERM_FREE(ptr);
+        return;
+    }
+
+    PR_ASSERT(_ptr_in_pool(pool, ptr));
+
+#ifdef PER_POOL_STATISTICS
+
+    ++pool->stats.freeCnt;
+    pool->stats.thread = PR_GetCurrentThread();
+
+#endif /* PER_POOL_STATISTICS */
+
+    return;
+}
+
+NSAPI_PUBLIC void *
+pool_calloc(pool_handle_t *pool_handle, size_t nelem, size_t elsize)
+{
+    void *ptr;
+
+    if (pool_handle == NULL)
+        return calloc(1, elsize * nelem);
+
+    ptr = pool_malloc(pool_handle, elsize * nelem);
+    if (ptr)
+        memset(ptr, 0, elsize * nelem);
+    return ptr;
+}
+
+NSAPI_PUBLIC void *
+pool_realloc(pool_handle_t *pool_handle, void *ptr, size_t size)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+    void *newptr;
+    block_t *block_ptr;
+    size_t oldsize;
+
+    if (pool == NULL)
+        return PERM_REALLOC(ptr, size);
+
+    if ( (newptr = pool_malloc(pool_handle, size)) == NULL) 
+        return NULL;
+
+    /* With our structure we don't know exactly where the end
+     * of the original block is.  But we do know an upper bound
+     * which is a valid ptr.  Search the outstanding blocks
+     * for the block which contains this ptr, and copy...
+     */
+
+    if ( !(block_ptr = _ptr_in_pool(pool, ptr)) ) {
+        /* User is trying to realloc nonmalloc'd space! */
+        return newptr;
+    }
+
+    oldsize = block_ptr->end - (char *)ptr ;
+    if (oldsize > size)
+        oldsize = size;
+    memmove((char *)newptr, (char *)ptr, oldsize);
+
+    return newptr;
+}
+
+NSAPI_PUBLIC char *
+pool_strdup(pool_handle_t *pool_handle, const char *orig_str)
+{
+    char *new_str;
+    int len = strlen(orig_str);
+
+    if (pool_handle == NULL)
+        return PERM_STRDUP(orig_str);
+
+    new_str = (char *)pool_malloc(pool_handle, len+1);
+
+    if (new_str) 
+        memcpy(new_str, orig_str, len+1);
+
+    return new_str;
+}
+
+NSAPI_PUBLIC long
+pool_space(pool_handle_t *pool_handle)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+
+    return pool->size;
+}
+
+NSAPI_PUBLIC int pool_enabled()
+{
+    if (getThreadMallocKey() == -1)
+        return 0;
+
+    if (!systhread_getdata(getThreadMallocKey()))
+        return 0;
+
+    return 1;
+}
+
+#ifdef DEBUG
+NSAPI_PUBLIC void INTpool_assert(pool_handle_t *pool_handle, const void *ptr)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+
+    if (pool == NULL)
+        return;
+
+    PR_ASSERT(_ptr_in_pool(pool, ptr));
+}
+#endif
+
+NSAPI_PUBLIC pool_config_t *pool_getConfig(void)
+{
+    return &pool_config;
+}
+
+#ifdef POOL_GLOBAL_STATISTICS
+NSAPI_PUBLIC pool_global_stats_t *pool_getGlobalStats(void)
+{
+    return &pool_global_stats;
+}
+#endif /* POOL_GLOBAL_STATISTICS */
+
+#ifdef PER_POOL_STATISTICS
+NSAPI_PUBLIC pool_stats_t *pool_getPoolStats(pool_handle_t *pool_handle)
+{
+    pool_t *pool = (pool_t *)pool_handle;
+
+    if (pool == NULL)
+        return NULL;
+
+    return &pool->stats;
+}
+#endif /* PER_POOL_STATISTICS */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/pool.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,139 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_POOL_H
+#define BASE_POOL_H
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * pool.h
+ *
+ * Module for handling memory allocations.
+ *
+ * Notes:
+ * This module is used instead of the NSPR prarena module because the prarenas
+ * did not fit as cleanly into the existing server.
+ *
+ * Mike Belshe
+ * 10-02-95
+ *
+ */
+
+#ifndef NETSITE_H
+//include "netsite.h"
+#include "../public/nsapi.h"
+#include "nspr.h"
+#endif /* !NETSITE_H */
+
+#ifndef BASE_PBLOCK_H
+//include "pblock.h"
+#endif /* !BASE_PBLOCK_H */
+
+#ifndef BASE_SESSION_H
+//#include "session.h"
+#endif /* !BASE_SESSION_H */
+
+#ifndef FRAME_REQ_H
+//include "frame/req.h"
+#endif /* !FRAME_REQ_H */
+
+/* --- Begin function prototypes --- */
+
+#ifdef INTNSAPI
+
+NSPR_BEGIN_EXTERN_C
+
+NSAPI_PUBLIC int INTpool_init(pblock *pb, Session *sn, Request *rq);
+
+#ifdef DEBUG_CACHES
+NSAPI_PUBLIC int INTpool_service_debug(pblock *pb, Session *sn, Request *rq);
+#endif
+
+NSAPI_PUBLIC pool_handle_t *INTpool_create(void);
+
+NSAPI_PUBLIC void *INTpool_mark(pool_handle_t *pool_handle);
+
+NSAPI_PUBLIC void INTpool_recycle(pool_handle_t *pool_handle, void *mark);
+
+NSAPI_PUBLIC void INTpool_destroy(pool_handle_t *pool_handle);
+
+NSAPI_PUBLIC int INTpool_enabled(void);
+
+NSAPI_PUBLIC void *INTpool_malloc(pool_handle_t *pool_handle, size_t size );
+
+NSAPI_PUBLIC void INTpool_free(pool_handle_t *pool_handle, void *ptr );
+
+NSAPI_PUBLIC 
+void *INTpool_calloc(pool_handle_t *pool_handle, size_t nelem, size_t elsize);
+
+NSAPI_PUBLIC 
+void *INTpool_realloc(pool_handle_t *pool_handle, void *ptr, size_t size );
+
+NSAPI_PUBLIC
+char *INTpool_strdup(pool_handle_t *pool_handle, const char *orig_str );
+
+#ifdef DEBUG
+NSAPI_PUBLIC void INTpool_assert(pool_handle_t *pool_handle, const void *ptr);
+#endif
+
+NSPR_END_EXTERN_C
+
+#define pool_init INTpool_init
+
+#ifdef DEBUG_CACHES
+#define pool_service_debug INTpool_service_debug
+#endif /* DEBUG_CACHES */
+
+#ifdef DEBUG
+#define POOL_ASSERT(pool, ptr) INTpool_assert(pool, ptr);
+#else
+#define POOL_ASSERT(pool, ptr)
+#endif
+
+#define pool_create INTpool_create
+#define pool_mark INTpool_mark
+#define pool_recycle INTpool_recycle
+#define pool_destroy INTpool_destroy
+#define pool_enabled INTpool_enabled
+#define pool_malloc INTpool_malloc
+#define pool_free INTpool_free
+#define pool_calloc INTpool_calloc
+#define pool_realloc INTpool_realloc
+#define pool_strdup INTpool_strdup
+
+#endif /* INTNSAPI */
+
+#endif /* !BASE_POOL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/pool_pvt.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,183 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_POOL_PVT_H
+#define BASE_POOL_PVT_H
+
+#ifndef BASE_POOL_H
+#include "pool.h"
+#endif /* BASE_POOL_H */
+
+/*
+ * pool_pvt.h - private definitions for memory pools
+ */
+
+/* Definitions */
+
+/*
+ * Define PER_POOL_STATISTICS to get detailed statistics for each
+ * pool.
+ */
+#ifdef DEBUG
+#define PER_POOL_STATISTICS
+#endif
+
+/* Define POOL_GLOBAL_STATISTICS to get global pool statistics */
+#define POOL_GLOBAL_STATISTICS
+
+/*
+ * When POOL_ZERO_DEBUG is defined, overwrite the contents of freed
+ * pool data structures and memory with the POOL_ZERO_DEBUG byte value.
+ */
+#ifdef DEBUG
+#define POOL_ZERO_DEBUG 0xa
+#endif
+
+/*
+ * DEFAULT_BLOCK_SIZE specifies the minimum granularity, in bytes, used
+ * in allocating memory from the heap for use with a pool.  A request
+ * for more than DEFAULT_BLOCK_SIZE bytes from a pool will cause a block
+ * of that size to be allocated from the heap.
+ */
+#define DEFAULT_BLOCK_SIZE      (32 * 1024)
+
+/*
+ * The pool_recycle() mechanism keeps a list of free blocks associated
+ * with each pool, in order to avoid global locking when doing the
+ * pool_recycle() operation, or when subsequently allocating memory
+ * from the pool.  DEFAULT_RETENTION_SIZE and DEFAULT_RETENTION_NUM
+ * specify the maximum number of bytes and blocks, respectively, that
+ * will be kept on a per-pool free list.
+ */
+#define DEFAULT_RETENTION_SIZE  (DEFAULT_BLOCK_SIZE * 2)
+#define DEFAULT_RETENTION_NUM   2
+
+/* WORD_SIZE 8 sets us up for 8 byte alignment. */
+#define WORD_SIZE       8   
+#undef  ALIGN
+#define ALIGN(x)        ( (x + WORD_SIZE-1) & (~(WORD_SIZE-1)) )
+
+/* Types */
+
+/*
+ * pool_stats_t
+ * This structure contains per pool statistics.
+ */
+#ifdef PER_POOL_STATISTICS
+typedef struct pool_stats_t pool_stats_t;
+struct pool_stats_t {
+    PRUint32  poolId;      /* pool id */
+    PRUint32  maxAlloc;    /* maximum bytes ever used from pool */
+    PRUint32  allocCnt;    /* count of memory allocations from pool */
+    PRUint32  freeCnt;     /* count of pool memory free operations */
+    PRUint32  blkAlloc;    /* count of block allocations */
+    PRUint32  blkFree;     /* count of blocks freed (on pool_recycle) */
+    PRThread *thread;      /* last thread to use pool */
+    PRTime    created;     /* time of pool creation */
+};
+#endif /* PER_POOL_STATISTICS */
+
+typedef struct pool_config_t pool_config_t;
+struct pool_config_t {
+    PRUint32 block_size;   /* size of blocks to allocate */
+    PRUint32 retain_size;  /* maximum bytes kept on per-pool free list */
+    PRUint32 retain_num;   /* maximum blocks kept on per-pool free list */
+};
+
+#define POOL_CONFIG_INIT { \
+                           DEFAULT_BLOCK_SIZE,     /* block_size */ \
+                           DEFAULT_RETENTION_SIZE, /* retain_size */ \
+                           DEFAULT_RETENTION_NUM,  /* retain_num */ \
+                         }
+
+/*
+ * block_t
+ * When the user allocates space, a DEFAULT_BLOCK_SIZE (or larger) block
+ * is created in the pool.  This block is used until all the space is
+ * eaten within it.  When all the space is gone, a new block is created.
+ */
+typedef struct block_t block_t;
+struct block_t {
+    char    *data;              /* the real alloc'd space */
+    char    *start;             /* first free byte in block */
+    char    *end;               /* ptr to end of block */
+    block_t *next;              /* ptr to next block */
+};
+
+#define POOL_PTR_IN_BLOCK(blk, ptr) \
+    (((char *)(ptr) < (blk)->end) && ((char *)(ptr) >= (blk)->data))
+
+/*
+ * pool_t
+ * A pool is a collection of blocks.  The blocks consist of multiple 
+ * allocations of memory, but a single allocation cannot be freed by
+ * itself.  Once the memory is allocated it is allocated until the
+ * entire pool is freed.
+ */
+typedef struct pool_t pool_t;
+struct pool_t {
+    block_t  *curr_block;       /* current block being used */
+    block_t  *used_blocks;      /* blocks that are all used up */
+    block_t  *free_blocks;      /* blocks that are free */
+    PRUint32  free_size;        /* number of bytes in free_blocks */
+    PRUint32  free_num;         /* number of blocks in free_blocks */
+    size_t    size;             /* size of memory in pool */
+    pool_t   *next;             /* known_pools list */
+#ifdef PER_POOL_STATISTICS
+    pool_stats_t stats;         /* statistics for this pool */
+#endif /* PER_POOL_STATISTICS */
+};
+
+typedef struct pool_global_stats_t pool_global_stats_t;
+struct pool_global_stats_t {
+    PRLock   *lock;        /* lock for access to poolList */
+    pool_t   *poolList;    /* list of known pools */
+    PRUint32  createCnt;   /* count of pools created */
+    PRUint32  destroyCnt;  /* count of pools destroyed */
+#ifdef POOL_GLOBAL_STATISTICS
+    PRUint32  blkAlloc;    /* count of block allocations from heap */
+    PRUint32  blkFree;     /* count of blocks freed to heap */
+#endif /* POOL_GLOBAL_STATISTICS */
+};
+
+/* Private functions for inspecting pool configuration/statistics */
+
+NSAPI_PUBLIC pool_config_t *pool_getConfig(void);
+
+NSAPI_PUBLIC pool_global_stats_t *pool_getGlobalStats(void);
+
+#ifdef PER_POOL_STATISTICS
+NSAPI_PUBLIC pool_stats_t *pool_getPoolStats(pool_handle_t *pool_handle);
+#endif
+
+#endif /* BASE_POOL_PVT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/shexp.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,496 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * shexp.c: shell-like wildcard match routines
+ *
+ *
+ * See shexp.h for public documentation.
+ *
+ * Rob McCool
+ *
+ */
+
+#include <ctype.h>    /* isalpha, tolower */
+
+#include "shexp.h"
+
+
+/*
+ * The observant engineer will notice 2 distinct sets of functions here.
+ * All of the noicmp flavor of functions do case sensitive compares on all
+ * platforms.  The other set (public set) does case insensitive compares on NT.
+ */
+int _shexp_match_noicmp(const char *str, const char *exp) ;
+
+
+/* ----------------------------- shexp_valid ------------------------------ */
+
+
+int valid_subexp(const char *exp, char stop)
+{
+    register int x,y,t;
+    int nsc,np,tld;
+
+    x=0;nsc=0;tld=0;
+
+    while(exp[x] && (exp[x] != stop)) {
+        switch(exp[x]) {
+          case '~':
+            if(tld) return INVALID_SXP;
+            else ++tld;
+          case '*':
+          case '?':
+          case '^':
+          case '$':
+            ++nsc;
+            break;
+          case '[':
+            ++nsc;
+            if((!exp[++x]) || (exp[x] == ']'))
+                return INVALID_SXP;
+            for(++x;exp[x] && (exp[x] != ']');++x)
+                if(exp[x] == '\\')
+                    if(!exp[++x])
+                        return INVALID_SXP;
+            if(!exp[x])
+                return INVALID_SXP;
+            break;
+          case '(':
+            ++nsc;
+            while(1) {
+                if(exp[++x] == ')')
+                    return INVALID_SXP;
+                for(y=x;(exp[y]) && (exp[y] != '|') && (exp[y] != ')');++y)
+                    if(exp[y] == '\\')
+                        if(!exp[++y])
+                            return INVALID_SXP;
+                if(!exp[y])
+                    return INVALID_SXP;
+                t = valid_subexp(&exp[x],exp[y]);
+                if(t == INVALID_SXP)
+                    return INVALID_SXP;
+                x+=t;
+                if(exp[x] == ')') {
+                    break;
+                }
+            }
+            break;
+          case ')':
+          case ']':
+            return INVALID_SXP;
+          case '\\':
+            if(!exp[++x])
+                return INVALID_SXP;
+          default:
+            break;
+        }
+        ++x;
+    }
+    if((!stop) && (!nsc))
+        return NON_SXP;
+    return ((exp[x] == stop) ? x : INVALID_SXP);
+}
+
+NSAPI_PUBLIC int shexp_valid(const char *exp) {
+    int x;
+
+    x = valid_subexp(exp, '\0');
+    if (x < 0) {
+        if (x == INVALID_SXP) {
+            //NsprError::setError(PR_INVALID_ARGUMENT_ERROR,
+            //                    XP_GetAdminStr(DBT_invalidshexp));
+            // TODO
+        }
+        return x;
+    }
+    return VALID_SXP;
+}
+
+
+/* ----------------------------- shexp_match ----------------------------- */
+
+
+#define MATCH 0
+#define NOMATCH 1
+#define ABORTED -1
+
+int _shexp_match(const char *str, const char *exp);
+
+int handle_union(const char *str, const char *exp)
+{
+    char *e2 = (char *) MALLOC(sizeof(char)*strlen(exp));
+    register int t,p2,p1 = 1;
+    int cp;
+
+    while(1) {
+        for(cp=1;exp[cp] != ')';cp++)
+            if(exp[cp] == '\\')
+                ++cp;
+        for(p2 = 0;(exp[p1] != '|') && (p1 != cp);p1++,p2++) {
+            if(exp[p1] == '\\')
+                e2[p2++] = exp[p1++];
+            e2[p2] = exp[p1];
+        }
+        for(t=cp+1;(e2[p2] = exp[t]);++t,++p2);
+        if(_shexp_match(str,e2) == MATCH) {
+            FREE(e2);
+            return MATCH;
+        }
+        if(p1 == cp) {
+            FREE(e2);
+            return NOMATCH;
+        }
+        else ++p1;
+    }
+}
+
+int handle_union_noicmp(const char *str, const char *exp)
+{
+    char *e2 = (char *) MALLOC(sizeof(char)*strlen(exp));
+    register int t,p2,p1 = 1;
+    int cp;
+
+    while(1) {
+        for(cp=1;exp[cp] != ')';cp++)
+            if(exp[cp] == '\\')
+                ++cp;
+        for(p2 = 0;(exp[p1] != '|') && (p1 != cp);p1++,p2++) {
+            if(exp[p1] == '\\')
+                e2[p2++] = exp[p1++];
+            e2[p2] = exp[p1];
+        }
+        for(t=cp+1;(e2[p2] = exp[t]);++t,++p2);
+        if(_shexp_match_noicmp(str,e2) == MATCH) {
+            FREE(e2);
+            return MATCH;
+        }
+        if(p1 == cp) {
+            FREE(e2);
+            return NOMATCH;
+        }
+        else ++p1;
+    }
+}
+
+int _shexp_match(const char *str, const char *exp)
+{
+    register int x,y;
+    int ret,neg;
+
+    ret = 0;
+    for(x=0,y=0;exp[y];++y,++x) {
+        if((!str[x]) && (exp[y] != '(') && (exp[y] != '$') && (exp[y] != '*'))
+            ret = ABORTED;
+        else {
+            switch(exp[y]) {
+              case '$':
+                if( (str[x]) )
+                    ret = NOMATCH;
+                else
+                    --x;             /* we don't want loop to increment x */
+                break;
+              case '*':
+                while(exp[++y] == '*');
+                if(!exp[y])
+                    return MATCH;
+                while(str[x]) {
+                    switch(_shexp_match(&str[x++],&exp[y])) {
+                    case NOMATCH:
+                        continue;
+                    case ABORTED:
+                        ret = ABORTED;
+                        break;
+                    default:
+                        return MATCH;
+                    }
+                    break;
+                }
+                if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
+                    return MATCH;
+                else
+                    ret = ABORTED;
+                break;
+              case '[':
+                if((neg = ((exp[++y] == '^') && (exp[y+1] != ']'))))
+                    ++y;
+
+                if((isalnum(exp[y])) && (exp[y+1] == '-') &&
+                   (isalnum(exp[y+2])) && (exp[y+3] == ']'))
+                    {
+                        int start = exp[y], end = exp[y+2];
+
+                        /* Droolproofing for pinheads not included */
+                        if(neg ^ ((str[x] < start) || (str[x] > end))) {
+                            ret = NOMATCH;
+                            break;
+                        }
+                        y+=3;
+                    }
+                else {
+                    int matched;
+
+                    for(matched=0;exp[y] != ']';y++)
+                        matched |= (str[x] == exp[y]);
+                    if(neg ^ (!matched))
+                        ret = NOMATCH;
+                }
+                break;
+              case '(':
+                return handle_union(&str[x],&exp[y]);
+                break;
+              case '?':
+                break;
+              case '\\':
+                ++y;
+              default:
+#ifdef XP_UNIX
+                if(str[x] != exp[y])
+#else /* XP_WIN32 */
+                if(strnicmp(str + x, exp + y, 1))
+#endif /* XP_WIN32 */
+                    ret = NOMATCH;
+                break;
+            }
+        }
+        if(ret)
+            break;
+    }
+    return (ret ? ret : (str[x] ? NOMATCH : MATCH));
+}
+
+int _shexp_match_noicmp(const char *str, const char *exp)
+{
+    register int x,y;
+    int ret,neg;
+
+    ret = 0;
+    for(x=0,y=0;exp[y];++y,++x) {
+        if((!str[x]) && (exp[y] != '(') && (exp[y] != '$') && (exp[y] != '*'))
+            ret = ABORTED;
+        else {
+            switch(exp[y]) {
+              case '$':
+                if( (str[x]) )
+                    ret = NOMATCH;
+                else
+                    --x;             /* we don't want loop to increment x */
+                break;
+              case '*':
+                while(exp[++y] == '*');
+                if(!exp[y])
+                    return MATCH;
+                while(str[x]) {
+                    switch(_shexp_match_noicmp(&str[x++],&exp[y])) {
+                    case NOMATCH:
+                        continue;
+                    case ABORTED:
+                        ret = ABORTED;
+                        break;
+                    default:
+                        return MATCH;
+                    }
+                    break;
+                }
+                if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
+                    return MATCH;
+                else
+                    ret = ABORTED;
+                break;
+              case '[':
+                if((neg = ((exp[++y] == '^') && (exp[y+1] != ']'))))
+                    ++y;
+
+                if((isalnum(exp[y])) && (exp[y+1] == '-') &&
+                   (isalnum(exp[y+2])) && (exp[y+3] == ']'))
+                    {
+                        int start = exp[y], end = exp[y+2];
+
+                        /* Droolproofing for pinheads not included */
+                        if(neg ^ ((str[x] < start) || (str[x] > end))) {
+                            ret = NOMATCH;
+                            break;
+                        }
+                        y+=3;
+                    }
+                else {
+                    int matched;
+
+                    for(matched=0;exp[y] != ']';y++)
+                        matched |= (str[x] == exp[y]);
+                    if(neg ^ (!matched))
+                        ret = NOMATCH;
+                }
+                break;
+              case '(':
+                return handle_union_noicmp(&str[x],&exp[y]);
+                break;
+              case '?':
+                break;
+              case '\\':
+                ++y;
+              default:
+                if(str[x] != exp[y])
+                    ret = NOMATCH;
+                break;
+            }
+        }
+        if(ret)
+            break;
+    }
+    return (ret ? ret : (str[x] ? NOMATCH : MATCH));
+}
+
+NSAPI_PUBLIC int shexp_match(const char *str, const char *exp)
+{
+    register int x;
+    char *expbase = NULL;
+
+    for(x=strlen(exp)-1;x;--x) {
+        if((exp[x] == '~') && (exp[x-1] != '\\')) {
+            /* we're done if the negative subexp matches */
+            if(_shexp_match(str,&exp[x+1]) == MATCH)
+                return 1;
+            /* we're done if the only thing in front of the subexp is '*' */
+            if (x == 1 && exp[0] == '*')
+                return 0;
+            /* create a copy so we can strip off the subexp */
+            expbase = STRDUP(exp);
+            expbase[x] = '\0';
+            exp = expbase;
+            break;
+        }
+    }
+    if(_shexp_match(str,exp) == MATCH) {
+        if (expbase)
+            FREE(expbase);
+        return 0;
+    }
+
+    if (expbase)
+        FREE(expbase);
+    return 1;
+}
+
+NSAPI_PUBLIC int shexp_match_noicmp(const char *str, const char *exp)
+{
+    register int x;
+    char *expbase = NULL;
+
+    for(x=strlen(exp)-1;x;--x) {
+        if((exp[x] == '~') && (exp[x-1] != '\\')) {
+            /* we're done if the negative subexp matches */
+            if(_shexp_match_noicmp(str,&exp[x+1]) == MATCH)
+                return 1;
+            /* we're done if the only thing in front of the subexp is '*' */
+            if (x == 1 && exp[0] == '*')
+                return 0;
+            /* create a copy so we can strip off the subexp */
+            expbase = STRDUP(exp);
+            expbase[x] = '\0';
+            exp = expbase;
+            break;
+        }
+    }
+    if(_shexp_match_noicmp(str,exp) == MATCH) {
+        if (expbase)
+            FREE(expbase);
+        return 0;
+    }
+
+    if (expbase)
+        FREE(expbase);
+    return 1;
+}
+
+/* ------------------------------ shexp_cmp ------------------------------- */
+
+
+NSAPI_PUBLIC int shexp_cmp(const char *str, const char *exp)
+{
+    switch(shexp_valid(exp)) {
+      case INVALID_SXP:
+        return -1;
+      case NON_SXP:
+#ifdef XP_UNIX
+        return (strcmp(exp,str) ? 1 : 0);
+#else  /* XP_WIN32 */
+        return (stricmp(exp,str) ? 1 : 0);
+#endif /* XP_WIN32 */
+      default:
+        return shexp_match(str, exp);
+    }
+}
+
+/* ------------------------------ shexp_cmp ------------------------------- */
+
+NSAPI_PUBLIC int shexp_noicmp(const char *str, const char *exp)
+{
+    switch(shexp_valid(exp)) {
+      case INVALID_SXP:
+        return -1;
+      case NON_SXP:
+        return (strcmp(exp,str) ? 1 : 0);
+      default:
+        return shexp_match_noicmp(str, exp);
+    }
+}
+
+/* ---------------------------- shexp_casecmp ----------------------------- */
+
+
+NSAPI_PUBLIC int shexp_casecmp(const char *str, const char *exp)
+{
+    char *lstr = STRDUP(str), *lexp = STRDUP(exp), *t;
+    int ret;
+
+    for(t = lstr; *t; t++)
+        if(isalpha(*t)) *t = tolower(*t);
+    for(t = lexp; *t; t++)
+        if(isalpha(*t)) *t = tolower(*t);
+
+    switch(shexp_valid(lexp)) {
+      case INVALID_SXP:
+        ret = -1;
+        break;
+      case NON_SXP:
+        ret = (strcmp(lexp, lstr) ? 1 : 0);
+        break;
+      default:
+        ret = shexp_match(lstr, lexp);
+    }
+    FREE(lstr);
+    FREE(lexp);
+    return ret;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/shexp.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,141 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_SHEXP_H
+#define BASE_SHEXP_H
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * shexp.h: Defines and prototypes for shell exp. match routines
+ *
+ *
+ * This routine will match a string with a shell expression. The expressions
+ * accepted are based loosely on the expressions accepted by zsh.
+ *
+ * o * matches anything
+ * o ? matches one character
+ * o \ will escape a special character
+ * o $ matches the end of the string
+ * o [abc] matches one occurence of a, b, or c. The only character that needs
+ *         to be escaped in this is ], all others are not special.
+ * o [a-z] matches any character between a and z
+ * o [^az] matches any character except a or z
+ * o ~ followed by another shell expression will remove any pattern
+ *     matching the shell expression from the match list
+ * o (foo|bar) will match either the substring foo, or the substring bar.
+ *             These can be shell expressions as well.
+ *
+ * The public interface to these routines is documented in
+ * public/base/shexp.h.
+ *
+ * Rob McCool
+ *
+ */
+
+/*
+ * Requires that the macro MALLOC be set to a "safe" malloc that will
+ * exit if no memory is available. If not under MCC httpd, define MALLOC
+ * to be the real malloc and play with fire, or make your own function.
+ */
+
+#ifndef NETSITE_H
+#include "../daemon/netsite.h"
+#endif /* !NETSITE_H */
+
+#ifndef OS_CTYPE_H
+#include <ctype.h>  /* isalnum */
+#define OS_CTYPE_H
+#endif /* !OS_CTYPE_H */
+
+#ifndef OS_STRING_H
+#include <string.h> /* strlen */
+#define OS_STRING_H
+#endif /* !OS_STRING_H */
+
+/* See public/base/shexp.h or public/base/regexp.h concerning USE_REGEX */
+
+/*
+ * This little bit of nonsense is because USE_REGEX is currently
+ * supposed to be recognized only by the proxy.  If that's the
+ * case, only the proxy should define USE_REGEX, but I'm playing
+ * it safe.  XXXHEP 12/96
+ */
+#ifndef MCC_PROXY
+#ifdef USE_REGEX
+#define SAVED_USE_REGEX USE_REGEX
+#undef USE_REGEX
+#endif /* USE_REGEX */
+#endif /* !MCC_PROXY */
+
+/* --- Begin function prototypes --- */
+
+#ifdef INTNSAPI
+
+NSPR_BEGIN_EXTERN_C
+
+NSAPI_PUBLIC int INTshexp_valid(const char *exp);
+
+NSAPI_PUBLIC int INTshexp_match(const char *str, const char *exp);
+
+NSAPI_PUBLIC int INTshexp_cmp(const char *str, const char *exp);
+
+NSAPI_PUBLIC int INTshexp_noicmp(const char *str, const char *exp);
+
+NSAPI_PUBLIC int INTshexp_casecmp(const char *str, const char *exp);
+
+NSPR_END_EXTERN_C
+
+/* --- End function prototypes --- */
+
+#define shexp_valid INTshexp_valid
+#define shexp_match INTshexp_match
+#define shexp_cmp INTshexp_cmp
+#define shexp_noicmp INTshexp_noicmp
+#define shexp_casecmp INTshexp_casecmp
+
+#endif /* INTNSAPI */
+
+/* Restore USE_REGEX definition for non-proxy.  See above. */
+#ifdef SAVED_USE_REGEX
+#define USE_REGEX SAVED_USE_REGEX
+#undef SAVED_USE_REGEX
+#endif /* SAVED_USE_REGEX */
+
+#ifdef USE_REGEX
+#include "base/regexp.h"
+#endif /* USE_REGEX */
+
+#endif /* !BASE_SHEXP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/strbuf.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "strbuf.h"
+#include "../ucx/sstring.h"
+
+sbuf_t* sbuf_new(size_t size) {
+    sbuf_t *buf = malloc(sizeof(sbuf_t));
+
+    buf->ptr = malloc(size);
+    buf->ptr[0] = 0;
+    buf->size = size;
+    buf->length = 0;
+
+    return buf;
+}
+
+void sbuf_puts(sbuf_t *buf, char *str) {
+    sbuf_append(buf, sstr(str));
+}
+
+void sbuf_put(sbuf_t *buf, char chr) {
+    sbuf_append(buf, sstrn(&chr, 1));
+}
+
+void sbuf_append(sbuf_t *buf, sstr_t str) {
+    if (buf->length + str.length >= buf->size) {
+        buf->size *= 2;
+        buf->ptr = realloc(buf->ptr, buf->size);
+        sbuf_append(buf, str);
+        return;
+    }
+
+    memcpy(&buf->ptr[buf->length], str.ptr, str.length);
+    buf->length += str.length;
+    buf->ptr[buf->length] = 0;
+}
+
+void sbuf_free(sbuf_t *buf) {
+    free(buf->ptr);
+    free(buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/strbuf.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRBUF_H
+#define	STRBUF_H
+
+#include "../ucx/sstring.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* string buffer */
+typedef struct _strbuf {
+    char *ptr;
+    size_t length;  /* length of string */
+    size_t size;    /* allocated size */
+} sbuf_t;
+
+sbuf_t* sbuf_new(size_t size);
+
+void sbuf_puts(sbuf_t *buf, char *str);
+
+void sbuf_put(sbuf_t *buf, char chr);
+
+void sbuf_append(sbuf_t *buf, sstr_t str);
+
+void sbuf_free(sbuf_t *buf);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* STRBUF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/system.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,387 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * system.c: A grab bag of system-level abstractions
+ * 
+ * Many authors
+ */
+
+#if (defined(__GNUC__) && (__GNUC__ > 2))
+#include <new>
+using namespace std;
+#else
+//include <new.h>
+#endif
+#include "../daemon/netsite.h"
+#include "ereport.h"
+
+#ifdef XP_WIN32
+#include <windows.h>
+#include <process.h>
+#endif
+
+static int thread_malloc_key = -1;
+
+static char* temp_dir = NULL;
+
+#ifdef XP_WIN32
+_PNH original_newhandler = 0;
+#else
+typedef void (newhandler)(void);
+static newhandler *original_newhandler = 0;
+#endif
+
+#include "pool.h"
+#include "systhr.h"
+
+#define MALLOC_KEY \
+    ((pool_handle_t *)(thread_malloc_key != -1 ? systhread_getdata(thread_malloc_key) : NULL))
+
+
+#ifdef MCC_DEBUG
+#define DEBUG_MALLOC
+#endif
+
+#ifdef DEBUG_MALLOC
+
+/* The debug malloc routines provide several functions:
+ *
+ *  - detect allocated memory overflow/underflow
+ *  - detect multiple frees
+ *  - intentionally clobbers malloc'd buffers
+ *  - intentionally clobbers freed buffers
+ */
+#define DEBUG_MAGIC 0x12345678
+#define DEBUG_MARGIN 32
+#define DEBUG_MARGIN_CHAR '*'
+#define DEBUG_MALLOC_CHAR '.'
+#define DEBUG_FREE_CHAR   'X'
+#endif /* DEBUG_MALLOC */
+
+NSAPI_PUBLIC char *system_version()
+{
+    //return PRODUCT_ID"/"PRODUCT_VERSION_ID;
+    return "Solaris 11 Express";
+}
+
+NSAPI_PUBLIC pool_handle_t *system_pool(void)
+{
+    return MALLOC_KEY;
+}
+
+NSAPI_PUBLIC void *system_malloc(int size)
+{
+    void *ret;
+    ret = pool_malloc(MALLOC_KEY, size);
+    if (!ret) {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return ret;
+}
+
+
+NSAPI_PUBLIC void *system_calloc(int size)
+{
+    void *ret;
+    ret = pool_malloc(MALLOC_KEY, size);
+    if(ret) {
+        ZERO(ret, size);
+    } else {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return ret;
+}
+
+
+NSAPI_PUBLIC void *system_realloc(void *ptr, int size)
+{
+    void *ret;
+    ret = pool_realloc(MALLOC_KEY, ptr, size);
+    if (!ret) {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return ret;
+}
+
+
+NSAPI_PUBLIC void system_free(void *ptr)
+{
+    pool_free(MALLOC_KEY, ptr);
+}
+
+NSAPI_PUBLIC char *system_strdup(const char *ptr)
+{
+    //NS_ASSERT(ptr);
+    char *ret;
+    ret = pool_strdup(MALLOC_KEY, ptr);
+    if (!ret) {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return ret;
+}
+
+
+NSAPI_PUBLIC void *system_malloc_perm(int size)
+{
+    void *ret;
+#ifndef DEBUG_MALLOC
+    ret = malloc(size);
+#else
+    char *ptr = (char *)malloc(size + 2*DEBUG_MARGIN+2*sizeof(int));
+    char *real_ptr;
+    int *magic;
+    int *length;
+  
+    magic = (int *)ptr;
+    *magic = DEBUG_MAGIC;
+    ptr += sizeof(int);
+    length = (int *)ptr;
+    *length = size;
+    ptr += sizeof(int);
+    memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN);
+    ptr += DEBUG_MARGIN;
+    memset(ptr, DEBUG_MALLOC_CHAR, size);
+    real_ptr = ptr;
+    ptr += size;
+    memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN);
+
+    ret = real_ptr;
+#endif
+    if (!ret) {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return ret;
+}
+
+NSAPI_PUBLIC void *system_calloc_perm(int size)
+{
+    void *ret = system_malloc_perm(size);
+    if(ret)
+        ZERO(ret, size);
+    return ret;
+}
+
+NSAPI_PUBLIC void *system_realloc_perm(void *ptr, int size)
+{
+    void *ret;
+
+#ifndef DEBUG_MALLOC
+    ret = realloc(ptr, size);
+#else
+    int *magic, *length;
+    char *baseptr;
+    char *cptr;
+
+    /* realloc semantics allow realloc(NULL, size) */
+    if (ptr == NULL)
+        return system_malloc_perm(size);
+
+    cptr = (char *)ptr - DEBUG_MARGIN - 2 * sizeof(int);
+    magic = (int *)cptr;
+    if (*magic == DEBUG_MAGIC) {
+        cptr += sizeof(int);
+        length = (int *)cptr;
+        if (*length < size) {
+            char *newptr = (char *)system_malloc_perm(size);
+            memcpy(newptr, ptr, *length);
+            system_free_perm(ptr);
+
+            ret = newptr;
+        }else {
+            ret = ptr;
+        }
+    } else {
+        ereport(LOG_WARN, XP_GetAdminString(DBT_systemReallocSmallerSize));
+        ret = realloc(ptr, size);
+    }
+#endif
+
+    if (!ret) {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+
+    return ret;
+}
+
+NSAPI_PUBLIC void system_free_perm(void *ptr)
+{
+#ifdef DEBUG_MALLOC
+    int *length, *magic;
+    char *baseptr, *cptr;
+    int index;
+
+    NS_ASSERT(ptr);
+
+    cptr = baseptr = ((char *)ptr) - DEBUG_MARGIN - 2*sizeof(int);
+
+    magic = (int *)cptr;
+    if (*magic == DEBUG_MAGIC) {
+        cptr += sizeof(int);
+
+        length = (int *)cptr;
+
+        cptr += sizeof(int); 
+        for (index=0; index<DEBUG_MARGIN; index++)
+            if (cptr[index] != DEBUG_MARGIN_CHAR) {
+                ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeCorruptMemoryPre));
+                break;
+            }
+
+        cptr += DEBUG_MARGIN + *length;
+        for (index=0; index<DEBUG_MARGIN; index++)
+            if (cptr[index] != DEBUG_MARGIN_CHAR) {
+                ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeCorruptMemoryPost));
+                break;
+            }
+
+        memset(baseptr, DEBUG_FREE_CHAR, *length + 2*DEBUG_MARGIN+sizeof(int));
+    } else {
+        ereport(LOG_CATASTROPHE, XP_GetAdminString(DBT_systemRFreeUnallocatedMem));
+    }
+    free(baseptr);
+#else
+    free(ptr);
+#endif
+}
+
+NSAPI_PUBLIC char *system_strdup_perm(const char *ptr)
+{
+    char *ret;
+
+#ifndef DEBUG_MALLOC
+    //NS_ASSERT(ptr);
+    ret = strdup(ptr);
+#else
+    int len = strlen(ptr);
+    char *nptr = (char *)system_malloc_perm(len+1);
+    memcpy(nptr, ptr, len);
+    nptr[len] = '\0';
+    ret = nptr;
+#endif
+
+    if (!ret) {
+        //ereport_outofmemory();
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+
+    return ret;
+}
+
+NSAPI_PUBLIC void system_set_temp_dir(const char *dir)
+{
+    // Leak any previously-allocated dir in case someone still has a reference
+    temp_dir = STRDUP(dir);
+}
+
+NSAPI_PUBLIC const char *system_get_temp_dir(void)
+{
+    char* dir = temp_dir;
+
+    if (!dir) {
+#ifdef XP_WIN32
+        dir = getenv("TEMP");
+        if (!dir) dir = getenv("TMP");
+        if (!dir) dir = "C:\\TEMP";
+#else
+        dir = "/tmp";
+#endif
+    }
+
+    return dir;
+}
+
+NSAPI_PUBLIC int 
+getThreadMallocKey(void)
+{
+    return thread_malloc_key;
+}
+
+NSAPI_PUBLIC void
+InitThreadMallocKey(void)
+{
+    PR_NewThreadPrivateIndex((unsigned int *)&thread_malloc_key, NULL);
+    PR_ASSERT(thread_malloc_key);
+}
+
+#ifdef XP_WIN32
+static int _cdecl system_newhandler(unsigned int size)
+{
+    //ereport_outofmemory();
+
+    if (original_newhandler) {
+        // Let original handler deal with things
+        return (*original_newhandler)(size);
+    }
+
+    // Tell new not to retry the allocation
+    return 0;
+}
+#else
+static void system_newhandler()
+{
+    // We want to preserve the original new semantics, but we don't know what
+    // those semantics are.  Some platforms throw xalloc while others throw
+    // bad_alloc.
+
+    //ereport_outofmemory();
+
+    if (original_newhandler) {
+        // Let original handler deal with things
+        (*original_newhandler)();
+    } else {
+        // No original handler to call; try to remove all handlers
+        static PRBool flagRemovedHandler = PR_FALSE;
+        if (flagRemovedHandler) {
+            abort();
+        }
+        //set_new_handler(0); // TODO: set_new_handler
+        flagRemovedHandler = PR_TRUE;
+    }
+}
+#endif
+
+NSAPI_PUBLIC void system_setnewhandler(void)
+{
+#ifdef XP_WIN32
+    original_newhandler = _set_new_handler(system_newhandler);
+#else
+    //original_newhandler = set_new_handler(system_newhandler); // TODO: ...
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/systems.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,541 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_SYSTEMS_H
+#define BASE_SYSTEMS_H
+
+#include <nspr.h>
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * systems.h: Lists of defines for systems
+ * 
+ * This sets what general flavor the system is (UNIX, etc.), 
+ * and defines what extra functions your particular system needs.
+ */
+
+
+/* --- Begin common definitions for all supported platforms --- */
+
+#define DAEMON_ANY
+#define DAEMON_STATS
+
+/* --- End common definitions for all supported platforms --- */
+
+/* --- Begin platform-specific definitions --- */
+
+#if defined(AIX)
+
+#define HAS_IPV6
+#define AUTH_DBM
+#define BSD_RLIMIT
+#undef BSD_SIGNALS
+//define DAEMON_NEEDS_SEMAPHORE
+//define DAEMON_UNIX_MOBRULE
+//define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW|RTLD_GLOBAL
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATFS
+#define HAVE_ATEXIT
+#define HAVE_STRERROR_R
+#define HAVE_STRTOK_R
+#define HAVE_TIME_R 2 /* arg count */
+#define HAVE_STRFTIME /* no cftime */
+#define JAVA_STATIC_LINK
+#undef NEED_CRYPT_H
+#define NEED_STRINGS_H /* for strcasecmp */
+#define NET_SOCKETS
+#define SA_HANDLER_T(x) (void (*)(int))x
+#ifdef NS_OLDES3X
+#define SA_NOCLDWAIT 0 /* AIX don't got this */
+#endif
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+#ifdef HW_THREADS
+#define THREAD_ANY
+#endif
+#elif defined(BSDI)
+
+#define AUTH_DBM
+#define BSD_MAIL
+#define BSD_RLIMIT
+#define BSD_SIGNALS
+#define BSD_TIME
+#define DAEMON_UNIX_MOBRULE
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS (MAP_FILE | MAP_SHARED)
+#define HAS_STATFS
+#define HAVE_ATEXIT
+#undef NEED_CRYPT_PROTO
+#define NET_SOCKETS
+#define NO_DOMAINNAME
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+#define JAVA_STATIC_LINK
+
+#elif defined(HPUX)
+
+#define HAVE_TIME_R 2 /* arg count */
+#define AUTH_DBM
+#undef BSD_RLIMIT
+#undef BSD_SIGNALS
+#ifdef MCC_PROXY
+#define DAEMON_NEEDS_SEMAPHORE
+#else
+#define DAEMON_NEEDS_SEMAPHORE
+#endif
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_HPSHL
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_PRIVATE
+#define HAS_STATFS
+#define HAVE_ATEXIT
+#define HAVE_STRFTIME
+#define JAVA_STATIC_LINK
+#undef NEED_CRYPT_H
+#define NET_SOCKETS
+#define SA_HANDLER_T(x) (void (*)(int))x
+#define SEM_FLOCK
+/* warning: mmap doesn't work under 9.04 */
+#define SHMEM_MMAP_FLAGS MAP_FILE | MAP_VARIABLE | MAP_SHARED
+
+#elif defined (IRIX)
+
+#define AUTH_DBM
+#define BSD_RLIMIT
+#undef BSD_SIGNALS
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define HAVE_STRTOK_R
+#define HAVE_TIME_R 2 /* arg count */
+#define JAVA_STATIC_LINK
+#define NEED_CRYPT_H
+#define NET_SOCKETS
+#define SA_HANDLER_T(x) (void (*)(int))x
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+#define THROW_HACK throw()
+
+#elif defined(Linux)
+
+#define HAS_IPV6
+#define AUTH_DBM
+#define BSD_RLIMIT
+#undef BSD_SIGNALS
+#define DAEMON_NEEDS_SEMAPHORE
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define HAVE_STRTOK_R
+#define HAVE_TIME_R 2 /* arg count */
+#define NEED_CRYPT_H
+#undef NEED_FILIO
+#define NEED_GHN_PROTO
+#define NET_SOCKETS
+#define SA_HANDLER_T(x) (void (*)(int))x
+#undef NEED_GHN_PROTO 
+
+#elif defined(NCR)
+
+#define AUTH_DBM
+#undef BSD_RLIMIT
+/* #define DAEMON_NEEDS_SEMAPHORE */
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define HAVE_STRTOK_R
+#define JAVA_STATIC_LINK
+#define NEED_CRYPT_H
+#define NEED_FILIO
+#define NEED_GHN_PROTO
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#elif defined(NEC)
+
+#define DNS_CACHE
+#define AUTH_DBM
+#undef BSD_RLIMIT
+#define DAEMON_NEEDS_SEMAPHORE
+#define DAEMON_UNIX_MOBRULE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DLL_CAPABLE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define HAVE_STRTOK_R
+#define HAVE_TIME_R 2 /* arg count */
+#define JAVA_STATIC_LINK
+#define NEED_CRYPT_H
+#define NEED_FILIO
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#elif defined(OSF1)
+
+#define HAS_IPV6
+#define AUTH_DBM
+#define BSD_RLIMIT
+#undef BSD_SIGNALS
+#define BSD_TIME
+#define DAEMON_UNIX_MOBRULE
+#define DAEMON_NEEDS_SEMAPHORE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAVE_ATEXIT
+#define HAVE_STRFTIME /* no cftime */
+#define HAVE_TIME_R 2 /* ctime_r arg count */
+#define NET_SOCKETS
+#define SA_HANDLER_T(x) (void (*)(int))x
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#elif defined(SCO)
+
+#define AUTH_DBM
+#undef BSD_RLIMIT
+#undef BSD_SIGNALS
+#define DAEMON_NEEDS_SEMAPHORE
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#undef NEED_CRYPT_H
+#undef NEED_FILIO
+#undef NEED_GHN_PROTO
+#undef NEED_SETEID_PROTO /* setegid, seteuid */
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+#define SA_HANDLER_T(x) (void (*)(int))x
+
+
+#elif defined(SNI)
+
+#define AUTH_DBM
+#undef BSD_RLIMIT
+#define DAEMON_NEEDS_SEMAPHORE
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define JAVA_STATIC_LINK
+#define NEED_CRYPT_H
+#define NEED_FILIO
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+#define USE_PIPE
+
+#elif defined(SOLARIS)
+
+#if defined(ENABLE_IPV6)
+#define HAS_IPV6
+#endif
+#define AUTH_DBM
+#define BSD_RLIMIT
+#undef BSD_SIGNALS
+#define DAEMON_NEEDS_SEMAPHORE
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW|RTLD_FIRST
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define HAVE_STRTOK_R
+#define HAVE_TIME_R 3 /* arg count */
+#define NEED_CRYPT_H
+#define NEED_FILIO
+#define NEED_GHN_PROTO
+#define NET_SOCKETS
+#if OSVERSION > 504 
+#define SA_HANDLER_T(x) x 
+#endif
+#if OSVERSION >= 506 
+#undef NEED_GHN_PROTO 
+#endif
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#elif defined (SONY)
+
+#define AUTH_DBM
+#undef BSD_RLIMIT
+#define DAEMON_NEEDS_SEMAPHORE
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAVE_ATEXIT
+#define NEED_CRYPT_H
+#define NEED_FILIO
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#elif defined(SUNOS4)
+
+#define AUTH_DBM
+#define BSD_MAIL
+#define BSD_RLIMIT
+#define BSD_SIGNALS
+#define BSD_TIME
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS 1
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATFS
+#undef HAVE_ATEXIT
+#undef NEED_CRYPT_H
+#define NEED_CRYPT_PROTO
+#define NEED_FILIO
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#elif defined(UNIXWARE)
+
+#define AUTH_DBM
+#undef BSD_RLIMIT
+#define DAEMON_UNIX_MOBRULE
+#define DLL_CAPABLE
+#define DLL_DLOPEN
+#define DLL_DLOPEN_FLAGS RTLD_NOW
+#define DNS_CACHE
+#define FILE_INHERIT_FCNTL
+#define FILE_MMAP_FLAGS MAP_SHARED
+#define HAS_STATVFS
+#define HAVE_ATEXIT
+#define NEED_CRYPT_H
+#define NEED_FILIO
+#define NEED_GHN_PROTO
+#define NEED_SETEID_PROTO /* setegid, seteuid */
+#define NET_SOCKETS
+#define SEM_FLOCK
+#define SHMEM_MMAP_FLAGS MAP_SHARED
+
+#ifndef boolean
+#define boolean boolean
+#endif
+
+#elif defined (XP_WIN32)      /* Windows NT */
+
+#include <wtypes.h>
+#include <winbase.h>
+
+#define AUTH_DBM
+#define DAEMON_WIN32
+#define DLL_CAPABLE
+#define DLL_WIN32
+#define DNS_CACHE
+#define LOG_BUFFERING
+#define HAVE_STRFTIME /* no cftime */
+#define NEED_CRYPT_PROTO
+#define NEEDS_WRITEV
+#define NET_SOCKETS
+#define NO_DOMAINNAME
+#ifdef BUILD_DLL
+#if defined (NSAPI_PUBLIC)
+#undef  NSAPI_PUBLIC
+#endif
+#define NSAPI_PUBLIC __declspec(dllexport)
+#else
+#if defined (NSAPI_PUBLIC)
+#undef  NSAPI_PUBLIC
+#endif
+#define NSAPI_PUBLIC
+#endif /* BUILD_DLL */
+#define SEM_WIN32
+#define THREAD_ANY
+#define THREAD_NSPR_KERNEL
+#define USE_NSPR
+#define USE_STRFTIME /* no cftime */
+#define FILE_DEV_NULL "\\\\.\NUL"
+
+#endif	/* Windows NT */
+
+/* --- Begin defaults for values not defined above --- */
+
+#ifndef DAEMON_LISTEN_SIZE
+#define DAEMON_LISTEN_SIZE 128
+#endif /* !DAEMON_LISTEN_SIZE */
+
+#ifndef NSAPI_PUBLIC
+#define NSAPI_PUBLIC
+#endif
+
+#ifndef SA_HANDLER_T
+#define SA_HANDLER_T(x) (void (*)())x 
+#endif
+
+#ifndef THROW_HACK
+#define THROW_HACK /* as nothing */
+#endif
+
+#ifndef FILE_DEV_NULL
+#define FILE_DEV_NULL "/dev/null"
+#endif
+
+/* --- End defaults for values not defined above --- */
+
+/* --- Begin the great debate --- */
+
+/* NS_MAIL builds sec-key.c which calls systhread_init, which requires */
+/* that USE_NSPR is defined when systhr.c is compiled.  --lachman */
+/* MCC_PROXY does the same thing now --nbreslow -- LIKE HELL --ari */
+#if (defined(MCC_HTTPD) || defined(MCC_ADMSERV) || defined(MCC_PROXY) || defined(NS_MAIL)) && defined(XP_UNIX)
+#define USE_NSPR
+/* XXXrobm This is UNIX-only for the moment */
+#define LOG_BUFFERING
+#ifdef SW_THREADS
+#define THREAD_NSPR_USER
+#else
+#define THREAD_NSPR_KERNEL
+#endif
+#define THREAD_ANY
+#endif
+
+/* --- End the great debate --- */
+
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#ifndef NSPR_PRIO_H
+//include "prio.h"
+#define NSPR_PRIO_H
+#endif /* !NSPR_PRIO_H */
+
+/*
+ * These types have to be defined early, because they are defined
+ * as (void *) in the public API.
+ */
+
+#ifndef SYS_FILE_T
+typedef PRFileDesc *SYS_FILE;
+#define SYS_FILE_T PRFileDesc *
+#endif /* !SYS_FILE_T */
+
+#ifndef SYS_NETFD_T
+typedef PRFileDesc *SYS_NETFD;
+#define SYS_NETFD_T PRFileDesc *
+#endif /* !SYS_NETFD_T */
+
+#ifdef SEM_WIN32
+
+typedef HANDLE SEMAPHORE;
+#define SEMAPHORE_T HANDLE
+#define SEM_ERROR NULL
+/* That oughta hold them (I hope) */
+#define SEM_MAXVALUE 32767
+
+#elif defined(SEM_FLOCK)
+
+//define SEMAPHORE_T int
+//typedef int SEMAPHORE;
+//define SEM_ERROR -1
+
+#elif defined(SEM_POSIX)
+
+#define SEM_ERROR ((void *)(-1))
+typedef	void* SEMAPHORE_T;
+
+#else /* ! SEM_WIN32 */
+
+typedef int SEMAPHORE;
+#define SEMAPHORE_T int
+#define SEM_ERROR -1
+
+#endif /* SEM_WIN32 */
+
+#endif /* !APSTUDIO_READONLY_SYMBOLS */
+
+#ifndef XP_CPLUSPLUS
+#ifdef __cplusplus
+#define XP_CPLUSPLUS
+#endif /* __cplusplus */
+#endif /* !XP_CPLUSPLUS */
+
+#endif /* BASE_SYSTEMS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/systhr.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,182 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * systhr.c: Abstracted threading mechanisms
+ * 
+ * Rob McCool
+ */
+
+
+#include "systhr.h"
+#include "ereport.h"
+
+#include "prinit.h"
+#include "prthread.h"
+#include "private/pprthred.h"
+
+#include "systems.h"
+
+#ifdef XP_UNIX
+#include <poll.h>
+#endif
+
+#ifdef THREAD_WIN32
+#include <process.h>
+
+typedef struct {
+    HANDLE hand;
+    DWORD id;
+} sys_thread_s;
+
+#endif
+
+#define DEFAULT_STACKSIZE (64*1024)
+
+static unsigned long _systhr_stacksize = DEFAULT_STACKSIZE;
+
+NSAPI_PUBLIC 
+void systhread_set_default_stacksize(unsigned long size)
+{
+	_systhr_stacksize = size;
+}
+
+NSAPI_PUBLIC 
+SYS_THREAD systhread_start(int prio, int stksz, thrstartfunc fn, void *arg)
+{
+    PRThread *ret = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))fn,
+				    (void *)arg, (PRThreadPriority)prio, 
+				    PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
+                                    stksz ? stksz : _systhr_stacksize);
+    return (void *) ret;
+}
+
+
+NSAPI_PUBLIC SYS_THREAD systhread_current(void)
+{
+    return PR_GetCurrentThread();
+}
+
+NSAPI_PUBLIC void systhread_yield(void)
+{
+    PR_Sleep(PR_INTERVAL_NO_WAIT);
+}
+
+
+NSAPI_PUBLIC void systhread_timerset(int usec)
+{
+   /* This is an interesting problem.  If you ever do turn on interrupts
+    * on the server, you're in for lots of fun with NSPR Threads
+   PR_StartEvents(usec); */
+}
+
+
+NSAPI_PUBLIC 
+SYS_THREAD systhread_attach(void)
+{
+    PRThread *ret;
+    ret = PR_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL);
+
+    return (void *) ret;
+}
+
+NSAPI_PUBLIC
+void systhread_detach(SYS_THREAD thr)
+{
+    /* XXXMB - this is not correct! */
+    PR_DetachThread();
+}
+
+NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
+{
+    PR_Interrupt((PRThread *)thr);
+}
+
+NSAPI_PUBLIC void systhread_sleep(int milliseconds)
+{
+#ifdef XP_WIN32
+    PR_Sleep(PR_MillisecondsToInterval(milliseconds));
+#else
+    /* poll() is more efficient than PR_Sleep() */
+    if (milliseconds > 0)
+        poll(NULL, NULL, milliseconds);
+#endif
+}
+
+NSAPI_PUBLIC void systhread_init(char *name)
+{
+    if (!PR_Initialized()) {
+        PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
+    }
+    // XXX: ruslan - this bug can potentially exist on all plafroms due to
+    //	possible priority inversion on NSPR spin locks. This code will
+    //	need to be remove as we get new NSPR drop
+    // <WORKAROUND>
+    /* VB: This is to fix bug# 364813 coupled with NSPR not wanting to patch
+           their problems. The fix is to prevent NSPR itself from
+           using atomic stacks.
+    */
+    // ruslan: this problem exists on DEC also. We will roll it back when
+    //	we have the right fix from NSPR group. It has smth. to do with
+    //	atomic operations on DEC, it's an assembly code which is different
+    //	for every platform. NSPR_FD_CACHE_SIZE_HIGH env var will cause the
+    //	same effect as this fix. Debug version of NSPR always works as it doesn't
+    //  have FD stack.
+
+    int maxPRFdCache = 8192;
+    PR_SetFDCacheSize(0, maxPRFdCache);
+    // </WORKAROUND>
+}
+
+
+NSAPI_PUBLIC int systhread_newkey()
+{
+    uintn newkey;
+
+    PR_NewThreadPrivateIndex(&newkey, NULL);
+    return (newkey);
+}
+
+NSAPI_PUBLIC void *systhread_getdata(int key)
+{
+    return PR_GetThreadPrivate(key);
+}
+
+NSAPI_PUBLIC void systhread_setdata(int key, void *data)
+{
+    PR_SetThreadPrivate(key, data);
+}
+
+NSAPI_PUBLIC void systhread_dummy(void)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/systhr.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,113 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_SYSTHR_H
+#define BASE_SYSTHR_H
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * systhr.h: Abstracted threading mechanisms
+ * 
+ * Rob McCool
+ */
+
+#ifndef NETSITE_H
+#include "../daemon/netsite.h"
+#include "../public/nsapi.h"
+#include "nspr.h"
+#endif /* !NETSITE_H */
+
+#define THREAD_ANY
+#ifdef THREAD_ANY
+
+/* --- Begin function prototypes --- */
+
+#define INTNSAPI
+#ifdef INTNSAPI
+
+NSPR_BEGIN_EXTERN_C
+
+NSAPI_PUBLIC
+SYS_THREAD INTsysthread_start(int prio, int stksz, thrstartfunc fn, void *arg);
+
+NSAPI_PUBLIC SYS_THREAD INTsysthread_current(void);
+
+NSAPI_PUBLIC void INTsysthread_yield(void);
+
+NSAPI_PUBLIC SYS_THREAD INTsysthread_attach(void);
+
+NSAPI_PUBLIC void INTsysthread_detach(SYS_THREAD thr);
+
+NSAPI_PUBLIC void INTsysthread_terminate(SYS_THREAD thr);
+
+NSAPI_PUBLIC void INTsysthread_sleep(int milliseconds);
+
+NSAPI_PUBLIC void INTsysthread_init(char *name);
+
+NSAPI_PUBLIC void INTsysthread_timerset(int usec);
+
+NSAPI_PUBLIC int INTsysthread_newkey(void);
+
+NSAPI_PUBLIC void *INTsysthread_getdata(int key);
+
+NSAPI_PUBLIC void INTsysthread_setdata(int key, void *data);
+
+NSAPI_PUBLIC 
+void INTsysthread_set_default_stacksize(unsigned long size);
+
+NSPR_END_EXTERN_C
+
+/* --- End function prototypes --- */
+
+#define systhread_start INTsysthread_start
+#define systhread_current INTsysthread_current
+#define systhread_yield INTsysthread_yield
+#define systhread_attach INTsysthread_attach
+#define systhread_detach INTsysthread_detach
+#define systhread_terminate INTsysthread_terminate
+#define systhread_sleep INTsysthread_sleep
+#define systhread_init INTsysthread_init
+#define systhread_timerset INTsysthread_timerset
+#define systhread_newkey INTsysthread_newkey
+#define systhread_getdata INTsysthread_getdata
+#define systhread_setdata INTsysthread_setdata
+#define systhread_set_default_stacksize INTsysthread_set_default_stacksize
+
+#endif /* INTNSAPI */
+
+#endif /* THREAD_ANY */
+
+#endif /* !BASE_SYSTHR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/thrpool.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,122 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "thrpool.h"
+
+
+
+threadpool_t* threadpool_new(int n) {
+    threadpool_t *pool = malloc(sizeof(threadpool_t));
+    pool->queue = NULL;
+    pool->queue_len = 0;
+
+    pthread_mutex_init(&pool->queue_lock, NULL);
+    pthread_mutex_init(&pool->avlbl_lock, NULL);
+    pthread_cond_init(&pool->available, NULL);
+
+    /* create pool threads */
+    for(int i=0;i<n;i++) {
+        pthread_t t;
+        if (pthread_create(&t, NULL, threadpool_func, pool) != 0) {
+            perror("Error: threadpool_new: pthread_create");
+            return NULL;
+        }
+    }
+
+    return pool;
+}
+
+void* threadpool_func(void *data) {
+    threadpool_t *pool = (threadpool_t*)data;
+
+    for(;;) {
+        threadpool_job *job = threadpool_get_job(pool);
+        if(job == NULL) {
+            break;
+        }
+
+        job->callback(job->data);
+
+        free(job);
+    }
+    return NULL;
+}
+
+threadpool_job* threadpool_get_job(threadpool_t *pool) {
+    pthread_mutex_lock(&pool->queue_lock);
+
+    threadpool_job *job = NULL;
+    while(job == NULL) {
+        if(pool->queue_len == 0) {
+            pthread_cond_wait(&pool->available, &pool->queue_lock);
+            continue;
+        } else {
+            pool_queue_t *q = pool->queue;
+            job = q->job;
+            pool->queue = q->next;
+            pool->queue_len--;
+            free(q);
+        }
+    }
+
+    pthread_mutex_unlock(&pool->queue_lock);
+
+    return job;
+}
+
+void threadpool_run(threadpool_t *pool, job_callback_f func, void *data) {
+    threadpool_job *job = malloc(sizeof(threadpool_job));
+    job->callback = func;
+    job->data = data;
+
+    pool_queue_t *q = malloc(sizeof(pool_queue_t));
+    q->job = job;
+    q->next = NULL;
+
+    pthread_mutex_lock(&pool->queue_lock);
+    if(pool->queue == NULL) {
+        pool->queue = q;
+    } else {
+        pool_queue_t *last_elem = pool->queue;
+        while(last_elem->next != NULL) {
+            last_elem = last_elem->next;
+        }
+        last_elem->next = q;
+    }
+    pool->queue_len++;
+
+    if(pool->queue_len == 1) {
+        pthread_cond_signal(&pool->available);
+    }
+
+    pthread_mutex_unlock(&pool->queue_lock);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/thrpool.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,71 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THREADPOOL_H
+#define	THREADPOOL_H
+
+#include <pthread.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct _pool_queue pool_queue_t;
+typedef struct _thread_pool {
+    pthread_mutex_t queue_lock;
+    pthread_mutex_t avlbl_lock;
+    pthread_cond_t  available;
+    int             queue_len;
+    pool_queue_t    *queue;
+} threadpool_t;
+
+typedef void*(*job_callback_f)(void *data);
+typedef struct _threadpool_job {
+    job_callback_f  callback;
+    void            *data;
+} threadpool_job;
+
+struct _pool_queue {
+    threadpool_job   *job;
+    pool_queue_t     *next;
+};
+
+
+threadpool_t* threadpool_new(int n);
+
+void* threadpool_func(void *data);
+
+threadpool_job* threadpool_get_job(threadpool_t *pool);
+
+void threadpool_run(threadpool_t *pool, job_callback_f func, void *data);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* THREADPOOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/uri.cpp	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,561 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef XP_WIN32
+#define _MBCS
+#include <windows.h>
+#include <mbctype.h>
+#endif
+
+#include "util.h"
+#include "pool.h"
+//include "frame/conf_api.h"
+//include "support/stringvalue.h"
+
+#ifdef XP_WIN32
+static PRBool _getfullpathname = -1;
+#endif /* XP_WIN32 */
+
+/* --------------------------- util_uri_is_evil --------------------------- */
+
+static inline int allow_dbcs_uri()
+{
+    /*
+    static int flagDbcsUri = -1;
+    if (flagDbcsUri == -1) {
+        flagDbcsUri = StringValue::getBoolean(conf_findGlobal("DbcsUri"));
+    }
+    return flagDbcsUri;
+    */
+    return PR_FALSE;
+}
+
+#ifdef XP_WIN32
+void set_fullpathname(PRBool b)
+{
+    _getfullpathname = b;
+}
+#endif  /*XP_WIN32*/
+
+NSAPI_PUBLIC int util_uri_is_evil_internal(const char *t, int allow_tilde, int allow_dot_dir)
+{
+#ifdef XP_WIN32
+    int flagDbcsUri = allow_dbcs_uri();
+#endif // XP_WIN32
+    PRBool flagEmptySegment = PR_FALSE;
+    register int x;
+
+    for (x = 0; t[x]; ++x) {
+        if (t[x] == '/') {
+            if (flagEmptySegment)
+                return 1; // "/;a/b"
+#ifdef XP_WIN32
+            if (t[x+1] == '/' && x != 0)
+#else
+            if (t[x+1] == '/')
+#endif
+                return 1;
+            if (t[x+1] == ';')
+                flagEmptySegment = PR_TRUE; // "/;a/b" is evil, "/a/;b" is not
+            if (t[x+1] == '.') {
+                /* "." at end of line is always prohibited */
+                if (t[x+2] == '\0')
+                    return 1;
+
+                /* "." as a path segment is prohibited conditionally */
+                if (!allow_dot_dir && (t[x+2] == '/' || t[x+2] == ';'))
+                    return 1;
+
+                /* ".." as a path segment is always prohibited */
+                if (t[x+2] == '.' && (t[x+3] == '/' || t[x+3] == ';' || t[x+3] == '\0'))
+                    return 1;
+            }
+        }
+#ifdef XP_WIN32
+        // Don't allow '~' in the filename.  On some filesystems a long name
+        // (e.g. longfilename.htm) can be accessed using '~' bypassing any ACL
+        // checks (e.g. longfi~1.htm).
+        if (!allow_tilde && (t[x] == '~')) {
+            return 1;
+        }
+
+        // Do not allow ':' apart from drive letter. Windows filestream
+        // will treat filename::$DATA as a plain file & display content.
+        // So block it to prevent source viewing vulnerability.
+        if ((t[x] == ':') && x > 1) {
+            return 1;
+        }
+
+        // On NT, the directory "abc...." is the same as "abc"
+        // The only cheap way to catch this globally is to disallow
+        // names with the trailing "."s.  Hopefully this is not over
+        // restrictive.
+        // Also trailing spaces in names can wreak havoc on ACL checks
+        // and name resolution.  Therefore, ban them on the end of a
+        // name.
+        if (((t[x] == '.') || (t[x] == ' ')) &&
+            ((t[x+1] == ';') || (t[x+1] == '/') || (t[x+1] == '\0')))
+        {
+            return 1;
+        }
+
+        // Skip past the second byte of two byte DBCS characters.  Bug 353999
+        if (flagDbcsUri && t[x+1] && IsDBCSLeadByte(t[x])) x++;
+#endif // XP_WIN32
+    }
+    return 0;
+}
+
+NSAPI_PUBLIC int util_uri_is_evil(const char *t)
+{
+    return util_uri_is_evil_internal(t, 0, 0);
+}
+
+
+/* -------------------- util_uri_unescape_and_normalize -------------------- */
+
+#ifdef XP_WIN32
+/* The server calls this function to unescape the URI and also normalize
+ * the uri.  Normalizing the uri converts all "\" characters in the URI
+ * and pathinfo portion to "/".  Does not touch "\" in query strings.
+ */
+NSAPI_PUBLIC
+int util_uri_unescape_and_normalize(pool_handle_t *pool, char *s, char *unnormalized)
+{
+    if(!(util_uri_unescape_strict(s)))
+        return 0;
+
+    if (unnormalized) strcpy(unnormalized, s);
+
+    if (_getfullpathname == -1)
+        _getfullpathname = (_getmbcp() != 0);
+
+    /* Get canonical filename Bugid: 4672869 */
+    if(_getfullpathname && strcmp(s, "*") && (*s == '/' ) ) {
+        char *pzAbsPath = NULL;
+        int pathlen = 0;
+        int len = 0;
+        int ret = 0;
+        if(!(pzAbsPath = util_canonicalize_uri(pool, s, strlen(s), NULL))) {
+            //Error canonicalizing; possibly pointing out of docroot
+            return 0;
+        }
+        char *pzPath = (char *)MALLOC(MAX_PATH + 1); /* reserved byte for trailing slash */
+        char *pzFilename = NULL;
+
+        /* If required length of the buffer(pzPath) is more than the allocated one i.e. MAX_PATH(neglecting the reserved byte for trailing slash), return BAD REQUEST. This will happen if length of uri is more than the specified uri length(257) for MBCS windows */
+        if(!(ret = GetFullPathName(pzAbsPath, MAX_PATH, pzPath, &pzFilename)) || ( ret > MAX_PATH)){
+            FREE(pzAbsPath);
+            FREE(pzPath);
+            return 0;
+        }
+        len = strlen(pzAbsPath);
+        pathlen = strlen( pzPath );
+
+        /*  GetFullPathName behaves differently in case of WINNT and WIN2K */
+        /* o/p string doesn't contain the trailing slash in case of WINNT */
+        /* if i/p is /foo/, we get o/p as c:\foo instead of c:\foo\ */
+        /* Checking if i/p has trailing slash and o/p doesn't have, then */
+        /* adding slash */
+        if ( pzAbsPath[len-1] == '/' && pzPath[pathlen-1] != '\\')
+            strcat( pzPath, "\\");
+        FREE(pzAbsPath);
+        pzFilename = strchr(pzPath, '\\');
+        if(!pzFilename) {
+            FREE(pzPath);
+            return 0;
+        }
+        strcpy(s, pzFilename);
+        FREE(pzPath);
+    }
+
+    util_uri_normalize_slashes(s);
+
+    return 1;
+}
+#endif /* XP_WIN32 */
+
+
+/* ---------------------- util_uri_normalize_slashes ---------------------- */
+
+void util_uri_normalize_slashes(char *s)
+{
+#ifdef XP_WIN32
+    int flagDbcsUri = allow_dbcs_uri();
+
+    while (*s) {
+        if (*s == '\\') {
+            // Normalize '\\' to '/'
+            *s = '/';
+        } else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0])) {
+            // Skip past two byte DBCS characters.  Bug 353999
+            s++;
+        }
+        s++;
+    }
+#endif
+}
+
+
+/* --------------------------- util_uri_escape ---------------------------- */
+/*
+NSAPI_PUBLIC char *util_uri_escape(char *od, const char *s)
+{
+    int flagDbcsUri = allow_dbcs_uri();
+    char *d;
+
+    if (!od)
+        od = (char *) MALLOC((strlen(s)*3) + 1);
+    d = od;
+
+    while (*s) {
+        if (strchr("% ?#:+&*\"'<>\r\n", *s)) {
+            util_sprintf(d, "%%%02x", (unsigned char)*s);
+            ++s; d += 3;
+        }
+#ifdef XP_WIN32
+        else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
+#else
+        // Treat any character with the high bit set as a DBCS lead byte
+        else if (flagDbcsUri && s[1] && (s[0] & 0x80))
+#endif
+	{
+            // Escape the second byte of DBCS characters.  The first byte will
+            // have been escaped already.  IE translates all unescaped '\\'s
+            // into '/'.
+            // Bug 353999
+            util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
+            s += 2; d += 6;
+        }
+        else if (0x80 & *s) {
+            util_sprintf(d, "%%%02x", (unsigned char)*s);
+            ++s; d += 3;
+        } else {
+            *d++ = *s++;
+        }
+    }
+    *d = '\0';
+    return od;
+}
+*/
+
+
+/* --------------------------- util_url_escape ---------------------------- */
+/*
+NSAPI_PUBLIC char *util_url_escape(char *od, const char *s)
+{
+    int flagDbcsUri = allow_dbcs_uri();
+    char *d;
+
+    if (!od)
+        od = (char *) MALLOC((strlen(s)*3) + 1);
+    d = od;
+
+    while (*s) {
+        if (strchr("% +*\"'<>\r\n", *s)) {
+            util_sprintf(d, "%%%02x", (unsigned char)*s);
+            ++s; d += 3;
+        }
+#ifdef XP_WIN32
+        else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
+#else
+        // Treat any character with the high bit set as a DBCS lead byte
+        else if (flagDbcsUri && s[1] && (s[0] & 0x80))
+#endif
+	{
+            // Escape the second byte of DBCS characters.  The first byte will
+            // have been escaped already.  IE translates all unescaped '\\'s
+            // into '/'.
+            // Bug 353999
+            util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
+            s += 2; d += 6;
+        }
+        else if (0x80 & *s) {
+            util_sprintf(d, "%%%02x", (unsigned char)*s);
+            ++s; d += 3;
+        } else {
+            *d++ = *s++;
+        }
+    }
+    *d = '\0';
+    return od;
+}
+*/
+
+/* ------------------------- util_uri_strip_params ------------------------- */
+
+NSAPI_PUBLIC char* util_uri_strip_params(char *uri)
+{
+    // As per RFC2396, URI path segments can contain parameters beginning with
+    // ';'.  These parameters must be removed from the ppath.  Bug 418271
+    char* out;
+    if (out = strchr(uri, ';')) {
+        char* in = out;
+        while (*in) {
+            if (*in == ';') {
+                // Skip past parameter
+                do in++; while (*in && *in != '/');
+            } else {
+                // Copy non-parameter path data
+                *out++ = *in++;
+            }
+        }
+        *out = 0;
+    }
+    return uri;
+}
+
+
+/* ------------------------ util_canonicalize_uri ------------------------- */
+
+/*
+ * rewrite rules:
+ *   //                       ->  '/'
+ *   /./                      ->  '/'
+ *   /.\0                     ->  '/'
+ *   /foo/../                 ->  '/'
+ *   /foo/..\0                ->  '/'
+ *
+ * Allocate a new string, as otherwise replacing in-line would impact the
+ * RequestURI, i.e. original URI in the request.
+ * Some guidelines in: http://www.ietf.org/rfc/rfc2396.txt
+ *      Uniform Resource Identifiers (URI): Generic Syntax
+ */
+NSAPI_PUBLIC char* util_canonicalize_uri(pool_handle_t *pool, const char *uri, int len, int *pcanonlen)
+{
+    PRBool success = PR_TRUE;
+    const char *in_ptr = uri;
+    int in = 0;
+    int in_len = len;
+
+    PR_ASSERT(uri != NULL);
+
+    char* canonPath = (char *)pool_malloc(pool, in_len+1);
+    char* out_ptr = canonPath;
+
+    if (!canonPath) {
+        success = PR_FALSE;
+        goto done;
+    }
+
+
+    /* in goes from 0 .. sURIPath.len-1; out_ptr points to
+     * space where next char from input would be copied to
+     */
+    while (in < in_len) {
+
+        /* If the character isn't '/' then copy it out and move on*/
+        if (in_ptr[0] != '/') {
+            *out_ptr++ = *in_ptr++;
+            in++;
+            continue;
+        }
+
+        /* found '/' and reached end of sURIPath, done */
+        if (in+1 >= in_len) {
+            *out_ptr++ = *in_ptr++;
+            in++;
+            break;
+        }
+
+        /* we have '/' and there are more chars in the string */
+        switch(in_ptr[1]) {
+        case '/':
+            /*  '//' => '/'  */
+            in_ptr++;
+            in++;
+            break;
+
+        case '.':
+            /* we have "/." so far */
+            if (in+2 >= in_len) {
+                /*  the string ends after this; basically ignore '.'
+                 *  make sure the ending / is transferred to output.
+                 */
+                *out_ptr++ = *in_ptr++;
+                goto done;
+            }
+
+            /* more chars after "/."; see if it is a '/' */
+            if (in_ptr[2] == '/') {
+                /* in deed, compact "/./" => "/"; */
+                in_ptr += 2;
+                in += 2;
+                break;
+            }
+
+            if (in_ptr[2] != '.') {
+                /* "/.x" where x is not '.'; copy as is */
+                *out_ptr++ = *in_ptr++;
+                in++;
+                break;
+            }
+
+            /* we have "/.." so far. see if we have either string
+             * ending after this or '/' following.
+             */
+            if (in+3 < in_len && in_ptr[3] != '/' && in_ptr[3] != ';') {
+                /* we have "/..x" here; so copy as is */
+                *out_ptr++ = *in_ptr++;
+                in++;
+            }
+            else {
+                /* we have "foo/../" or "foo/.." at the end; */
+                if (out_ptr == canonPath) {
+                    /* oops, we found "/../" pointing out of docroot */
+                    success = PR_FALSE;
+                    goto done;
+                }
+
+                /* remove the previous segment in the output */
+                for (out_ptr--;
+                     out_ptr != canonPath && out_ptr[0] != '/';
+                     out_ptr--); /* Empty Loop */
+
+                /* point to '/' if the last segment ended with .. then
+                 * leave the '/' before the previous segment.
+                 */
+                if(in+3 == in_len)
+                    out_ptr++;
+
+                /* skip the input as well */
+                in_ptr += 3;
+                in += 3;
+            }
+            break;
+
+        default:
+            /* If we already have '/' at out_ptr we donot need to copy */
+            if (out_ptr == canonPath || *(out_ptr-1) != '/')
+                *out_ptr++ = *in_ptr;
+            in_ptr++; in++;
+            break;
+        }
+    }
+
+done:
+    int canonLen = 0;
+
+    if (success) {
+        /* the path looks fine; return the canonicalized form */
+        canonLen = out_ptr - canonPath;
+        canonPath[canonLen] = '\0';
+    } else {
+        /* error canonicalizing */
+        pool_free(pool, canonPath);
+        canonPath = NULL;
+    }
+
+    if (pcanonlen)
+        *pcanonlen = canonLen;
+
+    return canonPath;
+}
+
+
+/* ---------------------- util_canonicalize_redirect ---------------------- */
+
+NSAPI_PUBLIC char* util_canonicalize_redirect(pool_handle_t *pool, const char *baseUri, const char *newUri)
+{
+    PR_ASSERT(baseUri != NULL);
+
+    if (*newUri == '/')
+        return util_canonicalize_uri(pool, newUri, strlen(newUri), NULL);
+
+    int bLen = strlen(baseUri);
+    if (bLen > 0 && baseUri[bLen - 1] != '/') {
+        while (bLen > 0 && baseUri[bLen - 1] != '/')
+            bLen--;
+    }
+
+    int pLen = strlen(newUri) + bLen + 1; // 1 for slash
+    char *pUri = (char *)pool_malloc(pool, pLen + 1);
+    if (!pUri)
+        return PR_FALSE;
+
+    memcpy(pUri, baseUri, bLen);
+    pUri[bLen] = '/';
+    strcpy(pUri + bLen + 1, newUri);
+
+    char *rval = util_canonicalize_uri(pool, pUri, pLen, NULL);
+    pool_free(pool, pUri);
+
+    return rval;
+}
+
+
+/* ------------------------ util_host_port_suffix ------------------------- */
+
+NSAPI_PUBLIC char *util_host_port_suffix(char *h)
+{
+    return (char *)util_host_port_suffix((const char *)h);
+}
+
+const char *util_host_port_suffix(const char *h)
+{
+    /* Return a pointer to the colon preceding the port number in a hostname.
+     *
+     * util_host_port_suffix("foo.com:80") = ":80"
+     * util_host_port_suffix("foo.com") = NULL
+     * util_host_port_suffix("[::]:80") = ":80"
+     * util_host_port_suffix("[::]") = NULL
+     */
+
+    if (h == NULL)
+        return h;
+
+    for (;;) {
+        /* Find end of host, beginning of ":port", or an IPv6 address */
+        for (;;) {
+            register char c = *h;
+
+            if (c == '\0')
+                return NULL; /* end of host, no port found */
+
+            if (c == '/')
+                return NULL; /* end of host, no port found */
+
+            if (c == ':')
+                return h; /* found port */
+
+            if (c == '[')
+                break; /* skip IPv6 address */
+
+            h++;
+        }
+
+        /* Skip IPv6 address */
+        while (*h != '\0' && *h != ']')
+            h++;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/util.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,133 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * util.c: A hodge podge of utility functions and standard functions which 
+ *         are unavailable on certain systems
+ * 
+ * Rob McCool
+ */
+
+#ifdef XP_UNIX
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include "prthread.h"
+#endif /* XP_UNIX */
+
+
+#include "nspr.h"
+#include "../public/nsapi.h"
+
+#include "util.h"
+
+/*
+NSAPI_PUBLIC int util_getboolean(const char *v, int def) {
+    if(v[0] == 'T' || v[0] == 't') {
+        return 1;
+    }
+    if(v[0] == 'F' || v[0] == 'f') {
+        return 0;
+    }
+    return def;
+}
+*/
+
+NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def) {
+    if(v[0] == 'T' || v[0] == 't') {
+        return 1;
+    }
+    if(v[0] == 'F' || v[0] == 'f') {
+        return 0;
+    }
+    return def;
+}
+
+
+/* ------------------------------ util_itoa ------------------------------- */
+/*
+NSAPI_PUBLIC int util_itoa(int i, char *a)
+{
+    int len = util_i64toa(i, a);
+
+    PR_ASSERT(len < UTIL_ITOA_SIZE);
+
+    return len;
+}
+*/
+NSAPI_PUBLIC int INTutil_itoa(int i, char *a) {
+    return INTutil_i64toa(i, a);
+}
+
+
+/* ----------------------------- util_i64toa ------------------------------ */
+
+/*
+ * Assumption: Reversing the digits will be faster in the general case
+ * than doing a log10 or some nasty trick to find the # of digits.
+ */
+
+NSAPI_PUBLIC int INTutil_i64toa(PRInt64 i, char *a)
+{
+    register int x, y, p;
+    register char c;
+    int negative;
+
+    negative = 0;
+    if(i < 0) {
+        *a++ = '-';
+        negative = 1;
+        i = -i;
+    }
+    p = 0;
+    while(i > 9) {
+        a[p++] = (i%10) + '0';
+        i /= 10;
+    }
+    a[p++] = i + '0';
+
+    if(p > 1) {
+        for(x = 0, y = p - 1; x < y; ++x, --y) {
+            c = a[x];
+            a[x] = a[y];
+            a[y] = c;
+        }
+    }
+    a[p] = '\0';
+
+    //PR_ASSERT(p + negative < UTIL_I64TOA_SIZE);
+
+    return p + negative;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/util/util.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,356 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer. 
+ * Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution. 
+ *
+ * Neither the name of the  nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without 
+ * specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASE_UTIL_H
+#define BASE_UTIL_H
+
+#include "../daemon/netsite.h"
+
+#ifndef NOINTNSAPI
+#define INTNSAPI
+#endif /* !NOINTNSAPI */
+
+/*
+ * util.h: A hodge podge of utility functions and standard functions which 
+ *         are unavailable on certain systems
+ * 
+ * Rob McCool
+ */
+
+/* Needed for various reentrant functions */
+#define DEF_CTIMEBUF 26
+#define DEF_ERRBUF 256
+#define DEF_PWBUF 1024
+
+#ifndef BASE_BUFFER_H
+//include "buffer.h"    /* filebuf for getline */
+#endif /* !BASE_BUFFER_H */
+
+/*
+ * UTIL_ITOA_SIZE is the minimum size for buffers passed to util_itoa().
+ */
+#define UTIL_ITOA_SIZE 12
+
+/*
+ * UTIL_I64TOA_SIZE is the minimum size for buffers passed to util_i64toa().
+ */
+#define UTIL_I64TOA_SIZE 21
+
+/* --- Begin common function prototypes --- */
+
+#ifdef INTNSAPI
+
+NSPR_BEGIN_EXTERN_C
+
+NSAPI_PUBLIC
+int INTutil_init_PRNetAddr(PRNetAddr * naddr, char * ipstr, int iplen, int type);
+
+NSAPI_PUBLIC
+int INTutil_getline(filebuffer *buf, int lineno, int maxlen, char *l);
+
+NSAPI_PUBLIC char **INTutil_env_create(char **env, int n, int *pos);
+
+NSAPI_PUBLIC char *INTutil_env_str(const char *name, const char *value);
+
+NSAPI_PUBLIC void INTutil_env_replace(char **env, const char *name, const char *value);
+
+NSAPI_PUBLIC void INTutil_env_free(char **env);
+
+NSAPI_PUBLIC char **INTutil_env_copy(char **src, char **dst);
+
+NSAPI_PUBLIC char *INTutil_env_find(char **env, const char *name);
+
+NSAPI_PUBLIC char **util_argv_parse(const char *cmdline);
+
+NSAPI_PUBLIC char *INTutil_hostname(void);
+
+NSAPI_PUBLIC int INTutil_chdir2path(char *path);
+
+NSAPI_PUBLIC int INTutil_chdir(const char *path);
+
+NSAPI_PUBLIC char *INTutil_getcwd(void);
+
+NSAPI_PUBLIC int INTutil_is_mozilla(char *ua, char *major, char *minor);
+
+NSAPI_PUBLIC int INTutil_is_url(const char *url);
+
+NSAPI_PUBLIC int INTutil_mstr2num(const char *s);
+
+NSAPI_PUBLIC int INTutil_later_than(const struct tm *lms, const char *ims);
+
+NSAPI_PUBLIC int INTutil_time_equal(const struct tm *lms, const char *ims);
+
+NSAPI_PUBLIC int INTutil_str_time_equal(const char *t1, const char *t2);
+
+NSAPI_PUBLIC int INTutil_uri_is_evil(const char *t);
+
+NSAPI_PUBLIC int INTutil_uri_is_evil_internal(const char *t, int, int);
+
+NSAPI_PUBLIC void INTutil_uri_parse(char *uri);
+
+#ifdef XP_WIN32
+NSAPI_PUBLIC int INTutil_uri_unescape_and_normalize(pool_handle_t *pool, char *s, char *unnormalized);
+#endif /* XP_WIN32 */
+
+NSAPI_PUBLIC void INTutil_uri_normalize_slashes(char *s);
+
+NSAPI_PUBLIC void INTutil_uri_unescape		(char *s);
+
+NSAPI_PUBLIC int INTutil_uri_unescape_strict		(char *s);
+
+NSAPI_PUBLIC int  INTutil_uri_unescape_plus (const char *src, char *trg, int len);
+
+NSAPI_PUBLIC char *INTutil_uri_escape(char *d, const char *s);
+
+NSAPI_PUBLIC char *INTutil_uri_strip_params(char *uri);
+
+NSAPI_PUBLIC char* util_canonicalize_uri(pool_handle_t *pool, const char *uri, int len, int *pcanonlen);
+
+NSAPI_PUBLIC char* util_canonicalize_redirect(pool_handle_t *pool, const char *baseUri, const char *newUri);
+
+NSAPI_PUBLIC char *INTutil_url_escape(char *d, const char *s);
+
+NSAPI_PUBLIC char *INTutil_sh_escape(char *s);
+
+NSAPI_PUBLIC int INTutil_mime_separator(char *sep);
+
+NSAPI_PUBLIC int INTutil_itoa(int i, char *a);
+
+NSAPI_PUBLIC int INTutil_i64toa(PRInt64 i, char *a);
+
+
+NSAPI_PUBLIC
+int INTutil_vsprintf(char *s, register const char *fmt, va_list args);
+
+NSAPI_PUBLIC int INTutil_sprintf(char *s, const char *fmt, ...);
+
+NSAPI_PUBLIC int INTutil_vsnprintf(char *s, int n, register const char *fmt, 
+                                  va_list args);
+
+NSAPI_PUBLIC int INTutil_snprintf(char *s, int n, const char *fmt, ...);
+
+NSAPI_PUBLIC int util_strlftime(char *dst, size_t dstsize, const char *format, const struct tm *t);
+
+NSAPI_PUBLIC int INTutil_strftime(char *s, const char *format, const struct tm *t);
+
+NSAPI_PUBLIC char *INTutil_strtok(char *s1, const char *s2, char **lasts);
+
+NSAPI_PUBLIC struct tm *INTutil_localtime(const time_t *clock, struct tm *res);
+
+NSAPI_PUBLIC char *INTutil_ctime(const time_t *clock, char *buf, int buflen);
+
+NSAPI_PUBLIC char *INTutil_strerror(int errnum, char *msg, int buflen);
+
+NSAPI_PUBLIC struct tm *INTutil_gmtime(const time_t *clock, struct tm *res);
+
+NSAPI_PUBLIC char *INTutil_asctime(const struct tm *tm,char *buf, int buflen);
+
+NSAPI_PUBLIC char *INTutil_cookie_find(char *cookie, const char *name);
+
+NSAPI_PUBLIC char *INTutil_cookie_next(char *cookie, char **name, char **value);
+
+NSAPI_PUBLIC char *INTutil_cookie_next_av_pair(char *cookie, char **name, char **value);
+
+NSAPI_PUBLIC void INTutil_random(void *buf, size_t sz);
+
+NSAPI_PUBLIC PRBool INTutil_format_http_version(const char *v, int *protv_num, char *buffer, int size);
+
+NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def);
+NSAPI_PUBLIC PRIntervalTime INTutil_getinterval(const char *v, PRIntervalTime def);
+
+#ifdef NEED_STRCASECMP
+NSAPI_PUBLIC int INTutil_strcasecmp(const char *one, const char *two);
+#endif /* NEED_STRCASECMP */
+
+#ifdef NEED_STRNCASECMP
+NSAPI_PUBLIC int INTutil_strncasecmp(const char *one, const char *two, int n);
+#endif /* NEED_STRNCASECMP */
+
+NSAPI_PUBLIC char *INTutil_strcasestr(char *str, const char *substr);
+
+NSAPI_PUBLIC size_t util_strlcpy(char *dst, const char *src, size_t dstsize);
+
+NSAPI_PUBLIC size_t util_strlcat(char *dst, const char *src, size_t dstsize);
+
+NSAPI_PUBLIC char *INTutil_uuencode(const char *src, int len);
+
+NSAPI_PUBLIC char *INTutil_uudecode(const char *src);
+
+NSAPI_PUBLIC char *util_strlower(char *s);
+
+NSAPI_PUBLIC char *util_decrement_string(char *s);
+
+NSAPI_PUBLIC PRInt64 util_atoi64(const char *a);
+
+NSAPI_PUBLIC char *util_html_escape(const char *s);
+
+NSAPI_PUBLIC int util_qtoi(const char *q, const char **p);
+
+/* --- End common function prototypes --- */
+
+/* --- Begin Unix-only function prototypes --- */
+
+#ifdef XP_UNIX
+
+NSAPI_PUBLIC int INTutil_can_exec(struct stat *finfo, uid_t uid, gid_t gid);
+
+NSAPI_PUBLIC
+struct passwd *INTutil_getpwnam(const char *name, struct passwd *result,
+                               char *buffer,  int buflen);
+
+NSAPI_PUBLIC
+struct passwd *INTutil_getpwuid(uid_t uid, struct passwd *result,
+                                char *buffer, int buflen);
+
+NSAPI_PUBLIC pid_t INTutil_waitpid(pid_t pid, int *statptr, int options);
+
+#endif /* XP_UNIX */
+
+/* --- End Unix-only function prototypes --- */
+
+/* --- Begin Windows-only function prototypes --- */
+
+#ifdef XP_WIN32
+
+NSAPI_PUBLIC
+VOID INTutil_delete_directory(char *FileName, BOOL delete_directory);
+
+#endif /* XP_WIN32 */
+
+/* --- End Windows-only function prototypes --- */
+
+NSPR_END_EXTERN_C
+
+#ifdef __cplusplus
+
+NSAPI_PUBLIC char *util_host_port_suffix(char *h);
+
+NSAPI_PUBLIC const char *util_host_port_suffix(const char *h);
+
+#endif
+
+#define util_init_PRNetAddr INTutil_init_PRNetAddr
+#define util_getline INTutil_getline
+#define util_env_create INTutil_env_create
+#define util_env_str INTutil_env_str
+#define util_env_replace INTutil_env_replace
+#define util_env_free INTutil_env_free
+#define util_env_copy INTutil_env_copy
+#define util_env_find INTutil_env_find
+#define util_hostname INTutil_hostname
+#define util_chdir2path INTutil_chdir2path
+#define util_chdir INTutil_chdir
+#define util_getcwd INTutil_getcwd
+#define util_is_mozilla INTutil_is_mozilla
+#define util_is_url INTutil_is_url
+#define util_mstr2num INTutil_mstr2num
+#define util_later_than INTutil_later_than
+#define util_time_equal INTutil_time_equal
+#define util_str_time_equal INTutil_str_time_equal
+#define util_uri_is_evil INTutil_uri_is_evil
+#define util_uri_is_evil_internal INTutil_uri_is_evil_internal
+#define util_uri_parse INTutil_uri_parse
+#ifdef XP_WIN32
+#define util_uri_unescape_and_normalize INTutil_uri_unescape_and_normalize
+#endif /* XP_WIN32 */
+#define util_uri_normalize_slashes INTutil_uri_normalize_slashes
+#define util_uri_unescape	   INTutil_uri_unescape
+#define util_uri_unescape_strict	   INTutil_uri_unescape_strict
+#define util_uri_unescape_plus INTutil_uri_unescape_plus
+
+#define util_uri_escape INTutil_uri_escape
+#define util_uri_strip_params INTutil_uri_strip_params
+#define util_url_escape INTutil_url_escape
+#define util_sh_escape INTutil_sh_escape
+#define util_mime_separator INTutil_mime_separator
+#define util_itoa INTutil_itoa
+#define util_i64toa INTutil_i64toa
+#define util_vsprintf INTutil_vsprintf
+#define util_sprintf INTutil_sprintf
+#define util_vsnprintf INTutil_vsnprintf
+#define util_snprintf INTutil_snprintf
+#define util_strftime INTutil_strftime
+#define util_strcasecmp INTutil_strcasecmp
+#define util_strncasecmp INTutil_strncasecmp
+#define util_strcasestr INTutil_strcasestr
+#define util_strtok INTutil_strtok
+#define util_localtime INTutil_localtime
+#define util_ctime INTutil_ctime
+#define util_strerror INTutil_strerror
+#define util_gmtime INTutil_gmtime
+#define util_asctime INTutil_asctime
+#define util_uuencode INTutil_uuencode
+#define util_uudecode INTutil_uudecode
+
+#ifdef XP_UNIX
+#define util_can_exec INTutil_can_exec
+#define util_getpwnam INTutil_getpwnam
+#define util_getpwuid INTutil_getpwuid
+#define util_waitpid INTutil_waitpid
+#endif /* XP_UNIX */
+
+#ifdef XP_WIN32
+#define util_delete_directory INTutil_delete_directory
+#endif /* XP_WIN32 */
+
+#ifdef NEED_STRCASECMP
+#define util_strcasecmp INTutil_strcasecmp
+#define strcasecmp INTutil_strcasecmp
+#endif /* NEED_STRCASECMP */
+
+#ifdef NEED_STRINGS_H /* usually for strcasecmp */
+#include <strings.h>
+#endif
+
+#ifdef NEED_STRNCASECMP
+#define util_strncasecmp INTutil_strncasecmp
+#define strncasecmp INTutil_strncasecmp
+#endif /* NEED_STRNCASECMP */
+
+#define util_cookie_find INTutil_cookie_find
+#define util_cookie_next INTutil_cookie_next
+#define util_cookie_next_av_pair INTutil_cookie_next_av_pair
+
+#define util_random INTutil_random
+#define util_format_http_version INTutil_format_http_version
+#define util_getboolean INTutil_getboolean
+#define util_getinterval INTutil_getinterval
+
+#ifdef XP_WIN32
+void set_fullpathname(PRBool b);
+#endif /* XP_WIN32 */
+#endif /* INTNSAPI */
+
+#endif /* !BASE_UTIL_H */
+
+
--- a/src/server/vserver.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "vserver.h"
-
-VirtualServer* vs_new() {
-    VirtualServer *vs = malloc(sizeof(VirtualServer));
-    vs->default_obj_name = NULL;
-    vs->objects = NULL;
-    vs->document_root = sstr("docs");
-    return vs;
-}
-
-
-
--- a/src/server/vserver.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef VSERVER_H
-#define	VSERVER_H
-
-#include "object.h"
-#include "nsapi.h"
-
-#include "sstring.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-struct VirtualServer {
-    char              *default_obj_name;
-    HTTPObjectConfig  *objects;
-
-    sstr_t            document_root;
-};
-
-VirtualServer* vs_new();
-
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* VSERVER_H */
-
--- a/src/server/webdav.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "webdav.h"
-#include "sstring.h"
-#include "pool.h"
-#include "pblock.h"
-
-#include "davparser.h"
-
-int webdav_service(pblock *pb, Session *sn, Request *rq) {
-    /* TODO:
-     * Dies ist die Implementierung für PROPFIND. Es sollte für jede webdav-
-     * Methode eine eigene Service-Funktion geben. Solange die anderen
-     * Methoden nicht implementiert werden, behandelt webdav_service nur
-     * PROPFIND.
-     */
-
-    /* TODO: clean up if errors occurs */
-
-    /* Get request body which contains the webdav XML request */
-    char   *xml_body;
-    size_t xml_len = 0;
-
-    char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
-    if(ctlen) {
-        xml_len = atoi(ctlen);
-    } else {
-        /* invalid request */
-        return REQ_ABORTED;
-    }
-
-    xml_body = pool_malloc(sn->pool, xml_len + 1);
-    xml_body[xml_len] = 0;
-    if(!xml_body) {
-        /* server error */
-        return REQ_ABORTED;
-    }
-
-    /* TODO: bug with multi reads */
-    int r = 0;
-    char *xb = xml_body;
-    size_t xl = xml_len;
-    while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
-        xb += r;
-        xl -= xml_len;
-    }
-
-    PropfindRequest *davrq = dav_parse_propfind(sn, rq, xml_body, xml_len);
-    davrq->sn = sn;
-    davrq->rq = rq;
-    davrq->propertyBackend = create_property_backend();
-    davrq->notFoundProps = NULL;
-    davrq->forbiddenProps = NULL;
-    davrq->out = sbuf_new(512);
-
-    /* write header */
-    sbuf_puts(davrq->out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
-    sbuf_puts(davrq->out, "<D:multistatus xmlns:D=\"DAV:\">\n");
-
-    /* get stat of file */
-    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
-    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
-
-    struct stat st;
-    if(stat(ppath, &st) != 0) {
-        perror("webdav_service: stat");
-        return REQ_ABORTED;
-    }
-    /* TODO: check for more modes */
-    if(S_ISDIR(st.st_mode)) {
-        DIR *dir = opendir(ppath);
-        if(dir == NULL) {
-            protocol_status(sn, rq, 500, NULL);
-            printf("webdav_service: DIR is null\n");
-            return REQ_ABORTED;
-        }
-
-        struct dirent *f;
-        while((f = readdir(dir)) != NULL) {
-            if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
-                continue;
-            }
-
-            sstr_t filename = sstr(f->d_name);
-            sstr_t _path = sstr(ppath);
-            sstr_t _uri = sstr(uri);
-
-            sstr_t newuri;
-            newuri.length = filename.length + _uri.length;
-            newuri.ptr = alloca(newuri.length + 1);
-            newuri = sstrncat(2, newuri, _uri, filename);
-
-            sstr_t newpath;
-            newpath.length = _path.length + filename.length;
-            newpath.ptr = alloca(newpath.length + 1);
-            newpath = sstrncat(2, newpath, _path, filename);
-
-            davrq->path = newpath.ptr;
-            davrq->uri = newuri.ptr;
-            dav_create_response(davrq);
-        }
-    }
-    davrq->path = ppath;
-    davrq->uri = uri;
-    dav_create_response(davrq);
-
-    sbuf_puts(davrq->out, "</D:multistatus>\n");
-
-    /* send buffer to client */
-    pblock_removekey(pb_key_content_type, rq->srvhdrs);
-    pblock_nvinsert("content-type", "text/xml", rq->srvhdrs);
-    pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs);
-
-    protocol_status(sn, rq, 207, NULL);
-    http_start_response(sn, rq);
-
-    net_write(sn->csd, davrq->out->ptr, davrq->out->length);
-
-    return REQ_PROCEED;
-}
-
-int dav_foreach_reqprop(UcxDlist *list, PropfindRequest *davrq) {
-    DavProperty *prop = list->data;
-    int error = 0;
-    
-    char *str = davrq->propertyBackend->get_property(
-            davrq->propertyBackend,
-            davrq,
-            davrq->path,
-            prop->xmlns,
-            prop->name,
-            &error);
-    if(str == NULL) {
-        UcxDlist **dl = NULL;
-        if(error == 404) {
-            dl = &davrq->notFoundProps;
-        } else {
-            dl = &davrq->forbiddenProps;
-        }
-        *dl = ucx_dlist_append(*dl, prop);
-    } else {
-        //printf("dav property: {%s|%s::%s\n", prop->xmlns, prop->name, str);
-        sbuf_puts(davrq->out, "<D:");
-        sbuf_puts(davrq->out, prop->name);
-        sbuf_puts(davrq->out, ">");
-        sbuf_puts(davrq->out, str);
-        sbuf_puts(davrq->out, "</D:");
-        sbuf_puts(davrq->out, prop->name);
-        sbuf_puts(davrq->out, ">\n");
-    }
-    return 0;
-}
-
-void dav_create_response(PropfindRequest *davrq) {
-    sbuf_puts(davrq->out, "<D:response>\n");
-
-    sbuf_puts(davrq->out, "<D:href>");
-    sbuf_puts(davrq->out, davrq->uri);
-    sbuf_puts(davrq->out, "</D:href>\n");
-
-    sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
-    
-    ucx_dlist_foreach(
-            davrq->properties,
-            (ucx_callback)dav_foreach_reqprop,
-            davrq);
-
-    sbuf_puts(davrq->out, "</D:prop>\n<D:status>HTTP/1.1 200 OK</D:status>\n");
-    sbuf_puts(davrq->out, "</D:propstat>\n");
-
-    /* 404 props */
-    sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
-    UcxDlist *dl = davrq->notFoundProps;
-    while(dl != NULL) {
-        DavProperty *nfp = dl->data;
-        sbuf_puts(davrq->out, "<D:");
-        sbuf_puts(davrq->out, nfp->name);
-        sbuf_puts(davrq->out, " />\n");
-        dl = dl->next;
-    }
-    sbuf_puts(davrq->out, "</D:prop>\n");
-    sbuf_puts(davrq->out, "<D:status>HTTP/1.1 404 Not Found</D:status>\n");
-    sbuf_puts(davrq->out, "</D:propstat>\n");
-
-    /* end */
-    sbuf_puts(davrq->out, "</D:response>\n");
-    
-}
-
-char* dav_get_property(
-        DAVPropertyBackend *b,
-        PropfindRequest *davrq,
-        char *path,
-        char *xmlns,
-        char *name,
-        int *error)
-{
-    DAVDefaultBackend *be = (DAVDefaultBackend*)b;
-    *error = 200;
-
-    if(strcmp(name, "getcontentlength") == 0) {
-        struct stat s;
-        if(stat(davrq->path, &s) != 0) {
-            *error = 403; /* really? */
-            return NULL;
-        }
-        if(S_ISDIR(s.st_mode)) {
-            *error = 404;
-            return NULL;
-        }
-        char *buf = pool_malloc(davrq->sn->pool, 24);
-        sprintf(buf, "%d", s.st_size);
-        return buf;
-    }
-
-    *error = 404;
-    return NULL;
-}
-
-DAVPropertyBackend* create_property_backend() {
-    DAVDefaultBackend *backend = malloc(sizeof(DAVDefaultBackend));
-    backend->backend.get_property = dav_get_property;
-    backend->path = NULL;
-    backend->s = 0;
-    return (DAVPropertyBackend*)backend;
-}
--- a/src/server/webdav.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WEBDAV_H
-#define	WEBDAV_H
-
-#include "nsapi.h"
-
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include "map.h"
-#include "dlist.h"
-#include "strbuf.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-typedef struct PropfindResponse PropfindResponse;
-typedef struct DAVPropertyBackend DAVPropertyBackend;
-
-typedef struct PropfindRequest   PropfindRequest;
-typedef struct DavProperty       DavProperty;
-
-struct PropfindRequest {
-    Session            *sn;
-    Request            *rq;
-
-    UcxDlist           *properties; /* DavProperty list */
-    int8_t             allprop;
-    int8_t             propname;
-
-    UcxDlist           *notFoundProps;
-    UcxDlist           *forbiddenProps;
-    DAVPropertyBackend *propertyBackend;
-
-    char               *path;
-    char               *uri;
-
-    sbuf_t             *out;
-};
-
-struct DavProperty {
-    char *xmlns;
-    char *name;
-};
-
-typedef char*(*prop_get_func)(
-        DAVPropertyBackend*,
-        PropfindRequest*,
-        char*,
-        char*,
-        char*,
-        int*);
-
-struct DAVPropertyBackend {
-    prop_get_func get_property;
-};
-
-int webdav_service(pblock *pb, Session *sn, Request *rq);
-
-void dav_create_response(PropfindRequest *davrq);
-
-int dav_foreach_reqprop(UcxDlist *list, PropfindRequest *davrq);
-
-char* dav_get_property(
-        DAVPropertyBackend *b,
-        PropfindRequest *davrq,
-        char *path,
-        char *xmlns,
-        char *name,
-        int *error);
-
-DAVPropertyBackend* create_property_backend();
-
-typedef struct {
-    DAVPropertyBackend backend;
-    char *path;
-    struct stat st;
-    int s;
-} DAVDefaultBackend;
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* WEBDAV_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/Makefile	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,44 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BUILD_ROOT = ../../../
+OBJ_DIR = $(BUILD_ROOT)build/
+
+CFLAGS  = -I/usr/include/mps -g
+LDFLAGS = 
+
+include objs.mk
+
+all: $(DAVOBJS)
+
+$(DAV_OBJPRE)%.o: %.c
+	cc -o $@ -c $(CFLAGS) $<
+
+$(DAV_OBJPRE)%.o: %.cpp
+	CC -o $@ -c $(CFLAGS) $<
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/davparser.cpp	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,91 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "davparser.h"
+
+#include "../util/pool.h"
+#include "../util/pblock.h"
+
+#include "saxhandler.h"
+
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+#include <xercesc/sax2/DefaultHandler.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/framework/MemBufInputSource.hpp>
+
+XERCES_CPP_NAMESPACE_USE;
+
+int xcinit = 0;
+
+PropfindRequest* dav_parse_propfind(
+        Session *sn,
+        Request *rq,
+        char *xml,
+        size_t len)
+{
+    if(!xcinit) {
+        /* TODO: create webdav module init function */
+        XMLPlatformUtils::Initialize();
+        xcinit = 1;
+    }
+    PropfindRequest *davrq = (PropfindRequest*)pool_malloc(
+            sn->pool,
+            sizeof(PropfindRequest));
+    davrq->allprop = 0;
+    davrq->propname = 0;
+    davrq->properties = NULL;
+    // create xml parser
+    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
+    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
+
+    PropfindHandler handler(davrq, sn->pool);
+    parser->setContentHandler(&handler);
+    parser->setErrorHandler(&handler);
+
+    MemBufInputSource source((XMLByte*)xml, (XMLSize_t)len, "wsid");
+    try {
+        parser->parse(source);
+    }
+    catch (const XMLException& e) {
+        printf("XMLException\n");
+        
+    }
+    catch (const SAXParseException& e) {
+        printf("SAXParseException\n");
+        
+    }
+    catch (...) {
+        printf("davaparser Exception\n");
+    }
+
+    
+    
+
+    return davrq;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/davparser.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,53 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAVPARSER_H
+#define	DAVPARSER_H
+
+#include "../public/nsapi.h"
+
+#include "../ucx/dlist.h"
+#include <inttypes.h>
+#include "webdav.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+PropfindRequest* dav_parse_propfind(
+        Session *sn,
+        Request *rq,
+        char *xml,
+        size_t len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* DAVPARSER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/objs.mk	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,38 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2011 Olaf Wintermann. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#   1. Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+DAV_SRC_DIR = server/safs/
+
+DAV_OBJPRE = $(OBJ_DIR)$(DAV_SRC_DIR)
+
+DAVOBJ = davparser.o
+DAVOBJ += saxhandler.o
+DAVOBJ += webdav.o
+
+DAVOBJS = $(DAVOBJ:%=$(DAV_OBJPRE)%)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/saxhandler.cpp	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../ucx/sstring.h"
+#include "../ucx/dlist.h"
+#include "../util/pool.h"
+
+#include "saxhandler.h"
+
+using std;
+
+PropfindHandler::PropfindHandler(PropfindRequest *rq, pool_handle_t *p) {
+    davrq = rq;
+    pool  = p;
+
+    davPropTag = false;
+    property = NULL;
+}
+
+PropfindHandler::~PropfindHandler() {
+    
+}
+
+void PropfindHandler::startElement(
+        const XMLCh *const uri,
+        const XMLCh* const localname,
+        const XMLCh* const qname,
+        const Attributes& attrs)
+{
+    char *ns  = XMLString::transcode(uri);
+    char *name = XMLString::transcode(localname);
+    
+    if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
+        davPropTag = true;
+    } else if(davPropTag && property == NULL) {
+        //property = (DavProperty*)pool_malloc(pool, sizeof(DavProperty));
+        property = (DavProperty*)malloc(sizeof(DavProperty));
+        /* Ultra TODO: pool_malloc makes big mistakes!! */
+
+        size_t nslen = strlen(ns);
+        size_t namelen = strlen(name);
+        if(nslen > 0) {
+            property->xmlns = (char*)pool_malloc(pool, nslen + 1);
+            property->xmlns[nslen] = 0;
+            memcpy(property->xmlns, ns, nslen);
+        } else {
+            property->xmlns = NULL;
+        }
+
+        if(namelen > 0) {
+            property->name = (char*)pool_malloc(pool, namelen + 1);
+            property->name[namelen] = 0;
+            memcpy(property->name, name, namelen);
+        } else {
+            property->name = NULL;
+        }
+    }
+
+    XMLString::release(&ns);
+    XMLString::release(&name);
+}
+
+
+void PropfindHandler::endElement(
+        const XMLCh* const   uri,
+        const XMLCh* const   localname,
+        const XMLCh* const   qname)
+{
+    char *ns  = XMLString::transcode(uri);
+    char *name = XMLString::transcode(localname);
+
+    if(property != NULL) {
+        const char *xmlns = (property->xmlns) ? property->xmlns : "";
+        
+        if(!strcmp(ns, xmlns) && !strcmp(name, property->name)) {
+            // add property to DavRequest
+            UcxDlist *elm = (UcxDlist*)pool_malloc(pool, sizeof(UcxDlist));
+            elm->prev = NULL;
+            elm->next = NULL;
+            elm->data = property;
+            //printf("saxhandler: add property: {%s}\n", property->name);
+            davrq->properties = ucx_dlist_concat(davrq->properties, elm);
+            
+            property = NULL;
+        }
+    }
+
+    XMLString::release(&ns);
+    XMLString::release(&name);
+}
+
+void PropfindHandler::startDocument() {
+    
+}
+
+void PropfindHandler::endDocument() {
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/saxhandler.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SAXHANDLER_H
+#define	SAXHANDLER_H
+
+#include "davparser.h"
+
+#include <xercesc/sax2/DefaultHandler.hpp>
+
+using namespace xercesc;
+
+class PropfindHandler : public DefaultHandler {
+public:
+    PropfindHandler(PropfindRequest *rq, pool_handle_t *p);
+    virtual ~PropfindHandler();
+
+    void startElement(
+        const XMLCh* const   uri,
+        const XMLCh* const   localname,
+        const XMLCh* const   qname,
+        const Attributes&    attrs);
+    
+    void endElement(
+        const XMLCh* const   uri,
+        const XMLCh* const   localname,
+        const XMLCh* const   qname);
+
+    void startDocument();
+
+    void endDocument();
+
+private:
+    PropfindRequest *davrq;
+    pool_handle_t   *pool;
+
+    bool            davPropTag;
+    DavProperty     *property;
+};
+
+#endif	/* SAXHANDLER_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/webdav.c	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,256 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "webdav.h"
+#include "../ucx/sstring.h"
+#include "../util/pool.h"
+#include "../util/pblock.h"
+
+#include "davparser.h"
+
+int webdav_service(pblock *pb, Session *sn, Request *rq) {
+    /* TODO:
+     * Dies ist die Implementierung für PROPFIND. Es sollte für jede webdav-
+     * Methode eine eigene Service-Funktion geben. Solange die anderen
+     * Methoden nicht implementiert werden, behandelt webdav_service nur
+     * PROPFIND.
+     */
+
+    /* TODO: clean up if errors occurs */
+
+    /* Get request body which contains the webdav XML request */
+    char   *xml_body;
+    size_t xml_len = 0;
+
+    char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
+    if(ctlen) {
+        xml_len = atoi(ctlen);
+    } else {
+        /* invalid request */
+        return REQ_ABORTED;
+    }
+
+    xml_body = pool_malloc(sn->pool, xml_len + 1);
+    xml_body[xml_len] = 0;
+    if(!xml_body) {
+        /* server error */
+        return REQ_ABORTED;
+    }
+
+    /* TODO: bug with multi reads */
+    int r = 0;
+    char *xb = xml_body;
+    size_t xl = xml_len;
+    while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
+        xb += r;
+        xl -= xml_len;
+    }
+
+    PropfindRequest *davrq = dav_parse_propfind(sn, rq, xml_body, xml_len);
+    davrq->sn = sn;
+    davrq->rq = rq;
+    davrq->propertyBackend = create_property_backend();
+    davrq->notFoundProps = NULL;
+    davrq->forbiddenProps = NULL;
+    davrq->out = sbuf_new(512);
+
+    /* write header */
+    sbuf_puts(davrq->out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+    sbuf_puts(davrq->out, "<D:multistatus xmlns:D=\"DAV:\">\n");
+
+    /* get stat of file */
+    char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
+    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
+
+    struct stat st;
+    if(stat(ppath, &st) != 0) {
+        perror("webdav_service: stat");
+        return REQ_ABORTED;
+    }
+    /* TODO: check for more modes */
+    if(S_ISDIR(st.st_mode)) {
+        DIR *dir = opendir(ppath);
+        if(dir == NULL) {
+            protocol_status(sn, rq, 500, NULL);
+            printf("webdav_service: DIR is null\n");
+            return REQ_ABORTED;
+        }
+
+        struct dirent *f;
+        while((f = readdir(dir)) != NULL) {
+            if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
+                continue;
+            }
+
+            sstr_t filename = sstr(f->d_name);
+            sstr_t _path = sstr(ppath);
+            sstr_t _uri = sstr(uri);
+
+            sstr_t newuri;
+            newuri.length = filename.length + _uri.length;
+            newuri.ptr = alloca(newuri.length + 1);
+            newuri = sstrncat(2, newuri, _uri, filename);
+
+            sstr_t newpath;
+            newpath.length = _path.length + filename.length;
+            newpath.ptr = alloca(newpath.length + 1);
+            newpath = sstrncat(2, newpath, _path, filename);
+
+            davrq->path = newpath.ptr;
+            davrq->uri = newuri.ptr;
+            dav_create_response(davrq);
+        }
+    }
+    davrq->path = ppath;
+    davrq->uri = uri;
+    dav_create_response(davrq);
+
+    sbuf_puts(davrq->out, "</D:multistatus>\n");
+
+    /* send buffer to client */
+    pblock_removekey(pb_key_content_type, rq->srvhdrs);
+    pblock_nvinsert("content-type", "text/xml", rq->srvhdrs);
+    pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs);
+
+    protocol_status(sn, rq, 207, NULL);
+    http_start_response(sn, rq);
+
+    net_write(sn->csd, davrq->out->ptr, davrq->out->length);
+
+    return REQ_PROCEED;
+}
+
+int dav_foreach_reqprop(UcxDlist *list, PropfindRequest *davrq) {
+    DavProperty *prop = list->data;
+    int error = 0;
+    
+    char *str = davrq->propertyBackend->get_property(
+            davrq->propertyBackend,
+            davrq,
+            davrq->path,
+            prop->xmlns,
+            prop->name,
+            &error);
+    if(str == NULL) {
+        UcxDlist **dl = NULL;
+        if(error == 404) {
+            dl = &davrq->notFoundProps;
+        } else {
+            dl = &davrq->forbiddenProps;
+        }
+        *dl = ucx_dlist_append(*dl, prop);
+    } else {
+        //printf("dav property: {%s|%s::%s\n", prop->xmlns, prop->name, str);
+        sbuf_puts(davrq->out, "<D:");
+        sbuf_puts(davrq->out, prop->name);
+        sbuf_puts(davrq->out, ">");
+        sbuf_puts(davrq->out, str);
+        sbuf_puts(davrq->out, "</D:");
+        sbuf_puts(davrq->out, prop->name);
+        sbuf_puts(davrq->out, ">\n");
+    }
+    return 0;
+}
+
+void dav_create_response(PropfindRequest *davrq) {
+    sbuf_puts(davrq->out, "<D:response>\n");
+
+    sbuf_puts(davrq->out, "<D:href>");
+    sbuf_puts(davrq->out, davrq->uri);
+    sbuf_puts(davrq->out, "</D:href>\n");
+
+    sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
+    
+    ucx_dlist_foreach(
+            davrq->properties,
+            (ucx_callback)dav_foreach_reqprop,
+            davrq);
+
+    sbuf_puts(davrq->out, "</D:prop>\n<D:status>HTTP/1.1 200 OK</D:status>\n");
+    sbuf_puts(davrq->out, "</D:propstat>\n");
+
+    /* 404 props */
+    sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
+    UcxDlist *dl = davrq->notFoundProps;
+    while(dl != NULL) {
+        DavProperty *nfp = dl->data;
+        sbuf_puts(davrq->out, "<D:");
+        sbuf_puts(davrq->out, nfp->name);
+        sbuf_puts(davrq->out, " />\n");
+        dl = dl->next;
+    }
+    sbuf_puts(davrq->out, "</D:prop>\n");
+    sbuf_puts(davrq->out, "<D:status>HTTP/1.1 404 Not Found</D:status>\n");
+    sbuf_puts(davrq->out, "</D:propstat>\n");
+
+    /* end */
+    sbuf_puts(davrq->out, "</D:response>\n");
+    
+}
+
+char* dav_get_property(
+        DAVPropertyBackend *b,
+        PropfindRequest *davrq,
+        char *path,
+        char *xmlns,
+        char *name,
+        int *error)
+{
+    DAVDefaultBackend *be = (DAVDefaultBackend*)b;
+    *error = 200;
+
+    if(strcmp(name, "getcontentlength") == 0) {
+        struct stat s;
+        if(stat(davrq->path, &s) != 0) {
+            *error = 403; /* really? */
+            return NULL;
+        }
+        if(S_ISDIR(s.st_mode)) {
+            *error = 404;
+            return NULL;
+        }
+        char *buf = pool_malloc(davrq->sn->pool, 24);
+        sprintf(buf, "%d", s.st_size);
+        return buf;
+    }
+
+    *error = 404;
+    return NULL;
+}
+
+DAVPropertyBackend* create_property_backend() {
+    DAVDefaultBackend *backend = malloc(sizeof(DAVDefaultBackend));
+    backend->backend.get_property = dav_get_property;
+    backend->path = NULL;
+    backend->s = 0;
+    return (DAVPropertyBackend*)backend;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/webdav/webdav.h	Sat Jan 14 13:53:44 2012 +0100
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WEBDAV_H
+#define	WEBDAV_H
+
+#include "../public/nsapi.h"
+
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include "../util/map.h"
+#include "../ucx/dlist.h"
+#include "../util/strbuf.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct PropfindResponse PropfindResponse;
+typedef struct DAVPropertyBackend DAVPropertyBackend;
+
+typedef struct PropfindRequest   PropfindRequest;
+typedef struct DavProperty       DavProperty;
+
+struct PropfindRequest {
+    Session            *sn;
+    Request            *rq;
+
+    UcxDlist           *properties; /* DavProperty list */
+    int8_t             allprop;
+    int8_t             propname;
+
+    UcxDlist           *notFoundProps;
+    UcxDlist           *forbiddenProps;
+    DAVPropertyBackend *propertyBackend;
+
+    char               *path;
+    char               *uri;
+
+    sbuf_t             *out;
+};
+
+struct DavProperty {
+    char *xmlns;
+    char *name;
+};
+
+typedef char*(*prop_get_func)(
+        DAVPropertyBackend*,
+        PropfindRequest*,
+        char*,
+        char*,
+        char*,
+        int*);
+
+struct DAVPropertyBackend {
+    prop_get_func get_property;
+};
+
+int webdav_service(pblock *pb, Session *sn, Request *rq);
+
+void dav_create_response(PropfindRequest *davrq);
+
+int dav_foreach_reqprop(UcxDlist *list, PropfindRequest *davrq);
+
+char* dav_get_property(
+        DAVPropertyBackend *b,
+        PropfindRequest *davrq,
+        char *path,
+        char *xmlns,
+        char *name,
+        int *error);
+
+DAVPropertyBackend* create_property_backend();
+
+typedef struct {
+    DAVPropertyBackend backend;
+    char *path;
+    struct stat st;
+    int s;
+} DAVDefaultBackend;
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* WEBDAV_H */
+
--- a/src/server/webserver.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <dlfcn.h> 
-
-#include "nsapi.h"
-#include "systhr.h"
-
-#include "func.h"
-#include "conf.h"
-#include "httplistener.h"
-#include "webserver.h"
-
-
-extern struct FuncStruct webserver_funcs[];
-
-
-int webserver_init() {
-    // init NSPR
-    systhread_init("webserver");
-
-    // init NSAPI functions
-    func_init();
-    add_functions(webserver_funcs);
-
-    // load init.conf
-    load_init_conf(NULL);
-
-    // load server.conf
-    load_server_conf(NULL);
-
-    // init NSAPI functions
-
-
-    return 0;
-}
-
-int webserver_run() {
-    printf("webserver_run\n");
-
-    // start all http listener
-    if(start_all_listener() != 0) {
-        fprintf(stderr, "Error: Cannot start http listener\n");
-    }
-
-    return 0;
-}
-
-
-void webserver_atrestart(void (*fn)(void *), void *data) {
-    /*
-     * TODO: implement later
-     * only for mod_jk at this time
-     */
-}
-
--- a/src/server/webserver.h	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WEBSERVER_H
-#define	WEBSERVER_H
-
-#include "nsapi.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-int webserver_init();
-int webserver_run();
-
-
-void webserver_atrestart(void (*fn)(void *), void *data);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* WEBSERVER_H */
-
--- a/src/server/ws-fn.c	Sun Jan 08 15:46:47 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2011 Olaf Wintermann. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "nsapi.h"
-
-#include "nametrans.h"
-#include "objecttype.h"
-#include "service.h"
-#include "webdav.h"
-
-struct FuncStruct webserver_funcs[] = {
-    { "test-nametrans", test_nametrans, NULL, 0 },
-    { "assign-name", assign_name, NULL, 0},
-    { "type-by-extension", object_type_by_extension, NULL, 0},
-    { "send-file", send_file, NULL, 0},
-    { "common-index", service_index, NULL, 0},
-    { "service-hello", service_hello, NULL, 0},
-    { "webdav-service", webdav_service, NULL, 0},
-    {NULL, NULL, NULL, 0}
-};

mercurial