Added mod_jk dependencies

Thu, 29 Dec 2011 18:51:23 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 29 Dec 2011 18:51:23 +0100
changeset 9
30e51941a673
parent 8
f4d56bf9de40
child 10
e3ae779232a9

Added mod_jk dependencies

src/server/Makefile file | annotate | diff | comparison | revisions
src/server/httplistener.c file | annotate | diff | comparison | revisions
src/server/httprequest.c 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/main.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/objs.mk 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/session.c file | annotate | diff | comparison | revisions
src/server/session.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/systhr.h file | annotate | diff | comparison | revisions
src/server/webserver.c file | annotate | diff | comparison | revisions
src/server/webserver.h file | annotate | diff | comparison | revisions
--- a/src/server/Makefile	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/Makefile	Thu Dec 29 18:51:23 2011 +0100
@@ -30,7 +30,7 @@
 OBJ_DIR = $(BUILD_ROOT)build/
 
 CFLAGS  = -I/usr/include/mps -g
-LDFLAGS = -L/usr/lib/mps -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lposix4  -lsocket -lnsl -lgen -lm -R/usr/lib/mps -l sendfile
+LDFLAGS = -L/usr/lib/mps -R/usr/lib/mps -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lposix4  -lsocket -lnsl -lgen -lm -lsendfile -pg
 
 MAIN_TARGET = $(BUILD_ROOT)work/bin/webservd
 
--- a/src/server/httplistener.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/httplistener.c	Thu Dec 29 18:51:23 2011 +0100
@@ -162,7 +162,7 @@
             perror("Error: acceptor_thread: accept");
             continue;
         }
-
+        
         /* create Connection object */
         Connection *conn = malloc(sizeof(Connection));
         conn->address = ca;
--- a/src/server/httprequest.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/httprequest.c	Thu Dec 29 18:51:23 2011 +0100
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+
 #include "nsapi.h"
 #include "pool.h"
 #include "pblock.h"
@@ -70,11 +71,22 @@
     sn->sys_fd = request->connection->fd;
     sn->sn.pool = pool_create();
     sn->sn.csd = stream_new_from_fd(request->connection->fd);
-    sn->sn.client = NULL;
+    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");
--- a/src/server/io.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/io.c	Thu Dec 29 18:51:23 2011 +0100
@@ -91,6 +91,14 @@
     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) {
--- a/src/server/io.h	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/io.h	Thu Dec 29 18:51:23 2011 +0100
@@ -60,6 +60,7 @@
 
 /* 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 */
--- a/src/server/main.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/main.c	Thu Dec 29 18:51:23 2011 +0100
@@ -39,14 +39,13 @@
 #include "httprequest.h"
 
 void test() {
-    pool_handle_t *pool = pool_create();
     
 }
 
 int main(int argc, char **argv) {
-    //test();
+    pool_init(NULL, NULL, NULL);
 
-    pool_init(NULL, NULL, NULL);
+    //test();
 
     int status;
     status = webserver_init();
--- a/src/server/netsite.h	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/netsite.h	Thu Dec 29 18:51:23 2011 +0100
@@ -135,7 +135,6 @@
 NSAPI_PUBLIC pool_handle_t *INTsystem_pool(void);
 
 /* Not sure where to put this. */
-NSAPI_PUBLIC void INTmagnus_atrestart(void (*fn)(void *), void *data);
 
 NSAPI_PUBLIC void INTsystem_setnewhandler(void);
 
@@ -161,7 +160,6 @@
 #define system_strdup_perm INTsystem_strdup_perm
 #define getThreadMallocKey INTgetThreadMallocKey
 #define system_pool INTsystem_pool
-#define magnus_atrestart INTmagnus_atrestart
 #define system_setnewhandler INTsystem_setnewhandler
 
 #endif /* INTNSAPI */
--- a/src/server/nsapi.h	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/nsapi.h	Thu Dec 29 18:51:23 2011 +0100
@@ -832,7 +832,7 @@
 
     /* What port we listen to */
     int Vport;                                  /* OBSOLETE */
-#define server_portnum conf_getglobals()->Vport
+#define server_portnum 80
 
     /* What address to bind to */
     char *Vaddr;                                /* OBSOLETE */
@@ -863,7 +863,7 @@
     char *Vsecure_keyfn;                        /* OBSOLETE */
     char *Vsecure_certfn;                       /* OBSOLETE */
 
-#define security_active conf_getglobals()->Vsecurity_active
+#define security_active 0
     int Vsecurity_active;
     int Vssl3_active;                           /* OBSOLETE */
     int Vssl2_active;                           /* OBSOLETE */
@@ -872,7 +872,7 @@
     long Vssl3_session_timeout;
 
     /* The server's hostname as should be reported in self-ref URLs */
-#define server_hostname conf_getglobals()->Vserver_hostname
+#define server_hostname "x4"
     char *Vserver_hostname;
 
     /* The main object from which all are derived */
@@ -1065,444 +1065,6 @@
 /* --- End type definitions --- */
 
 /* --- Begin dispatch vector table definition --- */
-
-typedef struct nsapi_dispatch_s nsapi_dispatch_t;
-struct nsapi_dispatch_s {
-    char *(*f_system_version)();
-    void *(*f_system_malloc)(int size);
-    void *(*f_system_calloc)(int size);
-    void *(*f_system_realloc)(void *ptr, int size);
-    void (*f_system_free)(void *ptr);
-    char *(*f_system_strdup)(const char *ptr);
-    void *(*f_system_malloc_perm)(int size);
-    void *(*f_system_calloc_perm)(int size);
-    void *(*f_system_realloc_perm)(void *ptr, int size);
-    void (*f_system_free_perm)(void *ptr);
-    char *(*f_system_strdup_perm)(const char *ptr);
-    int (*f_getThreadMallocKey)(void);
-    void (*f_magnus_atrestart)(void (*fn)(void *), void *data);
-    filebuf_t *(*f_filebuf_open)(SYS_FILE fd, int sz);
-    netbuf *(*f_netbuf_open)(SYS_NETFD sd, int sz);
-    filebuf_t *(*f_filebuf_create)(SYS_FILE fd, caddr_t mmap_ptr,
-                                   int mmap_len, int bufsz);
-    void (*f_filebuf_close_buffer)(filebuf_t *buf, int clean_mmap);
-    filebuf_t *(*f_filebuf_open_nostat)(SYS_FILE fd, int sz,
-                                        struct stat *finfo);
-#ifdef XP_WIN32
-    filebuf_t *(*f_pipebuf_open)(SYS_FILE fd, int sz, struct stat *finfo);
-#else
-    void *(*f_pipebuf_open)(void);
-#endif /* XP_WIN32 */
-    int (*f_filebuf_next)(void);
-    int (*f_netbuf_next)(netbuf *buf, int advance);
-#ifdef XP_WIN32 
-    int (*f_pipebuf_next)(filebuf_t *buf, int advance);
-#else
-    int (*f_pipebuf_next)(void);
-#endif /* XP_WIN32 */
-    void (*f_filebuf_close)(filebuf_t *buf);
-    void (*f_netbuf_close)(netbuf *buf);
-#ifdef XP_WIN32
-    void        (*f_pipebuf_close)(filebuf_t *buf);
-#else
-    void (*f_pipebuf_close)(void);
-#endif /* XP_WIN32 */
-    int (*f_filebuf_grab)(filebuf_t *buf, int sz);
-    int (*f_netbuf_grab)(netbuf *buf, int sz);
-#ifdef XP_WIN32
-    int (*f_pipebuf_grab)(filebuf_t *buf, int sz);
-#else
-    int (*f_pipebuf_grab)(void);
-#endif /* XP_WIN32 */
-    int (*f_netbuf_buf2sd)(netbuf *buf, SYS_NETFD sd, int len);
-    int (*f_filebuf_buf2sd)(filebuf_t *buf, SYS_NETFD sd);
-#ifdef XP_WIN32
-    int (*f_pipebuf_buf2sd)(filebuf_t *buf, SYS_NETFD sd, int len);
-    int (*f_pipebuf_netbuf2sd)(netbuf *buf, SYS_FILE sd, int len);
-    int (*f_pipebuf_netbuf2pipe)(netbuf *buf, SYS_NETFD sd, int len);
-#else
-    int (*f_pipebuf_buf2sd)(void);
-    int (*f_pipebuf_netbuf2sd)(void);
-    int (*f_pipebuf_netbuf2pipe)(void);
-#endif /* XP_WIN32 */
-    void (*f_cinfo_init)(void);
-    void (*f_cinfo_terminate)(void);
-    char *(*f_cinfo_merge)(char *fn);
-    cinfo *(*f_cinfo_find)(char *uri);
-    cinfo *(*f_cinfo_lookup)(char *type);
-    void (*f_cinfo_dump_database)(FILE *dump);
-    CRITICAL (*f_crit_init)(void);
-    void (*f_crit_enter)(CRITICAL id);
-    void (*f_crit_exit)(CRITICAL id);
-    void (*f_crit_terminate)(CRITICAL id);
-    CONDVAR (*f_condvar_init)(CRITICAL id);
-    void (*f_condvar_wait)(CONDVAR cv);
-    void (*f_condvar_notify)(CONDVAR cv);
-    void (*f_condvar_notifyAll)(CONDVAR cv);
-    void (*f_condvar_terminate)(CONDVAR cv);
-    COUNTING_SEMAPHORE (*f_cs_init)(int initial_count);
-    void (*f_cs_terminate)(COUNTING_SEMAPHORE csp);
-    int (*f_cs_wait)(COUNTING_SEMAPHORE csp);
-    int (*f_cs_trywait)(COUNTING_SEMAPHORE csp);
-    int (*f_cs_release)(COUNTING_SEMAPHORE csp);
-    void (*f_daemon_atrestart)(void (*fn)(void *), void *data);
-    /* Obsolete: servssl_init() */
-    void (*f_servssl_init)(void);
-    int (*f_ereport)(int degree, const char *fmt, ...);
-    int (*f_ereport_v)(int degree, const char *fmt, va_list args);
-    char *(*f_ereport_init)(const char *err_fn, const char *email,
-                            struct passwd *pwuser, const char *version,
-                            int restart);
-    void (*f_ereport_terminate)(void);
-    SYS_FILE (*f_ereport_getfd)(void);
-    SYS_FILE (*f_system_fopenRO)(const char *path);
-    SYS_FILE (*f_system_fopenWA)(const char *path);
-    SYS_FILE (*f_system_fopenRW)(const char *path);
-    SYS_FILE (*f_system_fopenWT)(const char *path);
-    int (*f_system_fread)(SYS_FILE fd, void *buf, int sz);
-    int (*f_system_fwrite)(SYS_FILE fd, const void *buf,int sz);
-    int (*f_system_fwrite_atomic)(SYS_FILE fd, const void *buf, int sz);
-    int (*f_system_lseek)(SYS_FILE fd, int off, int wh);
-    int (*f_system_fclose)(SYS_FILE fd);
-    int (*f_system_stat)(const char *name, struct stat *finfo);
-    int (*f_system_rename)(const char *oldpath, const char *newpath);
-    int (*f_system_unlink)(const char *path);
-    int (*f_system_tlock)(SYS_FILE fd);
-    int (*f_system_flock)(SYS_FILE fd);
-    int (*f_system_ulock)(SYS_FILE fd);
-#ifdef XP_WIN32
-    SYS_DIR (*f_dir_open)(const char *path);
-    SYS_DIRENT *(*f_dir_read)(SYS_DIR ds);
-    void (*f_dir_close)(SYS_DIR ds);
-#else
-    void *(*f_dir_open)(void);
-    void *(*f_dir_read)(void);
-    void (*f_dir_close)(void);
-#endif /* XP_WIN32 */
-    int (*f_dir_create_all)(char *dir);
-#ifdef XP_WIN32
-    void *(*f_system_winsockerr)(void);
-    void *(*f_system_winerr)(void);
-    int (*f_system_pread)(SYS_FILE fd, void *buf, int sz);
-    int (*f_system_pwrite)(SYS_FILE fd, const void *buf, int sz);
-    void (*f_file_unix2local)(const char *path, char *p2);
-#else
-    void *(*f_system_winsockerr)(void);
-    void *(*f_system_winerr)(void);
-    int (*f_system_pread)(void);
-    int (*f_system_pwrite)(void);
-    void (*f_file_unix2local)(void);
-#endif /* XP_WIN32 */
-    int (*f_system_nocoredumps)(void);
-    int (*f_file_setinherit)(SYS_FILE fd, int value);
-    int (*f_file_notfound)(void);
-    char *(*f_system_errmsg)(void);
-    int (*f_system_errmsg_fn)(char **buff, size_t maxlen);
-    SYS_NETFD (*f_net_socket)(int domain, int type, int protocol);
-    int (*f_net_listen)(SYS_NETFD s, int backlog);
-    SYS_NETFD (*f_net_create_listener)(const char *ipaddr, int port);
-    int (*f_net_connect)(SYS_NETFD s, const void *sockaddr, int namelen);
-    int (*f_net_getpeername)(SYS_NETFD s, struct sockaddr *name, int *namelen);
-    int (*f_net_close)(SYS_NETFD s);
-    int (*f_net_bind)(SYS_NETFD s, const struct sockaddr *name, int namelen);
-    SYS_NETFD (*f_net_accept)(SYS_NETFD s, struct sockaddr *addr, int *addrlen);
-    int (*f_net_read)(SYS_NETFD sd, void *buf, int sz, int timeout);
-    int (*f_net_write)(SYS_NETFD sd, const void *buf, int sz);
-    int (*f_net_writev)(SYS_NETFD sd, const NSAPIIOVec *iov, int iovlen);
-    int (*f_net_isalive)(SYS_NETFD sd);
-    char *(*f_net_ip2host)(const char *ip, int verify);
-    int (*f_net_getsockopt)(SYS_NETFD s, int level, int optname,
-                            void *optval, int *optlen);
-    int (*f_net_setsockopt)(SYS_NETFD s, int level, int optname,
-                            const void *optval, int optlen);
-    int (*f_net_select)(int nfds, fd_set *r, fd_set *w, fd_set *e, 
-                        struct timeval *timeout);
-    int (*f_net_ioctl)(SYS_NETFD s, int tag, void *result);
-    pb_param *(*f_param_create)(const char *name, const char *value);
-    int (*f_param_free)(pb_param *pp);
-    pblock *(*f_pblock_create)(int n);
-    void (*f_pblock_free)(pblock *pb);
-    char *(*f_pblock_findval)(const char *name, const pblock *pb);
-    pb_param *(*f_pblock_nvinsert)(const char *name, const char *value, pblock *pb);
-    pb_param *(*f_pblock_nninsert)(const char *name, int value, pblock *pb);
-    void (*f_pblock_pinsert)(pb_param *pp, pblock *pb);
-    int (*f_pblock_str2pblock)(const char *str, pblock *pb);
-    char *(*f_pblock_pblock2str)(const pblock *pb, char *str);
-    int (*f_pblock_copy)(const pblock *src, pblock *dst);
-    pblock *(*f_pblock_dup)(const pblock *src);
-    char **(*f_pblock_pb2env)(const pblock *pb, char **env);
-    pb_param *(*f_pblock_fr)(const char *name, pblock *pb, int remove);
-    char * (*f_pblock_replace)(const char *name,char * new_value,pblock *pb);
-    pool_handle_t *(*f_pool_create)(void);
-    void (*f_pool_destroy)(pool_handle_t *pool_handle);
-    int (*f_pool_enabled)(void);
-    void *(*f_pool_malloc)(pool_handle_t *pool_handle, size_t size );
-    void (*f_pool_free)(pool_handle_t *pool_handle, void *ptr );
-    void *(*f_pool_calloc)(pool_handle_t *pool_handle, size_t nelem, size_t elsize);
-    void *(*f_pool_realloc)(pool_handle_t *pool_handle, void *ptr, size_t size );
-    char *(*f_pool_strdup)(pool_handle_t *pool_handle, const char *orig_str );
-    int (*f_regexp_valid)(const char *exp);
-    int (*f_regexp_match)(const char *str, const char *exp);
-    int (*f_regexp_cmp)(const char *str, const char *exp);
-    int (*f_regexp_casecmp)(const char *str, const char *exp);
-    SEMAPHORE (*f_sem_init)(char *name, int number);
-    void (*f_sem_terminate)(SEMAPHORE id);
-    int (*f_sem_grab)(SEMAPHORE id);
-    int (*f_sem_tgrab)(SEMAPHORE id);
-    int (*f_sem_release)(SEMAPHORE id);
-    Session *(*f_session_alloc)(SYS_NETFD csd, struct sockaddr_in *sac); /* internal */
-    Session *(*f_session_fill)(Session *sn); /* internal */
-    Session *(*f_session_create)(SYS_NETFD csd, struct sockaddr_in *sac);
-    void (*f_session_free)(Session *sn);
-    char *(*f_session_dns_lookup)(Session *sn, int verify);
-    int (*f_shexp_valid)(const char *exp);
-    int (*f_shexp_match)(const char *str, const char *exp);
-    int (*f_shexp_cmp)(const char *str, const char *exp);
-    int (*f_shexp_casecmp)(const char *str, const char *exp);
-    shmem_s *(*f_shmem_alloc)(char *name, int size, int expose);
-    void (*f_shmem_free)(shmem_s *region);
-    SYS_THREAD (*f_systhread_start)(int prio, int stksz, void (*fn)(void *), void *arg);
-    SYS_THREAD (*f_systhread_current)(void);
-    void (*f_systhread_yield)(void);
-    SYS_THREAD (*f_systhread_attach)(void);
-    void (*f_systhread_detach)(SYS_THREAD thr);
-    void (*f_systhread_terminate)(SYS_THREAD thr);
-    void (*f_systhread_sleep)(int milliseconds);
-    void (*f_systhread_init)(char *name);
-    void (*f_systhread_timerset)(int usec);
-    int (*f_systhread_newkey)(void);
-    void *(*f_systhread_getdata)(int key);
-    void (*f_systhread_setdata)(int key, void *data);
-    void (*f_systhread_set_default_stacksize)(unsigned long size);
-    int (*f_util_getline)(filebuffer *buf, int lineno, int maxlen, char *l);
-    char **(*f_util_env_create)(char **env, int n, int *pos);
-    char *(*f_util_env_str)(const char *name, const char *value);
-    void (*f_util_env_replace)(char **env, const char *name, const char *value);
-    void (*f_util_env_free)(char **env);
-    char **(*f_util_env_copy)(char **src, char **dst);
-    char *(*f_util_env_find)(char **env, const char *name);
-    char *(*f_util_hostname)(void);
-    int (*f_util_chdir2path)(char *path);
-    int (*f_util_is_mozilla)(char *ua, char *major, char *minor);
-    int (*f_util_is_url)(const char *url);
-    int (*f_util_later_than)(const struct tm *lms, const char *ims);
-    int (*f_util_time_equal)(const struct tm *lms, const char *ims);
-    int (*f_util_str_time_equal)(const char *t1, const char *t2);
-    int (*f_util_uri_is_evil)(const char *t);
-    void (*f_util_uri_parse)(char *uri);
-    void (*f_util_uri_unescape)(char *s);
-    char *(*f_util_uri_escape)(char *d, const char *s);
-    char *(*f_util_url_escape)(char *d, const char *s);
-    char *(*f_util_sh_escape)(char *s);
-    int (*f_util_mime_separator)(char *sep);
-    int (*f_util_itoa)(int i, char *a);
-    int (*f_util_vsprintf)(char *s, register const char *fmt, va_list args);
-    int (*f_util_sprintf)(char *s, const char *fmt, ...);
-    int (*f_util_vsnprintf)(char *s, int n, register const char *fmt, 
-                            va_list args);
-    int (*f_util_snprintf)(char *s, int n, const char *fmt, ...);
-    int (*f_util_strftime)(char *s, const char *format, const struct tm *t);
-    char *(*f_util_strtok)(char *s1, const char *s2, char **lasts);
-    struct tm *(*f_util_localtime)(const time_t *clock, struct tm *res);
-    char *(*f_util_ctime)(const time_t *clock, char *buf, int buflen);
-    char *(*f_util_strerror)(int errnum, char *msg, int buflen);
-    struct tm *(*f_util_gmtime)(const time_t *clock, struct tm *res);
-    char *(*f_util_asctime)(const struct tm *tm,char *buf, int buflen);
-#ifdef NEED_STRCASECMP
-    int (*f_util_strcasecmp)(const char *one, const char *two);
-#else
-    int (*f_util_strcasecmp)(void);
-#endif /* NEED_STRCASECMP */
-#ifdef NEED_STRNCASECMP
-    int (*f_util_strncasecmp)(const char *one, const char *two, int n);
-#else
-    int (*f_util_strncasecmp)(void);
-#endif /* NEED_STRNCASECMP */
-#ifdef XP_UNIX
-    int (*f_util_can_exec)(struct stat *finfo, uid_t uid, gid_t gid);
-    struct passwd *(*f_util_getpwnam)(const char *name, struct passwd
-                                      *result, char *buffer,  int buflen);
-    pid_t (*f_util_waitpid)(pid_t pid, int *statptr, int options);
-#else
-    int (*f_util_can_exec)(void);
-    void *(*f_util_getpwnam)(void);
-    int (*f_util_waitpid)(void);
-#endif /* XP_UNIX */
-#ifdef XP_WIN32
-    VOID (*f_util_delete_directory)(char *FileName, BOOL delete_directory);
-#else
-    void (*f_util_delete_directory)(void);
-#endif /* XP_WIN32 */
-    void *(*f_conf_init)(void);
-    void *(*f_conf_run_init_functions)(void);
-    void (*f_conf_terminate)(void);
-    conf_global_vars_s *(*f_conf_getglobals)(void);
-    void (*f_func_init)(struct FuncStruct *func_standard);
-    FuncPtr (*f_func_find)(char *name);
-    int (*f_func_exec)(pblock *pb, Session *sn, Request *rq);
-    struct FuncStruct *(*f_func_insert)(char *name, FuncPtr fn);
-    int (*f_object_execute)(directive *inst, Session *sn, Request *rq);
-    void *(*f_http_find_request)(void);
-    int (*f_http_parse_request)(char *t, Request *rq, Session *sn);
-    int (*f_http_scan_headers)(void);
-    int (*f_http_start_response)(Session *sn, Request *rq);
-    char **(*f_http_hdrs2env)(pblock *pb);
-    void (*f_http_status)(Session *sn, Request *rq, int n, const char *r);
-    int (*f_http_set_finfo)(Session *sn, Request *rq, struct stat *finfo);
-    char *(*f_http_dump822)(pblock *pb, char *t, int *pos, int tsz);
-    void (*f_http_finish_request)(Session *sn, Request *rq);
-    void (*f_http_handle_session)(void);
-    char *(*f_http_uri2url)(const char *prefix, const char *suffix);
-    char *(*f_http_uri2url_dynamic)(const char *prefix, const char *suffix,
-                                    Session *sn, Request *rq);
-    void (*f_http_set_keepalive_timeout)(int secs);
-    int (*f_log_error_v)(int degree, const char *func, Session *sn,
-                         Request *rq, const char *fmt, va_list args);
-    int (*f_log_error)(int degree, const char *func, Session *sn, Request *rq,
-                       const char *fmt, ...);
-    int (*f_log_ereport_v)(int degree, const char *fmt, va_list args);
-    int (*f_log_ereport)(int degree, const char *fmt, ...);
-    httpd_object *(*f_object_create)(int nd, pblock *name);
-    void (*f_object_free)(httpd_object *obj);
-    void (*f_object_add_directive)(int dc, pblock *p, pblock *c,
-                                   httpd_object *obj);
-    httpd_objset *(*f_objset_scan_buffer)(filebuffer *buf, char *errstr,
-                                          httpd_objset *os);
-    httpd_objset *(*f_objset_create)(void);
-    void (*f_objset_free)(httpd_objset *os);
-    void (*f_objset_free_setonly)(httpd_objset *os);
-    httpd_object *(*f_objset_new_object)(pblock *name, httpd_objset *os);
-    void (*f_objset_add_object)(httpd_object *obj, httpd_objset *os);
-    void (*f_objset_add_init)(pblock *initfn, httpd_objset *os);
-    httpd_object *(*f_objset_findbyname)(const char *name, httpd_objset *ign,
-                                         httpd_objset *os);
-    httpd_object *(*f_objset_findbyppath)(char *ppath, httpd_objset *ign,
-                                          httpd_objset *os);
-    Request *(*f_request_create)(void);
-    void (*f_request_free)(Request *req);
-    Request *(*f_request_restart_internal)(const char *uri, Request *rq);
-    int (*f_request_header)(char *name, char **value, Session *sn,
-                            Request *rq);
-    struct stat *(*f_request_stat_path)(const char *path, Request *rq);
-    const char *(*f_conf_getServerString)(void);
-    FuncPtr (*f_func_replace)(char *funcname, FuncPtr fn);
-    int (*f_net_socketpair)(SYS_NETFD *pair);
-#ifdef XP_UNIX
-    SYS_NETFD (*f_net_dup2)(SYS_NETFD prfd, int osfd);
-    int (*f_net_is_STDOUT)(SYS_NETFD prfd);
-    int (*f_net_is_STDIN)(SYS_NETFD prfd);
-#else
-    void *(*f_net_dup2)(void);
-    int (*f_net_is_STDOUT)(void);
-    int (*f_net_is_STDIN)(void);
-#endif /* XP_UNIX */
-    int (*f_func_set_native_thread_flag)(char *name, int flags);
-#ifdef NET_SSL
-    void *(*f_random_create)(void);
-    void (*f_random_update)(void *rctx, unsigned char *inbuf, int length);
-    void (*f_random_generate)(void *rctx, unsigned char *outbuf, int length);
-    void (*f_random_destroy)(void *rctx);
-    void *(*f_md5hash_create)(void);
-    void *(*f_md5hash_copy)(void *hctx);
-    void (*f_md5hash_begin)(void *hctx);
-    void (*f_md5hash_update)(void *hctx, unsigned char *inbuf, int length);
-    void (*f_md5hash_end)(void *hctx, unsigned char *outbuf);
-    void (*f_md5hash_destroy)(void *hctx);
-    void (*f_md5hash_data)(unsigned char *outbuf, unsigned char *src, int length);
-#else
-    void *(*f_random_create)(void);
-    void (*f_random_update)(void);
-    void (*f_random_generate)(void);
-    void (*f_random_destroy)(void);
-    void *(*f_md5hash_create)(void);
-    void *(*f_md5hash_copy)(void);
-    void (*f_md5hash_begin)(void);
-    void (*f_md5hash_update)(void);
-    void (*f_md5hash_end)(void);
-    void (*f_md5hash_destroy)(void);
-    void (*f_md5hash_data)(void);
-#endif
-    int (*f_ACL_SetupEval)(struct ACLListHandle *acllist, Session *sn, Request *rq, char **rights, char **map_generic, const char *user);
-    int (*f_netbuf_getbytes)(netbuf *buf, char *buffer, int size);
-    char *(*f_servact_translate_uri)(char *uri, Session *sn);
-#ifdef NET_SSL
-    int (*f_rsa_set_priv_fn)(void *);
-#else
-    int (*f_rsa_set_priv_fn)(void);
-#endif
-#ifdef XP_UNIX
-    int (*f_net_native_handle)(SYS_NETFD s);
-#else
-    HANDLE (*f_net_native_handle)(SYS_NETFD s);
-#endif /* XP_UNIX */
-    int (*f_internal_request)(Request *rq);
-    char *(*f_util_cookie_find)(char *cookie, const char *name);
-    char *(*f_util_cookie_next)(char *cookie, char **name, char **value);
-    char *(*f_util_cookie_next_av_pair)(char *cookie, char **name, char **value);
-    int (*f_objset_get_number_objects)(const httpd_objset *objset);
-    const httpd_object *(*f_objset_get_object)(const httpd_objset *objset, int pos);
-    const pblock * const *(*f_objset_get_initfns)(const httpd_objset *objset);
-    const pblock *(*f_object_get_name)(const httpd_object *object);
-    int (*f_object_get_num_directives)(const httpd_object *object);
-    const dtable *(*f_object_get_directive_table)(const httpd_object *object, int n);
-    int (*f_directive_table_get_num_directives)(const dtable *dt);
-    const directive *(*f_directive_table_get_directive)(const dtable *dt, int pos);
-    const pblock *(*f_directive_get_pblock)(const directive *);
-    const FuncStruct *(*f_directive_get_funcstruct)(const directive *);
-    const pblock *(*f_directive_get_client_pblock)(const directive *);
-#if NSAPI_VERSION >= 301
-    int (*f_vs_register_cb)(VSInitFunc *vs_init_func, VSDestroyFunc *vs_destroy_func);
-    const char* (*f_vs_get_id)(const VirtualServer *vs);
-    const char* (*f_vs_lookup_config_var)(const VirtualServer *vs, const char *name);
-    int (*f_vs_alloc_slot)(void);
-    void* (*f_vs_set_data)(const VirtualServer *vs, int *slot, void *data);
-    void* (*f_vs_get_data)(const VirtualServer *vs, int slot);
-    const VirtualServer* (*f_request_get_vs)(Request *rq);
-    httpd_objset* (*f_vs_get_httpd_objset)(VirtualServer *vs);
-    httpd_object* (*f_vs_get_default_httpd_object)(VirtualServer *vs);
-    char* (*f_vs_get_doc_root)(const VirtualServer *vs);
-    char* (*f_vs_translate_uri)(const VirtualServer *vs, const char *uri);
-    char* (*f_vs_get_mime_type)(const VirtualServer *vs, const char *uri);
-    int (*f_vs_is_default_vs)(const VirtualServer *vs);
-    void *(*f_vs_get_acllist)(const VirtualServer *vs);
-    void (*f_vs_set_acllist)(VirtualServer *vs, void *acllist);
-    int (*f_file_is_path_abs)(const char *path);
-    char* (*f_file_canonicalize_path)(const char* path);
-    int (*f_file_are_files_distinct)(SYS_FILE fd1, SYS_FILE fd2);
-    int (*f_vs_directive_register_cb)(FuncPtr func, VSDirectiveInitFunc *vs_init_func, VSDirectiveDestroyFunc *vs_destroy_func);
-    char* (*f_vs_substitute_vars)(const VirtualServer *vs, const char *string);
-    const char *(*f_conf_getfilename)(void);
-    const char *(*f_conf_getstring)(const char *name, const char *def);
-    int (*f_conf_getboolean)(const char *name, int def);
-    int (*f_conf_getinteger)(const char *name, int def);
-    int (*f_conf_getboundedinteger)(const char *name, int min, int max, int def);
-    void (*f_prepare_nsapi_thread)(Request *rq, Session *sn);
-#endif /* NSAPI_VERSION >= 301 */
-};
-
-#if NSAPI_VERSION >= 302
-typedef struct nsapi302_dispatch_s nsapi302_dispatch_t;
-struct nsapi302_dispatch_s {
-    int (*f_net_flush)(SYS_NETFD sd);
-    int (*f_net_sendfile)(SYS_NETFD sd, sendfiledata *sfd);
-    const Filter *(*f_filter_create)(const char *name, int order, const FilterMethods *methods);
-    const char *(*f_filter_name)(const Filter *filter);
-    const Filter *(*f_filter_find)(const char *name);
-    FilterLayer *(*f_filter_layer)(SYS_NETFD sd, const Filter *filter);
-    int (*f_filter_insert)(SYS_NETFD sd, pblock *pb, Session *sn, Request *rq, void *data, const Filter *filter);
-    int (*f_filter_remove)(SYS_NETFD sd, const Filter *filter);
-    SYS_NETFD (*f_filter_create_stack)(Session *sn);
-};
-#endif /* NSAPI_VERSION >= 302 */
-
-#if NSAPI_VERSION >= 303
-typedef struct nsapi303_dispatch_s nsapi303_dispatch_t;
-struct hostent;
-struct nsapi303_dispatch_s {
-    int (*f_dns_set_hostent)(struct hostent *he, Session *sn, Request *rq);
-};
-#endif /* NSAPI_VERSION >= 303 */
-
 /* --- End dispatch vector table definition --- */
 
 /* --- Begin API macro definitions --- */
@@ -1588,14 +1150,116 @@
  */
 #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
-#define protocol_status http_status
-#define protocol_set_finfo http_set_finfo
-#define protocol_finish_request http_finish_request
-#define protocol_uri2url http_uri2url
-#define protocol_uri2url_dynamic http_uri2url_dynamic
+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
+
 
-#define request_translate_uri servact_translate_uri
+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
@@ -1668,13 +1332,6 @@
 
 #else /* !XP_WIN32 */
 
-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 */
 
 #endif /* XP_WIN32 */
 
--- a/src/server/objs.mk	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/objs.mk	Thu Dec 29 18:51:23 2011 +0100
@@ -59,6 +59,7 @@
 MOBJ += service.o
 MOBJ += protocol.o
 MOBJ += netbuf.o
+MOBJ += shexp.o
 
 MAINOBJS = $(MOBJ:%=$(OBJPRE)%)
 
--- a/src/server/protocol.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/protocol.c	Thu Dec 29 18:51:23 2011 +0100
@@ -302,4 +302,13 @@
     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	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/protocol.h	Thu Dec 29 18:51:23 2011 +0100
@@ -45,6 +45,8 @@
 
 int http_start_response(Session *sn, Request *rq);
 
+int request_header(char *name, char **value, Session *sn, Request *rq);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/session.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/session.c	Thu Dec 29 18:51:23 2011 +0100
@@ -30,4 +30,7 @@
 
 #include "session.h"
 
-
+NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify) {
+    // TODO: implement
+    return NULL;
+}
--- a/src/server/session.h	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/session.h	Thu Dec 29 18:51:23 2011 +0100
@@ -42,6 +42,7 @@
     int sys_fd; /* system file descriptor */
 };
 
+NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify);
 
 #ifdef	__cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/shexp.c	Thu Dec 29 18:51:23 2011 +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/shexp.h	Thu Dec 29 18:51:23 2011 +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 "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/systhr.h	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/systhr.h	Thu Dec 29 18:51:23 2011 +0100
@@ -60,7 +60,6 @@
 
 NSPR_BEGIN_EXTERN_C
 
-typedef void (*thrstartfunc)(void *);
 NSAPI_PUBLIC
 SYS_THREAD INTsysthread_start(int prio, int stksz, thrstartfunc fn, void *arg);
 
--- a/src/server/webserver.c	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/webserver.c	Thu Dec 29 18:51:23 2011 +0100
@@ -28,6 +28,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <dlfcn.h> 
 
 #include "nsapi.h"
 #include "systhr.h"
@@ -57,7 +58,6 @@
 
     // init NSAPI functions
 
-    
 
     return 0;
 }
@@ -72,3 +72,12 @@
 
     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	Wed Dec 28 22:02:08 2011 +0100
+++ b/src/server/webserver.h	Thu Dec 29 18:51:23 2011 +0100
@@ -39,6 +39,7 @@
 int webserver_run();
 
 
+void webserver_atrestart(void (*fn)(void *), void *data);
 
 #ifdef	__cplusplus
 }

mercurial