source: branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c @ 880

Last change on this file since 880 was 880, checked in by djay, 6 years ago

Modify memory configuration option gesture. Now, in case you don't have setup memory option in the main section your main.cfg file then, the ZOO-Kernel will load everything in memory and will also store the file containing the input. In case you want the old mode, you have to set memory option to 'load' in your main.cfg file. Fix issue with loading R ZOO-Service located in a subdirectory. Support for XML Execute request containing TEXT_NODE when CDATA_NODE should be used.

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