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

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

Fix issue with headers located in extern C. Define java.library.path at runtime to search for libZOO.so from the Java zoo-api.

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