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

Last change on this file since 781 was 781, checked in by djay, 4 years ago

Fix issue #140

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