Ignore:
Timestamp:
May 28, 2015, 4:25:06 PM (9 years ago)
Author:
djay
Message:

First version including zoo_service shared library

Location:
trunk/zoo-project/zoo-kernel
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/zoo-project/zoo-kernel/Makefile.in

    r634 r640  
    55version.h:
    66        echo "#define ZOO_VERSION \"`svnversion`\"" > version.h
     7
     8service.o: service.c service.h
     9        gcc ${YAML_CFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service.c
    710
    811main_conf_read.tab.c: main_conf_read.y service.h
     
    3437
    3538request_parser.o: request_parser.c request_parser.h
    36         gcc -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c request_parser.c
     39        g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c request_parser.c
    3740
    38 service_internal.o: service_internal.c service.h mimetypes.h
    39         g++ ${GDAL_CFLAGS} ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_internal.c
     41sqlapi.o: sqlapi.c sqlapi.h
     42        g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c sqlapi.c
     43
     44caching.o: caching.c
     45        g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c caching.c
     46
     47response_print.o: response_print.c response_print.h
     48        g++ -fPIC ${XML2CFLAGS} ${CFLAGS} ${JSCFLAGS} ${JS_ENABLED} -c response_print.c
     49
     50server_internal.o: server_internal.c server_internal.h service.h mimetypes.h
     51        g++ ${GDAL_CFLAGS} ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c server_internal.c
     52
     53service_internal.o: service_internal.c service_internal.h service.h
     54        gcc ${GDAL_CFLAGS} ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_internal.c
    4055
    4156service_yaml.o: service_yaml.c service.h
     
    7893        g++ -g -O2 ${XML2CFLAGS} ${CFLAGS} ${SAGA_CFLAGS} ${OTBCFLAGS} ${PYTHONCFLAGS} ${JAVACFLAGS} ${JSCFLAGS} ${PERLCFLAGS} ${PHPCFLAGS} ${SAGA_ENABLED} ${OTB_ENABLED} ${PYTHON_ENABLED} ${JS_ENABLED} ${PHP_ENABLED} ${PERL_ENABLED} ${JAVA_ENABLED} -c zoo_service_loader.c  -fno-common -DPIC -o zoo_service_loader.o
    7994
    80 zoo_loader.cgi: version.h zoo_loader.c zoo_service_loader.o  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o service_internal.o request_parser.o ${MS_FILE} ${PYTHON_FILE} ${PHP_FILE} ${JAVA_FILE} ${JS_FILE} ${PERL_FILE} ${RUBY_FILE} ${YAML_FILE} ${OTB_FILE} ${SAGA_FILE}
     95libzoo_service.${EXT}: version.h service_internal.o service.o
     96        gcc -shared ${DEFAULT_OPTS} -fpic -o libzoo_service.${EXT} ${CFLAGS}  service_internal.o service.o -lfcgi
     97
     98zoo_loader.cgi: version.h libzoo_service.${EXT} zoo_loader.c zoo_service_loader.o  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o request_parser.o sqlapi.o response_print.o server_internal.o caching.o ${MS_FILE} ${PYTHON_FILE} ${PHP_FILE} ${JAVA_FILE} ${JS_FILE} ${PERL_FILE} ${RUBY_FILE} ${YAML_FILE} ${OTB_FILE} ${SAGA_FILE}
    8199        g++ -g -O2 ${JSCFLAGS} ${PHPCFLAGS}  ${PERLCFLAGS} ${RUBYCFLAGS}  ${JAVACFLAGS} ${XML2CFLAGS} ${PYTHONCFLAGS} ${CFLAGS} -c zoo_loader.c  -fno-common -DPIC -o zoo_loader.o
    82         g++  ${JSCFLAGS} ${SAGA_CFLAGS} ${OTBCFLAGS} ${GDAL_CFLAGS} ${XML2CFLAGS} ${PHPCFLAGS} ${PERLCFLAGS} ${JAVACFLAGS} ${PYTHONCFLAGS} ${CFLAGS} zoo_loader.o zoo_service_loader.o service_internal.o ${MS_FILE} ${PYTHON_FILE}  ${PERL_FILE} ${PHP_FILE}  ${JS_FILE} ${JAVA_FILE} ${YAML_FILE} ${OTB_FILE} ${SAGA_FILE} request_parser.o ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o -o zoo_loader.cgi ${LDFLAGS}
     100        g++  ${JSCFLAGS} ${SAGA_CFLAGS} ${OTBCFLAGS} ${GDAL_CFLAGS} ${XML2CFLAGS} ${PHPCFLAGS} ${PERLCFLAGS} ${JAVACFLAGS} ${PYTHONCFLAGS} ${CFLAGS} zoo_loader.o zoo_service_loader.o ${MS_FILE} ${PYTHON_FILE}  ${PERL_FILE} ${PHP_FILE}  ${JS_FILE} ${JAVA_FILE} ${YAML_FILE} ${OTB_FILE} ${SAGA_FILE} sqlapi.o response_print.o server_internal.o caching.o request_parser.o  ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o -o zoo_loader.cgi -L. ${LDFLAGS}
    83101
    84 zcfg2yaml: zcfg2yaml.c  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o service_internal.o ${MS_FILE} ${JS_FILE} ${RUBY_FILE} ${YAML_FILE}
     102zcfg2yaml: zcfg2yaml.c service.h lex.sr.o service_conf.tab.o service_conf.y main_conf_read.tab.o lex.cr.o response_print.o server_internal.o service_internal.o ${MS_FILE} ${YAML_FILE}
    85103        g++ -g -O2 ${JSCFLAGS} ${RUBYCFLAGS} ${XML2CFLAGS} ${CFLAGS} -c zcfg2yaml.c  -fno-common -DPIC -o zcfg2yaml.o
    86         g++  ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} zcfg2yaml.o service_internal.o ${MS_FILE} ${JS_FILE}  ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o  ${YAML_FILE} -o zcfg2yaml ${LDFLAGS}
     104        g++  ${XML2CFLAGS} ${CFLAGS} zcfg2yaml.o server_internal.o service_internal.o ${MS_FILE} response_print.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o  ${YAML_FILE} -o zcfg2yaml -L. ${LDFLAGS}
    87105
    88106install:
    89107        install -d ${CGI_DIR}
    90108        install zoo_loader.cgi ${CGI_DIR}/
    91         install main.cfg        ${CGI_DIR}/
     109        install libzoo_service.${EXT} ${DESTDIR}${INST_LIB}/libzoo_service.${VERSION}.${REVISION}.${EXT}
     110        (cd ${DESTDIR}${INST_LIB} ; \
     111         if [ -e "libzoo_service.${EXT}" ]; then rm  libzoo_service.${EXT}; fi ; \
     112         ln -s libzoo_service.${VERSION}.${REVISION}.${EXT} libzoo_service.${EXT})
     113        install -d ${DESTDIR}${INST_INCLUDE}/zoo
     114        install service.h service_internal.h ${DESTDIR}${INST_INCLUDE}/zoo
    92115
    93116clean:
    94         rm -f version.h *.o *.zo *.eo *.tab.c *.tab.h *.sr.c* service_loader lex.* *.lreg *.sibling service_loader.dSYM
     117        rm -f version.h *.o *.zo *.eo *.tab.c *.tab.h *.sr.c* service_loader lex.* *.lreg *.sibling service_loader.dSYM *${EXT}
  • trunk/zoo-project/zoo-kernel/ZOOMakefile.opts.in

    r634 r640  
     1prefix=@prefix@
     2exec_prefix=@exec_prefix@
     3PREFIX=@prefix@
     4INST_LIB=@libdir@
     5INST_INCLUDE=@includedir@
     6VERSION=1.5
     7REVISION=0
     8EXT=so
     9DEFAULT_OPTS=-Wl,-soname,libzoo_service.so.${VERSION}
    110OS:=$(shell uname -s)
    211ifeq ($(OS),Darwin)
     
    413        MACOS_LD_NET_FLAGS=-framework SystemConfiguration -framework CoreFoundation
    514        MACOS_CFLAGS=-arch $(shell uname -m)
     15        EXT=dylib
     16        DEFAULT_OPTS=-Wl,-compatibility_version,${VERSION},-current_version,${VERSION},-install_name,${DESTDIR}${INST_LIB}/libzoo_service.${VERSION}.${REVISION}.dylib
    617endif
    718
     
    8091
    8192CFLAGS=@DEB_DEF@ -fpic ${YAML_CFLAGS} ${MACOS_CFLAGS} ${MS_CFLAGS} -I../../thirds/cgic206 -I. -DLINUX_FREE_ISSUE #-DDEBUG #-DDEBUG_SERVICE_CONF
    82 LDFLAGS=-lcurl -L../../thirds/cgic206 -lcgic ${GDAL_LIBS} ${XML2LDFLAGS} ${PYTHONLDFLAGS} ${PERLLDFLAGS}  ${PHPLDFLAGS} ${JAVALDFLAGS} ${JSLDFLAGS} -lfcgi -lcrypto ${MS_LDFLAGS} ${MACOS_LD_FLAGS} ${MACOS_LD_NET_FLAGS} ${YAML_LDFLAGS} ${OTBLDFLAGS} ${SAGA_LDFLAGS}
     93LDFLAGS=-lzoo_service -lcurl -L../../thirds/cgic206 -lcgic ${GDAL_LIBS} ${XML2LDFLAGS} ${PYTHONLDFLAGS} ${PERLLDFLAGS}  ${PHPLDFLAGS} ${JAVALDFLAGS} ${JSLDFLAGS} -lfcgi -lcrypto ${MS_LDFLAGS} ${MACOS_LD_FLAGS} ${MACOS_LD_NET_FLAGS} ${YAML_LDFLAGS} ${OTBLDFLAGS} ${SAGA_LDFLAGS}
    8394
  • trunk/zoo-project/zoo-kernel/configure.ac

    r637 r640  
    5151AC_SUBST([CGI_DIR])
    5252
     53
     54# ===========================================================================
     55# Detect if libyaml is available
     56# ===========================================================================
     57
     58AC_ARG_WITH([yaml],
     59        [AS_HELP_STRING([--with-yaml=PATH], [specify an alternative location for the yaml library])],
     60        [YAMLPATH="$withval"], [YAMLPATH=""])
     61
     62if test -z "$YAMLPATH"
     63then
     64        YAML_LDFLAGS=""
     65        YAML_CPPFLAGS=""
     66        YAML_FILE=""
     67        YAML_FILE1=""
     68else
     69
     70        # Extract the linker and include flags
     71        YAML_LDFLAGS="-L$YAMLPATH/lib -lyaml"
     72        YAML_CPPFLAGS="-I$YAMLPATH/include -DYAML"
     73        YAML_FILE="service_yaml.o"
     74        YAML_FILE1="zcfg2yaml"
     75       
     76        # Check headers file
     77        CPPFLAGS_SAVE="$CPPFLAGS"
     78        CPPFLAGS="$YAML_CPPFLAGS"
     79        LIBS_SAVE="$LIBS"
     80        LIBS="$YAML_LDFLAGS"
     81        AC_CHECK_LIB([yaml], [yaml_parser_initialize,yaml_parser_set_input_file,yaml_parser_scan])
     82        AC_CHECK_HEADERS([yaml.h],
     83                 [], [AC_MSG_ERROR([could not find headers include related to YAML])])
     84        LIBS="$LIBS_SAVE"
     85fi
     86AC_SUBST([YAML_CPPFLAGS])
     87AC_SUBST([YAML_LDFLAGS])
     88AC_SUBST([YAML_FILE])
     89AC_SUBST([YAML_FILE1])
     90
     91# ===========================================================================
     92# Detect if fastcgi is available
     93# ===========================================================================
     94
     95AC_ARG_WITH([fastcgi],
     96        [AS_HELP_STRING([--with-fastcgi=PATH], [specify an alternative location for the fastcgi library])],
     97        [FCGIPATH="$withval"], [FCGIPATH="/usr"])
     98
     99# Extract the linker and include flags
     100FCGI_LDFLAGS="-L$FCGIPATH/lib"
     101FCGI_CPPFLAGS="-I$FCGIPATH/include"
     102
     103# Check headers file
     104CPPFLAGS_SAVE="$CPPFLAGS"
     105CPPFLAGS="$FCGI_CPPFLAGS"
     106LIBS_SAVE="$LIBS"
     107LIBS="$FCGI_LDFLAGS"
     108AC_CHECK_LIB([fcgi], [main])
     109AC_CHECK_HEADERS([fcgi_stdio.h],
     110                 [], [AC_MSG_ERROR([could not find headers include related to fastcgi])])
     111LIBS="$LIBS_SAVE"
     112AC_SUBST([FCGI_CPPFLAGS])
     113AC_SUBST([FCGI_LDFLAGS])
     114
     115# ===========================================================================
     116# Detect if libxml2 is installed
     117# ===========================================================================
     118
     119AC_ARG_WITH([xml2config],
     120        [AS_HELP_STRING([--with-xml2config=FILE], [specify an alternative xml2-config file])],
     121        [XML2CONFIG="$withval"], [XML2CONFIG=""])
     122
     123if test "x$XML2CONFIG" = "x"; then
     124        # XML2CONFIG was not specified, so search within the current path
     125        AC_PATH_PROG([XML2CONFIG], [xml2-config])
     126
     127        # If we couldn't find xml2-config, display a warning
     128        if test "x$XML2CONFIG" = "x"; then
     129                AC_MSG_ERROR([could not find xml2-config from libxml2 within the current path. You may need to try re-running configure with a --with-xml2config parameter.])
     130        fi
     131else
     132        # XML2CONFIG was specified; display a message to the user
     133        if test "x$XML2CONFIG" = "xyes"; then
     134                AC_MSG_ERROR([you must specify a parameter to --with-xml2config, e.g. --with-xml2config=/path/to/xml2-config])
     135        else
     136                if test -f $XML2CONFIG; then
     137                        AC_MSG_RESULT([Using user-specified xml2-config file: $XML2CONFIG])
     138                else
     139                        AC_MSG_ERROR([the user-specified xml2-config file $XML2CONFIG does not exist])
     140                fi     
     141        fi
     142fi
     143
     144# Extract the linker and include flags
     145XML2_LDFLAGS=`$XML2CONFIG --libs`
     146XML2_CPPFLAGS=`$XML2CONFIG --cflags`
     147
     148# Check headers file
     149CPPFLAGS_SAVE="$CPPFLAGS"
     150CPPFLAGS="$XML2_CPPFLAGS"
     151AC_CHECK_HEADERS([libxml/tree.h libxml/parser.h libxml/xpath.h libxml/xpathInternals.h],
     152                 [], [AC_MSG_ERROR([could not find headers include related to libxml2])])
     153
     154# Ensure we can link against libxml2
     155LIBS_SAVE="$LIBS"
     156LIBS="$XML2_LDFLAGS"
     157AC_CHECK_LIB([xml2], [xmlInitParser], [], [AC_MSG_ERROR([could not find libxml2])], [])
     158
     159AC_SUBST([XML2_CPPFLAGS])
     160AC_SUBST([XML2_LDFLAGS])
     161LIBS="$LIBS_SAVE"
     162
     163
     164# ===========================================================================
     165# Detect if libxslt is installed
     166# ===========================================================================
     167
     168AC_ARG_WITH([xsltconfig],
     169        [AS_HELP_STRING([--with-xsltconfig=FILE], [specify an alternative xslt-config file])],
     170        [XSLTCONFIG="$withval"], [XSLTCONFIG=""])
     171
     172if test "x$XSLTCONFIG" = "x"; then
     173        # XSLTCONFIG was not specified, so search within the current path
     174        AC_PATH_PROG([XSLTCONFIG], [xslt-config])
     175
     176        # If we couldn't find xslt-config, display a warning
     177        if test "x$XSLTCONFIG" = "x"; then
     178                AC_MSG_ERROR([could not find xslt-config from libxslt within the current path. You may need to try re-running configure with a --with-xtltconfig parameter.])
     179        fi
     180else
     181        # XSLTCONFIG was specified; display a message to the user
     182        if test "x$XSLTCONFIG" = "xyes"; then
     183                AC_MSG_ERROR([you must specify a parameter to --with-xsltconfig, e.g. --with-xsltconfig=/path/to/xslt-config])
     184        else
     185                if test -f $XSLTCONFIG; then
     186                        AC_MSG_RESULT([Using user-specified xslt-config file: $XSLTCONFIG])
     187                else
     188                        AC_MSG_ERROR([the user-specified xslt-config file $XSLTCONFIG does not exist])
     189                fi     
     190        fi
     191fi
     192
     193# Extract the linker and include flags
     194XSLT_LDFLAGS=`$XSLTCONFIG --libs`
     195XSLT_CPPFLAGS=`$XSLTCONFIG --cflags`
     196
     197# Check headers file
     198CPPFLAGS_SAVE="$CPPFLAGS"
     199CPPFLAGS="$XSLT_CPPFLAGS"
     200AC_CHECK_HEADERS([libxslt/xslt.h libxslt/xsltInternals.h libxslt/transform.h libxslt/xsltutils.h],
     201                 [], [AC_MSG_ERROR([could not find headers include related to libxlst])])
     202
     203AC_SUBST([XSLT_CPPFLAGS])
     204AC_SUBST([XSLT_LDFLAGS])
     205
     206#============================================================================
     207# Detect if gdal is installed
     208#============================================================================
     209
     210AC_ARG_WITH([gdal-config],
     211        [AS_HELP_STRING([--with-gdal-config=FILE], [specify an alternative gdal-config file])],
     212        [GDAL_CONFIG="$withval"], [GDAL_CONFIG=""])
     213if test -z $GDAL_CONFIG;
     214then
     215        AC_PATH_PROG([GDAL_CONFIG], [gdal-config])
     216        if test -z $GDAL_CONFIG;
     217        then
     218                AC_MSG_ERROR([could not find gdal-config from libgdal within the current path. You may need to try re-running configure with a --with-gdal-config parameter.])
     219        fi
     220       
     221else
     222        if test -f $GDAL_CONFIG; then
     223                AC_MSG_RESULT([Using user-specified gdal-config file: $GDAL_CONFIG])
     224        else
     225                AC_MSG_ERROR([the user-specified gdal-config file $GDAL_CONFIG does not exist])
     226        fi
     227fi
     228
     229GDAL_CFLAGS="`$GDAL_CONFIG --cflags`"
     230GDAL_LIBS="`$GDAL_CONFIG --libs`"
     231
     232AC_SUBST([GDAL_CFLAGS])
     233AC_SUBST([GDAL_LIBS])
     234
     235# ===========================================================================
     236# Detect if proj is installed
     237# ===========================================================================
     238
     239AC_ARG_WITH([proj],
     240        [AS_HELP_STRING([--with-proj=PATH], [specify an alternative location for PROJ4 setup])],
     241        [PROJPATH="$withval"], [PROJPATH=""])
     242
     243# Extract the linker and include flags
     244PROJ_LDFLAGS="-L$PROJPATH/lib"
     245PROJ_CPPFLAGS="-I$PROJPATH/include"
     246
     247# Check headers file
     248CPPFLAGS_SAVE="$CPPFLAGS"
     249CPPFLAGS="$PROJ_CPPFLAGS"
     250AC_CHECK_HEADERS([proj_api.h],
     251                 [], [AC_MSG_ERROR([could not find headers include related to PROJ4])])
     252
     253AC_SUBST([PROJ_CPPFLAGS])
     254AC_SUBST([PROJ_LDFLAGS])
     255
     256# ===========================================================================
     257# Detect if libgeos is installed
     258# ===========================================================================
     259
     260AC_ARG_WITH([geosconfig],
     261        [AS_HELP_STRING([--with-geosconfig=FILE], [specify an alternative geos-config file])],
     262        [GEOSCONFIG="$withval"], [GEOSCONFIG=""])
     263
     264if test "x$GEOSCONFIG" = "x"; then
     265        # GEOSCONFIG was not specified, so search within the current path
     266        AC_PATH_PROG([GEOSCONFIG], [geos-config])
     267
     268        # If we couldn't find geos-config, display a warning
     269        if test "x$GEOSCONFIG" = "x"; then
     270                AC_MSG_WARN([could not find geos-config from libgeos within the current path. You may need to try re-running configure with a --with-geosconfig parameter.])
     271        fi
     272else
     273        # GEOSCONFIG was specified; display a message to the user
     274        if test "x$GEOSCONFIG" = "xyes"; then
     275                AC_MSG_WARN([you must specify a parameter to --with-geosconfig, e.g. --with-geosconfig=/path/to/geos-config])
     276        else
     277                if test -f $GEOSCONFIG; then
     278                        AC_MSG_RESULT([Using user-specified geos-config file: $GEOSCONFIG])
     279                else
     280                        AC_MSG_ERROR([the user-specified geos-config file $GEOSCONFIG does not exist])
     281                fi     
     282        fi
     283fi
     284
     285GEOS_LDFLAGS=`$GEOSCONFIG --libs`
     286GEOS_CPPFLAGS=`$GEOSCONFIG --cflags`
     287
     288# Check headers file
     289CPPFLAGS_SAVE="$CPPFLAGS"
     290CPPFLAGS="$GEOS_CPPFLAGS"
     291AC_CHECK_HEADERS([geos_c.h],
     292                 [], [AC_MSG_WARN([could not find headers include related to libgeos])])
     293
     294AC_SUBST([GEOS_CPPFLAGS])
     295AC_SUBST([GEOS_LDFLAGS])
     296
     297
     298# ===========================================================================
     299# Detect if cgal is installed
     300# ===========================================================================
     301
     302AC_ARG_WITH([cgal],
     303        [AS_HELP_STRING([--with-cgal=PATH], [specify an alternative location for CGAL setup])],
     304        [CGALPATH="$withval"], [CGALPATH="/usr"])
     305
     306
     307# Check headers file
     308CPPFLAGS_SAVE="$CPPFLAGS"
     309CPPFLAGS="$CGAL_CPPFLAGS"
     310AC_CHECK_HEADERS([CGAL/Delaunay_triangulation_2.h],
     311         [], [AC_MSG_WARN([could not find headers include related to libCGAL])])
     312
     313# Extract the linker and include flags
     314CGAL_LDFLAGS="-L$CGALPATH/lib"
     315CGAL_CPPFLAGS="-I$CGALPATH/include"
     316
     317
     318AC_SUBST([CGAL_CPPFLAGS])
     319AC_SUBST([CGAL_LDFLAGS])
     320#============================================================================
     321# Detect if mapserver is installed
     322#============================================================================
     323
     324AC_ARG_WITH([mapserver],
     325       [AS_HELP_STRING([--with-mapserver=PATH], [specify the path for MapServer compiled source tree])],
     326       [MS_SRC_PATH="$withval"], [MS_SRC_PATH=""])
     327
     328if test -z $MS_SRC_PATH;
     329then
     330        MS_CPPFLAGS=""
     331        MS_LDFLAGS=""
     332else
     333       if test "x$MS_SRC_PATH" = "xmacos";
     334       then
     335               MS_LDFLAGS="/Library/Frameworks/MapServer.framework//Versions/6.0/MapServer -lintl"
     336               MS_CPPFLAGS="-DUSE_MS `/Library/Frameworks/MapServer.framework/Programs/mapserver-config --includes` -I/Library/Frameworks/MapServer.framework/Versions/Current/Headers/ -I../mapserver "
     337               AC_MSG_WARN([Please make sure that ../mapserver exists and contains MapServer source tree])
     338               AC_MSG_RESULT([Using MacOS X Framework for MapServer])
     339       else
     340               if test -d $MS_SRC_PATH; then
     341                       MS_LDFLAGS="-L$MS_SRC_PATH -lmapserver `$MS_SRC_PATH/mapserver-config --libs`"
     342                       MS_CPPFLAGS="-DUSE_MS `$MS_SRC_PATH/mapserver-config --includes` `$MS_SRC_PATH/mapserver-config --cflags` -I$MS_SRC_PATH "
     343               
     344                       AC_MSG_RESULT([Using user-specified MapServer src path: $MS_SRC_PATH])
     345               else
     346                       AC_MSG_ERROR([the user-specified mapserver-config file $MS_SRC_PATH does not exist])
     347               fi
     348       fi
     349       MS_FILE="service_internal_ms.o"
     350fi
     351
     352MS_CFLAGS="$MS_CPPFLAGS"
     353MS_LIBS="$MS_LDFLAGS"
     354
     355AC_SUBST([MS_CFLAGS])
     356AC_SUBST([MS_LIBS])
     357AC_SUBST([MS_FILE])
     358
    53359# ===========================================================================
    54360# Detect if python is installed
     
    100406        AC_SUBST([PYTHON_CPPFLAGS])
    101407        AC_SUBST([PYTHON_LDFLAGS])
     408        LIBS="$LIBS_SAVE"
    102409fi
    103410
     
    151458        CPPFLAGS_SAVE="$CPPFLAGS"
    152459        CPPFLAGS="$JS_CPPFLAGS"
    153 
    154         #AC_CHECK_HEADERS([jsapi.h],
    155         #                [], [AC_MSG_ERROR([could not find headers include related to libjs])])
    156 
    157        
     460        AC_LANG_PUSH([C++])
     461        AC_CHECK_HEADERS([jsapi.h],
     462                        [], [AC_MSG_ERROR([could not find headers include related to libjs])])
     463
     464        AC_LANG_POP([C++])
    158465        LIBS_SAVE="$LIBS"
    159466        LIBS="$JS_LDFLAGS"
    160467
    161468        AC_CHECK_LIB([$JS_LIB], [JS_CompileFile,JS_CallFunctionName], [], [AC_MSG_ERROR([could not find $JS_LIB])], [])
    162                        
     469        LIBS="$LIBS_SAVE"
     470       
    163471        AC_SUBST([JS_CPPFLAGS])
    164472        AC_SUBST([JS_LDFLAGS])
     
    206514        # Shouldn't we get php here rather than php5 :) ??
    207515        AC_CHECK_LIB([php5], [call_user_function], [], [AC_MSG_ERROR([could not find libphp])], [])
     516        LIBS="$LIBS_SAVE"
    208517        AC_SUBST([PHP_CPPFLAGS])
    209518        AC_SUBST([PHP_LDFLAGS])
     
    264573                AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], [], [AC_MSG_ERROR([could not find libjvm])], [])
    265574        fi
     575        LIBS="$LIBS_SAVE"
    266576
    267577        AC_SUBST([JAVA_CPPFLAGS])
     
    304614        LIBS="$RUBY_LDFLAGS"
    305615        # AC_CHECK_LIB([lruby], [PyObject_CallObject], [], [AC_MSG_ERROR([could not find libpython])], [])
     616        LIBS="$LIBS_SAVE"
    306617        AC_SUBST([RUBY_CPPFLAGS])
    307618        AC_SUBST([RUBY_LDFLAGS])
     
    387698        CPPFLAGS="$OTB_CPPFLAGS"
    388699        LDFLAGS_SAVE="$LDFLAGS"
    389         LDFLAGS="$OTB_LDFLAGS"
     700        LIBS="$LIBS_SAVE $OTB_LDFLAGS"
    390701        AC_CHECK_HEADERS([otbWrapperApplication.h otbWrapperInputImageListParameter.h otbWrapperApplicationRegistry.h],
    391702                        [], [AC_MSG_ERROR([could not find header file $i related to OTB])])
    392703        AC_LANG_POP([C++])
     704        AC_LANG(C++)
     705        LDFLAGS_SAVE="$LDFLAGS"
     706        LDFLAGS="$OTB_LDFLAGS"
     707        AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "otbWrapperApplication.h"],[std::vector<std::string> list = otb::Wrapwper::ApplicationRegistry::GetAvailableApplication();]])],
     708                [AC_MSG_RESULT([checking for GetAvailableApplication... yes])],[AC_MSG_ERROR([checking for GetAvailableApplication... failed])])
     709        LDFLAGS="$LDFLAGS_SAVE"
     710                       
    393711fi
    394712AC_SUBST([OTB_CPPFLAGS])
     
    435753        LIBS_SAVE="$LIBS"
    436754        LIBS="$SAGA_LDFLAGS"
    437         AC_MSG_RESULT(CPPFLAGS are $CPPFLAGS)
    438755        AC_CHECK_HEADERS([module_library.h],
    439756                        [], [AC_MSG_ERROR([could not find header file $i related to SAGA-GIS])])
    440         LIBS_SAVE="$LIBS"
    441         AC_CHECK_LIB([saga_api], [SG_Set_UI_Callback,SG_Get_Module_Library_Manager])
     757        AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "module_library.h"],[SG_Get_Module_Library_Manager();]])],
     758                [AC_MSG_RESULT([checking for SG_Get_Module_Library_Manager... yes])],[AC_MSG_ERROR([checking for SG_Get_Module_Library_Manager... failed])])
     759        LIBS="$LIBS_SAVE"
    442760        AC_LANG_POP([C++])
    443761fi
     
    447765AC_SUBST([SAGA_ENABLED])
    448766
    449 # ===========================================================================
    450 # Detect if libyaml is available
    451 # ===========================================================================
    452 
    453 AC_ARG_WITH([yaml],
    454         [AS_HELP_STRING([--with-yaml=PATH], [specify an alternative location for the yaml library])],
    455         [YAMLPATH="$withval"], [YAMLPATH=""])
    456 
    457 if test -z "$YAMLPATH"
    458 then
    459         YAML_LDFLAGS=""
    460         YAML_CPPFLAGS=""
    461         YAML_FILE=""
    462         YAML_FILE1=""
    463 else
    464 
    465         # Extract the linker and include flags
    466         YAML_LDFLAGS="-L$YAMLPATH/lib -lyaml"
    467         YAML_CPPFLAGS="-I$YAMLPATH/include -DYAML"
    468         YAML_FILE="service_yaml.o"
    469         YAML_FILE1="zcfg2yaml"
    470        
    471         # Check headers file
    472         CPPFLAGS_SAVE="$CPPFLAGS"
    473         CPPFLAGS="$YAML_CPPFLAGS"
    474         LIBS_SAVE="$LIBS"
    475         LIBS="$YAML_LDFLAGS"
    476         AC_CHECK_LIB([yaml], [yaml_parser_initialize,yaml_parser_set_input_file,yaml_parser_scan])
    477         AC_CHECK_HEADERS([yaml.h],
    478                  [], [AC_MSG_ERROR([could not find headers include related to YAML])])
    479         LIBS="$LIBS_SAVE"
    480 fi
    481 AC_SUBST([YAML_CPPFLAGS])
    482 AC_SUBST([YAML_LDFLAGS])
    483 AC_SUBST([YAML_FILE])
    484 AC_SUBST([YAML_FILE1])
    485 
    486 # ===========================================================================
    487 # Detect if fastcgi is available
    488 # ===========================================================================
    489 
    490 AC_ARG_WITH([fastcgi],
    491         [AS_HELP_STRING([--with-fastcgi=PATH], [specify an alternative location for the fastcgi library])],
    492         [FCGIPATH="$withval"], [FCGIPATH="/usr"])
    493 
    494 # Extract the linker and include flags
    495 FCGI_LDFLAGS="-L$FCGIPATH/lib"
    496 FCGI_CPPFLAGS="-I$FCGIPATH/include"
    497 
    498 # Check headers file
    499 CPPFLAGS_SAVE="$CPPFLAGS"
    500 CPPFLAGS="$FCGI_CPPFLAGS"
    501 LIBS_SAVE="$LIBS"
    502 LIBS="$FCGI_LDFLAGS"
    503 AC_CHECK_LIB([fcgi], [main])
    504 AC_CHECK_HEADERS([fcgi_stdio.h],
    505                  [], [AC_MSG_ERROR([could not find headers include related to fastcgi])])
    506 LIBS="$LIBS_SAVE"
    507 AC_SUBST([FCGI_CPPFLAGS])
    508 AC_SUBST([FCGI_LDFLAGS])
    509 
    510 
    511 # ===========================================================================
    512 # Detect if libxml2 is installed
    513 # ===========================================================================
    514 
    515 AC_ARG_WITH([xml2config],
    516         [AS_HELP_STRING([--with-xml2config=FILE], [specify an alternative xml2-config file])],
    517         [XML2CONFIG="$withval"], [XML2CONFIG=""])
    518 
    519 if test "x$XML2CONFIG" = "x"; then
    520         # XML2CONFIG was not specified, so search within the current path
    521         AC_PATH_PROG([XML2CONFIG], [xml2-config])
    522 
    523         # If we couldn't find xml2-config, display a warning
    524         if test "x$XML2CONFIG" = "x"; then
    525                 AC_MSG_ERROR([could not find xml2-config from libxml2 within the current path. You may need to try re-running configure with a --with-xml2config parameter.])
    526         fi
    527 else
    528         # XML2CONFIG was specified; display a message to the user
    529         if test "x$XML2CONFIG" = "xyes"; then
    530                 AC_MSG_ERROR([you must specify a parameter to --with-xml2config, e.g. --with-xml2config=/path/to/xml2-config])
    531         else
    532                 if test -f $XML2CONFIG; then
    533                         AC_MSG_RESULT([Using user-specified xml2-config file: $XML2CONFIG])
    534                 else
    535                         AC_MSG_ERROR([the user-specified xml2-config file $XML2CONFIG does not exist])
    536                 fi     
    537         fi
    538 fi
    539 
    540 # Extract the linker and include flags
    541 XML2_LDFLAGS=`$XML2CONFIG --libs`
    542 XML2_CPPFLAGS=`$XML2CONFIG --cflags`
    543 
    544 # Check headers file
    545 CPPFLAGS_SAVE="$CPPFLAGS"
    546 CPPFLAGS="$XML2_CPPFLAGS"
    547 AC_CHECK_HEADERS([libxml/tree.h libxml/parser.h libxml/xpath.h libxml/xpathInternals.h],
    548                  [], [AC_MSG_ERROR([could not find headers include related to libxml2])])
    549 
    550 # Ensure we can link against libxml2
    551 LIBS_SAVE="$LIBS"
    552 LIBS="$XML2_LDFLAGS"
    553 AC_CHECK_LIB([xml2], [xmlInitParser], [], [AC_MSG_ERROR([could not find libxml2])], [])
    554 
    555 AC_SUBST([XML2_CPPFLAGS])
    556 AC_SUBST([XML2_LDFLAGS])
    557 
    558 # ===========================================================================
    559 # Detect if libxslt is installed
    560 # ===========================================================================
    561 
    562 AC_ARG_WITH([xsltconfig],
    563         [AS_HELP_STRING([--with-xsltconfig=FILE], [specify an alternative xslt-config file])],
    564         [XSLTCONFIG="$withval"], [XSLTCONFIG=""])
    565 
    566 if test "x$XSLTCONFIG" = "x"; then
    567         # XSLTCONFIG was not specified, so search within the current path
    568         AC_PATH_PROG([XSLTCONFIG], [xslt-config])
    569 
    570         # If we couldn't find xslt-config, display a warning
    571         if test "x$XSLTCONFIG" = "x"; then
    572                 AC_MSG_ERROR([could not find xslt-config from libxslt within the current path. You may need to try re-running configure with a --with-xtltconfig parameter.])
    573         fi
    574 else
    575         # XSLTCONFIG was specified; display a message to the user
    576         if test "x$XSLTCONFIG" = "xyes"; then
    577                 AC_MSG_ERROR([you must specify a parameter to --with-xsltconfig, e.g. --with-xsltconfig=/path/to/xslt-config])
    578         else
    579                 if test -f $XSLTCONFIG; then
    580                         AC_MSG_RESULT([Using user-specified xslt-config file: $XSLTCONFIG])
    581                 else
    582                         AC_MSG_ERROR([the user-specified xslt-config file $XSLTCONFIG does not exist])
    583                 fi     
    584         fi
    585 fi
    586 
    587 # Extract the linker and include flags
    588 XSLT_LDFLAGS=`$XSLTCONFIG --libs`
    589 XSLT_CPPFLAGS=`$XSLTCONFIG --cflags`
    590 
    591 # Check headers file
    592 CPPFLAGS_SAVE="$CPPFLAGS"
    593 CPPFLAGS="$XSLT_CPPFLAGS"
    594 AC_CHECK_HEADERS([libxslt/xslt.h libxslt/xsltInternals.h libxslt/transform.h libxslt/xsltutils.h],
    595                  [], [AC_MSG_ERROR([could not find headers include related to libxlst])])
    596 
    597 AC_SUBST([XSLT_CPPFLAGS])
    598 AC_SUBST([XSLT_LDFLAGS])
    599 
    600 #============================================================================
    601 # Detect if gdal is installed
    602 #============================================================================
    603 
    604 AC_ARG_WITH([gdal-config],
    605         [AS_HELP_STRING([--with-gdal-config=FILE], [specify an alternative gdal-config file])],
    606         [GDAL_CONFIG="$withval"], [GDAL_CONFIG=""])
    607 if test -z $GDAL_CONFIG;
    608 then
    609         AC_PATH_PROG([GDAL_CONFIG], [gdal-config])
    610         if test -z $GDAL_CONFIG;
    611         then
    612                 AC_MSG_ERROR([could not find gdal-config from libgdal within the current path. You may need to try re-running configure with a --with-gdal-config parameter.])
    613         fi
    614        
    615 else
    616         if test -f $GDAL_CONFIG; then
    617                 AC_MSG_RESULT([Using user-specified gdal-config file: $GDAL_CONFIG])
    618         else
    619                 AC_MSG_ERROR([the user-specified gdal-config file $GDAL_CONFIG does not exist])
    620         fi
    621 fi
    622 
    623 GDAL_CFLAGS="`$GDAL_CONFIG --cflags`"
    624 GDAL_LIBS="`$GDAL_CONFIG --libs`"
    625 
    626 AC_SUBST([GDAL_CFLAGS])
    627 AC_SUBST([GDAL_LIBS])
    628 
    629 # ===========================================================================
    630 # Detect if proj is installed
    631 # ===========================================================================
    632 
    633 AC_ARG_WITH([proj],
    634         [AS_HELP_STRING([--with-proj=PATH], [specify an alternative location for PROJ4 setup])],
    635         [PROJPATH="$withval"], [PROJPATH=""])
    636 
    637 # Extract the linker and include flags
    638 PROJ_LDFLAGS="-L$PROJPATH/lib"
    639 PROJ_CPPFLAGS="-I$PROJPATH/include"
    640 
    641 # Check headers file
    642 CPPFLAGS_SAVE="$CPPFLAGS"
    643 CPPFLAGS="$PROJ_CPPFLAGS"
    644 AC_CHECK_HEADERS([proj_api.h],
    645                  [], [AC_MSG_ERROR([could not find headers include related to PROJ4])])
    646 
    647 AC_SUBST([PROJ_CPPFLAGS])
    648 AC_SUBST([PROJ_LDFLAGS])
    649 
    650 # ===========================================================================
    651 # Detect if libgeos is installed
    652 # ===========================================================================
    653 
    654 AC_ARG_WITH([geosconfig],
    655         [AS_HELP_STRING([--with-geosconfig=FILE], [specify an alternative geos-config file])],
    656         [GEOSCONFIG="$withval"], [GEOSCONFIG=""])
    657 
    658 if test "x$GEOSCONFIG" = "x"; then
    659         # GEOSCONFIG was not specified, so search within the current path
    660         AC_PATH_PROG([GEOSCONFIG], [geos-config])
    661 
    662         # If we couldn't find geos-config, display a warning
    663         if test "x$GEOSCONFIG" = "x"; then
    664                 AC_MSG_WARN([could not find geos-config from libgeos within the current path. You may need to try re-running configure with a --with-geosconfig parameter.])
    665         fi
    666 else
    667         # GEOSCONFIG was specified; display a message to the user
    668         if test "x$GEOSCONFIG" = "xyes"; then
    669                 AC_MSG_WARN([you must specify a parameter to --with-geosconfig, e.g. --with-geosconfig=/path/to/geos-config])
    670         else
    671                 if test -f $GEOSCONFIG; then
    672                         AC_MSG_RESULT([Using user-specified geos-config file: $GEOSCONFIG])
    673                 else
    674                         AC_MSG_ERROR([the user-specified geos-config file $GEOSCONFIG does not exist])
    675                 fi     
    676         fi
    677 fi
    678 
    679 GEOS_LDFLAGS=`$GEOSCONFIG --libs`
    680 GEOS_CPPFLAGS=`$GEOSCONFIG --cflags`
    681 
    682 # Check headers file
    683 CPPFLAGS_SAVE="$CPPFLAGS"
    684 CPPFLAGS="$GEOS_CPPFLAGS"
    685 AC_CHECK_HEADERS([geos_c.h],
    686                  [], [AC_MSG_WARN([could not find headers include related to libgeos])])
    687 
    688 AC_SUBST([GEOS_CPPFLAGS])
    689 AC_SUBST([GEOS_LDFLAGS])
    690 
    691 
    692 # ===========================================================================
    693 # Detect if cgal is installed
    694 # ===========================================================================
    695 
    696 AC_ARG_WITH([cgal],
    697         [AS_HELP_STRING([--with-cgal=PATH], [specify an alternative location for CGAL setup])],
    698         [CGALPATH="$withval"], [CGALPATH="/usr"])
    699 
    700 
    701 # Check headers file
    702 CPPFLAGS_SAVE="$CPPFLAGS"
    703 CPPFLAGS="$CGAL_CPPFLAGS"
    704 AC_CHECK_HEADERS([CGAL/Delaunay_triangulation_2.h],
    705          [], [AC_MSG_WARN([could not find headers include related to libCGAL])])
    706 
    707 # Extract the linker and include flags
    708 CGAL_LDFLAGS="-L$CGALPATH/lib"
    709 CGAL_CPPFLAGS="-I$CGALPATH/include"
    710 
    711 
    712 AC_SUBST([CGAL_CPPFLAGS])
    713 AC_SUBST([CGAL_LDFLAGS])
    714 #============================================================================
    715 # Detect if mapserver is installed
    716 #============================================================================
    717 
    718 AC_ARG_WITH([mapserver],
    719        [AS_HELP_STRING([--with-mapserver=PATH], [specify the path for MapServer compiled source tree])],
    720        [MS_SRC_PATH="$withval"], [MS_SRC_PATH=""])
    721 
    722 if test -z $MS_SRC_PATH;
    723 then
    724         MS_CPPFLAGS=""
    725         MS_LDFLAGS=""
    726 else
    727        if test "x$MS_SRC_PATH" = "xmacos";
    728        then
    729                MS_LDFLAGS="/Library/Frameworks/MapServer.framework//Versions/6.0/MapServer -lintl"
    730                MS_CPPFLAGS="-DUSE_MS `/Library/Frameworks/MapServer.framework/Programs/mapserver-config --includes` -I/Library/Frameworks/MapServer.framework/Versions/Current/Headers/ -I../mapserver "
    731                AC_MSG_WARN([Please make sure that ../mapserver exists and contains MapServer source tree])
    732                AC_MSG_RESULT([Using MacOS X Framework for MapServer])
    733        else
    734                if test -d $MS_SRC_PATH; then
    735                        MS_LDFLAGS="-L$MS_SRC_PATH -lmapserver `$MS_SRC_PATH/mapserver-config --libs`"
    736                        MS_CPPFLAGS="-DUSE_MS `$MS_SRC_PATH/mapserver-config --includes` `$MS_SRC_PATH/mapserver-config --cflags` -I$MS_SRC_PATH "
    737                
    738                        AC_MSG_RESULT([Using user-specified MapServer src path: $MS_SRC_PATH])
    739                else
    740                        AC_MSG_ERROR([the user-specified mapserver-config file $MS_SRC_PATH does not exist])
    741                fi
    742        fi
    743        MS_FILE="service_internal_ms.o"
    744 fi
    745 
    746 MS_CFLAGS="$MS_CPPFLAGS"
    747 MS_LIBS="$MS_LDFLAGS"
    748 
    749 AC_SUBST([MS_CFLAGS])
    750 AC_SUBST([MS_LIBS])
    751 AC_SUBST([MS_FILE])
    752 
    753767AC_CONFIG_FILES([Makefile])
    754768AC_CONFIG_FILES([ZOOMakefile.opts])
  • trunk/zoo-project/zoo-kernel/request_parser.c

    r631 r640  
    2525#include "request_parser.h"
    2626#include "service_internal.h"
     27#include "server_internal.h"
     28#include "response_print.h"
     29#include "caching.h"
    2730
    2831/**
     
    127130    }
    128131  return 0;
     132}
     133
     134/**
     135 * Make sure that each value encoded in base64 in a maps is decoded.
     136 *
     137 * @param in the maps containing the values
     138 * @see readBase64
     139 */
     140void ensureDecodedBase64(maps **in){
     141  maps* cursor=*in;
     142  while(cursor!=NULL){
     143    map *tmp=getMap(cursor->content,"encoding");
     144    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
     145      tmp=getMap(cursor->content,"value");
     146      readBase64(&tmp);
     147      addToMap(cursor->content,"base64_value",tmp->value);
     148      int size=0;
     149      char *s=strdup(tmp->value);
     150      free(tmp->value);
     151      tmp->value=base64d(s,strlen(s),&size);
     152      free(s);
     153      char sizes[1024];
     154      sprintf(sizes,"%d",size);
     155      addToMap(cursor->content,"size",sizes);
     156    }
     157    map* length=getMap(cursor->content,"length");
     158    if(length!=NULL){
     159      int len=atoi(length->value);
     160      for(int i=1;i<len;i++){
     161        tmp=getMapArray(cursor->content,"encoding",i);
     162        if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
     163          char key[17];
     164          sprintf(key,"base64_value_%d",i);
     165          tmp=getMapArray(cursor->content,"value",i);
     166          readBase64(&tmp);
     167          addToMap(cursor->content,key,tmp->value);
     168          int size=0;
     169          char *s=strdup(tmp->value);
     170          free(tmp->value);
     171          tmp->value=base64d(s,strlen(s),&size);
     172          free(s);
     173          char sizes[1024];
     174          sprintf(sizes,"%d",size);
     175          sprintf(key,"size_%d",i);
     176          addToMap(cursor->content,key,sizes);
     177        }
     178      }
     179    }
     180    cursor=cursor->next;
     181  }
    129182}
    130183
     
    14481501  return 1;
    14491502}
     1503
     1504
     1505/**
     1506 * Verify if a parameter value is valid.
     1507 *
     1508 * @param request the request map
     1509 * @param res the error map potentially generated
     1510 * @param toCheck the parameter to use
     1511 * @param avalues the acceptable values (or null if testing only for presence)
     1512 * @param mandatory verify the presence of the parameter if mandatory > 0
     1513 */
     1514void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
     1515  map* lres=*res;
     1516  map* r_inputs = getMap (request,toCheck);
     1517  if (r_inputs == NULL){
     1518    if(mandatory>0){
     1519      char *replace=_("Mandatory parameter <%s> was not specified");
     1520      char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
     1521      sprintf(message,replace,toCheck);
     1522      if(lres==NULL){
     1523        lres=createMap("code","MissingParameterValue");
     1524        addToMap(lres,"text",message);
     1525        addToMap(lres,"locator",toCheck);       
     1526      }else{
     1527        int length=1;
     1528        map* len=getMap(lres,"length");
     1529        if(len!=NULL){
     1530          length=atoi(len->value);
     1531        }
     1532        setMapArray(lres,"text",length,message);
     1533        setMapArray(lres,"locator",length,toCheck);
     1534        setMapArray(lres,"code",length,"MissingParameter");
     1535      }
     1536      free(message);
     1537    }
     1538  }else{
     1539    if(avalues==NULL)
     1540      return;
     1541    int nb=0;
     1542    int hasValidValue=-1;
     1543    if(strncasecmp(toCheck,"Accept",6)==0){
     1544      char *tmp=zStrdup(r_inputs->value);
     1545      char *pToken,*saveptr;
     1546      pToken=strtok_r(tmp,",",&saveptr);
     1547      while(pToken!=NULL){
     1548        while(avalues[nb]!=NULL){
     1549          if(strcasecmp(avalues[nb],pToken)==0){
     1550            hasValidValue=1;
     1551            break;
     1552          }
     1553          nb++;
     1554        }
     1555        pToken=strtok_r(NULL,",",&saveptr);
     1556      }
     1557      free(tmp);
     1558    }else{
     1559      while(avalues[nb]!=NULL){
     1560        if(strcasecmp(avalues[nb],r_inputs->value)==0){
     1561          hasValidValue=1;
     1562          break;
     1563        }
     1564        nb++;
     1565      }
     1566    }
     1567    if(hasValidValue<0){
     1568      char *replace=_("The value <%s> was not recognized, %s %s the only acceptable value.");
     1569      nb=0;
     1570      char *vvalues=NULL;
     1571      char* num=_("is");
     1572      while(avalues[nb]!=NULL){
     1573        char *tvalues;
     1574        if(vvalues==NULL){
     1575          vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
     1576          sprintf(vvalues,"%s",avalues[nb]);
     1577        }
     1578        else{
     1579          tvalues=zStrdup(vvalues);
     1580          vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
     1581          sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
     1582          free(tvalues);
     1583          num=_("are");
     1584        }
     1585        nb++;
     1586      }
     1587      char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
     1588      sprintf(message,replace,toCheck,vvalues,num);
     1589      const char *code="VersionNegotiationFailed";
     1590      code="InvalidParameterValue";
     1591      const char *locator=toCheck;
     1592      if( strncasecmp(toCheck,"version",7)==0 ||
     1593          strncasecmp(toCheck,"AcceptVersions",14)==0 )
     1594        code="VersionNegotiationFailed";
     1595      if( strncasecmp(toCheck,"request",7)==0){
     1596        code="OperationNotSupported";
     1597        locator=r_inputs->value;
     1598      }
     1599      if(lres==NULL){
     1600        lres=createMap("code","InvalidParameterValue");
     1601        addToMap(lres,"text",message);
     1602        addToMap(lres,"locator",locator);       
     1603      }else{
     1604        int length=1;
     1605        map* len=getMap(lres,"length");
     1606        if(len!=NULL){
     1607          length=atoi(len->value);
     1608        }
     1609        setMapArray(lres,"text",length,message);
     1610        setMapArray(lres,"locator",length,locator);
     1611        setMapArray(lres,"code",length,"InvalidParameterValue");
     1612      }
     1613    }
     1614  }
     1615  if(lres!=NULL){
     1616    *res=lres;
     1617  }
     1618}
  • trunk/zoo-project/zoo-kernel/request_parser.h

    r621 r640  
    2323 */
    2424
    25 #ifndef SERVICE_PARSER_H
    26 #define SERVICE_PARSER_H 1
     25#ifndef ZOO_REQUEST_PARSER_H
     26#define ZOO_REQUEST_PARSER_H 1
    2727
    2828#pragma once
     
    3939  xmlXPathObjectPtr extractFromDoc (xmlDocPtr, const char *);
    4040  int appendMapsToMaps (maps*, maps*, maps*, elements*);
     41  void ensureDecodedBase64(maps**);
    4142  int kvpParseInputs(maps**,service*,map*,maps**,HINTERNET*);
    4243  int kvpParseOutputs(maps**,map *,maps**);
     
    4546  int xmlParseRequest(maps**,const char*,map**,service*,maps**,maps**,HINTERNET*);
    4647  int parseRequest(maps**,map**,service*,maps**,maps**,HINTERNET*);
     48  void checkValidValue(map*,map**,const char*,const char**,int);
    4749  int validateRequest(maps**,service*,map*,maps**,maps**,HINTERNET*);
    4850
  • trunk/zoo-project/zoo-kernel/service.h

    r631 r640  
    144144 * The memory size to create an elements
    145145 */
    146 #define ELEMENTS_SIZE (sizeof(char*)+(((2*sizeof(char*))+sizeof(maps*))*2)+sizeof(char*)+(((2*sizeof(char*))+sizeof(iotype*))*2)+sizeof(elements*))
     146#define ELEMENTS_SIZE (sizeof(char*)+(((2*sizeof(char*))+sizeof(maps*))*2)+sizeof(char*)+(((2*sizeof(char*))+sizeof(iotype*))*2)+(2*sizeof(elements*)))
    147147/**
    148148 * The memory size to create a map
     
    206206    struct maps* next; //!< the pointer to the next maps if any or NULL
    207207  } maps;
    208 
    209   /**
    210    * Dump a map on stderr
    211    *
    212    * @param t the map to dump
    213    */
    214   static void _dumpMap(map* t){
    215     if(t!=NULL){
    216       fprintf(stderr,"%s: %s\n",t->name,t->value);
    217       fflush(stderr);
    218         }else{
    219       fprintf(stderr,"NULL\n");
    220       fflush(stderr);
    221     }
    222   }
    223 
    224   /**
    225    * Dump a map on stderr, see _dumpMap()
    226    *
    227    * @param t the map to dump
    228    */
    229   static void dumpMap(map* t){
    230     map* tmp=t;
    231     while(tmp!=NULL){
    232       _dumpMap(tmp);
    233       tmp=tmp->next;
    234     }
    235   }
    236 
    237   /**
    238    * Dump a map to a file
    239    *
    240    * @param t the map to dump to file
    241    * @param file the file to store the map
    242    */
    243   static void dumpMapToFile(map* t,FILE* file){
    244     map* tmp=t;
    245     while(tmp!=NULL){
    246 #ifdef DEBUG
    247       fprintf(stderr,"%s = %s\n",tmp->name,tmp->value);
    248 #endif
    249       fprintf(file,"%s = %s\n",tmp->name,tmp->value);
    250       tmp=tmp->next;
    251     }
    252   }
    253208 
    254   /**
    255    * Dump a maps on stderr, see dumpMap().
    256    *
    257    * @param m the map to dump
    258    */
    259   static void dumpMaps(maps* m){
    260     maps* tmp=m;
    261     while(tmp!=NULL){
    262       fprintf(stderr,"MAP => [%s] \n",tmp->name);
    263       dumpMap(tmp->content);
    264       tmp=tmp->next;
    265     }
    266   }
    267 
    268   /**
    269    * Dump a maps to a file, see dumpMapToFile().
    270    *
    271    * @param m the map to dump
    272    * @param file_path the full path to the file name to store the map
    273    */
    274   static void dumpMapsToFile(maps* m,char* file_path){
    275     FILE* file=fopen(file_path,"w");
    276     maps* tmp=m;
    277     if(tmp!=NULL){
    278       fprintf(file,"[%s]\n",tmp->name);
    279       dumpMapToFile(tmp->content,file);
    280       fflush(file);
    281     }
    282     fclose(file);
    283   }
    284  
    285   /**
    286    * Create a new map
    287    *
    288    * @param name the key to add to the map
    289    * @param value the corresponding value to add to the map
    290    * @return the allocated map
    291    */
    292   static map* createMap(const char* name,const char* value){
    293     map* tmp=(map *)malloc(MAP_SIZE);
    294     tmp->name=zStrdup(name);
    295     tmp->value=zStrdup(value);
    296     tmp->next=NULL;
    297     return tmp;
    298   }
    299 
    300   /**
    301    * Count number of map in a map
    302    *
    303    * @param m the maps to count
    304    * @return number of map in a map
    305    */
    306   static int count(map* m){
    307     map* tmp=m;
    308     int c=0;
    309     while(tmp!=NULL){
    310       c++;
    311       tmp=tmp->next;
    312     }
    313     return c;
    314   }
    315    
    316   /**
    317    * Verify if a key exist in a map
    318    *
    319    * @param m the map to search for the key
    320    * @param key the key to search in the map
    321    * @return true if the key wwas found, false in other case
    322    */
    323   static bool hasKey(map* m,const char *key){
    324     map* tmp=m;
    325     while(tmp!=NULL){
    326       if(strcasecmp(tmp->name,key)==0)
    327         return true;
    328       tmp=tmp->next;
    329     }
    330 #ifdef DEBUG_MAP
    331     fprintf(stderr,"NOT FOUND \n");
    332 #endif
    333     return false;
    334   }
    335 
    336   /**
    337    * Access a specific maps
    338    *
    339    * @param m the maps to search for the key
    340    * @param key the key to search in the maps
    341    * @return a pointer on the maps found or NULL if not found
    342    */
    343   static maps* getMaps(maps* m,const char *key){
    344     maps* tmp=m;
    345     while(tmp!=NULL){
    346       if(strcasecmp(tmp->name,key)==0){
    347         return tmp;
    348       }
    349       tmp=tmp->next;
    350     }
    351     return NULL;
    352   }
    353 
    354   /**
    355    * Access a specific map
    356    *
    357    * @param m the map to search for the key
    358    * @param key the key to search in the map
    359    * @return a pointer on the map found or NULL if not found
    360    */
    361   static map* getMap(map* m,const char *key){
    362     map* tmp=m;
    363     while(tmp!=NULL){
    364       if(strcasecmp(tmp->name,key)==0){
    365         return tmp;
    366       }
    367       tmp=tmp->next;
    368     }
    369     return NULL;
    370   }
    371 
    372 
    373   /**
    374    * Access the last map
    375    *
    376    * @param m the map to search for the lastest map
    377    * @return a pointer on the lastest map found or NULL if not found
    378    */
    379   static map* getLastMap(map* m){
    380     map* tmp=m;
    381     while(tmp!=NULL){
    382       if(tmp->next==NULL){
    383         return tmp;
    384       }
    385       tmp=tmp->next;
    386     }
    387     return NULL;
    388   }
    389 
    390   /**
    391    * Access a specific map from a maps
    392    *
    393    * @param m the maps to search for the key
    394    * @param key the key to search in the maps
    395    * @param subkey the key to search in the map (found for the key, if any)
    396    * @return a pointer on the map found or NULL if not found
    397    */
    398   static map* getMapFromMaps(maps* m,const char* key,const char* subkey){
    399     maps* _tmpm=getMaps(m,key);
    400     if(_tmpm!=NULL){
    401       map* _ztmpm=getMap(_tmpm->content,subkey);
    402       return _ztmpm;
    403     }
    404     else return NULL;
    405   }
    406 
    407   /**
    408    * Free allocated memory of a map.
    409    * Require to call free on mo after calling this function.
    410    *
    411    * @param mo the map to free
    412    */
    413   static void freeMap(map** mo){
    414     map* _cursor=*mo;
    415     if(_cursor!=NULL){
    416 #ifdef DEBUG
    417       fprintf(stderr,"freeMap\n");
    418 #endif
    419       free(_cursor->name);
    420       free(_cursor->value);
    421       if(_cursor->next!=NULL){
    422         freeMap(&_cursor->next);
    423         free(_cursor->next);
    424       }
    425     }
    426   }
    427 
    428   /**
    429    * Free allocated memory of a maps.
    430    * Require to call free on mo after calling this function.
    431    *
    432    * @param mo the maps to free
    433    */
    434   static void freeMaps(maps** mo){
    435     maps* _cursor=*mo;
    436     if(_cursor && _cursor!=NULL){
    437 #ifdef DEBUG
    438       fprintf(stderr,"freeMaps\n");
    439 #endif
    440       free(_cursor->name);
    441       if(_cursor->content!=NULL){
    442         freeMap(&_cursor->content);
    443         free(_cursor->content);
    444       }
    445       if(_cursor->next!=NULL){
    446         freeMaps(&_cursor->next);
    447         free(_cursor->next);
    448       }
    449     }
    450   }
    451 
    452209  /**
    453210   * Not named linked list
     
    472229    struct iotype* defaults; //!< the default iotype
    473230    struct iotype* supported; //!< the supported iotype
     231    struct elements* child; //!< the pointer to the children element if any (or NULL)
    474232    struct elements* next; //!< the pointer to the next element if any (or NULL)
    475233  } elements;
     
    503261  } registry;
    504262
    505   /**
    506    * Verify if an elements contains a name equal to the given key.
    507    *
    508    * @param e the elements to search for the key
    509    * @param key the elements name to search
    510    * @return true if the elements contains the name, false in other cases.
    511    */
    512   static bool hasElement(elements* e,const char* key){
    513     elements* tmp=e;
    514     while(tmp!=NULL){
    515       if(strcasecmp(key,tmp->name)==0)
    516         return true;
    517       tmp=tmp->next;
    518     }
    519     return false;
    520   }
    521 
    522   /**
    523    * Access a specific elements named key.
    524    *
    525    * @param m the elements to search
    526    * @param key the elements name to search
    527    * @return a pointer to the specific element if found, NULL in other case.
    528    */
    529   static elements* getElements(elements* m,char *key){
    530     elements* tmp=m;
    531     while(tmp!=NULL){
    532       if(strcasecmp(tmp->name,key)==0)
    533         return tmp;
    534       tmp=tmp->next;
    535     }
    536     return NULL;
    537   }
    538 
    539   /**
    540    * Free allocated memory of an iotype.
    541    * Require to call free on i after calling this function.
    542    *
    543    * @param i the iotype to free
    544    */
    545   static void freeIOType(iotype** i){
    546     iotype* _cursor=*i;
    547     if(_cursor!=NULL){
    548       if(_cursor->next!=NULL){
    549         freeIOType(&_cursor->next);
    550         free(_cursor->next);
    551       }
    552       freeMap(&_cursor->content);
    553       free(_cursor->content);
    554     }
    555   }
    556 
    557   /**
    558    * Free allocated memory of an elements.
    559    * Require to call free on e after calling this function.
    560    *
    561    * @param e the iotype to free
    562    */
    563   static void freeElements(elements** e){
    564     elements* tmp=*e;
    565     if(tmp!=NULL){
    566       if(tmp->name!=NULL)
    567         free(tmp->name);
    568       freeMap(&tmp->content);
    569       if(tmp->content!=NULL)
    570         free(tmp->content);
    571       freeMap(&tmp->metadata);
    572       if(tmp->metadata!=NULL)
    573         free(tmp->metadata);
    574       if(tmp->format!=NULL)
    575         free(tmp->format);
    576       freeIOType(&tmp->defaults);
    577       if(tmp->defaults!=NULL)
    578         free(tmp->defaults);
    579       freeIOType(&tmp->supported);
    580       if(tmp->supported!=NULL){
    581         free(tmp->supported);
    582       }
    583       freeElements(&tmp->next);
    584       if(tmp->next!=NULL)
    585         free(tmp->next);
    586     }
    587   }
    588 
    589   /**
    590    * Free allocated memory of a service.
    591    * Require to call free on e after calling this function.
    592    *
    593    * @param s the service to free
    594    */
    595   static void freeService(service** s){
    596     service* tmp=*s;
    597     if(tmp!=NULL){
    598       if(tmp->name!=NULL)
    599         free(tmp->name);
    600       freeMap(&tmp->content);
    601       if(tmp->content!=NULL)
    602         free(tmp->content);
    603       freeMap(&tmp->metadata);
    604       if(tmp->metadata!=NULL)
    605         free(tmp->metadata);
    606       freeElements(&tmp->inputs);
    607       if(tmp->inputs!=NULL)
    608         free(tmp->inputs);
    609       freeElements(&tmp->outputs);
    610       if(tmp->outputs!=NULL)
    611         free(tmp->outputs);
    612     }
    613   }
    614 
    615   /**
    616    * Add key value pair to an existing map.
    617    *
    618    * @param m the map to add the KVP
    619    * @param n the key to add
    620    * @param v the corresponding value to add
    621    */
    622   static void addToMap(map* m,const char* n,const char* v){
    623     if(hasKey(m,n)==false){
    624       map* _cursor=m;
    625       while(_cursor->next!=NULL){
    626         _cursor=_cursor->next;
    627       }
    628       _cursor->next=createMap(n,v);
    629     }
    630     else{
    631       map *tmp=getMap(m,n);
    632       if(tmp->value!=NULL)
    633         free(tmp->value);
    634       tmp->value=zStrdup(v);
    635     }
    636   }
    637 
    638   /**
    639    * Add a key and an integer value to an existing map.
    640    *
    641    * @param m the map to add the KVP
    642    * @param n the key to add
    643    * @param v the corresponding value to add
    644    */
    645   static void addIntToMap(map* m,const char* n,const int v){
    646     char svalue[10];
    647     sprintf(svalue,"%d",v);
    648     if(hasKey(m,n)==false){
    649       map* _cursor=m;
    650       while(_cursor->next!=NULL){
    651         _cursor=_cursor->next;
    652       }
    653       _cursor->next=createMap(n,svalue);
    654     }
    655     else{
    656       map *tmp=getMap(m,n);
    657       if(tmp->value!=NULL)
    658         free(tmp->value);
    659       tmp->value=zStrdup(svalue);
    660     }
    661   }
    662 
    663   /**
    664    * Add a key and a binary value to an existing map.
    665    *
    666    * @param m the map to add the KVP
    667    * @param n the key to add
    668    * @param v the corresponding value to add
    669    * @param size the size of the given value
    670    */
    671   static void addToMapWithSize(map* m,const char* n,const char* v,int size){
    672     if(hasKey(m,n)==false){
    673       map* _cursor=m;
    674       if(_cursor!=NULL){
    675         addToMap(m,n,"");
    676       }else{
    677         m=createMap(n,"");
    678       }
    679     }
    680     char sname[10]="size";
    681     if(strlen(n)>5)
    682       sprintf(sname,"size_%s",n+6);
    683     map *tmp=getMap(m,n);
    684     if(tmp->value!=NULL)
    685       free(tmp->value);
    686     tmp->value=(char*)malloc((size+1)*sizeof(char));
    687     memmove(tmp->value,v,size*sizeof(char));
    688     tmp->value[size]=0;
    689     char sin[128];
    690     sprintf(sin,"%d",size);
    691     addToMap(m,sname,sin);
    692   }
    693 
    694   /**
    695    * Add a map at the end of another map.
    696    *
    697    * @param mo the map to add mi
    698    * @param mi the map to add to mo
    699    */
    700   static void addMapToMap(map** mo,map* mi){
    701     map* tmp=mi;
    702     map* _cursor=*mo;
    703     while(tmp!=NULL){
    704       if(_cursor==NULL){
    705         *mo=createMap(tmp->name,tmp->value);
    706         (*mo)->next=NULL;
    707       }
    708       else{
    709 #ifdef DEBUG
    710         fprintf(stderr,"_CURSOR\n");
    711         dumpMap(_cursor);
    712 #endif
    713         while(_cursor->next!=NULL)
    714           _cursor=_cursor->next;
    715         map* tmp1=getMap(*mo,tmp->name);
    716         if(tmp1==NULL){
    717           _cursor->next=createMap(tmp->name,tmp->value);
    718         }
    719         else{
    720           addToMap(*mo,tmp->name,tmp->value);
    721         }
    722       }
    723       _cursor=*mo;
    724       tmp=tmp->next;
    725 #ifdef DEBUG
    726       fprintf(stderr,"MO\n");
    727       dumpMap(*mo);
    728 #endif
    729     }
    730   }
    731 
    732   /**
    733    * Add a map to iotype.
    734    *
    735    * @param io the iotype to add the map
    736    * @param mi the map to add to io
    737    */
    738   static void addMapToIoType(iotype** io,map* mi){
    739     iotype* tmp=*io;
    740     while(tmp->next!=NULL){
    741       tmp=tmp->next;
    742     }
    743     tmp->next=(iotype*)malloc(IOTYPE_SIZE);
    744     tmp->next->content=NULL;
    745     addMapToMap(&tmp->next->content,mi);
    746     tmp->next->next=NULL;
    747   }
    748 
    749   /**
    750    * Access a specific map or set its value.
    751    *
    752    * @param m the map to search for the key
    753    * @param key the key to search/add in the map
    754    * @param value the value to add if the key does not exist
    755    * @return a pointer on the map found or NULL if not found
    756    */
    757   static map* getMapOrFill(map** m,const char *key,const char* value){
    758     map* tmp=*m;
    759     map* tmpMap=getMap(tmp,key);
    760     if(tmpMap==NULL){
    761       if(tmp!=NULL){
    762         addToMap((*m),key,value);
    763       }
    764       else
    765         (*m)=createMap(key,value);
    766       tmpMap=getMap(*m,key);
    767     }
    768     return tmpMap;
    769   }
    770 
    771   /**
    772    * Verify if a map is contained in another map.
    773    *
    774    * @param m the map to search for i
    775    * @param i the map to search in m
    776    * @return true if i was found in m, false in other case
    777    */
    778   static bool contains(map* m,map* i){
    779     while(i!=NULL){     
    780       if(strcasecmp(i->name,"value")!=0 &&
    781          strcasecmp(i->name,"xlink:href")!=0 &&
    782          strcasecmp(i->name,"useMapServer")!=0 &&
    783          strcasecmp(i->name,"asReference")!=0){
    784         map *tmp;
    785         if(hasKey(m,i->name) && (tmp=getMap(m,i->name))!=NULL &&
    786            strcasecmp(i->value,tmp->value)!=0)
    787           return false;
    788       }
    789       i=i->next;
    790     }
    791     return true;
    792   }
    793 
    794   /**
    795    * Access a specific iotype from an elements.
    796    *
    797    * @param e the elements to search for the name
    798    * @param name the name to search in the elements e
    799    * @param values the map to verify it was contained in the defaults or
    800    *  supported content of the elements e
    801    * @return a pointer on the iotype found or NULL if not found
    802    */
    803   static iotype* getIoTypeFromElement(elements* e,char *name, map* values){
    804     elements* cursor=e;
    805     while(cursor!=NULL){
    806       if(strcasecmp(cursor->name,name)==0){
    807         if(contains(cursor->defaults->content,values)==true)
    808           return cursor->defaults;
    809         else{
    810           iotype* tmp=cursor->supported;
    811           while(tmp!=NULL){
    812             if(contains(tmp->content,values)==true)
    813               return tmp;           
    814             tmp=tmp->next;
    815           }
    816         }
    817       }
    818       cursor=cursor->next;
    819     }
    820     return NULL;
    821   }
    822 
    823   /**
    824    * Load binary values from a map (in) and add them to another map (out)
    825    *
    826    * @param out the map to add binaries values
    827    * @param in the map containing the binary values to add ti out
    828    * @param pos index of the binary in an array (in case of "MapArray")
    829    */
    830   static void loadMapBinary(map** out,map* in,int pos){
    831     map* size=getMap(in,"size");
    832     map *lout=*out;
    833     if(size!=NULL && pos>0){
    834       char tmp[11];
    835       sprintf(tmp,"size_%d",pos);
    836       size=getMap(in,tmp);
    837       sprintf(tmp,"value_%d",pos);
    838       map* tmpVin=getMap(in,tmp);
    839       map* tmpVout=getMap(lout,tmp);
    840       free(tmpVout->value);
    841       tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
    842       memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
    843       tmpVout->value[atoi(size->value)]=0;
    844     }else{
    845       if(size!=NULL){
    846         map* tmpVin=getMap(in,"value");
    847         map* tmpVout=getMap(lout,"value");
    848         free(tmpVout->value);
    849         tmpVout->value=(char*)malloc((atoi(size->value)+1)*sizeof(char));
    850         memmove(tmpVout->value,tmpVin->value,atoi(size->value)*sizeof(char));
    851         tmpVout->value[atoi(size->value)]=0;
    852       }
    853     }
    854   }
     263
     264  void _dumpMap(map*);
     265  void dumpMap(map*);
     266  void dumpMapToFile(map*,FILE*);
     267  void dumpMaps(maps* m);
     268  void dumpMapsToFile(maps*,char*);
     269  map* createMap(const char*,const char*);
     270  int count(map*);
     271  bool hasKey(map*,const char*);
     272  maps* getMaps(maps*,const char*);
     273  map* getMap(map*,const char*);
     274  map* getLastMap(map*);
     275  map* getMapFromMaps(maps*,const char*,const char*);
     276  void freeMap(map**);
     277  void freeMaps(maps** mo);
    855278 
    856   /**
    857    * Load binary values from a map (in) and add them to another map (out).
    858    * This function will take care of MapArray.
    859    * @see loadMapBinary
    860    *
    861    * @param out the map to add binaries values
    862    * @param in the map containing the binary values to add ti out
    863    */
    864   static void loadMapBinaries(map** out,map* in){
    865     map* size=getMap(in,"size");
    866     map* length=getMap(in,"length");
    867     if(length!=NULL){
    868       int len=atoi(length->value);
    869       int i=0;
    870       for(i=0;i<len;i++){
    871         loadMapBinary(out,in,i);
    872       }
    873     }
    874     else
    875       if(size!=NULL)
    876         loadMapBinary(out,in,-1);
    877   }
    878 
    879   /**
    880    * Duplicate a Maps
    881    *
    882    * @param mo the maps to clone
    883    * @return the allocated maps containing a copy of the mo maps
    884    */
    885   static maps* dupMaps(maps** mo){
    886     maps* _cursor=*mo;
    887     maps* res=NULL;
    888     if(_cursor!=NULL){
    889       res=(maps*)malloc(MAPS_SIZE);
    890       res->name=zStrdup(_cursor->name);
    891       res->content=NULL;
    892       res->next=NULL;
    893       map* mc=_cursor->content;
    894       if(mc!=NULL){
    895         addMapToMap(&res->content,mc);
    896         loadMapBinaries(&res->content,mc);
    897       }
    898       res->next=dupMaps(&_cursor->next);
    899     }
    900     return res;
    901   }
    902 
    903   /**
    904    * Add a maps at the end of another maps.
    905    *
    906    * @see addMapToMap, dupMaps, getMaps
    907    * @param mo the maps to add mi
    908    * @param mi the maps to add to mo
    909    */
    910   static void addMapsToMaps(maps** mo,maps* mi){
    911     maps* tmp=mi;
    912     maps* _cursor=*mo;
    913     while(tmp!=NULL){
    914       if(_cursor==NULL){
    915         *mo=dupMaps(&mi);
    916       }
    917       else{
    918         while(_cursor->next!=NULL)
    919           _cursor=_cursor->next;
    920         maps* tmp1=getMaps(*mo,tmp->name);
    921         if(tmp1==NULL)
    922           _cursor->next=dupMaps(&tmp);
    923         else
    924           addMapToMap(&tmp1->content,tmp->content);
    925         _cursor=*mo;
    926       }
    927       tmp=tmp->next;
    928     }
    929   }
    930 
    931   /**
    932    * Access a specific map array element
    933    *
    934    * @param m the map to search for the key
    935    * @param key the key to search in the map
    936    * @param index of the MapArray
    937    * @return a pointer on the map found or NULL if not found
    938    */
    939   static map* getMapArray(map* m,const char* key,int index){
    940     char tmp[1024];
    941     if(index>0)
    942       sprintf(tmp,"%s_%d",key,index);
    943     else
    944       sprintf(tmp,"%s",key);
    945 #ifdef DEBUG
    946     fprintf(stderr,"** KEY %s\n",tmp);
    947 #endif
    948     map* tmpMap=getMap(m,tmp);
    949 #ifdef DEBUG
    950     if(tmpMap!=NULL)
    951       dumpMap(tmpMap);
    952 #endif
    953     return tmpMap;
    954   }
    955 
    956 
    957   /**
    958    * Add a key value in a MapArray for a specific index
    959    *
    960    * @param m the map to search for the key
    961    * @param key the key to search in the map
    962    * @param index the index of the MapArray
    963    * @param value the value to set in the MapArray
    964    * @return a pointer on the map found or NULL if not found
    965    */
    966   static void setMapArray(map* m,const char* key,int index,const char* value){
    967     char tmp[1024];
    968     if(index>0){
    969       sprintf(tmp,"%s_%d",key,index);
    970       map* len=getMap(m,"length");
    971       if((len!=NULL && atoi(len->value)<index+1) || len==NULL){
    972         char tmp0[5];
    973         sprintf(tmp0,"%d",index+1);
    974         addToMap(m,"length",tmp0);
    975       }
    976     }
    977     else
    978       sprintf(tmp,"%s",key);
    979     map* tmpSize=getMapArray(m,"size",index);
    980     if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
    981 #ifdef DEBUG
    982       fprintf(stderr,"%s\n",tmpSize->value);
    983 #endif
    984       map* ptr=getMapOrFill(&m,tmp,(char *)"");
    985       free(ptr->value);
    986       ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
    987       memcpy(ptr->value,value,atoi(tmpSize->value));
    988     }
    989     else
    990       addToMap(m,tmp,value);
    991   }
    992 
    993   /**
    994    * Access the map "type"
    995    *
    996    * @param mt the map
    997    * @return a pointer on the map for mimeType/dataType/CRS if found, NULL in
    998    *  other case
    999    */
    1000   static map* getMapType(map* mt){
    1001     map* tmap=getMap(mt,(char *)"mimeType");
    1002     if(tmap==NULL){
    1003       tmap=getMap(mt,"dataType");
    1004       if(tmap==NULL){
    1005         tmap=getMap(mt,"CRS");
    1006       }
    1007     }
    1008 #ifdef DEBUG
    1009         dumpMap(tmap);
    1010 #endif
    1011     return tmap;
    1012   }
    1013 
    1014   /**
    1015    * Add a Maps containing a MapArray to a Maps
    1016    *
    1017    * @see getMapType
    1018    * @param mo the maps
    1019    * @param mi the maps
    1020    * @param typ the map "type"
    1021    * @return
    1022    */
    1023   static int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
    1024     maps* tmp=mi;   
    1025     maps* _cursor=getMaps(*mo,tmp->name);
    1026 
    1027     if(_cursor==NULL)
    1028       return -1;
    1029 
    1030     map* tmpLength=getMap(_cursor->content,"length");
    1031     char tmpLen[10];
    1032     int len=1;
    1033     if(tmpLength!=NULL){
    1034       len=atoi(tmpLength->value);
    1035     }
    1036 
    1037     char *tmpV[12]={
    1038       (char*)"size",
    1039       (char*)"value",
    1040       (char*)"uom",
    1041       (char*)"Reference",
    1042       (char*)"Order",
    1043       (char*)"cache_file",
    1044       (char*)"fmimeType",
    1045       (char*)"xlink:href",
    1046       typ,
    1047       (char*)"schema",
    1048       (char*)"encoding",
    1049       (char*)"isCached"
    1050     };
    1051     sprintf(tmpLen,"%d",len+1);
    1052     addToMap(_cursor->content,"length",tmpLen);
    1053     int i=0;
    1054     for(i=0;i<12;i++){
    1055       map* tmpVI=getMap(tmp->content,tmpV[i]);
    1056       if(tmpVI!=NULL){
    1057 #ifdef DEBUG
    1058         fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
    1059 #endif
    1060         setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
    1061       }
    1062     }
    1063    
    1064     addToMap(_cursor->content,"isArray","true");
    1065     return 0;
    1066   }
    1067 
    1068   /**
    1069    * Set a key value pair to a map contained in a Maps
    1070    *
    1071    * @param m the maps
    1072    * @param key the maps name
    1073    * @param subkey the map name included in the maps corresponding to key
    1074    * @param value the corresponding value to add in the map
    1075    */
    1076   static void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
    1077     maps* _tmpm=getMaps(m,key);
    1078     if(_tmpm!=NULL){
    1079       map* _ztmpm=getMap(_tmpm->content,subkey);
    1080       if(_ztmpm!=NULL){
    1081         if(_ztmpm->value!=NULL)
    1082           free(_ztmpm->value);
    1083         _ztmpm->value=zStrdup(value);
    1084       }else{
    1085         maps *tmp=(maps*)malloc(MAPS_SIZE);
    1086         tmp->name=zStrdup(key);
    1087         tmp->content=createMap(subkey,value);
    1088         tmp->next=NULL;
    1089         addMapsToMaps(&_tmpm,tmp);
    1090         freeMaps(&tmp);
    1091         free(tmp);
    1092       }
    1093     }else{
    1094       maps *tmp=(maps*)malloc(MAPS_SIZE);
    1095       tmp->name=zStrdup(key);
    1096       tmp->content=createMap(subkey,value);
    1097       tmp->next=NULL;
    1098       addMapsToMaps(&m,tmp);
    1099       freeMaps(&tmp);
    1100       free(tmp);
    1101     }
    1102   }
    1103 
    1104   /**
    1105    * Dump an elements on stderr
    1106    *
    1107    * @param e the elements to dump
    1108    */
    1109   static void dumpElements(elements* e){
    1110     elements* tmp=e;
    1111     while(tmp!=NULL){
    1112       fprintf(stderr,"ELEMENT [%s]\n",tmp->name);
    1113       fprintf(stderr," > CONTENT [%s]\n",tmp->name);
    1114       dumpMap(tmp->content);
    1115       fprintf(stderr," > METADATA [%s]\n",tmp->name);
    1116       dumpMap(tmp->metadata);
    1117       fprintf(stderr," > FORMAT [%s]\n",tmp->format);
    1118       iotype* tmpio=tmp->defaults;
    1119       int ioc=0;
    1120       while(tmpio!=NULL){
    1121         fprintf(stderr," > DEFAULTS [%s] (%i)\n",tmp->name,ioc);
    1122         dumpMap(tmpio->content);
    1123         tmpio=tmpio->next;
    1124         ioc++;
    1125       }
    1126       tmpio=tmp->supported;
    1127       ioc=0;
    1128       while(tmpio!=NULL){
    1129         fprintf(stderr," > SUPPORTED [%s] (%i)\n",tmp->name,ioc);
    1130         dumpMap(tmpio->content);
    1131         tmpio=tmpio->next;
    1132         ioc++;
    1133       }
    1134       fprintf(stderr,"------------------\n");
    1135       tmp=tmp->next;
    1136     }
    1137   }
    1138 
    1139   /**
    1140    * Dump an elements on stderr using the YAML syntaxe
    1141    *
    1142    * @param e the elements to dump
    1143    */
    1144   static void dumpElementsAsYAML(elements* e){
    1145     elements* tmp=e;
    1146     int i;
    1147     while(tmp!=NULL){
    1148       for(i=0;i<2;i++)
    1149         fprintf(stderr," ");
    1150       fprintf(stderr,"%s:\n",tmp->name);
    1151       map* mcurs=tmp->content;
    1152       while(mcurs!=NULL){
    1153         for(i=0;i<4;i++)
    1154           fprintf(stderr," ");
    1155         _dumpMap(mcurs);
    1156         mcurs=mcurs->next;
    1157       }
    1158       mcurs=tmp->metadata;
    1159       if(mcurs!=NULL){
    1160         for(i=0;i<4;i++)
    1161           fprintf(stderr," ");
    1162         fprintf(stderr,"MetaData:\n");
    1163         while(mcurs!=NULL){
    1164           for(i=0;i<6;i++)
    1165             fprintf(stderr," ");
    1166           _dumpMap(mcurs);
    1167           mcurs=mcurs->next;
    1168         }
    1169       }
    1170       for(i=0;i<4;i++)
    1171         fprintf(stderr," ");
    1172       fprintf(stderr,"%s:\n",tmp->format);
    1173       iotype* tmpio=tmp->defaults;
    1174       int ioc=0;
    1175       while(tmpio!=NULL){
    1176         for(i=0;i<6;i++)
    1177           fprintf(stderr," ");
    1178         fprintf(stderr,"default:\n");
    1179         mcurs=tmpio->content;
    1180         while(mcurs!=NULL){
    1181           for(i=0;i<8;i++)
    1182             fprintf(stderr," ");
    1183           if(strcasecmp(mcurs->name,"range")==0){
    1184             fprintf(stderr,"range: \"%s\"\n",mcurs->value);
    1185           }else
    1186             _dumpMap(mcurs);
    1187           mcurs=mcurs->next;
    1188         }
    1189         tmpio=tmpio->next;
    1190         ioc++;
    1191       }
    1192       tmpio=tmp->supported;
    1193       ioc=0;
    1194       while(tmpio!=NULL){
    1195         for(i=0;i<6;i++)
    1196           fprintf(stderr," ");
    1197         fprintf(stderr,"supported:\n");
    1198         mcurs=tmpio->content;
    1199         while(mcurs!=NULL){
    1200           for(i=0;i<8;i++)
    1201             fprintf(stderr," ");
    1202           if(strcasecmp(mcurs->name,"range")==0){
    1203             fprintf(stderr,"range: \"%s\"\n",mcurs->value);
    1204           }else
    1205             _dumpMap(mcurs);
    1206           mcurs=mcurs->next;
    1207         }
    1208         tmpio=tmpio->next;
    1209         ioc++;
    1210       }
    1211       tmp=tmp->next;
    1212     }
    1213   }
    1214 
    1215   /**
    1216    * Duplicate an elements
    1217    *
    1218    * @param e the elements to clone
    1219    * @return the allocated elements containing a copy of the elements e
    1220    */
    1221   static elements* dupElements(elements* e){
    1222     elements* cursor=e;
    1223     elements* tmp=NULL;
    1224     if(cursor!=NULL){
    1225 #ifdef DEBUG
    1226       fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
    1227       dumpElements(e);
    1228       fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
    1229 #endif
    1230       tmp=(elements*)malloc(ELEMENTS_SIZE);
    1231       tmp->name=zStrdup(e->name);
    1232       tmp->content=NULL;
    1233       addMapToMap(&tmp->content,e->content);
    1234       tmp->metadata=NULL;
    1235       addMapToMap(&tmp->metadata,e->metadata);
    1236       if(e->format!=NULL)
    1237         tmp->format=zStrdup(e->format);
    1238       else
    1239         tmp->format=NULL;
    1240       if(e->defaults!=NULL){
    1241         tmp->defaults=(iotype*)malloc(IOTYPE_SIZE);
    1242         tmp->defaults->content=NULL;
    1243         addMapToMap(&tmp->defaults->content,e->defaults->content);
    1244         tmp->defaults->next=NULL;
    1245 #ifdef DEBUG
    1246         fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
    1247         dumpMap(tmp->defaults->content);
    1248 #endif
    1249       }else
    1250         tmp->defaults=NULL;
    1251       if(e->supported!=NULL){
    1252         tmp->supported=(iotype*)malloc(IOTYPE_SIZE);
    1253         tmp->supported->content=NULL;
    1254         addMapToMap(&tmp->supported->content,e->supported->content);
    1255         tmp->supported->next=NULL;
    1256         iotype *tmp2=e->supported->next;
    1257         while(tmp2!=NULL){
    1258           addMapToIoType(&tmp->supported,tmp2->content);
    1259 #ifdef DEBUG
    1260           fprintf(stderr,">> %s %i\n",__FILE__,__LINE__);
    1261           dumpMap(tmp->defaults->content);
    1262 #endif
    1263           tmp2=tmp2->next;
    1264         }
    1265       }
    1266       else
    1267         tmp->supported=NULL;
    1268       tmp->next=dupElements(cursor->next);
    1269     }
    1270     return tmp;
    1271   }
    1272 
    1273   /**
    1274    * Add an elements to another elements.
    1275    *
    1276    * @see dupElements
    1277    * @param m the elements to add the e
    1278    * @param e the elements to be added to m
    1279    */
    1280   static void addToElements(elements** m,elements* e){
    1281     elements* tmp=e;
    1282     if(*m==NULL){
    1283       *m=dupElements(tmp);
    1284     }else{
    1285       addToElements(&(*m)->next,tmp);
    1286     }
    1287   }
    1288  
    1289   /**
    1290    * Dump a service on stderr
    1291    *
    1292    * @param s the service to dump
    1293    */
    1294   static void dumpService(service* s){
    1295     if(s==NULL)
    1296       return;
    1297     fprintf(stderr,"++++++++++++++++++\nSERVICE [%s]\n++++++++++++++++++\n",s->name);
    1298     if(s->content!=NULL){
    1299       fprintf(stderr,"CONTENT MAP\n");
    1300       dumpMap(s->content);
    1301       fprintf(stderr,"CONTENT METADATA\n");
    1302       dumpMap(s->metadata);
    1303     }
    1304     if(s->inputs!=NULL){
    1305       fprintf(stderr,"INPUT ELEMENTS [%s]\n------------------\n",s->name);
    1306       dumpElements(s->inputs);
    1307     }
    1308     if(s->outputs!=NULL){
    1309       fprintf(stderr,"OUTPUT ELEMENTS [%s]\n------------------\n",s->name);
    1310       dumpElements(s->outputs);
    1311     }
    1312     fprintf(stderr,"++++++++++++++++++\n");
    1313   }
    1314 
    1315   /**
    1316    * Dump a service on stderr using the YAML syntaxe
    1317    *
    1318    * @param s the service to dump
    1319    */
    1320   static void dumpServiceAsYAML(service* s){
    1321     int i;
    1322     fprintf(stderr,"# %s\n\n",s->name);
    1323     if(s->content!=NULL){
    1324       map* mcurs=s->content;
    1325       dumpMap(mcurs);
    1326       mcurs=s->metadata;
    1327       if(mcurs!=NULL){
    1328         fprintf(stderr,"MetaData:\n");
    1329         while(mcurs!=NULL){
    1330           for(i=0;i<2;i++)
    1331             fprintf(stderr," ");
    1332           _dumpMap(mcurs);
    1333           mcurs=mcurs->next;
    1334         }
    1335       }
    1336     }
    1337     if(s->inputs!=NULL){
    1338       fprintf(stderr,"\ninputs:\n");
    1339       dumpElementsAsYAML(s->inputs);
    1340     }
    1341     if(s->outputs!=NULL){
    1342       fprintf(stderr,"\noutputs:\n");
    1343       dumpElementsAsYAML(s->outputs);
    1344     }
    1345   }
    1346 
    1347   /**
    1348    * Duplicate a service
    1349    *
    1350    * @param s the service to clone
    1351    * @return the allocated service containing a copy of the serfvice s
    1352    */
    1353   static service* dupService(service* s){
    1354     service *res=(service*)malloc(SERVICE_SIZE);
    1355     res->name=zStrdup(s->name);
    1356     res->content=NULL;
    1357     addMapToMap(&res->content,s->content);
    1358     res->metadata=NULL;
    1359     addMapToMap(&res->metadata,s->metadata);
    1360     res->inputs=dupElements(s->inputs);
    1361     res->outputs=dupElements(s->outputs);
    1362     return res;
    1363   }
    1364 
    1365   /**
    1366    * Print the registry on stderr.
    1367    *
    1368    * @param r the registry
    1369    */
    1370   static void dumpRegistry(registry* r){
    1371     registry* p=r;
    1372     while(p!=NULL){
    1373       fprintf(stderr,"%s \n",p->name);
    1374       services* s=p->content;
    1375       s=p->content;
    1376       while(s!=NULL){
    1377         dumpService(s->content);
    1378         s=s->next;
    1379       }
    1380       p=p->next;
    1381     }
    1382   }
    1383 
    1384   /**
    1385    * Add a service to the registry
    1386    *
    1387    * @param reg the resgitry to add the service
    1388    * @param name the registry name to update
    1389    * @param content the service to add
    1390    */
    1391   static bool addServiceToRegistry(registry** reg,char* name,service* content){
    1392     registry *l=*reg;
    1393     int isInitial=-1;
    1394     if(l==NULL){
    1395       l=(registry*)malloc(REGISTRY_SIZE);
    1396       isInitial=1;
    1397     }
    1398     if(l!=NULL){
    1399       int hasLevel=-1;
    1400       while(isInitial<0 && l!=NULL){
    1401         if(l->name!=NULL && strcasecmp(name,l->name)==0){
    1402           hasLevel=1;
    1403           break;
    1404         }
    1405         l=l->next;
    1406       }
    1407       if(hasLevel<0){
    1408         if(isInitial<0)
    1409           l=(registry*)malloc(REGISTRY_SIZE);
    1410         l->name=zStrdup(name);
    1411         l->content=NULL;
    1412         l->next=NULL;
    1413       }
    1414       if(l->content==NULL){
    1415         l->content=(services*)malloc(SERVICES_SIZE);
    1416         l->content->content=dupService(content);
    1417         l->content->next=NULL;
    1418       }
    1419       else{
    1420         services* s=l->content;
    1421         while(s->next!=NULL)
    1422           s=s->next;
    1423         s->next=(services*)malloc(SERVICES_SIZE);
    1424         s->next->content=dupService(content);
    1425         s->next->next=NULL;
    1426       }
    1427       l->next=NULL;
    1428       if(isInitial>0)
    1429         *reg=l;
    1430       else{
    1431         registry *r=*reg;
    1432         while(r->next!=NULL)
    1433           r=r->next;
    1434         r->next=l;
    1435         r->next->next=NULL;
    1436       }
    1437       return true;
    1438     }
    1439     else
    1440       return false;
    1441   }
    1442 
    1443   /**
    1444    * Free memory allocated for the registry
    1445    *
    1446    * @param r the registry
    1447    */
    1448   static void freeRegistry(registry** r){
    1449     registry* lr=*r;
    1450     while(lr!=NULL){
    1451       services* s=lr->content;
    1452       free(lr->name);
    1453       while(s!=NULL){
    1454         service* s1=s->content;
    1455         s=s->next;
    1456         if(s1!=NULL){
    1457           freeService(&s1);
    1458           free(s1);
    1459           s1=NULL;
    1460         }
    1461       }
    1462       lr=lr->next;
    1463     }   
    1464   }
    1465 
    1466   /**
    1467    * Access a service in the registry
    1468    *
    1469    * @param r the registry
    1470    * @param level the regitry to search ("concept", "generic" or "implementation")
    1471    * @param sname the service name
    1472    * @return the service pointer if a corresponding service was found or NULL
    1473    */
    1474   static service* getServiceFromRegistry(registry* r,char  *level,char* sname){
    1475     registry *lr=r;
    1476     while(lr!=NULL){
    1477       if(strcasecmp(lr->name,level)==0){
    1478         services* s=lr->content;
    1479         while(s!=NULL){
    1480           if(s->content!=NULL && strcasecmp(s->content->name,sname)==0)
    1481             return s->content;
    1482           s=s->next;
    1483         }
    1484         break;
    1485       }
    1486       lr=lr->next;
    1487     }
    1488     return NULL;
    1489   }
    1490 
    1491   /**
    1492    * Apply inheritance to an out map from a reference in map
    1493    *
    1494    * @param out the map to update
    1495    * @param in the reference map (containing inherited properties)
    1496    */
    1497   static void inheritMap(map** out,map* in){
    1498     map* content=in;
    1499     while(content!=NULL && *out!=NULL){
    1500       map* cmap=getMap(*out,content->name);
    1501       if(cmap==NULL)
    1502         addToMap(*out,content->name,content->value);
    1503       content=content->next;
    1504     }
    1505   }
    1506 
    1507   /**
    1508    * Apply inheritance to an out iotype from a reference in iotype
    1509    *
    1510    * @param out the iotype to update
    1511    * @param in the reference iotype (containing inherited properties)
    1512    */
    1513   static void inheritIOType(iotype** out,iotype* in){
    1514     iotype* io=in;
    1515     iotype* oio=*out;
    1516     if(io!=NULL){
    1517       if(*out==NULL){
    1518         *out=(iotype*)malloc(IOTYPE_SIZE);
    1519         (*out)->content=NULL;
    1520         addMapToMap(&(*out)->content,io->content);
    1521         (*out)->next=NULL;
    1522         oio=*out;
    1523         inheritIOType(&oio->next,io->next);
    1524       }else{
    1525         inheritIOType(&oio->next,io->next);
    1526       }
    1527     }
    1528   }
    1529 
    1530   /**
    1531    * Apply inheritance to an out elements from a reference in elements
    1532    *
    1533    * @param out the elements to update
    1534    * @param in the reference elements (containing inherited properties)
    1535    */
    1536   static void inheritElements(elements** out,elements* in){
    1537     elements* content=in;
    1538     while(content!=NULL && *out!=NULL){
    1539       elements* cmap=getElements(*out,content->name);
    1540       if(cmap==NULL)
    1541         addToElements(out,content);
    1542       else{
    1543         inheritMap(&cmap->content,content->content);
    1544         inheritMap(&cmap->metadata,content->metadata);
    1545         if(cmap->format==NULL && content->format!=NULL)
    1546           cmap->format=zStrdup(content->format);
    1547         inheritIOType(&cmap->defaults,content->defaults);
    1548         if(cmap->supported==NULL)
    1549           inheritIOType(&cmap->supported,content->supported);
    1550         else{
    1551           iotype* p=content->supported;
    1552           while(p!=NULL){
    1553             addMapToIoType(&cmap->supported,p->content);
    1554             p=p->next;
    1555           }
    1556         }
    1557       }
    1558       content=content->next;
    1559     }
    1560   }
    1561 
    1562   /**
    1563    * Apply inheritance to a service based on a registry
    1564    *
    1565    * @param r the registry storing profiles hierarchy
    1566    * @param s the service to update depending on its inheritance
    1567    */
    1568   static void inheritance(registry *r,service** s){
    1569     if(r==NULL)
    1570       return;
    1571     service* ls=*s;
    1572     if(ls->content==NULL)
    1573       return;
    1574     map* profile=getMap(ls->content,"extend");
    1575     map* level=getMap(ls->content,"level");
    1576     if(profile!=NULL&&level!=NULL){
    1577       service* s1;
    1578       if(strncasecmp(level->value,"profile",7)==0)
    1579         s1=getServiceFromRegistry(r,"generic",profile->value);
    1580       else
    1581         s1=getServiceFromRegistry(r,level->value,profile->value);
    1582      
    1583       inheritMap(&ls->content,s1->content);
    1584       inheritMap(&ls->metadata,s1->metadata);
    1585       if(ls->inputs==NULL && s1->inputs!=NULL){
    1586         ls->inputs=dupElements(s1->inputs);
    1587       }else{
    1588         inheritElements(&ls->inputs,s1->inputs);
    1589       }
    1590       if(ls->outputs==NULL && s1->outputs!=NULL){
    1591         ls->outputs=dupElements(s1->outputs);
    1592       }else
    1593         inheritElements(&ls->outputs,s1->outputs);
    1594     }
    1595   }
    1596 
    1597   /**
    1598    * Convert a maps to a char*** (only used for Fortran support)
    1599    *
    1600    * @param m the maps to convert
    1601    * @param c the resulting array
    1602    */
    1603   static void mapsToCharXXX(maps* m,char*** c){
    1604     maps* tm=m;
    1605     int i=0;
    1606     int j=0;
    1607     char tmp[10][30][1024];
    1608     memset(tmp,0,1024*10*10);
    1609     while(tm!=NULL){
    1610       if(i>=10)
    1611         break;
    1612       strcpy(tmp[i][j],"name");
    1613       j++;
    1614       strcpy(tmp[i][j],tm->name);
    1615       j++;
    1616       map* tc=tm->content;
    1617       while(tc!=NULL){
    1618         if(j>=30)
    1619           break;
    1620         strcpy(tmp[i][j],tc->name);
    1621         j++;
    1622         strcpy(tmp[i][j],tc->value);
    1623         j++;
    1624         tc=tc->next;
    1625       }
    1626       tm=tm->next;
    1627       j=0;
    1628       i++;
    1629     }
    1630     memcpy(c,tmp,10*10*1024);
    1631   }
    1632 
    1633   /**
    1634    * Convert a char*** to a maps (only used for Fortran support)
    1635    *
    1636    * @param c the array to convert
    1637    * @param m the resulting maps
    1638    */
    1639   static void charxxxToMaps(char*** c,maps**m){
    1640     maps* trorf=*m;
    1641     int i,j;
    1642     char tmp[10][30][1024];
    1643     memcpy(tmp,c,10*30*1024);
    1644     for(i=0;i<10;i++){
    1645       if(strlen(tmp[i][1])==0)
    1646         break;
    1647       trorf->name=tmp[i][1];
    1648       trorf->content=NULL;
    1649       trorf->next=NULL;
    1650       for(j=2;j<29;j+=2){
    1651         if(strlen(tmp[i][j+1])==0)
    1652           break;
    1653         if(trorf->content==NULL)
    1654           trorf->content=createMap(tmp[i][j],tmp[i][j+1]);
    1655         else
    1656           addToMap(trorf->content,tmp[i][j],tmp[i][j+1]);
    1657       }
    1658       trorf=trorf->next;
    1659     }
    1660     m=&trorf;
    1661   }
    1662 
     279
     280  bool hasElement(elements*,const char*);
     281  elements* getElements(elements*,char*);
     282  void freeIOType(iotype**);
     283  void freeElements(elements**);
     284  void freeService(service**);
     285  void addToMap(map*,const char*,const char*);
     286  void addIntToMap(map*,const char*,const int);
     287  void addToMapWithSize(map*,const char*,const char*,int);
     288  void addMapToMap(map**,map*);
     289  void addMapToIoType(iotype**,map*);
     290  map* getMapOrFill(map**,const char*,const char*);
     291  bool contains(map*,map*);
     292  iotype* getIoTypeFromElement(elements*,char*, map*);
     293  void loadMapBinary(map**,map*,int);
     294  void loadMapBinaries(map**,map*);
     295  maps* dupMaps(maps**);
     296  void addMapsToMaps(maps**,maps*);
     297  map* getMapArray(map*,const char*,int);
     298  void setMapArray(map*,const char*,int,const char*);
     299  map* getMapType(map*);
     300  int addMapsArrayToMaps(maps**,maps*,char*);
     301  void setMapInMaps(maps*,const char*,const char*,const char*);
     302  void dumpElements(elements*);
     303  void dumpElementsAsYAML(elements*);
     304  elements* dupElements(elements*);
     305  void addToElements(elements**,elements*);
     306  void dumpService(service*);
     307  void dumpServiceAsYAML(service*);
     308  service* dupService(service*);
     309  void dumpRegistry(registry*);
     310  bool addServiceToRegistry(registry**,char*,service*);
     311  void freeRegistry(registry**);
     312  service* getServiceFromRegistry(registry*,char*,char*);
     313  void inheritMap(map**,map*);
     314  void inheritIOType(iotype**,iotype*);
     315  void inheritElements(elements**,elements*);
     316  void inheritance(registry*,service**);
     317  void mapsToCharXXX(maps*,char***);
     318  void charxxxToMaps(char***,maps**);
    1663319#ifdef WIN32
    1664320  extern char *url_encode(char *);
    1665 
    1666   static char* getMapsAsKVP(maps* m,int length,int type){
    1667     char *dataInputsKVP=(char*) malloc(length*sizeof(char));
    1668     char *dataInputsKVPi=NULL;
    1669     maps* curs=m;
    1670     int i=0;
    1671     while(curs!=NULL){
    1672       map *inRequest=getMap(curs->content,"inRequest");
    1673       map *hasLength=getMap(curs->content,"length");
    1674       if((inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0) ||
    1675          inRequest==NULL){
    1676         if(i==0)
    1677           if(type==0){
    1678             sprintf(dataInputsKVP,"%s=",curs->name);
    1679             if(hasLength!=NULL){
    1680               dataInputsKVPi=(char*)malloc((strlen(curs->name)+2)*sizeof(char));
    1681               sprintf(dataInputsKVPi,"%s=",curs->name);
    1682             }
    1683           }
    1684           else
    1685             sprintf(dataInputsKVP,"%s",curs->name);
    1686         else{
    1687           char *temp=zStrdup(dataInputsKVP);
    1688           if(type==0)
    1689             sprintf(dataInputsKVP,"%s;%s=",temp,curs->name);
    1690           else
    1691             sprintf(dataInputsKVP,"%s;%s",temp,curs->name);
    1692         }
    1693         map* icurs=curs->content;
    1694         if(type==0){
    1695           char *temp=zStrdup(dataInputsKVP);
    1696           if(getMap(curs->content,"xlink:href")!=NULL)
    1697             sprintf(dataInputsKVP,"%sReference",temp);
    1698           else{
    1699             if(hasLength!=NULL){
    1700               int j;
    1701               for(j=0;j<atoi(hasLength->value);j++){
    1702                 map* tmp0=getMapArray(curs->content,"value",j);
    1703                 if(j==0)
    1704                   free(temp);
    1705                 temp=zStrdup(dataInputsKVP);
    1706                 if(j==0)
    1707                   sprintf(dataInputsKVP,"%s%s",temp,tmp0->value);
    1708                 else
    1709                   sprintf(dataInputsKVP,"%s;%s%s",temp,dataInputsKVPi,tmp0->value);
    1710               }
    1711             }
    1712             else
    1713               sprintf(dataInputsKVP,"%s%s",temp,icurs->value);
    1714           }
    1715           free(temp);
    1716         }
    1717         while(icurs!=NULL){
    1718           if(strncasecmp(icurs->name,"value",5)!=0 &&
    1719              strncasecmp(icurs->name,"mimeType_",9)!=0 &&
    1720              strncasecmp(icurs->name,"dataType_",9)!=0 &&
    1721              strncasecmp(icurs->name,"size",4)!=0 &&
    1722              strncasecmp(icurs->name,"length",4)!=0 &&
    1723              strncasecmp(icurs->name,"isArray",7)!=0 &&
    1724              strcasecmp(icurs->name,"Reference")!=0 &&
    1725              strcasecmp(icurs->name,"minOccurs")!=0 &&
    1726              strcasecmp(icurs->name,"maxOccurs")!=0 &&
    1727              strncasecmp(icurs->name,"fmimeType",9)!=0 &&
    1728              strcasecmp(icurs->name,"inRequest")!=0){
    1729             char *itemp=zStrdup(dataInputsKVP);
    1730             if(strcasecmp(icurs->name,"xlink:href")!=0)
    1731               sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,icurs->value);
    1732             else
    1733               sprintf(dataInputsKVP,"%s@%s=%s",itemp,icurs->name,url_encode(icurs->value));
    1734             free(itemp);
    1735           }
    1736           icurs=icurs->next;
    1737         }
    1738       }
    1739       curs=curs->next;
    1740       i++;
    1741     }
    1742     return dataInputsKVP;
    1743   }
     321  char* getMapsAsKVP(maps*,int,int);
    1744322#endif
    1745323
  • trunk/zoo-project/zoo-kernel/service_conf.y

    r621 r640  
    174174      current_element->defaults=NULL;
    175175      current_element->supported=NULL;
     176      current_element->child=NULL;
    176177      current_element->next=NULL;
    177178    }
     
    223224        current_element->defaults=NULL;
    224225        current_element->supported=NULL;
     226        current_element->child=NULL;
    225227        current_element->next=NULL;
    226228      }
  • trunk/zoo-project/zoo-kernel/service_internal.c

    r634 r640  
    2323 */
    2424
     25#include "fcgi_stdio.h"
    2526#include "service_internal.h"
    26 #ifdef USE_MS
    27 #include "service_internal_ms.h"
    28 #else
    29 #include "cpl_vsi.h"
    30 #endif
    3127
    3228#ifndef TRUE
     
    3733#endif
    3834
    39 #ifndef WIN32
    40 #include <dlfcn.h>
    41 #endif
    42 
    4335#define ERROR_MSG_MAX_LENGTH 1024
    44 
    45 #include "mimetypes.h"
    46 
    47 /**
    48  * Verify if a given language is listed in the lang list defined in the [main]
    49  * section of the main.cfg file.
    50  *
    51  * @param conf the map containing the settings from the main.cfg file
    52  * @param str the specific language
    53  * @return 1 if the specific language is listed, -1 in other case.
    54  */
    55 int isValidLang(maps* conf,const char *str){
    56   map *tmpMap=getMapFromMaps(conf,"main","lang");
    57   char *tmp=zStrdup(tmpMap->value);
    58   char *pToken=strtok(tmp,",");
    59   int res=-1;
    60   while(pToken!=NULL){
    61     if(strcasecmp(str,pToken)==0){
    62       res=1;
    63       break;
    64     }
    65     pToken = strtok(NULL,",");
    66   }
    67   free(tmp);
    68   return res;
    69 }
    70 
    71 /**
    72  * Print the HTTP headers based on a map.
    73  *
    74  * @param m the map containing the headers informations
    75  */
    76 void printHeaders(maps* m){
    77   maps *_tmp=getMaps(m,"headers");
    78   if(_tmp!=NULL){
    79     map* _tmp1=_tmp->content;
    80     while(_tmp1!=NULL){
    81       printf("%s: %s\r\n",_tmp1->name,_tmp1->value);
    82       _tmp1=_tmp1->next;
    83     }
    84   }
    85 }
    86 
    87 /**
    88  * Add a land attribute to a XML node
    89  *
    90  * @param n the XML node to add the attribute
    91  * @param m the map containing the language key to add as xml:lang
    92  */
    93 void addLangAttr(xmlNodePtr n,maps *m){
    94   map *tmpLmap=getMapFromMaps(m,"main","language");
    95   if(tmpLmap!=NULL)
    96     xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST tmpLmap->value);
    97   else
    98     xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST "en-US");
    99 }
    100 
    101 /**
    102  * Converts a hex character to its integer value
    103  *
    104  * @param ch the char to convert
    105  * @return the converted char
    106  */
    107 char from_hex(char ch) {
    108   return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
    109 }
    110 
    111 /**
    112  * Converts an integer value to its hec character
    113  *
    114  * @param code the char to convert
    115  * @return the converted char
    116  */
    117 char to_hex(char code) {
    118   static char hex[] = "0123456789abcdef";
    119   return hex[code & 15];
    120 }
    12136
    12237/**
     
    649564#endif
    650565
    651 
    652 /**
    653  * URLEncode an url
    654  *
    655  * @param str the url to encode
    656  * @return a url-encoded version of str
    657  * @warning be sure to free() the returned string after use
    658  */
    659 char *url_encode(char *str) {
    660   char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
    661   while (*pstr) {
    662     if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
    663       *pbuf++ = *pstr;
    664     else if (*pstr == ' ')
    665       *pbuf++ = '+';
    666     else
    667       *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
    668     pstr++;
    669   }
    670   *pbuf = '\0';
    671   return buf;
    672 }
    673 
    674 /**
    675  * Decode an URLEncoded url
    676  *
    677  * @param str the URLEncoded url to decode
    678  * @return a url-decoded version of str
    679  * @warning be sure to free() the returned string after use
    680  */
    681 char *url_decode(char *str) {
    682   char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
    683   while (*pstr) {
    684     if (*pstr == '%') {
    685       if (pstr[1] && pstr[2]) {
    686         *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
    687         pstr += 2;
    688       }
    689     } else if (*pstr == '+') {
    690       *pbuf++ = ' ';
    691     } else {
    692       *pbuf++ = *pstr;
    693     }
    694     pstr++;
    695   }
    696   *pbuf = '\0';
    697   return buf;
    698 }
    699 
    700 /**
    701  * Replace the first letter by its upper case version in a new char array
    702  *
    703  * @param tmp the char*
    704  * @return a new char* with first letter in upper case
    705  * @warning be sure to free() the returned string after use
    706  */
    707 char *zCapitalize1(char *tmp){
    708   char *res=zStrdup(tmp);
    709   if(res[0]>=97 && res[0]<=122)
    710     res[0]-=32;
    711   return res;
    712 }
    713 
    714 /**
    715  * Replace all letters by their upper case version in a new char array
    716  *
    717  * @param tmp the char*
    718  * @return a new char* with first letter in upper case
    719  * @warning be sure to free() the returned string after use
    720  */
    721 char *zCapitalize(char *tmp){
    722   int i=0;
    723   char *res=zStrdup(tmp);
    724   for(i=0;i<strlen(res);i++)
    725     if(res[i]>=97 && res[i]<=122)
    726       res[i]-=32;
    727   return res;
    728 }
    729 
    730 /**
    731  * Search for an existing XML namespace in usedNS.
    732  *
    733  * @param name the name of the XML namespace to search
    734  * @return the index of the XML namespace found or -1 if not found.
    735  */
    736 int zooXmlSearchForNs(const char* name){
    737   int i;
    738   int res=-1;
    739   for(i=0;i<nbNs;i++)
    740     if(strncasecmp(name,nsName[i],strlen(nsName[i]))==0){
    741       res=i;
    742       break;
    743     }
    744   return res;
    745 }
    746 
    747 /**
    748  * Add an XML namespace to the usedNS if it was not already used.
    749  *
    750  * @param nr the xmlNodePtr to attach the XML namspace (can be NULL)
    751  * @param url the url of the XML namespace to add
    752  * @param name the name of the XML namespace to add
    753  * @return the index of the XML namespace added.
    754  */
    755 int zooXmlAddNs(xmlNodePtr nr,const char* url,const char* name){
    756 #ifdef DEBUG
    757   fprintf(stderr,"zooXmlAddNs %d %s \n",nbNs,name);
    758 #endif
    759   int currId=-1;
    760   if(nbNs==0){
    761     nbNs++;
    762     currId=0;
    763     nsName[currId]=strdup(name);
    764     usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
    765   }else{
    766     currId=zooXmlSearchForNs(name);
    767     if(currId<0){
    768       nbNs++;
    769       currId=nbNs-1;
    770       nsName[currId]=strdup(name);
    771       usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
    772     }
    773   }
    774   return currId;
    775 }
    776 
    777 /**
    778  * Free allocated memory to store used XML namespace.
    779  */
    780 void zooXmlCleanupNs(){
    781   int j;
    782 #ifdef DEBUG
    783   fprintf(stderr,"zooXmlCleanup %d\n",nbNs);
    784 #endif
    785   for(j=nbNs-1;j>=0;j--){
    786 #ifdef DEBUG
    787     fprintf(stderr,"zooXmlCleanup %d\n",j);
    788 #endif
    789     if(j==0)
    790       xmlFreeNs(usedNs[j]);
    791     free(nsName[j]);
    792     nbNs--;
    793   }
    794   nbNs=0;
    795 }
    796 
    797 /**
    798  * Add a XML document to the iDocs.
    799  *
    800  * @param value the string containing the XML document
    801  * @return the index of the XML document added.
    802  */
    803 int zooXmlAddDoc(const char* value){
    804   int currId=0;
    805   nbDocs++;
    806   currId=nbDocs-1;
    807   iDocs[currId]=xmlParseMemory(value,strlen(value));
    808   return currId;
    809 }
    810 
    811 /**
    812  * Free allocated memort to store XML documents
    813  */
    814 void zooXmlCleanupDocs(){
    815   int j;
    816   for(j=nbDocs-1;j>=0;j--){
    817     xmlFreeDoc(iDocs[j]);
    818   }
    819   nbDocs=0;
    820 }
    821 
    822 /**
    823  * Generate a SOAP Envelope node when required (if the isSoap key of the [main]
    824  * section is set to true).
    825  *
    826  * @param conf the conf maps containing the main.cfg settings
    827  * @param n the node used as children of the generated soap:Envelope
    828  * @return the generated soap:Envelope (if isSoap=true) or the input node n
    829  *  (when isSoap=false)
    830  */
    831 xmlNodePtr soapEnvelope(maps* conf,xmlNodePtr n){
    832   map* soap=getMapFromMaps(conf,"main","isSoap");
    833   if(soap!=NULL && strcasecmp(soap->value,"true")==0){
    834     int lNbNs=nbNs;
    835     nsName[lNbNs]=strdup("soap");
    836     usedNs[lNbNs]=xmlNewNs(NULL,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
    837     nbNs++;
    838     xmlNodePtr nr = xmlNewNode(usedNs[lNbNs], BAD_CAST "Envelope");
    839     nsName[nbNs]=strdup("soap");
    840     usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
    841     nbNs++;
    842     nsName[nbNs]=strdup("xsi");
    843     usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
    844     nbNs++;
    845     xmlNsPtr ns_xsi=usedNs[nbNs-1];
    846     xmlNewNsProp(nr,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.w3.org/2003/05/soap-envelope http://www.w3.org/2003/05/soap-envelope");
    847     xmlNodePtr nr1 = xmlNewNode(usedNs[lNbNs], BAD_CAST "Body");
    848     xmlAddChild(nr1,n);
    849     xmlAddChild(nr,nr1);
    850     return nr;
    851   }else
    852     return n;
    853 }
    854 
    855 /**
    856  * Generate a WPS header.
    857  *
    858  * @param doc the document to add the header
    859  * @param m the conf maps containing the main.cfg settings
    860  * @param req the request type (GetCapabilities,DescribeProcess,Execute)
    861  * @param rname the root node name
    862  * @return the generated wps:rname xmlNodePtr (can be wps: Capabilities,
    863  *  wps:ProcessDescriptions,wps:ExecuteResponse)
    864  */
    865 xmlNodePtr printWPSHeader(xmlDocPtr doc,maps* m,const char* req,const char* rname){
    866 
    867   xmlNsPtr ns,ns_xsi;
    868   xmlNodePtr n;
    869 
    870   int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
    871   ns=usedNs[wpsId];
    872   n = xmlNewNode(ns, BAD_CAST rname);
    873   zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
    874   xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
    875   zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
    876   int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
    877   ns_xsi=usedNs[xsiId];
    878  
    879   char *tmp=(char*) malloc((86+strlen(req)+1)*sizeof(char));
    880   sprintf(tmp,"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wps%s_response.xsd",req);
    881   xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST tmp);
    882   free(tmp);
    883   xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
    884   xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
    885   addLangAttr(n,m);
    886   xmlNodePtr fn=soapEnvelope(m,n);
    887   xmlDocSetRootElement(doc, fn);
    888   return n;
    889 }
    890 
    891 /**
    892  * Generate a Capabilities header.
    893  *
    894  * @param doc the document to add the header
    895  * @param m the conf maps containing the main.cfg settings
    896  * @return the generated wps:ProcessOfferings xmlNodePtr
    897  */
    898 xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr doc,maps* m){
    899 
    900   xmlNsPtr ns,ns_ows,ns_xlink;
    901   xmlNodePtr n,nc,nc1,nc2,nc3,nc4,nc5,nc6;
    902   n = printWPSHeader(doc,m,"GetCapabilities","Capabilities");
    903   maps* toto1=getMaps(m,"main");
    904   char tmp[256];
    905 
    906   int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
    907   ns=usedNs[wpsId];
    908   int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
    909   ns_xlink=usedNs[xlinkId];
    910   int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
    911   ns_ows=usedNs[owsId];
    912 
    913   nc = xmlNewNode(ns_ows, BAD_CAST "ServiceIdentification");
    914   maps* tmp4=getMaps(m,"identification");
    915   if(tmp4!=NULL){
    916     map* tmp2=tmp4->content;
    917     const char *orderedFields[5];
    918     orderedFields[0]="Title";
    919     orderedFields[1]="Abstract";
    920     orderedFields[2]="Keywords";
    921     orderedFields[3]="Fees";
    922     orderedFields[4]="AccessConstraints";
    923     int oI=0;
    924     for(oI=0;oI<5;oI++)
    925       if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
    926         if(strcasecmp(tmp2->name,"abstract")==0 ||
    927            strcasecmp(tmp2->name,"title")==0 ||
    928            strcasecmp(tmp2->name,"accessConstraints")==0 ||
    929            strcasecmp(tmp2->name,"fees")==0){
    930           tmp2->name[0]=toupper(tmp2->name[0]);
    931           nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
    932           xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
    933           xmlAddChild(nc,nc1);
    934         }
    935         else
    936           if(strcmp(tmp2->name,"keywords")==0){
    937             nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
    938             char *toto=tmp2->value;
    939             char buff[256];
    940             int i=0;
    941             int j=0;
    942             while(toto[i]){
    943               if(toto[i]!=',' && toto[i]!=0){
    944                 buff[j]=toto[i];
    945                 buff[j+1]=0;
    946                 j++;
    947               }
    948               else{
    949                 nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
    950                 xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
    951                 xmlAddChild(nc1,nc2);
    952                 j=0;
    953               }
    954               i++;
    955             }
    956             if(strlen(buff)>0){
    957               nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
    958               xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
    959               xmlAddChild(nc1,nc2);
    960             }
    961             xmlAddChild(nc,nc1);
    962             nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceType");
    963             xmlAddChild(nc2,xmlNewText(BAD_CAST "WPS"));
    964             xmlAddChild(nc,nc2);
    965             nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceTypeVersion");
    966             xmlAddChild(nc2,xmlNewText(BAD_CAST "1.0.0"));
    967             xmlAddChild(nc,nc2);
    968           }
    969         tmp2=tmp2->next;
    970       }
    971   }
    972   else{
    973     fprintf(stderr,"TMP4 NOT FOUND !!");
    974     return NULL;
    975   }
    976   xmlAddChild(n,nc);
    977 
    978   nc = xmlNewNode(ns_ows, BAD_CAST "ServiceProvider");
    979   nc3 = xmlNewNode(ns_ows, BAD_CAST "ServiceContact");
    980   nc4 = xmlNewNode(ns_ows, BAD_CAST "ContactInfo");
    981   nc5 = xmlNewNode(ns_ows, BAD_CAST "Phone");
    982   nc6 = xmlNewNode(ns_ows, BAD_CAST "Address");
    983   tmp4=getMaps(m,"provider");
    984   if(tmp4!=NULL){
    985     map* tmp2=tmp4->content;
    986     const char *tmpAddress[6];
    987     tmpAddress[0]="addressDeliveryPoint";
    988     tmpAddress[1]="addressCity";
    989     tmpAddress[2]="addressAdministrativeArea";
    990     tmpAddress[3]="addressPostalCode";
    991     tmpAddress[4]="addressCountry";
    992     tmpAddress[5]="addressElectronicMailAddress";
    993     const char *tmpPhone[2];
    994     tmpPhone[0]="phoneVoice";
    995     tmpPhone[1]="phoneFacsimile";
    996     const char *orderedFields[12];
    997     orderedFields[0]="providerName";
    998     orderedFields[1]="providerSite";
    999     orderedFields[2]="individualName";
    1000     orderedFields[3]="positionName";
    1001     orderedFields[4]=tmpPhone[0];
    1002     orderedFields[5]=tmpPhone[1];
    1003     orderedFields[6]=tmpAddress[0];
    1004     orderedFields[7]=tmpAddress[1];
    1005     orderedFields[8]=tmpAddress[2];
    1006     orderedFields[9]=tmpAddress[3];
    1007     orderedFields[10]=tmpAddress[4];
    1008     orderedFields[11]=tmpAddress[5];
    1009     int oI=0;
    1010     for(oI=0;oI<12;oI++)
    1011       if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
    1012         if(strcmp(tmp2->name,"keywords")!=0 &&
    1013            strcmp(tmp2->name,"serverAddress")!=0 &&
    1014            strcmp(tmp2->name,"lang")!=0){
    1015           tmp2->name[0]=toupper(tmp2->name[0]);
    1016           if(strcmp(tmp2->name,"ProviderName")==0){
    1017             nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
    1018             xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
    1019             xmlAddChild(nc,nc1);
    1020           }
    1021           else{
    1022             if(strcmp(tmp2->name,"ProviderSite")==0){
    1023               nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
    1024               xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST tmp2->value);
    1025               xmlAddChild(nc,nc1);
    1026             }
    1027             else 
    1028               if(strcmp(tmp2->name,"IndividualName")==0 ||
    1029                  strcmp(tmp2->name,"PositionName")==0){
    1030                 nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
    1031                 xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
    1032                 xmlAddChild(nc3,nc1);
    1033               }
    1034               else
    1035                 if(strncmp(tmp2->name,"Phone",5)==0){
    1036                   int j;
    1037                   for(j=0;j<2;j++)
    1038                     if(strcasecmp(tmp2->name,tmpPhone[j])==0){
    1039                       char *tmp4=tmp2->name;
    1040                       nc1 = xmlNewNode(ns_ows, BAD_CAST tmp4+5);
    1041                       xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
    1042                       xmlAddChild(nc5,nc1);
    1043                     }
    1044                 }
    1045                 else
    1046                   if(strncmp(tmp2->name,"Address",7)==0){
    1047                     int j;
    1048                     for(j=0;j<6;j++)
    1049                       if(strcasecmp(tmp2->name,tmpAddress[j])==0){
    1050                         char *tmp4=tmp2->name;
    1051                         nc1 = xmlNewNode(ns_ows, BAD_CAST tmp4+7);
    1052                         xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
    1053                         xmlAddChild(nc6,nc1);
    1054                       }
    1055                   }
    1056           }
    1057         }
    1058         else
    1059           if(strcmp(tmp2->name,"keywords")==0){
    1060             nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
    1061             char *toto=tmp2->value;
    1062             char buff[256];
    1063             int i=0;
    1064             int j=0;
    1065             while(toto[i]){
    1066               if(toto[i]!=',' && toto[i]!=0){
    1067                 buff[j]=toto[i];
    1068                 buff[j+1]=0;
    1069                 j++;
    1070               }
    1071               else{
    1072                 nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
    1073                 xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
    1074                 xmlAddChild(nc1,nc2);
    1075                 j=0;
    1076               }
    1077               i++;
    1078             }
    1079             if(strlen(buff)>0){
    1080               nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
    1081               xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
    1082               xmlAddChild(nc1,nc2);
    1083             }
    1084             xmlAddChild(nc,nc1);
    1085           }
    1086         tmp2=tmp2->next;
    1087       }
    1088   }
    1089   else{
    1090     fprintf(stderr,"TMP4 NOT FOUND !!");
    1091   }
    1092   xmlAddChild(nc4,nc5);
    1093   xmlAddChild(nc4,nc6);
    1094   xmlAddChild(nc3,nc4);
    1095   xmlAddChild(nc,nc3);
    1096   xmlAddChild(n,nc);
    1097 
    1098 
    1099   nc = xmlNewNode(ns_ows, BAD_CAST "OperationsMetadata");
    1100   char *tmp2[3];
    1101   tmp2[0]=strdup("GetCapabilities");
    1102   tmp2[1]=strdup("DescribeProcess");
    1103   tmp2[2]=strdup("Execute");
    1104   int j=0;
    1105 
    1106   if(toto1!=NULL){
    1107     map* tmp=getMap(toto1->content,"serverAddress");
    1108     if(tmp!=NULL){
    1109       SERVICE_URL = strdup(tmp->value);
    1110     }
    1111     else
    1112       SERVICE_URL = strdup("not_defined");
    1113   }
    1114   else
    1115     SERVICE_URL = strdup("not_defined");
    1116 
    1117   for(j=0;j<3;j++){
    1118     nc1 = xmlNewNode(ns_ows, BAD_CAST "Operation");
    1119     xmlNewProp(nc1,BAD_CAST "name",BAD_CAST tmp2[j]);
    1120     nc2 = xmlNewNode(ns_ows, BAD_CAST "DCP");
    1121     nc3 = xmlNewNode(ns_ows, BAD_CAST "HTTP");
    1122     nc4 = xmlNewNode(ns_ows, BAD_CAST "Get");
    1123     sprintf(tmp,"%s",SERVICE_URL);
    1124     xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
    1125     xmlAddChild(nc3,nc4);
    1126     nc4 = xmlNewNode(ns_ows, BAD_CAST "Post");
    1127     xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
    1128     xmlAddChild(nc3,nc4);
    1129     xmlAddChild(nc2,nc3);
    1130     xmlAddChild(nc1,nc2);   
    1131     xmlAddChild(nc,nc1);   
    1132   }
    1133   for(j=2;j>=0;j--)
    1134     free(tmp2[j]);
    1135   xmlAddChild(n,nc);
    1136 
    1137   nc = xmlNewNode(ns, BAD_CAST "ProcessOfferings");
    1138   xmlAddChild(n,nc);
    1139 
    1140   nc1 = xmlNewNode(ns, BAD_CAST "Languages");
    1141   nc2 = xmlNewNode(ns, BAD_CAST "Default");
    1142   nc3 = xmlNewNode(ns, BAD_CAST "Supported");
    1143  
    1144   toto1=getMaps(m,"main");
    1145   if(toto1!=NULL){
    1146     map* tmp1=getMap(toto1->content,"lang");
    1147     char *toto=tmp1->value;
    1148     char buff[256];
    1149     int i=0;
    1150     int j=0;
    1151     int dcount=0;
    1152     while(toto[i]){
    1153       if(toto[i]!=',' && toto[i]!=0){
    1154         buff[j]=toto[i];
    1155         buff[j+1]=0;
    1156         j++;
    1157       }
    1158       else{
    1159         nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
    1160         xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
    1161         if(dcount==0){
    1162           xmlAddChild(nc2,nc4);
    1163           xmlAddChild(nc1,nc2);
    1164           dcount++;
    1165         }
    1166         nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
    1167         xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
    1168         xmlAddChild(nc3,nc4);
    1169         j=0;
    1170         buff[j]=0;
    1171       }
    1172       i++;
    1173     }
    1174     if(strlen(buff)>0){
    1175       nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
    1176       xmlAddChild(nc4,xmlNewText(BAD_CAST buff));             
    1177       xmlAddChild(nc3,nc4);
    1178     }
    1179   }
    1180   xmlAddChild(nc1,nc3);
    1181   xmlAddChild(n,nc1);
    1182  
    1183   free(SERVICE_URL);
    1184   return nc;
    1185 }
    1186 
    1187 /**
    1188  * Add prefix to the service name.
    1189  *
    1190  * @param conf the conf maps containing the main.cfg settings
    1191  * @param level the map containing the level information
    1192  * @param serv the service structure created from the zcfg file
    1193  */
    1194 void addPrefix(maps* conf,map* level,service* serv){
    1195   if(level!=NULL){
    1196     char key[25];
    1197     char* prefix=NULL;
    1198     int clevel=atoi(level->value);
    1199     int cl=0;
    1200     for(cl=0;cl<clevel;cl++){
    1201       sprintf(key,"sprefix_%d",cl);
    1202       map* tmp2=getMapFromMaps(conf,"lenv",key);
    1203       if(tmp2!=NULL){
    1204         if(prefix==NULL)
    1205           prefix=zStrdup(tmp2->value);
    1206         else{
    1207           int plen=strlen(prefix);
    1208           prefix=(char*)realloc(prefix,(plen+strlen(tmp2->value)+2)*sizeof(char));
    1209           memcpy(prefix+plen,tmp2->value,strlen(tmp2->value)*sizeof(char));
    1210           prefix[plen+strlen(tmp2->value)]=0;
    1211         }
    1212       }
    1213     }
    1214     if(prefix!=NULL){
    1215       char* tmp0=strdup(serv->name);
    1216       free(serv->name);
    1217       serv->name=(char*)malloc((strlen(prefix)+strlen(tmp0)+1)*sizeof(char));
    1218       sprintf(serv->name,"%s%s",prefix,tmp0);
    1219       free(tmp0);
    1220       free(prefix);
    1221       prefix=NULL;
    1222     }
    1223   }
    1224 }
    1225 
    1226 /**
    1227  * Generate a wps:Process node for a servie and add it to a given node.
    1228  *
    1229  * @param m the conf maps containing the main.cfg settings
    1230  * @param registry the profile registry if any
    1231  * @param nc the XML node to add the Process node
    1232  * @param serv the service structure created from the zcfg file
    1233  * @return the generated wps:ProcessOfferings xmlNodePtr
    1234  */
    1235 void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
    1236   xmlNsPtr ns,ns_ows,ns_xlink;
    1237   xmlNodePtr n=NULL,nc1,nc2;
    1238   /**
    1239    * Initialize or get existing namspaces
    1240    */
    1241   int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
    1242   ns=usedNs[wpsId];
    1243   int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
    1244   ns_ows=usedNs[owsId];
    1245   int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
    1246   ns_xlink=usedNs[xlinkId];
    1247 
    1248   map* tmp1;
    1249   if(serv->content!=NULL){
    1250     nc1 = xmlNewNode(ns, BAD_CAST "Process");
    1251     tmp1=getMap(serv->content,"processVersion");
    1252     if(tmp1!=NULL)
    1253       xmlNewNsProp(nc1,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);
    1254     else
    1255       xmlNewNsProp(nc1,ns,BAD_CAST "processVersion",BAD_CAST "1");
    1256     map* tmp3=getMapFromMaps(m,"lenv","level");
    1257     addPrefix(m,tmp3,serv);
    1258     printDescription(nc1,ns_ows,serv->name,serv->content);
    1259     tmp1=serv->metadata;
    1260     while(tmp1!=NULL){
    1261       nc2 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
    1262       xmlNewNsProp(nc2,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
    1263       xmlAddChild(nc1,nc2);
    1264       tmp1=tmp1->next;
    1265     }
    1266     xmlAddChild(nc,nc1);
    1267   }
    1268 }
    1269 
    1270 /**
    1271  * Generate a ProcessDescription node for a servie and add it to a given node.
    1272  *
    1273  * @param m the conf maps containing the main.cfg settings
    1274  * @param nc the XML node to add the Process node
    1275  * @param serv the servive structure created from the zcfg file
    1276  * @return the generated wps:ProcessOfferings xmlNodePtr
    1277  */
    1278 void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv){
    1279   xmlNsPtr ns,ns_ows,ns_xlink;
    1280   xmlNodePtr n,nc1;
    1281 
    1282   n=nc;
    1283  
    1284   int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
    1285   ns=usedNs[wpsId];
    1286   int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
    1287   ns_ows=usedNs[owsId];
    1288   int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
    1289   ns_xlink=usedNs[xlinkId];
    1290 
    1291   nc = xmlNewNode(NULL, BAD_CAST "ProcessDescription");
    1292   const char *tmp4[3];
    1293   tmp4[0]="processVersion";
    1294   tmp4[1]="storeSupported";
    1295   tmp4[2]="statusSupported";
    1296   int j=0;
    1297   map* tmp1=NULL;
    1298   for(j=0;j<3;j++){
    1299     tmp1=getMap(serv->content,tmp4[j]);
    1300     if(tmp1!=NULL){
    1301       if(j==0)
    1302         xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);     
    1303       else
    1304         xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value);     
    1305     }
    1306     else{
    1307       if(j>0)
    1308         xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "true");
    1309       else
    1310         xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST "1");
    1311     }
    1312   }
    1313  
    1314   tmp1=getMapFromMaps(m,"lenv","level");
    1315   addPrefix(m,tmp1,serv);
    1316   printDescription(nc,ns_ows,serv->name,serv->content);
    1317 
    1318   tmp1=serv->metadata;
    1319   while(tmp1!=NULL){
    1320     nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
    1321     xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
    1322     xmlAddChild(nc,nc1);
    1323     tmp1=tmp1->next;
    1324   }
    1325 
    1326   tmp1=getMap(serv->content,"Profile");
    1327   if(tmp1!=NULL){
    1328     nc1 = xmlNewNode(ns, BAD_CAST "Profile");
    1329     xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
    1330     xmlAddChild(nc,nc1);
    1331   }
    1332 
    1333   if(serv->inputs!=NULL){
    1334     nc1 = xmlNewNode(NULL, BAD_CAST "DataInputs");
    1335     elements* e=serv->inputs;
    1336     printFullDescription(1,e,"Input",ns_ows,nc1);
    1337     xmlAddChild(nc,nc1);
    1338   }
    1339 
    1340   nc1 = xmlNewNode(NULL, BAD_CAST "ProcessOutputs");
    1341   elements* e=serv->outputs;
    1342   printFullDescription(0,e,"Output",ns_ows,nc1);
    1343   xmlAddChild(nc,nc1);
    1344 
    1345   xmlAddChild(n,nc);
    1346 
    1347 }
    1348 
    1349 /**
    1350  * Generate the required XML tree for the detailled metadata informations of
    1351  * inputs or outputs
    1352  *
    1353  * @param in 1 in case of inputs, 0 for outputs
    1354  * @param elem the elements structure containing the metadata informations
    1355  * @param type the name ("Input" or "Output") of the XML node to create
    1356  * @param ns_ows the ows XML namespace
    1357  * @param nc1 the XML node to use to add the created tree
    1358  */
    1359 void printFullDescription(int in,elements *elem,const char* type,xmlNsPtr ns_ows,xmlNodePtr nc1){
    1360   const char *orderedFields[13];
    1361   orderedFields[0]="mimeType";
    1362   orderedFields[1]="encoding";
    1363   orderedFields[2]="schema";
    1364   orderedFields[3]="dataType";
    1365   orderedFields[4]="uom";
    1366   orderedFields[5]="CRS";
    1367   orderedFields[6]="value";
    1368   orderedFields[7]="AllowedValues";
    1369   orderedFields[8]="range";
    1370   orderedFields[9]="rangeMin";
    1371   orderedFields[10]="rangeMax";
    1372   orderedFields[11]="rangeClosure";
    1373   orderedFields[12]="rangeSpace";
    1374 
    1375   xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8,nc9;
    1376   elements* e=elem;
    1377 
    1378   map* tmp1=NULL;
    1379   while(e!=NULL){
    1380     int default1=0;
    1381     int isAnyValue=1;
    1382     nc2 = xmlNewNode(NULL, BAD_CAST type);
    1383     if(strncmp(type,"Input",5)==0){
    1384       tmp1=getMap(e->content,"minOccurs");
    1385       if(tmp1!=NULL){
    1386         xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
    1387       }else
    1388         xmlNewProp(nc2,BAD_CAST "minOccurs",BAD_CAST "0");
    1389       tmp1=getMap(e->content,"maxOccurs");
    1390       if(tmp1!=NULL){
    1391         if(strcasecmp(tmp1->value,"unbounded")!=0)
    1392           xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
    1393         else
    1394           xmlNewProp(nc2,BAD_CAST "maxOccurs",BAD_CAST "1000");
    1395       }else
    1396         xmlNewProp(nc2,BAD_CAST "maxOccurs",BAD_CAST "1");
    1397       if((tmp1=getMap(e->content,"maximumMegabytes"))!=NULL){
    1398         xmlNewProp(nc2,BAD_CAST "maximumMegabytes",BAD_CAST tmp1->value);
    1399       }
    1400     }
    1401 
    1402     printDescription(nc2,ns_ows,e->name,e->content);
    1403 
    1404     /**
    1405      * Build the (Literal/Complex/BoundingBox)Data node
    1406      */
    1407     if(strncmp(type,"Output",6)==0){
    1408       if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
    1409         nc3 = xmlNewNode(NULL, BAD_CAST "LiteralOutput");
    1410       else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
    1411         nc3 = xmlNewNode(NULL, BAD_CAST "ComplexOutput");
    1412       else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
    1413         nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
    1414       else
    1415         nc3 = xmlNewNode(NULL, BAD_CAST e->format);
    1416     }else{
    1417       if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0){
    1418         nc3 = xmlNewNode(NULL, BAD_CAST "LiteralData");
    1419       }
    1420       else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
    1421         nc3 = xmlNewNode(NULL, BAD_CAST "ComplexData");
    1422       else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
    1423         nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxData");
    1424       else
    1425         nc3 = xmlNewNode(NULL, BAD_CAST e->format);
    1426     }
    1427 
    1428     iotype* _tmp0=NULL;
    1429     iotype* _tmp=e->defaults;
    1430     int datatype=0;
    1431     bool hasUOM=false;
    1432     bool hasUOM1=false;
    1433     if(_tmp!=NULL){
    1434       if(strcmp(e->format,"LiteralOutput")==0 ||
    1435          strcmp(e->format,"LiteralData")==0){
    1436         datatype=1;
    1437         nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
    1438         nc5 = xmlNewNode(NULL, BAD_CAST "Default");
    1439       }
    1440       else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
    1441               strcmp(e->format,"BoundingBoxData")==0){
    1442         datatype=2;
    1443         nc5 = xmlNewNode(NULL, BAD_CAST "Default");
    1444       }
    1445       else{
    1446         nc4 = xmlNewNode(NULL, BAD_CAST "Default");
    1447         nc5 = xmlNewNode(NULL, BAD_CAST "Format");
    1448       }
    1449      
    1450       tmp1=_tmp->content;
    1451 
    1452       if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
    1453         nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
    1454         xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
    1455         char tmp[1024];
    1456         sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
    1457         xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
    1458         xmlAddChild(nc3,nc8);
    1459         datatype=1;
    1460       }
    1461 
    1462       if(strncmp(type,"Input",5)==0){
    1463 
    1464         if((tmp1=getMap(_tmp->content,"AllowedValues"))!=NULL){
    1465           nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
    1466           char *token,*saveptr1;
    1467           token=strtok_r(tmp1->value,",",&saveptr1);
    1468           while(token!=NULL){
    1469             nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
    1470             char *tmps=strdup(token);
    1471             tmps[strlen(tmps)]=0;
    1472             xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
    1473             free(tmps);
    1474             xmlAddChild(nc6,nc7);
    1475             token=strtok_r(NULL,",",&saveptr1);
    1476           }
    1477           if(getMap(_tmp->content,"range")!=NULL ||
    1478              getMap(_tmp->content,"rangeMin")!=NULL ||
    1479              getMap(_tmp->content,"rangeMax")!=NULL ||
    1480              getMap(_tmp->content,"rangeClosure")!=NULL )
    1481             goto doRange;
    1482           xmlAddChild(nc3,nc6);
    1483           isAnyValue=-1;
    1484         }
    1485 
    1486         tmp1=getMap(_tmp->content,"range");
    1487         if(tmp1==NULL)
    1488           tmp1=getMap(_tmp->content,"rangeMin");
    1489         if(tmp1==NULL)
    1490           tmp1=getMap(_tmp->content,"rangeMax");
    1491        
    1492         if(tmp1!=NULL && isAnyValue==1){
    1493           nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
    1494         doRange:
    1495          
    1496           /**
    1497            * Range: Table 46 OGC Web Services Common Standard
    1498            */
    1499           nc8 = xmlNewNode(ns_ows, BAD_CAST "Range");
    1500          
    1501           map* tmp0=getMap(tmp1,"range");
    1502           if(tmp0!=NULL){
    1503             char* pToken;
    1504             char* orig=zStrdup(tmp0->value);
    1505             /**
    1506              * RangeClosure: Table 47 OGC Web Services Common Standard
    1507              */
    1508             const char *tmp="closed";
    1509             if(orig[0]=='[' && orig[strlen(orig)-1]=='[')
    1510               tmp="closed-open";
    1511             else
    1512               if(orig[0]==']' && orig[strlen(orig)-1]==']')
    1513                 tmp="open-closed";
    1514               else
    1515                 if(orig[0]==']' && orig[strlen(orig)-1]=='[')
    1516                   tmp="open";
    1517             xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
    1518             pToken=strtok(orig,",");
    1519             int nci0=0;
    1520             while(pToken!=NULL){
    1521               char *tmpStr=(char*) malloc((strlen(pToken))*sizeof(char));
    1522               if(nci0==0){
    1523                 nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
    1524                 strncpy( tmpStr, pToken+1, strlen(pToken)-1 );
    1525                 tmpStr[strlen(pToken)-1] = '\0';
    1526               }else{
    1527                 nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
    1528                 const char* bkt;
    1529                 if ( ( bkt = strchr(pToken, '[') ) != NULL || ( bkt = strchr(pToken, ']') ) != NULL ){
    1530                   strncpy( tmpStr, pToken, bkt - pToken );
    1531                   tmpStr[bkt - pToken] = '\0';
    1532                 }
    1533               }
    1534               xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr));
    1535               free(tmpStr);
    1536               xmlAddChild(nc8,nc7);
    1537               nci0++;
    1538               pToken = strtok(NULL,",");
    1539             }               
    1540             if(getMap(tmp1,"rangeSpacing")==NULL){
    1541               nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
    1542               xmlAddChild(nc7,xmlNewText(BAD_CAST "1"));
    1543               xmlAddChild(nc8,nc7);
    1544             }
    1545             free(orig);
    1546           }else{
    1547            
    1548             tmp0=getMap(tmp1,"rangeMin");
    1549             if(tmp0!=NULL){
    1550               nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
    1551               xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
    1552               xmlAddChild(nc8,nc7);
    1553             }else{
    1554               nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
    1555               xmlAddChild(nc8,nc7);
    1556             }
    1557             tmp0=getMap(tmp1,"rangeMax");
    1558             if(tmp0!=NULL){
    1559               nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
    1560               xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
    1561               xmlAddChild(nc8,nc7);
    1562             }else{
    1563               nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
    1564               xmlAddChild(nc8,nc7);
    1565             }
    1566             tmp0=getMap(tmp1,"rangeSpacing");
    1567             if(tmp0!=NULL){
    1568               nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
    1569               xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
    1570               xmlAddChild(nc8,nc7);
    1571             }
    1572             tmp0=getMap(tmp1,"rangeClosure");
    1573             if(tmp0!=NULL){
    1574               const char *tmp="closed";
    1575               if(strcasecmp(tmp0->value,"co")==0)
    1576                 tmp="closed-open";
    1577               else
    1578                 if(strcasecmp(tmp0->value,"oc")==0)
    1579                   tmp="open-closed";
    1580                 else
    1581                   if(strcasecmp(tmp0->value,"o")==0)
    1582                     tmp="open";
    1583               xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
    1584             }else
    1585               xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
    1586           }
    1587           if(_tmp0==NULL){
    1588             xmlAddChild(nc6,nc8);
    1589             _tmp0=e->supported;
    1590             if(_tmp0!=NULL &&
    1591                (getMap(_tmp0->content,"range")!=NULL ||
    1592                 getMap(_tmp0->content,"rangeMin")!=NULL ||
    1593                 getMap(_tmp0->content,"rangeMax")!=NULL ||
    1594                 getMap(_tmp0->content,"rangeClosure")!=NULL )){
    1595               tmp1=_tmp0->content;
    1596               goto doRange;
    1597             }
    1598           }else{
    1599             _tmp0=_tmp0->next;
    1600             if(_tmp0!=NULL){
    1601               xmlAddChild(nc6,nc8);
    1602               if(getMap(_tmp0->content,"range")!=NULL ||
    1603                  getMap(_tmp0->content,"rangeMin")!=NULL ||
    1604                  getMap(_tmp0->content,"rangeMax")!=NULL ||
    1605                  getMap(_tmp0->content,"rangeClosure")!=NULL ){
    1606                 tmp1=_tmp0->content;
    1607                 goto doRange;
    1608               }
    1609             }
    1610           }
    1611           xmlAddChild(nc6,nc8);
    1612           xmlAddChild(nc3,nc6);
    1613           isAnyValue=-1;
    1614         }
    1615        
    1616       }
    1617      
    1618       int oI=0;
    1619       for(oI=0;oI<13;oI++)
    1620         if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
    1621 #ifdef DEBUG
    1622           printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
    1623 #endif
    1624           if(strcmp(tmp1->name,"asReference")!=0 &&
    1625              strncasecmp(tmp1->name,"DataType",8)!=0 &&
    1626              strcasecmp(tmp1->name,"extension")!=0 &&
    1627              strcasecmp(tmp1->name,"value")!=0 &&
    1628              strcasecmp(tmp1->name,"AllowedValues")!=0 &&
    1629              strncasecmp(tmp1->name,"range",5)!=0){
    1630             if(datatype!=1){
    1631               char *tmp2=zCapitalize1(tmp1->name);
    1632               nc9 = xmlNewNode(NULL, BAD_CAST tmp2);
    1633               free(tmp2);
    1634             }
    1635             else{
    1636               char *tmp2=zCapitalize(tmp1->name);
    1637               nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
    1638               free(tmp2);
    1639             }
    1640             xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
    1641             xmlAddChild(nc5,nc9);
    1642             if(strcasecmp(tmp1->name,"uom")==0)
    1643               hasUOM1=true;
    1644             hasUOM=true;
    1645           }else
    1646          
    1647             tmp1=tmp1->next;
    1648         }
    1649    
    1650    
    1651       if(datatype!=2){
    1652         if(hasUOM==true){
    1653           xmlAddChild(nc4,nc5);
    1654           xmlAddChild(nc3,nc4);
    1655         }else{
    1656           if(hasUOM1==false){
    1657             xmlFreeNode(nc5);
    1658             if(datatype==1)
    1659               xmlFreeNode(nc4);
    1660           }
    1661         }
    1662       }else{
    1663         xmlAddChild(nc3,nc5);
    1664       }
    1665      
    1666       if(datatype!=1 && default1<0){
    1667         xmlFreeNode(nc5);
    1668         if(datatype!=2)
    1669           xmlFreeNode(nc4);
    1670       }
    1671 
    1672       map* metadata=e->metadata;
    1673       xmlNodePtr n=NULL;
    1674       int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
    1675       xmlNsPtr ns_xlink=usedNs[xlinkId];
    1676 
    1677       while(metadata!=NULL){
    1678         nc6=xmlNewNode(ns_ows, BAD_CAST "Metadata");
    1679         xmlNewNsProp(nc6,ns_xlink,BAD_CAST metadata->name,BAD_CAST metadata->value);
    1680         xmlAddChild(nc2,nc6);
    1681         metadata=metadata->next;
    1682       }
    1683 
    1684     }
    1685 
    1686     _tmp=e->supported;
    1687     if(_tmp==NULL && datatype!=1)
    1688       _tmp=e->defaults;
    1689 
    1690     int hasSupported=-1;
    1691 
    1692     while(_tmp!=NULL){
    1693       if(hasSupported<0){
    1694         if(datatype==0){
    1695           nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
    1696           nc5 = xmlNewNode(NULL, BAD_CAST "Format");
    1697         }
    1698         else
    1699           nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
    1700         hasSupported=0;
    1701       }else
    1702         if(datatype==0)
    1703           nc5 = xmlNewNode(NULL, BAD_CAST "Format");
    1704       tmp1=_tmp->content;
    1705       int oI=0;
    1706       for(oI=0;oI<6;oI++)
    1707         if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
    1708 #ifdef DEBUG
    1709           printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
    1710 #endif
    1711           if(strcmp(tmp1->name,"asReference")!=0 &&
    1712              strcmp(tmp1->name,"value")!=0 &&
    1713              strcmp(tmp1->name,"DataType")!=0 &&
    1714              strcasecmp(tmp1->name,"extension")!=0){
    1715             if(datatype!=1){
    1716               char *tmp2=zCapitalize1(tmp1->name);
    1717               nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
    1718               free(tmp2);
    1719             }
    1720             else{
    1721               char *tmp2=zCapitalize(tmp1->name);
    1722               nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
    1723               free(tmp2);
    1724             }
    1725             if(datatype==2){
    1726               char *tmpv,*tmps;
    1727               tmps=strtok_r(tmp1->value,",",&tmpv);
    1728               while(tmps){
    1729                 xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
    1730                 tmps=strtok_r(NULL,",",&tmpv);
    1731                 if(tmps){
    1732                   char *tmp2=zCapitalize1(tmp1->name);
    1733                   nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
    1734                   free(tmp2);
    1735                 }
    1736               }
    1737             }
    1738             else{
    1739               xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
    1740             }
    1741             xmlAddChild(nc5,nc6);
    1742           }
    1743           tmp1=tmp1->next;
    1744         }
    1745       if(hasSupported<=0){
    1746         if(datatype==0){
    1747           xmlAddChild(nc4,nc5);
    1748           xmlAddChild(nc3,nc4);
    1749         }else{
    1750           if(datatype!=1)
    1751             xmlAddChild(nc3,nc5);
    1752         }
    1753         hasSupported=1;
    1754       }
    1755       else
    1756         if(datatype==0){
    1757           xmlAddChild(nc4,nc5);
    1758           xmlAddChild(nc3,nc4);
    1759         }
    1760         else
    1761           if(datatype!=1)
    1762             xmlAddChild(nc3,nc5);
    1763 
    1764       _tmp=_tmp->next;
    1765     }
    1766 
    1767     if(hasSupported==0){
    1768       if(datatype==0)
    1769         xmlFreeNode(nc4);
    1770       xmlFreeNode(nc5);
    1771     }
    1772 
    1773     _tmp=e->defaults;
    1774     if(datatype==1 && hasUOM1==true){
    1775       xmlAddChild(nc4,nc5);
    1776       xmlAddChild(nc3,nc4);
    1777     }
    1778 
    1779     if(in>0 && datatype==1 &&
    1780        getMap(_tmp->content,"AllowedValues")==NULL &&
    1781        getMap(_tmp->content,"range")==NULL &&
    1782        getMap(_tmp->content,"rangeMin")==NULL &&
    1783        getMap(_tmp->content,"rangeMax")==NULL &&
    1784        getMap(_tmp->content,"rangeClosure")==NULL ){
    1785       tmp1=getMap(_tmp->content,"dataType");
    1786       if(tmp1!=NULL && strcasecmp(tmp1->value,"boolean")==0){
    1787         nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
    1788         nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
    1789         xmlAddChild(nc7,xmlNewText(BAD_CAST "true"));
    1790         xmlAddChild(nc6,nc7);
    1791         nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
    1792         xmlAddChild(nc7,xmlNewText(BAD_CAST "false"));
    1793         xmlAddChild(nc6,nc7);
    1794         xmlAddChild(nc3,nc6);
    1795       }
    1796       else
    1797         xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
    1798     }
    1799    
    1800     if(_tmp!=NULL && (tmp1=getMap(_tmp->content,"value"))!=NULL){
    1801       nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
    1802       xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
    1803       xmlAddChild(nc3,nc7);
    1804     }
    1805    
    1806     xmlAddChild(nc2,nc3);
    1807    
    1808     xmlAddChild(nc1,nc2);
    1809    
    1810     e=e->next;
    1811   }
    1812 }
    1813 
    1814 /**
    1815  * Generate a wps:Execute XML document.
    1816  *
    1817  * @param m the conf maps containing the main.cfg settings
    1818  * @param request the map representing the HTTP request
    1819  * @param pid the process identifier linked to a service
    1820  * @param serv the serv structure created from the zcfg file
    1821  * @param service the service name
    1822  * @param status the status returned by the service
    1823  * @param inputs the inputs provided
    1824  * @param outputs the outputs generated by the service
    1825  */
    1826 void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
    1827   xmlNsPtr ns,ns_ows,ns_xlink;
    1828   xmlNodePtr nr,n,nc,nc1=NULL,nc3;
    1829   xmlDocPtr doc;
    1830   time_t time1; 
    1831   time(&time1);
    1832   nr=NULL;
    1833   doc = xmlNewDoc(BAD_CAST "1.0");
    1834   n = printWPSHeader(doc,m,"Execute","ExecuteResponse");
    1835   int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
    1836   ns=usedNs[wpsId];
    1837   int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
    1838   ns_ows=usedNs[owsId];
    1839   int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
    1840   ns_xlink=usedNs[xlinkId];
    1841 
    1842   char tmp[256];
    1843   char url[1024];
    1844   char stored_path[1024];
    1845   memset(tmp,0,256);
    1846   memset(url,0,1024);
    1847   memset(stored_path,0,1024);
    1848   maps* tmp_maps=getMaps(m,"main");
    1849   if(tmp_maps!=NULL){
    1850     map* tmpm1=getMap(tmp_maps->content,"serverAddress");
    1851     /**
    1852      * Check if the ZOO Service GetStatus is available in the local directory.
    1853      * If yes, then it uses a reference to an URL which the client can access
    1854      * to get information on the status of a running Service (using the
    1855      * percentCompleted attribute).
    1856      * Else fallback to the initial method using the xml file to write in ...
    1857      */
    1858     char ntmp[1024];
    1859 #ifndef WIN32
    1860     getcwd(ntmp,1024);
    1861 #else
    1862     _getcwd(ntmp,1024);
    1863 #endif
    1864     struct stat myFileInfo;
    1865     int statRes;
    1866     char file_path[1024];
    1867     sprintf(file_path,"%s/GetStatus.zcfg",ntmp);
    1868     statRes=stat(file_path,&myFileInfo);
    1869     if(statRes==0){
    1870       char currentSid[128];
    1871       map* tmpm=getMap(tmp_maps->content,"rewriteUrl");
    1872       map *tmp_lenv=NULL;
    1873       tmp_lenv=getMapFromMaps(m,"lenv","usid");
    1874       if(tmp_lenv==NULL)
    1875         sprintf(currentSid,"%i",pid);
    1876       else
    1877         sprintf(currentSid,"%s",tmp_lenv->value);
    1878       if(tmpm==NULL || strcasecmp(tmpm->value,"false")==0){
    1879         sprintf(url,"%s?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
    1880       }else{
    1881         if(strlen(tmpm->value)>0)
    1882           if(strcasecmp(tmpm->value,"true")!=0)
    1883             sprintf(url,"%s/%s/GetStatus/%s",tmpm1->value,tmpm->value,currentSid);
    1884           else
    1885             sprintf(url,"%s/GetStatus/%s",tmpm1->value,currentSid);
    1886         else
    1887           sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
    1888       }
    1889     }else{
    1890       int lpid;
    1891       map* tmpm2=getMapFromMaps(m,"lenv","usid");
    1892       lpid=atoi(tmpm2->value);
    1893       tmpm2=getMap(tmp_maps->content,"tmpUrl");
    1894       if(tmpm1!=NULL && tmpm2!=NULL){
    1895         if( strncasecmp( tmpm2->value, "http://", 7) == 0 ||
    1896             strncasecmp( tmpm2->value, "https://", 8 ) == 0 ){
    1897           sprintf(url,"%s/%s_%i.xml",tmpm2->value,service,lpid);
    1898         }else
    1899           sprintf(url,"%s/%s/%s_%i.xml",tmpm1->value,tmpm2->value,service,lpid);
    1900       }
    1901     }
    1902     if(tmpm1!=NULL)
    1903       sprintf(tmp,"%s",tmpm1->value);
    1904     int lpid;
    1905     tmpm1=getMapFromMaps(m,"lenv","usid");
    1906     lpid=atoi(tmpm1->value);
    1907     tmpm1=getMapFromMaps(m,"main","TmpPath");
    1908     sprintf(stored_path,"%s/%s_%i.xml",tmpm1->value,service,lpid);
    1909   }
    1910 
    1911 
    1912 
    1913   xmlNewProp(n,BAD_CAST "serviceInstance",BAD_CAST tmp);
    1914   map* test=getMap(request,"storeExecuteResponse");
    1915   bool hasStoredExecuteResponse=false;
    1916   if(test!=NULL && strcasecmp(test->value,"true")==0){
    1917     xmlNewProp(n,BAD_CAST "statusLocation",BAD_CAST url);
    1918     hasStoredExecuteResponse=true;
    1919   }
    1920 
    1921   nc = xmlNewNode(ns, BAD_CAST "Process");
    1922   map* tmp2=getMap(serv->content,"processVersion");
    1923   if(tmp2!=NULL)
    1924     xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp2->value);
    1925  
    1926   map* tmpI=getMapFromMaps(m,"lenv","oIdentifier");
    1927   printDescription(nc,ns_ows,tmpI->value,serv->content);
    1928 
    1929   xmlAddChild(n,nc);
    1930 
    1931   nc = xmlNewNode(ns, BAD_CAST "Status");
    1932   const struct tm *tm;
    1933   size_t len;
    1934   time_t now;
    1935   char *tmp1;
    1936   map *tmpStatus;
    1937  
    1938   now = time ( NULL );
    1939   tm = localtime ( &now );
    1940 
    1941   tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
    1942 
    1943   len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
    1944 
    1945   xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
    1946 
    1947   char sMsg[2048];
    1948   switch(status){
    1949   case SERVICE_SUCCEEDED:
    1950     nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
    1951     sprintf(sMsg,_("The service \"%s\" ran successfully."),serv->name);
    1952     nc3=xmlNewText(BAD_CAST sMsg);
    1953     xmlAddChild(nc1,nc3);
    1954     break;
    1955   case SERVICE_STARTED:
    1956     nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
    1957     tmpStatus=getMapFromMaps(m,"lenv","status");
    1958     xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
    1959     sprintf(sMsg,_("The ZOO service \"%s\" is currently running. Please reload this document to get the up-to-date status of the service."),serv->name);
    1960     nc3=xmlNewText(BAD_CAST sMsg);
    1961     xmlAddChild(nc1,nc3);
    1962     break;
    1963   case SERVICE_ACCEPTED:
    1964     nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
    1965     sprintf(sMsg,_("The service \"%s\" was accepted by the ZOO kernel and is running as a background task. Please access the URL in the statusLocation attribute provided in this document to get the up-to-date status and results."),serv->name);
    1966     nc3=xmlNewText(BAD_CAST sMsg);
    1967     xmlAddChild(nc1,nc3);
    1968     break;
    1969   case SERVICE_FAILED:
    1970     nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
    1971     map *errorMap;
    1972     map *te;
    1973     te=getMapFromMaps(m,"lenv","code");
    1974     if(te!=NULL)
    1975       errorMap=createMap("code",te->value);
    1976     else
    1977       errorMap=createMap("code","NoApplicableCode");
    1978     te=getMapFromMaps(m,"lenv","message");
    1979     if(te!=NULL)
    1980       addToMap(errorMap,"text",_ss(te->value));
    1981     else
    1982       addToMap(errorMap,"text",_("No more information available"));
    1983     nc3=createExceptionReportNode(m,errorMap,0);
    1984     freeMap(&errorMap);
    1985     free(errorMap);
    1986     xmlAddChild(nc1,nc3);
    1987     break;
    1988   default :
    1989     printf(_("error code not know : %i\n"),status);
    1990     //exit(1);
    1991     break;
    1992   }
    1993   xmlAddChild(nc,nc1);
    1994   xmlAddChild(n,nc);
    1995   free(tmp1);
    1996 
    1997 #ifdef DEBUG
    1998   fprintf(stderr,"printProcessResponse 1 161\n");
    1999 #endif
    2000 
    2001   map* lineage=getMap(request,"lineage");
    2002   if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
    2003     nc = xmlNewNode(ns, BAD_CAST "DataInputs");
    2004     maps* mcursor=inputs;
    2005     elements* scursor=NULL;
    2006     while(mcursor!=NULL /*&& scursor!=NULL*/){
    2007       scursor=getElements(serv->inputs,mcursor->name);
    2008       printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input");
    2009       mcursor=mcursor->next;
    2010     }
    2011     xmlAddChild(n,nc);
    2012    
    2013 #ifdef DEBUG
    2014     fprintf(stderr,"printProcessResponse 1 177\n");
    2015 #endif
    2016 
    2017     nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
    2018     mcursor=outputs;
    2019     scursor=NULL;
    2020     while(mcursor!=NULL){
    2021       scursor=getElements(serv->outputs,mcursor->name);
    2022       printOutputDefinitions(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
    2023       mcursor=mcursor->next;
    2024     }
    2025     xmlAddChild(n,nc);
    2026   }
    2027 #ifdef DEBUG
    2028   fprintf(stderr,"printProcessResponse 1 190\n");
    2029 #endif
    2030 
    2031   /**
    2032    * Display the process output only when requested !
    2033    */
    2034   if(status==SERVICE_SUCCEEDED){
    2035     nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
    2036     maps* mcursor=outputs;
    2037     elements* scursor=serv->outputs;
    2038     map* testResponse=getMap(request,"RawDataOutput");
    2039     if(testResponse==NULL)
    2040       testResponse=getMap(request,"ResponseDocument");
    2041     while(mcursor!=NULL){
    2042       map* tmp0=getMap(mcursor->content,"inRequest");
    2043       scursor=getElements(serv->outputs,mcursor->name);
    2044       if(scursor!=NULL){
    2045         if(testResponse==NULL || tmp0==NULL)
    2046           printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
    2047         else
    2048           if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0)
    2049             printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
    2050       }else
    2051         /**
    2052          * In case there was no definition found in the ZCFG file but
    2053          * present in the service code
    2054          */
    2055         printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
    2056       mcursor=mcursor->next;
    2057     }
    2058     xmlAddChild(n,nc);
    2059   }
    2060 
    2061   if(hasStoredExecuteResponse==true && status!=SERVICE_STARTED){
    2062     semid lid=getShmLockId(m,1);
    2063     if(lid<0){
    2064       /* If the lock failed */
    2065       errorException(m,_("Lock failed."),"InternalError",NULL);
    2066       xmlFreeDoc(doc);
    2067       xmlCleanupParser();
    2068       zooXmlCleanupNs();
    2069       return;
    2070     }
    2071     else{
    2072 #ifdef DEBUG
    2073       fprintf(stderr,"LOCK %s %d !\n",__FILE__,__LINE__);
    2074 #endif
    2075       lockShm(lid);
    2076       /* We need to write the ExecuteResponse Document somewhere */
    2077       FILE* output=fopen(stored_path,"w");
    2078       if(output==NULL){
    2079         /* If the file cannot be created return an ExceptionReport */
    2080         char tmpMsg[1024];
    2081         sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the ExecuteResponse."),stored_path);
    2082 
    2083         errorException(m,tmpMsg,"InternalError",NULL);
    2084         xmlFreeDoc(doc);
    2085         xmlCleanupParser();
    2086         zooXmlCleanupNs();
    2087         unlockShm(lid);
    2088         return;
    2089       }
    2090       xmlChar *xmlbuff;
    2091       int buffersize;
    2092       xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
    2093       fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
    2094       xmlFree(xmlbuff);
    2095       fclose(output);
    2096 #ifdef DEBUG
    2097       fprintf(stderr,"UNLOCK %s %d !\n",__FILE__,__LINE__);
    2098 #endif
    2099       unlockShm(lid);
    2100       map* test1=getMap(request,"status");
    2101       if(test1==NULL || strcasecmp(test1->value,"true")!=0){
    2102         removeShmLock(m,1);
    2103       }
    2104     }
    2105   }
    2106   printDocument(m,doc,pid);
    2107 
    2108   xmlCleanupParser();
    2109   zooXmlCleanupNs();
    2110 }
    2111 
    2112 /**
    2113  * Print a XML document.
    2114  *
    2115  * @param m the conf maps containing the main.cfg settings
    2116  * @param doc the XML document
    2117  * @param pid the process identifier linked to a service
    2118  */
    2119 void printDocument(maps* m, xmlDocPtr doc,int pid){
    2120   char *encoding=getEncoding(m);
    2121   if(pid==getpid()){
    2122     printHeaders(m);
    2123     printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
    2124   }
    2125   fflush(stdout);
    2126   xmlChar *xmlbuff;
    2127   int buffersize;
    2128   /*
    2129    * Dump the document to a buffer and print it on stdout
    2130    * for demonstration purposes.
    2131    */
    2132   xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
    2133   printf("%s",xmlbuff);
    2134   fflush(stdout);
    2135   /*
    2136    * Free associated memory.
    2137    */
    2138   xmlFree(xmlbuff);
    2139   xmlFreeDoc(doc);
    2140   xmlCleanupParser();
    2141   zooXmlCleanupNs();
    2142 }
    2143 
    2144 /**
    2145  * Print a XML document.
    2146  *
    2147  * @param doc the XML document (unused)
    2148  * @param nc the XML node to add the output definition
    2149  * @param ns_wps the wps XML namespace
    2150  * @param ns_ows the ows XML namespace
    2151  * @param e the output elements
    2152  * @param m the conf maps containing the main.cfg settings
    2153  * @param type the type (unused)
    2154  */
    2155 void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
    2156   xmlNodePtr nc1;
    2157   nc1=xmlNewNode(ns_wps, BAD_CAST type);
    2158   map *tmp=NULL; 
    2159   if(e!=NULL && e->defaults!=NULL)
    2160     tmp=e->defaults->content;
    2161   else{
    2162     /*
    2163     dumpElements(e);
    2164     */
    2165     return;
    2166   }
    2167   while(tmp!=NULL){
    2168     if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
    2169        || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
    2170        || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
    2171        || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
    2172     xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
    2173     tmp=tmp->next;
    2174   }
    2175   tmp=getMap(e->defaults->content,"asReference");
    2176   if(tmp==NULL)
    2177     xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
    2178 
    2179   tmp=e->content;
    2180 
    2181   printDescription(nc1,ns_ows,m->name,e->content);
    2182 
    2183   xmlAddChild(nc,nc1);
    2184 
    2185 }
    2186 
    2187 /**
    2188  * Generate XML nodes describing inputs or outputs metadata.
    2189  *
    2190  * @param doc the XML document
    2191  * @param nc the XML node to add the definition
    2192  * @param ns_wps the wps namespace
    2193  * @param ns_ows the ows namespace
    2194  * @param ns_xlink the xlink namespace
    2195  * @param e the output elements
    2196  * @param m the conf maps containing the main.cfg settings
    2197  * @param type the type
    2198  */
    2199 void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type){
    2200 
    2201   xmlNodePtr nc1,nc2,nc3;
    2202   nc1=xmlNewNode(ns_wps, BAD_CAST type);
    2203   map *tmp=NULL;
    2204   if(e!=NULL)
    2205     tmp=e->content;
    2206   else
    2207     tmp=m->content;
    2208 
    2209   nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
    2210   if(e!=NULL)
    2211     nc3=xmlNewText(BAD_CAST e->name);
    2212   else
    2213     nc3=xmlNewText(BAD_CAST m->name);
    2214 
    2215   xmlAddChild(nc2,nc3);
    2216   xmlAddChild(nc1,nc2);
    2217   xmlAddChild(nc,nc1);
    2218   if(e!=NULL)
    2219     tmp=getMap(e->content,"Title");
    2220   else
    2221     tmp=getMap(m->content,"Title");
    2222  
    2223   if(tmp!=NULL){
    2224     nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
    2225     nc3=xmlNewText(BAD_CAST _ss(tmp->value));
    2226     xmlAddChild(nc2,nc3); 
    2227     xmlAddChild(nc1,nc2);
    2228   }
    2229 
    2230   if(e!=NULL)
    2231     tmp=getMap(e->content,"Abstract");
    2232   else
    2233     tmp=getMap(m->content,"Abstract");
    2234 
    2235   if(tmp!=NULL){
    2236     nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
    2237     nc3=xmlNewText(BAD_CAST _ss(tmp->value));
    2238     xmlAddChild(nc2,nc3); 
    2239     xmlAddChild(nc1,nc2);
    2240     xmlAddChild(nc,nc1);
    2241   }
    2242 
    2243   /**
    2244    * IO type Reference or full Data ?
    2245    */
    2246   map *tmpMap=getMap(m->content,"Reference");
    2247   if(tmpMap==NULL){
    2248     nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
    2249     if(e!=NULL){
    2250       if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
    2251         nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
    2252       else
    2253         if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
    2254           nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
    2255         else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
    2256           nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
    2257         else
    2258           nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
    2259     }
    2260     else {
    2261       map* tmpV=getMapFromMaps(m,"format","value");
    2262       if(tmpV!=NULL)
    2263         nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
    2264       else
    2265         nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
    2266     }
    2267     tmp=m->content;
    2268 
    2269     while(tmp!=NULL){
    2270       if(strcasecmp(tmp->name,"mimeType")==0 ||
    2271          strcasecmp(tmp->name,"encoding")==0 ||
    2272          strcasecmp(tmp->name,"schema")==0 ||
    2273          strcasecmp(tmp->name,"datatype")==0 ||
    2274          strcasecmp(tmp->name,"uom")==0) {
    2275 
    2276         xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
    2277       }
    2278       tmp=tmp->next;
    2279       xmlAddChild(nc2,nc3);
    2280     }
    2281     if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0) {
    2282       map* bb=getMap(m->content,"value");
    2283       if(bb!=NULL) {
    2284         map* tmpRes=parseBoundingBox(bb->value);
    2285         printBoundingBox(ns_ows,nc3,tmpRes);
    2286         freeMap(&tmpRes);
    2287         free(tmpRes);
    2288       }
    2289     }
    2290     else {
    2291       if(e!=NULL)
    2292         tmp=getMap(e->defaults->content,"mimeType");
    2293       else
    2294         tmp=NULL;
    2295        
    2296       map* tmp1=getMap(m->content,"encoding");
    2297       map* tmp2=getMap(m->content,"mimeType");
    2298       map* tmp3=getMap(m->content,"value");
    2299       int hasValue=1;
    2300       if(tmp3==NULL){
    2301         tmp3=createMap("value","");
    2302         hasValue=-1;
    2303       }
    2304 
    2305       if( ( tmp1 != NULL && strncmp(tmp1->value,"base64",6) == 0 )     // if encoding is base64
    2306           ||                                                           // or if
    2307           ( tmp2 != NULL && ( strstr(tmp2->value,"text") == NULL       //  mime type is not text
    2308                               &&                                       //  nor
    2309                               strstr(tmp2->value,"xml") == NULL        //  xml
    2310                               &&                                       // nor
    2311                               strstr(tmp2->value,"javascript") == NULL // javascript
    2312                               &&
    2313                               strstr(tmp2->value,"json") == NULL
    2314                               &&
    2315                               strstr(tmp2->value,"ecmascript") == NULL
    2316                               &&
    2317                               // include for backwards compatibility,
    2318                               // although correct mime type is ...kml+xml:
    2319                               strstr(tmp2->value,"google-earth.kml") == NULL                                                    )
    2320             )
    2321           ) {                                                    // then       
    2322         map* rs=getMap(m->content,"size");                       // obtain size
    2323         bool isSized=true;
    2324         if(rs==NULL){
    2325           char tmp1[1024];
    2326           sprintf(tmp1,"%ld",strlen(tmp3->value));
    2327           rs=createMap("size",tmp1);
    2328           isSized=false;
    2329         }
    2330          
    2331         xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));  // base 64 encode in XML
    2332                
    2333         if(tmp1==NULL || (tmp1!=NULL && strncmp(tmp1->value,"base64",6)!=0)) {
    2334           xmlAttrPtr ap = xmlHasProp(nc3, BAD_CAST "encoding");
    2335           if (ap != NULL) {
    2336             xmlRemoveProp(ap);
    2337           }                     
    2338           xmlNewProp(nc3,BAD_CAST "encoding",BAD_CAST "base64");
    2339         }
    2340                
    2341         if(!isSized){
    2342           freeMap(&rs);
    2343           free(rs);
    2344         }
    2345       }
    2346       else if (tmp2!=NULL) {                                 // else (text-based format)
    2347         if(strstr(tmp2->value, "javascript") != NULL ||      //    if javascript put code in CDATA block
    2348            strstr(tmp2->value, "json") != NULL ||            //    (will not be parsed by XML reader)
    2349            strstr(tmp2->value, "ecmascript") != NULL
    2350            ) {
    2351           xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
    2352         }   
    2353         else {                                                     // else
    2354           if (strstr(tmp2->value, "xml") != NULL ||                 // if XML-based format
    2355               // include for backwards compatibility,
    2356               // although correct mime type is ...kml+xml:                 
    2357               strstr(tmp2->value, "google-earth.kml") != NULL
    2358               ) {
    2359                          
    2360             int li=zooXmlAddDoc(tmp3->value);
    2361             xmlDocPtr doc = iDocs[li];
    2362             xmlNodePtr ir = xmlDocGetRootElement(doc);
    2363             xmlAddChild(nc3,ir);
    2364           }
    2365           else                                                     // else     
    2366             xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));    //   add text node
    2367         }
    2368         xmlAddChild(nc2,nc3);
    2369       }
    2370       else {
    2371         xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
    2372       }
    2373          
    2374       if(hasValue<0) {
    2375         freeMap(&tmp3);
    2376         free(tmp3);
    2377       }
    2378     }
    2379   }
    2380   else { // Reference
    2381     tmpMap=getMap(m->content,"Reference");
    2382     nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
    2383     if(strcasecmp(type,"Output")==0)
    2384       xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
    2385     else
    2386       xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
    2387    
    2388     tmp=m->content;
    2389     while(tmp!=NULL) {
    2390       if(strcasecmp(tmp->name,"mimeType")==0 ||
    2391          strcasecmp(tmp->name,"encoding")==0 ||
    2392          strcasecmp(tmp->name,"schema")==0 ||
    2393          strcasecmp(tmp->name,"datatype")==0 ||
    2394          strcasecmp(tmp->name,"uom")==0){
    2395 
    2396         if(strcasecmp(tmp->name,"datatype")==0)
    2397           xmlNewProp(nc3,BAD_CAST "mimeType",BAD_CAST "text/plain");
    2398         else
    2399           xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
    2400       }
    2401       tmp=tmp->next;
    2402       xmlAddChild(nc2,nc3);
    2403     }
    2404   }
    2405   xmlAddChild(nc1,nc2);
    2406   xmlAddChild(nc,nc1);
    2407 }
    2408 
    2409 /**
    2410  * Create XML node with basic ows metadata informations (Identifier,Title,Abstract)
    2411  *
    2412  * @param root the root XML node to add the description
    2413  * @param ns_ows the ows XML namespace
    2414  * @param identifier the identifier to use
    2415  * @param amap the map containing the ows metadata informations
    2416  */
    2417 void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
    2418   xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
    2419  
    2420   xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
    2421   xmlAddChild(root,nc2);
    2422   map* tmp=amap;
    2423   const char *tmp2[2];
    2424   tmp2[0]="Title";
    2425   tmp2[1]="Abstract";
    2426   int j=0;
    2427   for(j=0;j<2;j++){
    2428     map* tmp1=getMap(tmp,tmp2[j]);
    2429     if(tmp1!=NULL){
    2430       nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
    2431       xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
    2432       xmlAddChild(root,nc2);
    2433     }
    2434   }
    2435 }
    2436 
    2437 /**
    2438  * Access the value of the encoding key in a maps
    2439  *
    2440  * @param m the maps to search for the encoding key
    2441  * @return the value of the encoding key in a maps if encoding key exists,
    2442  *  "UTF-8" in other case.
    2443  */
    2444 char* getEncoding(maps* m){
    2445   if(m!=NULL){
    2446     map* tmp=getMap(m->content,"encoding");
    2447     if(tmp!=NULL){
    2448       return tmp->value;
    2449     }
    2450     else
    2451       return (char*)"UTF-8";
    2452   }
    2453   else
    2454     return (char*)"UTF-8"; 
    2455 }
    2456 
    2457 /**
    2458  * Access the value of the version key in a maps
    2459  *
    2460  * @param m the maps to search for the version key
    2461  * @return the value of the version key in a maps if encoding key exists,
    2462  *  "1.0.0" in other case.
    2463  */
    2464 char* getVersion(maps* m){
    2465   if(m!=NULL){
    2466     map* tmp=getMap(m->content,"version");
    2467     if(tmp!=NULL){
    2468       return tmp->value;
    2469     }
    2470     else
    2471       return (char*)"1.0.0";
    2472   }
    2473   else
    2474     return (char*)"1.0.0";
    2475 }
    2476 
    2477 /**
    2478  * Print an OWS ExceptionReport Document and HTTP headers (when required)
    2479  * depending on the code.
    2480  * Set hasPrinted value to true in the [lenv] section.
    2481  *
    2482  * @param m the maps containing the settings of the main.cfg file
    2483  * @param s the map containing the text,code,locator keys
    2484  */
    2485 void printExceptionReportResponse(maps* m,map* s){
    2486   if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
    2487     return;
    2488   int buffersize;
    2489   xmlDocPtr doc;
    2490   xmlChar *xmlbuff;
    2491   xmlNodePtr n;
    2492 
    2493   zooXmlCleanupNs();
    2494   doc = xmlNewDoc(BAD_CAST "1.0");
    2495   maps* tmpMap=getMaps(m,"main");
    2496   char *encoding=getEncoding(tmpMap);
    2497   const char *exceptionCode;
    2498  
    2499   map* tmp=getMap(s,"code");
    2500   if(tmp!=NULL){
    2501     if(strcmp(tmp->value,"OperationNotSupported")==0 ||
    2502        strcmp(tmp->value,"NoApplicableCode")==0)
    2503       exceptionCode="501 Not Implemented";
    2504     else
    2505       if(strcmp(tmp->value,"MissingParameterValue")==0 ||
    2506          strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
    2507          strcmp(tmp->value,"OptionNotSupported")==0 ||
    2508          strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
    2509          strcmp(tmp->value,"InvalidParameterValue")==0)
    2510         exceptionCode="400 Bad request";
    2511       else
    2512         exceptionCode="501 Internal Server Error";
    2513   }
    2514   else
    2515     exceptionCode="501 Internal Server Error";
    2516 
    2517   if(m!=NULL){
    2518     map *tmpSid=getMapFromMaps(m,"lenv","sid");
    2519     if(tmpSid!=NULL){
    2520       if( getpid()==atoi(tmpSid->value) ){
    2521         printHeaders(m);
    2522         printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
    2523       }
    2524     }
    2525     else{
    2526       printHeaders(m);
    2527       printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
    2528     }
    2529   }else{
    2530     printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
    2531   }
    2532   n=createExceptionReportNode(m,s,1);
    2533   xmlDocSetRootElement(doc, n);
    2534   xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
    2535   printf("%s",xmlbuff);
    2536   fflush(stdout);
    2537   xmlFreeDoc(doc);
    2538   xmlFree(xmlbuff);
    2539   xmlCleanupParser();
    2540   zooXmlCleanupNs();
    2541   if(m!=NULL)
    2542     setMapInMaps(m,"lenv","hasPrinted","true");
    2543 }
    2544 
    2545 /**
    2546  * Create an OWS ExceptionReport Node.
    2547  *
    2548  * @param m the conf maps
    2549  * @param s the map containing the text,code,locator keys
    2550  * @param use_ns (0/1) choose if you want to generate an ExceptionReport or
    2551  *  ows:ExceptionReport node respectively
    2552  * @return the ExceptionReport/ows:ExceptionReport node
    2553  */
    2554 xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
    2555  
    2556   xmlNsPtr ns,ns_xsi;
    2557   xmlNodePtr n,nc,nc1;
    2558 
    2559   int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows","ows");
    2560   ns=usedNs[nsid];
    2561   if(use_ns==0){
    2562     ns=NULL;
    2563   }
    2564   n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
    2565   if(use_ns==1){
    2566     xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST"ows");
    2567     int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
    2568     ns_xsi=usedNs[xsiId];
    2569     xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd");
    2570   }
    2571 
    2572 
    2573   addLangAttr(n,m);
    2574   xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
    2575  
    2576   int length=1;
    2577   int cnt=0;
    2578   map* len=getMap(s,"length");
    2579   if(len!=NULL)
    2580     length=atoi(len->value);
    2581   for(cnt=0;cnt<length;cnt++){
    2582     nc = xmlNewNode(ns, BAD_CAST "Exception");
    2583    
    2584     map* tmp=getMapArray(s,"code",cnt);
    2585     if(tmp==NULL)
    2586       tmp=getMap(s,"code");
    2587     if(tmp!=NULL)
    2588       xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
    2589     else
    2590       xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
    2591    
    2592     tmp=getMapArray(s,"locator",cnt);
    2593     if(tmp==NULL)
    2594       tmp=getMap(s,"locator");
    2595     if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
    2596       xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
    2597 
    2598     tmp=getMapArray(s,"text",cnt);
    2599     nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
    2600     if(tmp!=NULL){
    2601       xmlNodePtr txt=xmlNewText(BAD_CAST tmp->value);
    2602       xmlAddChild(nc1,txt);
    2603     }
    2604     else{
    2605       xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
    2606     }
    2607     xmlAddChild(nc,nc1);
    2608     xmlAddChild(n,nc);
    2609   }
    2610   return n;
    2611 }
    2612 
    2613 /**
    2614  * Print an OWS ExceptionReport.
    2615  *
    2616  * @param m the conf maps
    2617  * @param message the error message
    2618  * @param errorcode the error code
    2619  * @param locator the potential locator
    2620  */
    2621 int errorException(maps *m, const char *message, const char *errorcode, const char *locator)
    2622 {
    2623   map* errormap = createMap("text", message);
    2624   addToMap(errormap,"code", errorcode);
    2625   if(locator!=NULL)
    2626     addToMap(errormap,"locator", locator);
    2627   else
    2628     addToMap(errormap,"locator", "NULL");
    2629   printExceptionReportResponse(m,errormap);
    2630   freeMap(&errormap);
    2631   free(errormap);
    2632   return -1;
    2633 }
    2634 
    2635 /**
    2636  * Read a file generated by a service.
    2637  *
    2638  * @param m the conf maps
    2639  * @param content the output item
    2640  * @param filename the file to read
    2641  */
    2642 void readGeneratedFile(maps* m,map* content,char* filename){
    2643   FILE * file=fopen(filename,"rb");
    2644   if(file==NULL){
    2645     fprintf(stderr,"Failed to open file %s for reading purpose.\n",filename);
    2646     setMapInMaps(m,"lenv","message","Unable to read produced file. Please try again later");
    2647     return ;
    2648   }
    2649   fseek(file, 0, SEEK_END);
    2650   long count = ftell(file);
    2651   rewind(file);
    2652   struct stat file_status;
    2653   stat(filename, &file_status);
    2654   map* tmpMap1=getMap(content,"value");
    2655   if(tmpMap1==NULL){
    2656     addToMap(content,"value","");
    2657     tmpMap1=getMap(content,"value");
    2658   }
    2659   free(tmpMap1->value);
    2660   tmpMap1->value=(char*) malloc((count+1)*sizeof(char)); 
    2661   fread(tmpMap1->value,1,count,file);
    2662   tmpMap1->value[count]=0;
    2663   fclose(file);
    2664   char rsize[1000];
    2665   sprintf(rsize,"%ld",count);
    2666   addToMap(content,"size",rsize);
    2667 }
    2668 
    2669 /**
    2670  * Generate the output response (RawDataOutput or ResponseDocument)
    2671  *
    2672  * @param s the service structure containing the metadata informations
    2673  * @param request_inputs the inputs provided to the service for execution
    2674  * @param request_outputs the outputs updated by the service execution
    2675  * @param request_inputs1 the map containing the HTTP request
    2676  * @param cpid the process identifier attached to a service execution
    2677  * @param m the conf maps containing the main.cfg settings
    2678  * @param res the value returned by the service execution
    2679  */
    2680 void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
    2681                     map* request_inputs1,int cpid,maps* m,int res){
    2682 #ifdef DEBUG
    2683   dumpMaps(request_inputs);
    2684   dumpMaps(request_outputs);
    2685   fprintf(stderr,"printProcessResponse\n");
    2686 #endif
    2687   map* toto=getMap(request_inputs1,"RawDataOutput");
    2688   int asRaw=0;
    2689   if(toto!=NULL)
    2690     asRaw=1;
    2691  
    2692   maps* tmpSess=getMaps(m,"senv");
    2693   if(tmpSess!=NULL){
    2694     map *_tmp=getMapFromMaps(m,"lenv","cookie");
    2695     char* sessId=NULL;
    2696     if(_tmp!=NULL){
    2697       printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
    2698       printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
    2699       char session_file_path[100];
    2700       char *tmp1=strtok(_tmp->value,";");
    2701       if(tmp1!=NULL)
    2702         sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
    2703       else
    2704         sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
    2705       sessId=strdup(session_file_path);
    2706     }else{
    2707       maps* t=getMaps(m,"senv");
    2708       map*p=t->content;
    2709       while(p!=NULL){
    2710         if(strstr(p->name,"ID")!=NULL){
    2711           sessId=strdup(p->value);
    2712           break;
    2713         }
    2714         p=p->next;
    2715       }
    2716     }
    2717     char session_file_path[1024];
    2718     map *tmpPath=getMapFromMaps(m,"main","sessPath");
    2719     if(tmpPath==NULL)
    2720       tmpPath=getMapFromMaps(m,"main","tmpPath");
    2721     sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
    2722     FILE* teste=fopen(session_file_path,"w");
    2723     if(teste==NULL){
    2724       char tmpMsg[1024];
    2725       sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the session maps."),session_file_path);
    2726       errorException(m,tmpMsg,"InternalError",NULL);
    2727 
    2728       return;
    2729     }
    2730     else{
    2731       fclose(teste);
    2732       dumpMapsToFile(tmpSess,session_file_path);
    2733     }
    2734   }
    2735  
    2736   if(res==SERVICE_FAILED){
    2737     map *lenv;
    2738     lenv=getMapFromMaps(m,"lenv","message");
    2739     char *tmp0;
    2740     if(lenv!=NULL){
    2741       tmp0=(char*)malloc((strlen(lenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "))+1)*sizeof(char));
    2742       sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
    2743     }
    2744     else{
    2745       tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
    2746       sprintf(tmp0,"%s",_("Unable to run the Service. No more information was returned back by the Service."));
    2747     }
    2748     errorException(m,tmp0,"InternalError",NULL);
    2749     free(tmp0);
    2750     return;
    2751   }
    2752 
    2753 
    2754   map *tmp1=getMapFromMaps(m,"main","tmpPath");
    2755   if(asRaw==0){
    2756 #ifdef DEBUG
    2757     fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
    2758     dumpMaps(request_outputs);
    2759 #endif
    2760     maps* tmpI=request_outputs;
    2761 
    2762     while(tmpI!=NULL){
    2763 #ifdef USE_MS
    2764       map* testMap=getMap(tmpI->content,"useMapserver");       
    2765 #endif
    2766       map *gfile=getMap(tmpI->content,"generated_file");
    2767       char *file_name;
    2768       if(gfile!=NULL){
    2769         gfile=getMap(tmpI->content,"expected_generated_file");
    2770         if(gfile==NULL){
    2771           gfile=getMap(tmpI->content,"generated_file");
    2772         }
    2773         readGeneratedFile(m,tmpI->content,gfile->value);           
    2774         file_name=(char*)malloc((strlen(gfile->value)+strlen(tmp1->value)+1)*sizeof(char));
    2775         for(int i=0;i<strlen(gfile->value);i++)
    2776           file_name[i]=gfile->value[i+strlen(tmp1->value)];
    2777       }
    2778 
    2779       toto=getMap(tmpI->content,"asReference");
    2780 #ifdef USE_MS
    2781       if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
    2782 #else
    2783       if(toto!=NULL && strcasecmp(toto->value,"true")==0)
    2784 #endif
    2785         {
    2786           elements* in=getElements(s->outputs,tmpI->name);
    2787           char *format=NULL;
    2788           if(in!=NULL){
    2789             format=strdup(in->format);
    2790           }else
    2791             format=strdup("LiteralData");
    2792           if(strcasecmp(format,"BoundingBoxData")==0){
    2793             addToMap(tmpI->content,"extension","xml");
    2794             addToMap(tmpI->content,"mimeType","text/xml");
    2795             addToMap(tmpI->content,"encoding","UTF-8");
    2796             addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
    2797           }
    2798 
    2799           if(gfile==NULL){
    2800             map *ext=getMap(tmpI->content,"extension");
    2801             char *file_path;
    2802             char file_ext[32];
    2803 
    2804             if( ext != NULL && ext->value != NULL) {
    2805               strncpy(file_ext, ext->value, 32);
    2806             }
    2807             else {
    2808               // Obtain default file extension (see mimetypes.h).             
    2809               // If the MIME type is not recognized, txt is used as the default extension
    2810               map* mtype=getMap(tmpI->content,"mimeType");
    2811               getFileExtension(mtype != NULL ? mtype->value : NULL, file_ext, 32);
    2812             }
    2813                
    2814             file_name=(char*)malloc((strlen(s->name)+strlen(file_ext)+strlen(tmpI->name)+1024)*sizeof(char));
    2815             int cpid0=cpid+time(NULL);     
    2816             sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,file_ext);
    2817             file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
    2818             sprintf(file_path,"%s/%s",tmp1->value,file_name);
    2819    
    2820                 FILE *ofile=fopen(file_path,"wb");
    2821             if(ofile==NULL){
    2822               char tmpMsg[1024];
    2823               sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the %s final result."),file_name,tmpI->name);
    2824               errorException(m,tmpMsg,"InternalError",NULL);
    2825               free(file_name);
    2826               free(file_path);
    2827               return;
    2828             }
    2829             free(file_path);
    2830 
    2831             toto=getMap(tmpI->content,"value");
    2832             if(strcasecmp(format,"BoundingBoxData")!=0){
    2833               map* size=getMap(tmpI->content,"size");
    2834               if(size!=NULL && toto!=NULL)
    2835                 fwrite(toto->value,1,(atoi(size->value))*sizeof(char),ofile);
    2836               else
    2837                 if(toto!=NULL && toto->value!=NULL)
    2838                   fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
    2839             }else{
    2840               printBoundingBoxDocument(m,tmpI,ofile);
    2841             }
    2842             fclose(ofile);
    2843 
    2844           }
    2845           map *tmp2=getMapFromMaps(m,"main","tmpUrl");
    2846           map *tmp3=getMapFromMaps(m,"main","serverAddress");
    2847           char *file_url;
    2848           if(strncasecmp(tmp2->value,"http://",7)==0 ||
    2849              strncasecmp(tmp2->value,"https://",8)==0){
    2850             file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
    2851             sprintf(file_url,"%s/%s",tmp2->value,file_name);
    2852           }else{
    2853             file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
    2854             sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
    2855           }
    2856           addToMap(tmpI->content,"Reference",file_url);
    2857           free(format);
    2858           free(file_name);
    2859           free(file_url);       
    2860          
    2861         }
    2862 #ifdef USE_MS
    2863       else{
    2864         if(testMap!=NULL){
    2865           setReferenceUrl(m,tmpI);
    2866         }
    2867       }
    2868 #endif
    2869       tmpI=tmpI->next;
    2870     }
    2871     map *r_inputs=getMap(s->content,"serviceProvider");
    2872 #ifdef DEBUG
    2873     fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
    2874     dumpMaps(m);
    2875 #endif
    2876     printProcessResponse(m,request_inputs1,cpid,
    2877                 //       s,r_inputs->value,res,
    2878                          s, s->name,res,  // replace serviceProvider with serviceName in stored response file name
    2879                          request_inputs,
    2880                          request_outputs);
    2881   }
    2882   else{
    2883     /**
    2884      * We get the requested output or fallback to the first one if the
    2885      * requested one is not present in the resulting outputs maps.
    2886      */
    2887     maps* tmpI=NULL;
    2888     map* tmpIV=getMap(request_inputs1,"RawDataOutput");
    2889     if(tmpIV!=NULL){
    2890       tmpI=getMaps(request_outputs,tmpIV->value);
    2891     }
    2892     if(tmpI==NULL)
    2893       tmpI=request_outputs;
    2894     elements* e=getElements(s->outputs,tmpI->name);
    2895     if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
    2896       printBoundingBoxDocument(m,tmpI,NULL);
    2897     }else{
    2898       map *gfile=getMap(tmpI->content,"generated_file");
    2899       if(gfile!=NULL){
    2900         gfile=getMap(tmpI->content,"expected_generated_file");
    2901         if(gfile==NULL){
    2902           gfile=getMap(tmpI->content,"generated_file");
    2903         }
    2904         readGeneratedFile(m,tmpI->content,gfile->value);
    2905       }
    2906       toto=getMap(tmpI->content,"value");
    2907       if(toto==NULL){
    2908         char tmpMsg[1024];
    2909         sprintf(tmpMsg,_("Wrong RawDataOutput parameter: unable to fetch any result for the given parameter name: \"%s\"."),tmpI->name);
    2910         errorException(m,tmpMsg,"InvalidParameterValue","RawDataOutput");
    2911         return;
    2912       }
    2913       map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
    2914       if(fname!=NULL)
    2915         printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
    2916       map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
    2917       if(rs!=NULL)
    2918         printf("Content-Length: %s\r\n",rs->value);
    2919       printHeaders(m);
    2920       char mime[1024];
    2921       map* mi=getMap(tmpI->content,"mimeType");
    2922 #ifdef DEBUG
    2923       fprintf(stderr,"SERVICE OUTPUTS\n");
    2924       dumpMaps(request_outputs);
    2925       fprintf(stderr,"SERVICE OUTPUTS\n");
    2926 #endif
    2927       map* en=getMap(tmpI->content,"encoding");
    2928       if(mi!=NULL && en!=NULL)
    2929         sprintf(mime,
    2930                 "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
    2931                 mi->value,en->value);
    2932       else
    2933         if(mi!=NULL)
    2934           sprintf(mime,
    2935                   "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
    2936                   mi->value);
    2937         else
    2938           sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
    2939       printf("%s",mime);
    2940       if(rs!=NULL)
    2941         fwrite(toto->value,1,atoi(rs->value),stdout);
    2942       else
    2943         fwrite(toto->value,1,strlen(toto->value),stdout);
    2944 #ifdef DEBUG
    2945       dumpMap(toto);
    2946 #endif
    2947     }
    2948   }
    2949 }
    2950 
    2951 /**
    2952  * Write a file from value and length
    2953  *
    2954  * @param fname the file name
    2955  * @param val the value
    2956  * @param length the value length
    2957  */
    2958 int writeFile(char* fname,char* val,int length){
    2959   FILE* of=fopen(fname,"wb");
    2960   if(of==NULL){
    2961     return -1;
    2962   }
    2963   size_t ret=fwrite(val,sizeof(char),length,of);
    2964   if(ret<length){
    2965     fprintf(stderr,"Write error occured!\n");
    2966     fclose(of);
    2967     return -1;
    2968   }
    2969   fclose(of);
    2970   return 1;
    2971 }
    2972 
    2973 /**
    2974  * Dump all values in a maps as files
    2975  *
    2976  * @param main_conf the maps containing the settings of the main.cfg file
    2977  * @param in the maps containing values to dump as files
    2978  */
    2979 void dumpMapsValuesToFiles(maps** main_conf,maps** in){
    2980   map* tmpPath=getMapFromMaps(*main_conf,"main","tmpPath");
    2981   map* tmpSid=getMapFromMaps(*main_conf,"lenv","sid");
    2982   maps* inputs=*in;
    2983   int length=0;
    2984   while(inputs!=NULL){
    2985     if(getMap(inputs->content,"mimeType")!=NULL &&
    2986        getMap(inputs->content,"cache_file")==NULL){
    2987       map* cMap=inputs->content;
    2988       if(getMap(cMap,"length")!=NULL){
    2989         map* tmpLength=getMap(cMap,"length");
    2990         int len=atoi(tmpLength->value);
    2991         int k=0;
    2992         for(k=0;k<len;k++){
    2993           map* cMimeType=getMapArray(cMap,"mimeType",k);
    2994           map* cValue=getMapArray(cMap,"value",k);
    2995           map* cSize=getMapArray(cMap,"size",k);
    2996           char file_ext[32];
    2997           getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
    2998           char* val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
    2999           sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,k,file_ext);
    3000           length=0;
    3001           if(cSize!=NULL){
    3002             length=atoi(cSize->value);
    3003           }
    3004           writeFile(val,cValue->value,length);
    3005           setMapArray(cMap,"cache_file",k,val);
    3006           free(val);
    3007         }
    3008       }else{
    3009         int length=0;
    3010         map* cMimeType=getMap(cMap,"mimeType");
    3011         map* cValue=getMap(cMap,"value");
    3012         map* cSize=getMap(cMap,"size");
    3013         char file_ext[32];
    3014         getFileExtension(cMimeType != NULL ? cMimeType->value : NULL, file_ext, 32);
    3015         char *val=(char*)malloc((strlen(tmpPath->value)+strlen(inputs->name)+strlen(tmpSid->value)+strlen(file_ext)+16)*sizeof(char));
    3016         sprintf(val,"%s/Input_%s_%s_%d.%s",tmpPath->value,inputs->name,tmpSid->value,0,file_ext);
    3017         if(cSize!=NULL){
    3018           length=atoi(cSize->value);
    3019         }
    3020         writeFile(val,cValue->value,length);
    3021         addToMap(cMap,"cache_file",val);
    3022         free(val);
    3023       }
    3024     }
    3025     inputs=inputs->next;
    3026   }
    3027 }
    3028 
    3029 /**
    3030  * Base64 encoding of a char*
    3031  *
    3032  * @param input the value to encode
    3033  * @param length the value length
    3034  * @return the buffer containing the base64 value
    3035  * @warning make sure to free the returned value
    3036  */
    3037 char *base64(const char *input, int length)
    3038 {
    3039   BIO *bmem, *b64;
    3040   BUF_MEM *bptr;
    3041 
    3042   b64 = BIO_new(BIO_f_base64());
    3043   BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    3044   bmem = BIO_new(BIO_s_mem());
    3045   b64 = BIO_push(b64, bmem);
    3046   BIO_write(b64, input, length);
    3047   BIO_flush(b64);
    3048   BIO_get_mem_ptr(b64, &bptr);
    3049 
    3050   char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
    3051   memcpy(buff, bptr->data, bptr->length);
    3052   buff[bptr->length] = 0;
    3053 
    3054   BIO_free_all(b64);
    3055 
    3056   return buff;
    3057 }
    3058 
    3059 /**
    3060  * Base64 decoding of a char*
    3061  *
    3062  * @param input the value to decode
    3063  * @param length the value length
    3064  * @param red the value length
    3065  * @return the buffer containing the base64 value
    3066  * @warning make sure to free the returned value
    3067  */
    3068 char *base64d(const char *input, int length,int* red)
    3069 {
    3070   BIO *b64, *bmem;
    3071 
    3072   char *buffer = (char *)malloc(length);
    3073   if(buffer){
    3074     memset(buffer, 0, length);
    3075     b64 = BIO_new(BIO_f_base64());
    3076     if(b64){
    3077       bmem = BIO_new_mem_buf((unsigned char*)input,length);
    3078       bmem = BIO_push(b64, bmem);
    3079       *red=BIO_read(bmem, buffer, length);
    3080       buffer[length-1]=0;
    3081       BIO_free_all(bmem);
    3082     }
    3083   }
    3084   return buffer;
    3085 }
    3086 
    3087 /**
    3088  * Read Base64 value and split it value by lines of 64 char.
    3089  *
    3090  * @param in the map containing the value to split
    3091  */
    3092 void readBase64(map **in){
    3093   char *res = NULL;
    3094   char *curs = (*in)->value;
    3095   int i = 0;
    3096   for (i = 0; i <= strlen ((*in)->value) / 64;
    3097        i++)
    3098     {
    3099       if (res == NULL)
    3100         res =
    3101           (char *) malloc (65 * sizeof (char));
    3102       else
    3103         res =
    3104           (char *) realloc (res,
    3105                             (((i + 1) * 65) +
    3106                              i) * sizeof (char));
    3107       int csize = i * 65;
    3108       strncpy (res + csize, curs, 64);
    3109       if (i == strlen ((*in)->value) / 64)
    3110         strcat (res, "\n\0");
    3111       else
    3112         {
    3113           strncpy (res + (((i + 1) * 64) + i),
    3114                    "\n\0", 2);
    3115           curs += 64;
    3116         }
    3117     }
    3118   free ((*in)->value);
    3119   (*in)->value = zStrdup (res);
    3120   free (res);
    3121 }
    3122 
    3123 /**
    3124  * Make sure that each value encoded in base64 in a maps is decoded.
    3125  *
    3126  * @param in the maps containing the values
    3127  * @see readBase64
    3128  */
    3129 void ensureDecodedBase64(maps **in){
    3130   maps* cursor=*in;
    3131   while(cursor!=NULL){
    3132     map *tmp=getMap(cursor->content,"encoding");
    3133     if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
    3134       tmp=getMap(cursor->content,"value");
    3135       readBase64(&tmp);
    3136       addToMap(cursor->content,"base64_value",tmp->value);
    3137       int size=0;
    3138       char *s=strdup(tmp->value);
    3139       free(tmp->value);
    3140       tmp->value=base64d(s,strlen(s),&size);
    3141       free(s);
    3142       char sizes[1024];
    3143       sprintf(sizes,"%d",size);
    3144       addToMap(cursor->content,"size",sizes);
    3145     }
    3146     map* length=getMap(cursor->content,"length");
    3147     if(length!=NULL){
    3148       int len=atoi(length->value);
    3149       for(int i=1;i<len;i++){
    3150         tmp=getMapArray(cursor->content,"encoding",i);
    3151         if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
    3152           char key[17];
    3153           sprintf(key,"base64_value_%d",i);
    3154           tmp=getMapArray(cursor->content,"value",i);
    3155           readBase64(&tmp);
    3156           addToMap(cursor->content,key,tmp->value);
    3157           int size=0;
    3158           char *s=strdup(tmp->value);
    3159           free(tmp->value);
    3160           tmp->value=base64d(s,strlen(s),&size);
    3161           free(s);
    3162           char sizes[1024];
    3163           sprintf(sizes,"%d",size);
    3164           sprintf(key,"size_%d",i);
    3165           addToMap(cursor->content,key,sizes);
    3166         }
    3167       }
    3168     }
    3169     cursor=cursor->next;
    3170   }
    3171 }
    3172 
    3173 /**
    3174  * Add the default values defined in the zcfg to a maps.
    3175  *
    3176  * @param out the maps containing the inputs or outputs given in the initial
    3177  *  HTTP request
    3178  * @param in the description of all inputs or outputs available for a service
    3179  * @param m the maps containing the settings of the main.cfg file
    3180  * @param type 0 for inputs and 1 for outputs
    3181  * @param err the map to store potential missing mandatory input parameters or
    3182  *  wrong output names depending on the type.
    3183  * @return "" if no error was detected, the name of last input or output causing
    3184  *  an error.
    3185  */
    3186 char* addDefaultValues(maps** out,elements* in,maps* m,int type,map** err){
    3187   map *res=*err;
    3188   elements* tmpInputs=in;
    3189   maps* out1=*out;
    3190   char *result=NULL;
    3191   int nb=0;
    3192   if(type==1){
    3193     while(out1!=NULL){
    3194       if(getElements(in,out1->name)==NULL){
    3195         if(res==NULL){
    3196           res=createMap("value",out1->name);
    3197         }else{
    3198           setMapArray(res,"value",nb,out1->name);
    3199         }
    3200         nb++;
    3201         result=out1->name;
    3202       }
    3203       out1=out1->next;
    3204     }
    3205     if(res!=NULL){
    3206       *err=res;
    3207       return result;
    3208     }
    3209     out1=*out;
    3210   }
    3211   while(tmpInputs!=NULL){
    3212     maps *tmpMaps=getMaps(out1,tmpInputs->name);
    3213     if(tmpMaps==NULL){
    3214       maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
    3215       tmpMaps2->name=strdup(tmpInputs->name);
    3216       tmpMaps2->content=NULL;
    3217       tmpMaps2->next=NULL;
    3218      
    3219       if(type==0){
    3220         map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
    3221         if(tmpMapMinO!=NULL){
    3222           if(atoi(tmpMapMinO->value)>=1){
    3223             freeMaps(&tmpMaps2);
    3224             free(tmpMaps2);
    3225             if(res==NULL){
    3226               res=createMap("value",tmpInputs->name);
    3227             }else{
    3228               setMapArray(res,"value",nb,tmpInputs->name);
    3229             }
    3230             nb++;
    3231             result=tmpInputs->name;
    3232           }
    3233           else{
    3234             if(tmpMaps2->content==NULL)
    3235               tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
    3236             else
    3237               addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
    3238           }
    3239         }
    3240         if(res==NULL){
    3241           map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
    3242           if(tmpMaxO!=NULL){
    3243             if(tmpMaps2->content==NULL)
    3244               tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
    3245             else
    3246               addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
    3247           }
    3248           map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
    3249           if(tmpMaxMB!=NULL){
    3250             if(tmpMaps2->content==NULL)
    3251               tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
    3252             else
    3253               addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
    3254           }
    3255         }
    3256       }
    3257 
    3258       if(res==NULL){
    3259         iotype* tmpIoType=tmpInputs->defaults;
    3260         if(tmpIoType!=NULL){
    3261           map* tmpm=tmpIoType->content;
    3262           while(tmpm!=NULL){
    3263             if(tmpMaps2->content==NULL)
    3264               tmpMaps2->content=createMap(tmpm->name,tmpm->value);
    3265             else
    3266               addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
    3267             tmpm=tmpm->next;
    3268           }
    3269         }
    3270         addToMap(tmpMaps2->content,"inRequest","false");
    3271         if(type==0){
    3272           map *tmpMap=getMap(tmpMaps2->content,"value");
    3273           if(tmpMap==NULL)
    3274             addToMap(tmpMaps2->content,"value","NULL");
    3275         }
    3276         if(out1==NULL){
    3277           *out=dupMaps(&tmpMaps2);
    3278           out1=*out;
    3279         }
    3280         else
    3281           addMapsToMaps(&out1,tmpMaps2);
    3282         freeMap(&tmpMaps2->content);
    3283         free(tmpMaps2->content);
    3284         tmpMaps2->content=NULL;
    3285         freeMaps(&tmpMaps2);
    3286         free(tmpMaps2);
    3287         tmpMaps2=NULL;
    3288       }
    3289     }
    3290     else{
    3291       iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
    3292                                              tmpMaps->content);
    3293       if(type==0) {
    3294         /**
    3295          * In case of an Input maps, then add the minOccurs and maxOccurs to the
    3296          * content map.
    3297          */
    3298         map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
    3299         if(tmpMap1!=NULL){
    3300           if(tmpMaps->content==NULL)
    3301             tmpMaps->content=createMap("minOccurs",tmpMap1->value);
    3302           else
    3303             addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
    3304         }
    3305         map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
    3306         if(tmpMaxO!=NULL){
    3307           if(tmpMaps->content==NULL)
    3308             tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
    3309           else
    3310             addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
    3311         }
    3312         map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
    3313         if(tmpMaxMB!=NULL){
    3314           if(tmpMaps->content==NULL)
    3315             tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
    3316           else
    3317             addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
    3318         }
    3319         /**
    3320          * Parsing BoundingBoxData, fill the following map and then add it to
    3321          * the content map of the Input maps:
    3322          * lowerCorner, upperCorner, srs and dimensions
    3323          * cf. parseBoundingBox
    3324          */
    3325         if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
    3326           maps* tmpI=getMaps(*out,tmpInputs->name);
    3327           if(tmpI!=NULL){
    3328             map* tmpV=getMap(tmpI->content,"value");
    3329             if(tmpV!=NULL){
    3330               char *tmpVS=strdup(tmpV->value);
    3331               map* tmp=parseBoundingBox(tmpVS);
    3332               free(tmpVS);
    3333               map* tmpC=tmp;
    3334               while(tmpC!=NULL){
    3335                 addToMap(tmpMaps->content,tmpC->name,tmpC->value);
    3336                 tmpC=tmpC->next;
    3337               }
    3338               freeMap(&tmp);
    3339               free(tmp);
    3340             }
    3341           }
    3342         }
    3343       }
    3344 
    3345       if(tmpIoType!=NULL){
    3346         map* tmpContent=tmpIoType->content;
    3347         map* cval=NULL;
    3348         int hasPassed=-1;
    3349         while(tmpContent!=NULL){
    3350           if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
    3351 #ifdef DEBUG
    3352             fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
    3353 #endif
    3354             if(tmpMaps->content==NULL)
    3355               tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
    3356             else
    3357               addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
    3358            
    3359             if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
    3360               map* length=getMap(tmpMaps->content,"length");
    3361               int i;
    3362               char *tcn=strdup(tmpContent->name);
    3363               for(i=1;i<atoi(length->value);i++){
    3364 #ifdef DEBUG
    3365                 dumpMap(tmpMaps->content);
    3366                 fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
    3367 #endif
    3368                 int len=strlen((char*) tcn);
    3369                 char *tmp1=(char *)malloc((len+10)*sizeof(char));
    3370                 sprintf(tmp1,"%s_%d",tcn,i);
    3371 #ifdef DEBUG
    3372                 fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
    3373 #endif
    3374                 addToMap(tmpMaps->content,tmp1,tmpContent->value);
    3375                 free(tmp1);
    3376                 hasPassed=1;
    3377               }
    3378               free(tcn);
    3379             }
    3380           }
    3381           tmpContent=tmpContent->next;
    3382         }
    3383 #ifdef USE_MS
    3384         /**
    3385          * check for useMapServer presence
    3386          */
    3387         map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
    3388         if(tmpCheck!=NULL){
    3389           // Get the default value
    3390           tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
    3391           tmpCheck=getMap(tmpMaps->content,"mimeType");
    3392           addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
    3393           map* cursor=tmpIoType->content;
    3394           while(cursor!=NULL){
    3395             addToMap(tmpMaps->content,cursor->name,cursor->value);
    3396             cursor=cursor->next;
    3397           }
    3398          
    3399           cursor=tmpInputs->content;
    3400           while(cursor!=NULL){
    3401             if(strcasecmp(cursor->name,"Title")==0 ||
    3402                strcasecmp(cursor->name,"Abstract")==0)
    3403               addToMap(tmpMaps->content,cursor->name,cursor->value);
    3404            cursor=cursor->next;
    3405           }
    3406         }
    3407 #endif
    3408       }
    3409       if(tmpMaps->content==NULL)
    3410         tmpMaps->content=createMap("inRequest","true");
    3411       else
    3412         addToMap(tmpMaps->content,"inRequest","true");
    3413 
    3414     }
    3415     tmpInputs=tmpInputs->next;
    3416   }
    3417   if(res!=NULL){
    3418     *err=res;
    3419     return result;
    3420   }
    3421   return "";
    3422 }
    3423 
    3424 /**
    3425  * Parse a BoundingBox string
    3426  *
    3427  * [OGC 06-121r3](http://portal.opengeospatial.org/files/?artifact_id=20040):
    3428  *  10.2 Bounding box
    3429  *
    3430  *
    3431  * Value is provided as : lowerCorner,upperCorner,crs,dimension
    3432  * Exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
    3433  *
    3434  * A map to store boundingbox informations should contain:
    3435  *  - lowerCorner : double,double (minimum within this bounding box)
    3436  *  - upperCorner : double,double (maximum within this bounding box)
    3437  *  - crs : URI (Reference to definition of the CRS)
    3438  *  - dimensions : int
    3439  *
    3440  * Note : support only 2D bounding box.
    3441  *
    3442  * @param value the char* containing the KVP bouding box
    3443  * @return a map containing all the bounding box keys
    3444  */
    3445 map* parseBoundingBox(const char* value){
    3446   map *res=NULL;
    3447   if(value!=NULL){
    3448     char *cv,*cvp;
    3449     cv=strtok_r((char*) value,",",&cvp);
    3450     int cnt=0;
    3451     int icnt=0;
    3452     char *currentValue=NULL;
    3453     while(cv){
    3454       if(cnt<2)
    3455         if(currentValue!=NULL){
    3456           char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
    3457           sprintf(finalValue,"%s%s",currentValue,cv);
    3458           switch(cnt){
    3459           case 0:
    3460             res=createMap("lowerCorner",finalValue);
    3461             break;
    3462           case 1:
    3463             addToMap(res,"upperCorner",finalValue);
    3464             icnt=-1;
    3465             break;
    3466           }
    3467           cnt++;
    3468           free(currentValue);
    3469           currentValue=NULL;
    3470           free(finalValue);
    3471         }
    3472         else{
    3473           currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
    3474           sprintf(currentValue,"%s ",cv);
    3475         }
    3476       else
    3477         if(cnt==2){
    3478           addToMap(res,"crs",cv);
    3479           cnt++;
    3480         }
    3481         else
    3482           addToMap(res,"dimensions",cv);
    3483       icnt++;
    3484       cv=strtok_r(NULL,",",&cvp);
    3485     }
    3486   }
    3487   return res;
    3488 }
    3489 
    3490 /**
    3491  * Create required XML nodes for boundingbox and update the current XML node
    3492  *
    3493  * @param ns_ows the ows XML namespace
    3494  * @param n the XML node to update
    3495  * @param boundingbox the map containing the boundingbox definition
    3496  */
    3497 void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
    3498 
    3499   xmlNodePtr lw=NULL,uc=NULL;
    3500 
    3501   map* tmp=getMap(boundingbox,"value");
    3502 
    3503   tmp=getMap(boundingbox,"lowerCorner");
    3504   if(tmp!=NULL){
    3505     lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
    3506     xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
    3507   }
    3508 
    3509   tmp=getMap(boundingbox,"upperCorner");
    3510   if(tmp!=NULL){
    3511     uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
    3512     xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
    3513   }
    3514 
    3515   tmp=getMap(boundingbox,"crs");
    3516   if(tmp!=NULL)
    3517     xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
    3518 
    3519   tmp=getMap(boundingbox,"dimensions");
    3520   if(tmp!=NULL)
    3521     xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
    3522 
    3523   xmlAddChild(n,lw);
    3524   xmlAddChild(n,uc);
    3525 
    3526 }
    3527 
    3528 /**
    3529  * Print an ows:BoundingBox XML document
    3530  *
    3531  * @param m the maps containing the settings of the main.cfg file
    3532  * @param boundingbox the maps containing the boundingbox definition
    3533  * @param file the file to print the BoundingBox (if NULL then print on stdout)
    3534  * @see parseBoundingBox, printBoundingBox
    3535  */
    3536 void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
    3537   if(file==NULL)
    3538     rewind(stdout);
    3539   xmlNodePtr n;
    3540   xmlDocPtr doc;
    3541   xmlNsPtr ns_ows,ns_xsi;
    3542   xmlChar *xmlbuff;
    3543   int buffersize;
    3544   char *encoding=getEncoding(m);
    3545   map *tmp;
    3546   if(file==NULL){
    3547     int pid=0;
    3548     tmp=getMapFromMaps(m,"lenv","sid");
    3549     if(tmp!=NULL)
    3550       pid=atoi(tmp->value);
    3551     if(pid==getpid()){
    3552       printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
    3553     }
    3554     fflush(stdout);
    3555   }
    3556 
    3557   doc = xmlNewDoc(BAD_CAST "1.0");
    3558   int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
    3559   ns_ows=usedNs[owsId];
    3560   n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
    3561   xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
    3562   int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
    3563   ns_xsi=usedNs[xsiId];
    3564   xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
    3565   map *tmp1=getMap(boundingbox->content,"value");
    3566   tmp=parseBoundingBox(tmp1->value);
    3567   printBoundingBox(ns_ows,n,tmp);
    3568   xmlDocSetRootElement(doc, n);
    3569 
    3570   xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
    3571   if(file==NULL)
    3572     printf("%s",xmlbuff);
    3573   else{
    3574     fprintf(file,"%s",xmlbuff);
    3575   }
    3576 
    3577   if(tmp!=NULL){
    3578     freeMap(&tmp);
    3579     free(tmp);
    3580   }
    3581   xmlFree(xmlbuff);
    3582   xmlFreeDoc(doc);
    3583   xmlCleanupParser();
    3584   zooXmlCleanupNs();
    3585  
    3586 }
    3587 
    3588 /**
    3589  * Compute md5
    3590  *
    3591  * @param url the char*
    3592  * @return a char* representing the md5 of the url
    3593  * @warning make sure to free ressources returned by this function
    3594  */
    3595 char* getMd5(char* url){
    3596   EVP_MD_CTX md5ctx;
    3597   char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
    3598   unsigned char result[EVP_MAX_MD_SIZE];
    3599   unsigned int len;
    3600   EVP_DigestInit(&md5ctx, EVP_md5());
    3601   EVP_DigestUpdate(&md5ctx, url, strlen(url));
    3602   EVP_DigestFinal_ex(&md5ctx,result,&len);
    3603   EVP_MD_CTX_cleanup(&md5ctx);
    3604   int i;
    3605   for(i = 0; i < len; i++){
    3606     if(i>0){
    3607       char *tmp=strdup(fresult);
    3608       sprintf(fresult,"%s%02x", tmp,result[i]);
    3609       free(tmp);
    3610     }
    3611     else
    3612       sprintf(fresult,"%02x",result[i]);
    3613   }
    3614   return fresult;
    3615 }
    3616 
    3617 /**
    3618  * Cache a file for a given request.
    3619  * For each cached file, the are two files stored, a .zca and a .zcm containing
    3620  * the downloaded content and the mimeType respectively.
    3621  *
    3622  * @param conf the maps containing the settings of the main.cfg file
    3623  * @param request the url used too fetch the content
    3624  * @param content the downloaded content
    3625  * @param mimeType the content mimeType
    3626  * @param length the content size
    3627  * @param filepath a buffer for storing the path of the cached file; may be NULL
    3628  * @param max_path the size of the allocated filepath buffer 
    3629  */
    3630 void addToCache(maps* conf,char* request,char* content,char* mimeType,int length,
    3631                 char* filepath, size_t max_path){
    3632   map* tmp=getMapFromMaps(conf,"main","cacheDir");
    3633   if(tmp!=NULL){
    3634     char* md5str=getMd5(request);
    3635     char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
    3636     sprintf(fname,"%s/%s.zca",tmp->value,md5str);
    3637 #ifdef DEBUG
    3638     fprintf(stderr,"Cache list : %s\n",fname);
    3639     fflush(stderr);
    3640 #endif
    3641     FILE* fo=fopen(fname,"w+");
    3642     if(fo==NULL){
    3643 #ifdef DEBUG
    3644       fprintf (stderr, "Failed to open %s for writing: %s\n",fname, strerror(errno));
    3645 #endif
    3646       filepath = NULL; 
    3647       return;
    3648     }
    3649     fwrite(content,sizeof(char),length,fo);
    3650     fclose(fo);
    3651        
    3652         if (filepath != NULL) {
    3653                 strncpy(filepath, fname, max_path);
    3654         }       
    3655 
    3656     sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
    3657     fo=fopen(fname,"w+");
    3658 #ifdef DEBUG
    3659     fprintf(stderr,"MIMETYPE: %s\n",mimeType);
    3660 #endif
    3661     fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
    3662     fclose(fo);
    3663 
    3664     free(md5str);
    3665     free(fname);
    3666   }
    3667   else {
    3668           filepath = NULL;
    3669   }       
    3670 }
    3671 
    3672 /**
    3673  * Verify if a url is available in the cache
    3674  *
    3675  * @param conf the maps containing the settings of the main.cfg file
    3676  * @param request the url
    3677  * @return the full name of the cached file if any, NULL in other case
    3678  * @warning make sure to free ressources returned by this function (if not NULL)
    3679  */
    3680 char* isInCache(maps* conf,char* request){
    3681   map* tmpM=getMapFromMaps(conf,"main","cacheDir");
    3682   if(tmpM!=NULL){
    3683     char* md5str=getMd5(request);
    3684 #ifdef DEBUG
    3685     fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
    3686 #endif
    3687     char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
    3688     sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
    3689     struct stat f_status;
    3690     int s=stat(fname, &f_status);
    3691     if(s==0 && f_status.st_size>0){
    3692       free(md5str);
    3693       return fname;
    3694     }
    3695     free(md5str);
    3696     free(fname);
    3697   }
    3698   return NULL;
    3699 }
    3700 
    3701 /**
    3702  * Effectively run all the HTTP requests in the queue
    3703  *
    3704  * @param m the maps containing the settings of the main.cfg file
    3705  * @param inputs the maps containing the inputs (defined in the requests+added
    3706  *  per default based on the zcfg file)
    3707  * @param hInternet the HINTERNET pointer
    3708  * @return 0 on success
    3709  */
    3710 int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet){
    3711   if(hInternet->nb>0){
    3712     processDownloads(hInternet);
    3713     maps* content=*inputs;
    3714     map* tmp1;
    3715     int index=0;
    3716     char sindex[5];
    3717     while(content!=NULL){
    3718      
    3719       map* length=getMap(content->content,"length");
    3720       int shouldClean=-1;
    3721       if(length==NULL){
    3722         length=createMap("length","1");
    3723         shouldClean=1;
    3724       }
    3725       for(int i=0;i<atoi(length->value);i++){
    3726         char* fcontent;
    3727         char *mimeType=NULL;
    3728         int fsize=0;
    3729         char cname[15];
    3730         char vname[11];
    3731         char vname1[11];
    3732         char sname[9];
    3733         char mname[15];
    3734         char icname[14];
    3735         char xname[16];
    3736         char oname[12];
    3737         if(index>0)
    3738           sprintf(vname1,"value_%d",index);
    3739         else
    3740           sprintf(vname1,"value");
    3741 
    3742         if(i>0){
    3743           tmp1=getMap(content->content,cname);
    3744           sprintf(cname,"cache_file_%d",i);
    3745           sprintf(vname,"value_%d",i);
    3746           sprintf(sname,"size_%d",i);
    3747           sprintf(mname,"mimeType_%d",i);
    3748           sprintf(icname,"isCached_%d",i);
    3749           sprintf(xname,"Reference_%d",i);
    3750           sprintf(oname,"Order_%d",i);
    3751         }else{
    3752           sprintf(cname,"cache_file");
    3753           sprintf(vname,"value");
    3754           sprintf(sname,"size");
    3755           sprintf(mname,"mimeType");
    3756           sprintf(icname,"isCached");
    3757           sprintf(xname,"Reference");
    3758           sprintf(oname,"Order");
    3759         }
    3760 
    3761         map* tmap=getMap(content->content,oname);
    3762         sprintf(sindex,"%d",index+1);
    3763         if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){
    3764 
    3765           if(getMap(content->content,icname)==NULL){
    3766            
    3767             fcontent=(char*)malloc((hInternet->ihandle[index].nDataLen+1)*sizeof(char));
    3768             if(fcontent == NULL){
    3769               return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
    3770             }
    3771             size_t dwRead;
    3772             InternetReadFile(hInternet->ihandle[index],
    3773                              (LPVOID)fcontent,
    3774                              hInternet->ihandle[index].nDataLen,
    3775                              &dwRead);
    3776             fcontent[hInternet->ihandle[index].nDataLen]=0;
    3777             fsize=hInternet->ihandle[index].nDataLen;
    3778             if(hInternet->ihandle[index].mimeType==NULL)
    3779               mimeType=strdup("none");
    3780             else
    3781               mimeType=strdup(hInternet->ihandle[index].mimeType);           
    3782            
    3783             map* tmpMap=getMapOrFill(&content->content,vname,"");
    3784             free(tmpMap->value);
    3785             tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
    3786             if(tmpMap->value==NULL){
    3787               return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
    3788             }
    3789             memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
    3790            
    3791             char ltmp1[256];
    3792             sprintf(ltmp1,"%d",fsize);
    3793             map* tmp=getMapFromMaps(*m,"main","cacheDir");
    3794             if(tmp!=NULL){
    3795               char* md5str=getMd5(tmp1->value);
    3796               char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
    3797               sprintf(fname,"%s/%s.zca",tmp->value,md5str);
    3798               addToMap(content->content,cname,fname);
    3799               free(fname);
    3800             }
    3801             addToMap(content->content,sname,ltmp1);
    3802             addToMap(content->content,mname,mimeType);
    3803             addToCache(*m,tmp1->value,fcontent,mimeType,fsize, NULL, 0);
    3804             free(fcontent);
    3805             free(mimeType);
    3806             index++;
    3807 
    3808           }
    3809         }
    3810       }
    3811       if(shouldClean>0){
    3812         freeMap(&length);
    3813         free(length);
    3814       }
    3815      
    3816       content=content->next;
    3817     }
    3818    
    3819   }
    3820   return 0;
    3821 }
    3822 
    3823 /**
    3824  * Add a request in the download queue
    3825  *
    3826  * @param m the maps containing the settings of the main.cfg file
    3827  * @param url the url to add to the queue
    3828  */
    3829 void addRequestToQueue(maps** m,HINTERNET* hInternet,const char* url,bool req){
    3830   hInternet->waitingRequests[hInternet->nb]=strdup(url);
    3831   hInternet->ihandle[hInternet->nb].header=NULL;
    3832   if(req)
    3833     InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
    3834   maps *oreq=getMaps(*m,"orequests");
    3835   if(oreq==NULL){
    3836     oreq=(maps*)malloc(MAPS_SIZE);
    3837     oreq->name=zStrdup("orequests");
    3838     oreq->content=createMap("value",url);
    3839     oreq->next=NULL;
    3840     addMapsToMaps(m,oreq);
    3841     freeMaps(&oreq);
    3842     free(oreq);
    3843   }else{
    3844     setMapArray(oreq->content,"value",hInternet->nb-1,url);
    3845   }
    3846 }
    3847 
    3848 /**
    3849  * Try to load file from cache or download a remote file if not in cache
    3850  *
    3851  * @param m the maps containing the settings of the main.cfg file
    3852  * @param content the map to update
    3853  * @param hInternet the HINTERNET pointer
    3854  * @param url the url to fetch
    3855  * @return 0
    3856  */
    3857 int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){
    3858   char* fcontent;
    3859   char* cached=isInCache(*m,url);
    3860   char *mimeType=NULL;
    3861   int fsize=0;
    3862 
    3863   map* t=getMap(*content,"xlink:href");
    3864   if(t==NULL){
    3865     t=getMap((*content),"href");
    3866     addToMap(*content,"xlink:href",url);
    3867   }
    3868 
    3869   if(cached!=NULL){
    3870 
    3871     struct stat f_status;
    3872     int s=stat(cached, &f_status);
    3873     if(s==0){
    3874       fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
    3875       FILE* f=fopen(cached,"rb");
    3876       fread(fcontent,f_status.st_size,1,f);
    3877       fsize=f_status.st_size;
    3878       fcontent[fsize]=0;
    3879       fclose(f);
    3880       addToMap(*content,"cache_file",cached);
    3881     }
    3882     cached[strlen(cached)-1]='m';
    3883     s=stat(cached, &f_status);
    3884     if(s==0){
    3885       mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
    3886       FILE* f=fopen(cached,"rb");
    3887       fread(mimeType,f_status.st_size,1,f);
    3888       mimeType[f_status.st_size]=0;
    3889       fclose(f);
    3890     }
    3891 
    3892   }else{   
    3893     addRequestToQueue(m,hInternet,url,true);
    3894     return 0;
    3895   }
    3896   if(fsize==0){
    3897     return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
    3898   }
    3899   if(mimeType!=NULL){
    3900     addToMap(*content,"fmimeType",mimeType);
    3901   }
    3902 
    3903   map* tmpMap=getMapOrFill(content,"value","");
    3904    
    3905   free(tmpMap->value);
    3906 
    3907   tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
    3908   if(tmpMap->value==NULL)
    3909     return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
    3910   memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
    3911 
    3912   char ltmp1[256];
    3913   sprintf(ltmp1,"%d",fsize);
    3914   addToMap(*content,"size",ltmp1);
    3915   if(cached==NULL){
    3916     addToCache(*m,url,fcontent,mimeType,fsize, NULL, 0);
    3917   }
    3918   else{
    3919     addToMap(*content,"isCached","true");
    3920     map* tmp=getMapFromMaps(*m,"main","cacheDir");
    3921     if(tmp!=NULL){
    3922       map *c=getMap((*content),"xlink:href");
    3923       char* md5str=getMd5(c->value);
    3924       char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
    3925       sprintf(fname,"%s/%s.zca",tmp->value,md5str);
    3926       addToMap(*content,"cache_file",fname);
    3927       free(fname);
    3928     }
    3929   }
    3930   free(fcontent);
    3931   free(mimeType);
    3932   free(cached);
    3933   return 0;
    3934 }
    3935 
    3936 /**
    3937  * Read a file using the GDAL VSI API
    3938  *
    3939  * @param conf the maps containing the settings of the main.cfg file
    3940  * @param dataSource the datasource name to read
    3941  * @warning make sure to free ressources returned by this function
    3942  */
    3943 char *readVSIFile(maps* conf,const char* dataSource){
    3944     VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
    3945     VSIStatBufL file_status;
    3946     VSIStatL(dataSource, &file_status);
    3947     if(fichier==NULL){
    3948       char tmp[1024];
    3949       sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %lld.",
    3950               dataSource,file_status.st_size);
    3951       setMapInMaps(conf,"lenv","message",tmp);
    3952       return NULL;
    3953     }
    3954     char *res1=(char *)malloc(file_status.st_size*sizeof(char));
    3955     VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
    3956     res1[file_status.st_size-1]=0;
    3957     VSIFCloseL(fichier);
    3958     VSIUnlink(dataSource);
    3959     return res1;
    3960 }
    3961 
    3962 /**
    3963  * Extract the service identifier from the full service identifier
    3964  * ie:
    3965  *  - Full service name: OTB.BandMath
    3966  *  - Service name: BandMath
    3967  *
    3968  * @param conf the maps containing the settings of the main.cfg file
    3969  * @param conf_dir the full path to the ZOO-Kernel directory
    3970  * @param identifier the full service name (potentialy including a prefix, ie:
    3971  *  Prefix.MyService)
    3972  * @param buffer the resulting service identifier (without any prefix)
    3973  */
    3974 void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
    3975   setMapInMaps(conf,"lenv","oIdentifier",identifier);
    3976   char *lid=zStrdup(identifier);
    3977   char *saveptr1;
    3978   char *tmps1=strtok_r(lid,".",&saveptr1);
    3979   int level=0;
    3980   char key[25];
    3981   char levels[18];
    3982   while(tmps1!=NULL){
    3983     char *test=zStrdup(tmps1);
    3984     char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
    3985     sprintf(key,"sprefix_%d",level);
    3986     sprintf(tmps2,"%s.",test);
    3987     sprintf(levels,"%d",level);
    3988     setMapInMaps(conf,"lenv","level",levels);
    3989     setMapInMaps(conf,"lenv",key,tmps2);
    3990     free(tmps2);
    3991     free(test);
    3992     level++;
    3993     tmps1=strtok_r(NULL,".",&saveptr1);
    3994   }
    3995   int i=0;
    3996   sprintf(buffer,"%s",conf_dir);
    3997   for(i=0;i<level;i++){
    3998     char *tmp0=zStrdup(buffer);
    3999     sprintf(key,"sprefix_%d",i);
    4000     map* tmp00=getMapFromMaps(conf,"lenv",key);
    4001     if(tmp00!=NULL)
    4002       sprintf(buffer,"%s/%s",tmp0,tmp00->value);
    4003     free(tmp0);
    4004     buffer[strlen(buffer)-1]=0;
    4005     if(i+1<level){
    4006       #ifdef IGNORE_METAPATH
    4007         map* tmpMap = createMap("metapath", "");
    4008       #else 
    4009         map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
    4010       #endif     
    4011       if(tmpMap==NULL || strlen(tmpMap->value)==0){
    4012         char *tmp01=zStrdup(tmp00->value);
    4013         tmp01[strlen(tmp01)-1]=0;
    4014         setMapInMaps(conf,"lenv","metapath",tmp01);
    4015         free(tmp01);
    4016         tmp01=NULL;
    4017       }
    4018       else{
    4019         if(tmp00!=NULL && tmpMap!=NULL){
    4020           char *tmp00s=zStrdup(tmp00->value);
    4021           tmp00s[strlen(tmp00s)-1]=0;
    4022           char *value=(char*)malloc((strlen(tmp00s)+strlen(tmpMap->value)+2)*sizeof(char));
    4023           sprintf(value,"%s/%s",tmpMap->value,tmp00s);
    4024           setMapInMaps(conf,"lenv","metapath",value);
    4025           free(value);
    4026           free(tmp00s);
    4027           value=NULL;
    4028         }
    4029       }
    4030     }else{
    4031       char *tmp01=zStrdup(tmp00->value);
    4032       tmp01[strlen(tmp01)-1]=0;
    4033       setMapInMaps(conf,"lenv","Identifier",tmp01);
    4034       free(tmp01);
    4035     }
    4036   }
    4037   char *tmp0=zStrdup(buffer);
    4038   sprintf(buffer,"%s.zcfg",tmp0);
    4039   free(tmp0);
    4040   free(lid);
    4041 }
    4042 
    4043566/**
    4044567 * Update the status of an ongoing service
     
    4111634}
    4112635
    4113 /**
    4114  * Verify if a parameter value is valid.
    4115  *
    4116  * @param request the request map
    4117  * @param res the error map potentially generated
    4118  * @param toCheck the parameter to use
    4119  * @param avalues the acceptable values (or null if testing only for presence)
    4120  * @param mandatory verify the presence of the parameter if mandatory > 0
    4121  */
    4122 void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
    4123   map* lres=*res;
    4124   map* r_inputs = getMap (request,toCheck);
    4125   if (r_inputs == NULL){
    4126     if(mandatory>0){
    4127       char *replace=_("Mandatory parameter <%s> was not specified");
    4128       char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
    4129       sprintf(message,replace,toCheck);
    4130       if(lres==NULL){
    4131         lres=createMap("code","MissingParameterValue");
    4132         addToMap(lres,"text",message);
    4133         addToMap(lres,"locator",toCheck);       
    4134       }else{
    4135         int length=1;
    4136         map* len=getMap(lres,"length");
    4137         if(len!=NULL){
    4138           length=atoi(len->value);
    4139         }
    4140         setMapArray(lres,"text",length,message);
    4141         setMapArray(lres,"locator",length,toCheck);
    4142         setMapArray(lres,"code",length,"MissingParameter");
    4143       }
    4144       free(message);
    4145     }
    4146   }else{
    4147     if(avalues==NULL)
    4148       return;
    4149     int nb=0;
    4150     int hasValidValue=-1;
    4151     while(avalues[nb]!=NULL){
    4152       if(strcasecmp(avalues[nb],r_inputs->value)==0){
    4153         hasValidValue=1;
    4154         break;
    4155       }
    4156       nb++;
    4157     }
    4158     if(hasValidValue<0){
    4159       char *replace=_("The value <%s> was not recognized, %s %s the only acceptable value.");
    4160       nb=0;
    4161       char *vvalues=NULL;
    4162       char* num=_("is");
    4163       while(avalues[nb]!=NULL){
    4164         char *tvalues;
    4165         if(vvalues==NULL){
    4166           vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
    4167           sprintf(vvalues,"%s",avalues[nb]);
    4168         }
    4169         else{
    4170           tvalues=zStrdup(vvalues);
    4171           vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
    4172           sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
    4173           free(tvalues);
    4174           num=_("are");
    4175         }
    4176         nb++;
    4177       }
    4178       char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
    4179       sprintf(message,replace,toCheck,vvalues,num);
    4180       if(lres==NULL){
    4181         lres=createMap("code","InvalidParameterValue");
    4182         addToMap(lres,"text",message);
    4183         addToMap(lres,"locator",toCheck);       
    4184       }else{
    4185         int length=1;
    4186         map* len=getMap(lres,"length");
    4187         if(len!=NULL){
    4188           length=atoi(len->value);
    4189         }
    4190         setMapArray(lres,"text",length,message);
    4191         setMapArray(lres,"locator",length,toCheck);
    4192         setMapArray(lres,"code",length,"InvalidParameterValue");
    4193       }
    4194     }
    4195   }
    4196   if(lres!=NULL){
    4197     *res=lres;
    4198   }
    4199 }
    4200 
    4201 /**
    4202  * Access the last error message returned by the OS when trying to dynamically
    4203  * load a shared library.
    4204  *
    4205  * @return the last error message
    4206  * @warning The character string returned from getLastErrorMessage resides
    4207  * in a static buffer. The application should not write to this
    4208  * buffer or attempt to free() it.
    4209  */
    4210 char* getLastErrorMessage() {                                             
    4211 #ifdef WIN32
    4212   LPVOID lpMsgBuf;
    4213   DWORD errCode = GetLastError();
    4214   static char msg[ERROR_MSG_MAX_LENGTH];
    4215   size_t i;
    4216  
    4217   DWORD length = FormatMessage(
    4218                                FORMAT_MESSAGE_ALLOCATE_BUFFER |
    4219                                FORMAT_MESSAGE_FROM_SYSTEM |
    4220                                FORMAT_MESSAGE_IGNORE_INSERTS,
    4221                                NULL,
    4222                                errCode,
    4223                                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    4224                                (LPTSTR) &lpMsgBuf,
    4225                                0, NULL );       
    4226  
    4227 #ifdef UNICODE         
    4228   wcstombs_s( &i, msg, ERROR_MSG_MAX_LENGTH,
    4229               (wchar_t*) lpMsgBuf, _TRUNCATE );
    4230 #else
    4231   strcpy_s( msg, ERROR_MSG_MAX_LENGTH,
    4232             (char *) lpMsgBuf );               
    4233 #endif 
    4234   LocalFree(lpMsgBuf);
    4235  
    4236   return msg;
    4237 #else
    4238   return dlerror();
    4239 #endif
    4240 }
    4241 
  • trunk/zoo-project/zoo-kernel/service_internal.h

    r631 r640  
    7474#include <time.h>
    7575#include <ctype.h>
    76 #ifdef WIN32
    7776#ifndef USE_RUBY
    7877#include <unistd.h>
    79 #endif
    8078#endif
    8179#ifndef WIN32
    8280#include <xlocale.h>
    8381#endif
    84 #include "ulinet.h"
    8582
    8683#include "service.h"
    87 #include <openssl/sha.h>
    88 #include <openssl/md5.h>
    89 #include <openssl/hmac.h>
    90 #include <openssl/evp.h>
    91 #include <openssl/bio.h>
    92 #include <openssl/buffer.h>
    9384
    94 extern   int conf_read(const char*,maps*);
     85#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
    9586
    96 #ifdef USE_JS
    97 #ifdef WIN32
    98 #define XP_WIN 1
    99 #else
    100 #define XP_UNIX 0
     87#include <CoreServices/CoreServices.h>
     88#include <SystemConfiguration/SystemConfiguration.h>
     89
    10190#endif
    102 #include "service_internal_js.h"
    103 #endif
    104 
    10591
    10692#ifdef __cplusplus
    10793extern "C" {
    10894#endif
    109 #include <libxml/parser.h>
    110 #include <libxml/xpath.h>
    11195
    112   /**
    113    * Maximum number of XML namespaces
    114    */
    115 #define ZOO_NS_MAX 10
    116   /**
    117    * Maximum number of XML docs
    118    */
    119 #define ZOO_DOC_MAX 20
     96  int  setOutputValue( maps*, const char*, char*, size_t);
     97  char* getInputValue( maps*,const char*,size_t*);
    12098
    121   /**
    122    * Global char* to store the serverAddress value of the mmmmmain section
    123    */
    124   static char* SERVICE_URL;
    125   /**
    126    * Array of xmlNsPtr storing all used XML namespace
    127    */
    128   static xmlNsPtr usedNs[ZOO_NS_MAX];
    129   /**
    130    * Array storing names of the used XML namespace
    131    */
    132   static char* nsName[ZOO_NS_MAX];
    133   /**
    134    * Number of XML namespaces
    135    */
    136   static int nbNs=0;
    137   /**
    138    * Array of xmlDocPtr storing XML docs
    139    */
    140   static xmlDocPtr iDocs[ZOO_DOC_MAX];
    141   /**
    142    * Number of XML docs
    143    */
    144   static int nbDocs=0;
    145 
    146   int getServiceFromYAML(maps*,char*,service**,char *name);
    147   int readServiceFile(maps*, char*,service**,char *);
    148   int isValidLang(maps*,const char*);
    149   void addLangAttr(xmlNodePtr,maps*);
    150 
    151   void printHeaders(maps*);
    15299  void unhandleStatus(maps*);
    153100  int _updateStatus(maps*);
    154101  char* _getStatus(maps*,int);
    155102  char* getStatus(int);
     103  int updateStatus( maps*,const int,const char*);
    156104  int removeShmLock(maps*, int);
    157105  /**
     
    170118#endif
    171119 
    172   void readGeneratedFile(maps*,map*,char*);
    173 
    174   void URLDecode(char *);
    175   char *url_encode(char *);
    176   char *url_decode(char *);
    177   char* getEncoding(maps*);
    178 
    179   int zooXmlSearchForNs(const char*);
    180   int zooXmlAddNs(xmlNodePtr,const char*,const char*);
    181   void zooXmlCleanupNs();
    182 
    183   int zooXmlAddDoc(xmlNodePtr,const char*,const char*);
    184   void zooXmlCleanupDocs();
    185  
    186   void printExceptionReportResponse(maps*,map*);
    187   xmlNodePtr createExceptionReportNode(maps*,map*,int);
    188   void printProcessResponse(maps*,map*,int,service*,const char*,int,maps*,maps*);
    189   xmlNodePtr printWPSHeader(xmlDocPtr,maps*,const char*,const char*);
    190   xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr,maps*);
    191   void printGetCapabilitiesForProcess(maps*,xmlNodePtr,service*);
    192   void printDescribeProcessForProcess(maps*,xmlNodePtr,service*);
    193   void printFullDescription(int,elements*,const char*,xmlNsPtr,xmlNodePtr);
    194   void printDocument(maps*,xmlDocPtr,int);
    195   void printDescription(xmlNodePtr,xmlNsPtr,const char*,map*);
    196   void printIOType(xmlDocPtr,xmlNodePtr,xmlNsPtr,xmlNsPtr,xmlNsPtr,elements*,maps*,const char*);
    197   map* parseBoundingBox(const char*);
    198   void printBoundingBox(xmlNsPtr,xmlNodePtr,map*);
    199   void printBoundingBoxDocument(maps*,maps*,FILE*);
    200   void printOutputDefinitions(xmlDocPtr,xmlNodePtr,xmlNsPtr,xmlNsPtr,elements*,maps*,const char*);
    201 
    202   void outputResponse(service*,maps*,maps*,map*,int,maps*,int);
    203 
    204   void dumpMapsValuesToFiles(maps**,maps**);
    205 
    206   char *base64(const char*,int);
    207   char *base64d(const char*,int,int*);
    208   void ensureDecodedBase64(maps**);
    209   void checkValidValue(map*,map**,const char*,const char**,int);
    210   char* addDefaultValues(maps**,elements*,maps*,int,map**);
    211 
    212   int errorException(maps *, const char *, const char *, const char*);
    213 
    214   xmlNodePtr soapEnvelope(maps*,xmlNodePtr);
    215   int checkForSoapEnvelope(xmlDocPtr);
    216  
    217   void addToCache(maps*,char*,char*,char*,int,char*,size_t);
    218   char* isInCache(maps*,char*);
    219   int runHttpRequests(maps**,maps**,HINTERNET*);
    220   void addRequestToQueue(maps**,HINTERNET*,const char*,bool);
    221   int loadRemoteFile(maps**,map**,HINTERNET*,char*);
    222 
    223   char *readVSIFile(maps*,const char*);
    224   void parseIdentifier(maps*,char*,char*,char*);
    225   int updateStatus( maps*,const int,const char*);
    226   char* getInputValue( maps*,const char*,size_t*);
    227   int  setOutputValue( maps*, const char*, char*, size_t);
    228  
    229   char* getLastErrorMessage();
    230120#ifdef __cplusplus
    231121}
  • trunk/zoo-project/zoo-kernel/service_internal_java.c

    r613 r640  
    2424
    2525#include "service_internal_java.h"
     26#include "response_print.h"
    2627
    2728/**
     
    8788  int nb=1;
    8889  int nbc0=0;
    89   maps* javaXXMap=getMaps(main_conf,"javaxx");
     90  maps* javaXXMap=getMaps(*main_conf,"javaxx");
    9091  if(javaXXMap!=NULL){
    9192    nbc0+=count(javaXXMap->content);
    9293  }
    9394  int nbc1=0;
    94   maps* javaXMap=getMaps(main_conf,"javax");
     95  maps* javaXMap=getMaps(*main_conf,"javax");
    9596  if(javaXMap!=NULL){
    9697    nbc1+=count(javaXMap->content);
     
    107108  long result;
    108109  jmethodID pmid;
    109   jfieldID fid;
    110   jobject jobj;
    111110  jclass cls;
    112111#ifdef JAVA7
     
    502501   * }
    503502   */
    504   jclass scHashMap_class,scSetClass,scIteratorClass,scMapEntryClass,scSet_class,scMapClass;
     503  jclass scSetClass,scIteratorClass,scMapEntryClass;
    505504  jmethodID entrySet_mid,containsKey_mid,get_mid,iterator_mid,hasNext_mid,next_mid,getKey_mid,getValue_mid;
    506   jobject scObject,scObject1;
    507505  if(scHashMapClass==NULL){
    508506#ifdef DEBUG
  • trunk/zoo-project/zoo-kernel/service_internal_js.c

    r586 r640  
    2323 */
    2424
    25 #include "service_internal.h"
     25#include "service_internal_js.h"
     26#include "response_print.h"
    2627
    2728#ifndef JSCLASS_GLOBAL_FLAGS
     
    6768JSLoadScripts(JSContext *cx, uintN argc, jsval *argv1)
    6869{
    69   //map* request = JS_GetContextPrivate(cx);
    70   //map* tmpm1=getMap(request,"metapath");
    7170  JS_MaybeGC(cx);
    7271
     
    7877  JS_MaybeGC(cx);
    7978  for(i=0;i<argc;i++){
    80     JSString* jsmsg = JS_ValueToString(cx,argv[i]);
    8179    char *filename = JSValToChar(cx,&argv[i]);
    8280    char *api0=(char*)malloc((strlen(ntmp)+strlen(filename)+2)*sizeof(char));
     
    110108int zoo_js_support(maps** main_conf,map* request,service* s,maps **inputs,maps **outputs)
    111109{
    112   maps* main=*main_conf;
     110  /*maps* main=*main_conf;
    113111  maps* _inputs=*inputs;
    114   maps* _outputs=*outputs;
     112  maps* _outputs=*outputs;*/
    115113
    116114  /* The class of the global object. */
     
    202200  /* Your application code here. This may include JSAPI calls
    203201     to create your own custom JS objects and run scripts. */
    204   maps* out=*outputs;
     202  //maps* out=*outputs;
    205203  int res=SERVICE_FAILED;
    206   maps* mc=*main_conf;
     204  //maps* mc=*main_conf;
    207205  map* tmpm2=getMap(s->content,"serviceProvider");
    208206
     
    216214  stat(filename, &file_status);
    217215  //char *source=(char*)malloc(file_status.st_size);
    218   uint16 lineno;
     216  //uint16 lineno;
    219217  jsval rval;
    220218  JSBool ok ;
     
    281279  }
    282280
    283   jsval t=OBJECT_TO_JSVAL(d);
     281  //jsval t=OBJECT_TO_JSVAL(d);
    284282  if(JS_IsArrayObject(cx,d)){
    285283#ifdef JS_DEBUG
     
    395393  if(s==0){
    396394    jsval rval;
    397     JSBool ok ;
    398395    JSObject *script = JS_CompileFile(cx, JS_GetGlobalObject(cx), filename);
    399396    if(script!=NULL){
     
    425422JSObject* JSObject_FromMaps(JSContext *cx,maps* t){
    426423  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
    427   //JSObject *res = JS_NewArrayObject(cx, 0, NULL);
    428424  if(res==NULL)
    429425    fprintf(stderr,"Array Object is NULL!\n");
    430426  maps* tmp=t;
    431427  while(tmp!=NULL){
    432     jsuint len;
    433     JSObject* res1=JS_NewObject(cx, NULL, NULL, NULL);
    434428    JSObject *pval=JSObject_FromMap(cx,tmp->content);
    435429    jsval pvalj=OBJECT_TO_JSVAL(pval);
     
    452446JSObject* JSObject_FromMap(JSContext *cx,map* t){
    453447  JSObject* res=JS_NewObject(cx, NULL, NULL, NULL);
    454   jsval resf =  OBJECT_TO_JSVAL(res);
    455448  map* tmpm=t;
    456449  map* isArray=getMap(t,"isArray");
     
    463456    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
    464457#endif
    465   while(tmpm!=NULL){
     458  while(isArray==NULL && tmpm!=NULL){
    466459    jsval jsstr;
    467     if((isArray==NULL && isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0))
     460    if((isBinary!=NULL && strncasecmp(tmpm->name,"value",5)==0))
    468461      jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,atoi(isBinary->value)));
    469462    else
     
    534527        jsval id = idp->vector[index];
    535528        jsval vp;
    536         JSString* str;
    537529        JS_IdToValue(cx,id,&vp);
    538         char *c, *tmp;
     530        char *tmp;
    539531        JSString *jsmsg;
    540532        size_t len1;
     
    583575  fprintf(stderr,"outputs array length : %d\n",len);
    584576#endif
    585   for(oi=0;oi < len;oi++){
     577  for(oi=0;hasLen && oi < len;oi++){
    586578#ifdef JS_DEBUG
    587579    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
     
    605597        jsval id = idp->vector[index];
    606598        jsval vp;
    607         JSString* str;
    608599        JS_IdToValue(cx,id,&vp);
    609         char *c, *tmp;
     600        char *tmp;
    610601        JSString *jsmsg;
    611602        size_t len1;
     
    706697      jsval id = idp->vector[index];
    707698      jsval vp;
    708       JSString* str;
    709699      JS_IdToValue(cx,id,&vp);
    710       char *c, *tmp, *tmp1;
     700      char *tmp, *tmp1;
    711701      JSString *jsmsg,*jsmsg1;
    712702      size_t len,len1;
     
    877867  jsval *argv = JS_ARGV(cx,argv1);
    878868  HINTERNET hInternet;
    879   HINTERNET res;
    880   HINTERNET res1;
    881869  JSObject *header;
    882870  char *url;
     
    884872  char* tmpValue;
    885873  size_t dwRead;
    886   int i=0;
    887874  JS_MaybeGC(cx);
    888875  hInternet=InternetOpen("ZooWPSClient\0",
  • trunk/zoo-project/zoo-kernel/service_internal_ms.c

    r623 r640  
    3232#endif
    3333#include "service_internal_ms.h"
     34#include "server_internal.h"
     35#include "response_print.h"
    3436
    3537/**
  • trunk/zoo-project/zoo-kernel/service_internal_otb.c

    r632 r640  
    2828
    2929#include "service_internal_otb.h"
     30#include "response_print.h"
     31#include "server_internal.h"
    3032
    3133using namespace otb::Wrapper;
     34
     35/**
     36 * Global OTB counter
     37 */
     38int otbCounter=0;
    3239
    3340/**
     
    148155          for (unsigned int i = 0; i < appKeyList.size(); i++){
    149156            const std::string paramKey(appKeyList[i]);
    150             std::vector<std::string> values;
     157            fprintf(stderr,"%s %d %s !\n",__FILE__,__LINE__,paramKey.c_str());
    151158            Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
    152159            ParameterType type = m_Application->GetParameterType(paramKey);
     
    154161              map* test=getMapFromMaps(inputs,paramKey.c_str(),"cache_file");
    155162              if(test==NULL){
     163                fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,paramKey.c_str());
    156164                test=getMapFromMaps(inputs,paramKey.c_str(),"inRequest");
    157165                map* tmpPath=getMapFromMaps(m,"main","tmpPath");
     
    160168                map* tmpVal=getMapFromMaps(outputs,paramKey.c_str(),"mimeType");
    161169                maps* tmpMaps=getMaps(outputs,paramKey.c_str());
    162                 if(test!=NULL && test->value!=NULL && strncasecmp(test->value,"true",4)==0){
     170                if(tmpMaps!=NULL && test!=NULL && test->value!=NULL && strncasecmp(test->value,"true",4)==0){
    163171                  test=getMapFromMaps(inputs,paramKey.c_str(),"value");
    164172                  if(type == ParameterType_OutputImage){
     
    187195                            ext="jpeg";
    188196                    }
    189                     sprintf(tmp,"%s/%s_%s.%s",tmpPath->value,s->name,tmpSid->value,ext);
     197                    sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
     198                    otbCounter++;
    190199                    m_Application->SetParameterString(paramKey, tmp);
    191200                    setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
    192201                    dynamic_cast<OutputImageParameter *> (param.GetPointer())->SetPixelType(outPixType);
    193                   }
    194                   else{
    195                     if(test!=NULL && test->value!=NULL)
    196                       m_Application->SetParameterString(paramKey, test->value);
    197202                  }
    198203                }else{
     
    212217                              ext="kml";
    213218                      }
    214                       sprintf(tmp,"%s/%s_%s.%s",tmpPath->value,s->name,tmpSid->value,ext);
     219                      sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
     220                      otbCounter++;
    215221                      m_Application->SetParameterString(paramKey, tmp);
    216222                      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
     
    234240                                if(strncasecmp(tmpVal->value,"application/vnd.google-earth.kmz",32)==0){
    235241                                  ext="kmz";
    236                                   sprintf(tmp,"%s/%s_%sxt.%s",tmpPath->value,s->name,tmpSid->value,ext);
     242                                  sprintf(tmp,"%s/%s_%d_%sxt.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
    237243                                  m_Application->SetParameterString(paramKey, tmp);
    238244                                  setMapInMaps(outputs,paramKey.c_str(),"expected_generated_file",tmp);
     
    240246
    241247                      }
    242                       sprintf(tmp,"%s/%s_%s.%s",tmpPath->value,s->name,tmpSid->value,ext);
     248                      sprintf(tmp,"%s/%s_%d_%s.%s",tmpPath->value,s->name,otbCounter,tmpSid->value,ext);
     249                      otbCounter++;
    243250                      m_Application->SetParameterString(paramKey, tmp);
    244251                      setMapInMaps(inputs,paramKey.c_str(),"generated_file",tmp);
    245252                    }
    246 
     253                    else{
     254                      test=getMapFromMaps(inputs,paramKey.c_str(),"value");
     255                      if(test!=NULL && type!=ParameterType_ListView){
     256                        m_Application->SetParameterString(paramKey, test->value);
     257                      }
     258                      else
     259                        if(type==ParameterType_ListView){
     260                          std::vector<std::string> values;
     261                          values.push_back(test->value);
     262                          map* tmpLength=getMapFromMaps(inputs,paramKey.c_str(),"length");
     263                          if(tmpLength!=NULL){
     264                            int len=atoi(tmpLength->value);
     265                            for(int k=1;k<len;k++){
     266                              char tmp[15];
     267                              sprintf(tmp,"cache_file_%d",k);
     268                              map* tmpVal=getMapFromMaps(inputs,paramKey.c_str(),tmp);
     269                              if(tmpVal!=NULL){
     270                                values.push_back(tmpVal->value);
     271                              }
     272                            }
     273                          }
     274                          dynamic_cast<ListViewParameter *> (param.GetPointer())->SetSelectedItems(values);
     275                        }
     276                    }
    247277                }
    248278              }else{
    249279                if(type == ParameterType_InputImageList){
     280                  std::vector<std::string> values;
    250281                  values.push_back(test->value);
    251282                  map* tmpPath=getMapFromMaps(inputs,paramKey.c_str(),"length");
  • trunk/zoo-project/zoo-kernel/service_internal_otb.h

    r618 r640  
    3131#include "otbWrapperApplicationRegistry.h"
    3232#include "otbWrapperInputImageListParameter.h"
     33#include "otbWrapperListViewParameter.h"
    3334#include "otbWrapperAddProcessToWatchEvent.h"
    3435#include "otbZooWatcher.h"
    3536#include "service_internal.h"
    36 #include "mimetypes.h"
    3737#include "service.h"
    3838#include "cgic.h"
  • trunk/zoo-project/zoo-kernel/service_internal_python.h

    r579 r640  
    2929
    3030#include "service_internal.h"
     31#include "response_print.h"
    3132#include <Python.h>
    3233#include "cgic.h"
  • trunk/zoo-project/zoo-kernel/service_internal_saga.c

    r639 r640  
    3333#define _ZOO_SAGA
    3434#include "service_internal_saga.h"
     35#include "server_internal.h"
    3536#include "mimetypes.h"
    3637
  • trunk/zoo-project/zoo-kernel/zcfg2yaml.c

    r550 r640  
    2323 */
    2424
    25 #include "service_internal.h"
     25#include "server_internal.h"
     26#include "response_print.h"
    2627#include "service.h"
    2728
  • trunk/zoo-project/zoo-kernel/zoo_loader.c

    r621 r640  
    3737#include <unistd.h>
    3838#include "service_internal.h"
     39#include "response_print.h"
    3940
    4041
     
    216217   * one.
    217218   */
    218 
    219219  if(strncasecmp(cgiRequestMethod,"post",4)==0 ||
    220220     (count(tmpMap)==1 && strncmp(tmpMap->value,"<",1)==0)
     
    287287        xmlXPathObjectPtr versptr=extractFromDoc(doc,"/*/*/*[local-name()='Version']");
    288288        xmlNodeSet* vers=versptr->nodesetval;
    289         xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
    290         addToMap(tmpMap,"version",(char*)content);
     289        if(vers!=NULL && vers->nodeTab!=NULL && vers->nodeTab[0]!=NULL){
     290          xmlChar* content=xmlNodeListGetString(doc, vers->nodeTab[0]->xmlChildrenNode,1);
     291          addToMap(tmpMap,"version",(char*)content);
     292          xmlFree(content);
     293        }
     294        if(cur->ns){
     295          addToMap(tmpMap,"wps_schemas",(char*)cur->ns->href);
     296          xmlFree(tval);
     297          int j=0;
     298          for(j=0;j<2;j++)
     299            if(strncasecmp(schemas[j][2],(char*)cur->ns->href,strlen(schemas[j][2]))==0){
     300              char vers[6];
     301              sprintf(vers,"%d.0.0",j+1);
     302              addToMap(tmpMap,"version",(char*)vers);
     303            }
     304        }
     305        dumpMap(tmpMap);
    291306        xmlXPathFreeObject(versptr);
    292         xmlFree(content);
    293307      }else{
    294308        tval=NULL;
     
    376390    free(strQuery);
    377391
     392 
    378393  runRequest(&tmpMap);
    379394
  • trunk/zoo-project/zoo-kernel/zoo_service_loader.c

    r634 r640  
    5454
    5555#include "service_internal.h"
     56#include "server_internal.h"
     57#include "response_print.h"
    5658#include "request_parser.h"
     59#include "sqlapi.h"
    5760
    5861#ifdef USE_PYTHON
     
    10441047  r_inputs = getMap (request_inputs, "language");
    10451048  if (r_inputs == NULL)
     1049    r_inputs = getMap (request_inputs, "AcceptLanguages");
     1050  if (r_inputs == NULL)
    10461051    r_inputs = getMapFromMaps (m, "main", "language");
    10471052  if (r_inputs != NULL)
     
    11411146    NULL
    11421147  };
    1143   checkValidValue(request_inputs,&err,"Request",(const char**)vvr,1);
     1148  checkValidValue(request_inputs,&err,"request",(const char**)vvr,1);
    11441149  const char *vvs[]={
    11451150    "WPS",
     
    11611166  }
    11621167  checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
     1168
    11631169  const char *vvv[]={
    11641170    "1.0.0",
     1171    "2.0.0",
    11651172    NULL
    11661173  };
     
    11721179  }else{
    11731180    checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
     1181    map* version=getMap(request_inputs,"AcceptVersions");
     1182    if(version!=NULL){
     1183      if(strstr(version->value,schemas[1][0])!=NULL)
     1184        addToMap(request_inputs,"version",schemas[1][0]);
     1185      else
     1186        addToMap(request_inputs,"version",version->value);
     1187    }
    11741188  }
     1189  map* version=getMap(request_inputs,"version");
     1190  if(version==NULL)
     1191    version=getMapFromMaps(m,"main","version");
     1192  setMapInMaps(m,"main","rversion",version->value);
    11751193  if(err!=NULL){
    11761194    printExceptionReportResponse (m, err);
     
    12371255      r_inputs = NULL;
    12381256      //r_inputs = getMap (request_inputs, "ServiceProvider");
    1239       xmlNodePtr n=printGetCapabilitiesHeader(doc,m);
     1257      r_inputs = getMap (request_inputs, "version");
     1258      xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(r_inputs!=NULL?r_inputs->value:"1.0.0"));
    12401259      /**
    12411260       * Here we need to close stdout to ensure that unsupported chars
     
    12991318          xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
    13001319          r_inputs = NULL;
     1320          r_inputs = getMap (request_inputs, "version");
     1321          map* version=getMapFromMaps(m,"main","rversion");
     1322          int vid=getVersionId(version->value);
    13011323          xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
    1302                                         "ProcessDescriptions");
     1324                                        root_nodes[vid][1],(r_inputs!=NULL?r_inputs->value:"1.0.0"),1);
    13031325
    13041326          r_inputs = getMap (request_inputs, "Identifier");
     
    17481770   *  - usid : it is an unique identification number
    17491771   *  - sid : it is the process idenfitication number (OS)
     1772   *  - uusid : it is an universally unique identification number
    17501773   *  - status : value between 0 and 100 to express the  completude of
    17511774   * the operations of the running service
     
    17771800  sprintf (tmpBuff, "%i", cpid);
    17781801  addToMap (_tmpMaps->content, "sid", tmpBuff);
     1802  char* tmpUuid=get_uuid();
     1803  addToMap (_tmpMaps->content, "uusid", tmpUuid);
     1804  free(tmpUuid);
    17791805  addToMap (_tmpMaps->content, "status", "0");
    17801806  addToMap (_tmpMaps->content, "cwd", ntmp);
Note: See TracChangeset for help on using the changeset viewer.

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png