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

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

Fix issue when running service in asynch mode with missing parameters.

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