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

Last change on this file since 914 was 889, checked in by knut, 6 years ago

Added some new logging functionality (function logMessage(), macros zooLog, zooLogMsg). Added utility functions setErrorMessage(), hasvalue(), and nonempty() in service.c. Added enum WPSException and arrays WPSExceptionText and WPSExceptionCode (see also function setErrorMessage). New conditional definition of type bool in service.c (to fix issue with bool). Null pointer check in function addToMap. Added missing return values and explicit type casts in some functions. Removed Windows-specific code in function dumpBackFinalFile (zoo_service_loader.c) that may cause error for async raw data output in formats other than XML.

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