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

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

Small fix for CDATA content. ExceptionReport? if lock failed.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 120.0 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2008-2013 GeoLabs SARL. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
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
57#ifdef USE_PYTHON
58#include "service_internal_python.h"
59#endif
60
61#ifdef USE_JAVA
62#include "service_internal_java.h"
63#endif
64
65#ifdef USE_PHP
66#include "service_internal_php.h"
67#endif
68
69#ifdef USE_JS
70#include "service_internal_js.h"
71#endif
72
73#ifdef USE_RUBY
74#include "service_internal_ruby.h"
75#endif
76
77#ifdef USE_PERL
78#include "service_internal_perl.h"
79#endif
80
81#include <dirent.h>
82#include <signal.h>
83#include <unistd.h>
84#ifndef WIN32
85#include <dlfcn.h>
86#include <libgen.h>
87#else
88#include <windows.h>
89#include <direct.h>
90#include <sys/types.h>
91#include <sys/stat.h>
92#include <unistd.h>
93#define pid_t int;
94#endif
95#include <fcntl.h>
96#include <time.h>
97#include <stdarg.h>
98
99#ifdef WIN32
100extern "C"
101{
102  __declspec (dllexport) char *strcasestr (char const *a, char const *b)
103#ifndef USE_MS
104  {
105    char *x = zStrdup (a);
106    char *y = zStrdup (b);
107
108      x = _strlwr (x);
109      y = _strlwr (y);
110    char *pos = strstr (x, y);
111    char *ret = pos == NULL ? NULL : (char *) (a + (pos - x));
112      free (x);
113      free (y);
114      return ret;
115  };
116#else
117   ;
118#endif
119}
120#endif
121
122/**
123 * Translation function for zoo-kernel
124 */
125#define _(String) dgettext ("zoo-kernel",String)
126/**
127 * Translation function for zoo-service
128 */
129#define __(String) dgettext ("zoo-service",String)
130
131#ifdef WIN32
132  #ifndef PROGRAMNAME
133    #define PROGRAMNAME "zoo_loader.cgi"
134  #endif
135#endif
136
137extern int getServiceFromFile (maps *, const char *, service **);
138
139/**
140 * Parse the service file using getServiceFromFile or use getServiceFromYAML
141 * if YAML support was activated.
142 *
143 * @param conf the conf maps containing the main.cfg settings
144 * @param file the file name to parse
145 * @param service the service to update witht the file content
146 * @param name the service name
147 * @return true if the file can be parsed or false
148 * @see getServiceFromFile, getServiceFromYAML
149 */
150int
151readServiceFile (maps * conf, char *file, service ** service, char *name)
152{
153  int t = getServiceFromFile (conf, file, service);
154#ifdef YAML
155  if (t < 0)
156    {
157      t = getServiceFromYAML (conf, file, service, name);
158    }
159#endif
160  return t;
161}
162
163/**
164 * Replace a char by another one in a string
165 *
166 * @param str the string to update
167 * @param toReplace the char to replace
168 * @param toReplaceBy the char that will be used
169 */
170void
171translateChar (char *str, char toReplace, char toReplaceBy)
172{
173  int i = 0, len = strlen (str);
174  for (i = 0; i < len; i++)
175    {
176      if (str[i] == toReplace)
177        str[i] = toReplaceBy;
178    }
179}
180
181/**
182 * Create (or append to) an array valued maps value = "["",""]"
183 *
184 * @param m the conf maps containing the main.cfg settings
185 * @param mo the map to update
186 * @param mi the map to append
187 * @param elem the elements containing default definitions
188 * @return 0 on success, -1 on failure
189 */
190int
191appendMapsToMaps (maps * m, maps * mo, maps * mi, elements * elem)
192{
193  maps *tmpMaps = getMaps (mo, mi->name);
194  map *tmap = getMapType (tmpMaps->content);
195  elements *el = getElements (elem, mi->name);
196  int hasEl = 1;
197  if (el == NULL)
198    hasEl = -1;
199  if (tmap == NULL)
200    {
201      if (hasEl > 0)
202        tmap = getMapType (el->defaults->content);
203    }
204
205  map *testMap = NULL;
206  if (hasEl > 0)
207    {
208      testMap = getMap (el->content, "maxOccurs");
209    }
210  else
211    {
212      testMap = createMap ("maxOccurs", "unbounded");
213    }
214
215  if (testMap != NULL)
216    {
217      if (strncasecmp (testMap->value, "unbounded", 9) != 0
218          && atoi (testMap->value) > 1)
219        {
220          addMapsArrayToMaps (&mo, mi, tmap->name);
221          map* nb=getMapFromMaps(mo,mi->name,"length");
222          if (nb!=NULL && atoi(nb->value)>atoi(testMap->value))
223            {
224              char emsg[1024];
225              sprintf (emsg,
226                       _("The maximum allowed occurrences for <%s> (%i) was exceeded."),
227                       mi->name, atoi (testMap->value));
228              errorException (m, emsg, "InternalError", NULL);
229              return -1;
230            }
231        }
232      else
233        {
234          if (strncasecmp (testMap->value, "unbounded", 9) == 0)
235            {
236              if (hasEl < 0)
237                {
238                  freeMap (&testMap);
239                  free (testMap);
240                }
241              if (addMapsArrayToMaps (&mo, mi, tmap->name) < 0)
242                {
243                  char emsg[1024];
244                  map *tmpMap = getMap (mi->content, "length");
245                  sprintf (emsg,
246                           _
247                           ("ZOO-Kernel was unable to load your data for %s position %s."),
248                           mi->name, tmpMap->value);
249                  errorException (m, emsg, "InternalError", NULL);
250                  return -1;
251                }
252            }
253          else
254            {
255              char emsg[1024];
256              sprintf (emsg,
257                       _
258                       ("The maximum allowed occurrences for <%s> is one."),
259                       mi->name);
260              errorException (m, emsg, "InternalError", NULL);
261              return -1;
262            }
263        }
264    }
265  return 0;
266}
267
268/**
269 * Create the profile registry.
270 *
271 * The profile registry is optional (created only if the registry key is
272 * available in the [main] section of the main.cfg file) and can be used to
273 * store the profiles hierarchy. The registry is a directory which should
274 * contain the following sub-directories:
275 *  * concept: direcotry containing .html files describing concept
276 *  * generic: directory containing .zcfg files for wps:GenericProcess
277 *  * implementation: directory containing .zcfg files for wps:Process
278 *
279 * @param m the conf maps containing the main.cfg settings
280 * @param r the registry to update
281 * @param reg_dir the resgitry
282 * @param saved_stdout the saved stdout identifier
283 * @return 0 if the resgitry is null or was correctly updated, -1 on failure
284 */
285int
286createRegistry (maps* m,registry ** r, char *reg_dir, int saved_stdout)
287{
288  struct dirent *dp;
289  int scount = 0;
290
291  if (reg_dir == NULL)
292    return 0;
293  DIR *dirp = opendir (reg_dir);
294  if (dirp == NULL)
295    {
296      return -1;
297    }
298  while ((dp = readdir (dirp)) != NULL){
299    if ((dp->d_type == DT_DIR || dp->d_type == DT_LNK) && dp->d_name[0] != '.')
300      {
301
302        char * tmpName =
303          (char *) malloc ((strlen (reg_dir) + strlen (dp->d_name) + 2) *
304                           sizeof (char));
305        sprintf (tmpName, "%s/%s", reg_dir, dp->d_name);
306       
307        DIR *dirp1 = opendir (tmpName);
308        struct dirent *dp1;
309        while ((dp1 = readdir (dirp1)) != NULL){
310          char* extn = strstr(dp1->d_name, ".zcfg");
311          if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
312            {
313              int t;
314              char *tmps1=
315                (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
316                                 sizeof (char));
317              sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
318              char *tmpsn = zStrdup (dp1->d_name);
319              tmpsn[strlen (tmpsn) - 5] = 0;
320              service* s1 = (service *) malloc (SERVICE_SIZE);
321              if (s1 == NULL)
322                {
323                  dup2 (saved_stdout, fileno (stdout));
324                  errorException (m, _("Unable to allocate memory."),
325                                  "InternalError", NULL);
326                  return -1;
327                }
328              t = readServiceFile (m, tmps1, &s1, tmpsn);
329              free (tmpsn);
330              if (t < 0)
331                {
332                  map *tmp00 = getMapFromMaps (m, "lenv", "message");
333                  char tmp01[1024];
334                  if (tmp00 != NULL)
335                    sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
336                             dp1->d_name, tmp00->value);
337                  else
338                    sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
339                             dp1->d_name);
340                  dup2 (saved_stdout, fileno (stdout));
341                  errorException (m, tmp01, "InternalError", NULL);
342                  return -1;
343                }
344#ifdef DEBUG
345              dumpService (s1);
346              fflush (stdout);
347              fflush (stderr);
348#endif
349              if(strncasecmp(dp->d_name,"implementation",14)==0){
350                inheritance(*r,&s1);
351              }
352              addServiceToRegistry(r,dp->d_name,s1);
353              freeService (&s1);
354              free (s1);
355              scount++;
356            }
357        }
358        (void) closedir (dirp1);
359      }
360  }
361  (void) closedir (dirp);
362  return 0;
363}
364
365/**
366 * Recursivelly parse zcfg starting from the ZOO-Kernel cwd.
367 * Call the func function given in arguments after parsing the ZCFG file.
368 *
369 * @param m the conf maps containing the main.cfg settings
370 * @param r the registry containing profiles hierarchy
371 * @param n the root XML Node to add the sub-elements
372 * @param conf_dir the location of the main.cfg file (basically cwd)
373 * @param prefix the current prefix if any, or NULL
374 * @param saved_stdout the saved stdout identifier
375 * @param level the current level (number of sub-directories to reach the
376 * current path)
377 * @see inheritance, readServiceFile
378 */
379int
380recursReaddirF (maps * m, registry *r, xmlNodePtr n, char *conf_dir, char *prefix,
381                int saved_stdout, int level, void (func) (maps *, xmlNodePtr,
382                                                          service *))
383{
384  struct dirent *dp;
385  int scount = 0;
386
387  if (conf_dir == NULL)
388    return 1;
389  DIR *dirp = opendir (conf_dir);
390  if (dirp == NULL)
391    {
392      if (level > 0)
393        return 1;
394      else
395        return -1;
396    }
397  char tmp1[25];
398  sprintf (tmp1, "sprefix_%d", level);
399  char levels[17];
400  sprintf (levels, "%d", level);
401  setMapInMaps (m, "lenv", "level", levels);
402  while ((dp = readdir (dirp)) != NULL)
403    if ((dp->d_type == DT_DIR || dp->d_type == DT_LNK) && dp->d_name[0] != '.'
404        && strstr (dp->d_name, ".") == NULL)
405      {
406
407        char *tmp =
408          (char *) malloc ((strlen (conf_dir) + strlen (dp->d_name) + 2) *
409                           sizeof (char));
410        sprintf (tmp, "%s/%s", conf_dir, dp->d_name);
411
412        if (prefix != NULL)
413          {
414            prefix = NULL;
415          }
416        prefix = (char *) malloc ((strlen (dp->d_name) + 2) * sizeof (char));
417        sprintf (prefix, "%s.", dp->d_name);
418
419        //map* tmpMap=getMapFromMaps(m,"lenv",tmp1);
420
421        int res;
422        if (prefix != NULL)
423          {
424            setMapInMaps (m, "lenv", tmp1, prefix);
425            char levels1[17];
426            sprintf (levels1, "%d", level + 1);
427            setMapInMaps (m, "lenv", "level", levels1);
428            res =
429              recursReaddirF (m, r, n, tmp, prefix, saved_stdout, level + 1,
430                              func);
431            sprintf (levels1, "%d", level);
432            setMapInMaps (m, "lenv", "level", levels1);
433            free (prefix);
434            prefix = NULL;
435          }
436        else
437          res = -1;
438        free (tmp);
439        if (res < 0)
440          {
441            return res;
442          }
443      }
444    else
445      {
446        char* extn = strstr(dp->d_name, ".zcfg");
447        if(dp->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
448          {
449            int t;
450            char tmps1[1024];
451            memset (tmps1, 0, 1024);
452            snprintf (tmps1, 1024, "%s/%s", conf_dir, dp->d_name);
453            service *s1 = (service *) malloc (SERVICE_SIZE);
454            if (s1 == NULL)
455              {
456                dup2 (saved_stdout, fileno (stdout));
457                errorException (m, _("Unable to allocate memory."),
458                                "InternalError", NULL);
459                return -1;
460              }
461#ifdef DEBUG
462            fprintf (stderr, "#################\n%s\n#################\n",
463                     tmps1);
464#endif
465            char *tmpsn = zStrdup (dp->d_name);
466            tmpsn[strlen (tmpsn) - 5] = 0;
467            t = readServiceFile (m, tmps1, &s1, tmpsn);
468            free (tmpsn);
469            if (t < 0)
470              {
471                map *tmp00 = getMapFromMaps (m, "lenv", "message");
472                char tmp01[1024];
473                if (tmp00 != NULL)
474                  sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
475                           dp->d_name, tmp00->value);
476                else
477                  sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
478                           dp->d_name);
479                dup2 (saved_stdout, fileno (stdout));
480                errorException (m, tmp01, "InternalError", NULL);
481                return -1;
482              }
483#ifdef DEBUG
484            dumpService (s1);
485            fflush (stdout);
486            fflush (stderr);
487#endif
488            inheritance(r,&s1);
489            func (m, n, s1);
490            freeService (&s1);
491            free (s1);
492            scount++;
493          }
494      }
495  (void) closedir (dirp);
496  return 1;
497}
498
499/**
500 * Apply XPath Expression on XML document.
501 *
502 * @param doc the XML Document
503 * @param search the XPath expression
504 * @return xmlXPathObjectPtr containing the resulting nodes set
505 */
506xmlXPathObjectPtr
507extractFromDoc (xmlDocPtr doc, const char *search)
508{
509  xmlXPathContextPtr xpathCtx;
510  xmlXPathObjectPtr xpathObj;
511  xpathCtx = xmlXPathNewContext (doc);
512  xpathObj = xmlXPathEvalExpression (BAD_CAST search, xpathCtx);
513  xmlXPathFreeContext (xpathCtx);
514  return xpathObj;
515}
516
517/**
518 * Signal handling function which simply call exit(0).
519 *
520 * @param sig the signal number
521 */
522void
523donothing (int sig)
524{
525#ifdef DEBUG
526  fprintf (stderr, "Signal %d after the ZOO-Kernel returned result!\n", sig);
527#endif
528  exit (0);
529}
530
531/**
532 * Signal handling function which create an ExceptionReport node containing the
533 * information message corresponding to the signal number.
534 *
535 * @param sig the signal number
536 */
537void
538sig_handler (int sig)
539{
540  char tmp[100];
541  const char *ssig;
542  switch (sig)
543    {
544    case SIGSEGV:
545      ssig = "SIGSEGV";
546      break;
547    case SIGTERM:
548      ssig = "SIGTERM";
549      break;
550    case SIGINT:
551      ssig = "SIGINT";
552      break;
553    case SIGILL:
554      ssig = "SIGILL";
555      break;
556    case SIGFPE:
557      ssig = "SIGFPE";
558      break;
559    case SIGABRT:
560      ssig = "SIGABRT";
561      break;
562    default:
563      ssig = "UNKNOWN";
564      break;
565    }
566  sprintf (tmp,
567           _
568           ("ZOO Kernel failed to process your request, receiving signal %d = %s"),
569           sig, ssig);
570  errorException (NULL, tmp, "InternalError", NULL);
571#ifdef DEBUG
572  fprintf (stderr, "Not this time!\n");
573#endif
574  exit (0);
575}
576
577/**
578 * Load a service provider and run the service function.
579 *
580 * @param myMap the conf maps containing the main.cfg settings
581 * @param s1 the service structure
582 * @param request_inputs map storing all the request parameters
583 * @param inputs the inputs maps
584 * @param ioutputs the outputs maps
585 * @param eres the result returned by the service execution
586 */
587void
588loadServiceAndRun (maps ** myMap, service * s1, map * request_inputs,
589                   maps ** inputs, maps ** ioutputs, int *eres)
590{
591  char tmps1[1024];
592  char ntmp[1024];
593  maps *m = *myMap;
594  maps *request_output_real_format = *ioutputs;
595  maps *request_input_real_format = *inputs;
596  /**
597   * Extract serviceType to know what kind of service should be loaded
598   */
599  map *r_inputs = NULL;
600#ifndef WIN32
601  getcwd (ntmp, 1024);
602#else
603  _getcwd (ntmp, 1024);
604#endif
605  r_inputs = getMap (s1->content, "serviceType");
606#ifdef DEBUG
607  fprintf (stderr, "LOAD A %s SERVICE PROVIDER \n", r_inputs->value);
608  fflush (stderr);
609#endif
610
611  map* libp = getMapFromMaps(m, "main", "libPath");
612 
613  if (strlen (r_inputs->value) == 1
614      && strncasecmp (r_inputs->value, "C", 1) == 0)
615  {
616     if (libp != NULL && libp->value != NULL) {
617            r_inputs = getMap (s1->content, "ServiceProvider");
618                sprintf (tmps1, "%s/%s", libp->value, r_inputs->value);
619         }
620     else {     
621        r_inputs = getMap (request_inputs, "metapath");
622        if (r_inputs != NULL)
623          sprintf (tmps1, "%s/%s", ntmp, r_inputs->value);
624        else
625          sprintf (tmps1, "%s/", ntmp);
626         
627        char *altPath = zStrdup (tmps1);
628        r_inputs = getMap (s1->content, "ServiceProvider");
629        sprintf (tmps1, "%s/%s", altPath, r_inputs->value);
630        free (altPath);
631         }
632#ifdef DEBUG
633      fprintf (stderr, "Trying to load %s\n", tmps1);
634#endif
635#ifdef WIN32
636      HINSTANCE so =
637        LoadLibraryEx (tmps1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
638#else
639      void *so = dlopen (tmps1, RTLD_LAZY);
640#endif
641#ifdef WIN32
642      char* errstr = getLastErrorMessage();
643#else
644      char *errstr;
645      errstr = dlerror ();
646#endif
647#ifdef DEBUG
648          fprintf (stderr, "%s loaded (%s) \n", tmps1, errstr);
649#endif
650      if (so != NULL)
651        {
652#ifdef DEBUG
653          fprintf (stderr, "Library loaded %s \n", errstr);
654          fprintf (stderr, "Service Shared Object = %s\n", r_inputs->value);
655#endif
656          r_inputs = getMap (s1->content, "serviceType");
657#ifdef DEBUG
658          dumpMap (r_inputs);
659          fprintf (stderr, "%s\n", r_inputs->value);
660          fflush (stderr);
661#endif
662          if (strncasecmp (r_inputs->value, "C-FORTRAN", 9) == 0)
663            {
664              r_inputs = getMap (request_inputs, "Identifier");
665              char fname[1024];
666              sprintf (fname, "%s_", r_inputs->value);
667#ifdef DEBUG
668              fprintf (stderr, "Try to load function %s\n", fname);
669#endif
670#ifdef WIN32
671              typedef int (CALLBACK * execute_t) (char ***, char ***,
672                                                  char ***);
673              execute_t execute = (execute_t) GetProcAddress (so, fname);
674#else
675              typedef int (*execute_t) (char ***, char ***, char ***);
676              execute_t execute = (execute_t) dlsym (so, fname);
677#endif
678#ifdef DEBUG
679#ifdef WIN32
680                          errstr = getLastErrorMessage();
681#else
682              errstr = dlerror ();
683#endif
684              fprintf (stderr, "Function loaded %s\n", errstr);
685#endif
686
687              char main_conf[10][30][1024];
688              char inputs[10][30][1024];
689              char outputs[10][30][1024];
690              for (int i = 0; i < 10; i++)
691                {
692                  for (int j = 0; j < 30; j++)
693                    {
694                      memset (main_conf[i][j], 0, 1024);
695                      memset (inputs[i][j], 0, 1024);
696                      memset (outputs[i][j], 0, 1024);
697                    }
698                }
699              mapsToCharXXX (m, (char ***) main_conf);
700              mapsToCharXXX (request_input_real_format, (char ***) inputs);
701              mapsToCharXXX (request_output_real_format, (char ***) outputs);
702              *eres =
703                execute ((char ***) &main_conf[0], (char ***) &inputs[0],
704                         (char ***) &outputs[0]);
705#ifdef DEBUG
706              fprintf (stderr, "Function run successfully \n");
707#endif
708              charxxxToMaps ((char ***) &outputs[0],
709                             &request_output_real_format);
710            }
711          else
712            {
713#ifdef DEBUG
714#ifdef WIN32
715                          errstr = getLastErrorMessage();
716              fprintf (stderr, "Function %s failed to load because of %s\n",
717                       r_inputs->value, errstr);
718#endif
719#endif
720              r_inputs = getMapFromMaps (m, "lenv", "Identifier");
721#ifdef DEBUG
722              fprintf (stderr, "Try to load function %s\n", r_inputs->value);
723#endif
724              typedef int (*execute_t) (maps **, maps **, maps **);
725#ifdef WIN32
726              execute_t execute =
727                (execute_t) GetProcAddress (so, r_inputs->value);
728#else
729              execute_t execute = (execute_t) dlsym (so, r_inputs->value);
730#endif
731
732              if (execute == NULL)
733                {
734#ifdef WIN32
735                                  errstr = getLastErrorMessage();
736#else
737                  errstr = dlerror ();
738#endif
739                  char *tmpMsg =
740                    (char *) malloc (2048 + strlen (r_inputs->value));
741                  sprintf (tmpMsg,
742                           _
743                           ("Error occured while running the %s function: %s"),
744                           r_inputs->value, errstr);
745                  errorException (m, tmpMsg, "InternalError", NULL);
746                  free (tmpMsg);
747#ifdef DEBUG
748                  fprintf (stderr, "Function %s error %s\n", r_inputs->value,
749                           errstr);
750#endif
751                  *eres = -1;
752                  return;
753                }
754
755#ifdef DEBUG
756#ifdef WIN32
757                          errstr = getLastErrorMessage();
758#else
759              errstr = dlerror ();
760#endif
761              fprintf (stderr, "Function loaded %s\n", errstr);
762#endif
763
764#ifdef DEBUG
765              fprintf (stderr, "Now run the function \n");
766              fflush (stderr);
767#endif
768              *eres =
769                execute (&m, &request_input_real_format,
770                         &request_output_real_format);
771#ifdef DEBUG
772              fprintf (stderr, "Function loaded and returned %d\n", eres);
773              fflush (stderr);
774#endif
775            }
776#ifdef WIN32
777          *ioutputs = dupMaps (&request_output_real_format);
778          FreeLibrary (so);
779#else
780          dlclose (so);
781#endif
782        }
783      else
784        {
785      /**
786       * Unable to load the specified shared library
787       */
788          char tmps[1024];
789#ifdef WIN32
790                  errstr = getLastErrorMessage();
791#else
792              errstr = dlerror ();
793#endif
794          sprintf (tmps, _("Unable to load C Library %s"), errstr);
795          errorException(m,tmps,"InternalError",NULL);
796          *eres = -1;
797        }
798    }
799  else
800
801#ifdef USE_OTB
802  if (strncasecmp (r_inputs->value, "OTB", 6) == 0)
803    {
804      *eres =
805        zoo_otb_support (&m, request_inputs, s1,
806                            &request_input_real_format,
807                            &request_output_real_format);
808    }
809  else
810#endif
811
812#ifdef USE_PYTHON
813  if (strncasecmp (r_inputs->value, "PYTHON", 6) == 0)
814    {
815      *eres =
816        zoo_python_support (&m, request_inputs, s1,
817                            &request_input_real_format,
818                            &request_output_real_format);
819    }
820  else
821#endif
822
823#ifdef USE_JAVA
824  if (strncasecmp (r_inputs->value, "JAVA", 4) == 0)
825    {
826      *eres =
827        zoo_java_support (&m, request_inputs, s1, &request_input_real_format,
828                          &request_output_real_format);
829    }
830  else
831#endif
832
833#ifdef USE_PHP
834  if (strncasecmp (r_inputs->value, "PHP", 3) == 0)
835    {
836      *eres =
837        zoo_php_support (&m, request_inputs, s1, &request_input_real_format,
838                         &request_output_real_format);
839    }
840  else
841#endif
842
843
844#ifdef USE_PERL
845  if (strncasecmp (r_inputs->value, "PERL", 4) == 0)
846    {
847      *eres =
848        zoo_perl_support (&m, request_inputs, s1, &request_input_real_format,
849                          &request_output_real_format);
850    }
851  else
852#endif
853
854#ifdef USE_JS
855  if (strncasecmp (r_inputs->value, "JS", 2) == 0)
856    {
857      *eres =
858        zoo_js_support (&m, request_inputs, s1, &request_input_real_format,
859                        &request_output_real_format);
860    }
861  else
862#endif
863
864#ifdef USE_RUBY
865  if (strncasecmp (r_inputs->value, "Ruby", 4) == 0)
866    {
867      *eres =
868        zoo_ruby_support (&m, request_inputs, s1, &request_input_real_format,
869                          &request_output_real_format);
870    }
871  else
872#endif
873
874    {
875      char tmpv[1024];
876      sprintf (tmpv,
877               _
878               ("Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n"),
879               r_inputs->value);
880      errorException (m, tmpv, "InternalError", NULL);
881      *eres = -1;
882    }
883  *myMap = m;
884  *ioutputs = request_output_real_format;
885}
886
887
888#ifdef WIN32
889/**
890 * createProcess function: create a new process after setting some env variables
891 */
892void
893createProcess (maps * m, map * request_inputs, service * s1, char *opts,
894               int cpid, maps * inputs, maps * outputs)
895{
896  STARTUPINFO si;
897  PROCESS_INFORMATION pi;
898  ZeroMemory (&si, sizeof (si));
899  si.cb = sizeof (si);
900  ZeroMemory (&pi, sizeof (pi));
901  char *tmp = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
902  char *tmpq = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
903  map *req = getMap (request_inputs, "request");
904  map *id = getMap (request_inputs, "identifier");
905  map *di = getMap (request_inputs, "DataInputs");
906
907  // The required size for the dataInputsKVP and dataOutputsKVP buffers
908  // may exceed cgiContentLength, hence a 2 kb extension. However, a
909  // better solution would be to have getMapsAsKVP() determine the required
910  // buffer size before allocating memory.     
911  char *dataInputsKVP = getMapsAsKVP (inputs, cgiContentLength + 2048, 0);
912  char *dataOutputsKVP = getMapsAsKVP (outputs, cgiContentLength + 2048, 1);
913#ifdef DEBUG
914  fprintf (stderr, "DATAINPUTSKVP %s\n", dataInputsKVP);
915  fprintf (stderr, "DATAOUTPUTSKVP %s\n", dataOutputsKVP);
916#endif
917  map *sid = getMapFromMaps (m, "lenv", "sid");
918  map *r_inputs = getMapFromMaps (m, "main", "tmpPath");
919  map *r_inputs1 = getMap (request_inputs, "metapath");
920 
921  int hasIn = -1;
922  if (r_inputs1 == NULL)
923    {
924      r_inputs1 = createMap ("metapath", "");
925      hasIn = 1;
926    }
927  map *r_inputs2 = getMap (request_inputs, "ResponseDocument");
928  if (r_inputs2 == NULL)
929    r_inputs2 = getMap (request_inputs, "RawDataOutput");
930  map *tmpPath = getMapFromMaps (m, "lenv", "cwd");
931
932  map *tmpReq = getMap (request_inputs, "xrequest");
933 
934  if(r_inputs2 != NULL && tmpReq != NULL) {
935        const char key[] = "rfile=";
936        char* kvp = (char*) malloc((FILENAME_MAX + strlen(key))*sizeof(char));
937        char* filepath = kvp + strlen(key);
938        strncpy(kvp, key, strlen(key));
939        addToCache(m, tmpReq->value, tmpReq->value, "text/xml", strlen(tmpReq->value), 
940                   filepath, FILENAME_MAX);                               
941    if (filepath == NULL) {
942        errorException( m, _("Unable to cache HTTP POST Execute request."), "InternalError", NULL); 
943                return;
944    }   
945        sprintf(tmp,"\"metapath=%s&%s&cgiSid=%s",
946                r_inputs1->value,kvp,sid->value);
947    sprintf(tmpq,"metapath=%s&%s",
948                r_inputs1->value,kvp);
949        free(kvp);             
950  }
951  else if (r_inputs2 != NULL)
952    {
953      sprintf (tmp,
954               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s&cgiSid=%s",
955               r_inputs1->value, req->value, id->value, dataInputsKVP,
956               r_inputs2->name, dataOutputsKVP, sid->value);
957      sprintf (tmpq,
958               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s",
959               r_inputs1->value, req->value, id->value, dataInputsKVP,
960               r_inputs2->name, dataOutputsKVP);                   
961    }
962  else
963    {
964      sprintf (tmp,
965               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&cgiSid=%s",
966               r_inputs1->value, req->value, id->value, dataInputsKVP,
967               sid->value);
968      sprintf (tmpq,
969               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s",
970               r_inputs1->value, req->value, id->value, dataInputsKVP,
971               sid->value);   
972    }
973
974  if (hasIn > 0)
975    {
976      freeMap (&r_inputs1);
977      free (r_inputs1);
978    }
979  char *tmp1 = zStrdup (tmp);
980  sprintf (tmp, "\"%s\" %s \"%s\"", PROGRAMNAME, tmp1, sid->value); 
981  free (dataInputsKVP);
982  free (dataOutputsKVP);
983#ifdef DEBUG
984  fprintf (stderr, "REQUEST IS : %s \n", tmp);
985#endif
986
987  map* usid = getMapFromMaps (m, "lenv", "usid");
988  if (usid != NULL && usid->value != NULL) {
989    SetEnvironmentVariable("USID", TEXT (usid->value));
990  }
991
992  SetEnvironmentVariable ("CGISID", TEXT (sid->value));
993  SetEnvironmentVariable ("QUERY_STRING", TEXT (tmpq));
994  // knut: Prevent REQUEST_METHOD=POST in background process call to cgic:main (process hangs when reading cgiIn):
995  SetEnvironmentVariable("REQUEST_METHOD", "GET");
996 
997  char clen[1000];
998  sprintf (clen, "%d", strlen (tmpq));
999  SetEnvironmentVariable ("CONTENT_LENGTH", TEXT (clen));
1000
1001  if (!CreateProcess (NULL,     // No module name (use command line)
1002                      TEXT (tmp),       // Command line
1003                      NULL,     // Process handle not inheritable
1004                      NULL,     // Thread handle not inheritable
1005                      FALSE,    // Set handle inheritance to FALSE
1006                      CREATE_NO_WINDOW, // Apache won't wait until the end
1007                      NULL,     // Use parent's environment block
1008                      NULL,     // Use parent's starting directory
1009                      &si,      // Pointer to STARTUPINFO struct
1010                      &pi)      // Pointer to PROCESS_INFORMATION struct
1011    )
1012    {
1013#ifdef DEBUG
1014      fprintf (stderr, "CreateProcess failed (%d).\n", GetLastError ());
1015#endif
1016      if (tmp != NULL) {
1017        free(tmp);
1018      }
1019      if (tmpq != NULL) {
1020        free(tmpq);
1021      }         
1022      return;
1023    }
1024  else
1025    {
1026#ifdef DEBUG
1027      fprintf (stderr, "CreateProcess successful (%d).\n\n\n\n",
1028               GetLastError ());
1029#endif
1030    }
1031  CloseHandle (pi.hProcess);
1032  CloseHandle (pi.hThread);
1033 
1034  if (tmp != NULL) {
1035    free(tmp);
1036  }
1037  if (tmpq != NULL) {
1038    free(tmpq);
1039  }
1040 
1041#ifdef DEBUG
1042  fprintf (stderr, "CreateProcess finished !\n");
1043#endif
1044}
1045#endif
1046
1047/**
1048 * Process the request.
1049 *
1050 * @param inputs the request parameters map
1051 * @return 0 on sucess, other value on failure
1052 * @see conf_read,recursReaddirF
1053 */
1054int
1055runRequest (map ** inputs)
1056{
1057
1058#ifndef USE_GDB
1059#ifndef WIN32
1060  signal (SIGCHLD, SIG_IGN);
1061#endif 
1062  signal (SIGSEGV, sig_handler);
1063  signal (SIGTERM, sig_handler);
1064  signal (SIGINT, sig_handler);
1065  signal (SIGILL, sig_handler);
1066  signal (SIGFPE, sig_handler);
1067  signal (SIGABRT, sig_handler);
1068#endif
1069
1070  map *r_inputs = NULL;
1071  map *request_inputs = *inputs;
1072#ifdef IGNORE_METAPATH
1073  addToMap(request_inputs, "metapath", "");
1074#endif 
1075  maps *m = NULL;
1076  char *REQUEST = NULL;
1077  /**
1078   * Parsing service specfic configuration file
1079   */
1080  m = (maps *) malloc (MAPS_SIZE);
1081  if (m == NULL)
1082    {
1083      return errorException (m, _("Unable to allocate memory."),
1084                             "InternalError", NULL);
1085    }
1086  char ntmp[1024];
1087#ifndef WIN32
1088  getcwd (ntmp, 1024);
1089#else
1090  _getcwd (ntmp, 1024);
1091#endif
1092  r_inputs = getMapOrFill (&request_inputs, "metapath", "");
1093
1094  char conf_file[10240];
1095  snprintf (conf_file, 10240, "%s/%s/main.cfg", ntmp, r_inputs->value);
1096  if (conf_read (conf_file, m) == 2)
1097    {
1098      errorException (NULL, _("Unable to load the main.cfg file."),
1099                      "InternalError", NULL);
1100      free (m);
1101      return 1;
1102    }
1103#ifdef DEBUG
1104  fprintf (stderr, "***** BEGIN MAPS\n");
1105  dumpMaps (m);
1106  fprintf (stderr, "***** END MAPS\n");
1107#endif
1108
1109  map *getPath = getMapFromMaps (m, "main", "gettextPath");
1110  if (getPath != NULL)
1111    {
1112      bindtextdomain ("zoo-kernel", getPath->value);
1113      bindtextdomain ("zoo-services", getPath->value);
1114    }
1115  else
1116    {
1117      bindtextdomain ("zoo-kernel", "/usr/share/locale/");
1118      bindtextdomain ("zoo-services", "/usr/share/locale/");
1119    }
1120
1121
1122  /**
1123   * Manage our own error log file (usefull to separate standard apache debug
1124   * messages from the ZOO-Kernel ones but also for IIS users to avoid wrong
1125   * headers messages returned by the CGI due to wrong redirection of stderr)
1126   */
1127  FILE *fstde = NULL;
1128  map *fstdem = getMapFromMaps (m, "main", "logPath");
1129  if (fstdem != NULL)
1130    fstde = freopen (fstdem->value, "a+", stderr);
1131
1132  r_inputs = getMap (request_inputs, "language");
1133  if (r_inputs == NULL)
1134    r_inputs = getMapFromMaps (m, "main", "language");
1135  if (r_inputs != NULL)
1136    {
1137      if (isValidLang (m, r_inputs->value) < 0)
1138        {
1139          char tmp[1024];
1140          sprintf (tmp,
1141                   _
1142                   ("The value %s is not supported for the <language> parameter"),
1143                   r_inputs->value);
1144          errorException (m, tmp, "InvalidParameterValue", "language");
1145          freeMaps (&m);
1146          free (m);
1147          free (REQUEST);
1148          return 1;
1149
1150        }
1151      char *tmp = zStrdup (r_inputs->value);
1152      setMapInMaps (m, "main", "language", tmp);
1153#ifdef DEB
1154      char tmp2[12];
1155      sprintf (tmp2, "%s.utf-8", tmp);
1156      translateChar (tmp2, '-', '_');
1157      setlocale (LC_ALL, tmp2);
1158#else
1159      translateChar (tmp, '-', '_');
1160      setlocale (LC_ALL, tmp);
1161#endif
1162#ifndef WIN32
1163      setenv ("LC_ALL", tmp, 1);
1164#else
1165      char tmp1[12];
1166      sprintf (tmp1, "LC_ALL=%s", tmp);
1167      putenv (tmp1);
1168#endif
1169      free (tmp);
1170    }
1171  else
1172    {
1173      setlocale (LC_ALL, "en_US");
1174#ifndef WIN32
1175      setenv ("LC_ALL", "en_US", 1);
1176#else
1177      char tmp1[12];
1178      sprintf (tmp1, "LC_ALL=en_US");
1179      putenv (tmp1);
1180#endif
1181      setMapInMaps (m, "main", "language", "en-US");
1182    }
1183  setlocale (LC_NUMERIC, "en_US");
1184  bind_textdomain_codeset ("zoo-kernel", "UTF-8");
1185  textdomain ("zoo-kernel");
1186  bind_textdomain_codeset ("zoo-services", "UTF-8");
1187  textdomain ("zoo-services");
1188
1189  map *lsoap = getMap (request_inputs, "soap");
1190  if (lsoap != NULL && strcasecmp (lsoap->value, "true") == 0)
1191    setMapInMaps (m, "main", "isSoap", "true");
1192  else
1193    setMapInMaps (m, "main", "isSoap", "false");
1194
1195  if(strlen(cgiServerName)>0)
1196  {
1197    char tmpUrl[1024];
1198       
1199        if ( getenv("HTTPS") != NULL && strncmp(getenv("HTTPS"), "on", 2) == 0 ) { // Knut: check if non-empty instead of "on"?         
1200                if ( strncmp(cgiServerPort, "443", 3) == 0 ) { 
1201                        sprintf(tmpUrl, "https://%s%s", cgiServerName, cgiScriptName);
1202                }
1203                else {
1204                        sprintf(tmpUrl, "https://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1205                }
1206        }
1207        else {
1208                if ( strncmp(cgiServerPort, "80", 2) == 0 ) { 
1209                        sprintf(tmpUrl, "http://%s%s", cgiServerName, cgiScriptName);
1210                }
1211                else {
1212                        sprintf(tmpUrl, "http://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1213                }
1214        }
1215#ifdef DEBUG
1216    fprintf(stderr,"*** %s ***\n",tmpUrl);
1217#endif
1218    setMapInMaps(m,"main","serverAddress",tmpUrl);
1219  }
1220
1221  /**
1222   * Check for minimum inputs
1223   */
1224  map* err=NULL;
1225  const char *vvr[]={
1226    "GetCapabilities",
1227    "DescribeProcess",
1228    "Execute",
1229    NULL
1230  };
1231  checkValidValue(request_inputs,&err,"Request",(const char**)vvr,1);
1232  const char *vvs[]={
1233    "WPS",
1234    NULL
1235  };
1236  if(err!=NULL){
1237    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
1238    printExceptionReportResponse (m, err);
1239    freeMap(&err);
1240    free(err);
1241    if (count (request_inputs) == 1)
1242      {
1243        freeMap (&request_inputs);
1244        free (request_inputs);
1245      }
1246    freeMaps (&m);
1247    free (m);
1248    return 1;
1249  }
1250  checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
1251  const char *vvv[]={
1252    "1.0.0",
1253    NULL
1254  };
1255  r_inputs = getMap (request_inputs, "Request");
1256  REQUEST = zStrdup (r_inputs->value);
1257  if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
1258    checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
1259    checkValidValue(request_inputs,&err,"identifier",NULL,1);
1260  }else{
1261    checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
1262  }
1263  if(err!=NULL){
1264    printExceptionReportResponse (m, err);
1265    freeMap(&err);
1266    free(err);
1267    if (count (request_inputs) == 1)
1268      {
1269        freeMap (&request_inputs);
1270        free (request_inputs);
1271      }
1272    free(REQUEST);
1273    freeMaps (&m);
1274    free (m);
1275    return 1;
1276  }
1277
1278  r_inputs = getMap (request_inputs, "serviceprovider");
1279  if (r_inputs == NULL)
1280    {
1281      addToMap (request_inputs, "serviceprovider", "");
1282    }
1283
1284  maps *request_output_real_format = NULL;
1285  map *tmpm = getMapFromMaps (m, "main", "serverAddress");
1286  if (tmpm != NULL)
1287    SERVICE_URL = zStrdup (tmpm->value);
1288  else
1289    SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
1290
1291
1292
1293  service *s1;
1294  int scount = 0;
1295#ifdef DEBUG
1296  dumpMap (r_inputs);
1297#endif
1298  char conf_dir[1024];
1299  int t;
1300  char tmps1[1024];
1301
1302  r_inputs = NULL;
1303  r_inputs = getMap (request_inputs, "metapath");
1304 
1305  if (r_inputs != NULL)
1306    snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
1307  else
1308    snprintf (conf_dir, 1024, "%s", ntmp);
1309
1310  map* reg = getMapFromMaps (m, "main", "registry");
1311  registry* zooRegistry=NULL;
1312  if(reg!=NULL){
1313    int saved_stdout = dup (fileno (stdout));
1314    dup2 (fileno (stderr), fileno (stdout));
1315    createRegistry (m,&zooRegistry,reg->value,saved_stdout);
1316    dup2 (saved_stdout, fileno (stdout));
1317  }
1318
1319  if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
1320    {
1321#ifdef DEBUG
1322      dumpMap (r_inputs);
1323#endif
1324      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
1325      r_inputs = NULL;
1326      //r_inputs = getMap (request_inputs, "ServiceProvider");
1327      xmlNodePtr n=printGetCapabilitiesHeader(doc,m);
1328      /**
1329       * Here we need to close stdout to ensure that unsupported chars
1330       * has been found in the zcfg and then printed on stdout
1331       */
1332      int saved_stdout = dup (fileno (stdout));
1333      dup2 (fileno (stderr), fileno (stdout));
1334      if (int res =               
1335          recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
1336                          printGetCapabilitiesForProcess) < 0)
1337        {
1338          freeMaps (&m);
1339          free (m);
1340          if(zooRegistry!=NULL){
1341            freeRegistry(&zooRegistry);
1342            free(zooRegistry);
1343          }
1344          free (REQUEST);
1345          free (SERVICE_URL);
1346          fflush (stdout);
1347          return res;
1348        }
1349      dup2 (saved_stdout, fileno (stdout));
1350      printDocument (m, doc, getpid ());
1351      freeMaps (&m);
1352      free (m);
1353      if(zooRegistry!=NULL){
1354        freeRegistry(&zooRegistry);
1355        free(zooRegistry);
1356      }
1357      free (REQUEST);
1358      free (SERVICE_URL);
1359      fflush (stdout);
1360      return 0;
1361    }
1362  else
1363    {
1364      r_inputs = getMap (request_inputs, "Identifier");
1365
1366      struct dirent *dp;
1367      DIR *dirp = opendir (conf_dir);
1368      if (dirp == NULL)
1369        {
1370          errorException (m, _("The specified path path does not exist."),
1371                          "InvalidParameterValue", conf_dir);
1372          freeMaps (&m);
1373          free (m);
1374          if(zooRegistry!=NULL){
1375            freeRegistry(&zooRegistry);
1376            free(zooRegistry);
1377          }
1378          free (REQUEST);
1379          free (SERVICE_URL);
1380          return 0;
1381        }
1382      if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
1383        {
1384          /**
1385           * Loop over Identifier list
1386           */
1387          xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
1388          r_inputs = NULL;
1389          xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
1390                                        "ProcessDescriptions");
1391
1392          r_inputs = getMap (request_inputs, "Identifier");
1393
1394          char *orig = zStrdup (r_inputs->value);
1395
1396          int saved_stdout = dup (fileno (stdout));
1397          dup2 (fileno (stderr), fileno (stdout));
1398          if (strcasecmp ("all", orig) == 0)
1399            {
1400              if (int res =
1401                  recursReaddirF (m, zooRegistry, n, conf_dir, NULL, saved_stdout, 0,
1402                                  printDescribeProcessForProcess) < 0)
1403                return res;
1404            }
1405          else
1406            {
1407              char *saveptr;
1408              char *tmps = strtok_r (orig, ",", &saveptr);
1409
1410              char buff[256];
1411              char buff1[1024];
1412              while (tmps != NULL)
1413                {
1414                  int hasVal = -1;
1415                  char *corig = zStrdup (tmps);
1416                  if (strstr (corig, ".") != NULL)
1417                    {
1418
1419                      parseIdentifier (m, conf_dir, corig, buff1);
1420                      map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
1421                      if (tmpMap != NULL)
1422                        addToMap (request_inputs, "metapath", tmpMap->value);
1423                      map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
1424
1425                      s1 = (service *) malloc (SERVICE_SIZE);
1426                      t = readServiceFile (m, buff1, &s1, tmpMapI->value);
1427                      if (t < 0)
1428                        {
1429                          map *tmp00 = getMapFromMaps (m, "lenv", "message");
1430                          char tmp01[1024];
1431                          if (tmp00 != NULL)
1432                            sprintf (tmp01,
1433                                     _
1434                                     ("Unable to parse the ZCFG file for the following ZOO-Service: %s. Message: %s"),
1435                                     tmps, tmp00->value);
1436                          else
1437                            sprintf (tmp01,
1438                                     _
1439                                     ("Unable to parse the ZCFG file for the following ZOO-Service: %s."),
1440                                     tmps);
1441                          dup2 (saved_stdout, fileno (stdout));
1442                          errorException (m, tmp01, "InvalidParameterValue",
1443                                          "identifier");
1444                          freeMaps (&m);
1445                          free (m);
1446                          if(zooRegistry!=NULL){
1447                            freeRegistry(&zooRegistry);
1448                            free(zooRegistry);
1449                          }
1450                          free (REQUEST);
1451                          free (corig);
1452                          free (orig);
1453                          free (SERVICE_URL);
1454                          free (s1);
1455                          closedir (dirp);
1456                          xmlFreeDoc (doc);
1457                          xmlCleanupParser ();
1458                          zooXmlCleanupNs ();
1459                          return 1;
1460                        }
1461#ifdef DEBUG
1462                      dumpService (s1);
1463#endif
1464                      inheritance(zooRegistry,&s1);
1465                      printDescribeProcessForProcess (m, n, s1);
1466                      freeService (&s1);
1467                      free (s1);
1468                      s1 = NULL;
1469                      scount++;
1470                      hasVal = 1;
1471                      setMapInMaps (m, "lenv", "level", "0");
1472                    }
1473                  else
1474                    {
1475                      memset (buff, 0, 256);
1476                      snprintf (buff, 256, "%s.zcfg", corig);
1477                      memset (buff1, 0, 1024);
1478#ifdef DEBUG
1479                      printf ("\n#######%s\n########\n", buff);
1480#endif
1481                      while ((dp = readdir (dirp)) != NULL)
1482                        {
1483                          if (strcasecmp (dp->d_name, buff) == 0)
1484                            {
1485                              memset (buff1, 0, 1024);
1486                              snprintf (buff1, 1024, "%s/%s", conf_dir,
1487                                        dp->d_name);
1488                              s1 = (service *) malloc (SERVICE_SIZE);
1489                              if (s1 == NULL)
1490                                {
1491                                  dup2 (saved_stdout, fileno (stdout));
1492                                  return errorException (m,
1493                                                         _
1494                                                         ("Unable to allocate memory."),
1495                                                         "InternalError",
1496                                                         NULL);
1497                                }
1498#ifdef DEBUG
1499                              printf
1500                                ("#################\n(%s) %s\n#################\n",
1501                                 r_inputs->value, buff1);
1502#endif
1503                              char *tmp0 = zStrdup (dp->d_name);
1504                              tmp0[strlen (tmp0) - 5] = 0;
1505                              t = readServiceFile (m, buff1, &s1, tmp0);
1506                              free (tmp0);
1507                              if (t < 0)
1508                                {
1509                                  map *tmp00 =
1510                                    getMapFromMaps (m, "lenv", "message");
1511                                  char tmp01[1024];
1512                                  if (tmp00 != NULL)
1513                                    sprintf (tmp01,
1514                                             _
1515                                             ("Unable to parse the ZCFG file: %s (%s)"),
1516                                             dp->d_name, tmp00->value);
1517                                  else
1518                                    sprintf (tmp01,
1519                                             _
1520                                             ("Unable to parse the ZCFG file: %s."),
1521                                             dp->d_name);
1522                                  dup2 (saved_stdout, fileno (stdout));
1523                                  errorException (m, tmp01, "InternalError",
1524                                                  NULL);
1525                                  freeMaps (&m);
1526                                  free (m);
1527                                  if(zooRegistry!=NULL){
1528                                    freeRegistry(&zooRegistry);
1529                                    free(zooRegistry);
1530                                  }
1531                                  free (orig);
1532                                  free (REQUEST);
1533                                  closedir (dirp);
1534                                  xmlFreeDoc (doc);
1535                                  xmlCleanupParser ();
1536                                  zooXmlCleanupNs ();
1537                                  return 1;
1538                                }
1539#ifdef DEBUG
1540                              dumpService (s1);
1541#endif
1542                              inheritance(zooRegistry,&s1);
1543                              printDescribeProcessForProcess (m, n, s1);
1544                              freeService (&s1);
1545                              free (s1);
1546                              s1 = NULL;
1547                              scount++;
1548                              hasVal = 1;
1549                            }
1550                        }
1551                    }
1552                  if (hasVal < 0)
1553                    {
1554                      map *tmp00 = getMapFromMaps (m, "lenv", "message");
1555                      char tmp01[1024];
1556                      if (tmp00 != NULL)
1557                        sprintf (tmp01,
1558                                 _("Unable to parse the ZCFG file: %s (%s)"),
1559                                 buff, tmp00->value);
1560                      else
1561                        sprintf (tmp01,
1562                                 _("Unable to parse the ZCFG file: %s."),
1563                                 buff);
1564                      dup2 (saved_stdout, fileno (stdout));
1565                      errorException (m, tmp01, "InvalidParameterValue",
1566                                      "Identifier");
1567                      freeMaps (&m);
1568                      free (m);
1569                      if(zooRegistry!=NULL){
1570                        freeRegistry(&zooRegistry);
1571                        free(zooRegistry);
1572                      }
1573                      free (orig);
1574                      free (REQUEST);
1575                      closedir (dirp);
1576                      xmlFreeDoc (doc);
1577                      xmlCleanupParser ();
1578                      zooXmlCleanupNs ();
1579                      return 1;
1580                    }
1581                  rewinddir (dirp);
1582                  tmps = strtok_r (NULL, ",", &saveptr);
1583                  if (corig != NULL)
1584                    free (corig);
1585                }
1586            }
1587          closedir (dirp);
1588          fflush (stdout);
1589          dup2 (saved_stdout, fileno (stdout));
1590          free (orig);
1591          printDocument (m, doc, getpid ());
1592          freeMaps (&m);
1593          free (m);
1594          if(zooRegistry!=NULL){
1595            freeRegistry(&zooRegistry);
1596            free(zooRegistry);
1597          }
1598          free (REQUEST);
1599          free (SERVICE_URL);
1600          fflush (stdout);
1601          return 0;
1602        }
1603      else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
1604        {
1605          errorException (m,
1606                          _
1607                          ("The <request> value was not recognized. Allowed values are GetCapabilities, DescribeProcess, and Execute."),
1608                          "InvalidParameterValue", "request");
1609#ifdef DEBUG
1610          fprintf (stderr, "No request found %s", REQUEST);
1611#endif
1612          closedir (dirp);
1613          freeMaps (&m);
1614          free (m);
1615          if(zooRegistry!=NULL){
1616            freeRegistry(&zooRegistry);
1617            free(zooRegistry);
1618          }
1619          free (REQUEST);
1620          free (SERVICE_URL);
1621          fflush (stdout);
1622          return 0;
1623        }
1624      closedir (dirp);
1625    }
1626
1627  s1 = NULL;
1628  s1 = (service *) malloc (SERVICE_SIZE);
1629  if (s1 == NULL)
1630    {
1631      freeMaps (&m);
1632      free (m);
1633      if(zooRegistry!=NULL){
1634        freeRegistry(&zooRegistry);
1635        free(zooRegistry);
1636      }
1637      free (REQUEST);
1638      free (SERVICE_URL);
1639      return errorException (m, _("Unable to allocate memory."),
1640                             "InternalError", NULL);
1641    }
1642
1643  r_inputs = getMap (request_inputs, "MetaPath");
1644  if (r_inputs != NULL)
1645    snprintf (tmps1, 1024, "%s/%s", ntmp, r_inputs->value);
1646  else
1647    snprintf (tmps1, 1024, "%s/", ntmp);
1648  r_inputs = getMap (request_inputs, "Identifier");
1649  char *ttmp = zStrdup (tmps1);
1650  snprintf (tmps1, 1024, "%s/%s.zcfg", ttmp, r_inputs->value);
1651  free (ttmp);
1652#ifdef DEBUG
1653  fprintf (stderr, "Trying to load %s\n", tmps1);
1654#endif
1655  if (strstr (r_inputs->value, ".") != NULL)
1656    {
1657      char *identifier = zStrdup (r_inputs->value);
1658      parseIdentifier (m, conf_dir, identifier, tmps1);
1659      map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
1660      if (tmpMap != NULL)
1661        addToMap (request_inputs, "metapath", tmpMap->value);
1662      free (identifier);
1663    }
1664  else
1665    {
1666      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
1667      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
1668    }
1669
1670  r_inputs = getMapFromMaps (m, "lenv", "Identifier");
1671  int saved_stdout = dup (fileno (stdout));
1672  dup2 (fileno (stderr), fileno (stdout));
1673  t = readServiceFile (m, tmps1, &s1, r_inputs->value);
1674  inheritance(zooRegistry,&s1);
1675  if(zooRegistry!=NULL){
1676    freeRegistry(&zooRegistry);
1677    free(zooRegistry);
1678  }
1679  fflush (stdout);
1680  dup2 (saved_stdout, fileno (stdout));
1681  if (t < 0)
1682    {
1683      char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
1684      sprintf (tmpMsg,
1685               _
1686               ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
1687               r_inputs->value);
1688      errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
1689      free (tmpMsg);
1690      free (s1);
1691      freeMaps (&m);
1692      free (m);
1693      free (REQUEST);
1694      free (SERVICE_URL);
1695      return 0;
1696    }
1697  close (saved_stdout);
1698
1699#ifdef DEBUG
1700  dumpService (s1);
1701#endif
1702  int j;
1703
1704
1705  /**
1706   * Create the input and output maps data structure
1707   */
1708  int i = 0;
1709  HINTERNET hInternet;
1710  HINTERNET res;
1711  hInternet = InternetOpen (
1712#ifndef WIN32
1713                             (LPCTSTR)
1714#endif
1715                             "ZooWPSClient\0",
1716                             INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
1717
1718#ifndef WIN32
1719  if (!CHECK_INET_HANDLE (hInternet))
1720    fprintf (stderr, "WARNING : hInternet handle failed to initialize");
1721#endif
1722  maps *request_input_real_format = NULL;
1723  maps *tmpmaps = request_input_real_format;
1724  map *postRequest = NULL;
1725  postRequest = getMap (request_inputs, "xrequest");
1726  if (postRequest == NULLMAP)
1727    {
1728    /**
1729     * Parsing outputs provided as KVP
1730     */
1731      r_inputs = NULL;
1732#ifdef DEBUG
1733      fprintf (stderr, "OUTPUT Parsing ... \n");
1734#endif
1735      r_inputs = getMap (request_inputs, "ResponseDocument");
1736      if (r_inputs == NULL)
1737        r_inputs = getMap (request_inputs, "RawDataOutput");
1738
1739#ifdef DEBUG
1740      fprintf (stderr, "OUTPUT Parsing ... \n");
1741#endif
1742      if (r_inputs != NULL)
1743        {
1744#ifdef DEBUG
1745          fprintf (stderr, "OUTPUT Parsing start now ... \n");
1746#endif
1747          char cursor_output[10240];
1748          char *cotmp = zStrdup (r_inputs->value);
1749          snprintf (cursor_output, 10240, "%s", cotmp);
1750          free (cotmp);
1751          j = 0;
1752
1753      /**
1754       * Put each Output into the outputs_as_text array
1755       */
1756          char *pToken;
1757          maps *tmp_output = NULL;
1758#ifdef DEBUG
1759          fprintf (stderr, "OUTPUT [%s]\n", cursor_output);
1760#endif
1761          pToken = strtok (cursor_output, ";");
1762          char **outputs_as_text = (char **) malloc (128 * sizeof (char *));
1763          if (outputs_as_text == NULL)
1764            {
1765              return errorException (m, _("Unable to allocate memory"),
1766                                     "InternalError", NULL);
1767            }
1768          i = 0;
1769          while (pToken != NULL)
1770            {
1771#ifdef DEBUG
1772              fprintf (stderr, "***%s***\n", pToken);
1773              fflush (stderr);
1774              fprintf (stderr, "***%s***\n", pToken);
1775#endif
1776              outputs_as_text[i] =
1777                (char *) malloc ((strlen (pToken) + 1) * sizeof (char));
1778              if (outputs_as_text[i] == NULL)
1779                {
1780                  return errorException (m, _("Unable to allocate memory"),
1781                                         "InternalError", NULL);
1782                }
1783              snprintf (outputs_as_text[i], strlen (pToken) + 1, "%s",
1784                        pToken);
1785              pToken = strtok (NULL, ";");
1786              i++;
1787            }
1788          for (j = 0; j < i; j++)
1789            {
1790              char *tmp = zStrdup (outputs_as_text[j]);
1791              free (outputs_as_text[j]);
1792              char *tmpc;
1793              tmpc = strtok (tmp, "@");
1794              int k = 0;
1795              while (tmpc != NULL)
1796                {
1797                  if (k == 0)
1798                    {
1799                      if (tmp_output == NULL)
1800                        {
1801                          tmp_output = (maps *) malloc (MAPS_SIZE);
1802                          if (tmp_output == NULL)
1803                            {
1804                              return errorException (m,
1805                                                     _
1806                                                     ("Unable to allocate memory."),
1807                                                     "InternalError", NULL);
1808                            }
1809                          tmp_output->name = zStrdup (tmpc);
1810                          tmp_output->content = NULL;
1811                          tmp_output->next = NULL;
1812                        }
1813                    }
1814                  else
1815                    {
1816                      char *tmpv = strstr (tmpc, "=");
1817                      char tmpn[256];
1818                      memset (tmpn, 0, 256);
1819                      strncpy (tmpn, tmpc,
1820                               (strlen (tmpc) -
1821                                strlen (tmpv)) * sizeof (char));
1822                      tmpn[strlen (tmpc) - strlen (tmpv)] = 0;
1823#ifdef DEBUG
1824                      fprintf (stderr, "OUTPUT DEF [%s]=[%s]\n", tmpn,
1825                               tmpv + 1);
1826#endif
1827                      if (tmp_output->content == NULL)
1828                        {
1829                          tmp_output->content = createMap (tmpn, tmpv + 1);
1830                          tmp_output->content->next = NULL;
1831                        }
1832                      else
1833                        addToMap (tmp_output->content, tmpn, tmpv + 1);
1834                    }
1835                  k++;
1836#ifdef DEBUG
1837                  fprintf (stderr, "***%s***\n", tmpc);
1838#endif
1839                  tmpc = strtok (NULL, "@");
1840                }
1841              if (request_output_real_format == NULL)
1842                request_output_real_format = dupMaps (&tmp_output);
1843              else
1844                addMapsToMaps (&request_output_real_format, tmp_output);
1845              freeMaps (&tmp_output);
1846              free (tmp_output);
1847              tmp_output = NULL;
1848#ifdef DEBUG
1849              dumpMaps (tmp_output);
1850              fflush (stderr);
1851#endif
1852              free (tmp);
1853            }
1854          free (outputs_as_text);
1855        }
1856
1857
1858    /**
1859     * Parsing inputs provided as KVP
1860     */
1861      r_inputs = getMap (request_inputs, "DataInputs");
1862#ifdef DEBUG
1863      fprintf (stderr, "DATA INPUTS [%s]\n", r_inputs->value);
1864#endif
1865      char cursor_input[40960];
1866      if (r_inputs != NULL){
1867        snprintf (cursor_input, 40960, "%s", r_inputs->value);
1868        j = 0;
1869
1870        /**
1871         * Put each DataInputs into the inputs_as_text array
1872         */
1873        char *tmp1 = zStrdup (cursor_input);
1874        char *pToken;
1875        pToken = strtok (cursor_input, ";");
1876        if (pToken != NULL && strncasecmp (pToken, tmp1, strlen (tmp1)) == 0)
1877          {
1878            char *tmp2 = url_decode (tmp1);
1879            snprintf (cursor_input, (strlen (tmp2) + 1) * sizeof (char), "%s",
1880                      tmp2);
1881            free (tmp2);
1882            pToken = strtok (cursor_input, ";");
1883          }
1884        free (tmp1);
1885       
1886        char **inputs_as_text = (char **) malloc (100 * sizeof (char *));
1887        if (inputs_as_text == NULL)
1888          {
1889            return errorException (m, _("Unable to allocate memory."),
1890                                   "InternalError", NULL);
1891          }
1892        i = 0;
1893        while (pToken != NULL)
1894          {
1895#ifdef DEBUG
1896            fprintf (stderr, "***%s***\n", pToken);
1897            fflush (stderr);
1898            fprintf (stderr, "***%s***\n", pToken);
1899#endif
1900            inputs_as_text[i] =
1901              (char *) malloc ((strlen (pToken) + 1) * sizeof (char));
1902            if (inputs_as_text[i] == NULL)
1903              {
1904                return errorException (m, _("Unable to allocate memory."),
1905                                       "InternalError", NULL);
1906              }
1907            snprintf (inputs_as_text[i], strlen (pToken) + 1, "%s", pToken);
1908            pToken = strtok (NULL, ";");
1909            i++;
1910          }
1911       
1912        for (j = 0; j < i; j++)
1913          {
1914            char *tmp = zStrdup (inputs_as_text[j]);
1915            free (inputs_as_text[j]);
1916            char *tmpc;
1917            tmpc = strtok (tmp, "@");
1918            while (tmpc != NULL)
1919              {
1920#ifdef DEBUG
1921                fprintf (stderr, "***\n***%s***\n", tmpc);
1922#endif
1923                char *tmpv = strstr (tmpc, "=");
1924                char tmpn[256];
1925                memset (tmpn, 0, 256);
1926                if (tmpv != NULL)
1927                  {
1928                    strncpy (tmpn, tmpc,
1929                             (strlen (tmpc) - strlen (tmpv)) * sizeof (char));
1930                    tmpn[strlen (tmpc) - strlen (tmpv)] = 0;
1931                  }
1932                else
1933                  {
1934                    strncpy (tmpn, tmpc, strlen (tmpc) * sizeof (char));
1935                    tmpn[strlen (tmpc)] = 0;
1936                  }
1937#ifdef DEBUG
1938                fprintf (stderr, "***\n*** %s = %s ***\n", tmpn, tmpv + 1);
1939#endif
1940                if (tmpmaps == NULL)
1941                  {
1942                    tmpmaps = (maps *) malloc (MAPS_SIZE);
1943                    if (tmpmaps == NULL)
1944                      {
1945                        return errorException (m,
1946                                               _("Unable to allocate memory."),
1947                                               "InternalError", NULL);
1948                      }
1949                    tmpmaps->name = zStrdup (tmpn);
1950                    if (tmpv != NULL)
1951                      {
1952                        char *tmpvf = url_decode (tmpv + 1);
1953                        tmpmaps->content = createMap ("value", tmpvf);
1954                        free (tmpvf);
1955                      }
1956                    else
1957                      tmpmaps->content = createMap ("value", "Reference");
1958                    tmpmaps->next = NULL;
1959                  }
1960                tmpc = strtok (NULL, "@");
1961                while (tmpc != NULL)
1962                  {
1963#ifdef DEBUG
1964                    fprintf (stderr, "*** KVP NON URL-ENCODED \n***%s***\n",
1965                             tmpc);
1966#endif
1967                    char *tmpv1 = strstr (tmpc, "=");
1968#ifdef DEBUG
1969                    fprintf (stderr, "*** VALUE NON URL-ENCODED \n***%s***\n",
1970                             tmpv1 + 1);
1971#endif
1972                    char tmpn1[1024];
1973                    memset (tmpn1, 0, 1024);
1974                    if (tmpv1 != NULL)
1975                      {
1976                        strncpy (tmpn1, tmpc, strlen (tmpc) - strlen (tmpv1));
1977                        tmpn1[strlen (tmpc) - strlen (tmpv1)] = 0;
1978                        addToMap (tmpmaps->content, tmpn1, tmpv1 + 1);
1979                      }
1980                    else
1981                      {
1982                        strncpy (tmpn1, tmpc, strlen (tmpc));
1983                        tmpn1[strlen (tmpc)] = 0;
1984                        map *lmap = getLastMap (tmpmaps->content);
1985                        char *tmpValue =
1986                          (char *) malloc ((strlen (tmpv) + strlen (tmpc) + 1) *
1987                                           sizeof (char));
1988                        sprintf (tmpValue, "%s@%s", tmpv + 1, tmpc);
1989                        free (lmap->value);
1990                        lmap->value = zStrdup (tmpValue);
1991                        free (tmpValue);
1992                        tmpc = strtok (NULL, "@");
1993                        continue;
1994                      }
1995#ifdef DEBUG
1996                    fprintf (stderr, "*** NAME NON URL-ENCODED \n***%s***\n",
1997                             tmpn1);
1998                    fprintf (stderr, "*** VALUE NON URL-ENCODED \n***%s***\n",
1999                             tmpv1 + 1);
2000#endif
2001                    if (strcmp (tmpn1, "xlink:href") != 0)
2002                      addToMap (tmpmaps->content, tmpn1, tmpv1 + 1);
2003                    else if (tmpv1 != NULL)
2004                      {
2005                        char *tmpx2 = url_decode (tmpv1 + 1);
2006                        if (strncasecmp (tmpx2, "http://", 7) != 0 &&
2007                            strncasecmp (tmpx2, "ftp://", 6) != 0 &&
2008                            strncasecmp (tmpx2, "https://", 8) != 0)
2009                          {
2010                            char emsg[1024];
2011                            sprintf (emsg,
2012                                     _
2013                                     ("Unable to find a valid protocol to download the remote file %s"),
2014                                     tmpv1 + 1);
2015                            errorException (m, emsg, "InternalError", NULL);
2016                            freeMaps (&m);
2017                            free (m);
2018                            free (REQUEST);
2019                            free (SERVICE_URL);
2020                            InternetCloseHandle (&hInternet);
2021                            freeService (&s1);
2022                            free (s1);
2023                            return 0;
2024                          }
2025#ifdef DEBUG
2026                        fprintf (stderr,
2027                                 "REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n",
2028                                 tmpv1 + 1);
2029#endif
2030                        addToMap (tmpmaps->content, tmpn1, tmpx2);
2031#ifndef WIN32
2032                        if (CHECK_INET_HANDLE (hInternet))
2033#endif
2034                          {
2035                            if (loadRemoteFile
2036                                (&m, &tmpmaps->content, &hInternet, tmpx2) < 0)
2037                              {
2038                                freeMaps (&m);
2039                                free (m);
2040                                free (REQUEST);
2041                                free (SERVICE_URL);
2042                                InternetCloseHandle (&hInternet);
2043                                freeService (&s1);
2044                                free (s1);
2045                                return 0;
2046                              }
2047                          }
2048                        free (tmpx2);
2049                        addToMap (tmpmaps->content, "Reference", tmpv1 + 1);
2050                      }
2051                    tmpc = strtok (NULL, "@");
2052                  }
2053#ifdef DEBUG
2054                dumpMaps (tmpmaps);
2055                fflush (stderr);
2056#endif
2057                if (request_input_real_format == NULL)
2058                  request_input_real_format = dupMaps (&tmpmaps);
2059                else
2060                  {
2061                    maps *testPresence =
2062                      getMaps (request_input_real_format, tmpmaps->name);
2063                    if (testPresence != NULL)
2064                      {
2065                        elements *elem =
2066                          getElements (s1->inputs, tmpmaps->name);
2067                        if (elem != NULL)
2068                          {
2069                            if (appendMapsToMaps
2070                                (m, request_input_real_format, tmpmaps,
2071                                 elem) < 0)
2072                              {
2073                                freeMaps (&m);
2074                                free (m);
2075                                free (REQUEST);
2076                                free (SERVICE_URL);
2077                                InternetCloseHandle (&hInternet);
2078                                freeService (&s1);
2079                                free (s1);
2080                                return 0;
2081                              }
2082                          }
2083                      }
2084                    else
2085                      addMapsToMaps (&request_input_real_format, tmpmaps);
2086                  }
2087                freeMaps (&tmpmaps);
2088                free (tmpmaps);
2089                tmpmaps = NULL;
2090                free (tmp);
2091              }
2092          }
2093        free (inputs_as_text);
2094      }
2095    }
2096  else
2097    {
2098    /**
2099     * Parse XML request
2100     */
2101      xmlInitParser ();
2102#ifdef DEBUG
2103      fflush (stderr);
2104      fprintf (stderr, "BEFORE %s\n", postRequest->value);
2105      fflush (stderr);
2106#endif
2107      xmlDocPtr doc = xmlParseMemory (postRequest->value, cgiContentLength);
2108#ifdef DEBUG
2109      fprintf (stderr, "AFTER\n");
2110      fflush (stderr);
2111#endif
2112
2113    /**
2114     * Parse every Input in DataInputs node.
2115     */
2116      xmlXPathObjectPtr tmpsptr =
2117        extractFromDoc (doc, "/*/*/*[local-name()='Input']");
2118      xmlNodeSet *tmps = tmpsptr->nodesetval;
2119#ifdef DEBUG
2120      fprintf (stderr, "*****%d*****\n", tmps->nodeNr);
2121#endif
2122      for (int k = 0; k < tmps->nodeNr; k++)
2123        {
2124          maps *tmpmaps = NULL;
2125          xmlNodePtr cur = tmps->nodeTab[k];
2126          if (tmps->nodeTab[k]->type == XML_ELEMENT_NODE)
2127            {
2128        /**
2129         * A specific Input node.
2130         */
2131#ifdef DEBUG
2132              fprintf (stderr, "= element 0 node \"%s\"\n", cur->name);
2133#endif
2134              xmlNodePtr cur2 = cur->children;
2135              while (cur2 != NULL)
2136                {
2137                  while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
2138                    cur2 = cur2->next;
2139                  if (cur2 == NULL)
2140                    break;
2141          /**
2142           * Indentifier
2143           */
2144                  if (xmlStrncasecmp
2145                      (cur2->name, BAD_CAST "Identifier",
2146                       xmlStrlen (cur2->name)) == 0)
2147                    {
2148                      xmlChar *val =
2149                        xmlNodeListGetString (doc, cur2->xmlChildrenNode, 1);
2150                      if (tmpmaps == NULL)
2151                        {
2152                          tmpmaps = (maps *) malloc (MAPS_SIZE);
2153                          if (tmpmaps == NULL)
2154                            {
2155                              return errorException (m,
2156                                                     _
2157                                                     ("Unable to allocate memory."),
2158                                                     "InternalError", NULL);
2159                            }
2160                          tmpmaps->name = zStrdup ((char *) val);
2161                          tmpmaps->content = NULL;
2162                          tmpmaps->next = NULL;
2163                        }
2164                      xmlFree (val);
2165                    }
2166          /**
2167           * Title, Asbtract
2168           */
2169                  if (xmlStrncasecmp
2170                      (cur2->name, BAD_CAST "Title",
2171                       xmlStrlen (cur2->name)) == 0
2172                      || xmlStrncasecmp (cur2->name, BAD_CAST "Abstract",
2173                                         xmlStrlen (cur2->name)) == 0)
2174                    {
2175                      xmlChar *val =
2176                        xmlNodeListGetString (doc, cur2->xmlChildrenNode, 1);
2177                      if (tmpmaps == NULL)
2178                        {
2179                          tmpmaps = (maps *) malloc (MAPS_SIZE);
2180                          if (tmpmaps == NULL)
2181                            {
2182                              return errorException (m,
2183                                                     _
2184                                                     ("Unable to allocate memory."),
2185                                                     "InternalError", NULL);
2186                            }
2187                          tmpmaps->name = zStrdup ("missingIndetifier");
2188                          tmpmaps->content =
2189                            createMap ((char *) cur2->name, (char *) val);
2190                          tmpmaps->next = NULL;
2191                        }
2192                      else
2193                        {
2194                          if (tmpmaps->content != NULL)
2195                            addToMap (tmpmaps->content,
2196                                      (char *) cur2->name, (char *) val);
2197                          else
2198                            tmpmaps->content =
2199                              createMap ((char *) cur2->name, (char *) val);
2200                        }
2201#ifdef DEBUG
2202                      dumpMaps (tmpmaps);
2203#endif
2204                      xmlFree (val);
2205                    }
2206          /**
2207           * InputDataFormChoice (Reference or Data ?)
2208           */
2209                  if (xmlStrcasecmp (cur2->name, BAD_CAST "Reference") == 0)
2210                    {
2211            /**
2212             * Get every attribute from a Reference node
2213             * mimeType, encoding, schema, href, method
2214             * Header and Body gesture should be added here
2215             */
2216#ifdef DEBUG
2217                      fprintf (stderr, "REFERENCE\n");
2218#endif
2219                      const char *refs[5] =
2220                        { "mimeType", "encoding", "schema", "method",
2221                        "href"
2222                      };
2223                      for (int l = 0; l < 5; l++)
2224                        {
2225#ifdef DEBUG
2226                          fprintf (stderr, "*** %s ***", refs[l]);
2227#endif
2228                          xmlChar *val = xmlGetProp (cur2, BAD_CAST refs[l]);
2229                          if (val != NULL && xmlStrlen (val) > 0)
2230                            {
2231                              if (tmpmaps->content != NULL)
2232                                addToMap (tmpmaps->content, refs[l],
2233                                          (char *) val);
2234                              else
2235                                tmpmaps->content =
2236                                  createMap (refs[l], (char *) val);
2237                              map *ltmp = getMap (tmpmaps->content, "method");
2238                              if (l == 4)
2239                                {
2240                                  if (!
2241                                      (ltmp != NULL
2242                                       && strncmp (ltmp->value, "POST",
2243                                                   4) == 0)
2244                                      && CHECK_INET_HANDLE (hInternet))
2245                                    {
2246                                      if (loadRemoteFile
2247                                          (&m, &tmpmaps->content, &hInternet,
2248                                           (char *) val) != 0)
2249                                        {
2250                                          freeMaps (&m);
2251                                          free (m);
2252                                          free (REQUEST);
2253                                          free (SERVICE_URL);
2254                                          InternetCloseHandle (&hInternet);
2255                                          freeService (&s1);
2256                                          free (s1);
2257                                          return 0;
2258                                        }
2259                                    }
2260                                }
2261                            }
2262#ifdef DEBUG
2263                          fprintf (stderr, "%s\n", val);
2264#endif
2265                          xmlFree (val);
2266                        }
2267#ifdef POST_DEBUG
2268                      fprintf (stderr,
2269                               "Parse Header and Body from Reference \n");
2270#endif
2271                      xmlNodePtr cur3 = cur2->children;
2272                      /*      HINTERNET hInternetP;
2273                         hInternetP=InternetOpen(
2274                         #ifndef WIN32
2275                         (LPCTSTR)
2276                         #endif
2277                         "ZooWPSClient\0",
2278                         INTERNET_OPEN_TYPE_PRECONFIG,
2279                         NULL,NULL, 0); */
2280                      //hInternet.ihandle[hInternet.nb].header=NULL;
2281                      while (cur3 != NULL)
2282                        {
2283                          while (cur3 != NULL
2284                                 && cur3->type != XML_ELEMENT_NODE)
2285                            cur3 = cur3->next;
2286                          if (cur3 == NULL)
2287                            break;
2288                          if (xmlStrcasecmp (cur3->name, BAD_CAST "Header") ==
2289                              0)
2290                            {
2291                              const char *ha[2];
2292                              ha[0] = "key";
2293                              ha[1] = "value";
2294                              int hai;
2295                              char *has;
2296                              char *key;
2297                              for (hai = 0; hai < 2; hai++)
2298                                {
2299                                  xmlChar *val =
2300                                    xmlGetProp (cur3, BAD_CAST ha[hai]);
2301#ifdef POST_DEBUG
2302                                  fprintf (stderr, "%s = %s\n", ha[hai],
2303                                           (char *) val);
2304#endif
2305                                  if (hai == 0)
2306                                    {
2307                                      key = zStrdup ((char *) val);
2308                                    }
2309                                  else
2310                                    {
2311                                      has =
2312                                        (char *)
2313                                        malloc ((4 + xmlStrlen (val) +
2314                                                 strlen (key)) *
2315                                                sizeof (char));
2316                                      if (has == NULL)
2317                                        {
2318                                          return errorException (m,
2319                                                                 _
2320                                                                 ("Unable to allocate memory."),
2321                                                                 "InternalError",
2322                                                                 NULL);
2323                                        }
2324                                      snprintf (has,
2325                                                (3 + xmlStrlen (val) +
2326                                                 strlen (key)), "%s: %s", key,
2327                                                (char *) val);
2328                                      free (key);
2329#ifdef POST_DEBUG
2330                                      fprintf (stderr, "%s\n", has);
2331#endif
2332                                    }
2333                                  xmlFree (val);
2334                                }
2335                              hInternet.ihandle[hInternet.nb].header =
2336                                curl_slist_append (hInternet.ihandle
2337                                                   [hInternet.nb].header,
2338                                                   has);
2339                              if (has != NULL)
2340                                free (has);
2341                            }
2342                          else
2343                            {
2344#ifdef POST_DEBUG
2345                              fprintf (stderr,
2346                                       "Try to fetch the body part of the request ...\n");
2347#endif
2348                              if (xmlStrcasecmp (cur3->name, BAD_CAST "Body")
2349                                  == 0)
2350                                {
2351#ifdef POST_DEBUG
2352                                  fprintf (stderr, "Body part found !!!\n",
2353                                           (char *) cur3->content);
2354#endif
2355                                  char *tmp =
2356                                    (char *) malloc (cgiContentLength +
2357                                                     1 * sizeof (char));
2358                                  memset (tmp, 0, cgiContentLength);
2359                                  xmlNodePtr cur4 = cur3->children;
2360                                  while (cur4 != NULL)
2361                                    {
2362                                      while (cur4->type != XML_ELEMENT_NODE)
2363                                        cur4 = cur4->next;
2364                                      xmlDocPtr bdoc =
2365                                        xmlNewDoc (BAD_CAST "1.0");
2366                                      bdoc->encoding =
2367                                        xmlCharStrdup ("UTF-8");
2368                                      xmlDocSetRootElement (bdoc, cur4);
2369                                      xmlChar *btmps;
2370                                      int bsize;
2371                                      xmlDocDumpMemory (bdoc, &btmps, &bsize);
2372#ifdef POST_DEBUG
2373                                      fprintf (stderr,
2374                                               "Body part found !!! %s %s\n",
2375                                               tmp, (char *) btmps);
2376#endif
2377                                      if (btmps != NULL)
2378                                        sprintf (tmp, "%s", (char *) btmps);
2379                                      xmlFree (btmps);
2380                                      cur4 = cur4->next;
2381                                      xmlFreeDoc (bdoc);
2382                                    }
2383                                  map *btmp =
2384                                    getMap (tmpmaps->content, "href");
2385                                  if (btmp != NULL)
2386                                    {
2387#ifdef POST_DEBUG
2388                                      fprintf (stderr, "%s %s\n", btmp->value,
2389                                               tmp);
2390                                      curl_easy_setopt (hInternet.handle,
2391                                                        CURLOPT_VERBOSE, 1);
2392#endif
2393                                      hInternet.
2394                                        waitingRequests[hInternet.nb] =
2395                                        strdup (tmp);
2396                                      InternetOpenUrl (&hInternet,
2397                                                       btmp->value,
2398                                                       hInternet.waitingRequests
2399                                                       [hInternet.nb],
2400                                                       strlen
2401                                                       (hInternet.waitingRequests
2402                                                        [hInternet.nb]),
2403                                                       INTERNET_FLAG_NO_CACHE_WRITE,
2404                                                       0);
2405                                    }
2406                                  free (tmp);
2407                                }
2408                              else
2409                                if (xmlStrcasecmp
2410                                    (cur3->name,
2411                                     BAD_CAST "BodyReference") == 0)
2412                                {
2413                                  xmlChar *val =
2414                                    xmlGetProp (cur3, BAD_CAST "href");
2415                                  HINTERNET bInternet, res1;
2416                                  bInternet = InternetOpen (
2417#ifndef WIN32
2418                                                             (LPCTSTR)
2419#endif
2420                                                             "ZooWPSClient\0",
2421                                                             INTERNET_OPEN_TYPE_PRECONFIG,
2422                                                             NULL, NULL, 0);
2423                                  if (!CHECK_INET_HANDLE (hInternet))
2424                                    fprintf (stderr,
2425                                             "WARNING : hInternet handle failed to initialize");
2426#ifdef POST_DEBUG
2427                                  curl_easy_setopt (bInternet.handle,
2428                                                    CURLOPT_VERBOSE, 1);
2429#endif
2430                                  bInternet.waitingRequests[0] =
2431                                    strdup ((char *) val);
2432                                  res1 =
2433                                    InternetOpenUrl (&bInternet,
2434                                                     bInternet.waitingRequests
2435                                                     [0], NULL, 0,
2436                                                     INTERNET_FLAG_NO_CACHE_WRITE,
2437                                                     0);
2438                                  processDownloads (&bInternet);
2439                                  char *tmp =
2440                                    (char *)
2441                                    malloc ((bInternet.ihandle[0].nDataLen +
2442                                             1) * sizeof (char));
2443                                  if (tmp == NULL)
2444                                    {
2445                                      return errorException (m,
2446                                                             _
2447                                                             ("Unable to allocate memory."),
2448                                                             "InternalError",
2449                                                             NULL);
2450                                    }
2451                                  size_t bRead;
2452                                  InternetReadFile (bInternet.ihandle[0],
2453                                                    (LPVOID) tmp,
2454                                                    bInternet.
2455                                                    ihandle[0].nDataLen,
2456                                                    &bRead);
2457                                  tmp[bInternet.ihandle[0].nDataLen] = 0;
2458                                  InternetCloseHandle (&bInternet);
2459                                  map *btmp =
2460                                    getMap (tmpmaps->content, "href");
2461                                  if (btmp != NULL)
2462                                    {
2463#ifdef POST_DEBUG
2464                                      fprintf (stderr, "%s %s\n", btmp->value,
2465                                               tmp);
2466#endif
2467                                      hInternet.
2468                                        waitingRequests[hInternet.nb] =
2469                                        strdup (tmp);
2470                                      res =
2471                                        InternetOpenUrl (&hInternet,
2472                                                         btmp->value,
2473                                                         hInternet.waitingRequests
2474                                                         [hInternet.nb],
2475                                                         strlen
2476                                                         (hInternet.waitingRequests
2477                                                          [hInternet.nb]),
2478                                                         INTERNET_FLAG_NO_CACHE_WRITE,
2479                                                         0);
2480                                    }
2481                                  free (tmp);
2482                                }
2483                            }
2484                          cur3 = cur3->next;
2485                        }
2486#ifdef POST_DEBUG
2487                      fprintf (stderr,
2488                               "Header and Body was parsed from Reference \n");
2489#endif
2490#ifdef DEBUG
2491                      dumpMap (tmpmaps->content);
2492                      fprintf (stderr, "= element 2 node \"%s\" = (%s)\n",
2493                               cur2->name, cur2->content);
2494#endif
2495                    }
2496                  else if (xmlStrcasecmp (cur2->name, BAD_CAST "Data") == 0)
2497                    {
2498#ifdef DEBUG
2499                      fprintf (stderr, "DATA\n");
2500#endif
2501                      xmlNodePtr cur4 = cur2->children;
2502                      while (cur4 != NULL)
2503                        {
2504                          while (cur4 != NULL
2505                                 && cur4->type != XML_ELEMENT_NODE)
2506                            cur4 = cur4->next;
2507                          if (cur4 == NULL)
2508                            break;
2509                          if (xmlStrcasecmp
2510                              (cur4->name, BAD_CAST "LiteralData") == 0)
2511                            {
2512                /**
2513                 * Get every attribute from a LiteralData node
2514                 * dataType , uom
2515                 */
2516                              char *list[2];
2517                              list[0] = zStrdup ("dataType");
2518                              list[1] = zStrdup ("uom");
2519                              for (int l = 0; l < 2; l++)
2520                                {
2521#ifdef DEBUG
2522                                  fprintf (stderr, "*** LiteralData %s ***",
2523                                           list[l]);
2524#endif
2525                                  xmlChar *val =
2526                                    xmlGetProp (cur4, BAD_CAST list[l]);
2527                                  if (val != NULL
2528                                      && strlen ((char *) val) > 0)
2529                                    {
2530                                      if (tmpmaps->content != NULL)
2531                                        addToMap (tmpmaps->content, list[l],
2532                                                  (char *) val);
2533                                      else
2534                                        tmpmaps->content =
2535                                          createMap (list[l], (char *) val);
2536#ifdef DEBUG
2537                                      fprintf (stderr, "%s\n", val);
2538#endif
2539                                    }
2540                                  xmlFree (val);
2541                                  free (list[l]);
2542                                }
2543                            }
2544                          else
2545                            if (xmlStrcasecmp
2546                                (cur4->name, BAD_CAST "ComplexData") == 0)
2547                            {
2548                /**
2549                 * Get every attribute from a Reference node
2550                 * mimeType, encoding, schema
2551                 */
2552                              const char *coms[3] =
2553                                { "mimeType", "encoding", "schema" };
2554                              for (int l = 0; l < 3; l++)
2555                                {
2556#ifdef DEBUG
2557                                  fprintf (stderr, "*** ComplexData %s ***\n",
2558                                           coms[l]);
2559#endif
2560                                  xmlChar *val =
2561                                    xmlGetProp (cur4, BAD_CAST coms[l]);
2562                                  if (val != NULL
2563                                      && strlen ((char *) val) > 0)
2564                                    {
2565                                      if (tmpmaps->content != NULL)
2566                                        addToMap (tmpmaps->content, coms[l],
2567                                                  (char *) val);
2568                                      else
2569                                        tmpmaps->content =
2570                                          createMap (coms[l], (char *) val);
2571#ifdef DEBUG
2572                                      fprintf (stderr, "%s\n", val);
2573#endif
2574                                    }
2575                                  xmlFree (val);
2576                                }
2577                            }
2578
2579                          map *test = getMap (tmpmaps->content, "encoding");
2580
2581                          if (test == NULL)
2582                            { 
2583                              if (tmpmaps->content != NULL)
2584                                addToMap (tmpmaps->content, "encoding",
2585                                          "utf-8");
2586                              else
2587                                tmpmaps->content =
2588                                  createMap ("encoding", "utf-8");
2589                              test = getMap (tmpmaps->content, "encoding");
2590                            }
2591
2592                          if (strcasecmp (test->value, "base64") != 0)
2593                            { 
2594                              xmlChar *mv = xmlNodeListGetString (doc,
2595                                                                  cur4->
2596                                                                  xmlChildrenNode,
2597                                                                  1);
2598                              map *ltmp =
2599                                getMap (tmpmaps->content, "mimeType");
2600                              if (mv == NULL
2601                                  ||
2602                                  (xmlStrcasecmp
2603                                   (cur4->name, BAD_CAST "ComplexData") == 0
2604                                   && (ltmp == NULL
2605                                       || strncasecmp (ltmp->value,
2606                                                       "text/xml", 8) == 0)))
2607                                {
2608                                  xmlDocPtr doc1 = xmlNewDoc (BAD_CAST "1.0");
2609                                  int buffersize;
2610                                  xmlNodePtr cur5 = cur4->children;
2611                                  while (cur5 != NULL
2612                                         && cur5->type != XML_ELEMENT_NODE
2613                                         && cur5->type !=
2614                                         XML_CDATA_SECTION_NODE)
2615                                    cur5 = cur5->next;
2616                                  if (cur5 != NULL
2617                                      && cur5->type != XML_CDATA_SECTION_NODE)
2618                                    {
2619                                      xmlDocSetRootElement (doc1, cur5);
2620                                      xmlDocDumpFormatMemoryEnc (doc1, &mv,
2621                                                                 &buffersize,
2622                                                                 "utf-8", 1);
2623                                      char size[1024];
2624                                      sprintf (size, "%d", buffersize);
2625                                      addToMap (tmpmaps->content, "size",
2626                                                size);
2627                                      xmlFreeDoc (doc1);
2628                                    }
2629                                  else
2630                                    {
2631                                      if (cur5 != NULL
2632                                          && cur5->type == XML_CDATA_SECTION_NODE){
2633                                        xmlDocPtr doc2 = xmlParseMemory((const char*)cur5->content,xmlStrlen(cur5->content));
2634                                        xmlDocSetRootElement (doc1,xmlDocGetRootElement(doc2));
2635                                        xmlDocDumpFormatMemoryEnc (doc1, &mv,
2636                                                                   &buffersize,
2637                                                                   "utf-8", 1);
2638                                        char size[1024];
2639                                        sprintf (size, "%d", buffersize);
2640                                        addToMap (tmpmaps->content, "size",
2641                                                  size);
2642                                        xmlFreeDoc (doc2);
2643                                        xmlFreeDoc (doc1);
2644                                      }
2645                                    }
2646                                }else{
2647                                xmlNodePtr cur5 = cur4->children;
2648                                while (cur5 != NULL
2649                                       && cur5->type != XML_CDATA_SECTION_NODE)
2650                                  cur5 = cur5->next;
2651                                if (cur5 != NULL
2652                                    && cur5->type == XML_CDATA_SECTION_NODE){
2653                                  xmlFree(mv);
2654                                  mv=xmlStrdup(cur5->content);
2655                                }
2656                              }
2657                              if (mv != NULL)
2658                                {
2659                                  addToMap (tmpmaps->content, "value",
2660                                            (char *) mv);
2661                                  xmlFree (mv);
2662                                }
2663                            }
2664                          else
2665                            {
2666                              xmlChar *tmp = xmlNodeListGetRawString (doc,
2667                                                                      cur4->xmlChildrenNode,
2668                                                                      0);
2669                              addToMap (tmpmaps->content, "value",
2670                                        (char *) tmp);
2671                              map *tmpv = getMap (tmpmaps->content, "value");
2672                              char *res = NULL;
2673                              char *curs = tmpv->value;
2674                              for (int i = 0; i <= strlen (tmpv->value) / 64;
2675                                   i++)
2676                                {
2677                                  if (res == NULL)
2678                                    res =
2679                                      (char *) malloc (67 * sizeof (char));
2680                                  else
2681                                    res =
2682                                      (char *) realloc (res,
2683                                                        (((i + 1) * 65) +
2684                                                         i) * sizeof (char));
2685                                  int csize = i * 65;
2686                                  strncpy (res + csize, curs, 64);
2687                                  if (i == xmlStrlen (tmp) / 64)
2688                                    strcat (res, "\n\0");
2689                                  else
2690                                    {
2691                                      strncpy (res + (((i + 1) * 64) + i),
2692                                               "\n\0", 2);
2693                                      curs += 64;
2694                                    }
2695                                }
2696                              free (tmpv->value);
2697                              tmpv->value = zStrdup (res);
2698                              free (res);
2699                              xmlFree (tmp);
2700                            }
2701                          cur4 = cur4->next;
2702                        }
2703                    }
2704#ifdef DEBUG
2705                  fprintf (stderr, "cur2 next \n");
2706                  fflush (stderr);
2707#endif
2708                  cur2 = cur2->next;
2709                }
2710#ifdef DEBUG
2711              fprintf (stderr, "ADD MAPS TO REQUEST MAPS !\n");
2712              fflush (stderr);
2713#endif
2714
2715              {
2716                maps *testPresence =
2717                  getMaps (request_input_real_format, tmpmaps->name);
2718                if (testPresence != NULL)
2719                  {
2720                    elements *elem = getElements (s1->inputs, tmpmaps->name);
2721                    if (elem != NULL)
2722                      {
2723                        if (appendMapsToMaps
2724                            (m, request_input_real_format, tmpmaps, elem) < 0)
2725                          {
2726                            freeMaps (&m);
2727                            free (m);
2728                            free (REQUEST);
2729                            free (SERVICE_URL);
2730                            InternetCloseHandle (&hInternet);
2731                            freeService (&s1);
2732                            free (s1);
2733                            return 0;
2734                          }
2735                      }
2736                  }
2737                else
2738                  addMapsToMaps (&request_input_real_format, tmpmaps);
2739              }
2740
2741#ifdef DEBUG
2742              fprintf (stderr, "******TMPMAPS*****\n");
2743              dumpMaps (tmpmaps);
2744              fprintf (stderr, "******REQUESTMAPS*****\n");
2745              dumpMaps (request_input_real_format);
2746#endif
2747              freeMaps (&tmpmaps);
2748              free (tmpmaps);
2749              tmpmaps = NULL;
2750            }
2751#ifdef DEBUG
2752          dumpMaps (tmpmaps);
2753#endif
2754        }
2755#ifdef DEBUG
2756      fprintf (stderr, "Search for response document node\n");
2757#endif
2758      xmlXPathFreeObject (tmpsptr);
2759
2760      tmpsptr =
2761        extractFromDoc (doc, "/*/*/*[local-name()='ResponseDocument']");
2762      bool asRaw = false;
2763      tmps = tmpsptr->nodesetval;
2764      if (tmps->nodeNr == 0)
2765        {
2766          xmlXPathFreeObject (tmpsptr);
2767          tmpsptr =
2768            extractFromDoc (doc, "/*/*/*[local-name()='RawDataOutput']");
2769          tmps = tmpsptr->nodesetval;
2770          asRaw = true;
2771        }
2772#ifdef DEBUG
2773      fprintf (stderr, "*****%d*****\n", tmps->nodeNr);
2774#endif
2775      if (asRaw == true)
2776        {
2777          addToMap (request_inputs, "RawDataOutput", "");
2778          xmlNodePtr cur0 = tmps->nodeTab[0];
2779          if (cur0->type == XML_ELEMENT_NODE)
2780            {
2781
2782              maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
2783              if (tmpmaps == NULL)
2784                {
2785                  return errorException (m, _("Unable to allocate memory."),
2786                                         "InternalError", NULL);
2787                }
2788              tmpmaps->name = zStrdup ("unknownIdentifier");
2789              tmpmaps->content = NULL;
2790              tmpmaps->next = NULL;
2791
2792        /**
2793         * Get every attribute from a RawDataOutput node
2794         * mimeType, encoding, schema, uom
2795         */
2796              const char *outs[4] =
2797                { "mimeType", "encoding", "schema", "uom" };
2798              for (int l = 0; l < 4; l++)
2799                {
2800#ifdef DEBUG
2801                  fprintf (stderr, "*** %s ***\t", outs[l]);
2802#endif
2803                  xmlChar *val = xmlGetProp (cur0, BAD_CAST outs[l]);
2804                  if (val != NULL)
2805                    {
2806                      if (strlen ((char *) val) > 0)
2807                        {
2808                          if (tmpmaps->content != NULL)
2809                            addToMap (tmpmaps->content, outs[l],
2810                                      (char *) val);
2811                          else
2812                            tmpmaps->content =
2813                              createMap (outs[l], (char *) val);
2814                        }
2815                      xmlFree (val);
2816                    }
2817                }
2818              xmlNodePtr cur2 = cur0->children;
2819              while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
2820                cur2 = cur2->next;
2821              while (cur2 != NULL)
2822                {
2823                  if (xmlStrncasecmp
2824                      (cur2->name, BAD_CAST "Identifier",
2825                       xmlStrlen (cur2->name)) == 0)
2826                    {
2827                      xmlChar *val =
2828                        xmlNodeListGetString (NULL, cur2->xmlChildrenNode, 1);
2829                      free (tmpmaps->name);
2830                      tmpmaps->name = zStrdup ((char *) val);
2831                      xmlFree (val);
2832                    }
2833                  cur2 = cur2->next;
2834                  while (cur2 != NULL && cur2->type != XML_ELEMENT_NODE)
2835                    cur2 = cur2->next;
2836                }
2837              if (request_output_real_format == NULL)
2838                request_output_real_format = dupMaps (&tmpmaps);
2839              else
2840                addMapsToMaps (&request_output_real_format, tmpmaps);
2841              if (tmpmaps != NULL)
2842                {
2843                  freeMaps (&tmpmaps);
2844                  free (tmpmaps);
2845                  tmpmaps = NULL;
2846                }
2847            }
2848        }
2849      else
2850          {
2851                addToMap (request_inputs, "ResponseDocument", "");
2852                       
2853                xmlNodePtr cur = tmps->nodeTab[0]; // only one ResponseDocument node
2854                if (cur->type == XML_ELEMENT_NODE) {
2855                /**
2856                 * Get every attribute: storeExecuteResponse, lineage, status
2857                 */
2858                        //map* attributes = NULL;
2859                        const char *ress[3] =
2860                          { "storeExecuteResponse", "lineage", "status" };
2861                        xmlChar *val;
2862                        for (int l = 0; l < 3; l++)
2863                        {
2864        #ifdef DEBUG
2865                                fprintf (stderr, "*** %s ***\t", ress[l]);
2866        #endif
2867                                val = xmlGetProp (cur, BAD_CAST ress[l]);
2868                                if (val != NULL && strlen ((char *) val) > 0)
2869                                {
2870                                /*
2871                                        if (attributes == NULL) {
2872                                                attributes = createMap (ress[l], (char *) val);
2873                                        }
2874                                        else {
2875                                                addToMap (attributes, ress[l], (char *) val);
2876                                        }
2877                                */             
2878                                        addToMap (request_inputs, ress[l], (char *) val);
2879                                  }
2880        #ifdef DEBUG
2881                                fprintf (stderr, "%s\n", val);
2882        #endif
2883                                xmlFree (val);
2884                        }
2885                       
2886                        xmlNodePtr cur1 = cur->children;               
2887                        while (cur1 != NULL) // iterate over Output nodes
2888                        {
2889                                if (cur1->type != XML_ELEMENT_NODE || 
2890                                        xmlStrncasecmp(cur1->name, BAD_CAST "Output", 
2891                                                                   xmlStrlen (cur1->name)) != 0) {
2892                                        cur1 = cur1->next;
2893                                        continue;
2894                                }
2895                               
2896                                maps *tmpmaps = (maps *) malloc (MAPS_SIZE); // one per Output node
2897                                if (tmpmaps == NULL) {
2898                                        return errorException (m,
2899                                                                                   _
2900                                                                                   ("Unable to allocate memory."),
2901                                                                                   "InternalError", NULL);
2902                                }
2903                                tmpmaps->name = zStrdup ("unknownIdentifier");
2904                                tmpmaps->content = NULL;
2905                                tmpmaps->next = NULL;
2906                               
2907                                xmlNodePtr elems = cur1->children;
2908                               
2909                                while (elems != NULL) {
2910                               
2911                                        /**
2912                                         * Identifier
2913                                         */             
2914                                        if (xmlStrncasecmp
2915                                                (elems->name, BAD_CAST "Identifier",
2916                                                 xmlStrlen (elems->name)) == 0)
2917                                        {                       
2918                                                xmlChar *val =
2919                                                  xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
2920                                               
2921                                                free(tmpmaps->name);
2922                                                tmpmaps->name = zStrdup ((char *) val); 
2923                                                if (tmpmaps->content == NULL) {
2924                                                        tmpmaps->content = createMap("Identifier", zStrdup ((char *) val));
2925                                                }
2926                                                else {
2927                                                        addToMap(tmpmaps->content, "Identifier", zStrdup ((char *) val));
2928                                                }
2929                                         
2930                                                map* tt = getMap (request_inputs, "ResponseDocument");                           
2931                                                if (strlen(tt->value) == 0) {
2932                                                  addToMap (request_inputs, "ResponseDocument",
2933                                                                        (char *) val);                                                 
2934                                                }       
2935                                                else {
2936                                                        char* tmp = (char*) malloc((strlen(tt->value) + 1 
2937                                                                                                + strlen((char*) val) + 1) * sizeof(char));
2938                                                        sprintf (tmp, "%s;%s", tt->value, (char *) val);
2939                                                        free(tt->value);
2940                                                        tt->value = tmp;       
2941                                                }       
2942                                                xmlFree (val);
2943                                        }                               
2944                                        /**
2945                                         * Title, Abstract
2946                                         */
2947                                        else if (xmlStrncasecmp(elems->name, BAD_CAST "Title",
2948                                                                                        xmlStrlen (elems->name)) == 0
2949                                                  || xmlStrncasecmp(elems->name, BAD_CAST "Abstract",
2950                                                                                 xmlStrlen (elems->name)) == 0)
2951                                        {
2952                                                xmlChar *val =
2953                                                        xmlNodeListGetString (doc, elems->xmlChildrenNode, 1);
2954                                                       
2955                                                if (tmpmaps->content == NULL) {
2956                                                        tmpmaps->content = createMap((char*) elems->name, zStrdup ((char *) val));
2957                                                }
2958                                                else {
2959                                                        addToMap(tmpmaps->content, (char*) elems->name, zStrdup ((char *) val));
2960                                                }
2961                                                xmlFree (val);
2962                                        }
2963                                        elems = elems->next;
2964                                }
2965                               
2966                                /**
2967                                 * Get every attribute from an Output node:
2968                                 * mimeType, encoding, schema, uom, asReference
2969                                 */
2970                                const char *outs[5] =
2971                                          { "mimeType", "encoding", "schema", "uom", "asReference" };
2972                                         
2973                                for (int l = 0; l < 5; l++) {
2974        #ifdef DEBUG
2975                                        fprintf (stderr, "*** %s ***\t", outs[l]);
2976        #endif
2977                                        xmlChar *val = xmlGetProp (cur1, BAD_CAST outs[l]);                             
2978                                        if (val != NULL && xmlStrlen(val) > 0) {
2979                                                if (tmpmaps->content != NULL) {
2980                                                        addToMap (tmpmaps->content, outs[l], (char *) val);
2981                                                }                         
2982                                                else {
2983                                                        tmpmaps->content = createMap (outs[l], (char *) val);
2984                                                }       
2985                                        }
2986        #ifdef DEBUG
2987                                        fprintf (stderr, "%s\n", val);
2988        #endif
2989                                        xmlFree (val);
2990                                }
2991                               
2992                                if (request_output_real_format == NULL) {
2993                                        request_output_real_format = tmpmaps;
2994                                }       
2995                                else if (getMaps(request_output_real_format, tmpmaps->name) != NULL) {
2996                                        return errorException (m,
2997                                                                                   _
2998                                                                                   ("Duplicate <Output> elements in WPS Execute request"),
2999                                                                                   "InternalError", NULL);
3000                                }
3001                                else {
3002                                        maps* mptr = request_output_real_format;
3003                                        while (mptr->next != NULL) {
3004                                                mptr = mptr->next;
3005                                        }
3006                                        mptr->next = tmpmaps;   
3007                                }                                       
3008                                cur1 = cur1->next;
3009                        }                       
3010                }
3011          } 
3012      xmlXPathFreeObject (tmpsptr);
3013      xmlFreeDoc (doc);
3014      xmlCleanupParser ();
3015    }
3016
3017  runHttpRequests (&m, &request_input_real_format, &hInternet);
3018
3019  //  if(CHECK_INET_HANDLE(hInternet))
3020  InternetCloseHandle (&hInternet);
3021
3022#ifdef DEBUG
3023  fprintf (stderr, "\n%d\n", __LINE__);
3024  fflush (stderr);
3025  dumpMaps (request_input_real_format);
3026  dumpMaps (request_output_real_format);
3027  dumpMap (request_inputs);
3028  fprintf (stderr, "\n%d\n", __LINE__);
3029  fflush (stderr);
3030#endif
3031
3032  /**
3033   * Ensure that each requested arguments are present in the request
3034   * DataInputs and ResponseDocument / RawDataOutput
3035   */
3036  map* errI=NULL;
3037#ifdef DEBUG 
3038  dumpMaps(request_input_real_format);
3039#endif 
3040  char *dfv = addDefaultValues (&request_input_real_format, s1->inputs, m, 0,&errI);
3041#ifdef DEBUG 
3042  dumpMaps(request_input_real_format);
3043#endif 
3044  maps *ptr = request_input_real_format;
3045  while (ptr != NULL)
3046    {
3047      map *tmp0 = getMap (ptr->content, "size");
3048      map *tmp1 = getMap (ptr->content, "maximumMegabytes");
3049      if (tmp1 != NULL && tmp0 != NULL)
3050        {
3051          float i = atof (tmp0->value) / 1048576.0;
3052          if (i >= atoi (tmp1->value))
3053            {
3054              char tmps[1024];
3055              map *tmpe = createMap ("code", "FileSizeExceeded");
3056              snprintf (tmps, 1024,
3057                        _
3058                        ("The <%s> parameter has a size limit (%s MB) defined in the ZOO ServicesProvider configuration file, but the reference you provided exceeds this limit (%f MB)."),
3059                        ptr->name, tmp1->value, i);
3060              addToMap (tmpe, "locator", ptr->name);
3061              addToMap (tmpe, "text", tmps);
3062              printExceptionReportResponse (m, tmpe);
3063              freeService (&s1);
3064              free (s1);
3065              freeMap (&tmpe);
3066              free (tmpe);
3067              freeMaps (&m);
3068              free (m);
3069              free (REQUEST);
3070              free (SERVICE_URL);
3071              freeMaps (&request_input_real_format);
3072              free (request_input_real_format);
3073              freeMaps (&request_output_real_format);
3074              free (request_output_real_format);
3075              freeMaps (&tmpmaps);
3076              free (tmpmaps);
3077              return 1;
3078            }
3079        }
3080      ptr = ptr->next;
3081    }
3082
3083  map* errO=NULL;
3084  char *dfv1 =
3085    addDefaultValues (&request_output_real_format, s1->outputs, m, 1,&errO);
3086  if (strcmp (dfv1, "") != 0 || strcmp (dfv, "") != 0)
3087    {
3088      char tmps[1024];
3089      map *tmpe = NULL;
3090      if (strcmp (dfv, "") != 0)
3091        {
3092          tmpe = createMap ("code", "MissingParameterValue");
3093          int nb=0;
3094          int length=1;
3095          map* len=getMap(errI,"length");
3096          if(len!=NULL)
3097            length=atoi(len->value);
3098          for(nb=0;nb<length;nb++){
3099            map* errp=getMapArray(errI,"value",nb);
3100            snprintf (tmps, 1024,
3101                      _
3102                      ("The <%s> argument was not specified in DataInputs but is required according to the ZOO ServicesProvider configuration file."),
3103                      errp->value);
3104            setMapArray (tmpe, "locator", nb , errp->value);
3105            setMapArray (tmpe, "text", nb , tmps);
3106            setMapArray (tmpe, "code", nb , "MissingParameterValue");
3107          }
3108        }
3109      if (strcmp (dfv1, "") != 0)
3110        {
3111          int ilength=0;
3112          if(tmpe==NULL)
3113            tmpe = createMap ("code", "InvalidParameterValue");
3114          else{
3115            map* len=getMap(tmpe,"length");
3116            if(len!=NULL)
3117              ilength=atoi(len->value);
3118          }
3119          int nb=0;
3120          int length=1;
3121          map* len=getMap(errO,"length");
3122          if(len!=NULL)
3123            length=atoi(len->value);
3124          for(nb=0;nb<length;nb++){
3125            map* errp=getMapArray(errO,"value",nb);
3126            snprintf (tmps, 1024,
3127                      _
3128                      ("The <%s> argument specified as %s identifier was not recognized (not defined in the ZOO Configuration File)."),
3129                      errp->value,
3130                      ((getMap(request_inputs,"RawDataOutput")!=NULL)?"RawDataOutput":"ResponseDocument"));
3131            setMapArray (tmpe, "locator", nb+ilength , errp->value);
3132            setMapArray (tmpe, "text", nb+ilength , tmps);
3133            setMapArray (tmpe, "code", nb+ilength , "InvalidParameterValue");
3134          }
3135        }
3136      printExceptionReportResponse (m, tmpe);
3137      freeService (&s1);
3138      free (s1);
3139      freeMap (&tmpe);
3140      free (tmpe);
3141      freeMaps (&m);
3142      free (m);
3143      free (REQUEST);
3144      free (SERVICE_URL);
3145      freeMaps (&request_input_real_format);
3146      free (request_input_real_format);
3147      freeMaps (&request_output_real_format);
3148      free (request_output_real_format);
3149      freeMaps (&tmpmaps);
3150      free (tmpmaps);
3151      if(errI!=NULL){
3152        freeMap(&errI);
3153        free(errI);
3154      }
3155      if(errO!=NULL){
3156        freeMap(&errO);
3157        free(errO);
3158      }
3159      return 1;
3160    }
3161  maps *tmpReqI = request_input_real_format;
3162  while (tmpReqI != NULL)
3163    {
3164      char name[1024];
3165      if (getMap (tmpReqI->content, "isFile") != NULL)
3166        {
3167          if (cgiFormFileName (tmpReqI->name, name, sizeof (name)) ==
3168              cgiFormSuccess)
3169            {
3170              int BufferLen = 1024;
3171              cgiFilePtr file;
3172              int targetFile;
3173              char storageNameOnServer[2048];
3174              char fileNameOnServer[64];
3175              char contentType[1024];
3176              char buffer[1024];
3177              char *tmpStr = NULL;
3178              int size;
3179              int got, t;
3180              map *path = getMapFromMaps (m, "main", "tmpPath");
3181              cgiFormFileSize (tmpReqI->name, &size);
3182              cgiFormFileContentType (tmpReqI->name, contentType,
3183                                      sizeof (contentType));
3184              if (cgiFormFileOpen (tmpReqI->name, &file) == cgiFormSuccess)
3185                {
3186                  t = -1;
3187                  while (1)
3188                    {
3189                      tmpStr = strstr (name + t + 1, "\\");
3190                      if (NULL == tmpStr)
3191                        tmpStr = strstr (name + t + 1, "/");
3192                      if (NULL != tmpStr)
3193                        t = (int) (tmpStr - name);
3194                      else
3195                        break;
3196                    }
3197                  strcpy (fileNameOnServer, name + t + 1);
3198
3199                  sprintf (storageNameOnServer, "%s/%s", path->value,
3200                           fileNameOnServer);
3201#ifdef DEBUG
3202                  fprintf (stderr, "Name on server %s\n",
3203                           storageNameOnServer);
3204                  fprintf (stderr, "fileNameOnServer: %s\n",
3205                           fileNameOnServer);
3206#endif
3207                  targetFile =
3208                    open (storageNameOnServer, O_RDWR | O_CREAT | O_TRUNC,
3209                          S_IRWXU | S_IRGRP | S_IROTH);
3210                  if (targetFile < 0)
3211                    {
3212#ifdef DEBUG
3213                      fprintf (stderr, "could not create the new file,%s\n",
3214                               fileNameOnServer);
3215#endif
3216                    }
3217                  else
3218                    {
3219                      while (cgiFormFileRead (file, buffer, BufferLen, &got)
3220                             == cgiFormSuccess)
3221                        {
3222                          if (got > 0)
3223                            write (targetFile, buffer, got);
3224                        }
3225                    }
3226                  addToMap (tmpReqI->content, "lref", storageNameOnServer);
3227                  cgiFormFileClose (file);
3228                  close (targetFile);
3229#ifdef DEBUG
3230                  fprintf (stderr, "File \"%s\" has been uploaded",
3231                           fileNameOnServer);
3232#endif
3233                }
3234            }
3235        }
3236      tmpReqI = tmpReqI->next;
3237    }
3238
3239  ensureDecodedBase64 (&request_input_real_format);
3240
3241#ifdef DEBUG
3242  fprintf (stderr, "REQUEST_INPUTS\n");
3243  dumpMaps (request_input_real_format);
3244  fprintf (stderr, "REQUEST_OUTPUTS\n");
3245  dumpMaps (request_output_real_format);
3246#endif
3247
3248  maps *curs = getMaps (m, "env");
3249  if (curs != NULL)
3250    {
3251      map *mapcs = curs->content;
3252      while (mapcs != NULLMAP)
3253        {
3254#ifndef WIN32
3255          setenv (mapcs->name, mapcs->value, 1);
3256#else
3257#ifdef DEBUG
3258          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
3259                   mapcs->value);
3260#endif
3261          if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
3262            {
3263#ifdef DEBUG
3264              fprintf (stderr, "[ZOO: Env var finish with \r]\n");
3265#endif
3266              mapcs->value[strlen (mapcs->value) - 1] = 0;
3267            }
3268#ifdef DEBUG
3269          if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
3270            {
3271              fflush (stderr);
3272              fprintf (stderr, "setting variable... %s\n", "OK");
3273            }
3274          else
3275            {
3276              fflush (stderr);
3277              fprintf (stderr, "setting variable... %s\n", "OK");
3278            }
3279#else
3280
3281
3282          SetEnvironmentVariable (mapcs->name, mapcs->value);
3283#endif
3284          char *toto =
3285            (char *)
3286            malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
3287                     2) * sizeof (char));
3288          sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
3289          putenv (toto);
3290#ifdef DEBUG
3291          fflush (stderr);
3292#endif
3293#endif
3294#ifdef DEBUG
3295          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
3296                   mapcs->value);
3297          fflush (stderr);
3298#endif
3299          mapcs = mapcs->next;
3300        }
3301    }
3302
3303#ifdef DEBUG
3304  dumpMap (request_inputs);
3305#endif
3306
3307  /**
3308   * Need to check if we need to fork to load a status enabled
3309   */
3310  r_inputs = NULL;
3311  map *store = getMap (request_inputs, "storeExecuteResponse");
3312  map *status = getMap (request_inputs, "status");
3313  /**
3314   * 05-007r7 WPS 1.0.0 page 57 :
3315   * 'If status="true" and storeExecuteResponse is "false" then the service
3316   * shall raise an exception.'
3317   */
3318  if (status != NULL && strcmp (status->value, "true") == 0 &&
3319      store != NULL && strcmp (store->value, "false") == 0)
3320    {
3321      errorException (m,
3322                      _
3323                      ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
3324                      "InvalidParameterValue", "storeExecuteResponse");
3325      freeService (&s1);
3326      free (s1);
3327      freeMaps (&m);
3328      free (m);
3329
3330      freeMaps (&request_input_real_format);
3331      free (request_input_real_format);
3332
3333      freeMaps (&request_output_real_format);
3334      free (request_output_real_format);
3335
3336      free (REQUEST);
3337      free (SERVICE_URL);
3338      return 1;
3339    }
3340  r_inputs = getMap (request_inputs, "storeExecuteResponse");
3341  int eres = SERVICE_STARTED;
3342  int cpid = getpid ();
3343
3344  /**
3345   * Initialize the specific [lenv] section which contains runtime variables:
3346   *
3347   *  - usid : it is an unique identification number
3348   *  - sid : it is the process idenfitication number (OS)
3349   *  - status : value between 0 and 100 to express the  completude of
3350   * the operations of the running service
3351   *  - message : is a string where you can store error messages, in case
3352   * service is failing, or o provide details on the ongoing operation.
3353   *  - cwd : is the current working directory
3354   *  - soap : is a boolean value, true if the request was contained in a SOAP
3355   * Envelop
3356   *  - sessid : string storing the session identifier (only when cookie is
3357   * used)
3358   *  - cgiSid : only defined on Window platforms (for being able to identify
3359   * the created process)
3360   *
3361   */
3362  maps *_tmpMaps = (maps *) malloc (MAPS_SIZE);
3363  _tmpMaps->name = zStrdup ("lenv");
3364  char tmpBuff[100];
3365  semid lid = getShmLockId (NULL, 1);
3366  lockShm (lid);
3367  struct ztimeval tp;
3368  if (zGettimeofday (&tp, NULL) == 0)
3369    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
3370  else
3371    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
3372  unlockShm (lid);
3373  removeShmLock (NULL, 1);
3374  _tmpMaps->content = createMap ("usid", tmpBuff);
3375  _tmpMaps->next = NULL;
3376  sprintf (tmpBuff, "%i", cpid);
3377  addToMap (_tmpMaps->content, "sid", tmpBuff);
3378  addToMap (_tmpMaps->content, "status", "0");
3379  addToMap (_tmpMaps->content, "cwd", ntmp);
3380  addToMap (_tmpMaps->content, "message", _("No message provided"));
3381  map *ltmp = getMap (request_inputs, "soap");
3382  if (ltmp != NULL)
3383    addToMap (_tmpMaps->content, "soap", ltmp->value);
3384  else
3385    addToMap (_tmpMaps->content, "soap", "false");
3386  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
3387    {
3388      int hasValidCookie = -1;
3389      char *tcook = zStrdup (cgiCookie);
3390      char *tmp = NULL;
3391      map *testing = getMapFromMaps (m, "main", "cookiePrefix");
3392      if (testing == NULL)
3393        {
3394          tmp = zStrdup ("ID=");
3395        }
3396      else
3397        {
3398          tmp =
3399            (char *) malloc ((strlen (testing->value) + 2) * sizeof (char));
3400          sprintf (tmp, "%s=", testing->value);
3401        }
3402      if (strstr (cgiCookie, ";") != NULL)
3403        {
3404          char *token, *saveptr;
3405          token = strtok_r (cgiCookie, ";", &saveptr);
3406          while (token != NULL)
3407            {
3408              if (strcasestr (token, tmp) != NULL)
3409                {
3410                  if (tcook != NULL)
3411                    free (tcook);
3412                  tcook = zStrdup (token);
3413                  hasValidCookie = 1;
3414                }
3415              token = strtok_r (NULL, ";", &saveptr);
3416            }
3417        }
3418      else
3419        {
3420          if (strstr (cgiCookie, "=") != NULL
3421              && strcasestr (cgiCookie, tmp) != NULL)
3422            {
3423              tcook = zStrdup (cgiCookie);
3424              hasValidCookie = 1;
3425            }
3426          if (tmp != NULL)
3427            {
3428              free (tmp);
3429            }
3430        }
3431      if (hasValidCookie > 0)
3432        {
3433          addToMap (_tmpMaps->content, "sessid", strstr (tcook, "=") + 1);
3434          char session_file_path[1024];
3435          map *tmpPath = getMapFromMaps (m, "main", "sessPath");
3436          if (tmpPath == NULL)
3437            tmpPath = getMapFromMaps (m, "main", "tmpPath");
3438          char *tmp1 = strtok (tcook, ";");
3439          if (tmp1 != NULL)
3440            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
3441                     strstr (tmp1, "=") + 1);
3442          else
3443            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
3444                     strstr (cgiCookie, "=") + 1);
3445          free (tcook);
3446          maps *tmpSess = (maps *) malloc (MAPS_SIZE);
3447          struct stat file_status;
3448          int istat = stat (session_file_path, &file_status);
3449          if (istat == 0 && file_status.st_size > 0)
3450            {
3451              conf_read (session_file_path, tmpSess);
3452              addMapsToMaps (&m, tmpSess);
3453              freeMaps (&tmpSess);
3454              free (tmpSess);
3455            }
3456        }
3457    }
3458  addMapsToMaps (&m, _tmpMaps);
3459  freeMaps (&_tmpMaps);
3460  free (_tmpMaps);
3461
3462#ifdef DEBUG
3463  dumpMap (request_inputs);
3464#endif
3465#ifdef WIN32
3466  char *cgiSidL = NULL;
3467  if (getenv ("CGISID") != NULL)
3468    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
3469
3470  char* usidp;
3471  if ( (usidp = getenv("USID")) != NULL ) {
3472    setMapInMaps (m, "lenv", "usid", usidp);
3473  }
3474
3475  map *test1 = getMap (request_inputs, "cgiSid");
3476  if (test1 != NULL)
3477    {
3478      cgiSid = test1->value;
3479      addToMap (request_inputs, "storeExecuteResponse", "true");
3480      addToMap (request_inputs, "status", "true");
3481      setMapInMaps (m, "lenv", "sid", test1->value);
3482      status = getMap (request_inputs, "status");
3483    }
3484#endif
3485  char *fbkp, *fbkp1;
3486  FILE *f0, *f1;
3487  if (status != NULL)
3488    if (strcasecmp (status->value, "false") == 0)
3489      status = NULLMAP;
3490  if (status == NULLMAP)
3491    {
3492      loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
3493                         &request_output_real_format, &eres);
3494    }
3495  else
3496    {
3497      int pid;
3498#ifdef DEBUG
3499      fprintf (stderr, "\nPID : %d\n", cpid);
3500#endif
3501
3502#ifndef WIN32
3503      pid = fork ();
3504#else
3505      if (cgiSid == NULL)
3506        {
3507          createProcess (m, request_inputs, s1, NULL, cpid,
3508                         request_input_real_format,
3509                         request_output_real_format);
3510          pid = cpid;
3511        }
3512      else
3513        {
3514          pid = 0;
3515          cpid = atoi (cgiSid);
3516        }
3517#endif
3518      if (pid > 0)
3519        {
3520      /**
3521       * dady :
3522       * set status to SERVICE_ACCEPTED
3523       */
3524#ifdef DEBUG
3525          fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
3526                   getpid ());
3527#endif
3528          eres = SERVICE_ACCEPTED;
3529        }
3530      else if (pid == 0)
3531        {
3532      /**
3533       * son : have to close the stdout, stdin and stderr to let the parent
3534       * process answer to http client.
3535       */
3536#ifndef WIN32
3537          zSleep (1);
3538#endif
3539          r_inputs = getMapFromMaps (m, "lenv", "usid");
3540          int cpid = atoi (r_inputs->value);
3541          r_inputs = getMapFromMaps (m, "main", "tmpPath");
3542          //map *r_inputs1 = getMap (s1->content, "ServiceProvider");
3543                  map* r_inputs1 = createMap("ServiceName", s1->name);
3544
3545          fbkp =
3546            (char *)
3547            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3548                     1024) * sizeof (char));
3549          sprintf (fbkp, "%s/%s_%d.xml", r_inputs->value, r_inputs1->value,
3550                   cpid);
3551          char *flog =
3552            (char *)
3553            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3554                     1024) * sizeof (char));
3555          sprintf (flog, "%s/%s_%d_error.log", r_inputs->value,
3556                   r_inputs1->value, cpid);
3557#ifdef DEBUG
3558          fprintf (stderr, "RUN IN BACKGROUND MODE \n");
3559          fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
3560                   getpid ());
3561          fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
3562#endif
3563          freopen (flog, "w+", stderr);
3564          semid lid = getShmLockId (m, 1);
3565          fflush (stderr);
3566          if (lid < 0)
3567            {
3568              fprintf (stderr, "ERROR %s %d\n", __FILE__, __LINE__);
3569              fflush (stderr);
3570              return -1;
3571            }
3572          else
3573            {
3574              if (lockShm (lid) < 0)
3575                {
3576                  fprintf (stderr, "ERROR %s %d\n", __FILE__, __LINE__);
3577                  fflush (stderr);
3578                  return -1;
3579                }
3580              fflush (stderr);
3581            }
3582          f0 = freopen (fbkp, "w+", stdout);
3583          rewind (stdout);
3584#ifndef WIN32
3585          fclose (stdin);
3586#endif
3587          free (flog);
3588      /**
3589       * set status to SERVICE_STARTED and flush stdout to ensure full
3590       * content was outputed (the file used to store the ResponseDocument).
3591       * The rewind stdout to restart writing from the bgining of the file,
3592       * this way the data will be updated at the end of the process run.
3593       */
3594          printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
3595                                SERVICE_STARTED, request_input_real_format,
3596                                request_output_real_format);
3597          fflush (stdout);
3598          unlockShm (lid);
3599          fflush (stderr);
3600          fbkp1 =
3601            (char *)
3602            malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3603                     1024) * sizeof (char));
3604          sprintf (fbkp1, "%s/%s_final_%d.xml", r_inputs->value,
3605                   r_inputs1->value, cpid);
3606          f1 = freopen (fbkp1, "w+", stdout);
3607          loadServiceAndRun (&m, s1, request_inputs,
3608                             &request_input_real_format,
3609                             &request_output_real_format, &eres);
3610        }
3611      else
3612        {
3613      /**
3614       * error server don't accept the process need to output a valid
3615       * error response here !!!
3616       */
3617          eres = -1;
3618          errorException (m, _("Unable to run the child process properly"),
3619                          "InternalError", NULL);
3620        }
3621    }
3622
3623#ifdef DEBUG
3624  dumpMaps (request_output_real_format);
3625#endif
3626  if (eres != -1)
3627    outputResponse (s1, request_input_real_format,
3628                    request_output_real_format, request_inputs,
3629                    cpid, m, eres);
3630  fflush (stdout);
3631 
3632  /**
3633   * Ensure that if error occurs when freeing memory, no signal will return
3634   * an ExceptionReport document as the result was already returned to the
3635   * client.
3636   */
3637#ifndef USE_GDB
3638  signal (SIGSEGV, donothing);
3639  signal (SIGTERM, donothing);
3640  signal (SIGINT, donothing);
3641  signal (SIGILL, donothing);
3642  signal (SIGFPE, donothing);
3643  signal (SIGABRT, donothing);
3644#endif
3645  if (((int) getpid ()) != cpid || cgiSid != NULL)
3646    {
3647      fclose (stdout);
3648      fclose (stderr);
3649    /**
3650     * Dump back the final file fbkp1 to fbkp
3651     */
3652      fclose (f0);
3653      fclose (f1);
3654      FILE *f2 = fopen (fbkp1, "rb");
3655      semid lid = getShmLockId (m, 1);
3656      if (lid < 0)
3657        return -1;
3658      lockShm (lid);
3659      FILE *f3 = fopen (fbkp, "wb+");
3660      free (fbkp);
3661      fseek (f2, 0, SEEK_END);
3662      long flen = ftell (f2);
3663      fseek (f2, 0, SEEK_SET);
3664      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
3665      fread (tmps1, flen, 1, f2);
3666      fwrite (tmps1, 1, flen, f3);
3667      fclose (f2);
3668      fclose (f3);
3669      unlockShm (lid);
3670      unlink (fbkp1);
3671      free (fbkp1);
3672      free (tmps1);
3673      unhandleStatus (m);
3674    }
3675
3676  freeService (&s1);
3677  free (s1);
3678  freeMaps (&m);
3679  free (m);
3680
3681  freeMaps (&request_input_real_format);
3682  free (request_input_real_format);
3683
3684  freeMaps (&request_output_real_format);
3685  free (request_output_real_format);
3686
3687  free (REQUEST);
3688  free (SERVICE_URL);
3689#ifdef DEBUG
3690  fprintf (stderr, "Processed response \n");
3691  fflush (stdout);
3692  fflush (stderr);
3693#endif
3694
3695  if (((int) getpid ()) != cpid || cgiSid != NULL)
3696    {
3697      exit (0);
3698    }
3699
3700  return 0;
3701}
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