source: trunk/zoo-project/zoo-kernel/zoo_service_loader.c @ 675

Last change on this file since 675 was 673, checked in by djay, 10 years ago

Fixes in configure.ac. Fix in registry creation. Fixes for Data node for WPS version 2.0.0.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 65.0 KB
RevLine 
[607]1/*
[1]2 * Author : Gérald FENOY
3 *
[392]4 *  Copyright 2008-2013 GeoLabs SARL. All rights reserved.
[1]5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
[541]25extern "C" int yylex ();
26extern "C" int crlex ();
[9]27
[550]28#ifdef USE_OTB
29#include "service_internal_otb.h"
30#else
31#define length(x) (sizeof(x) / sizeof(x[0]))
32#endif
33
[376]34#include "cgic.h"
35
[541]36extern "C"
37{
[1]38#include <libxml/tree.h>
39#include <libxml/xmlmemory.h>
40#include <libxml/parser.h>
41#include <libxml/xpath.h>
42#include <libxml/xpathInternals.h>
43}
44
45#include "ulinet.h"
46
[34]47#include <libintl.h>
48#include <locale.h>
[1]49#include <string.h>
50
51#include "service.h"
[34]52
[1]53#include "service_internal.h"
[640]54#include "server_internal.h"
55#include "response_print.h"
[621]56#include "request_parser.h"
[640]57#include "sqlapi.h"
[33]58
59#ifdef USE_PYTHON
[1]60#include "service_internal_python.h"
[33]61#endif
[1]62
[634]63#ifdef USE_SAGA
64#include "service_internal_saga.h"
65#endif
66
[1]67#ifdef USE_JAVA
68#include "service_internal_java.h"
69#endif
70
71#ifdef USE_PHP
72#include "service_internal_php.h"
73#endif
74
75#ifdef USE_JS
76#include "service_internal_js.h"
77#endif
78
[453]79#ifdef USE_RUBY
80#include "service_internal_ruby.h"
81#endif
82
[25]83#ifdef USE_PERL
84#include "service_internal_perl.h"
85#endif
[1]86
87#include <dirent.h>
88#include <signal.h>
89#include <unistd.h>
90#ifndef WIN32
91#include <dlfcn.h>
92#include <libgen.h>
93#else
94#include <windows.h>
95#include <direct.h>
[364]96#include <sys/types.h>
97#include <sys/stat.h>
98#include <unistd.h>
99#define pid_t int;
[1]100#endif
101#include <fcntl.h>
102#include <time.h>
103#include <stdarg.h>
104
[364]105#ifdef WIN32
[541]106extern "C"
107{
108  __declspec (dllexport) char *strcasestr (char const *a, char const *b)
[370]109#ifndef USE_MS
[541]110  {
111    char *x = zStrdup (a);
112    char *y = zStrdup (b);
113
114      x = _strlwr (x);
115      y = _strlwr (y);
116    char *pos = strstr (x, y);
117    char *ret = pos == NULL ? NULL : (char *) (a + (pos - x));
118      free (x);
119      free (y);
120      return ret;
121  };
[370]122#else
[541]123   ;
[370]124#endif
[364]125}
126#endif
127
[607]128/**
129 * Translation function for zoo-kernel
130 */
[34]131#define _(String) dgettext ("zoo-kernel",String)
[607]132/**
133 * Translation function for zoo-service
134 */
[376]135#define __(String) dgettext ("zoo-service",String)
[34]136
[582]137#ifdef WIN32
138  #ifndef PROGRAMNAME
139    #define PROGRAMNAME "zoo_loader.cgi"
140  #endif
141#endif
142
[541]143extern int getServiceFromFile (maps *, const char *, service **);
[34]144
[607]145/**
146 * Parse the service file using getServiceFromFile or use getServiceFromYAML
147 * if YAML support was activated.
148 *
149 * @param conf the conf maps containing the main.cfg settings
150 * @param file the file name to parse
151 * @param service the service to update witht the file content
152 * @param name the service name
153 * @return true if the file can be parsed or false
154 * @see getServiceFromFile, getServiceFromYAML
155 */
[541]156int
157readServiceFile (maps * conf, char *file, service ** service, char *name)
158{
159  int t = getServiceFromFile (conf, file, service);
[467]160#ifdef YAML
[541]161  if (t < 0)
162    {
163      t = getServiceFromYAML (conf, file, service, name);
164    }
[467]165#endif
166  return t;
167}
168
[607]169/**
170 * Replace a char by another one in a string
171 *
172 * @param str the string to update
173 * @param toReplace the char to replace
174 * @param toReplaceBy the char that will be used
175 */
[541]176void
177translateChar (char *str, char toReplace, char toReplaceBy)
178{
179  int i = 0, len = strlen (str);
180  for (i = 0; i < len; i++)
181    {
182      if (str[i] == toReplace)
183        str[i] = toReplaceBy;
184    }
[34]185}
186
[360]187
[607]188/**
189 * Create the profile registry.
190 *
191 * The profile registry is optional (created only if the registry key is
192 * available in the [main] section of the main.cfg file) and can be used to
193 * store the profiles hierarchy. The registry is a directory which should
194 * contain the following sub-directories:
195 *  * concept: direcotry containing .html files describing concept
196 *  * generic: directory containing .zcfg files for wps:GenericProcess
197 *  * implementation: directory containing .zcfg files for wps:Process
198 *
199 * @param m the conf maps containing the main.cfg settings
200 * @param r the registry to update
201 * @param reg_dir the resgitry
202 * @param saved_stdout the saved stdout identifier
203 * @return 0 if the resgitry is null or was correctly updated, -1 on failure
204 */
[541]205int
[607]206createRegistry (maps* m,registry ** r, char *reg_dir, int saved_stdout)
207{
[673]208  char registryKeys[3][15]={
209    "concept",
210    "generic",
211    "implementation"
212  };
213  int scount = 0,i=0;
[607]214  if (reg_dir == NULL)
215    return 0;
[673]216  for(i=0;i<3;i++){
217    char * tmpName =
218      (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *
219                       sizeof (char));
220    sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);
221   
222    DIR *dirp1 = opendir (tmpName);
223    struct dirent *dp1;
224    while ((dp1 = readdir (dirp1)) != NULL){
225      char* extn = strstr(dp1->d_name, ".zcfg");
226      if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
227        {
228          int t;
229          char *tmps1=
230            (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
231                             sizeof (char));
232          sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
233          char *tmpsn = zStrdup (dp1->d_name);
234          tmpsn[strlen (tmpsn) - 5] = 0;
235          service* s1 = (service *) malloc (SERVICE_SIZE);
236          if (s1 == NULL)
[607]237            {
[673]238              dup2 (saved_stdout, fileno (stdout));
239              errorException (m, _("Unable to allocate memory."),
240                              "InternalError", NULL);
241              return -1;
242            }
243          t = readServiceFile (m, tmps1, &s1, tmpsn);
244          free (tmpsn);
245          if (t < 0)
246            {
247              map *tmp00 = getMapFromMaps (m, "lenv", "message");
248              char tmp01[1024];
249              if (tmp00 != NULL)
250                sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
251                         dp1->d_name, tmp00->value);
252              else
253                sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
254                         dp1->d_name);
255              dup2 (saved_stdout, fileno (stdout));
256              errorException (m, tmp01, "InternalError", NULL);
257              return -1;
258            }
[607]259#ifdef DEBUG
[673]260          dumpService (s1);
261          fflush (stdout);
262          fflush (stderr);
[607]263#endif
[673]264          if(strncasecmp(registryKeys[i],"implementation",14)==0){
265            inheritance(*r,&s1);
266          }
267          addServiceToRegistry(r,registryKeys[i],s1);
268          freeService (&s1);
269          free (s1);
270          scount++;
[607]271        }
[673]272    }
273    (void) closedir (dirp1);
[607]274  }
275  return 0;
276}
277
278/**
279 * Recursivelly parse zcfg starting from the ZOO-Kernel cwd.
280 * Call the func function given in arguments after parsing the ZCFG file.
281 *
282 * @param m the conf maps containing the main.cfg settings
283 * @param r the registry containing profiles hierarchy
284 * @param n the root XML Node to add the sub-elements
285 * @param conf_dir the location of the main.cfg file (basically cwd)
286 * @param prefix the current prefix if any, or NULL
287 * @param saved_stdout the saved stdout identifier
288 * @param level the current level (number of sub-directories to reach the
289 * current path)
290 * @see inheritance, readServiceFile
291 */
292int
293recursReaddirF (maps * m, registry *r, xmlNodePtr n, char *conf_dir, char *prefix,
[541]294                int saved_stdout, int level, void (func) (maps *, xmlNodePtr,
295                                                          service *))
296{
[469]297  struct dirent *dp;
[541]298  int scount = 0;
[469]299
[541]300  if (conf_dir == NULL)
[469]301    return 1;
[541]302  DIR *dirp = opendir (conf_dir);
303  if (dirp == NULL)
304    {
305      if (level > 0)
306        return 1;
307      else
308        return -1;
309    }
[469]310  char tmp1[25];
[541]311  sprintf (tmp1, "sprefix_%d", level);
[469]312  char levels[17];
[541]313  sprintf (levels, "%d", level);
314  setMapInMaps (m, "lenv", "level", levels);
315  while ((dp = readdir (dirp)) != NULL)
316    if ((dp->d_type == DT_DIR || dp->d_type == DT_LNK) && dp->d_name[0] != '.'
317        && strstr (dp->d_name, ".") == NULL)
318      {
[469]319
[541]320        char *tmp =
321          (char *) malloc ((strlen (conf_dir) + strlen (dp->d_name) + 2) *
322                           sizeof (char));
323        sprintf (tmp, "%s/%s", conf_dir, dp->d_name);
[469]324
[541]325        if (prefix != NULL)
326          {
327            prefix = NULL;
328          }
329        prefix = (char *) malloc ((strlen (dp->d_name) + 2) * sizeof (char));
330        sprintf (prefix, "%s.", dp->d_name);
331
332        //map* tmpMap=getMapFromMaps(m,"lenv",tmp1);
333
334        int res;
335        if (prefix != NULL)
336          {
337            setMapInMaps (m, "lenv", tmp1, prefix);
338            char levels1[17];
339            sprintf (levels1, "%d", level + 1);
340            setMapInMaps (m, "lenv", "level", levels1);
341            res =
[607]342              recursReaddirF (m, r, n, tmp, prefix, saved_stdout, level + 1,
[541]343                              func);
344            sprintf (levels1, "%d", level);
345            setMapInMaps (m, "lenv", "level", levels1);
346            free (prefix);
347            prefix = NULL;
348          }
349        else
350          res = -1;
351        free (tmp);
352        if (res < 0)
353          {
354            return res;
355          }
[469]356      }
[541]357    else
358      {
[557]359        char* extn = strstr(dp->d_name, ".zcfg");
360        if(dp->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
[541]361          {
362            int t;
363            char tmps1[1024];
364            memset (tmps1, 0, 1024);
365            snprintf (tmps1, 1024, "%s/%s", conf_dir, dp->d_name);
366            service *s1 = (service *) malloc (SERVICE_SIZE);
367            if (s1 == NULL)
368              {
369                dup2 (saved_stdout, fileno (stdout));
370                errorException (m, _("Unable to allocate memory."),
371                                "InternalError", NULL);
372                return -1;
373              }
[469]374#ifdef DEBUG
[541]375            fprintf (stderr, "#################\n%s\n#################\n",
376                     tmps1);
[469]377#endif
[541]378            char *tmpsn = zStrdup (dp->d_name);
379            tmpsn[strlen (tmpsn) - 5] = 0;
380            t = readServiceFile (m, tmps1, &s1, tmpsn);
381            free (tmpsn);
382            if (t < 0)
383              {
384                map *tmp00 = getMapFromMaps (m, "lenv", "message");
385                char tmp01[1024];
386                if (tmp00 != NULL)
387                  sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
388                           dp->d_name, tmp00->value);
389                else
390                  sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
391                           dp->d_name);
392                dup2 (saved_stdout, fileno (stdout));
393                errorException (m, tmp01, "InternalError", NULL);
394                return -1;
395              }
[469]396#ifdef DEBUG
[541]397            dumpService (s1);
398            fflush (stdout);
399            fflush (stderr);
[469]400#endif
[607]401            inheritance(r,&s1);
[541]402            func (m, n, s1);
403            freeService (&s1);
404            free (s1);
405            scount++;
406          }
[469]407      }
[541]408  (void) closedir (dirp);
[469]409  return 1;
410}
411
[607]412/**
413 * Signal handling function which simply call exit(0).
414 *
415 * @param sig the signal number
416 */
[541]417void
418donothing (int sig)
419{
[478]420#ifdef DEBUG
[605]421  fprintf (stderr, "Signal %d after the ZOO-Kernel returned result!\n", sig);
[478]422#endif
[541]423  exit (0);
[105]424}
425
[607]426/**
427 * Signal handling function which create an ExceptionReport node containing the
428 * information message corresponding to the signal number.
429 *
430 * @param sig the signal number
431 */
[541]432void
433sig_handler (int sig)
434{
[9]435  char tmp[100];
[114]436  const char *ssig;
[541]437  switch (sig)
438    {
439    case SIGSEGV:
440      ssig = "SIGSEGV";
441      break;
442    case SIGTERM:
443      ssig = "SIGTERM";
444      break;
445    case SIGINT:
446      ssig = "SIGINT";
447      break;
448    case SIGILL:
449      ssig = "SIGILL";
450      break;
451    case SIGFPE:
452      ssig = "SIGFPE";
453      break;
454    case SIGABRT:
455      ssig = "SIGABRT";
456      break;
457    default:
458      ssig = "UNKNOWN";
459      break;
460    }
461  sprintf (tmp,
462           _
[605]463           ("ZOO Kernel failed to process your request, receiving signal %d = %s"),
[541]464           sig, ssig);
465  errorException (NULL, tmp, "InternalError", NULL);
[10]466#ifdef DEBUG
[541]467  fprintf (stderr, "Not this time!\n");
[10]468#endif
[541]469  exit (0);
[1]470}
471
[607]472/**
473 * Load a service provider and run the service function.
474 *
475 * @param myMap the conf maps containing the main.cfg settings
476 * @param s1 the service structure
477 * @param request_inputs map storing all the request parameters
478 * @param inputs the inputs maps
479 * @param ioutputs the outputs maps
480 * @param eres the result returned by the service execution
481 */
[541]482void
483loadServiceAndRun (maps ** myMap, service * s1, map * request_inputs,
484                   maps ** inputs, maps ** ioutputs, int *eres)
485{
[34]486  char tmps1[1024];
487  char ntmp[1024];
[541]488  maps *m = *myMap;
489  maps *request_output_real_format = *ioutputs;
490  maps *request_input_real_format = *inputs;
[34]491  /**
492   * Extract serviceType to know what kind of service should be loaded
493   */
[541]494  map *r_inputs = NULL;
[34]495#ifndef WIN32
[541]496  getcwd (ntmp, 1024);
[34]497#else
[541]498  _getcwd (ntmp, 1024);
[34]499#endif
[541]500  r_inputs = getMap (s1->content, "serviceType");
[34]501#ifdef DEBUG
[541]502  fprintf (stderr, "LOAD A %s SERVICE PROVIDER \n", r_inputs->value);
503  fflush (stderr);
[34]504#endif
[605]505
506  map* libp = getMapFromMaps(m, "main", "libPath");
507 
[541]508  if (strlen (r_inputs->value) == 1
509      && strncasecmp (r_inputs->value, "C", 1) == 0)
[605]510  {
511     if (libp != NULL && libp->value != NULL) {
512            r_inputs = getMap (s1->content, "ServiceProvider");
513                sprintf (tmps1, "%s/%s", libp->value, r_inputs->value);
514         }
515     else {     
516        r_inputs = getMap (request_inputs, "metapath");
517        if (r_inputs != NULL)
518          sprintf (tmps1, "%s/%s", ntmp, r_inputs->value);
519        else
520          sprintf (tmps1, "%s/", ntmp);
521         
522        char *altPath = zStrdup (tmps1);
523        r_inputs = getMap (s1->content, "ServiceProvider");
524        sprintf (tmps1, "%s/%s", altPath, r_inputs->value);
525        free (altPath);
526         }
[34]527#ifdef DEBUG
[541]528      fprintf (stderr, "Trying to load %s\n", tmps1);
[34]529#endif
530#ifdef WIN32
[541]531      HINSTANCE so =
532        LoadLibraryEx (tmps1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
[34]533#else
[541]534      void *so = dlopen (tmps1, RTLD_LAZY);
[34]535#endif
[57]536#ifdef WIN32
[578]537      char* errstr = getLastErrorMessage();
[34]538#else
[541]539      char *errstr;
540      errstr = dlerror ();
[34]541#endif
[478]542#ifdef DEBUG
[578]543          fprintf (stderr, "%s loaded (%s) \n", tmps1, errstr);
[478]544#endif
[541]545      if (so != NULL)
546        {
[34]547#ifdef DEBUG
[541]548          fprintf (stderr, "Library loaded %s \n", errstr);
549          fprintf (stderr, "Service Shared Object = %s\n", r_inputs->value);
[34]550#endif
[541]551          r_inputs = getMap (s1->content, "serviceType");
[34]552#ifdef DEBUG
[541]553          dumpMap (r_inputs);
554          fprintf (stderr, "%s\n", r_inputs->value);
555          fflush (stderr);
[34]556#endif
[541]557          if (strncasecmp (r_inputs->value, "C-FORTRAN", 9) == 0)
558            {
559              r_inputs = getMap (request_inputs, "Identifier");
560              char fname[1024];
561              sprintf (fname, "%s_", r_inputs->value);
[34]562#ifdef DEBUG
[541]563              fprintf (stderr, "Try to load function %s\n", fname);
[34]564#endif
565#ifdef WIN32
[541]566              typedef int (CALLBACK * execute_t) (char ***, char ***,
567                                                  char ***);
568              execute_t execute = (execute_t) GetProcAddress (so, fname);
[34]569#else
[541]570              typedef int (*execute_t) (char ***, char ***, char ***);
571              execute_t execute = (execute_t) dlsym (so, fname);
[34]572#endif
573#ifdef DEBUG
574#ifdef WIN32
[578]575                          errstr = getLastErrorMessage();
[34]576#else
[541]577              errstr = dlerror ();
[34]578#endif
[541]579              fprintf (stderr, "Function loaded %s\n", errstr);
580#endif
[34]581
[541]582              char main_conf[10][30][1024];
583              char inputs[10][30][1024];
584              char outputs[10][30][1024];
585              for (int i = 0; i < 10; i++)
586                {
587                  for (int j = 0; j < 30; j++)
588                    {
589                      memset (main_conf[i][j], 0, 1024);
590                      memset (inputs[i][j], 0, 1024);
591                      memset (outputs[i][j], 0, 1024);
592                    }
593                }
594              mapsToCharXXX (m, (char ***) main_conf);
595              mapsToCharXXX (request_input_real_format, (char ***) inputs);
596              mapsToCharXXX (request_output_real_format, (char ***) outputs);
597              *eres =
598                execute ((char ***) &main_conf[0], (char ***) &inputs[0],
599                         (char ***) &outputs[0]);
[34]600#ifdef DEBUG
[541]601              fprintf (stderr, "Function run successfully \n");
[34]602#endif
[541]603              charxxxToMaps ((char ***) &outputs[0],
604                             &request_output_real_format);
605            }
606          else
607            {
[34]608#ifdef DEBUG
609#ifdef WIN32
[578]610                          errstr = getLastErrorMessage();
611              fprintf (stderr, "Function %s failed to load because of %s\n",
[541]612                       r_inputs->value, errstr);
[34]613#endif
614#endif
[541]615              r_inputs = getMapFromMaps (m, "lenv", "Identifier");
[34]616#ifdef DEBUG
[541]617              fprintf (stderr, "Try to load function %s\n", r_inputs->value);
[34]618#endif
[541]619              typedef int (*execute_t) (maps **, maps **, maps **);
[34]620#ifdef WIN32
[541]621              execute_t execute =
622                (execute_t) GetProcAddress (so, r_inputs->value);
[34]623#else
[541]624              execute_t execute = (execute_t) dlsym (so, r_inputs->value);
[34]625#endif
626
[541]627              if (execute == NULL)
628                {
[469]629#ifdef WIN32
[578]630                                  errstr = getLastErrorMessage();
[469]631#else
[541]632                  errstr = dlerror ();
[469]633#endif
[541]634                  char *tmpMsg =
635                    (char *) malloc (2048 + strlen (r_inputs->value));
636                  sprintf (tmpMsg,
637                           _
638                           ("Error occured while running the %s function: %s"),
639                           r_inputs->value, errstr);
640                  errorException (m, tmpMsg, "InternalError", NULL);
641                  free (tmpMsg);
[478]642#ifdef DEBUG
[541]643                  fprintf (stderr, "Function %s error %s\n", r_inputs->value,
644                           errstr);
[478]645#endif
[541]646                  *eres = -1;
647                  return;
648                }
[469]649
[34]650#ifdef DEBUG
651#ifdef WIN32
[578]652                          errstr = getLastErrorMessage();
[34]653#else
[541]654              errstr = dlerror ();
[34]655#endif
[541]656              fprintf (stderr, "Function loaded %s\n", errstr);
657#endif
[34]658
659#ifdef DEBUG
[541]660              fprintf (stderr, "Now run the function \n");
661              fflush (stderr);
[34]662#endif
[541]663              *eres =
664                execute (&m, &request_input_real_format,
665                         &request_output_real_format);
[34]666#ifdef DEBUG
[541]667              fprintf (stderr, "Function loaded and returned %d\n", eres);
668              fflush (stderr);
[34]669#endif
[541]670            }
[216]671#ifdef WIN32
[541]672          *ioutputs = dupMaps (&request_output_real_format);
673          FreeLibrary (so);
[216]674#else
[541]675          dlclose (so);
[216]676#endif
[541]677        }
678      else
679        {
[34]680      /**
681       * Unable to load the specified shared library
682       */
[541]683          char tmps[1024];
[34]684#ifdef WIN32
[578]685                  errstr = getLastErrorMessage();
[34]686#else
[578]687              errstr = dlerror ();
[34]688#endif
[605]689          sprintf (tmps, _("Unable to load C Library %s"), errstr);
[576]690          errorException(m,tmps,"InternalError",NULL);
[541]691          *eres = -1;
692        }
[34]693    }
694  else
[550]695
[634]696#ifdef USE_SAGA
697  if (strncasecmp (r_inputs->value, "SAGA", 6) == 0)
698    {
699      *eres =
700        zoo_saga_support (&m, request_inputs, s1,
701                            &request_input_real_format,
702                            &request_output_real_format);
703    }
704  else
705#endif
706
[550]707#ifdef USE_OTB
708  if (strncasecmp (r_inputs->value, "OTB", 6) == 0)
709    {
710      *eres =
711        zoo_otb_support (&m, request_inputs, s1,
712                            &request_input_real_format,
713                            &request_output_real_format);
714    }
715  else
716#endif
717
[34]718#ifdef USE_PYTHON
[541]719  if (strncasecmp (r_inputs->value, "PYTHON", 6) == 0)
720    {
721      *eres =
722        zoo_python_support (&m, request_inputs, s1,
723                            &request_input_real_format,
724                            &request_output_real_format);
[34]725    }
[541]726  else
[34]727#endif
[541]728
[34]729#ifdef USE_JAVA
[541]730  if (strncasecmp (r_inputs->value, "JAVA", 4) == 0)
731    {
732      *eres =
733        zoo_java_support (&m, request_inputs, s1, &request_input_real_format,
734                          &request_output_real_format);
735    }
736  else
[34]737#endif
738
739#ifdef USE_PHP
[541]740  if (strncasecmp (r_inputs->value, "PHP", 3) == 0)
741    {
742      *eres =
743        zoo_php_support (&m, request_inputs, s1, &request_input_real_format,
744                         &request_output_real_format);
745    }
746  else
[34]747#endif
[541]748
749
[34]750#ifdef USE_PERL
[541]751  if (strncasecmp (r_inputs->value, "PERL", 4) == 0)
752    {
753      *eres =
754        zoo_perl_support (&m, request_inputs, s1, &request_input_real_format,
755                          &request_output_real_format);
756    }
757  else
[34]758#endif
759
760#ifdef USE_JS
[541]761  if (strncasecmp (r_inputs->value, "JS", 2) == 0)
762    {
763      *eres =
764        zoo_js_support (&m, request_inputs, s1, &request_input_real_format,
765                        &request_output_real_format);
766    }
767  else
[34]768#endif
[453]769
770#ifdef USE_RUBY
[541]771  if (strncasecmp (r_inputs->value, "Ruby", 4) == 0)
772    {
773      *eres =
774        zoo_ruby_support (&m, request_inputs, s1, &request_input_real_format,
775                          &request_output_real_format);
776    }
777  else
[453]778#endif
779
[541]780    {
781      char tmpv[1024];
782      sprintf (tmpv,
783               _
784               ("Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n"),
785               r_inputs->value);
[576]786      errorException (m, tmpv, "InternalError", NULL);
[541]787      *eres = -1;
788    }
789  *myMap = m;
790  *ioutputs = request_output_real_format;
[34]791}
792
[384]793
[216]794#ifdef WIN32
795/**
796 * createProcess function: create a new process after setting some env variables
797 */
[541]798void
799createProcess (maps * m, map * request_inputs, service * s1, char *opts,
800               int cpid, maps * inputs, maps * outputs)
801{
[216]802  STARTUPINFO si;
803  PROCESS_INFORMATION pi;
[541]804  ZeroMemory (&si, sizeof (si));
805  si.cb = sizeof (si);
806  ZeroMemory (&pi, sizeof (pi));
807  char *tmp = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
808  char *tmpq = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
809  map *req = getMap (request_inputs, "request");
810  map *id = getMap (request_inputs, "identifier");
811  map *di = getMap (request_inputs, "DataInputs");
[216]812
[583]813  // The required size for the dataInputsKVP and dataOutputsKVP buffers
814  // may exceed cgiContentLength, hence a 2 kb extension. However, a
815  // better solution would be to have getMapsAsKVP() determine the required
816  // buffer size before allocating memory.     
817  char *dataInputsKVP = getMapsAsKVP (inputs, cgiContentLength + 2048, 0);
818  char *dataOutputsKVP = getMapsAsKVP (outputs, cgiContentLength + 2048, 1);
[384]819#ifdef DEBUG
[541]820  fprintf (stderr, "DATAINPUTSKVP %s\n", dataInputsKVP);
821  fprintf (stderr, "DATAOUTPUTSKVP %s\n", dataOutputsKVP);
[384]822#endif
[541]823  map *sid = getMapFromMaps (m, "lenv", "sid");
824  map *r_inputs = getMapFromMaps (m, "main", "tmpPath");
825  map *r_inputs1 = getMap (request_inputs, "metapath");
[605]826 
[541]827  int hasIn = -1;
828  if (r_inputs1 == NULL)
829    {
830      r_inputs1 = createMap ("metapath", "");
831      hasIn = 1;
832    }
833  map *r_inputs2 = getMap (request_inputs, "ResponseDocument");
834  if (r_inputs2 == NULL)
835    r_inputs2 = getMap (request_inputs, "RawDataOutput");
836  map *tmpPath = getMapFromMaps (m, "lenv", "cwd");
[216]837
[541]838  map *tmpReq = getMap (request_inputs, "xrequest");
[587]839 
840  if(r_inputs2 != NULL && tmpReq != NULL) {
841        const char key[] = "rfile=";
842        char* kvp = (char*) malloc((FILENAME_MAX + strlen(key))*sizeof(char));
843        char* filepath = kvp + strlen(key);
844        strncpy(kvp, key, strlen(key));
845        addToCache(m, tmpReq->value, tmpReq->value, "text/xml", strlen(tmpReq->value), 
846                   filepath, FILENAME_MAX);                               
847    if (filepath == NULL) {
848        errorException( m, _("Unable to cache HTTP POST Execute request."), "InternalError", NULL); 
849                return;
850    }   
851        sprintf(tmp,"\"metapath=%s&%s&cgiSid=%s",
852                r_inputs1->value,kvp,sid->value);
853    sprintf(tmpq,"metapath=%s&%s",
854                r_inputs1->value,kvp);
855        free(kvp);             
856  }
857  else if (r_inputs2 != NULL)
[541]858    {
859      sprintf (tmp,
[587]860               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s&cgiSid=%s",
[541]861               r_inputs1->value, req->value, id->value, dataInputsKVP,
862               r_inputs2->name, dataOutputsKVP, sid->value);
863      sprintf (tmpq,
864               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s",
865               r_inputs1->value, req->value, id->value, dataInputsKVP,
[587]866               r_inputs2->name, dataOutputsKVP);                   
[541]867    }
868  else
869    {
870      sprintf (tmp,
[587]871               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&cgiSid=%s",
[541]872               r_inputs1->value, req->value, id->value, dataInputsKVP,
873               sid->value);
874      sprintf (tmpq,
875               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s",
876               r_inputs1->value, req->value, id->value, dataInputsKVP,
[587]877               sid->value);   
[541]878    }
879
880  if (hasIn > 0)
881    {
882      freeMap (&r_inputs1);
883      free (r_inputs1);
884    }
885  char *tmp1 = zStrdup (tmp);
[587]886  sprintf (tmp, "\"%s\" %s \"%s\"", PROGRAMNAME, tmp1, sid->value); 
[541]887  free (dataInputsKVP);
888  free (dataOutputsKVP);
[384]889#ifdef DEBUG
[541]890  fprintf (stderr, "REQUEST IS : %s \n", tmp);
[384]891#endif
[554]892
893  map* usid = getMapFromMaps (m, "lenv", "usid");
894  if (usid != NULL && usid->value != NULL) {
895    SetEnvironmentVariable("USID", TEXT (usid->value));
896  }
897
[541]898  SetEnvironmentVariable ("CGISID", TEXT (sid->value));
899  SetEnvironmentVariable ("QUERY_STRING", TEXT (tmpq));
[587]900  // knut: Prevent REQUEST_METHOD=POST in background process call to cgic:main (process hangs when reading cgiIn):
901  SetEnvironmentVariable("REQUEST_METHOD", "GET");
902 
[216]903  char clen[1000];
[541]904  sprintf (clen, "%d", strlen (tmpq));
905  SetEnvironmentVariable ("CONTENT_LENGTH", TEXT (clen));
906
907  if (!CreateProcess (NULL,     // No module name (use command line)
908                      TEXT (tmp),       // Command line
909                      NULL,     // Process handle not inheritable
910                      NULL,     // Thread handle not inheritable
911                      FALSE,    // Set handle inheritance to FALSE
912                      CREATE_NO_WINDOW, // Apache won't wait until the end
913                      NULL,     // Use parent's environment block
914                      NULL,     // Use parent's starting directory
915                      &si,      // Pointer to STARTUPINFO struct
916                      &pi)      // Pointer to PROCESS_INFORMATION struct
917    )
918    {
[384]919#ifdef DEBUG
[541]920      fprintf (stderr, "CreateProcess failed (%d).\n", GetLastError ());
[384]921#endif
[587]922      if (tmp != NULL) {
923        free(tmp);
924      }
925      if (tmpq != NULL) {
926        free(tmpq);
927      }         
[541]928      return;
929    }
930  else
931    {
[384]932#ifdef DEBUG
[587]933      fprintf (stderr, "CreateProcess successful (%d).\n\n\n\n",
[541]934               GetLastError ());
[384]935#endif
[541]936    }
937  CloseHandle (pi.hProcess);
938  CloseHandle (pi.hThread);
[587]939 
940  if (tmp != NULL) {
941    free(tmp);
942  }
943  if (tmpq != NULL) {
944    free(tmpq);
945  }
946 
[384]947#ifdef DEBUG
[541]948  fprintf (stderr, "CreateProcess finished !\n");
[384]949#endif
[216]950}
951#endif
952
[607]953/**
954 * Process the request.
955 *
956 * @param inputs the request parameters map
957 * @return 0 on sucess, other value on failure
958 * @see conf_read,recursReaddirF
959 */
[541]960int
961runRequest (map ** inputs)
[1]962{
[541]963
[53]964#ifndef USE_GDB
[554]965#ifndef WIN32
[541]966  signal (SIGCHLD, SIG_IGN);
[554]967#endif 
[541]968  signal (SIGSEGV, sig_handler);
969  signal (SIGTERM, sig_handler);
970  signal (SIGINT, sig_handler);
971  signal (SIGILL, sig_handler);
972  signal (SIGFPE, sig_handler);
973  signal (SIGABRT, sig_handler);
[53]974#endif
[9]975
[541]976  map *r_inputs = NULL;
977  map *request_inputs = *inputs;
[605]978#ifdef IGNORE_METAPATH
979  addToMap(request_inputs, "metapath", "");
980#endif 
[541]981  maps *m = NULL;
982  char *REQUEST = NULL;
[1]983  /**
984   * Parsing service specfic configuration file
985   */
[541]986  m = (maps *) malloc (MAPS_SIZE);
987  if (m == NULL)
988    {
989      return errorException (m, _("Unable to allocate memory."),
990                             "InternalError", NULL);
991    }
[1]992  char ntmp[1024];
993#ifndef WIN32
[541]994  getcwd (ntmp, 1024);
[1]995#else
[541]996  _getcwd (ntmp, 1024);
[1]997#endif
[541]998  r_inputs = getMapOrFill (&request_inputs, "metapath", "");
[282]999
[9]1000  char conf_file[10240];
[541]1001  snprintf (conf_file, 10240, "%s/%s/main.cfg", ntmp, r_inputs->value);
1002  if (conf_read (conf_file, m) == 2)
1003    {
1004      errorException (NULL, _("Unable to load the main.cfg file."),
1005                      "InternalError", NULL);
1006      free (m);
1007      return 1;
1008    }
[9]1009#ifdef DEBUG
[541]1010  fprintf (stderr, "***** BEGIN MAPS\n");
1011  dumpMaps (m);
1012  fprintf (stderr, "***** END MAPS\n");
[9]1013#endif
1014
[541]1015  map *getPath = getMapFromMaps (m, "main", "gettextPath");
1016  if (getPath != NULL)
1017    {
1018      bindtextdomain ("zoo-kernel", getPath->value);
1019      bindtextdomain ("zoo-services", getPath->value);
1020    }
1021  else
1022    {
1023      bindtextdomain ("zoo-kernel", "/usr/share/locale/");
1024      bindtextdomain ("zoo-services", "/usr/share/locale/");
1025    }
[364]1026
[381]1027
[364]1028  /**
1029   * Manage our own error log file (usefull to separate standard apache debug
1030   * messages from the ZOO-Kernel ones but also for IIS users to avoid wrong
1031   * headers messages returned by the CGI due to wrong redirection of stderr)
1032   */
[541]1033  FILE *fstde = NULL;
1034  map *fstdem = getMapFromMaps (m, "main", "logPath");
1035  if (fstdem != NULL)
1036    fstde = freopen (fstdem->value, "a+", stderr);
[364]1037
[541]1038  r_inputs = getMap (request_inputs, "language");
1039  if (r_inputs == NULL)
[640]1040    r_inputs = getMap (request_inputs, "AcceptLanguages");
1041  if (r_inputs == NULL)
[541]1042    r_inputs = getMapFromMaps (m, "main", "language");
1043  if (r_inputs != NULL)
1044    {
1045      if (isValidLang (m, r_inputs->value) < 0)
1046        {
1047          char tmp[1024];
1048          sprintf (tmp,
1049                   _
1050                   ("The value %s is not supported for the <language> parameter"),
1051                   r_inputs->value);
1052          errorException (m, tmp, "InvalidParameterValue", "language");
1053          freeMaps (&m);
1054          free (m);
1055          free (REQUEST);
1056          return 1;
[501]1057
[541]1058        }
1059      char *tmp = zStrdup (r_inputs->value);
1060      setMapInMaps (m, "main", "language", tmp);
[466]1061#ifdef DEB
[541]1062      char tmp2[12];
1063      sprintf (tmp2, "%s.utf-8", tmp);
1064      translateChar (tmp2, '-', '_');
1065      setlocale (LC_ALL, tmp2);
[466]1066#else
[541]1067      translateChar (tmp, '-', '_');
1068      setlocale (LC_ALL, tmp);
[466]1069#endif
[444]1070#ifndef WIN32
[541]1071      setenv ("LC_ALL", tmp, 1);
[444]1072#else
[541]1073      char tmp1[12];
1074      sprintf (tmp1, "LC_ALL=%s", tmp);
1075      putenv (tmp1);
[376]1076#endif
[541]1077      free (tmp);
1078    }
1079  else
1080    {
1081      setlocale (LC_ALL, "en_US");
[444]1082#ifndef WIN32
[541]1083      setenv ("LC_ALL", "en_US", 1);
[444]1084#else
[541]1085      char tmp1[12];
1086      sprintf (tmp1, "LC_ALL=en_US");
1087      putenv (tmp1);
[376]1088#endif
[541]1089      setMapInMaps (m, "main", "language", "en-US");
1090    }
[34]1091  setlocale (LC_NUMERIC, "en_US");
[541]1092  bind_textdomain_codeset ("zoo-kernel", "UTF-8");
1093  textdomain ("zoo-kernel");
1094  bind_textdomain_codeset ("zoo-services", "UTF-8");
1095  textdomain ("zoo-services");
[34]1096
[541]1097  map *lsoap = getMap (request_inputs, "soap");
1098  if (lsoap != NULL && strcasecmp (lsoap->value, "true") == 0)
1099    setMapInMaps (m, "main", "isSoap", "true");
[280]1100  else
[541]1101    setMapInMaps (m, "main", "isSoap", "false");
[34]1102
[584]1103  if(strlen(cgiServerName)>0)
[654]1104    {
1105      char tmpUrl[1024];
[584]1106       
[654]1107      if ( getenv("HTTPS") != NULL && strncmp(getenv("HTTPS"), "on", 2) == 0 ) { // Knut: check if non-empty instead of "on"?           
1108        if ( strncmp(cgiServerPort, "443", 3) == 0 ) { 
1109          sprintf(tmpUrl, "https://%s%s", cgiServerName, cgiScriptName);
[584]1110        }
1111        else {
[654]1112          sprintf(tmpUrl, "https://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
[584]1113        }
[654]1114      }
1115      else {
1116        if ( strncmp(cgiServerPort, "80", 2) == 0 ) { 
1117          sprintf(tmpUrl, "http://%s%s", cgiServerName, cgiScriptName);
1118        }
1119        else {
1120          sprintf(tmpUrl, "http://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1121        }
1122      }
[445]1123#ifdef DEBUG
[654]1124      fprintf(stderr,"*** %s ***\n",tmpUrl);
[445]1125#endif
[654]1126      setMapInMaps(m,"main","serverAddress",tmpUrl);
1127    }
[381]1128
[654]1129  //Check for minimum inputs
1130  map* version=getMap(request_inputs,"version");
1131  if(version==NULL)
1132    version=getMapFromMaps(m,"main","version");
1133  setMapInMaps(m,"main","rversion",version->value);
1134  int vid=getVersionId(version->value);
1135  if(vid<0)
1136    vid=0;
[576]1137  map* err=NULL;
[654]1138  const char **vvr=(const char**)requests[vid];
1139  checkValidValue(request_inputs,&err,"request",vvr,1);
[576]1140  const char *vvs[]={
1141    "WPS",
1142    NULL
1143  };
1144  if(err!=NULL){
1145    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
1146    printExceptionReportResponse (m, err);
1147    freeMap(&err);
1148    free(err);
1149    if (count (request_inputs) == 1)
1150      {
1151        freeMap (&request_inputs);
1152        free (request_inputs);
1153      }
1154    freeMaps (&m);
1155    free (m);
1156    return 1;
1157  }
1158  checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
[640]1159
[576]1160  const char *vvv[]={
1161    "1.0.0",
[640]1162    "2.0.0",
[576]1163    NULL
1164  };
[541]1165  r_inputs = getMap (request_inputs, "Request");
[576]1166  REQUEST = zStrdup (r_inputs->value);
[654]1167  int reqId=-1;
[576]1168  if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
1169    checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
[654]1170    int j=0;
1171    for(j=0;j<nbSupportedRequests;j++){
1172      if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
1173        if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(REQUEST))==0){
1174          checkValidValue(request_inputs,&err,"identifier",NULL,1);
1175          reqId=j+1;
1176          break;
1177        }
1178        else
1179          if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
1180             strncasecmp(REQUEST,requests[vid][j+1],strlen(REQUEST))==0){
1181            checkValidValue(request_inputs,&err,"jobid",NULL,1);
1182            reqId=j+1;
1183            break;
1184          }
1185      }else
1186        break;
1187    }
[576]1188  }else{
1189    checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
[658]1190    map* version1=getMap(request_inputs,"AcceptVersions");
1191    if(version1!=NULL){
1192      if(strstr(version1->value,schemas[1][0])!=NULL)
[640]1193        addToMap(request_inputs,"version",schemas[1][0]);
1194      else
[658]1195        addToMap(request_inputs,"version",version1->value);
1196      version=getMap(request_inputs,"version");
1197      setMapInMaps(m,"main","rversion",version->value);
1198      vid=getVersionId(version->value);
[640]1199    }
[576]1200  }
1201  if(err!=NULL){
1202    printExceptionReportResponse (m, err);
1203    freeMap(&err);
1204    free(err);
1205    if (count (request_inputs) == 1)
1206      {
1207        freeMap (&request_inputs);
1208        free (request_inputs);
1209      }
1210    free(REQUEST);
1211    freeMaps (&m);
1212    free (m);
1213    return 1;
1214  }
[1]1215
[541]1216  r_inputs = getMap (request_inputs, "serviceprovider");
1217  if (r_inputs == NULL)
1218    {
1219      addToMap (request_inputs, "serviceprovider", "");
1220    }
[1]1221
[541]1222  maps *request_output_real_format = NULL;
1223  map *tmpm = getMapFromMaps (m, "main", "serverAddress");
1224  if (tmpm != NULL)
1225    SERVICE_URL = zStrdup (tmpm->value);
[1]1226  else
[541]1227    SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
[1]1228
[607]1229
1230
[541]1231  service *s1;
1232  int scount = 0;
[1]1233#ifdef DEBUG
[541]1234  dumpMap (r_inputs);
[1]1235#endif
1236  char conf_dir[1024];
1237  int t;
1238  char tmps1[1024];
1239
[541]1240  r_inputs = NULL;
1241  r_inputs = getMap (request_inputs, "metapath");
[605]1242 
[541]1243  if (r_inputs != NULL)
1244    snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
[9]1245  else
[541]1246    snprintf (conf_dir, 1024, "%s", ntmp);
[9]1247
[607]1248  map* reg = getMapFromMaps (m, "main", "registry");
1249  registry* zooRegistry=NULL;
1250  if(reg!=NULL){
1251    int saved_stdout = dup (fileno (stdout));
1252    dup2 (fileno (stderr), fileno (stdout));
1253    createRegistry (m,&zooRegistry,reg->value,saved_stdout);
1254    dup2 (saved_stdout, fileno (stdout));
1255  }
1256
[541]1257  if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
1258    {
[1]1259#ifdef DEBUG
[541]1260      dumpMap (r_inputs);
[1]1261#endif
[541]1262      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
[656]1263      xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
[576]1264      /**
1265       * Here we need to close stdout to ensure that unsupported chars
1266       * has been found in the zcfg and then printed on stdout
1267       */
[541]1268      int saved_stdout = dup (fileno (stdout));
1269      dup2 (fileno (stderr), fileno (stdout));
[584]1270      if (int res =               
[607]1271          recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
[541]1272                          printGetCapabilitiesForProcess) < 0)
1273        {
1274          freeMaps (&m);
1275          free (m);
[607]1276          if(zooRegistry!=NULL){
1277            freeRegistry(&zooRegistry);
1278            free(zooRegistry);
1279          }
[541]1280          free (REQUEST);
1281          free (SERVICE_URL);
1282          fflush (stdout);
1283          return res;
1284        }
[656]1285      fflush (stdout);
[541]1286      dup2 (saved_stdout, fileno (stdout));
1287      printDocument (m, doc, getpid ());
1288      freeMaps (&m);
1289      free (m);
[607]1290      if(zooRegistry!=NULL){
1291        freeRegistry(&zooRegistry);
1292        free(zooRegistry);
1293      }
[541]1294      free (REQUEST);
1295      free (SERVICE_URL);
1296      fflush (stdout);
[9]1297      return 0;
[1]1298    }
[541]1299  else
1300    {
[654]1301      r_inputs = getMap (request_inputs, "JobId");
1302      if(reqId>nbReqIdentifier){
1303        if (strncasecmp (REQUEST, "GetStatus", strlen(REQUEST)) == 0 ||
1304            strncasecmp (REQUEST, "GetResult", strlen(REQUEST)) == 0){
1305          runGetStatus(m,r_inputs->value,REQUEST);
1306          freeMaps (&m);
1307          free (m);
[607]1308          if(zooRegistry!=NULL){
1309            freeRegistry(&zooRegistry);
1310            free(zooRegistry);
1311          }
[654]1312          free (REQUEST);
1313          free (SERVICE_URL);
1314          return 0;
1315        }
1316        else
1317          if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
1318            runDismiss(m,r_inputs->value);
1319            freeMaps (&m);
1320            free (m);
1321            if(zooRegistry!=NULL){
1322              freeRegistry(&zooRegistry);
1323              free(zooRegistry);
1324            }
1325            free (REQUEST);
1326            free (SERVICE_URL);
1327            return 0;
1328           
1329          }
1330        return 0;
1331      }
1332      if(reqId<=nbReqIdentifier){
1333        r_inputs = getMap (request_inputs, "Identifier");
[9]1334
[654]1335        struct dirent *dp;
1336        DIR *dirp = opendir (conf_dir);
1337        if (dirp == NULL)
1338          {
1339            errorException (m, _("The specified path path does not exist."),
1340                            "InvalidParameterValue", conf_dir);
1341            freeMaps (&m);
1342            free (m);
1343            if(zooRegistry!=NULL){
1344              freeRegistry(&zooRegistry);
1345              free(zooRegistry);
1346            }
1347            free (REQUEST);
1348            free (SERVICE_URL);
1349            return 0;
1350          }
1351        if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
1352          {
1353            /**
1354             * Loop over Identifier list
1355             */
1356            xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
1357            r_inputs = NULL;
1358            r_inputs = getMap (request_inputs, "version");
1359            xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
[656]1360                                          root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
[469]1361
[654]1362            r_inputs = getMap (request_inputs, "Identifier");
[503]1363
[654]1364            char *orig = zStrdup (r_inputs->value);
[541]1365
[654]1366            int saved_stdout = dup (fileno (stdout));
1367            dup2 (fileno (stderr), fileno (stdout));
1368            if (strcasecmp ("all", orig) == 0)
1369              {
1370                if (int res =
1371                    recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
1372                                    printDescribeProcessForProcess) < 0)
1373                  return res;
1374              }
1375            else
1376              {
1377                char *saveptr;
1378                char *tmps = strtok_r (orig, ",", &saveptr);
[541]1379
[654]1380                char buff[256];
1381                char buff1[1024];
1382                while (tmps != NULL)
1383                  {
1384                    int hasVal = -1;
1385                    char *corig = zStrdup (tmps);
1386                    if (strstr (corig, ".") != NULL)
1387                      {
[541]1388
[654]1389                        parseIdentifier (m, conf_dir, corig, buff1);
1390                        map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
1391                        if (tmpMap != NULL)
1392                          addToMap (request_inputs, "metapath", tmpMap->value);
1393                        map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
1394
1395                        s1 = (service *) malloc (SERVICE_SIZE);
1396                        t = readServiceFile (m, buff1, &s1, tmpMapI->value);
1397                        if (t < 0)
1398                          {
1399                            map *tmp00 = getMapFromMaps (m, "lenv", "message");
1400                            char tmp01[1024];
1401                            if (tmp00 != NULL)
1402                              sprintf (tmp01,
1403                                       _
1404                                       ("Unable to parse the ZCFG file for the following ZOO-Service: %s. Message: %s"),
1405                                       tmps, tmp00->value);
1406                            else
1407                              sprintf (tmp01,
1408                                       _
1409                                       ("Unable to parse the ZCFG file for the following ZOO-Service: %s."),
1410                                       tmps);
1411                            dup2 (saved_stdout, fileno (stdout));
1412                            errorException (m, tmp01, "InvalidParameterValue",
1413                                            "identifier");
1414                            freeMaps (&m);
1415                            free (m);
1416                            if(zooRegistry!=NULL){
1417                              freeRegistry(&zooRegistry);
1418                              free(zooRegistry);
1419                            }
1420                            free (REQUEST);
1421                            free (corig);
1422                            free (orig);
1423                            free (SERVICE_URL);
1424                            free (s1);
1425                            closedir (dirp);
1426                            xmlFreeDoc (doc);
1427                            xmlCleanupParser ();
1428                            zooXmlCleanupNs ();
1429                            return 1;
[607]1430                          }
[9]1431#ifdef DEBUG
[654]1432                        dumpService (s1);
[9]1433#endif
[654]1434                        inheritance(zooRegistry,&s1);
1435                        printDescribeProcessForProcess (m, n, s1);
1436                        freeService (&s1);
1437                        free (s1);
1438                        s1 = NULL;
1439                        scount++;
1440                        hasVal = 1;
1441                        setMapInMaps (m, "lenv", "level", "0");
1442                      }
1443                    else
1444                      {
1445                        memset (buff, 0, 256);
1446                        snprintf (buff, 256, "%s.zcfg", corig);
1447                        memset (buff1, 0, 1024);
[469]1448#ifdef DEBUG
[654]1449                        printf ("\n#######%s\n########\n", buff);
[469]1450#endif
[654]1451                        while ((dp = readdir (dirp)) != NULL)
1452                          {
1453                            if (strcasecmp (dp->d_name, buff) == 0)
1454                              {
1455                                memset (buff1, 0, 1024);
1456                                snprintf (buff1, 1024, "%s/%s", conf_dir,
1457                                          dp->d_name);
1458                                s1 = (service *) malloc (SERVICE_SIZE);
1459                                if (s1 == NULL)
1460                                  {
1461                                    dup2 (saved_stdout, fileno (stdout));
1462                                    return errorException (m,
1463                                                           _
1464                                                           ("Unable to allocate memory."),
1465                                                           "InternalError",
1466                                                           NULL);
1467                                  }
[469]1468#ifdef DEBUG
[654]1469                                printf
1470                                  ("#################\n(%s) %s\n#################\n",
1471                                   r_inputs->value, buff1);
[469]1472#endif
[654]1473                                char *tmp0 = zStrdup (dp->d_name);
1474                                tmp0[strlen (tmp0) - 5] = 0;
1475                                t = readServiceFile (m, buff1, &s1, tmp0);
1476                                free (tmp0);
1477                                if (t < 0)
1478                                  {
1479                                    map *tmp00 =
1480                                      getMapFromMaps (m, "lenv", "message");
1481                                    char tmp01[1024];
1482                                    if (tmp00 != NULL)
1483                                      sprintf (tmp01,
1484                                               _
1485                                               ("Unable to parse the ZCFG file: %s (%s)"),
1486                                               dp->d_name, tmp00->value);
1487                                    else
1488                                      sprintf (tmp01,
1489                                               _
1490                                               ("Unable to parse the ZCFG file: %s."),
1491                                               dp->d_name);
1492                                    dup2 (saved_stdout, fileno (stdout));
1493                                    errorException (m, tmp01, "InternalError",
1494                                                    NULL);
1495                                    freeMaps (&m);
1496                                    free (m);
1497                                    if(zooRegistry!=NULL){
1498                                      freeRegistry(&zooRegistry);
1499                                      free(zooRegistry);
1500                                    }
1501                                    free (orig);
1502                                    free (REQUEST);
1503                                    closedir (dirp);
1504                                    xmlFreeDoc (doc);
1505                                    xmlCleanupParser ();
1506                                    zooXmlCleanupNs ();
1507                                    return 1;
[607]1508                                  }
[469]1509#ifdef DEBUG
[654]1510                                dumpService (s1);
[469]1511#endif
[654]1512                                inheritance(zooRegistry,&s1);
1513                                printDescribeProcessForProcess (m, n, s1);
1514                                freeService (&s1);
1515                                free (s1);
1516                                s1 = NULL;
1517                                scount++;
1518                                hasVal = 1;
1519                              }
1520                          }
[607]1521                      }
[654]1522                    if (hasVal < 0)
1523                      {
1524                        map *tmp00 = getMapFromMaps (m, "lenv", "message");
1525                        char tmp01[1024];
1526                        if (tmp00 != NULL)
1527                          sprintf (tmp01,
1528                                   _("Unable to parse the ZCFG file: %s (%s)"),
1529                                   buff, tmp00->value);
1530                        else
1531                          sprintf (tmp01,
1532                                   _("Unable to parse the ZCFG file: %s."),
1533                                   buff);
1534                        dup2 (saved_stdout, fileno (stdout));
1535                        errorException (m, tmp01, "InvalidParameterValue",
1536                                        "Identifier");
1537                        freeMaps (&m);
1538                        free (m);
1539                        if(zooRegistry!=NULL){
1540                          freeRegistry(&zooRegistry);
1541                          free(zooRegistry);
1542                        }
1543                        free (orig);
1544                        free (REQUEST);
1545                        closedir (dirp);
1546                        xmlFreeDoc (doc);
1547                        xmlCleanupParser ();
1548                        zooXmlCleanupNs ();
1549                        return 1;
1550                      }
1551                    rewinddir (dirp);
1552                    tmps = strtok_r (NULL, ",", &saveptr);
1553                    if (corig != NULL)
1554                      free (corig);
1555                  }
1556              }
1557            closedir (dirp);
1558            fflush (stdout);
1559            dup2 (saved_stdout, fileno (stdout));
1560            free (orig);
1561            printDocument (m, doc, getpid ());
1562            freeMaps (&m);
1563            free (m);
1564            if(zooRegistry!=NULL){
1565              freeRegistry(&zooRegistry);
1566              free(zooRegistry);
1567            }
1568            free (REQUEST);
1569            free (SERVICE_URL);
1570            fflush (stdout);
1571            return 0;
[607]1572          }
[654]1573        else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
1574          {
1575            map* version=getMapFromMaps(m,"main","rversion");
1576            int vid=getVersionId(version->value);
1577            int len,j=0;
1578            for(j=0;j<nbSupportedRequests;j++){
1579              if(requests[vid][j]!=NULL)
1580                len+=strlen(requests[vid][j])+2;
1581              else{
1582                len+=4;
1583                break;
1584              }
1585            }
1586            char *tmpStr=(char*)malloc(len*sizeof(char));
1587            int it=0;
1588            for(j=0;j<nbSupportedRequests;j++){
1589              if(requests[vid][j]!=NULL){
1590                if(it==0){
1591                  sprintf(tmpStr,"%s",requests[vid][j]);
1592                  it++;
1593                }else{
1594                  char *tmpS=zStrdup(tmpStr);
1595                  if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
1596                    sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
1597                  }else{
1598                    sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
1599                 
1600                  }
1601                  free(tmpS);
1602                }
1603              }
1604              else{
1605                len+=4;
1606                break;
1607              }
1608            }
1609            char* message=(char*)malloc((61+len)*sizeof(char));
1610            sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
1611            errorException (m,_(message),"InvalidParameterValue", "request");
[541]1612#ifdef DEBUG
[654]1613            fprintf (stderr, "No request found %s", REQUEST);
[541]1614#endif
[654]1615            closedir (dirp);
1616            freeMaps (&m);
1617            free (m);
1618            if(zooRegistry!=NULL){
1619              freeRegistry(&zooRegistry);
1620              free(zooRegistry);
1621            }
1622            free (REQUEST);
1623            free (SERVICE_URL);
1624            fflush (stdout);
1625            return 0;
[607]1626          }
[654]1627        closedir (dirp);
1628      }
[1]1629    }
[541]1630
[654]1631  map *postRequest = NULL;
1632  postRequest = getMap (request_inputs, "xrequest");
1633
1634  if(vid==1 && postRequest==NULL){
1635    errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request"); 
1636    freeMaps (&m);
1637    free (m);
1638    if(zooRegistry!=NULL){
1639      freeRegistry(&zooRegistry);
1640      free(zooRegistry);
1641    }
1642    free (REQUEST);
1643    free (SERVICE_URL);
1644    fflush (stdout);
1645    return 0;
1646  }
1647 
[541]1648  s1 = NULL;
1649  s1 = (service *) malloc (SERVICE_SIZE);
1650  if (s1 == NULL)
1651    {
1652      freeMaps (&m);
1653      free (m);
[607]1654      if(zooRegistry!=NULL){
1655        freeRegistry(&zooRegistry);
1656        free(zooRegistry);
1657      }
[541]1658      free (REQUEST);
1659      free (SERVICE_URL);
1660      return errorException (m, _("Unable to allocate memory."),
1661                             "InternalError", NULL);
1662    }
[587]1663
[541]1664  r_inputs = getMap (request_inputs, "MetaPath");
1665  if (r_inputs != NULL)
1666    snprintf (tmps1, 1024, "%s/%s", ntmp, r_inputs->value);
[9]1667  else
[541]1668    snprintf (tmps1, 1024, "%s/", ntmp);
1669  r_inputs = getMap (request_inputs, "Identifier");
1670  char *ttmp = zStrdup (tmps1);
1671  snprintf (tmps1, 1024, "%s/%s.zcfg", ttmp, r_inputs->value);
1672  free (ttmp);
[1]1673#ifdef DEBUG
[541]1674  fprintf (stderr, "Trying to load %s\n", tmps1);
[1]1675#endif
[541]1676  if (strstr (r_inputs->value, ".") != NULL)
1677    {
1678      char *identifier = zStrdup (r_inputs->value);
1679      parseIdentifier (m, conf_dir, identifier, tmps1);
1680      map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
1681      if (tmpMap != NULL)
1682        addToMap (request_inputs, "metapath", tmpMap->value);
1683      free (identifier);
1684    }
1685  else
1686    {
1687      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
1688      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
1689    }
[539]1690
[541]1691  r_inputs = getMapFromMaps (m, "lenv", "Identifier");
1692  int saved_stdout = dup (fileno (stdout));
1693  dup2 (fileno (stderr), fileno (stdout));
1694  t = readServiceFile (m, tmps1, &s1, r_inputs->value);
[607]1695  inheritance(zooRegistry,&s1);
1696  if(zooRegistry!=NULL){
1697    freeRegistry(&zooRegistry);
1698    free(zooRegistry);
1699  }
[541]1700  fflush (stdout);
1701  dup2 (saved_stdout, fileno (stdout));
1702  if (t < 0)
1703    {
1704      char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
1705      sprintf (tmpMsg,
1706               _
[605]1707               ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
[541]1708               r_inputs->value);
1709      errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
1710      free (tmpMsg);
1711      free (s1);
1712      freeMaps (&m);
1713      free (m);
1714      free (REQUEST);
1715      free (SERVICE_URL);
1716      return 0;
1717    }
1718  close (saved_stdout);
[1]1719
1720#ifdef DEBUG
[541]1721  dumpService (s1);
[1]1722#endif
1723  int j;
[381]1724
[541]1725
[1]1726  /**
[344]1727   * Create the input and output maps data structure
[1]1728   */
[541]1729  int i = 0;
[1]1730  HINTERNET hInternet;
1731  HINTERNET res;
[541]1732  hInternet = InternetOpen (
[1]1733#ifndef WIN32
[654]1734                            (LPCTSTR)
[1]1735#endif
[654]1736                            "ZooWPSClient\0",
1737                            INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
[1]1738
1739#ifndef WIN32
[541]1740  if (!CHECK_INET_HANDLE (hInternet))
1741    fprintf (stderr, "WARNING : hInternet handle failed to initialize");
[1]1742#endif
[541]1743  maps *request_input_real_format = NULL;
1744  maps *tmpmaps = request_input_real_format;
1745
1746
[621]1747  if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
1748    freeMaps (&m);
1749    free (m);
1750    free (REQUEST);
1751    free (SERVICE_URL);
1752    InternetCloseHandle (&hInternet);
1753    freeService (&s1);
1754    free (s1);
1755    return 0;
1756  }
[1]1757
[652]1758
1759  // Define each env variable in runing environment
[541]1760  maps *curs = getMaps (m, "env");
1761  if (curs != NULL)
1762    {
1763      map *mapcs = curs->content;
1764      while (mapcs != NULLMAP)
1765        {
[1]1766#ifndef WIN32
[541]1767          setenv (mapcs->name, mapcs->value, 1);
[1]1768#else
1769#ifdef DEBUG
[541]1770          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
1771                   mapcs->value);
[1]1772#endif
[541]1773          if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
1774            {
[1]1775#ifdef DEBUG
[541]1776              fprintf (stderr, "[ZOO: Env var finish with \r]\n");
[1]1777#endif
[541]1778              mapcs->value[strlen (mapcs->value) - 1] = 0;
1779            }
[1]1780#ifdef DEBUG
[541]1781          if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
1782            {
1783              fflush (stderr);
1784              fprintf (stderr, "setting variable... %s\n", "OK");
1785            }
1786          else
1787            {
1788              fflush (stderr);
1789              fprintf (stderr, "setting variable... %s\n", "OK");
1790            }
[1]1791#else
[541]1792
1793
1794          SetEnvironmentVariable (mapcs->name, mapcs->value);
[1]1795#endif
[541]1796          char *toto =
1797            (char *)
1798            malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
1799                     2) * sizeof (char));
1800          sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
1801          putenv (toto);
[1]1802#ifdef DEBUG
[541]1803          fflush (stderr);
[1]1804#endif
1805#endif
1806#ifdef DEBUG
[541]1807          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
1808                   mapcs->value);
1809          fflush (stderr);
[1]1810#endif
[541]1811          mapcs = mapcs->next;
1812        }
[1]1813    }
[541]1814
[1]1815#ifdef DEBUG
[541]1816  dumpMap (request_inputs);
[1]1817#endif
1818
[541]1819  map *status = getMap (request_inputs, "status");
[654]1820  if(vid==0){
1821    // Need to check if we need to fork to load a status enabled
1822    r_inputs = NULL;
1823    map *store = getMap (request_inputs, "storeExecuteResponse");
1824    /**
1825     * 05-007r7 WPS 1.0.0 page 57 :
1826     * 'If status="true" and storeExecuteResponse is "false" then the service
1827     * shall raise an exception.'
1828     */
1829    if (status != NULL && strcmp (status->value, "true") == 0 &&
1830        store != NULL && strcmp (store->value, "false") == 0)
1831      {
1832        errorException (m,
1833                        _
1834                        ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
1835                        "InvalidParameterValue", "storeExecuteResponse");
1836        freeService (&s1);
1837        free (s1);
1838        freeMaps (&m);
1839        free (m);
1840       
1841        freeMaps (&request_input_real_format);
1842        free (request_input_real_format);
1843       
1844        freeMaps (&request_output_real_format);
1845        free (request_output_real_format);
[94]1846
[654]1847        free (REQUEST);
1848        free (SERVICE_URL);
1849        return 1;
1850      }
1851    r_inputs = getMap (request_inputs, "storeExecuteResponse");
1852  }else{
1853    // Define status depending on the WPS 2.0.0 mode attribute
1854    status = getMap (request_inputs, "mode");
1855    map* mode=getMap(s1->content,"mode");
1856    if(strcasecmp(status->value,"async")==0){
1857      if(mode!=NULL && strcasecmp(mode->value,"async")==0)
1858        addToMap(request_inputs,"status","true");
1859      else{
1860        if(mode!=NULL){
1861          // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
1862          errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value); 
1863          fflush (stdout);
1864          freeMaps (&m);
1865          free (m);
1866          if(zooRegistry!=NULL){
1867            freeRegistry(&zooRegistry);
1868            free(zooRegistry);
1869          }
1870          freeMaps (&request_input_real_format);
1871          free (request_input_real_format);
1872          freeMaps (&request_output_real_format);
1873          free (request_output_real_format);
1874          free (REQUEST);
1875          free (SERVICE_URL);
1876          return 0;
1877        }else
1878          addToMap(request_inputs,"status","true");
1879      }
1880    }
1881    else{
1882      if(strcasecmp(status->value,"auto")==0){
1883        if(mode!=NULL){
1884          if(strcasecmp(mode->value,"async")==0)
1885            addToMap(request_inputs,"status","false");
1886          else
1887            addToMap(request_inputs,"status","true");
1888        }
1889        else
1890          addToMap(request_inputs,"status","false");
1891      }else
1892        addToMap(request_inputs,"status","false");
1893    }
1894    status = getMap (request_inputs, "status");
1895  }
[541]1896
1897  int eres = SERVICE_STARTED;
1898  int cpid = getpid ();
1899
[453]1900  /**
1901   * Initialize the specific [lenv] section which contains runtime variables:
1902   *
1903   *  - usid : it is an unique identification number
1904   *  - sid : it is the process idenfitication number (OS)
[640]1905   *  - uusid : it is an universally unique identification number
[453]1906   *  - status : value between 0 and 100 to express the  completude of
1907   * the operations of the running service
1908   *  - message : is a string where you can store error messages, in case
1909   * service is failing, or o provide details on the ongoing operation.
1910   *  - cwd : is the current working directory
1911   *  - soap : is a boolean value, true if the request was contained in a SOAP
1912   * Envelop
1913   *  - sessid : string storing the session identifier (only when cookie is
1914   * used)
1915   *  - cgiSid : only defined on Window platforms (for being able to identify
1916   * the created process)
1917   *
1918   */
[541]1919  maps *_tmpMaps = (maps *) malloc (MAPS_SIZE);
1920  _tmpMaps->name = zStrdup ("lenv");
[32]1921  char tmpBuff[100];
[514]1922  struct ztimeval tp;
[541]1923  if (zGettimeofday (&tp, NULL) == 0)
1924    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
[514]1925  else
[541]1926    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
[652]1927  _tmpMaps->content = createMap ("osid", tmpBuff);
[541]1928  _tmpMaps->next = NULL;
1929  sprintf (tmpBuff, "%i", cpid);
1930  addToMap (_tmpMaps->content, "sid", tmpBuff);
[640]1931  char* tmpUuid=get_uuid();
1932  addToMap (_tmpMaps->content, "uusid", tmpUuid);
[652]1933  addToMap (_tmpMaps->content, "usid", tmpUuid);
[640]1934  free(tmpUuid);
[541]1935  addToMap (_tmpMaps->content, "status", "0");
1936  addToMap (_tmpMaps->content, "cwd", ntmp);
1937  addToMap (_tmpMaps->content, "message", _("No message provided"));
1938  map *ltmp = getMap (request_inputs, "soap");
1939  if (ltmp != NULL)
1940    addToMap (_tmpMaps->content, "soap", ltmp->value);
[280]1941  else
[541]1942    addToMap (_tmpMaps->content, "soap", "false");
[654]1943
1944  // Parse the session file and add it to the main maps
[541]1945  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
1946    {
1947      int hasValidCookie = -1;
1948      char *tcook = zStrdup (cgiCookie);
1949      char *tmp = NULL;
1950      map *testing = getMapFromMaps (m, "main", "cookiePrefix");
1951      if (testing == NULL)
1952        {
1953          tmp = zStrdup ("ID=");
1954        }
[390]1955      else
[541]1956        {
1957          tmp =
1958            (char *) malloc ((strlen (testing->value) + 2) * sizeof (char));
1959          sprintf (tmp, "%s=", testing->value);
1960        }
1961      if (strstr (cgiCookie, ";") != NULL)
1962        {
1963          char *token, *saveptr;
1964          token = strtok_r (cgiCookie, ";", &saveptr);
1965          while (token != NULL)
1966            {
1967              if (strcasestr (token, tmp) != NULL)
1968                {
1969                  if (tcook != NULL)
1970                    free (tcook);
1971                  tcook = zStrdup (token);
1972                  hasValidCookie = 1;
1973                }
1974              token = strtok_r (NULL, ";", &saveptr);
1975            }
1976        }
1977      else
1978        {
1979          if (strstr (cgiCookie, "=") != NULL
1980              && strcasestr (cgiCookie, tmp) != NULL)
1981            {
1982              tcook = zStrdup (cgiCookie);
1983              hasValidCookie = 1;
1984            }
1985          if (tmp != NULL)
1986            {
1987              free (tmp);
1988            }
1989        }
1990      if (hasValidCookie > 0)
1991        {
1992          addToMap (_tmpMaps->content, "sessid", strstr (tcook, "=") + 1);
1993          char session_file_path[1024];
1994          map *tmpPath = getMapFromMaps (m, "main", "sessPath");
1995          if (tmpPath == NULL)
1996            tmpPath = getMapFromMaps (m, "main", "tmpPath");
1997          char *tmp1 = strtok (tcook, ";");
1998          if (tmp1 != NULL)
1999            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
2000                     strstr (tmp1, "=") + 1);
2001          else
2002            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
2003                     strstr (cgiCookie, "=") + 1);
2004          free (tcook);
2005          maps *tmpSess = (maps *) malloc (MAPS_SIZE);
2006          struct stat file_status;
2007          int istat = stat (session_file_path, &file_status);
2008          if (istat == 0 && file_status.st_size > 0)
2009            {
2010              conf_read (session_file_path, tmpSess);
2011              addMapsToMaps (&m, tmpSess);
2012              freeMaps (&tmpSess);
2013              free (tmpSess);
2014            }
2015        }
[92]2016    }
[541]2017  addMapsToMaps (&m, _tmpMaps);
2018  freeMaps (&_tmpMaps);
2019  free (_tmpMaps);
[654]2020  maps* bmap=NULL;
[1]2021#ifdef DEBUG
[541]2022  dumpMap (request_inputs);
[1]2023#endif
[216]2024#ifdef WIN32
[541]2025  char *cgiSidL = NULL;
2026  if (getenv ("CGISID") != NULL)
2027    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
[554]2028
2029  char* usidp;
2030  if ( (usidp = getenv("USID")) != NULL ) {
2031    setMapInMaps (m, "lenv", "usid", usidp);
2032  }
2033
[541]2034  map *test1 = getMap (request_inputs, "cgiSid");
2035  if (test1 != NULL)
2036    {
2037      cgiSid = test1->value;
2038      addToMap (request_inputs, "storeExecuteResponse", "true");
2039      addToMap (request_inputs, "status", "true");
2040      setMapInMaps (m, "lenv", "sid", test1->value);
2041      status = getMap (request_inputs, "status");
2042    }
[216]2043#endif
[654]2044  char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
[541]2045  FILE *f0, *f1;
2046  if (status != NULL)
2047    if (strcasecmp (status->value, "false") == 0)
2048      status = NULLMAP;
2049  if (status == NULLMAP)
2050    {
[621]2051      if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
2052        freeService (&s1);
2053        free (s1);
2054        freeMaps (&m);
2055        free (m);
2056        free (REQUEST);
2057        free (SERVICE_URL);
2058        freeMaps (&request_input_real_format);
2059        free (request_input_real_format);
2060        freeMaps (&request_output_real_format);
2061        free (request_output_real_format);
2062        freeMaps (&tmpmaps);
2063        free (tmpmaps);
2064        return -1;
2065      }
2066
[541]2067      loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
2068                         &request_output_real_format, &eres);
2069    }
2070  else
2071    {
2072      int pid;
[1]2073#ifdef DEBUG
[541]2074      fprintf (stderr, "\nPID : %d\n", cpid);
[1]2075#endif
[9]2076
[1]2077#ifndef WIN32
[541]2078      pid = fork ();
[1]2079#else
[541]2080      if (cgiSid == NULL)
2081        {
2082          createProcess (m, request_inputs, s1, NULL, cpid,
2083                         request_input_real_format,
2084                         request_output_real_format);
2085          pid = cpid;
2086        }
2087      else
2088        {
2089          pid = 0;
2090          cpid = atoi (cgiSid);
2091        }
[1]2092#endif
[541]2093      if (pid > 0)
2094        {
[654]2095          /**
2096           * dady :
2097           * set status to SERVICE_ACCEPTED
2098           */
[1]2099#ifdef DEBUG
[541]2100          fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
2101                   getpid ());
[1]2102#endif
[541]2103          eres = SERVICE_ACCEPTED;
2104        }
2105      else if (pid == 0)
2106        {
[621]2107          /**
2108           * son : have to close the stdout, stdin and stderr to let the parent
2109           * process answer to http client.
2110           */
[652]2111          map* usid = getMapFromMaps (m, "lenv", "uusid");
[654]2112          map* tmpm = getMapFromMaps (m, "lenv", "osid");
2113          int cpid = atoi (tmpm->value);
[541]2114          r_inputs = getMapFromMaps (m, "main", "tmpPath");
[652]2115          map* r_inputs1 = createMap("ServiceName", s1->name);
[605]2116
[654]2117          // Create the filename for the result file (.res)
2118          fbkpres =
2119            (char *)
2120            malloc ((strlen (r_inputs->value) +
2121                     strlen (usid->value) + 7) * sizeof (char));
2122          sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
2123          bmap = (maps *) malloc (MAPS_SIZE);
2124          bmap->name=zStrdup("status");
2125          bmap->content=createMap("usid",usid->value);
2126          bmap->next=NULL;
2127          addToMap(bmap->content,"sid",tmpm->value);
2128          addIntToMap(bmap->content,"pid",getpid());
2129         
[652]2130          // Create PID file referencing the OS process identifier
2131          fbkpid =
2132            (char *)
2133            malloc ((strlen (r_inputs->value) +
2134                     strlen (usid->value) + 7) * sizeof (char));
2135          sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
2136
2137          f0 = freopen (fbkpid, "w+", stdout);
2138          fprintf(stdout,"%d",getpid());
2139          fflush(stdout);
2140
2141          // Create SID file referencing the semaphore name
[541]2142          fbkp =
2143            (char *)
2144            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
[652]2145                     strlen (usid->value) + 7) * sizeof (char));
2146          sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
2147
2148          FILE* f2 = fopen (fbkp, "w+");
2149          fprintf(f2,"%s",tmpm->value);
2150          fflush(f2);
2151          fclose(f2);
2152          free(fbkp);
2153
2154          fbkp =
[541]2155            (char *)
2156            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
[652]2157                     strlen (usid->value) + 7) * sizeof (char));
2158          sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
2159                   usid->value);
2160          flog =
2161            (char *)
2162            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
2163                     strlen (usid->value) + 13) * sizeof (char));
2164          sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
2165                   r_inputs1->value, usid->value);
[1]2166#ifdef DEBUG
[541]2167          fprintf (stderr, "RUN IN BACKGROUND MODE \n");
2168          fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
2169                   getpid ());
2170          fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
[1]2171#endif
[541]2172          freopen (flog, "w+", stderr);
2173          fflush (stderr);
[654]2174          f0 = freopen (fbkp, "w+", stdout);
2175          rewind (stdout);
[458]2176#ifndef WIN32
[654]2177          fclose (stdin);
[458]2178#endif
[631]2179
[652]2180#ifdef RELY_ON_DB
2181          init_sql(m);
2182          recordServiceStatus(m);
2183#endif
[654]2184          if(vid==0){
2185            /**
2186             * set status to SERVICE_STARTED and flush stdout to ensure full
2187             * content was outputed (the file used to store the ResponseDocument).
2188             * The rewind stdout to restart writing from the bgining of the file,
2189             * this way the data will be updated at the end of the process run.
2190             */
2191            printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
2192                                  SERVICE_STARTED, request_input_real_format,
2193                                  request_output_real_format);
2194            fflush (stdout);
2195#ifdef RELY_ON_DB
2196            recordResponse(m,fbkp);
2197#endif
2198          }
2199
[631]2200          fflush (stderr);
[654]2201
[631]2202          fbkp1 =
2203            (char *)
2204            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
[652]2205                     strlen (usid->value) + 13) * sizeof (char));
2206          sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
2207                   r_inputs1->value, usid->value);
[631]2208
2209          f1 = freopen (fbkp1, "w+", stdout);
2210
[621]2211          if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
2212            freeService (&s1);
2213            free (s1);
2214            freeMaps (&m);
2215            free (m);
2216            free (REQUEST);
2217            free (SERVICE_URL);
2218            freeMaps (&request_input_real_format);
2219            free (request_input_real_format);
2220            freeMaps (&request_output_real_format);
2221            free (request_output_real_format);
2222            freeMaps (&tmpmaps);
2223            free (tmpmaps);
2224            fflush (stdout);
2225            fflush (stderr);
[652]2226            unhandleStatus (m);
[621]2227            return -1;
2228          }
[541]2229          loadServiceAndRun (&m, s1, request_inputs,
2230                             &request_input_real_format,
2231                             &request_output_real_format, &eres);
[631]2232
[541]2233        }
2234      else
2235        {
[652]2236          /**
2237           * error server don't accept the process need to output a valid
2238           * error response here !!!
2239           */
[541]2240          eres = -1;
2241          errorException (m, _("Unable to run the child process properly"),
2242                          "InternalError", NULL);
2243        }
[1]2244    }
2245
2246#ifdef DEBUG
[541]2247  dumpMaps (request_output_real_format);
[1]2248#endif
[541]2249  if (eres != -1)
2250    outputResponse (s1, request_input_real_format,
2251                    request_output_real_format, request_inputs,
2252                    cpid, m, eres);
2253  fflush (stdout);
[605]2254 
[105]2255  /**
2256   * Ensure that if error occurs when freeing memory, no signal will return
2257   * an ExceptionReport document as the result was already returned to the
2258   * client.
2259   */
2260#ifndef USE_GDB
[541]2261  signal (SIGSEGV, donothing);
2262  signal (SIGTERM, donothing);
2263  signal (SIGINT, donothing);
2264  signal (SIGILL, donothing);
2265  signal (SIGFPE, donothing);
2266  signal (SIGABRT, donothing);
[105]2267#endif
[541]2268  if (((int) getpid ()) != cpid || cgiSid != NULL)
2269    {
2270      fclose (stdout);
[654]2271      //fclose (stderr);
[652]2272      /**
2273       * Dump back the final file fbkp1 to fbkp
2274       */
[541]2275      fclose (f0);
2276      fclose (f1);
[654]2277
[541]2278      FILE *f2 = fopen (fbkp1, "rb");
[652]2279#ifndef RELY_ON_DB
[541]2280      semid lid = getShmLockId (m, 1);
2281      if (lid < 0)
2282        return -1;
2283      lockShm (lid);
[652]2284#endif
[654]2285      fclose(f0);
[541]2286      FILE *f3 = fopen (fbkp, "wb+");
2287      free (fbkp);
2288      fseek (f2, 0, SEEK_END);
2289      long flen = ftell (f2);
2290      fseek (f2, 0, SEEK_SET);
2291      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
2292      fread (tmps1, flen, 1, f2);
2293      fwrite (tmps1, 1, flen, f3);
2294      fclose (f2);
2295      fclose (f3);
[652]2296      unlink (fbkpid);
[654]2297      switch(eres){
2298      default:
2299      case SERVICE_FAILED:
2300        setMapInMaps(bmap,"status","status",wpsStatus[1]);
2301        setMapInMaps(m,"lenv","fstate",wpsStatus[1]);
2302        break;
2303      case SERVICE_SUCCEEDED:
2304        setMapInMaps(bmap,"status","status",wpsStatus[0]);
2305        setMapInMaps(m,"lenv","fstate",wpsStatus[0]);
2306        break;
2307      }
[652]2308#ifndef RELY_ON_DB
[654]2309      dumpMapsToFile(bmap,fbkpres);
[652]2310      removeShmLock (m, 1);
2311#else
2312      recordResponse(m,fbkp1);
2313#endif
[654]2314      freeMaps(&bmap);
2315      free(bmap);
[541]2316      unlink (fbkp1);
[652]2317      unlink (flog);
2318      unhandleStatus (m);
2319      free(fbkpid);
[654]2320      free(fbkpres);
[652]2321      free (flog);
[541]2322      free (fbkp1);
2323      free (tmps1);
2324    }
[32]2325
[541]2326  freeService (&s1);
2327  free (s1);
2328  freeMaps (&m);
2329  free (m);
2330
2331  freeMaps (&request_input_real_format);
2332  free (request_input_real_format);
2333
2334  freeMaps (&request_output_real_format);
2335  free (request_output_real_format);
2336
2337  free (REQUEST);
2338  free (SERVICE_URL);
[1]2339#ifdef DEBUG
[541]2340  fprintf (stderr, "Processed response \n");
2341  fflush (stdout);
2342  fflush (stderr);
[1]2343#endif
2344
[541]2345  if (((int) getpid ()) != cpid || cgiSid != NULL)
2346    {
2347      exit (0);
2348    }
[516]2349
[1]2350  return 0;
2351}
Note: See TracBrowser for help on using the repository browser.

Search

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