source: branches/PublicaMundi_David-devel/zoo-project/zoo-kernel/zoo_service_loader.c @ 524

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