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

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

Add support for nested inputs and outputs.

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