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

Last change on this file since 682 was 682, checked in by djay, 9 years ago

Fix GetResult? and POST asynchronous requests on Windows. Prevent CONTENT_TYPE=text/xml before creating the process using CreateProcess?. Revert modifications made r587 for using url_decode directly inside zoo_loader.c, the url_decode call should be in kvpParseInputs (from request_parser.c), indeed, there should not be any decoding required in other cases than Execute requests. Fix issue in mapsFromPyDict, small changes in mapFromPyDict to fix parsing result value (only) for Python 3.

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