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

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

Integrate a basic SAGA-GIS support into the ZOO-Kernel.

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