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

Last change on this file since 652 was 652, checked in by djay, 6 years ago

Better concurrency gesture for asynchronous requests, add db backend support for status informations.

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