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

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

Fixes for supporting properly the memory=protect which force the ZOO-Kernel to not store any downloaded files in memory. Add footer to the HPC support. Fix the autotools to build service_json and sshapi only when required so, when HPC support is activated, this also avoid adding too much dependencies at compilation time. Store md5 of the downloaded files to avoid uploading on HPC server the same file more than once, in case the md5 correspond.

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