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

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

Dynamically add a [renv] section to store all environment variables available at runtime. Update the documentation to provide informations about thie new section.

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