Sat, 14 Jan 2012 13:53:44 +0100
New source folder layout
--- 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} -};