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

Last change on this file since 674 was 673, checked in by djay, 10 years ago

Fixes in configure.ac. Fix in registry creation. Fixes for Data node for WPS version 2.0.0.

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