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

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

Add readBase64 function, avoid calling it prior to fork . Add dumpMapsValuesToFiles function used to simplify OTB support.

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