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

Last change on this file since 839 was 839, checked in by djay, 7 years ago

Update the source code for HPC support. Automatically adding nested outputs for the HPC support (should this be available for every support?). Add capability to store the metadata in the Collection DataBase?. Addition of the zcfg2sql to import any existing ZCFG file into the Collection DB. Add the support to invoke a callback (for history purpose) in case a [callback] section contains at least one parameter defined (url). Add support to convert maps and map to JSON (for callback use only by now). Fix some memory leaks (some are still there).

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