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

Last change on this file since 760 was 752, checked in by djay, 8 years ago

Add optional CORS support. Fix issue when dealing with Array in JavaScript? support.

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