source: branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c @ 822

Last change on this file since 822 was 822, checked in by djay, 7 years ago

Commit the minimal requirements for remote HPC support

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