source: branches/branch-1.5/zoo-project/zoo-kernel/zoo_service_loader.c @ 973

Last change on this file since 973 was 725, checked in by djay, 10 years ago

Fix issue with rst files displayed from Trac. Fix strings to be translated. Always use the same string in all messages.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 62.6 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[12];
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[12];
976      sprintf (tmp1, "LC_ALL=en_US");
977      putenv (tmp1);
978#endif
979      setMapInMaps (m, "main", "language", "en-US");
980    }
981  setlocale (LC_NUMERIC, "en_US");
982  bind_textdomain_codeset ("zoo-kernel", "UTF-8");
983  textdomain ("zoo-kernel");
984  bind_textdomain_codeset ("zoo-services", "UTF-8");
985  textdomain ("zoo-services");
986
987  map *lsoap = getMap (request_inputs, "soap");
988  if (lsoap != NULL && strcasecmp (lsoap->value, "true") == 0)
989    setMapInMaps (m, "main", "isSoap", "true");
990  else
991    setMapInMaps (m, "main", "isSoap", "false");
992
993  if(strlen(cgiServerName)>0)
994    {
995      char tmpUrl[1024];
996       
997      if ( getenv("HTTPS") != NULL && strncmp(getenv("HTTPS"), "on", 2) == 0 ) {
998        // Knut: check if non-empty instead of "on"?           
999        if ( strncmp(cgiServerPort, "443", 3) == 0 ) { 
1000          sprintf(tmpUrl, "https://%s%s", cgiServerName, cgiScriptName);
1001        }
1002        else {
1003          sprintf(tmpUrl, "https://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1004        }
1005      }
1006      else {
1007        if ( strncmp(cgiServerPort, "80", 2) == 0 ) { 
1008          sprintf(tmpUrl, "http://%s%s", cgiServerName, cgiScriptName);
1009        }
1010        else {
1011          sprintf(tmpUrl, "http://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1012        }
1013      }
1014#ifdef DEBUG
1015      fprintf(stderr,"*** %s ***\n",tmpUrl);
1016#endif
1017      setMapInMaps(m,"main","serverAddress",tmpUrl);
1018    }
1019
1020  //Check for minimum inputs
1021  map* version=getMap(request_inputs,"version");
1022  if(version==NULL)
1023    version=getMapFromMaps(m,"main","version");
1024  setMapInMaps(m,"main","rversion",version->value);
1025  int vid=getVersionId(version->value);
1026  if(vid<0)
1027    vid=0;
1028  map* err=NULL;
1029  const char **vvr=(const char**)requests[vid];
1030  checkValidValue(request_inputs,&err,"request",vvr,1);
1031  const char *vvs[]={
1032    "WPS",
1033    NULL
1034  };
1035  if(err!=NULL){
1036    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
1037    printExceptionReportResponse (m, err);
1038    freeMap(&err);
1039    free(err);
1040    if (count (request_inputs) == 1)
1041      {
1042        freeMap (&request_inputs);
1043        free (request_inputs);
1044      }
1045    freeMaps (&m);
1046    free (m);
1047    return 1;
1048  }
1049  checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
1050
1051  const char *vvv[]={
1052    "1.0.0",
1053    "2.0.0",
1054    NULL
1055  };
1056  r_inputs = getMap (request_inputs, "Request");
1057  REQUEST = zStrdup (r_inputs->value);
1058  int reqId=-1;
1059  if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
1060    checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
1061    int j=0;
1062    for(j=0;j<nbSupportedRequests;j++){
1063      if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
1064        if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(REQUEST))==0){
1065          checkValidValue(request_inputs,&err,"identifier",NULL,1);
1066          reqId=j+1;
1067          break;
1068        }
1069        else
1070          if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
1071             strncasecmp(REQUEST,requests[vid][j+1],strlen(REQUEST))==0){
1072            checkValidValue(request_inputs,&err,"jobid",NULL,1);
1073            reqId=j+1;
1074            break;
1075          }
1076      }else
1077        break;
1078    }
1079  }else{
1080    checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
1081    map* version1=getMap(request_inputs,"AcceptVersions");
1082    if(version1!=NULL){
1083      if(strstr(version1->value,schemas[1][0])!=NULL)
1084        addToMap(request_inputs,"version",schemas[1][0]);
1085      else
1086        addToMap(request_inputs,"version",version1->value);
1087      version=getMap(request_inputs,"version");
1088      setMapInMaps(m,"main","rversion",version->value);
1089      vid=getVersionId(version->value);
1090    }
1091  }
1092  if(err!=NULL){
1093    printExceptionReportResponse (m, err);
1094    freeMap(&err);
1095    free(err);
1096    if (count (request_inputs) == 1)
1097      {
1098        freeMap (&request_inputs);
1099        free (request_inputs);
1100      }
1101    free(REQUEST);
1102    freeMaps (&m);
1103    free (m);
1104    return 1;
1105  }
1106
1107  r_inputs = getMap (request_inputs, "serviceprovider");
1108  if (r_inputs == NULL)
1109    {
1110      addToMap (request_inputs, "serviceprovider", "");
1111    }
1112
1113  maps *request_output_real_format = NULL;
1114  map *tmpm = getMapFromMaps (m, "main", "serverAddress");
1115  if (tmpm != NULL)
1116    SERVICE_URL = zStrdup (tmpm->value);
1117  else
1118    SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
1119
1120
1121
1122  service *s1;
1123  int scount = 0;
1124#ifdef DEBUG
1125  dumpMap (r_inputs);
1126#endif
1127  char conf_dir[1024];
1128  int t;
1129  char tmps1[1024];
1130
1131  r_inputs = NULL;
1132  r_inputs = getMap (request_inputs, "metapath");
1133 
1134  if (r_inputs != NULL)
1135    snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
1136  else
1137    snprintf (conf_dir, 1024, "%s", ntmp);
1138
1139  map* reg = getMapFromMaps (m, "main", "registry");
1140  registry* zooRegistry=NULL;
1141  if(reg!=NULL){
1142    int saved_stdout = dup (fileno (stdout));
1143    dup2 (fileno (stderr), fileno (stdout));
1144    if(createRegistry (m,&zooRegistry,reg->value)<0){
1145      map *message=getMapFromMaps(m,"lenv","message");
1146      map *type=getMapFromMaps(m,"lenv","type");
1147      dup2 (saved_stdout, fileno (stdout));
1148      errorException (m, message->value,
1149                      type->value, NULL);
1150      return 0;
1151    }
1152    dup2 (saved_stdout, fileno (stdout));
1153    close(saved_stdout);
1154  }
1155
1156  if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
1157    {
1158#ifdef DEBUG
1159      dumpMap (r_inputs);
1160#endif
1161      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
1162      xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
1163      /**
1164       * Here we need to close stdout to ensure that unsupported chars
1165       * has been found in the zcfg and then printed on stdout
1166       */
1167      int saved_stdout = dup (fileno (stdout));
1168      dup2 (fileno (stderr), fileno (stdout));
1169      if (int res =               
1170          recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
1171                          printGetCapabilitiesForProcess) < 0)
1172        {
1173          freeMaps (&m);
1174          free (m);
1175          if(zooRegistry!=NULL){
1176            freeRegistry(&zooRegistry);
1177            free(zooRegistry);
1178          }
1179          free (REQUEST);
1180          free (SERVICE_URL);
1181          fflush (stdout);
1182          return res;
1183        }
1184      fflush (stdout);
1185      dup2 (saved_stdout, fileno (stdout));
1186      printDocument (m, doc, getpid ());
1187      freeMaps (&m);
1188      free (m);
1189      if(zooRegistry!=NULL){
1190        freeRegistry(&zooRegistry);
1191        free(zooRegistry);
1192      }
1193      free (REQUEST);
1194      free (SERVICE_URL);
1195      fflush (stdout);
1196      return 0;
1197    }
1198  else
1199    {
1200      r_inputs = getMap (request_inputs, "JobId");
1201      if(reqId>nbReqIdentifier){
1202        if (strncasecmp (REQUEST, "GetStatus", strlen(REQUEST)) == 0 ||
1203            strncasecmp (REQUEST, "GetResult", strlen(REQUEST)) == 0){
1204          runGetStatus(m,r_inputs->value,REQUEST);
1205          freeMaps (&m);
1206          free (m);
1207          if(zooRegistry!=NULL){
1208            freeRegistry(&zooRegistry);
1209            free(zooRegistry);
1210          }
1211          free (REQUEST);
1212          free (SERVICE_URL);
1213          return 0;
1214        }
1215        else
1216          if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
1217            runDismiss(m,r_inputs->value);
1218            freeMaps (&m);
1219            free (m);
1220            if(zooRegistry!=NULL){
1221              freeRegistry(&zooRegistry);
1222              free(zooRegistry);
1223            }
1224            free (REQUEST);
1225            free (SERVICE_URL);
1226            return 0;
1227           
1228          }
1229        return 0;
1230      }
1231      if(reqId<=nbReqIdentifier){
1232        r_inputs = getMap (request_inputs, "Identifier");
1233
1234        struct dirent *dp;
1235        DIR *dirp = opendir (conf_dir);
1236        if (dirp == NULL)
1237          {
1238            errorException (m, _("The specified path does not exist."),
1239                            "InvalidParameterValue", conf_dir);
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        if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
1251          {
1252            /**
1253             * Loop over Identifier list
1254             */
1255            xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
1256            r_inputs = NULL;
1257            r_inputs = getMap (request_inputs, "version");
1258            xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
1259                                          root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
1260
1261            r_inputs = getMap (request_inputs, "Identifier");
1262
1263            char *orig = zStrdup (r_inputs->value);
1264
1265            int saved_stdout = dup (fileno (stdout));
1266            dup2 (fileno (stderr), fileno (stdout));
1267            if (strcasecmp ("all", orig) == 0)
1268              {
1269                if (int res =
1270                    recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
1271                                    printDescribeProcessForProcess) < 0)
1272                  return res;
1273              }
1274            else
1275              {
1276                char *saveptr;
1277                char *tmps = strtok_r (orig, ",", &saveptr);
1278
1279                char buff[256];
1280                char buff1[1024];
1281                while (tmps != NULL)
1282                  {
1283                    int hasVal = -1;
1284                    char *corig = zStrdup (tmps);
1285                    if (strstr (corig, ".") != NULL)
1286                      {
1287
1288                        parseIdentifier (m, conf_dir, corig, buff1);
1289                        map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
1290                        if (tmpMap != NULL)
1291                          addToMap (request_inputs, "metapath", tmpMap->value);
1292                        map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
1293
1294                        s1 = (service *) malloc (SERVICE_SIZE);
1295                        t = readServiceFile (m, buff1, &s1, tmpMapI->value);
1296                        if (t < 0)
1297                          {
1298                            map *tmp00 = getMapFromMaps (m, "lenv", "message");
1299                            char tmp01[1024];
1300                            if (tmp00 != NULL)
1301                              sprintf (tmp01,
1302                                       _
1303                                       ("Unable to parse the ZCFG file for the following ZOO-Service: %s. Message: %s"),
1304                                       tmps, tmp00->value);
1305                            else
1306                              sprintf (tmp01,
1307                                       _
1308                                       ("Unable to parse the ZCFG file for the following ZOO-Service: %s."),
1309                                       tmps);
1310                            dup2 (saved_stdout, fileno (stdout));
1311                            errorException (m, tmp01, "InvalidParameterValue",
1312                                            "identifier");
1313                            freeMaps (&m);
1314                            free (m);
1315                            if(zooRegistry!=NULL){
1316                              freeRegistry(&zooRegistry);
1317                              free(zooRegistry);
1318                            }
1319                            free (REQUEST);
1320                            free (corig);
1321                            free (orig);
1322                            free (SERVICE_URL);
1323                            free (s1);
1324                            closedir (dirp);
1325                            xmlFreeDoc (doc);
1326                            xmlCleanupParser ();
1327                            zooXmlCleanupNs ();
1328                            return 1;
1329                          }
1330#ifdef DEBUG
1331                        dumpService (s1);
1332#endif
1333                        inheritance(zooRegistry,&s1);
1334                        printDescribeProcessForProcess (zooRegistry,m, n, s1);
1335                        freeService (&s1);
1336                        free (s1);
1337                        s1 = NULL;
1338                        scount++;
1339                        hasVal = 1;
1340                        setMapInMaps (m, "lenv", "level", "0");
1341                      }
1342                    else
1343                      {
1344                        memset (buff, 0, 256);
1345                        snprintf (buff, 256, "%s.zcfg", corig);
1346                        memset (buff1, 0, 1024);
1347#ifdef DEBUG
1348                        printf ("\n#######%s\n########\n", buff);
1349#endif
1350                        while ((dp = readdir (dirp)) != NULL)
1351                          {
1352                            if (strcasecmp (dp->d_name, buff) == 0)
1353                              {
1354                                memset (buff1, 0, 1024);
1355                                snprintf (buff1, 1024, "%s/%s", conf_dir,
1356                                          dp->d_name);
1357                                s1 = (service *) malloc (SERVICE_SIZE);
1358                                if (s1 == NULL)
1359                                  {
1360                                    dup2 (saved_stdout, fileno (stdout));
1361                                    return errorException (m,
1362                                                           _
1363                                                           ("Unable to allocate memory"),
1364                                                           "InternalError",
1365                                                           NULL);
1366                                  }
1367#ifdef DEBUG
1368                                printf
1369                                  ("#################\n(%s) %s\n#################\n",
1370                                   r_inputs->value, buff1);
1371#endif
1372                                char *tmp0 = zStrdup (dp->d_name);
1373                                tmp0[strlen (tmp0) - 5] = 0;
1374                                t = readServiceFile (m, buff1, &s1, tmp0);
1375                                free (tmp0);
1376                                if (t < 0)
1377                                  {
1378                                    map *tmp00 =
1379                                      getMapFromMaps (m, "lenv", "message");
1380                                    char tmp01[1024];
1381                                    if (tmp00 != NULL)
1382                                      sprintf (tmp01,
1383                                               _
1384                                               ("Unable to parse the ZCFG file: %s (%s)"),
1385                                               dp->d_name, tmp00->value);
1386                                    else
1387                                      sprintf (tmp01,
1388                                               _
1389                                               ("Unable to parse the ZCFG file: %s."),
1390                                               dp->d_name);
1391                                    dup2 (saved_stdout, fileno (stdout));
1392                                    errorException (m, tmp01, "InternalError",
1393                                                    NULL);
1394                                    freeMaps (&m);
1395                                    free (m);
1396                                    if(zooRegistry!=NULL){
1397                                      freeRegistry(&zooRegistry);
1398                                      free(zooRegistry);
1399                                    }
1400                                    free (orig);
1401                                    free (REQUEST);
1402                                    closedir (dirp);
1403                                    xmlFreeDoc (doc);
1404                                    xmlCleanupParser ();
1405                                    zooXmlCleanupNs ();
1406                                    return 1;
1407                                  }
1408#ifdef DEBUG
1409                                dumpService (s1);
1410#endif
1411                                inheritance(zooRegistry,&s1);
1412                                printDescribeProcessForProcess (zooRegistry,m, n, s1);
1413                                freeService (&s1);
1414                                free (s1);
1415                                s1 = NULL;
1416                                scount++;
1417                                hasVal = 1;
1418                              }
1419                          }
1420                      }
1421                    if (hasVal < 0)
1422                      {
1423                        map *tmp00 = getMapFromMaps (m, "lenv", "message");
1424                        char tmp01[1024];
1425                        if (tmp00 != NULL)
1426                          sprintf (tmp01,
1427                                   _("Unable to parse the ZCFG file: %s (%s)"),
1428                                   buff, tmp00->value);
1429                        else
1430                          sprintf (tmp01,
1431                                   _("Unable to parse the ZCFG file: %s."),
1432                                   buff);
1433                        dup2 (saved_stdout, fileno (stdout));
1434                        errorException (m, tmp01, "InvalidParameterValue",
1435                                        "Identifier");
1436                        freeMaps (&m);
1437                        free (m);
1438                        if(zooRegistry!=NULL){
1439                          freeRegistry(&zooRegistry);
1440                          free(zooRegistry);
1441                        }
1442                        free (orig);
1443                        free (REQUEST);
1444                        closedir (dirp);
1445                        xmlFreeDoc (doc);
1446                        xmlCleanupParser ();
1447                        zooXmlCleanupNs ();
1448                        return 1;
1449                      }
1450                    rewinddir (dirp);
1451                    tmps = strtok_r (NULL, ",", &saveptr);
1452                    if (corig != NULL)
1453                      free (corig);
1454                  }
1455              }
1456            closedir (dirp);
1457            fflush (stdout);
1458            dup2 (saved_stdout, fileno (stdout));
1459            free (orig);
1460            printDocument (m, doc, getpid ());
1461            freeMaps (&m);
1462            free (m);
1463            if(zooRegistry!=NULL){
1464              freeRegistry(&zooRegistry);
1465              free(zooRegistry);
1466            }
1467            free (REQUEST);
1468            free (SERVICE_URL);
1469            fflush (stdout);
1470            return 0;
1471          }
1472        else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
1473          {
1474            map* version=getMapFromMaps(m,"main","rversion");
1475            int vid=getVersionId(version->value);
1476            int len,j=0;
1477            for(j=0;j<nbSupportedRequests;j++){
1478              if(requests[vid][j]!=NULL)
1479                len+=strlen(requests[vid][j])+2;
1480              else{
1481                len+=4;
1482                break;
1483              }
1484            }
1485            char *tmpStr=(char*)malloc(len*sizeof(char));
1486            int it=0;
1487            for(j=0;j<nbSupportedRequests;j++){
1488              if(requests[vid][j]!=NULL){
1489                if(it==0){
1490                  sprintf(tmpStr,"%s",requests[vid][j]);
1491                  it++;
1492                }else{
1493                  char *tmpS=zStrdup(tmpStr);
1494                  if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
1495                    sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
1496                  }else{
1497                    sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
1498                 
1499                  }
1500                  free(tmpS);
1501                }
1502              }
1503              else{
1504                len+=4;
1505                break;
1506              }
1507            }
1508            char* message=(char*)malloc((61+len)*sizeof(char));
1509            sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
1510            errorException (m,_(message),"InvalidParameterValue", "request");
1511#ifdef DEBUG
1512            fprintf (stderr, "No request found %s", REQUEST);
1513#endif
1514            closedir (dirp);
1515            freeMaps (&m);
1516            free (m);
1517            if(zooRegistry!=NULL){
1518              freeRegistry(&zooRegistry);
1519              free(zooRegistry);
1520            }
1521            free (REQUEST);
1522            free (SERVICE_URL);
1523            fflush (stdout);
1524            return 0;
1525          }
1526        closedir (dirp);
1527      }
1528    }
1529
1530  map *postRequest = NULL;
1531  postRequest = getMap (request_inputs, "xrequest");
1532
1533  if(vid==1 && postRequest==NULL){
1534    errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request"); 
1535    freeMaps (&m);
1536    free (m);
1537    if(zooRegistry!=NULL){
1538      freeRegistry(&zooRegistry);
1539      free(zooRegistry);
1540    }
1541    free (REQUEST);
1542    free (SERVICE_URL);
1543    fflush (stdout);
1544    return 0;
1545  }
1546 
1547  s1 = NULL;
1548  s1 = (service *) malloc (SERVICE_SIZE);
1549  if (s1 == NULL)
1550    {
1551      freeMaps (&m);
1552      free (m);
1553      if(zooRegistry!=NULL){
1554        freeRegistry(&zooRegistry);
1555        free(zooRegistry);
1556      }
1557      free (REQUEST);
1558      free (SERVICE_URL);
1559      return errorException (m, _("Unable to allocate memory"),
1560                             "InternalError", NULL);
1561    }
1562
1563  r_inputs = getMap (request_inputs, "MetaPath");
1564  if (r_inputs != NULL)
1565    snprintf (tmps1, 1024, "%s/%s", ntmp, r_inputs->value);
1566  else
1567    snprintf (tmps1, 1024, "%s/", ntmp);
1568  r_inputs = getMap (request_inputs, "Identifier");
1569  char *ttmp = zStrdup (tmps1);
1570  snprintf (tmps1, 1024, "%s/%s.zcfg", ttmp, r_inputs->value);
1571  free (ttmp);
1572#ifdef DEBUG
1573  fprintf (stderr, "Trying to load %s\n", tmps1);
1574#endif
1575  if (strstr (r_inputs->value, ".") != NULL)
1576    {
1577      char *identifier = zStrdup (r_inputs->value);
1578      parseIdentifier (m, conf_dir, identifier, tmps1);
1579      map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
1580      if (tmpMap != NULL)
1581        addToMap (request_inputs, "metapath", tmpMap->value);
1582      free (identifier);
1583    }
1584  else
1585    {
1586      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
1587      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
1588    }
1589
1590  r_inputs = getMapFromMaps (m, "lenv", "Identifier");
1591  int saved_stdout = dup (fileno (stdout));
1592  dup2 (fileno (stderr), fileno (stdout));
1593  t = readServiceFile (m, tmps1, &s1, r_inputs->value);
1594  inheritance(zooRegistry,&s1);
1595  if(zooRegistry!=NULL){
1596    freeRegistry(&zooRegistry);
1597    free(zooRegistry);
1598  }
1599  fflush (stdout);
1600  dup2 (saved_stdout, fileno (stdout));
1601  if (t < 0)
1602    {
1603      char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
1604      sprintf (tmpMsg,
1605               _
1606               ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
1607               r_inputs->value);
1608      errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
1609      free (tmpMsg);
1610      free (s1);
1611      freeMaps (&m);
1612      free (m);
1613      free (REQUEST);
1614      free (SERVICE_URL);
1615      return 0;
1616    }
1617  close (saved_stdout);
1618
1619#ifdef DEBUG
1620  dumpService (s1);
1621#endif
1622  int j;
1623
1624
1625  /**
1626   * Create the input and output maps data structure
1627   */
1628  int i = 0;
1629  HINTERNET hInternet;
1630  HINTERNET res;
1631  hInternet = InternetOpen (
1632#ifndef WIN32
1633                            (LPCTSTR)
1634#endif
1635                            "ZooWPSClient\0",
1636                            INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1637
1638#ifndef WIN32
1639  if (!CHECK_INET_HANDLE (hInternet))
1640    fprintf (stderr, "WARNING : hInternet handle failed to initialize");
1641#endif
1642  maps *request_input_real_format = NULL;
1643  maps *tmpmaps = request_input_real_format;
1644
1645
1646  if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
1647    freeMaps (&m);
1648    free (m);
1649    free (REQUEST);
1650    free (SERVICE_URL);
1651    InternetCloseHandle (&hInternet);
1652    freeService (&s1);
1653    free (s1);
1654    return 0;
1655  }
1656
1657
1658  // Define each env variable in runing environment
1659  maps *curs = getMaps (m, "env");
1660  if (curs != NULL)
1661    {
1662      map *mapcs = curs->content;
1663      while (mapcs != NULLMAP)
1664        {
1665#ifndef WIN32
1666          setenv (mapcs->name, mapcs->value, 1);
1667#else
1668#ifdef DEBUG
1669          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
1670                   mapcs->value);
1671#endif
1672          if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
1673            {
1674#ifdef DEBUG
1675              fprintf (stderr, "[ZOO: Env var finish with \r]\n");
1676#endif
1677              mapcs->value[strlen (mapcs->value) - 1] = 0;
1678            }
1679#ifdef DEBUG
1680          if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
1681            {
1682              fflush (stderr);
1683              fprintf (stderr, "setting variable... %s\n", "OK");
1684            }
1685          else
1686            {
1687              fflush (stderr);
1688              fprintf (stderr, "setting variable... %s\n", "OK");
1689            }
1690#else
1691
1692
1693          SetEnvironmentVariable (mapcs->name, mapcs->value);
1694#endif
1695          char *toto =
1696            (char *)
1697            malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
1698                     2) * sizeof (char));
1699          sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
1700          putenv (toto);
1701#ifdef DEBUG
1702          fflush (stderr);
1703#endif
1704#endif
1705#ifdef DEBUG
1706          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
1707                   mapcs->value);
1708          fflush (stderr);
1709#endif
1710          mapcs = mapcs->next;
1711        }
1712    }
1713
1714#ifdef DEBUG
1715  dumpMap (request_inputs);
1716#endif
1717
1718  map *status = getMap (request_inputs, "status");
1719  if(vid==0){
1720    // Need to check if we need to fork to load a status enabled
1721    r_inputs = NULL;
1722    map *store = getMap (request_inputs, "storeExecuteResponse");
1723    /**
1724     * 05-007r7 WPS 1.0.0 page 57 :
1725     * 'If status="true" and storeExecuteResponse is "false" then the service
1726     * shall raise an exception.'
1727     */
1728    if (status != NULL && strcmp (status->value, "true") == 0 &&
1729        store != NULL && strcmp (store->value, "false") == 0)
1730      {
1731        errorException (m,
1732                        _
1733                        ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
1734                        "InvalidParameterValue", "storeExecuteResponse");
1735        freeService (&s1);
1736        free (s1);
1737        freeMaps (&m);
1738        free (m);
1739       
1740        freeMaps (&request_input_real_format);
1741        free (request_input_real_format);
1742       
1743        freeMaps (&request_output_real_format);
1744        free (request_output_real_format);
1745
1746        free (REQUEST);
1747        free (SERVICE_URL);
1748        return 1;
1749      }
1750    r_inputs = getMap (request_inputs, "storeExecuteResponse");
1751  }else{
1752    // Define status depending on the WPS 2.0.0 mode attribute
1753    status = getMap (request_inputs, "mode");
1754    map* mode=getMap(s1->content,"mode");
1755    if(strcasecmp(status->value,"async")==0){
1756      if(mode!=NULL && strcasecmp(mode->value,"async")==0)
1757        addToMap(request_inputs,"status","true");
1758      else{
1759        if(mode!=NULL){
1760          // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
1761          errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value); 
1762          fflush (stdout);
1763          freeMaps (&m);
1764          free (m);
1765          if(zooRegistry!=NULL){
1766            freeRegistry(&zooRegistry);
1767            free(zooRegistry);
1768          }
1769          freeMaps (&request_input_real_format);
1770          free (request_input_real_format);
1771          freeMaps (&request_output_real_format);
1772          free (request_output_real_format);
1773          free (REQUEST);
1774          free (SERVICE_URL);
1775          return 0;
1776        }else
1777          addToMap(request_inputs,"status","true");
1778      }
1779    }
1780    else{
1781      if(strcasecmp(status->value,"auto")==0){
1782        if(mode!=NULL){
1783          if(strcasecmp(mode->value,"async")==0)
1784            addToMap(request_inputs,"status","false");
1785          else
1786            addToMap(request_inputs,"status","true");
1787        }
1788        else
1789          addToMap(request_inputs,"status","false");
1790      }else
1791        addToMap(request_inputs,"status","false");
1792    }
1793    status = getMap (request_inputs, "status");
1794  }
1795
1796  int eres = SERVICE_STARTED;
1797  int cpid = getpid ();
1798
1799  /**
1800   * Initialize the specific [lenv] section which contains runtime variables:
1801   *
1802   *  - usid : it is an universally unique identifier 
1803   *  - osid : it is an idenfitication number
1804   *  - sid : it is the process idenfitication number (OS)
1805   *  - uusid : it is an universally unique identifier
1806   *  - status : value between 0 and 100 to express the  completude of
1807   * the operations of the running service
1808   *  - message : is a string where you can store error messages, in case
1809   * service is failing, or o provide details on the ongoing operation.
1810   *  - cwd : is the current working directory
1811   *  - soap : is a boolean value, true if the request was contained in a SOAP
1812   * Envelop
1813   *  - sessid : string storing the session identifier (only when cookie is
1814   * used)
1815   *  - cgiSid : only defined on Window platforms (for being able to identify
1816   * the created process)
1817   *
1818   */
1819  maps *_tmpMaps = (maps *) malloc (MAPS_SIZE);
1820  _tmpMaps->name = zStrdup ("lenv");
1821  char tmpBuff[100];
1822  struct ztimeval tp;
1823  if (zGettimeofday (&tp, NULL) == 0)
1824    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
1825  else
1826    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
1827  _tmpMaps->content = createMap ("osid", tmpBuff);
1828  _tmpMaps->next = NULL;
1829  sprintf (tmpBuff, "%i", cpid);
1830  addToMap (_tmpMaps->content, "sid", tmpBuff);
1831  char* tmpUuid=get_uuid();
1832  addToMap (_tmpMaps->content, "uusid", tmpUuid);
1833  addToMap (_tmpMaps->content, "usid", tmpUuid);
1834  free(tmpUuid);
1835  addToMap (_tmpMaps->content, "status", "0");
1836  addToMap (_tmpMaps->content, "cwd", ntmp);
1837  addToMap (_tmpMaps->content, "message", _("No message provided"));
1838  map *ltmp = getMap (request_inputs, "soap");
1839  if (ltmp != NULL)
1840    addToMap (_tmpMaps->content, "soap", ltmp->value);
1841  else
1842    addToMap (_tmpMaps->content, "soap", "false");
1843
1844  // Parse the session file and add it to the main maps
1845  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
1846    {
1847      int hasValidCookie = -1;
1848      char *tcook = zStrdup (cgiCookie);
1849      char *tmp = NULL;
1850      map *testing = getMapFromMaps (m, "main", "cookiePrefix");
1851      if (testing == NULL)
1852        {
1853          tmp = zStrdup ("ID=");
1854        }
1855      else
1856        {
1857          tmp =
1858            (char *) malloc ((strlen (testing->value) + 2) * sizeof (char));
1859          sprintf (tmp, "%s=", testing->value);
1860        }
1861      if (strstr (cgiCookie, ";") != NULL)
1862        {
1863          char *token, *saveptr;
1864          token = strtok_r (cgiCookie, ";", &saveptr);
1865          while (token != NULL)
1866            {
1867              if (strcasestr (token, tmp) != NULL)
1868                {
1869                  if (tcook != NULL)
1870                    free (tcook);
1871                  tcook = zStrdup (token);
1872                  hasValidCookie = 1;
1873                }
1874              token = strtok_r (NULL, ";", &saveptr);
1875            }
1876        }
1877      else
1878        {
1879          if (strstr (cgiCookie, "=") != NULL
1880              && strcasestr (cgiCookie, tmp) != NULL)
1881            {
1882              tcook = zStrdup (cgiCookie);
1883              hasValidCookie = 1;
1884            }
1885          if (tmp != NULL)
1886            {
1887              free (tmp);
1888            }
1889        }
1890      if (hasValidCookie > 0)
1891        {
1892          addToMap (_tmpMaps->content, "sessid", strstr (tcook, "=") + 1);
1893          char session_file_path[1024];
1894          map *tmpPath = getMapFromMaps (m, "main", "sessPath");
1895          if (tmpPath == NULL)
1896            tmpPath = getMapFromMaps (m, "main", "tmpPath");
1897          char *tmp1 = strtok (tcook, ";");
1898          if (tmp1 != NULL)
1899            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
1900                     strstr (tmp1, "=") + 1);
1901          else
1902            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
1903                     strstr (cgiCookie, "=") + 1);
1904          free (tcook);
1905          maps *tmpSess = (maps *) malloc (MAPS_SIZE);
1906          struct stat file_status;
1907          int istat = stat (session_file_path, &file_status);
1908          if (istat == 0 && file_status.st_size > 0)
1909            {
1910              conf_read (session_file_path, tmpSess);
1911              addMapsToMaps (&m, tmpSess);
1912              freeMaps (&tmpSess);
1913              free (tmpSess);
1914            }
1915        }
1916    }
1917  addMapsToMaps (&m, _tmpMaps);
1918  freeMaps (&_tmpMaps);
1919  free (_tmpMaps);
1920  maps* bmap=NULL;
1921#ifdef DEBUG
1922  dumpMap (request_inputs);
1923#endif
1924#ifdef WIN32
1925  char *cgiSidL = NULL;
1926  if (getenv ("CGISID") != NULL)
1927    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
1928
1929  char* usidp;
1930  if ( (usidp = getenv("USID")) != NULL ) {
1931    setMapInMaps (m, "lenv", "usid", usidp);
1932  }
1933
1934  map *test1 = getMap (request_inputs, "cgiSid");
1935  if (test1 != NULL){
1936    cgiSid = zStrdup(test1->value);
1937    addToMap (request_inputs, "storeExecuteResponse", "true");
1938    addToMap (request_inputs, "status", "true");
1939    setMapInMaps (m, "lenv", "osid", test1->value);
1940    status = getMap (request_inputs, "status");
1941  }
1942  test1 = getMap (request_inputs, "usid");
1943  if (test1 != NULL){
1944    setMapInMaps (m, "lenv", "usid", test1->value);
1945    setMapInMaps (m, "lenv", "uusid", test1->value);
1946  }
1947#endif
1948  char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
1949  FILE *f0, *f1;
1950  if (status != NULL)
1951    if (strcasecmp (status->value, "false") == 0)
1952      status = NULLMAP;
1953  if (status == NULLMAP)
1954    {
1955      if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
1956        freeService (&s1);
1957        free (s1);
1958        freeMaps (&m);
1959        free (m);
1960        free (REQUEST);
1961        free (SERVICE_URL);
1962        freeMaps (&request_input_real_format);
1963        free (request_input_real_format);
1964        freeMaps (&request_output_real_format);
1965        free (request_output_real_format);
1966        freeMaps (&tmpmaps);
1967        free (tmpmaps);
1968        return -1;
1969      }
1970
1971      loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
1972                         &request_output_real_format, &eres);
1973    }
1974  else
1975    {
1976      int pid;
1977#ifdef DEBUG
1978      fprintf (stderr, "\nPID : %d\n", cpid);
1979#endif
1980
1981#ifndef WIN32
1982      pid = fork ();
1983#else
1984      if (cgiSid == NULL)
1985        {
1986          createProcess (m, request_inputs, s1, NULL, cpid,
1987                         request_input_real_format,
1988                         request_output_real_format);
1989          pid = cpid;
1990        }
1991      else
1992        {
1993          pid = 0;
1994          cpid = atoi (cgiSid);
1995          updateStatus(m,0,_("Initializing"));
1996        }
1997#endif
1998      if (pid > 0)
1999        {
2000          /**
2001           * dady :
2002           * set status to SERVICE_ACCEPTED
2003           */
2004#ifdef DEBUG
2005          fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
2006                   getpid ());
2007#endif
2008          eres = SERVICE_ACCEPTED;
2009        }
2010      else if (pid == 0)
2011        {
2012          /**
2013           * son : have to close the stdout, stdin and stderr to let the parent
2014           * process answer to http client.
2015           */
2016          map* usid = getMapFromMaps (m, "lenv", "uusid");
2017          map* tmpm = getMapFromMaps (m, "lenv", "osid");
2018          int cpid = atoi (tmpm->value);
2019          r_inputs = getMapFromMaps (m, "main", "tmpPath");
2020          map* r_inputs1 = createMap("ServiceName", s1->name);
2021
2022          // Create the filename for the result file (.res)
2023          fbkpres =
2024            (char *)
2025            malloc ((strlen (r_inputs->value) +
2026                     strlen (usid->value) + 7) * sizeof (char));
2027          sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
2028          bmap = (maps *) malloc (MAPS_SIZE);
2029          bmap->name=zStrdup("status");
2030          bmap->content=createMap("usid",usid->value);
2031          bmap->next=NULL;
2032          addToMap(bmap->content,"sid",tmpm->value);
2033          addIntToMap(bmap->content,"pid",getpid());
2034         
2035          // Create PID file referencing the OS process identifier
2036          fbkpid =
2037            (char *)
2038            malloc ((strlen (r_inputs->value) +
2039                     strlen (usid->value) + 7) * sizeof (char));
2040          sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
2041
2042          f0 = freopen (fbkpid, "w+",stdout);
2043          printf("%d",getpid());
2044          fflush(stdout);
2045
2046          // Create SID file referencing the semaphore name
2047          fbkp =
2048            (char *)
2049            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
2050                     strlen (usid->value) + 7) * sizeof (char));
2051          sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
2052          FILE* f2 = freopen (fbkp, "w+",stdout);
2053          printf("%s",tmpm->value);
2054          fflush(f2);
2055          free(fbkp);
2056
2057          fbkp =
2058            (char *)
2059            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
2060                     strlen (usid->value) + 7) * sizeof (char));
2061          sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
2062                   usid->value);
2063          flog =
2064            (char *)
2065            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
2066                     strlen (usid->value) + 13) * sizeof (char));
2067          sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
2068                   r_inputs1->value, usid->value);
2069#ifdef DEBUG
2070          fprintf (stderr, "RUN IN BACKGROUND MODE \n");
2071          fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
2072                   getpid ());
2073          fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
2074#endif
2075          freopen (flog, "w+", stderr);
2076          fflush (stderr);
2077          f0 = freopen (fbkp, "w+", stdout);
2078          rewind (stdout);
2079#ifndef WIN32
2080          fclose (stdin);
2081#endif
2082#ifdef RELY_ON_DB
2083          init_sql(m);
2084          recordServiceStatus(m);
2085#endif
2086          if(vid==0){
2087            /**
2088             * set status to SERVICE_STARTED and flush stdout to ensure full
2089             * content was outputed (the file used to store the ResponseDocument).
2090             * The rewind stdout to restart writing from the bgining of the file,
2091             * this way the data will be updated at the end of the process run.
2092             */
2093            printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
2094                                  SERVICE_STARTED, request_input_real_format,
2095                                  request_output_real_format);
2096            fflush (stdout);
2097#ifdef RELY_ON_DB
2098            recordResponse(m,fbkp);
2099#endif
2100          }
2101
2102          fflush (stderr);
2103
2104          fbkp1 =
2105            (char *)
2106            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
2107                     strlen (usid->value) + 13) * sizeof (char));
2108          sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
2109                   r_inputs1->value, usid->value);
2110
2111          f1 = freopen (fbkp1, "w+", stdout);
2112
2113          if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
2114            freeService (&s1);
2115            free (s1);
2116            freeMaps (&m);
2117            free (m);
2118            free (REQUEST);
2119            free (SERVICE_URL);
2120            freeMaps (&request_input_real_format);
2121            free (request_input_real_format);
2122            freeMaps (&request_output_real_format);
2123            free (request_output_real_format);
2124            freeMaps (&tmpmaps);
2125            free (tmpmaps);
2126            fflush (stdout);
2127            fflush (stderr);
2128            unhandleStatus (m);
2129            return -1;
2130          }
2131          loadServiceAndRun (&m, s1, request_inputs,
2132                             &request_input_real_format,
2133                             &request_output_real_format, &eres);
2134        }
2135      else
2136        {
2137          /**
2138           * error server don't accept the process need to output a valid
2139           * error response here !!!
2140           */
2141          eres = -1;
2142          errorException (m, _("Unable to run the child process properly"),
2143                          "InternalError", NULL);
2144        }
2145    }
2146
2147#ifdef DEBUG
2148  dumpMaps (request_output_real_format);
2149#endif
2150  if (eres != -1)
2151    outputResponse (s1, request_input_real_format,
2152                    request_output_real_format, request_inputs,
2153                    cpid, m, eres);
2154  fflush (stdout);
2155 
2156  /**
2157   * Ensure that if error occurs when freeing memory, no signal will return
2158   * an ExceptionReport document as the result was already returned to the
2159   * client.
2160   */
2161#ifndef USE_GDB
2162  signal (SIGSEGV, donothing);
2163  signal (SIGTERM, donothing);
2164  signal (SIGINT, donothing);
2165  signal (SIGILL, donothing);
2166  signal (SIGFPE, donothing);
2167  signal (SIGABRT, donothing);
2168#endif
2169  if (((int) getpid ()) != cpid || cgiSid != NULL)
2170    {
2171      fclose (stdout);
2172      fclose (stderr);
2173      /**
2174       * Dump back the final file fbkp1 to fbkp
2175       */
2176      fclose (f0);
2177      fclose (f1);
2178
2179      FILE *f2 = fopen (fbkp1, "rb");
2180#ifndef RELY_ON_DB
2181      semid lid = getShmLockId (m, 1);
2182      if (lid < 0)
2183        return -1;
2184      lockShm (lid);
2185#endif
2186      FILE *f3 = fopen (fbkp, "wb+");
2187      free (fbkp);
2188      fseek (f2, 0, SEEK_END);
2189      long flen = ftell (f2);
2190      fseek (f2, 0, SEEK_SET);
2191      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
2192      fread (tmps1, flen, 1, f2);
2193#ifdef WIN32
2194      char *pchr=strrchr(tmps1,'>');
2195      flen=strlen(tmps1)-strlen(pchr)+1;
2196      tmps1[flen]=0;
2197#endif
2198      fwrite (tmps1, 1, flen, f3);
2199      fclose (f2);
2200      fclose (f3);
2201      unlink (fbkpid);
2202      switch(eres){
2203      default:
2204      case SERVICE_FAILED:
2205        setMapInMaps(bmap,"status","status",wpsStatus[1]);
2206        setMapInMaps(m,"lenv","fstate",wpsStatus[1]);
2207        break;
2208      case SERVICE_SUCCEEDED:
2209        setMapInMaps(bmap,"status","status",wpsStatus[0]);
2210        setMapInMaps(m,"lenv","fstate",wpsStatus[0]);
2211        break;
2212      }
2213#ifndef RELY_ON_DB
2214      dumpMapsToFile(bmap,fbkpres,1);
2215      removeShmLock (m, 1);
2216#else
2217      recordResponse(m,fbkp1);
2218#endif
2219      freeMaps(&bmap);
2220      free(bmap);
2221      unlink (fbkp1);
2222      unlink (flog);
2223      unhandleStatus (m);
2224      free(fbkpid);
2225      free(fbkpres);
2226      free (flog);
2227      free (fbkp1);
2228      free (tmps1);
2229      if(cgiSid!=NULL)
2230        free(cgiSid);
2231    }
2232
2233  freeService (&s1);
2234  free (s1);
2235  freeMaps (&m);
2236  free (m);
2237
2238  freeMaps (&request_input_real_format);
2239  free (request_input_real_format);
2240
2241  freeMaps (&request_output_real_format);
2242  free (request_output_real_format);
2243
2244  free (REQUEST);
2245  free (SERVICE_URL);
2246#ifdef DEBUG
2247  fprintf (stderr, "Processed response \n");
2248  fflush (stdout);
2249  fflush (stderr);
2250#endif
2251
2252  if (((int) getpid ()) != cpid || cgiSid != NULL)
2253    {
2254      exit (0);
2255    }
2256
2257  return 0;
2258}
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