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

Last change on this file since 666 was 666, checked in by djay, 9 years ago

Small fix for version id detection.

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