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

Last change on this file since 787 was 784, checked in by djay, 10 years ago

Give the capability to store the main.cfg file in sysconfdir and the services in servicePath if defined in the [main] section.

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