source: branches/PublicaMundi_David-devel/zoo-project/zoo-kernel/service_internal.c @ 644

Last change on this file since 644 was 617, checked in by david, 10 years ago

commit of partial async queue process management

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 122.2 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2013 GeoLabs SARL
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#include "service_internal.h"
26#ifdef USE_MS
27#include "service_internal_ms.h"
28#else
29#include "cpl_vsi.h"
30#endif
31
32#ifndef TRUE
33#define TRUE 1
34#endif
35#ifndef FALSE
36#define FALSE -1
37#endif
38
39int
40isValidLang (maps * conf, const char *str)
41{
42  map *tmpMap = getMapFromMaps (conf, "main", "lang");
43  char *tmp = zStrdup (tmpMap->value);
44  char *pToken = strtok (tmp, ",");
45  int res = -1;
46  while (pToken != NULL)
47    {
48      if (strcasecmp (str, pToken) == 0)
49        {
50          res = 1;
51          break;
52        }
53      pToken = strtok (NULL, ",");
54    }
55  free (tmp);
56  return res;
57}
58
59void
60printHeaders (maps * m,FCGX_Stream *out)
61{
62  maps *_tmp = getMaps (m, "headers");
63  if (_tmp != NULL)
64    {
65      map *_tmp1 = _tmp->content;
66      while (_tmp1 != NULL)
67        {
68          FCGX_FPrintF(out,"%s: %s\r\n", _tmp1->name, _tmp1->value);
69          //printf ("%s: %s\r\n", _tmp1->name, _tmp1->value);
70          _tmp1 = _tmp1->next;
71        }
72    }
73}
74
75void
76addLangAttr (xmlNodePtr n, maps * m)
77{
78  map *tmpLmap = getMapFromMaps (m, "main", "language");
79  if (tmpLmap != NULL)
80    xmlNewProp (n, BAD_CAST "xml:lang", BAD_CAST tmpLmap->value);
81  else
82    xmlNewProp (n, BAD_CAST "xml:lang", BAD_CAST "en-US");
83}
84
85/* Converts a hex character to its integer value */
86char
87from_hex (char ch)
88{
89  return isdigit (ch) ? ch - '0' : tolower (ch) - 'a' + 10;
90}
91
92/* Converts an integer value to its hex character*/
93char
94to_hex (char code)
95{
96  static char hex[] = "0123456789abcdef";
97  return hex[code & 15];
98}
99
100#ifdef WIN32
101
102#include <windows.h>
103//#include <fcgi_stdio.h>
104#include <stdio.h>
105#include <conio.h>
106#include <tchar.h>
107
108#define SHMEMSIZE 4096
109
110static LPVOID lpvMemG = NULL;   // pointer to shared memory
111static HANDLE hMapObjectG = NULL;       // handle to file mapping
112
113int
114_updateStatus (maps * conf)
115{
116  LPWSTR lpszTmp;
117  BOOL fInit;
118  char *final_string = NULL;
119  char *s = NULL;
120  map *tmpMap1;
121  map *tmpMap = getMapFromMaps (conf, "lenv", "sid");
122  if (hMapObjectG == NULL)
123    hMapObjectG = CreateFileMapping (INVALID_HANDLE_VALUE,      // use paging file
124                                     NULL,      // default security attributes
125                                     PAGE_READWRITE,    // read/write access
126                                     0, // size: high 32-bits
127                                     SHMEMSIZE, // size: low 32-bits
128                                     TEXT (tmpMap->value));     // name of map object
129  if (hMapObjectG == NULL)
130    {
131      fprintf (stderr, "Unable to create share memory segment %s !! \n",
132               tmpMap->value);
133      return -2;
134    }
135  fInit = (GetLastError () != ERROR_ALREADY_EXISTS);
136  if (lpvMemG == NULL)
137    lpvMemG = MapViewOfFile (hMapObjectG,       // object to map view of
138                             FILE_MAP_WRITE,    // read/write access
139                             0, // high offset:  map from
140                             0, // low offset:   beginning
141                             0);        // default: map entire file
142  if (lpvMemG == NULL)
143    {
144      fprintf (stderr,
145               "Unable to create or access the shared memory segment %s !! \n",
146               tmpMap->value);
147      return -1;
148    }
149  memset (lpvMemG, '\0', SHMEMSIZE);
150  tmpMap = getMapFromMaps (conf, "lenv", "status");
151  tmpMap1 = NULL;
152  tmpMap1 = getMapFromMaps (conf, "lenv", "message");
153  lpszTmp = (LPWSTR) lpvMemG;
154  final_string =
155    (char *) malloc ((strlen (tmpMap1->value) + strlen (tmpMap->value) + 2) *
156                     sizeof (char));
157  sprintf (final_string, "%s|%s", tmpMap->value, tmpMap1->value);
158  for (s = final_string; *s != '\0'; *s++)
159    {
160      *lpszTmp++ = *s;
161    }
162  *lpszTmp++ = '\0';
163  free (final_string);
164  return 0;
165}
166
167char *
168getStatus (int pid)
169{
170  char *lpszBuf = (char *) malloc (SHMEMSIZE * sizeof (char));
171  int i = 0;
172  LPWSTR lpszTmp = NULL;
173  LPVOID lpvMem = NULL;
174  HANDLE hMapObject = NULL;
175  BOOL fIgnore, fInit;
176  char tmp[100];
177  sprintf (tmp, "%i", pid);
178  if (hMapObject == NULL)
179    hMapObject = CreateFileMapping (INVALID_HANDLE_VALUE,       // use paging file
180                                    NULL,       // default security attributes
181                                    PAGE_READWRITE,     // read/write access
182                                    0,  // size: high 32-bits
183                                    4096,       // size: low 32-bits
184                                    TEXT (tmp));        // name of map object
185  if (hMapObject == NULL)
186    return FALSE;
187  if ((GetLastError () != ERROR_ALREADY_EXISTS))
188    {
189      fIgnore = UnmapViewOfFile (lpvMem);
190      fIgnore = CloseHandle (hMapObject);
191      return "-1";
192    }
193  fInit = TRUE;
194  if (lpvMem == NULL)
195    lpvMem = MapViewOfFile (hMapObject, // object to map view of
196                            FILE_MAP_READ,      // read/write access
197                            0,  // high offset:  map from
198                            0,  // low offset:   beginning
199                            0); // default: map entire file
200  if (lpvMem == NULL)
201    return "-1";
202  lpszTmp = (LPWSTR) lpvMem;
203  while (*lpszTmp)
204    {
205      lpszBuf[i] = (char) *lpszTmp;
206      *lpszTmp++;
207      lpszBuf[i + 1] = '\0';
208      i++;
209    }
210#ifdef DEBUG
211  fprintf (stderr, "READING STRING S %s\n", lpszBuf);
212#endif
213  return (char *) lpszBuf;
214}
215
216void
217unhandleStatus (maps * conf)
218{
219  BOOL fIgnore;
220  fIgnore = UnmapViewOfFile (lpvMemG);
221  fIgnore = CloseHandle (hMapObjectG);
222}
223#else
224
225void
226unhandleStatus (maps * conf)
227{
228  int shmid;
229  key_t key;
230  void *shm;
231  struct shmid_ds shmids;
232  map *tmpMap = getMapFromMaps (conf, "lenv", "sid");
233  if (tmpMap != NULL)
234    {
235      key = atoi (tmpMap->value);
236      if ((shmid = shmget (key, SHMSZ, IPC_CREAT | 0666)) < 0)
237        {
238#ifdef DEBUG
239          fprintf (stderr, "shmget failed to update value\n");
240#endif
241        }
242      else
243        {
244          if ((shm = shmat (shmid, NULL, 0)) == (char *) -1)
245            {
246#ifdef DEBUG
247              fprintf (stderr, "shmat failed to update value\n");
248#endif
249            }
250          else
251            {
252              shmdt (shm);
253              shmctl (shmid, IPC_RMID, &shmids);
254            }
255        }
256    }
257}
258
259int
260_updateStatus (maps * conf)
261{
262  int shmid;
263  key_t key;
264  char *shm, *s, *s1;
265  map *tmpMap = NULL;
266  tmpMap = getMapFromMaps (conf, "lenv", "sid");
267  if (tmpMap != NULL)
268    {
269      key = atoi (tmpMap->value);
270      if ((shmid = shmget (key, SHMSZ, IPC_CREAT | 0666)) < 0)
271        {
272#ifdef DEBUG
273          fprintf (stderr,
274                   "shmget failed to create new Shared memory segment\n");
275#endif
276          return -2;
277        }
278      else
279        {
280          if ((shm = (char *) shmat (shmid, NULL, 0)) == (char *) -1)
281            {
282#ifdef DEBUG
283              fprintf (stderr, "shmat failed to update value\n");
284#endif
285              return -1;
286            }
287          else
288            {
289              tmpMap = getMapFromMaps (conf, "lenv", "status");
290              s1 = shm;
291              for (s = tmpMap->value; *s != NULL && *s != 0; s++)
292                {
293                  *s1++ = *s;
294                }
295              *s1++ = '|';
296              tmpMap = getMapFromMaps (conf, "lenv", "message");
297              if (tmpMap != NULL)
298                for (s = tmpMap->value; *s != NULL && *s != 0; s++)
299                  {
300                    *s1++ = *s;
301                  }
302              *s1 = NULL;
303              shmdt ((void *) shm);
304            }
305        }
306    }
307  return 0;
308}
309
310char *
311getStatus (int pid)
312{
313  int shmid;
314  key_t key;
315  void *shm;
316  key = pid;
317  if ((shmid = shmget (key, SHMSZ, 0666)) < 0)
318    {
319#ifdef DEBUG
320      fprintf (stderr, "shmget failed in getStatus\n");
321#endif
322    }
323  else
324    {
325      if ((shm = shmat (shmid, NULL, 0)) == (char *) -1)
326        {
327#ifdef DEBUG
328          fprintf (stderr, "shmat failed in getStatus\n");
329#endif
330        }
331      else
332        {
333          return (char *) shm;
334        }
335    }
336  return (char *) "-1";
337}
338
339#endif
340
341#ifdef USE_JS
342
343JSBool
344JSUpdateStatus (JSContext * cx, uintN argc, jsval * argv1)
345{
346  jsval *argv = JS_ARGV (cx, argv1);
347  JS_MaybeGC (cx);
348  int istatus = 0;
349  char *status = NULL;
350  maps *conf;
351  if (argc > 2)
352    {
353#ifdef JS_DEBUG
354      fprintf (stderr, "Number of arguments used to call the function : %i",
355               argc);
356#endif
357      return JS_FALSE;
358    }
359  conf = mapsFromJSObject (cx, argv[0]);
360  if (JS_ValueToInt32 (cx, argv[1], &istatus) == JS_TRUE)
361    {
362      char tmpStatus[4];
363      sprintf (tmpStatus, "%i", istatus);
364      tmpStatus[3] = 0;
365      status = strdup (tmpStatus);
366    }
367  if (getMapFromMaps (conf, "lenv", "status") != NULL)
368    {
369      if (status != NULL)
370        {
371          setMapInMaps (conf, "lenv", "status", status);
372          free (status);
373        }
374      else
375        setMapInMaps (conf, "lenv", "status", "15");
376      _updateStatus (conf);
377    }
378  freeMaps (&conf);
379  free (conf);
380  JS_MaybeGC (cx);
381  return JS_TRUE;
382}
383
384#endif
385
386
387
388/* Returns a url-encoded version of str */
389/* IMPORTANT: be sure to free() the returned string after use */
390char *
391url_encode (char *str)
392{
393  char *pstr = str, *buf = (char *) malloc (strlen (str) * 3 + 1), *pbuf =
394    buf;
395  while (*pstr)
396    {
397      if (isalnum (*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.'
398          || *pstr == '~')
399        *pbuf++ = *pstr;
400      else if (*pstr == ' ')
401        *pbuf++ = '+';
402      else
403        *pbuf++ = '%', *pbuf++ = to_hex (*pstr >> 4), *pbuf++ =
404          to_hex (*pstr & 15);
405      pstr++;
406    }
407  *pbuf = '\0';
408  return buf;
409}
410
411/* Returns a url-decoded version of str */
412/* IMPORTANT: be sure to free() the returned string after use */
413char *
414url_decode (char *str)
415{
416  char *pstr = str, *buf = (char *) malloc (strlen (str) + 1), *pbuf = buf;
417  while (*pstr)
418    {
419      if (*pstr == '%')
420        {
421          if (pstr[1] && pstr[2])
422            {
423              *pbuf++ = from_hex (pstr[1]) << 4 | from_hex (pstr[2]);
424              pstr += 2;
425            }
426        }
427      else if (*pstr == '+')
428        {
429          *pbuf++ = ' ';
430        }
431      else
432        {
433          *pbuf++ = *pstr;
434        }
435      pstr++;
436    }
437  *pbuf = '\0';
438  return buf;
439}
440
441char *
442zCapitalize1 (char *tmp)
443{
444  char *res = strdup (tmp);
445  if (res[0] >= 97 && res[0] <= 122)
446    res[0] -= 32;
447  return res;
448}
449
450char *
451zCapitalize (char *tmp)
452{
453  int i = 0;
454  char *res = strdup (tmp);
455  for (i = 0; i < strlen (res); i++)
456    if (res[i] >= 97 && res[i] <= 122)
457      res[i] -= 32;
458  return res;
459}
460
461
462int
463zooXmlSearchForNs (const char *name)
464{
465  int i;
466  int res = -1;
467  for (i = 0; i < nbNs; i++)
468    if (strncasecmp (name, nsName[i], strlen (nsName[i])) == 0)
469      {
470        res = i;
471        break;
472      }
473  return res;
474}
475
476int
477zooXmlAddNs (xmlNodePtr nr, const char *url, const char *name)
478{
479#ifdef DEBUG
480  fprintf (stderr, "zooXmlAddNs %d %s \n", nbNs, name);
481#endif
482  int currId = -1;
483  if (nbNs == 0)
484    {
485      nbNs++;
486      currId = 0;
487      nsName[currId] = strdup (name);
488      usedNs[currId] = xmlNewNs (nr, BAD_CAST url, BAD_CAST name);
489    }
490  else
491    {
492      currId = zooXmlSearchForNs (name);
493      if (currId < 0)
494        {
495          nbNs++;
496          currId = nbNs - 1;
497          nsName[currId] = strdup (name);
498          usedNs[currId] = xmlNewNs (nr, BAD_CAST url, BAD_CAST name);
499        }
500    }
501  return currId;
502}
503
504void
505zooXmlCleanupNs ()
506{
507  int j;
508#ifdef DEBUG
509  fprintf (stderr, "zooXmlCleanup %d\n", nbNs);
510#endif
511  for (j = nbNs - 1; j >= 0; j--)
512    {
513#ifdef DEBUG
514      fprintf (stderr, "zooXmlCleanup %d\n", j);
515#endif
516      if (j == 0)
517        xmlFreeNs (usedNs[j]);
518      free (nsName[j]);
519      nbNs--;
520    }
521  nbNs = 0;
522}
523
524
525int
526zooXmlAddDoc (const char *value)
527{
528  int currId = 0;
529  nbDocs++;
530  currId = nbDocs - 1;
531  iDocs[currId] = xmlParseMemory (value, strlen (value));
532  return currId;
533}
534
535void
536zooXmlCleanupDocs ()
537{
538  int j;
539  for (j = nbDocs - 1; j >= 0; j--)
540    {
541      xmlFreeDoc (iDocs[j]);
542    }
543  nbDocs = 0;
544}
545
546
547xmlNodePtr
548soapEnvelope (maps * conf, xmlNodePtr n)
549{
550  map *soap = getMapFromMaps (conf, "main", "isSoap");
551  if (soap != NULL && strcasecmp (soap->value, "true") == 0)
552    {
553      int lNbNs = nbNs;
554      nsName[lNbNs] = strdup ("soap");
555      usedNs[lNbNs] =
556        xmlNewNs (NULL, BAD_CAST "http://www.w3.org/2003/05/soap-envelope",
557                  BAD_CAST "soap");
558      nbNs++;
559      xmlNodePtr nr = xmlNewNode (usedNs[lNbNs], BAD_CAST "Envelope");
560      nsName[nbNs] = strdup ("soap");
561      usedNs[nbNs] =
562        xmlNewNs (nr, BAD_CAST "http://www.w3.org/2003/05/soap-envelope",
563                  BAD_CAST "soap");
564      nbNs++;
565      nsName[nbNs] = strdup ("xsi");
566      usedNs[nbNs] =
567        xmlNewNs (nr, BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",
568                  BAD_CAST "xsi");
569      nbNs++;
570      xmlNsPtr ns_xsi = usedNs[nbNs - 1];
571      xmlNewNsProp (nr, ns_xsi, BAD_CAST "schemaLocation",
572                    BAD_CAST
573                    "http://www.w3.org/2003/05/soap-envelope http://www.w3.org/2003/05/soap-envelope");
574      xmlNodePtr nr1 = xmlNewNode (usedNs[lNbNs], BAD_CAST "Body");
575      xmlAddChild (nr1, n);
576      xmlAddChild (nr, nr1);
577      return nr;
578    }
579  else
580    return n;
581}
582
583xmlNodePtr
584printGetCapabilitiesHeader (xmlDocPtr doc, const char *service, maps * m)
585{
586
587  xmlNsPtr ns, ns_ows, ns_xlink, ns_xsi;
588  xmlNodePtr n, nc, nc1, nc2, nc3, nc4, nc5, nc6;
589  /**
590   * Create the document and its temporary root.
591   */
592  int wpsId = zooXmlAddNs (NULL, "http://www.opengis.net/wps/1.0.0", "wps");
593  ns = usedNs[wpsId];
594  maps *toto1 = getMaps (m, "main");
595
596  n = xmlNewNode (ns, BAD_CAST "Capabilities");
597  int owsId = zooXmlAddNs (n, "http://www.opengis.net/ows/1.1", "ows");
598  ns_ows = usedNs[owsId];
599  xmlNewNs (n, BAD_CAST "http://www.opengis.net/wps/1.0.0", BAD_CAST "wps");
600  int xsiId =
601    zooXmlAddNs (n, "http://www.w3.org/2001/XMLSchema-instance", "xsi");
602  ns_xsi = usedNs[xsiId];
603  int xlinkId = zooXmlAddNs (n, "http://www.w3.org/1999/xlink", "xlink");
604  ns_xlink = usedNs[xlinkId];
605  xmlNewNsProp (n, ns_xsi, BAD_CAST "schemaLocation",
606                BAD_CAST
607                "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsGetCapabilities_response.xsd");
608  xmlNewProp (n, BAD_CAST "service", BAD_CAST "WPS");
609  addLangAttr (n, m);
610
611  if (toto1 != NULL)
612    {
613      map *tmp = getMap (toto1->content, "version");
614      if (tmp != NULL)
615        {
616          xmlNewProp (n, BAD_CAST "version", BAD_CAST tmp->value);
617        }
618      else
619        xmlNewProp (n, BAD_CAST "version", BAD_CAST "1.0.0");
620    }
621  else
622    xmlNewProp (n, BAD_CAST "version", BAD_CAST "1.0.0");
623
624  char tmp[256];
625
626  nc = xmlNewNode (ns_ows, BAD_CAST "ServiceIdentification");
627  maps *tmp4 = getMaps (m, "identification");
628  if (tmp4 != NULL)
629    {
630      map *tmp2 = tmp4->content;
631      const char *orderedFields[5];
632      orderedFields[0] = "Title";
633      orderedFields[1] = "Abstract";
634      orderedFields[2] = "Keywords";
635      orderedFields[3] = "Fees";
636      orderedFields[4] = "AccessConstraints";
637      int oI = 0;
638      for (oI = 0; oI < 5; oI++)
639        if ((tmp2 = getMap (tmp4->content, orderedFields[oI])) != NULL)
640          {
641            if (strcasecmp (tmp2->name, "abstract") == 0 ||
642                strcasecmp (tmp2->name, "title") == 0 ||
643                strcasecmp (tmp2->name, "accessConstraints") == 0 ||
644                strcasecmp (tmp2->name, "fees") == 0)
645              {
646                tmp2->name[0] = toupper (tmp2->name[0]);
647                nc1 = xmlNewNode (ns_ows, BAD_CAST tmp2->name);
648                xmlAddChild (nc1, xmlNewText (BAD_CAST tmp2->value));
649                xmlAddChild (nc, nc1);
650              }
651            else if (strcmp (tmp2->name, "keywords") == 0)
652              {
653                nc1 = xmlNewNode (ns_ows, BAD_CAST "Keywords");
654                char *toto = tmp2->value;
655                char buff[256];
656                int i = 0;
657                int j = 0;
658                while (toto[i])
659                  {
660                    if (toto[i] != ',' && toto[i] != 0)
661                      {
662                        buff[j] = toto[i];
663                        buff[j + 1] = 0;
664                        j++;
665                      }
666                    else
667                      {
668                        nc2 = xmlNewNode (ns_ows, BAD_CAST "Keyword");
669                        xmlAddChild (nc2, xmlNewText (BAD_CAST buff));
670                        xmlAddChild (nc1, nc2);
671                        j = 0;
672                      }
673                    i++;
674                  }
675                if (strlen (buff) > 0)
676                  {
677                    nc2 = xmlNewNode (ns_ows, BAD_CAST "Keyword");
678                    xmlAddChild (nc2, xmlNewText (BAD_CAST buff));
679                    xmlAddChild (nc1, nc2);
680                  }
681                xmlAddChild (nc, nc1);
682                nc2 = xmlNewNode (ns_ows, BAD_CAST "ServiceType");
683                xmlAddChild (nc2, xmlNewText (BAD_CAST "WPS"));
684                xmlAddChild (nc, nc2);
685                nc2 = xmlNewNode (ns_ows, BAD_CAST "ServiceTypeVersion");
686                xmlAddChild (nc2, xmlNewText (BAD_CAST "1.0.0"));
687                xmlAddChild (nc, nc2);
688              }
689            tmp2 = tmp2->next;
690          }
691    }
692  else
693    {
694      fprintf (stderr, "TMP4 NOT FOUND !!");
695      return NULL;
696    }
697  xmlAddChild (n, nc);
698
699  nc = xmlNewNode (ns_ows, BAD_CAST "ServiceProvider");
700  nc3 = xmlNewNode (ns_ows, BAD_CAST "ServiceContact");
701  nc4 = xmlNewNode (ns_ows, BAD_CAST "ContactInfo");
702  nc5 = xmlNewNode (ns_ows, BAD_CAST "Phone");
703  nc6 = xmlNewNode (ns_ows, BAD_CAST "Address");
704  tmp4 = getMaps (m, "provider");
705  if (tmp4 != NULL)
706    {
707      map *tmp2 = tmp4->content;
708      const char *tmpAddress[6];
709      tmpAddress[0] = "addressDeliveryPoint";
710      tmpAddress[1] = "addressCity";
711      tmpAddress[2] = "addressAdministrativeArea";
712      tmpAddress[3] = "addressPostalCode";
713      tmpAddress[4] = "addressCountry";
714      tmpAddress[5] = "addressElectronicMailAddress";
715      const char *tmpPhone[2];
716      tmpPhone[0] = "phoneVoice";
717      tmpPhone[1] = "phoneFacsimile";
718      const char *orderedFields[12];
719      orderedFields[0] = "providerName";
720      orderedFields[1] = "providerSite";
721      orderedFields[2] = "individualName";
722      orderedFields[3] = "positionName";
723      orderedFields[4] = tmpPhone[0];
724      orderedFields[5] = tmpPhone[1];
725      orderedFields[6] = tmpAddress[0];
726      orderedFields[7] = tmpAddress[1];
727      orderedFields[8] = tmpAddress[2];
728      orderedFields[9] = tmpAddress[3];
729      orderedFields[10] = tmpAddress[4];
730      orderedFields[11] = tmpAddress[5];
731      int oI = 0;
732      for (oI = 0; oI < 12; oI++)
733        if ((tmp2 = getMap (tmp4->content, orderedFields[oI])) != NULL)
734          {
735            if (strcmp (tmp2->name, "keywords") != 0 &&
736                strcmp (tmp2->name, "serverAddress") != 0 &&
737                strcmp (tmp2->name, "lang") != 0)
738              {
739                tmp2->name[0] = toupper (tmp2->name[0]);
740                if (strcmp (tmp2->name, "ProviderName") == 0)
741                  {
742                    nc1 = xmlNewNode (ns_ows, BAD_CAST tmp2->name);
743                    xmlAddChild (nc1, xmlNewText (BAD_CAST tmp2->value));
744                    xmlAddChild (nc, nc1);
745                  }
746                else
747                  {
748                    if (strcmp (tmp2->name, "ProviderSite") == 0)
749                      {
750                        nc1 = xmlNewNode (ns_ows, BAD_CAST tmp2->name);
751                        xmlNewNsProp (nc1, ns_xlink, BAD_CAST "href",
752                                      BAD_CAST tmp2->value);
753                        xmlAddChild (nc, nc1);
754                      }
755                    else
756                      if (strcmp (tmp2->name, "IndividualName") == 0 ||
757                          strcmp (tmp2->name, "PositionName") == 0)
758                      {
759                        nc1 = xmlNewNode (ns_ows, BAD_CAST tmp2->name);
760                        xmlAddChild (nc1, xmlNewText (BAD_CAST tmp2->value));
761                        xmlAddChild (nc3, nc1);
762                      }
763                    else if (strncmp (tmp2->name, "Phone", 5) == 0)
764                      {
765                        int j;
766                        for (j = 0; j < 2; j++)
767                          if (strcasecmp (tmp2->name, tmpPhone[j]) == 0)
768                            {
769                              char *tmp4 = tmp2->name;
770                              nc1 = xmlNewNode (ns_ows, BAD_CAST tmp4 + 5);
771                              xmlAddChild (nc1,
772                                           xmlNewText (BAD_CAST tmp2->value));
773                              xmlAddChild (nc5, nc1);
774                            }
775                      }
776                    else if (strncmp (tmp2->name, "Address", 7) == 0)
777                      {
778                        int j;
779                        for (j = 0; j < 6; j++)
780                          if (strcasecmp (tmp2->name, tmpAddress[j]) == 0)
781                            {
782                              char *tmp4 = tmp2->name;
783                              nc1 = xmlNewNode (ns_ows, BAD_CAST tmp4 + 7);
784                              xmlAddChild (nc1,
785                                           xmlNewText (BAD_CAST tmp2->value));
786                              xmlAddChild (nc6, nc1);
787                            }
788                      }
789                  }
790              }
791            else if (strcmp (tmp2->name, "keywords") == 0)
792              {
793                nc1 = xmlNewNode (ns_ows, BAD_CAST "Keywords");
794                char *toto = tmp2->value;
795                char buff[256];
796                int i = 0;
797                int j = 0;
798                while (toto[i])
799                  {
800                    if (toto[i] != ',' && toto[i] != 0)
801                      {
802                        buff[j] = toto[i];
803                        buff[j + 1] = 0;
804                        j++;
805                      }
806                    else
807                      {
808                        nc2 = xmlNewNode (ns_ows, BAD_CAST "Keyword");
809                        xmlAddChild (nc2, xmlNewText (BAD_CAST buff));
810                        xmlAddChild (nc1, nc2);
811                        j = 0;
812                      }
813                    i++;
814                  }
815                if (strlen (buff) > 0)
816                  {
817                    nc2 = xmlNewNode (ns_ows, BAD_CAST "Keyword");
818                    xmlAddChild (nc2, xmlNewText (BAD_CAST buff));
819                    xmlAddChild (nc1, nc2);
820                  }
821                xmlAddChild (nc, nc1);
822              }
823            tmp2 = tmp2->next;
824          }
825    }
826  else
827    {
828      fprintf (stderr, "TMP4 NOT FOUND !!");
829    }
830  xmlAddChild (nc4, nc5);
831  xmlAddChild (nc4, nc6);
832  xmlAddChild (nc3, nc4);
833  xmlAddChild (nc, nc3);
834  xmlAddChild (n, nc);
835
836
837  nc = xmlNewNode (ns_ows, BAD_CAST "OperationsMetadata");
838  char *tmp2[3];
839  tmp2[0] = strdup ("GetCapabilities");
840  tmp2[1] = strdup ("DescribeProcess");
841  tmp2[2] = strdup ("Execute");
842  int j = 0;
843
844  if (toto1 != NULL)
845    {
846      map *tmp = getMap (toto1->content, "serverAddress");
847      if (tmp != NULL)
848        {
849          SERVICE_URL = strdup (tmp->value);
850        }
851      else
852        SERVICE_URL = strdup ("not_found");
853    }
854  else
855    SERVICE_URL = strdup ("not_found");
856
857  for (j = 0; j < 3; j++)
858    {
859      nc1 = xmlNewNode (ns_ows, BAD_CAST "Operation");
860      xmlNewProp (nc1, BAD_CAST "name", BAD_CAST tmp2[j]);
861      nc2 = xmlNewNode (ns_ows, BAD_CAST "DCP");
862      nc3 = xmlNewNode (ns_ows, BAD_CAST "HTTP");
863      nc4 = xmlNewNode (ns_ows, BAD_CAST "Get");
864      sprintf (tmp, "%s/%s", SERVICE_URL, service);
865      xmlNewNsProp (nc4, ns_xlink, BAD_CAST "href", BAD_CAST tmp);
866      xmlAddChild (nc3, nc4);
867      if (j > 0)
868        {
869          nc4 = xmlNewNode (ns_ows, BAD_CAST "Post");
870          xmlNewNsProp (nc4, ns_xlink, BAD_CAST "href", BAD_CAST tmp);
871          xmlAddChild (nc3, nc4);
872        }
873      xmlAddChild (nc2, nc3);
874      xmlAddChild (nc1, nc2);
875      xmlAddChild (nc, nc1);
876    }
877  for (j = 2; j >= 0; j--)
878    free (tmp2[j]);
879  xmlAddChild (n, nc);
880
881  nc = xmlNewNode (ns, BAD_CAST "ProcessOfferings");
882  xmlAddChild (n, nc);
883
884  nc1 = xmlNewNode (ns, BAD_CAST "Languages");
885  nc2 = xmlNewNode (ns, BAD_CAST "Default");
886  nc3 = xmlNewNode (ns, BAD_CAST "Supported");
887
888  toto1 = getMaps (m, "main");
889  if (toto1 != NULL)
890    {
891      map *tmp1 = getMap (toto1->content, "lang");
892      char *toto = tmp1->value;
893      char buff[256];
894      int i = 0;
895      int j = 0;
896      int dcount = 0;
897      while (toto[i])
898        {
899          if (toto[i] != ',' && toto[i] != 0)
900            {
901              buff[j] = toto[i];
902              buff[j + 1] = 0;
903              j++;
904            }
905          else
906            {
907              nc4 = xmlNewNode (ns_ows, BAD_CAST "Language");
908              xmlAddChild (nc4, xmlNewText (BAD_CAST buff));
909              if (dcount == 0)
910                {
911                  xmlAddChild (nc2, nc4);
912                  xmlAddChild (nc1, nc2);
913                  dcount++;
914                }
915              nc4 = xmlNewNode (ns_ows, BAD_CAST "Language");
916              xmlAddChild (nc4, xmlNewText (BAD_CAST buff));
917              xmlAddChild (nc3, nc4);
918              j = 0;
919              buff[j] = 0;
920            }
921          i++;
922        }
923      if (strlen (buff) > 0)
924        {
925          nc4 = xmlNewNode (ns_ows, BAD_CAST "Language");
926          xmlAddChild (nc4, xmlNewText (BAD_CAST buff));
927          xmlAddChild (nc3, nc4);
928        }
929    }
930  xmlAddChild (nc1, nc3);
931  xmlAddChild (n, nc1);
932
933  xmlNodePtr fn = soapEnvelope (m, n);
934  xmlDocSetRootElement (doc, fn);
935  //xmlFreeNs(ns);
936  free (SERVICE_URL);
937  return nc;
938}
939
940void
941addPrefix (maps * conf, map * level, service * serv)
942{
943  if (level != NULL)
944    {
945      char key[25];
946      char *prefix = NULL;
947      int clevel = atoi (level->value);
948      int cl = 0;
949      for (cl = 0; cl < clevel; cl++)
950        {
951          sprintf (key, "sprefix_%d", cl);
952          map *tmp2 = getMapFromMaps (conf, "lenv", key);
953          if (tmp2 != NULL)
954            {
955              if (prefix == NULL)
956                prefix = zStrdup (tmp2->value);
957              else
958                {
959                  int plen = strlen (prefix);
960                  prefix =
961                    (char *) realloc (prefix,
962                                      (plen + strlen (tmp2->value) +
963                                       2) * sizeof (char));
964                  memcpy (prefix + plen, tmp2->value,
965                          strlen (tmp2->value) * sizeof (char));
966                  prefix[plen + strlen (tmp2->value)] = 0;
967                }
968            }
969        }
970      if (prefix != NULL)
971        {
972          char *tmp0 = strdup (serv->name);
973          free (serv->name);
974          serv->name =
975            (char *) malloc ((strlen (prefix) + strlen (tmp0) + 1) *
976                             sizeof (char));
977          sprintf (serv->name, "%s%s", prefix, tmp0);
978          free (tmp0);
979          free (prefix);
980          prefix = NULL;
981        }
982    }
983}
984
985void
986printGetCapabilitiesForProcess (maps * m, xmlNodePtr nc, service * serv)
987{
988  xmlNsPtr ns, ns_ows, ns_xlink;
989  xmlNodePtr n = NULL, nc1, nc2;
990  /**
991   * Initialize or get existing namspaces
992   */
993  int wpsId = zooXmlAddNs (NULL, "http://www.opengis.net/wps/1.0.0", "wps");
994  ns = usedNs[wpsId];
995  int owsId = zooXmlAddNs (NULL, "http://www.opengis.net/ows/1.1", "ows");
996  ns_ows = usedNs[owsId];
997  int xlinkId = zooXmlAddNs (n, "http://www.w3.org/1999/xlink", "xlink");
998  ns_xlink = usedNs[xlinkId];
999
1000  map *tmp1;
1001  if (serv->content != NULL)
1002    {
1003      nc1 = xmlNewNode (ns, BAD_CAST "Process");
1004      tmp1 = getMap (serv->content, "processVersion");
1005      if (tmp1 != NULL)
1006        xmlNewNsProp (nc1, ns, BAD_CAST "processVersion",
1007                      BAD_CAST tmp1->value);
1008      map *tmp3 = getMapFromMaps (m, "lenv", "level");
1009      addPrefix (m, tmp3, serv);
1010      printDescription (nc1, ns_ows, serv->name, serv->content);
1011      tmp1 = serv->metadata;
1012      while (tmp1 != NULL)
1013        {
1014          nc2 = xmlNewNode (ns_ows, BAD_CAST "Metadata");
1015          xmlNewNsProp (nc2, ns_xlink, BAD_CAST tmp1->name,
1016                        BAD_CAST tmp1->value);
1017          xmlAddChild (nc1, nc2);
1018          tmp1 = tmp1->next;
1019        }
1020      xmlAddChild (nc, nc1);
1021    }
1022}
1023
1024xmlNodePtr
1025printDescribeProcessHeader (xmlDocPtr doc, const char *service, maps * m)
1026{
1027
1028  xmlNsPtr ns, ns_xsi;
1029  xmlNodePtr n;
1030
1031  int wpsId =
1032    zooXmlAddNs (NULL, "http://schemas.opengis.net/wps/1.0.0", "wps");
1033  ns = usedNs[wpsId];
1034  n = xmlNewNode (ns, BAD_CAST "ProcessDescriptions");
1035  zooXmlAddNs (n, "http://www.opengis.net/ows/1.1", "ows");
1036  xmlNewNs (n, BAD_CAST "http://www.opengis.net/wps/1.0.0", BAD_CAST "wps");
1037  zooXmlAddNs (n, "http://www.w3.org/1999/xlink", "xlink");
1038  int xsiId =
1039    zooXmlAddNs (n, "http://www.w3.org/2001/XMLSchema-instance", "xsi");
1040  ns_xsi = usedNs[xsiId];
1041
1042  xmlNewNsProp (n, ns_xsi, BAD_CAST "schemaLocation",
1043                BAD_CAST
1044                "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd");
1045  xmlNewProp (n, BAD_CAST "service", BAD_CAST "WPS");
1046  xmlNewProp (n, BAD_CAST "version", BAD_CAST "1.0.0");
1047  addLangAttr (n, m);
1048
1049  xmlNodePtr fn = soapEnvelope (m, n);
1050  xmlDocSetRootElement (doc, fn);
1051
1052  return n;
1053}
1054
1055void
1056printDescribeProcessForProcess (maps * m, xmlNodePtr nc, service * serv)
1057{
1058  xmlNsPtr ns, ns_ows, ns_xlink;
1059  xmlNodePtr n, nc1;
1060
1061  n = nc;
1062
1063  int wpsId =
1064    zooXmlAddNs (NULL, "http://schemas.opengis.net/wps/1.0.0", "wps");
1065  ns = usedNs[wpsId];
1066  int owsId = zooXmlAddNs (NULL, "http://www.opengis.net/ows/1.1", "ows");
1067  ns_ows = usedNs[owsId];
1068  int xlinkId = zooXmlAddNs (NULL, "http://www.w3.org/1999/xlink", "xlink");
1069  ns_xlink = usedNs[xlinkId];
1070
1071  nc = xmlNewNode (NULL, BAD_CAST "ProcessDescription");
1072  const char *tmp4[3];
1073  tmp4[0] = "processVersion";
1074  tmp4[1] = "storeSupported";
1075  tmp4[2] = "statusSupported";
1076  int j = 0;
1077  map *tmp1 = NULL;
1078  for (j = 0; j < 3; j++)
1079    {
1080      tmp1 = getMap (serv->content, tmp4[j]);
1081      if (tmp1 != NULL)
1082        {
1083          if (j == 0)
1084            xmlNewNsProp (nc, ns, BAD_CAST "processVersion",
1085                          BAD_CAST tmp1->value);
1086          else
1087            xmlNewProp (nc, BAD_CAST tmp4[j], BAD_CAST tmp1->value);
1088        }
1089      else
1090        {
1091          if (j > 0)
1092            xmlNewProp (nc, BAD_CAST tmp4[j], BAD_CAST "false");
1093        }
1094    }
1095
1096  tmp1 = getMapFromMaps (m, "lenv", "level");
1097  addPrefix (m, tmp1, serv);
1098  printDescription (nc, ns_ows, serv->identifier, serv->content);
1099
1100  tmp1 = serv->metadata;
1101  while (tmp1 != NULL)
1102    {
1103      nc1 = xmlNewNode (ns_ows, BAD_CAST "Metadata");
1104      xmlNewNsProp (nc1, ns_xlink, BAD_CAST tmp1->name, BAD_CAST tmp1->value);
1105      xmlAddChild (nc, nc1);
1106      tmp1 = tmp1->next;
1107    }
1108
1109  tmp1 = getMap (serv->content, "Profile");
1110  if (tmp1 != NULL)
1111    {
1112      nc1 = xmlNewNode (ns, BAD_CAST "Profile");
1113      xmlAddChild (nc1, xmlNewText (BAD_CAST tmp1->value));
1114      xmlAddChild (nc, nc1);
1115    }
1116
1117  if (serv->inputs != NULL)
1118    {
1119      nc1 = xmlNewNode (NULL, BAD_CAST "DataInputs");
1120      elements *e = serv->inputs;
1121      printFullDescription (1, e, "Input", ns_ows, nc1);
1122      xmlAddChild (nc, nc1);
1123    }
1124
1125  nc1 = xmlNewNode (NULL, BAD_CAST "ProcessOutputs");
1126  elements *e = serv->outputs;
1127  printFullDescription (0, e, "Output", ns_ows, nc1);
1128  xmlAddChild (nc, nc1);
1129
1130  xmlAddChild (n, nc);
1131
1132}
1133
1134void
1135printFullDescription (int in, elements * elem, const char *type,
1136                      xmlNsPtr ns_ows, xmlNodePtr nc1)
1137{
1138  const char *orderedFields[13];
1139  orderedFields[0] = "mimeType";
1140  orderedFields[1] = "encoding";
1141  orderedFields[2] = "schema";
1142  orderedFields[3] = "dataType";
1143  orderedFields[4] = "uom";
1144  orderedFields[5] = "CRS";
1145  orderedFields[6] = "value";
1146  orderedFields[7] = "AllowedValues";
1147  orderedFields[8] = "range";
1148  orderedFields[9] = "rangeMin";
1149  orderedFields[10] = "rangeMax";
1150  orderedFields[11] = "rangeClosure";
1151  orderedFields[12] = "rangeSpace";
1152
1153  xmlNodePtr nc2, nc3, nc4, nc5, nc6, nc7, nc8, nc9;
1154  elements *e = elem;
1155
1156  map *tmp1 = NULL;
1157  while (e != NULL)
1158    {
1159      int default1 = 0;
1160      int isAnyValue = 1;
1161      nc2 = xmlNewNode (NULL, BAD_CAST type);
1162      if (strncmp (type, "Input", 5) == 0)
1163        {
1164          tmp1 = getMap (e->content, "minOccurs");
1165          if (tmp1 != NULL)
1166            {
1167              xmlNewProp (nc2, BAD_CAST tmp1->name, BAD_CAST tmp1->value);
1168            }
1169          else
1170            xmlNewProp (nc2, BAD_CAST "minOccurs", BAD_CAST "0");
1171          tmp1 = getMap (e->content, "maxOccurs");
1172          if (tmp1 != NULL)
1173            {
1174              if (strcasecmp (tmp1->value, "unbounded") != 0)
1175                xmlNewProp (nc2, BAD_CAST tmp1->name, BAD_CAST tmp1->value);
1176              else
1177                xmlNewProp (nc2, BAD_CAST "maxOccurs", BAD_CAST "1000");
1178            }
1179          else
1180            xmlNewProp (nc2, BAD_CAST "maxOccurs", BAD_CAST "1");
1181          if ((tmp1 = getMap (e->content, "maximumMegabytes")) != NULL)
1182            {
1183              xmlNewProp (nc2, BAD_CAST "maximumMegabytes",
1184                          BAD_CAST tmp1->value);
1185            }
1186        }
1187
1188      printDescription (nc2, ns_ows, e->name, e->content);
1189
1190    /**
1191     * Build the (Literal/Complex/BoundingBox)Data node
1192     */
1193      if (strncmp (type, "Output", 6) == 0)
1194        {
1195          if (strncasecmp (e->format, "LITERALDATA", strlen (e->format)) == 0)
1196            nc3 = xmlNewNode (NULL, BAD_CAST "LiteralOutput");
1197          else if (strncasecmp (e->format, "COMPLEXDATA", strlen (e->format))
1198                   == 0)
1199            nc3 = xmlNewNode (NULL, BAD_CAST "ComplexOutput");
1200          else
1201            if (strncasecmp (e->format, "BOUNDINGBOXDATA", strlen (e->format))
1202                == 0)
1203            nc3 = xmlNewNode (NULL, BAD_CAST "BoundingBoxOutput");
1204          else
1205            nc3 = xmlNewNode (NULL, BAD_CAST e->format);
1206        }
1207      else
1208        {
1209          if (strncasecmp (e->format, "LITERALDATA", strlen (e->format)) == 0)
1210            {
1211              nc3 = xmlNewNode (NULL, BAD_CAST "LiteralData");
1212            }
1213          else if (strncasecmp (e->format, "COMPLEXDATA", strlen (e->format))
1214                   == 0)
1215            nc3 = xmlNewNode (NULL, BAD_CAST "ComplexData");
1216          else
1217            if (strncasecmp (e->format, "BOUNDINGBOXDATA", strlen (e->format))
1218                == 0)
1219            nc3 = xmlNewNode (NULL, BAD_CAST "BoundingBoxData");
1220          else
1221            nc3 = xmlNewNode (NULL, BAD_CAST e->format);
1222        }
1223
1224      iotype *_tmp0 = NULL;
1225      iotype *_tmp = e->defaults;
1226      int datatype = 0;
1227      bool hasUOM = false;
1228      bool hasUOM1 = false;
1229      if (_tmp != NULL)
1230        {
1231          if (strcmp (e->format, "LiteralOutput") == 0 ||
1232              strcmp (e->format, "LiteralData") == 0)
1233            {
1234              datatype = 1;
1235              nc4 = xmlNewNode (NULL, BAD_CAST "UOMs");
1236              nc5 = xmlNewNode (NULL, BAD_CAST "Default");
1237            }
1238          else if (strcmp (e->format, "BoundingBoxOutput") == 0 ||
1239                   strcmp (e->format, "BoundingBoxData") == 0)
1240            {
1241              datatype = 2;
1242              nc5 = xmlNewNode (NULL, BAD_CAST "Default");
1243            }
1244          else
1245            {
1246              nc4 = xmlNewNode (NULL, BAD_CAST "Default");
1247              nc5 = xmlNewNode (NULL, BAD_CAST "Format");
1248            }
1249
1250          tmp1 = _tmp->content;
1251
1252          if ((tmp1 = getMap (_tmp->content, "DataType")) != NULL)
1253            {
1254              nc8 = xmlNewNode (ns_ows, BAD_CAST "DataType");
1255              xmlAddChild (nc8, xmlNewText (BAD_CAST tmp1->value));
1256              char tmp[1024];
1257              sprintf (tmp, "http://www.w3.org/TR/xmlschema-2/#%s",
1258                       tmp1->value);
1259              xmlNewNsProp (nc8, ns_ows, BAD_CAST "reference", BAD_CAST tmp);
1260              xmlAddChild (nc3, nc8);
1261              datatype = 1;
1262            }
1263
1264          if (strncmp (type, "Input", 5) == 0)
1265            {
1266
1267              if ((tmp1 = getMap (_tmp->content, "AllowedValues")) != NULL)
1268                {
1269                  nc6 = xmlNewNode (ns_ows, BAD_CAST "AllowedValues");
1270                  char *token, *saveptr1;
1271                  token = strtok_r (tmp1->value, ",", &saveptr1);
1272                  while (token != NULL)
1273                    {
1274                      nc7 = xmlNewNode (ns_ows, BAD_CAST "Value");
1275                      char *tmps = strdup (token);
1276                      tmps[strlen (tmps)] = 0;
1277                      xmlAddChild (nc7, xmlNewText (BAD_CAST tmps));
1278                      free (tmps);
1279                      xmlAddChild (nc6, nc7);
1280                      token = strtok_r (NULL, ",", &saveptr1);
1281                    }
1282                  if (getMap (_tmp->content, "range") != NULL ||
1283                      getMap (_tmp->content, "rangeMin") != NULL ||
1284                      getMap (_tmp->content, "rangeMax") != NULL ||
1285                      getMap (_tmp->content, "rangeClosure") != NULL)
1286                    goto doRange;
1287                  xmlAddChild (nc3, nc6);
1288                  isAnyValue = -1;
1289                }
1290
1291              tmp1 = getMap (_tmp->content, "range");
1292              if (tmp1 == NULL)
1293                tmp1 = getMap (_tmp->content, "rangeMin");
1294              if (tmp1 == NULL)
1295                tmp1 = getMap (_tmp->content, "rangeMax");
1296
1297              if (tmp1 != NULL && isAnyValue == 1)
1298                {
1299                  nc6 = xmlNewNode (ns_ows, BAD_CAST "AllowedValues");
1300                doRange:
1301
1302          /**
1303           * Range: Table 46 OGC Web Services Common Standard
1304           */
1305                  nc8 = xmlNewNode (ns_ows, BAD_CAST "Range");
1306
1307                  map *tmp0 = getMap (tmp1, "range");
1308                  if (tmp0 != NULL)
1309                    {
1310                      char *pToken;
1311                      char *orig = zStrdup (tmp0->value);
1312            /**
1313             * RangeClosure: Table 47 OGC Web Services Common Standard
1314             */
1315                      const char *tmp = "closed";
1316                      if (orig[0] == '[' && orig[strlen (orig) - 1] == '[')
1317                        tmp = "closed-open";
1318                      else
1319                        if (orig[0] == ']' && orig[strlen (orig) - 1] == ']')
1320                        tmp = "open-closed";
1321                      else
1322                        if (orig[0] == ']' && orig[strlen (orig) - 1] == '[')
1323                        tmp = "open";
1324                      xmlNewNsProp (nc8, ns_ows, BAD_CAST "rangeClosure",
1325                                    BAD_CAST tmp);
1326                      pToken = strtok (orig, ",");
1327                      int nci0 = 0;
1328                      while (pToken != NULL)
1329                        {
1330                          char *tmpStr =
1331                            (char *) malloc ((strlen (pToken)) *
1332                                             sizeof (char));
1333                          if (nci0 == 0)
1334                            {
1335                              nc7 =
1336                                xmlNewNode (ns_ows, BAD_CAST "MinimumValue");
1337                              int nci = 1;
1338                              for (nci = 1; nci < strlen (pToken); nci++)
1339                                {
1340                                  tmpStr[nci - 1] = pToken[nci];
1341                                }
1342                            }
1343                          else
1344                            {
1345                              nc7 =
1346                                xmlNewNode (ns_ows, BAD_CAST "MaximumValue");
1347                              int nci = 0;
1348                              for (nci = 0; nci < strlen (pToken) - 1; nci++)
1349                                {
1350                                  tmpStr[nci] = pToken[nci];
1351                                }
1352                            }
1353                          xmlAddChild (nc7, xmlNewText (BAD_CAST tmpStr));
1354                          free (tmpStr);
1355                          xmlAddChild (nc8, nc7);
1356                          nci0++;
1357                          pToken = strtok (NULL, ",");
1358                        }
1359                      if (getMap (tmp1, "rangeSpacing") == NULL)
1360                        {
1361                          nc7 = xmlNewNode (ns_ows, BAD_CAST "Spacing");
1362                          xmlAddChild (nc7, xmlNewText (BAD_CAST "1"));
1363                          xmlAddChild (nc8, nc7);
1364                        }
1365                      free (orig);
1366                    }
1367                  else
1368                    {
1369
1370                      tmp0 = getMap (tmp1, "rangeMin");
1371                      if (tmp0 != NULL)
1372                        {
1373                          nc7 = xmlNewNode (ns_ows, BAD_CAST "MinimumValue");
1374                          xmlAddChild (nc7,
1375                                       xmlNewText (BAD_CAST tmp0->value));
1376                          xmlAddChild (nc8, nc7);
1377                        }
1378                      else
1379                        {
1380                          nc7 = xmlNewNode (ns_ows, BAD_CAST "MinimumValue");
1381                          xmlAddChild (nc8, nc7);
1382                        }
1383                      tmp0 = getMap (tmp1, "rangeMax");
1384                      if (tmp0 != NULL)
1385                        {
1386                          nc7 = xmlNewNode (ns_ows, BAD_CAST "MaximumValue");
1387                          xmlAddChild (nc7,
1388                                       xmlNewText (BAD_CAST tmp0->value));
1389                          xmlAddChild (nc8, nc7);
1390                        }
1391                      else
1392                        {
1393                          nc7 = xmlNewNode (ns_ows, BAD_CAST "MaximumValue");
1394                          xmlAddChild (nc8, nc7);
1395                        }
1396                      tmp0 = getMap (tmp1, "rangeSpacing");
1397                      if (tmp0 != NULL)
1398                        {
1399                          nc7 = xmlNewNode (ns_ows, BAD_CAST "Spacing");
1400                          xmlAddChild (nc7,
1401                                       xmlNewText (BAD_CAST tmp0->value));
1402                          xmlAddChild (nc8, nc7);
1403                        }
1404                      tmp0 = getMap (tmp1, "rangeClosure");
1405                      if (tmp0 != NULL)
1406                        {
1407                          const char *tmp = "closed";
1408                          if (strcasecmp (tmp0->value, "co") == 0)
1409                            tmp = "closed-open";
1410                          else if (strcasecmp (tmp0->value, "oc") == 0)
1411                            tmp = "open-closed";
1412                          else if (strcasecmp (tmp0->value, "o") == 0)
1413                            tmp = "open";
1414                          xmlNewNsProp (nc8, ns_ows, BAD_CAST "rangeClosure",
1415                                        BAD_CAST tmp);
1416                        }
1417                      else
1418                        xmlNewNsProp (nc8, ns_ows, BAD_CAST "rangeClosure",
1419                                      BAD_CAST "closed");
1420                    }
1421                  if (_tmp0 == NULL)
1422                    {
1423                      xmlAddChild (nc6, nc8);
1424                      _tmp0 = e->supported;
1425                      if (getMap (_tmp0->content, "range") != NULL ||
1426                          getMap (_tmp0->content, "rangeMin") != NULL ||
1427                          getMap (_tmp0->content, "rangeMax") != NULL ||
1428                          getMap (_tmp0->content, "rangeClosure") != NULL)
1429                        {
1430                          tmp1 = _tmp0->content;
1431                          goto doRange;
1432                        }
1433                    }
1434                  else
1435                    {
1436                      _tmp0 = _tmp0->next;
1437                      if (_tmp0 != NULL)
1438                        {
1439                          xmlAddChild (nc6, nc8);
1440                          if (getMap (_tmp0->content, "range") != NULL ||
1441                              getMap (_tmp0->content, "rangeMin") != NULL ||
1442                              getMap (_tmp0->content, "rangeMax") != NULL ||
1443                              getMap (_tmp0->content, "rangeClosure") != NULL)
1444                            {
1445                              tmp1 = _tmp0->content;
1446                              goto doRange;
1447                            }
1448                        }
1449                    }
1450                  xmlAddChild (nc6, nc8);
1451                  xmlAddChild (nc3, nc6);
1452                  isAnyValue = -1;
1453                }
1454
1455            }
1456
1457
1458          int oI = 0;
1459          for (oI = 0; oI < 13; oI++)
1460            if ((tmp1 = getMap (_tmp->content, orderedFields[oI])) != NULL)
1461              {
1462#ifdef DEBUG
1463                printf ("DATATYPE DEFAULT ? %s\n", tmp1->name);
1464#endif
1465                if (strcmp (tmp1->name, "asReference") != 0 &&
1466                    strncasecmp (tmp1->name, "DataType", 8) != 0 &&
1467                    strcasecmp (tmp1->name, "extension") != 0 &&
1468                    strcasecmp (tmp1->name, "value") != 0 &&
1469                    strcasecmp (tmp1->name, "AllowedValues") != 0 &&
1470                    strncasecmp (tmp1->name, "range", 5) != 0)
1471                  {
1472                    if (datatype != 1)
1473                      {
1474                        char *tmp2 = zCapitalize1 (tmp1->name);
1475                        nc9 = xmlNewNode (NULL, BAD_CAST tmp2);
1476                        free (tmp2);
1477                      }
1478                    else
1479                      {
1480                        char *tmp2 = zCapitalize (tmp1->name);
1481                        nc9 = xmlNewNode (ns_ows, BAD_CAST tmp2);
1482                        free (tmp2);
1483                      }
1484                    xmlAddChild (nc9, xmlNewText (BAD_CAST tmp1->value));
1485                    xmlAddChild (nc5, nc9);
1486                    if (strcasecmp (tmp1->name, "uom") == 0)
1487                      hasUOM1 = true;
1488                    hasUOM = true;
1489                  }
1490                else
1491
1492                  tmp1 = tmp1->next;
1493              }
1494
1495
1496          if (datatype != 2)
1497            {
1498              if (hasUOM == true)
1499                {
1500                  xmlAddChild (nc4, nc5);
1501                  xmlAddChild (nc3, nc4);
1502                }
1503              else
1504                {
1505                  if (hasUOM1 == false)
1506                    {
1507                      xmlFreeNode (nc5);
1508                      if (datatype == 1)
1509                        xmlFreeNode (nc4);
1510                    }
1511                }
1512            }
1513          else
1514            {
1515              xmlAddChild (nc3, nc5);
1516            }
1517
1518          if (datatype != 1 && default1 < 0)
1519            {
1520              xmlFreeNode (nc5);
1521              if (datatype != 2)
1522                xmlFreeNode (nc4);
1523            }
1524
1525          map *metadata = e->metadata;
1526          xmlNodePtr n = NULL;
1527          int xlinkId =
1528            zooXmlAddNs (n, "http://www.w3.org/1999/xlink", "xlink");
1529          xmlNsPtr ns_xlink = usedNs[xlinkId];
1530
1531          while (metadata != NULL)
1532            {
1533              nc6 = xmlNewNode (ns_ows, BAD_CAST "Metadata");
1534              xmlNewNsProp (nc6, ns_xlink, BAD_CAST metadata->name,
1535                            BAD_CAST metadata->value);
1536              xmlAddChild (nc2, nc6);
1537              metadata = metadata->next;
1538            }
1539
1540        }
1541
1542      _tmp = e->supported;
1543      if (_tmp == NULL && datatype != 1)
1544        _tmp = e->defaults;
1545
1546      int hasSupported = -1;
1547
1548      while (_tmp != NULL)
1549        {
1550          if (hasSupported < 0)
1551            {
1552              if (datatype == 0)
1553                {
1554                  nc4 = xmlNewNode (NULL, BAD_CAST "Supported");
1555                  nc5 = xmlNewNode (NULL, BAD_CAST "Format");
1556                }
1557              else
1558                nc5 = xmlNewNode (NULL, BAD_CAST "Supported");
1559              hasSupported = 0;
1560            }
1561          else if (datatype == 0)
1562            nc5 = xmlNewNode (NULL, BAD_CAST "Format");
1563          tmp1 = _tmp->content;
1564          int oI = 0;
1565          for (oI = 0; oI < 6; oI++)
1566            if ((tmp1 = getMap (_tmp->content, orderedFields[oI])) != NULL)
1567              {
1568#ifdef DEBUG
1569                printf ("DATATYPE SUPPORTED ? %s\n", tmp1->name);
1570#endif
1571                if (strcmp (tmp1->name, "asReference") != 0 &&
1572                    strcmp (tmp1->name, "value") != 0 &&
1573                    strcmp (tmp1->name, "DataType") != 0 &&
1574                    strcasecmp (tmp1->name, "extension") != 0)
1575                  {
1576                    if (datatype != 1)
1577                      {
1578                        char *tmp2 = zCapitalize1 (tmp1->name);
1579                        nc6 = xmlNewNode (NULL, BAD_CAST tmp2);
1580                        free (tmp2);
1581                      }
1582                    else
1583                      {
1584                        char *tmp2 = zCapitalize (tmp1->name);
1585                        nc6 = xmlNewNode (ns_ows, BAD_CAST tmp2);
1586                        free (tmp2);
1587                      }
1588                    if (datatype == 2)
1589                      {
1590                        char *tmpv, *tmps;
1591                        tmps = strtok_r (tmp1->value, ",", &tmpv);
1592                        while (tmps)
1593                          {
1594                            xmlAddChild (nc6, xmlNewText (BAD_CAST tmps));
1595                            tmps = strtok_r (NULL, ",", &tmpv);
1596                            if (tmps)
1597                              {
1598                                char *tmp2 = zCapitalize1 (tmp1->name);
1599                                nc6 = xmlNewNode (NULL, BAD_CAST tmp2);
1600                                free (tmp2);
1601                              }
1602                          }
1603                      }
1604                    else
1605                      {
1606                        xmlAddChild (nc6, xmlNewText (BAD_CAST tmp1->value));
1607                      }
1608                    xmlAddChild (nc5, nc6);
1609                  }
1610                tmp1 = tmp1->next;
1611              }
1612          if (hasSupported <= 0)
1613            {
1614              if (datatype == 0)
1615                {
1616                  xmlAddChild (nc4, nc5);
1617                  xmlAddChild (nc3, nc4);
1618                }
1619              else
1620                {
1621                  if (datatype != 1)
1622                    xmlAddChild (nc3, nc5);
1623                }
1624              hasSupported = 1;
1625            }
1626          else if (datatype == 0)
1627            {
1628              xmlAddChild (nc4, nc5);
1629              xmlAddChild (nc3, nc4);
1630            }
1631          else if (datatype != 1)
1632            xmlAddChild (nc3, nc5);
1633
1634          _tmp = _tmp->next;
1635        }
1636
1637      if (hasSupported == 0)
1638        {
1639          if (datatype == 0)
1640            xmlFreeNode (nc4);
1641          xmlFreeNode (nc5);
1642        }
1643
1644      _tmp = e->defaults;
1645      if (datatype == 1 && hasUOM1 == true)
1646        {
1647          xmlAddChild (nc4, nc5);
1648          xmlAddChild (nc3, nc4);
1649        }
1650
1651      if (in > 0 && datatype == 1 &&
1652          getMap (_tmp->content, "AllowedValues") == NULL &&
1653          getMap (_tmp->content, "range") == NULL &&
1654          getMap (_tmp->content, "rangeMin") == NULL &&
1655          getMap (_tmp->content, "rangeMax") == NULL &&
1656          getMap (_tmp->content, "rangeClosure") == NULL)
1657        {
1658          tmp1 = getMap (_tmp->content, "dataType");
1659          if (tmp1 != NULL)
1660            if (strcasecmp (tmp1->value, "boolean") == 0)
1661              {
1662                nc6 = xmlNewNode (ns_ows, BAD_CAST "AllowedValues");
1663                nc7 = xmlNewNode (ns_ows, BAD_CAST "Value");
1664                xmlAddChild (nc7, xmlNewText (BAD_CAST "true"));
1665                xmlAddChild (nc6, nc7);
1666                nc7 = xmlNewNode (ns_ows, BAD_CAST "Value");
1667                xmlAddChild (nc7, xmlNewText (BAD_CAST "false"));
1668                xmlAddChild (nc6, nc7);
1669                xmlAddChild (nc3, nc6);
1670              }
1671          xmlAddChild (nc3, xmlNewNode (ns_ows, BAD_CAST "AnyValue"));
1672        }
1673
1674      if ((tmp1 = getMap (_tmp->content, "value")) != NULL)
1675        {
1676          nc7 = xmlNewNode (NULL, BAD_CAST "DefaultValue");
1677          xmlAddChild (nc7, xmlNewText (BAD_CAST tmp1->value));
1678          xmlAddChild (nc3, nc7);
1679        }
1680
1681      xmlAddChild (nc2, nc3);
1682
1683      xmlAddChild (nc1, nc2);
1684
1685      e = e->next;
1686    }
1687}
1688
1689void
1690printProcessResponse (maps * m, map * request, int pid, service * serv,
1691                      const char *service, int status, maps * inputs,
1692                      maps * outputs, FCGX_Stream* out)
1693{
1694  xmlNsPtr ns, ns_ows, ns_xlink, ns_xsi;
1695  xmlNodePtr nr, n, nc, nc1 = NULL, nc3;
1696  xmlDocPtr doc;
1697  time_t time1;
1698  time (&time1);
1699  nr = NULL;
1700  /**
1701   * Create the document and its temporary root.
1702   */
1703  doc = xmlNewDoc (BAD_CAST "1.0");
1704  int wpsId = zooXmlAddNs (NULL, "http://www.opengis.net/wps/1.0.0", "wps");
1705  ns = usedNs[wpsId];
1706
1707  n = xmlNewNode (ns, BAD_CAST "ExecuteResponse");
1708  xmlNewNs (n, BAD_CAST "http://www.opengis.net/wps/1.0.0", BAD_CAST "wps");
1709  int owsId = zooXmlAddNs (n, "http://www.opengis.net/ows/1.1", "ows");
1710  ns_ows = usedNs[owsId];
1711  int xlinkId = zooXmlAddNs (n, "http://www.w3.org/1999/xlink", "xlink");
1712  ns_xlink = usedNs[xlinkId];
1713  int xsiId =
1714    zooXmlAddNs (n, "http://www.w3.org/2001/XMLSchema-instance", "xsi");
1715  ns_xsi = usedNs[xsiId];
1716
1717  xmlNewNsProp (n, ns_xsi, BAD_CAST "schemaLocation",
1718                BAD_CAST
1719                "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_response.xsd");
1720
1721  xmlNewProp (n, BAD_CAST "service", BAD_CAST "WPS");
1722  xmlNewProp (n, BAD_CAST "version", BAD_CAST "1.0.0");
1723  addLangAttr (n, m);
1724
1725  char tmp[256];
1726  char url[1024];
1727  char stored_path[1024];
1728  memset (tmp, 0, 256);
1729  memset (url, 0, 1024);
1730  memset (stored_path, 0, 1024);
1731  maps *tmp_maps = getMaps (m, "main");
1732  if (tmp_maps != NULL)
1733    {
1734      map *tmpm1 = getMap (tmp_maps->content, "serverAddress");
1735    /**
1736     * Check if the ZOO Service GetStatus is available in the local directory.
1737     * If yes, then it uses a reference to an URL which the client can access
1738     * to get information on the status of a running Service (using the
1739     * percentCompleted attribute).
1740     * Else fallback to the initial method using the xml file to write in ...
1741     */
1742      char ntmp[1024];
1743#ifndef WIN32
1744      getcwd (ntmp, 1024);
1745#else
1746      _getcwd (ntmp, 1024);
1747#endif
1748      struct stat myFileInfo;
1749      int statRes;
1750      char file_path[1024];
1751      sprintf (file_path, "%s/GetStatus.zcfg", ntmp);
1752      statRes = stat (file_path, &myFileInfo);
1753      if (statRes == 0)
1754        {
1755          char currentSid[128];
1756          map *tmpm = getMap (tmp_maps->content, "rewriteUrl");
1757          map *tmp_lenv = NULL;
1758          tmp_lenv = getMapFromMaps (m, "lenv", "sid");
1759          if (tmp_lenv == NULL)
1760            sprintf (currentSid, "%i", pid);
1761          else
1762            sprintf (currentSid, "%s", tmp_lenv->value);
1763          if (tmpm == NULL || strcasecmp (tmpm->value, "false") == 0)
1764            {
1765              sprintf (url,
1766                       "%s?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",
1767                       tmpm1->value, currentSid);
1768            }
1769          else
1770            {
1771              if (strlen (tmpm->value) > 0)
1772                if (strcasecmp (tmpm->value, "true") != 0)
1773                  sprintf (url, "%s/%s/GetStatus/%s", tmpm1->value,
1774                           tmpm->value, currentSid);
1775                else
1776                  sprintf (url, "%s/GetStatus/%s", tmpm1->value, currentSid);
1777              else
1778                sprintf (url,
1779                         "%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",
1780                         tmpm1->value, currentSid);
1781            }
1782        }
1783      else
1784        {
1785          map *tmpm2 = getMap (tmp_maps->content, "tmpUrl");
1786          if (tmpm1 != NULL && tmpm2 != NULL)
1787            {
1788              if (strncasecmp (tmpm2->value, "http://", 7) == 0 ||
1789                  strncasecmp (tmpm2->value, "https://", 8) == 0)
1790                {
1791                  sprintf (url, "%s/%s_%i.xml", tmpm2->value, service, pid);
1792                }
1793              else
1794                sprintf (url, "%s/%s/%s_%i.xml", tmpm1->value, tmpm2->value,
1795                         service, pid);
1796            }
1797        }
1798      if (tmpm1 != NULL)
1799        sprintf (tmp, "%s", tmpm1->value);
1800      tmpm1 = getMapFromMaps (m, "main", "TmpPath");
1801      sprintf (stored_path, "%s/%s_%i.xml", tmpm1->value, service, pid);
1802    }
1803
1804
1805
1806  xmlNewProp (n, BAD_CAST "serviceInstance", BAD_CAST tmp);
1807  map *test = getMap (request, "storeExecuteResponse");
1808  bool hasStoredExecuteResponse = false;
1809  if (test != NULL && strcasecmp (test->value, "true") == 0)
1810    {
1811      xmlNewProp (n, BAD_CAST "statusLocation", BAD_CAST url);
1812      hasStoredExecuteResponse = true;
1813    }
1814
1815  nc = xmlNewNode (ns, BAD_CAST "Process");
1816  map *tmp2 = getMap (serv->content, "processVersion");
1817  if (tmp2 != NULL)
1818    xmlNewNsProp (nc, ns, BAD_CAST "processVersion", BAD_CAST tmp2->value);
1819
1820  printDescription (nc, ns_ows, serv->name, serv->content);
1821
1822  xmlAddChild (n, nc);
1823
1824  nc = xmlNewNode (ns, BAD_CAST "Status");
1825  const struct tm *tm;
1826  size_t len;
1827  time_t now;
1828  char *tmp1;
1829  map *tmpStatus;
1830
1831  now = time (NULL);
1832  tm = localtime (&now);
1833
1834  tmp1 = (char *) malloc ((TIME_SIZE + 1) * sizeof (char));
1835
1836  len = strftime (tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm);
1837
1838  xmlNewProp (nc, BAD_CAST "creationTime", BAD_CAST tmp1);
1839
1840  char sMsg[2048];
1841  switch (status)
1842    {
1843    case SERVICE_SUCCEEDED:
1844      nc1 = xmlNewNode (ns, BAD_CAST "ProcessSucceeded");
1845      sprintf (sMsg, _("Service \"%s\" run successfully."), serv->name);
1846      nc3 = xmlNewText (BAD_CAST sMsg);
1847      xmlAddChild (nc1, nc3);
1848      break;
1849    case SERVICE_STARTED:
1850      nc1 = xmlNewNode (ns, BAD_CAST "ProcessStarted");
1851      tmpStatus = getMapFromMaps (m, "lenv", "status");
1852      xmlNewProp (nc1, BAD_CAST "percentCompleted",
1853                  BAD_CAST tmpStatus->value);
1854      sprintf (sMsg,
1855               _
1856               ("ZOO Service \"%s\" is currently running. Please, reload this document to get the up-to-date status of the Service."),
1857               serv->name);
1858      nc3 = xmlNewText (BAD_CAST sMsg);
1859      xmlAddChild (nc1, nc3);
1860      break;
1861    case SERVICE_ACCEPTED:
1862      nc1 = xmlNewNode (ns, BAD_CAST "ProcessAccepted");
1863      sprintf (sMsg,
1864               _
1865               ("Service \"%s\" was accepted by the ZOO Kernel and it run as a background task. Please consult the statusLocation attribtue providen in this document to get the up-to-date document."),
1866               serv->name);
1867      nc3 = xmlNewText (BAD_CAST sMsg);
1868      xmlAddChild (nc1, nc3);
1869      break;
1870    case SERVICE_FAILED:
1871      nc1 = xmlNewNode (ns, BAD_CAST "ProcessFailed");
1872      map *errorMap;
1873      map *te;
1874      te = getMapFromMaps (m, "lenv", "code");
1875      if (te != NULL)
1876        errorMap = createMap ("code", te->value);
1877      else
1878        errorMap = createMap ("code", "NoApplicableCode");
1879      te = getMapFromMaps (m, "lenv", "message");
1880      if (te != NULL)
1881        addToMap (errorMap, "text", _ss (te->value));
1882      else
1883        addToMap (errorMap, "text", _("No more information available"));
1884      nc3 = createExceptionReportNode (m, errorMap, 0);
1885      freeMap (&errorMap);
1886      free (errorMap);
1887      xmlAddChild (nc1, nc3);
1888      break;
1889    default:
1890      printf (_("error code not know : %i\n"), status);
1891      //exit(1);
1892      break;
1893    }
1894  xmlAddChild (nc, nc1);
1895  xmlAddChild (n, nc);
1896  free (tmp1);
1897
1898#ifdef DEBUG
1899  fprintf (stderr, "printProcessResponse 1 161\n");
1900#endif
1901
1902  map *lineage = getMap (request, "lineage");
1903  if (lineage != NULL && strcasecmp (lineage->value, "true") == 0)
1904    {
1905      nc = xmlNewNode (ns, BAD_CAST "DataInputs");
1906      maps *mcursor = inputs;
1907      elements *scursor = NULL;
1908      while (mcursor != NULL /*&& scursor!=NULL */ )
1909        {
1910          scursor = getElements (serv->inputs, mcursor->name);
1911          printIOType (doc, nc, ns, ns_ows, ns_xlink, scursor, mcursor,
1912                       "Input");
1913          mcursor = mcursor->next;
1914        }
1915      xmlAddChild (n, nc);
1916
1917#ifdef DEBUG
1918      fprintf (stderr, "printProcessResponse 1 177\n");
1919#endif
1920
1921      nc = xmlNewNode (ns, BAD_CAST "OutputDefinitions");
1922      mcursor = outputs;
1923      scursor = NULL;
1924      while (mcursor != NULL)
1925        {
1926          scursor = getElements (serv->outputs, mcursor->name);
1927          printOutputDefinitions1 (doc, nc, ns, ns_ows, scursor, mcursor,
1928                                   "Output");
1929          mcursor = mcursor->next;
1930        }
1931      xmlAddChild (n, nc);
1932    }
1933#ifdef DEBUG
1934  fprintf (stderr, "printProcessResponse 1 190\n");
1935#endif
1936
1937  /**
1938   * Display the process output only when requested !
1939   */
1940  if (status == SERVICE_SUCCEEDED)
1941    {
1942      nc = xmlNewNode (ns, BAD_CAST "ProcessOutputs");
1943      maps *mcursor = outputs;
1944      elements *scursor = serv->outputs;
1945      map *testResponse = getMap (request, "RawDataOutput");
1946      if (testResponse == NULL)
1947        testResponse = getMap (request, "ResponseDocument");
1948      while (mcursor != NULL)
1949        {
1950          map *tmp0 = getMap (mcursor->content, "inRequest");
1951          scursor = getElements (serv->outputs, mcursor->name);
1952          if (scursor != NULL)
1953            {
1954              if (testResponse == NULL || tmp0 == NULL)
1955                printIOType (doc, nc, ns, ns_ows, ns_xlink, scursor, mcursor,
1956                             "Output");
1957              else if (tmp0 != NULL && strncmp (tmp0->value, "true", 4) == 0)
1958                printIOType (doc, nc, ns, ns_ows, ns_xlink, scursor, mcursor,
1959                             "Output");
1960            }
1961          else
1962        /**
1963         * In case there was no definition found in the ZCFG file but
1964         * present in the service code
1965         */
1966            printIOType (doc, nc, ns, ns_ows, ns_xlink, scursor, mcursor,
1967                         "Output");
1968          mcursor = mcursor->next;
1969        }
1970      xmlAddChild (n, nc);
1971    }
1972
1973#ifdef DEBUG
1974  fprintf (stderr, "printProcessResponse 1 202\n");
1975#endif
1976  nr = soapEnvelope (m, n);
1977  xmlDocSetRootElement (doc, nr);
1978
1979
1980  map * background = NULL;
1981  background = getMapFromMaps(m,"lenv","background");
1982
1983    if (background != NULL){
1984        /* requete asynchrone */
1985      /* We need to write the ExecuteResponse Document somewhere */
1986      FILE *output = fopen (stored_path, "w");
1987      if (output == NULL)
1988        {
1989          /* If the file cannot be created return an ExceptionReport */
1990          char tmpMsg[1024];
1991          sprintf (tmpMsg,
1992                   _
1993                   ("Unable to create the file : \"%s\" for storing the ExecuteResponse."),
1994                   stored_path);
1995          map *errormap = createMap ("text", tmpMsg);
1996          addToMap (errormap, "code", "InternalError");
1997          printExceptionReportResponse (m, errormap,out);
1998          freeMap (&errormap);
1999          free (errormap);
2000          xmlFreeDoc (doc);
2001          xmlCleanupParser ();
2002          zooXmlCleanupNs ();
2003          return;
2004        }
2005      xmlChar *xmlbuff;
2006      int buffersize;
2007      xmlDocDumpFormatMemoryEnc (doc, &xmlbuff, &buffersize, "UTF-8", 1);
2008      fwrite (xmlbuff, 1, xmlStrlen (xmlbuff) * sizeof (char), output);
2009      xmlFree (xmlbuff);
2010      fclose (output);
2011    }
2012    else {
2013  printDocument (m, doc, pid,out);
2014    }
2015  xmlCleanupParser ();
2016  zooXmlCleanupNs ();
2017}
2018
2019
2020void
2021printDocument (maps * m, xmlDocPtr doc, int pid,FCGX_Stream * out)
2022{
2023  char *encoding = getEncoding (m);
2024  if (pid == getpid ())
2025    {
2026      printHeaders (m,out);
2027      FCGX_FPrintF(out,"Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2028      //printf ("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2029    }
2030  //fflush (stdout);
2031  xmlChar *xmlbuff;
2032  int buffersize;
2033  /*
2034   * Dump the document to a buffer and print it on stdout
2035   * for demonstration purposes.
2036   */
2037  xmlDocDumpFormatMemoryEnc (doc, &xmlbuff, &buffersize, encoding, 1);
2038 
2039 
2040  if (out != NULL){
2041    FCGX_FPrintF(out,(char *)xmlbuff);
2042    FCGX_FFlush(out);
2043    }
2044  //printf ("%s", xmlbuff);
2045  //fflush (stdout);
2046  /*
2047   * Free associated memory.
2048   */
2049  xmlFree (xmlbuff);
2050  xmlFreeDoc (doc);
2051  xmlCleanupParser ();
2052  zooXmlCleanupNs ();
2053}
2054
2055void
2056printOutputDefinitions1 (xmlDocPtr doc, xmlNodePtr nc, xmlNsPtr ns_wps,
2057                         xmlNsPtr ns_ows, elements * e, maps * m,
2058                         const char *type)
2059{
2060  xmlNodePtr nc1;
2061  nc1 = xmlNewNode (ns_wps, BAD_CAST type);
2062  map *tmp = NULL;
2063  if (e != NULL && e->defaults != NULL)
2064    tmp = e->defaults->content;
2065  else
2066    {
2067      /*
2068         dumpElements(e);
2069       */
2070      return;
2071    }
2072  while (tmp != NULL)
2073    {
2074      if (strncasecmp (tmp->name, "MIMETYPE", strlen (tmp->name)) == 0
2075          || strncasecmp (tmp->name, "ENCODING", strlen (tmp->name)) == 0
2076          || strncasecmp (tmp->name, "SCHEMA", strlen (tmp->name)) == 0
2077          || strncasecmp (tmp->name, "UOM", strlen (tmp->name)) == 0)
2078        xmlNewProp (nc1, BAD_CAST tmp->name, BAD_CAST tmp->value);
2079      tmp = tmp->next;
2080    }
2081  tmp = getMap (e->defaults->content, "asReference");
2082  if (tmp == NULL)
2083    xmlNewProp (nc1, BAD_CAST "asReference", BAD_CAST "false");
2084
2085  tmp = e->content;
2086
2087  printDescription (nc1, ns_ows, m->name, e->content);
2088
2089  xmlAddChild (nc, nc1);
2090
2091}
2092
2093void
2094printOutputDefinitions (xmlDocPtr doc, xmlNodePtr nc, xmlNsPtr ns_wps,
2095                        xmlNsPtr ns_ows, elements * e, map * m,
2096                        const char *type)
2097{
2098  xmlNodePtr nc1;
2099  nc1 = xmlNewNode (ns_wps, BAD_CAST type);
2100  map *tmp = NULL;
2101  if (e != NULL && e->defaults != NULL)
2102    tmp = e->defaults->content;
2103  else
2104    {
2105      /*
2106         dumpElements(e);
2107       */
2108      return;
2109    }
2110  while (tmp != NULL)
2111    {
2112      xmlNewProp (nc1, BAD_CAST tmp->name, BAD_CAST tmp->value);
2113      tmp = tmp->next;
2114    }
2115  tmp = getMap (e->defaults->content, "asReference");
2116  if (tmp == NULL)
2117    xmlNewProp (nc1, BAD_CAST "asReference", BAD_CAST "false");
2118
2119  tmp = e->content;
2120
2121  printDescription (nc1, ns_ows, m->name, e->content);
2122
2123  xmlAddChild (nc, nc1);
2124
2125}
2126
2127void
2128printIOType (xmlDocPtr doc, xmlNodePtr nc, xmlNsPtr ns_wps, xmlNsPtr ns_ows,
2129             xmlNsPtr ns_xlink, elements * e, maps * m, const char *type)
2130{
2131  xmlNodePtr nc1, nc2, nc3;
2132  nc1 = xmlNewNode (ns_wps, BAD_CAST type);
2133  map *tmp = NULL;
2134  if (e != NULL)
2135    tmp = e->content;
2136  else
2137    tmp = m->content;
2138#ifdef DEBUG
2139  dumpMap (tmp);
2140  dumpElements (e);
2141#endif
2142  nc2 = xmlNewNode (ns_ows, BAD_CAST "Identifier");
2143  if (e != NULL)
2144    nc3 = xmlNewText (BAD_CAST e->name);
2145  else
2146    nc3 = xmlNewText (BAD_CAST m->name);
2147  xmlAddChild (nc2, nc3);
2148  xmlAddChild (nc1, nc2);
2149  xmlAddChild (nc, nc1);
2150  if (e != NULL)
2151    tmp = getMap (e->content, "Title");
2152  else
2153    tmp = getMap (m->content, "Title");
2154
2155  if (tmp != NULL)
2156    {
2157      nc2 = xmlNewNode (ns_ows, BAD_CAST tmp->name);
2158      nc3 = xmlNewText (BAD_CAST _ss (tmp->value));
2159      xmlAddChild (nc2, nc3);
2160      xmlAddChild (nc1, nc2);
2161    }
2162
2163  if (e != NULL)
2164    tmp = getMap (e->content, "Abstract");
2165  else
2166    tmp = getMap (m->content, "Abstract");
2167  if (tmp != NULL)
2168    {
2169      nc2 = xmlNewNode (ns_ows, BAD_CAST tmp->name);
2170      nc3 = xmlNewText (BAD_CAST _ss (tmp->value));
2171      xmlAddChild (nc2, nc3);
2172      xmlAddChild (nc1, nc2);
2173      xmlAddChild (nc, nc1);
2174    }
2175
2176  /**
2177   * IO type Reference or full Data ?
2178   */
2179#ifdef DEBUG
2180  fprintf (stderr, "FORMAT %s %s\n", e->format, e->format);
2181#endif
2182  map *tmpMap = getMap (m->content, "Reference");
2183  if (tmpMap == NULL)
2184    {
2185      nc2 = xmlNewNode (ns_wps, BAD_CAST "Data");
2186      if (e != NULL)
2187        {
2188          if (strncasecmp (e->format, "LiteralOutput", strlen (e->format)) ==
2189              0)
2190            nc3 = xmlNewNode (ns_wps, BAD_CAST "LiteralData");
2191          else
2192            if (strncasecmp (e->format, "ComplexOutput", strlen (e->format))
2193                == 0)
2194            nc3 = xmlNewNode (ns_wps, BAD_CAST "ComplexData");
2195          else
2196            if (strncasecmp
2197                (e->format, "BoundingBoxOutput", strlen (e->format)) == 0)
2198            nc3 = xmlNewNode (ns_wps, BAD_CAST "BoundingBoxData");
2199          else
2200            nc3 = xmlNewNode (ns_wps, BAD_CAST e->format);
2201        }
2202      else
2203        {
2204          map *tmpV = getMapFromMaps (m, "format", "value");
2205          if (tmpV != NULL)
2206            nc3 = xmlNewNode (ns_wps, BAD_CAST tmpV->value);
2207          else
2208            nc3 = xmlNewNode (ns_wps, BAD_CAST "LitteralData");
2209        }
2210      tmp = m->content;
2211#ifdef USE_MS
2212      map *testMap = getMap (tmp, "requestedMimeType");
2213#endif
2214      while (tmp != NULL)
2215        {
2216          if (strcasecmp (tmp->name, "mimeType") == 0 ||
2217              strcasecmp (tmp->name, "encoding") == 0 ||
2218              strcasecmp (tmp->name, "schema") == 0 ||
2219              strcasecmp (tmp->name, "datatype") == 0 ||
2220              strcasecmp (tmp->name, "uom") == 0)
2221            {
2222#ifdef USE_MS
2223              if (testMap == NULL
2224                  || (testMap != NULL
2225                      && strncasecmp (testMap->value, "text/xml", 8) == 0))
2226                {
2227#endif
2228                  xmlNewProp (nc3, BAD_CAST tmp->name, BAD_CAST tmp->value);
2229#ifdef USE_MS
2230                }
2231              else if (strcasecmp (tmp->name, "mimeType") == 0)
2232                {
2233                  if (testMap != NULL)
2234                    xmlNewProp (nc3, BAD_CAST tmp->name,
2235                                BAD_CAST testMap->value);
2236                  else
2237                    xmlNewProp (nc3, BAD_CAST tmp->name, BAD_CAST tmp->value);
2238                }
2239#endif
2240            }
2241          tmp = tmp->next;
2242          xmlAddChild (nc2, nc3);
2243        }
2244      if (e != NULL && e->format != NULL
2245          && strcasecmp (e->format, "BoundingBoxData") == 0)
2246        {
2247          map *bb = getMap (m->content, "value");
2248          if (bb != NULL)
2249            {
2250              map *tmpRes = parseBoundingBox (bb->value);
2251              printBoundingBox (ns_ows, nc3, tmpRes);
2252              freeMap (&tmpRes);
2253              free (tmpRes);
2254            }
2255        }
2256      else
2257        {
2258          if (e != NULL)
2259            tmp = getMap (e->defaults->content, "mimeType");
2260          else
2261            tmp = NULL;
2262#ifdef USE_MS
2263      /**
2264       * In case of OGC WebServices output use, as the data was requested
2265       * with asReference=false we have to download the resulting OWS request
2266       * stored in the Reference map value.
2267       */
2268          map *testMap = getMap (m->content, "requestedMimeType");
2269          if (testMap != NULL)
2270            {
2271              HINTERNET hInternet;
2272              char *tmpValue;
2273              size_t dwRead;
2274              hInternet = InternetOpen (
2275#ifndef WIN32
2276                                         (LPCTSTR)
2277#endif
2278                                         "ZooWPSClient\0",
2279                                         INTERNET_OPEN_TYPE_PRECONFIG,
2280                                         NULL, NULL, 0);
2281              testMap = getMap (m->content, "Reference");
2282              loadRemoteFile (&m, &m->content, &hInternet, testMap->value);
2283              processDownloads (&hInternet);
2284              tmpValue =
2285                (char *) malloc ((hInternet.ihandle[0].nDataLen + 1) *
2286                                 sizeof (char));
2287              InternetReadFile (hInternet.ihandle[0], (LPVOID) tmpValue,
2288                                hInternet.ihandle[0].nDataLen, &dwRead);
2289              InternetCloseHandle (&hInternet);
2290            }
2291#endif
2292          map *tmp1 = getMap (m->content, "encoding");
2293          map *tmp2 = getMap (m->content, "mimeType");
2294          map *tmp3 = getMap (m->content, "value");
2295          int hasValue = 1;
2296          if (tmp3 == NULL)
2297            {
2298              tmp3 = createMap ("value", "");
2299              hasValue = -1;
2300            }
2301          if ((tmp1 != NULL && strncmp (tmp1->value, "base64", 6) == 0)
2302              || (tmp2 != NULL && (strncmp (tmp2->value, "image/", 6) == 0 ||
2303                                   (strncmp (tmp2->value, "application/", 12)
2304                                    == 0
2305                                    && strncmp (tmp2->value,
2306                                                "application/json", 16) != 0
2307                                    && strncmp (tmp2->value,
2308                                                "application/x-javascript",
2309                                                24) != 0
2310                                    && strncmp (tmp2->value,
2311                                                "application/vnd.google-earth.kml",
2312                                                32) != 0))))
2313            {
2314              map *rs = getMap (m->content, "size");
2315              bool isSized = true;
2316              if (rs == NULL)
2317                {
2318                  char tmp1[1024];
2319                  sprintf (tmp1, "%u", strlen (tmp3->value));
2320                  rs = createMap ("size", tmp1);
2321                  isSized = false;
2322                }
2323
2324              xmlAddChild (nc3,
2325                           xmlNewText (BAD_CAST
2326                                       base64 (tmp3->value,
2327                                               atoi (rs->value))));
2328              if (tmp1 == NULL
2329                  || (tmp1 != NULL
2330                      && strncmp (tmp1->value, "base64", 6) != 0))
2331                xmlNewProp (nc3, BAD_CAST "encoding", BAD_CAST "base64");
2332              if (!isSized)
2333                {
2334                  freeMap (&rs);
2335                  free (rs);
2336                }
2337            }
2338          else if (tmp2 != NULL)
2339            {
2340              if (strncmp (tmp2->value, "text/js", 7) == 0 ||
2341                  strncmp (tmp2->value, "application/json", 16) == 0)
2342                xmlAddChild (nc3,
2343                             xmlNewCDataBlock (doc, BAD_CAST tmp3->value,
2344                                               strlen (tmp3->value)));
2345              else
2346                {
2347                  if (strncmp (tmp2->value, "text/xml", 8) == 0 ||
2348                      strncmp (tmp2->value,
2349                               "application/vnd.google-earth.kml", 32) == 0)
2350                    {
2351                      int li = zooXmlAddDoc (tmp3->value);
2352                      xmlDocPtr doc = iDocs[li];
2353                      xmlNodePtr ir = xmlDocGetRootElement (doc);
2354                      xmlAddChild (nc3, ir);
2355                    }
2356                  else
2357                    xmlAddChild (nc3, xmlNewText (BAD_CAST tmp3->value));
2358                }
2359              xmlAddChild (nc2, nc3);
2360            }
2361          else
2362            {
2363              xmlAddChild (nc3, xmlNewText (BAD_CAST tmp3->value));
2364            }
2365          if (hasValue < 0)
2366            {
2367              freeMap (&tmp3);
2368              free (tmp3);
2369            }
2370        }
2371    }
2372  else
2373    {
2374      tmpMap = getMap (m->content, "Reference");
2375      nc3 = nc2 = xmlNewNode (ns_wps, BAD_CAST "Reference");
2376      if (strcasecmp (type, "Output") == 0)
2377        xmlNewProp (nc3, BAD_CAST "href", BAD_CAST tmpMap->value);
2378      else
2379        xmlNewNsProp (nc3, ns_xlink, BAD_CAST "href", BAD_CAST tmpMap->value);
2380      tmp = m->content;
2381#ifdef USE_MS
2382      map *testMap = getMap (tmp, "requestedMimeType");
2383#endif
2384      while (tmp != NULL)
2385        {
2386          if (strcasecmp (tmp->name, "mimeType") == 0 ||
2387              strcasecmp (tmp->name, "encoding") == 0 ||
2388              strcasecmp (tmp->name, "schema") == 0 ||
2389              strcasecmp (tmp->name, "datatype") == 0 ||
2390              strcasecmp (tmp->name, "uom") == 0)
2391            {
2392#ifdef USE_MS
2393              if (testMap != NULL
2394                  && strncasecmp (testMap->value, "text/xml", 8) != 0)
2395                {
2396                  if (strcasecmp (tmp->name, "mimeType") == 0)
2397                    xmlNewProp (nc3, BAD_CAST tmp->name,
2398                                BAD_CAST testMap->value);
2399                }
2400              else
2401#endif
2402              if (strcasecmp (tmp->name, "datatype") == 0)
2403                xmlNewProp (nc3, BAD_CAST "mimeType", BAD_CAST "text/plain");
2404              else
2405                xmlNewProp (nc3, BAD_CAST tmp->name, BAD_CAST tmp->value);
2406            }
2407          tmp = tmp->next;
2408          xmlAddChild (nc2, nc3);
2409        }
2410    }
2411  xmlAddChild (nc1, nc2);
2412  xmlAddChild (nc, nc1);
2413
2414}
2415
2416void
2417printDescription (xmlNodePtr root, xmlNsPtr ns_ows, const char *identifier,
2418                  map * amap)
2419{
2420  xmlNodePtr nc2 = xmlNewNode (ns_ows, BAD_CAST "Identifier");
2421
2422  xmlAddChild (nc2, xmlNewText (BAD_CAST identifier));
2423  xmlAddChild (root, nc2);
2424  map *tmp = amap;
2425  const char *tmp2[2];
2426  tmp2[0] = "Title";
2427  tmp2[1] = "Abstract";
2428  int j = 0;
2429  for (j = 0; j < 2; j++)
2430    {
2431      map *tmp1 = getMap (tmp, tmp2[j]);
2432      if (tmp1 != NULL)
2433        {
2434          nc2 = xmlNewNode (ns_ows, BAD_CAST tmp2[j]);
2435          xmlAddChild (nc2, xmlNewText (BAD_CAST _ss (tmp1->value)));
2436          xmlAddChild (root, nc2);
2437        }
2438    }
2439}
2440
2441char *
2442getEncoding (maps * m)
2443{
2444  if (m != NULL)
2445    {
2446      map *tmp = getMap (m->content, "encoding");
2447      if (tmp != NULL)
2448        {
2449          return tmp->value;
2450        }
2451      else
2452        return (char *) "UTF-8";
2453    }
2454  else
2455    return (char *) "UTF-8";
2456}
2457
2458char *
2459getVersion (maps * m)
2460{
2461  if (m != NULL)
2462    {
2463      map *tmp = getMap (m->content, "version");
2464      if (tmp != NULL)
2465        {
2466          return tmp->value;
2467        }
2468      else
2469        return (char *) "1.0.0";
2470    }
2471  else
2472    return (char *) "1.0.0";
2473}
2474
2475void
2476printExceptionReportResponse (maps * m, map * s,FCGX_Stream * out)
2477{
2478  if (getMapFromMaps (m, "lenv", "hasPrinted") != NULL)
2479    return;
2480  int buffersize;
2481  xmlDocPtr doc;
2482  xmlChar *xmlbuff;
2483  xmlNodePtr n;
2484
2485  zooXmlCleanupNs ();
2486  doc = xmlNewDoc (BAD_CAST "1.0");
2487  maps *tmpMap = getMaps (m, "main");
2488  char *encoding = getEncoding (tmpMap);
2489  const char *exceptionCode;
2490
2491  map *tmp = getMap (s, "code");
2492  if (tmp != NULL)
2493    {
2494      if (strcmp (tmp->value, "OperationNotSupported") == 0)
2495        exceptionCode = "501 Not Implemented";
2496      else
2497        if (strcmp (tmp->value, "MissingParameterValue") == 0 ||
2498            strcmp (tmp->value, "InvalidUpdateSequence") == 0 ||
2499            strcmp (tmp->value, "OptionNotSupported") == 0 ||
2500            strcmp (tmp->value, "VersionNegotiationFailed") == 0 ||
2501            strcmp (tmp->value, "InvalidParameterValue") == 0)
2502        exceptionCode = "400 Bad request";
2503      else if (strcmp (tmp->value, "NoApplicableCode") == 0)
2504        exceptionCode = "501 Internal Server Error";
2505      else
2506        exceptionCode = "501 Internal Server Error";
2507    }
2508  else
2509    exceptionCode = "501 Internal Server Error";
2510
2511  if (m != NULL)
2512    {
2513      map *tmpSid = getMapFromMaps (m, "lenv", "sid");
2514      if (tmpSid != NULL)
2515        {
2516          if (getpid () == atoi (tmpSid->value))
2517            {
2518              printHeaders (m,out);
2519              FCGX_FPrintF(out,"Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding, exceptionCode);
2520              //printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding, exceptionCode);
2521            }
2522        }
2523      else
2524        {
2525          printHeaders (m,out);
2526          FCGX_FPrintF(out,"Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",
2527                            encoding, exceptionCode);
2528          //printf ("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding, exceptionCode);
2529        }
2530    }
2531  else
2532    { 
2533      FCGX_FPrintF(out,"Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding, exceptionCode);
2534      //printf ("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding, exceptionCode);
2535    }
2536  n = createExceptionReportNode (m, s, 1);
2537  xmlDocSetRootElement (doc, n);
2538  xmlDocDumpFormatMemoryEnc (doc, &xmlbuff, &buffersize, encoding, 1);
2539  //printf ("%s", xmlbuff);
2540  FCGX_FPrintF(out,"%s",xmlbuff);
2541FCGX_FFlush(out);
2542  //fflush (stdout);
2543  xmlFreeDoc (doc);
2544  xmlFree (xmlbuff);
2545  xmlCleanupParser ();
2546  zooXmlCleanupNs ();
2547  if (m != NULL)
2548    setMapInMaps (m, "lenv", "hasPrinted", "true");
2549}
2550
2551xmlNodePtr
2552createExceptionReportNode (maps * m, map * s, int use_ns)
2553{
2554
2555  xmlNsPtr ns, ns_xsi;
2556  xmlNodePtr n, nc, nc1;
2557
2558  int nsid = zooXmlAddNs (NULL, "http://www.opengis.net/ows", "ows");
2559  ns = usedNs[nsid];
2560  if (use_ns == 1)
2561    {
2562      ns = NULL;
2563    }
2564  n = xmlNewNode (ns, BAD_CAST "ExceptionReport");
2565  if (use_ns == 1)
2566    {
2567      xmlNewNs (n, BAD_CAST "http://www.opengis.net/ows/1.1", NULL);
2568      int xsiId =
2569        zooXmlAddNs (n, "http://www.w3.org/2001/XMLSchema-instance", "xsi");
2570      ns_xsi = usedNs[xsiId];
2571      xmlNewNsProp (n, ns_xsi, BAD_CAST "schemaLocation",
2572                    BAD_CAST
2573                    "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd");
2574    }
2575
2576
2577  addLangAttr (n, m);
2578  xmlNewProp (n, BAD_CAST "version", BAD_CAST "1.1.0");
2579
2580  nc = xmlNewNode (ns, BAD_CAST "Exception");
2581
2582  map *tmp = getMap (s, "code");
2583  if (tmp != NULL)
2584    xmlNewProp (nc, BAD_CAST "exceptionCode", BAD_CAST tmp->value);
2585  else
2586    xmlNewProp (nc, BAD_CAST "exceptionCode", BAD_CAST "NoApplicableCode");
2587
2588  tmp = getMap (s, "locator");
2589  if (tmp != NULL && strcasecmp (tmp->value, "NULL") != 0)
2590    xmlNewProp (nc, BAD_CAST "locator", BAD_CAST tmp->value);
2591
2592
2593  tmp = getMap (s, "text");
2594  nc1 = xmlNewNode (ns, BAD_CAST "ExceptionText");
2595  if (tmp != NULL)
2596    {
2597      xmlNodeSetContent (nc1, BAD_CAST tmp->value);
2598    }
2599  else
2600    {
2601      xmlNodeSetContent (nc1, BAD_CAST _("No debug message available"));
2602    }
2603  xmlAddChild (nc, nc1);
2604  xmlAddChild (n, nc);
2605  return n;
2606}
2607
2608
2609void
2610outputResponse (service * s, maps * request_inputs, maps * request_outputs,
2611                map * request_inputs1, int cpid, maps * m, int res,FCGX_Stream *out,FCGX_Stream *err)
2612{
2613
2614
2615#ifdef DEBUG
2616  dumpMaps (request_inputs);
2617  dumpMaps (request_outputs);
2618  fprintf (stderr, "printProcessResponse\n");
2619#endif
2620  map *toto = getMap (request_inputs1, "RawDataOutput");
2621  int asRaw = 0;
2622  if (toto != NULL)
2623    asRaw = 1;
2624
2625  maps *tmpSess = getMaps (m, "senv");
2626  if (tmpSess != NULL)
2627    {
2628      map *_tmp = getMapFromMaps (m, "lenv", "cookie");
2629      char *sessId = NULL;
2630      if (_tmp != NULL)
2631        {
2632          printf ("Set-Cookie: %s; HttpOnly\r\n", _tmp->value);
2633          printf
2634            ("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
2635          char session_file_path[100];
2636          char *tmp1 = strtok (_tmp->value, ";");
2637          if (tmp1 != NULL)
2638            sprintf (session_file_path, "%s", strstr (tmp1, "=") + 1);
2639          else
2640            sprintf (session_file_path, "%s", strstr (_tmp->value, "=") + 1);
2641          sessId = strdup (session_file_path);
2642        }
2643      else
2644        {
2645          maps *t = getMaps (m, "senv");
2646          map *p = t->content;
2647          while (p != NULL)
2648            {
2649              if (strstr (p->name, "ID") != NULL)
2650                {
2651                  sessId = strdup (p->value);
2652                  break;
2653                }
2654              p = p->next;
2655            }
2656        }
2657      char session_file_path[1024];
2658      map *tmpPath = getMapFromMaps (m, "main", "sessPath");
2659      if (tmpPath == NULL)
2660        tmpPath = getMapFromMaps (m, "main", "tmpPath");
2661      sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value, sessId);
2662      FILE *teste = fopen (session_file_path, "w");
2663      if (teste == NULL)
2664        {
2665          char tmpMsg[1024];
2666          sprintf (tmpMsg,
2667                   _
2668                   ("Unable to create the file : \"%s\" for storing the session maps."),
2669                   session_file_path);
2670          map *errormap = createMap ("text", tmpMsg);
2671          addToMap (errormap, "code", "InternalError");
2672
2673          printExceptionReportResponse (m, errormap,out);
2674          freeMap (&errormap);
2675          free (errormap);
2676          return;
2677        }
2678      else
2679        {
2680          fclose (teste);
2681          dumpMapsToFile (tmpSess, session_file_path);
2682        }
2683    }
2684
2685
2686  if (asRaw == 0)
2687    {
2688
2689
2690#ifdef DEBUG
2691      fprintf (stderr, "REQUEST_OUTPUTS FINAL\n");
2692      dumpMaps (request_outputs);
2693#endif
2694      maps *tmpI = request_outputs;
2695      while (tmpI != NULL)
2696        {
2697#ifdef USE_MS
2698          map *testMap = getMap (tmpI->content, "useMapserver");
2699#endif
2700          toto = getMap (tmpI->content, "asReference");
2701#ifdef USE_MS
2702          if (toto != NULL && strcasecmp (toto->value, "true") == 0
2703              && testMap == NULL)
2704#else
2705          if (toto != NULL && strcasecmp (toto->value, "true") == 0)
2706#endif
2707            {
2708              elements *in = getElements (s->outputs, tmpI->name);
2709              char *format = NULL;
2710              if (in != NULL)
2711                {
2712                  format = strdup (in->format);
2713                }
2714              else
2715                format = strdup ("LiteralData");
2716              if (strcasecmp (format, "BoundingBoxData") == 0)
2717                {
2718                  addToMap (tmpI->content, "extension", "xml");
2719                  addToMap (tmpI->content, "mimeType", "text/xml");
2720                  addToMap (tmpI->content, "encoding", "UTF-8");
2721                  addToMap (tmpI->content, "schema",
2722                            "http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2723                }
2724              map *ext = getMap (tmpI->content, "extension");
2725              map *tmp1 = getMapFromMaps (m, "main", "tmpPath");
2726              char *file_name, *file_path;
2727              bool hasExt = true;
2728              if (ext == NULL)
2729                {
2730                  // We can fallback to a default list of supported formats using
2731                  // mimeType information if present here. Maybe we can add more formats
2732                  // here.
2733                  // If mimeType was not found, we then set txt as the default extension
2734                  map *mtype = getMap (tmpI->content, "mimeType");
2735                  if (mtype != NULL)
2736                    {
2737                      if (strcasecmp (mtype->value, "text/xml") == 0)
2738                        ext = createMap ("extension", "xml");
2739                      else if (strcasecmp (mtype->value, "application/json")
2740                               == 0)
2741                        ext = createMap ("extension", "js");
2742                      else
2743                        if (strncmp
2744                            (mtype->value, "application/vnd.google-earth.kml",
2745                             32) == 0)
2746                        ext = createMap ("extension", "kml");
2747                      else if (strncmp (mtype->value, "image/", 6) == 0)
2748                        ext =
2749                          createMap ("extension",
2750                                     strstr (mtype->value, "/") + 1);
2751                      else
2752                        ext = createMap ("extension", "txt");
2753                    }
2754                  else
2755                    ext = createMap ("extension", "txt");
2756                  hasExt = false;
2757                }
2758              file_name =
2759                (char *)
2760                malloc ((strlen (s->name) + strlen (ext->value) +
2761                         strlen (tmpI->name) + 1024) * sizeof (char));
2762              int cpid0 = cpid + time (NULL);
2763              sprintf (file_name, "%s_%s_%i.%s", s->name, tmpI->name, cpid0,
2764                       ext->value);
2765              file_path =
2766                (char *)
2767                malloc ((strlen (tmp1->value) + strlen (file_name) +
2768                         2) * sizeof (char));
2769              sprintf (file_path, "%s/%s", tmp1->value, file_name);
2770              FILE *ofile = fopen (file_path, "wb");
2771              if (ofile == NULL)
2772                {
2773                  char tmpMsg[1024];
2774                  sprintf (tmpMsg,
2775                           _
2776                           ("Unable to create the file : \"%s\" for storing the %s final result."),
2777                           file_name, tmpI->name);
2778                  map *errormap = createMap ("text", tmpMsg);
2779                  addToMap (errormap, "code", "InternalError");
2780
2781                  printExceptionReportResponse (m, errormap,out);
2782                  freeMap (&errormap);
2783                  free (errormap);
2784                  free (file_name);
2785                  free (file_path);
2786                  return;
2787                }
2788              free (file_path);
2789              map *tmp2 = getMapFromMaps (m, "main", "tmpUrl");
2790              map *tmp3 = getMapFromMaps (m, "main", "serverAddress");
2791              char *file_url;
2792              if (strncasecmp (tmp2->value, "http://", 7) == 0 ||
2793                  strncasecmp (tmp2->value, "https://", 8) == 0)
2794                {
2795                  file_url =
2796                    (char *)
2797                    malloc ((strlen (tmp2->value) + strlen (file_name) +
2798                             2) * sizeof (char));
2799                  sprintf (file_url, "%s/%s", tmp2->value, file_name);
2800                }
2801              else
2802                {
2803                  file_url =
2804                    (char *)
2805                    malloc ((strlen (tmp3->value) + strlen (tmp2->value) +
2806                             strlen (file_name) + 3) * sizeof (char));
2807                  sprintf (file_url, "%s/%s/%s", tmp3->value, tmp2->value,
2808                           file_name);
2809                }
2810              addToMap (tmpI->content, "Reference", file_url);
2811              if (!hasExt)
2812                {
2813                  freeMap (&ext);
2814                  free (ext);
2815                }
2816              toto = getMap (tmpI->content, "value");
2817              if (strcasecmp (format, "BoundingBoxData") != 0)
2818                {
2819                  map *size = getMap (tmpI->content, "size");
2820                  if (size != NULL && toto != NULL)
2821                    fwrite (toto->value, 1,
2822                            atoi (size->value) * sizeof (char), ofile);
2823                  else if (toto != NULL && toto->value != NULL)
2824                    fwrite (toto->value, 1,
2825                            strlen (toto->value) * sizeof (char), ofile);
2826                }
2827              else
2828                {
2829                  printBoundingBoxDocument (m, tmpI, ofile);
2830                }
2831              free (format);
2832              fclose (ofile);
2833              free (file_name);
2834              free (file_url);
2835            }
2836#ifdef USE_MS
2837          else
2838            {
2839              if (testMap != NULL)
2840                {
2841                  setReferenceUrl (m, tmpI);
2842                }
2843            }
2844#endif
2845          tmpI = tmpI->next;
2846        }
2847      map *r_inputs = getMap (s->content, "serviceProvider");
2848#ifdef DEBUG
2849      fprintf (stderr, "SERVICE : %s\n", r_inputs->value);
2850      dumpMaps (m);
2851#endif
2852      printProcessResponse (m, request_inputs1, cpid,
2853                            s, r_inputs->value, res,
2854                            request_inputs, request_outputs,out);
2855    }
2856  else
2857    {
2858
2859      if (res == SERVICE_FAILED)
2860        {
2861
2862          map *errormap;
2863          map *lenv;
2864          lenv = getMapFromMaps (m, "lenv", "message");
2865          char *tmp0;
2866          if (lenv != NULL)
2867            {
2868              tmp0 =
2869                (char *)
2870                malloc ((strlen (lenv->value) +
2871                         strlen (_
2872                                 ("Unable to run the Service. The message returned back by the Service was the following: "))
2873                         + 1) * sizeof (char));
2874              sprintf (tmp0,
2875                       _
2876                       ("Unable to run the Service. The message returned back by the Service was the following: %s"),
2877                       lenv->value);
2878            }
2879          else
2880            {
2881              tmp0 =
2882                (char *)
2883                malloc ((strlen
2884                         (_
2885                          ("Unable to run the Service. No more information was returned back by the Service."))
2886                         + 1) * sizeof (char));
2887              sprintf (tmp0,
2888                       _
2889                       ("Unable to run the Service. No more information was returned back by the Service."));
2890            }
2891          errormap = createMap ("text", tmp0);
2892          free (tmp0);
2893          addToMap (errormap, "code", "InternalError");
2894          printExceptionReportResponse (m, errormap,out);
2895          freeMap (&errormap);
2896          free (errormap);
2897          return;
2898        }
2899      /**
2900       * We get the requested output or fallback to the first one if the
2901       * requested one is not present in the resulting outputs maps.
2902       */
2903
2904
2905      maps *tmpI = NULL;
2906      map *tmpIV = getMap (request_inputs1, "RawDataOutput");
2907      if (tmpIV != NULL)
2908        {
2909          tmpI = getMaps (request_outputs, tmpIV->value);
2910        }
2911      if (tmpI == NULL)
2912        tmpI = request_outputs;
2913      elements *e = getElements (s->outputs, tmpI->name);
2914      if (e != NULL && strcasecmp (e->format, "BoundingBoxData") == 0)
2915        {
2916          printBoundingBoxDocument (m, tmpI, NULL);
2917        }
2918      else
2919        {
2920          toto = getMap (tmpI->content, "value");
2921          if (toto == NULL)
2922            {
2923              char tmpMsg[1024];
2924              sprintf (tmpMsg,
2925                       _
2926                       ("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),
2927                       tmpI->name);
2928              map *errormap = createMap ("text", tmpMsg);
2929              addToMap (errormap, "code", "InvalidParameterValue");
2930              printExceptionReportResponse (m, errormap,out);
2931              freeMap (&errormap);
2932              free (errormap);
2933              return;
2934            }
2935          map *fname = getMapFromMaps (tmpI, tmpI->name, "filename");
2936          if (fname != NULL)
2937            FCGX_FPrintF(out,"Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2938            //printf ("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2939          map *rs = getMapFromMaps (tmpI, tmpI->name, "size");
2940          if (rs != NULL)
2941            FCGX_FPrintF(out,"Content-Length: %s\r\n", rs->value);
2942            //printf ("Content-Length: %s\r\n", rs->value);
2943          printHeaders (m,out);
2944          char mime[1024];
2945          map *mi = getMap (tmpI->content, "mimeType");
2946#ifdef DEBUG
2947          fprintf (stderr, "SERVICE OUTPUTS\n");
2948          dumpMaps (request_outputs);
2949          fprintf (stderr, "SERVICE OUTPUTS\n");
2950#endif
2951          map *en = getMap (tmpI->content, "encoding");
2952          if (mi != NULL && en != NULL)
2953            sprintf (mime,
2954                     "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2955                     mi->value, en->value);
2956          else if (mi != NULL)
2957            sprintf (mime,
2958                     "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2959                     mi->value);
2960          else
2961            sprintf (mime,
2962                     "Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2963          FCGX_FPrintF(out,"%s", mime);
2964
2965          //printf ("%s", mime);
2966          if (rs != NULL)
2967            FCGX_PutStr(toto->value,atoi(rs->value),out);
2968            //fwrite (toto->value, 1, atoi (rs->value), stdout);
2969          else
2970             FCGX_PutStr(toto->value,strlen (toto->value),out);
2971            //fwrite (toto->value, 1, strlen (toto->value), stdout);
2972
2973          FCGX_FFlush(out);
2974#ifdef DEBUG
2975          dumpMap (toto);
2976#endif
2977        }
2978    }
2979}
2980
2981char *
2982base64 (const char *input, int length)
2983{
2984  BIO *bmem, *b64;
2985  BUF_MEM *bptr;
2986
2987  b64 = BIO_new (BIO_f_base64 ());
2988  BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
2989  bmem = BIO_new (BIO_s_mem ());
2990  b64 = BIO_push (b64, bmem);
2991  BIO_write (b64, input, length + 1);
2992  BIO_flush (b64);
2993  BIO_get_mem_ptr (b64, &bptr);
2994
2995  char *buff = (char *) malloc ((bptr->length + 1) * sizeof (char));
2996  memcpy (buff, bptr->data, bptr->length);
2997  buff[bptr->length - 1] = 0;
2998
2999  BIO_free_all (b64);
3000
3001  return buff;
3002}
3003
3004char *
3005base64d (const char *input, int length, int *red)
3006{
3007  BIO *b64, *bmem;
3008
3009  char *buffer = (char *) malloc (length);
3010  if (buffer)
3011    {
3012      memset (buffer, 0, length);
3013      b64 = BIO_new (BIO_f_base64 ());
3014      if (b64)
3015        {
3016          bmem = BIO_new_mem_buf ((unsigned char *) input, length);
3017          bmem = BIO_push (b64, bmem);
3018          *red = BIO_read (bmem, buffer, length);
3019          buffer[length - 1] = 0;
3020          BIO_free_all (bmem);
3021        }
3022    }
3023  return buffer;
3024}
3025
3026void
3027ensureDecodedBase64 (maps ** in)
3028{
3029  maps *cursor = *in;
3030  while (cursor != NULL)
3031    {
3032      map *tmp = getMap (cursor->content, "encoding");
3033      if (tmp != NULL && strncasecmp (tmp->value, "base64", 6) == 0)
3034        {
3035          tmp = getMap (cursor->content, "value");
3036          addToMap (cursor->content, "base64_value", tmp->value);
3037          int size = 0;
3038          char *s = strdup (tmp->value);
3039          free (tmp->value);
3040          tmp->value = base64d (s, strlen (s), &size);
3041          free (s);
3042          char sizes[1024];
3043          sprintf (sizes, "%d", size);
3044          addToMap (cursor->content, "size", sizes);
3045        }
3046      cursor = cursor->next;
3047    }
3048}
3049
3050char *
3051addDefaultValues (maps ** out, elements * in, maps * m, int type)
3052{
3053  elements *tmpInputs = in;
3054  maps *out1 = *out;
3055  if (type == 1)
3056    {
3057      while (out1 != NULL)
3058        {
3059          if (getElements (in, out1->name) == NULL)
3060            return out1->name;
3061          out1 = out1->next;
3062        }
3063      out1 = *out;
3064    }
3065  while (tmpInputs != NULL)
3066    {
3067      maps *tmpMaps = getMaps (out1, tmpInputs->name);
3068      if (tmpMaps == NULL)
3069        {
3070          maps *tmpMaps2 = (maps *) malloc (MAPS_SIZE);
3071          tmpMaps2->name = strdup (tmpInputs->name);
3072          tmpMaps2->content = NULL;
3073          tmpMaps2->next = NULL;
3074
3075          if (type == 0)
3076            {
3077              map *tmpMapMinO = getMap (tmpInputs->content, "minOccurs");
3078              if (tmpMapMinO != NULL)
3079                {
3080                  if (atoi (tmpMapMinO->value) >= 1)
3081                    {
3082                      freeMaps (&tmpMaps2);
3083                      free (tmpMaps2);
3084                      return tmpInputs->name;
3085                    }
3086                  else
3087                    {
3088                      if (tmpMaps2->content == NULL)
3089                        tmpMaps2->content =
3090                          createMap ("minOccurs", tmpMapMinO->value);
3091                      else
3092                        addToMap (tmpMaps2->content, "minOccurs",
3093                                  tmpMapMinO->value);
3094                    }
3095                }
3096              map *tmpMaxO = getMap (tmpInputs->content, "maxOccurs");
3097              if (tmpMaxO != NULL)
3098                {
3099                  if (tmpMaps2->content == NULL)
3100                    tmpMaps2->content =
3101                      createMap ("maxOccurs", tmpMaxO->value);
3102                  else
3103                    addToMap (tmpMaps2->content, "maxOccurs", tmpMaxO->value);
3104                }
3105              map *tmpMaxMB = getMap (tmpInputs->content, "maximumMegabytes");
3106              if (tmpMaxMB != NULL)
3107                {
3108                  if (tmpMaps2->content == NULL)
3109                    tmpMaps2->content =
3110                      createMap ("maximumMegabytes", tmpMaxMB->value);
3111                  else
3112                    addToMap (tmpMaps2->content, "maximumMegabytes",
3113                              tmpMaxMB->value);
3114                }
3115            }
3116
3117          iotype *tmpIoType = tmpInputs->defaults;
3118          if (tmpIoType != NULL)
3119            {
3120              map *tmpm = tmpIoType->content;
3121              while (tmpm != NULL)
3122                {
3123                  if (tmpMaps2->content == NULL)
3124                    tmpMaps2->content = createMap (tmpm->name, tmpm->value);
3125                  else
3126                    addToMap (tmpMaps2->content, tmpm->name, tmpm->value);
3127                  tmpm = tmpm->next;
3128                }
3129            }
3130          addToMap (tmpMaps2->content, "inRequest", "false");
3131          if (type == 0)
3132            {
3133              map *tmpMap = getMap (tmpMaps2->content, "value");
3134              if (tmpMap == NULL)
3135                addToMap (tmpMaps2->content, "value", "NULL");
3136            }
3137          if (out1 == NULL)
3138            {
3139              *out = dupMaps (&tmpMaps2);
3140              out1 = *out;
3141            }
3142          else
3143            addMapsToMaps (&out1, tmpMaps2);
3144          freeMap (&tmpMaps2->content);
3145          free (tmpMaps2->content);
3146          tmpMaps2->content = NULL;
3147          freeMaps (&tmpMaps2);
3148          free (tmpMaps2);
3149          tmpMaps2 = NULL;
3150        }
3151      else
3152        {
3153          iotype *tmpIoType =
3154            getIoTypeFromElement (tmpInputs, tmpInputs->name,
3155                                  tmpMaps->content);
3156          if (type == 0)
3157            {
3158        /**
3159         * In case of an Input maps, then add the minOccurs and maxOccurs to the
3160         * content map.
3161         */
3162              map *tmpMap1 = getMap (tmpInputs->content, "minOccurs");
3163              if (tmpMap1 != NULL)
3164                {
3165                  if (tmpMaps->content == NULL)
3166                    tmpMaps->content =
3167                      createMap ("minOccurs", tmpMap1->value);
3168                  else
3169                    addToMap (tmpMaps->content, "minOccurs", tmpMap1->value);
3170                }
3171              map *tmpMaxO = getMap (tmpInputs->content, "maxOccurs");
3172              if (tmpMaxO != NULL)
3173                {
3174                  if (tmpMaps->content == NULL)
3175                    tmpMaps->content =
3176                      createMap ("maxOccurs", tmpMaxO->value);
3177                  else
3178                    addToMap (tmpMaps->content, "maxOccurs", tmpMaxO->value);
3179                }
3180              map *tmpMaxMB = getMap (tmpInputs->content, "maximumMegabytes");
3181              if (tmpMaxMB != NULL)
3182                {
3183                  if (tmpMaps->content == NULL)
3184                    tmpMaps->content =
3185                      createMap ("maximumMegabytes", tmpMaxMB->value);
3186                  else
3187                    addToMap (tmpMaps->content, "maximumMegabytes",
3188                              tmpMaxMB->value);
3189                }
3190        /**
3191         * Parsing BoundingBoxData, fill the following map and then add it to
3192         * the content map of the Input maps:
3193         * lowerCorner, upperCorner, srs and dimensions
3194         * cf. parseBoundingBox
3195         */
3196              if (strcasecmp (tmpInputs->format, "BoundingBoxData") == 0)
3197                {
3198                  maps *tmpI = getMaps (*out, tmpInputs->name);
3199                  if (tmpI != NULL)
3200                    {
3201                      map *tmpV = getMap (tmpI->content, "value");
3202                      if (tmpV != NULL)
3203                        {
3204                          char *tmpVS = strdup (tmpV->value);
3205                          map *tmp = parseBoundingBox (tmpVS);
3206                          free (tmpVS);
3207                          map *tmpC = tmp;
3208                          while (tmpC != NULL)
3209                            {
3210                              addToMap (tmpMaps->content, tmpC->name,
3211                                        tmpC->value);
3212                              tmpC = tmpC->next;
3213                            }
3214                          freeMap (&tmp);
3215                          free (tmp);
3216                        }
3217                    }
3218                }
3219            }
3220
3221          if (tmpIoType != NULL)
3222            {
3223              map *tmpContent = tmpIoType->content;
3224              map *cval = NULL;
3225              int hasPassed = -1;
3226              while (tmpContent != NULL)
3227                {
3228                  if ((cval =
3229                       getMap (tmpMaps->content, tmpContent->name)) == NULL)
3230                    {
3231#ifdef DEBUG
3232                      fprintf (stderr, "addDefaultValues %s => %s\n",
3233                               tmpContent->name, tmpContent->value);
3234#endif
3235                      if (tmpMaps->content == NULL)
3236                        tmpMaps->content =
3237                          createMap (tmpContent->name, tmpContent->value);
3238                      else
3239                        addToMap (tmpMaps->content, tmpContent->name,
3240                                  tmpContent->value);
3241
3242                      if (hasPassed < 0 && type == 0
3243                          && getMap (tmpMaps->content, "isArray") != NULL)
3244                        {
3245                          map *length = getMap (tmpMaps->content, "length");
3246                          int i;
3247                          char *tcn = strdup (tmpContent->name);
3248                          for (i = 1; i < atoi (length->value); i++)
3249                            {
3250#ifdef DEBUG
3251                              dumpMap (tmpMaps->content);
3252                              fprintf (stderr,
3253                                       "addDefaultValues %s_%d => %s\n", tcn,
3254                                       i, tmpContent->value);
3255#endif
3256                              int len = strlen ((char *) tcn);
3257                              char *tmp1 =
3258                                (char *) malloc ((len + 10) * sizeof (char));
3259                              sprintf (tmp1, "%s_%d", tcn, i);
3260#ifdef DEBUG
3261                              fprintf (stderr, "addDefaultValues %s => %s\n",
3262                                       tmp1, tmpContent->value);
3263#endif
3264                              addToMap (tmpMaps->content, tmp1,
3265                                        tmpContent->value);
3266                              free (tmp1);
3267                              hasPassed = 1;
3268                            }
3269                          free (tcn);
3270                        }
3271                    }
3272                  tmpContent = tmpContent->next;
3273                }
3274#ifdef USE_MS
3275        /**
3276         * check for useMapServer presence
3277         */
3278              map *tmpCheck = getMap (tmpIoType->content, "useMapServer");
3279              if (tmpCheck != NULL)
3280                {
3281                  // Get the default value
3282                  tmpIoType =
3283                    getIoTypeFromElement (tmpInputs, tmpInputs->name, NULL);
3284                  tmpCheck = getMap (tmpMaps->content, "mimeType");
3285                  addToMap (tmpMaps->content, "requestedMimeType",
3286                            tmpCheck->value);
3287                  map *cursor = tmpIoType->content;
3288                  while (cursor != NULL)
3289                    {
3290                      addToMap (tmpMaps->content, cursor->name,
3291                                cursor->value);
3292                      cursor = cursor->next;
3293                    }
3294
3295                  cursor = tmpInputs->content;
3296                  while (cursor != NULL)
3297                    {
3298                      if (strcasecmp (cursor->name, "Title") == 0 ||
3299                          strcasecmp (cursor->name, "Abstract") == 0)
3300                        addToMap (tmpMaps->content, cursor->name,
3301                                  cursor->value);
3302                      cursor = cursor->next;
3303                    }
3304                }
3305#endif
3306            }
3307          if (tmpMaps->content == NULL)
3308            tmpMaps->content = createMap ("inRequest", "true");
3309          else
3310            addToMap (tmpMaps->content, "inRequest", "true");
3311
3312        }
3313      tmpInputs = tmpInputs->next;
3314    }
3315  return "";
3316}
3317
3318/**
3319 * parseBoundingBox : parse a BoundingBox string
3320 *
3321 * OGC 06-121r3 : 10.2 Bounding box
3322 *
3323 * value is provided as : lowerCorner,upperCorner,crs,dimension
3324 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
3325 *
3326 * Need to create a map to store boundingbox informations :
3327 *  - lowerCorner : double,double (minimum within this bounding box)
3328 *  - upperCorner : double,double (maximum within this bounding box)
3329 *  - crs : URI (Reference to definition of the CRS)
3330 *  - dimensions : int
3331 *
3332 * Note : support only 2D bounding box.
3333 */
3334map *
3335parseBoundingBox (const char *value)
3336{
3337  map *res = NULL;
3338  if (value != NULL)
3339    {
3340      char *cv, *cvp;
3341      cv = strtok_r ((char *) value, ",", &cvp);
3342      int cnt = 0;
3343      int icnt = 0;
3344      char *currentValue = NULL;
3345      while (cv)
3346        {
3347          if (cnt < 2)
3348            if (currentValue != NULL)
3349              {
3350                char *finalValue =
3351                  (char *) malloc ((strlen (currentValue) + strlen (cv) + 1) *
3352                                   sizeof (char));
3353                sprintf (finalValue, "%s%s", currentValue, cv);
3354                switch (cnt)
3355                  {
3356                  case 0:
3357                    res = createMap ("lowerCorner", finalValue);
3358                    break;
3359                  case 1:
3360                    addToMap (res, "upperCorner", finalValue);
3361                    icnt = -1;
3362                    break;
3363                  }
3364                cnt++;
3365                free (currentValue);
3366                currentValue = NULL;
3367                free (finalValue);
3368              }
3369            else
3370              {
3371                currentValue =
3372                  (char *) malloc ((strlen (cv) + 2) * sizeof (char));
3373                sprintf (currentValue, "%s ", cv);
3374              }
3375          else if (cnt == 2)
3376            {
3377              addToMap (res, "crs", cv);
3378              cnt++;
3379            }
3380          else
3381            addToMap (res, "dimensions", cv);
3382          icnt++;
3383          cv = strtok_r (NULL, ",", &cvp);
3384        }
3385    }
3386  return res;
3387}
3388
3389/**
3390 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
3391 * wps:BoundingBoxData). Set crs and dimensions attributes, add
3392 * Lower/UpperCorner nodes to a pre-existing XML node.
3393 */
3394void
3395printBoundingBox (xmlNsPtr ns_ows, xmlNodePtr n, map * boundingbox)
3396{
3397
3398  xmlNodePtr lw = NULL, uc = NULL;
3399
3400  map *tmp = getMap (boundingbox, "value");
3401
3402  tmp = getMap (boundingbox, "lowerCorner");
3403  if (tmp != NULL)
3404    {
3405      lw = xmlNewNode (ns_ows, BAD_CAST "LowerCorner");
3406      xmlAddChild (lw, xmlNewText (BAD_CAST tmp->value));
3407    }
3408
3409  tmp = getMap (boundingbox, "upperCorner");
3410  if (tmp != NULL)
3411    {
3412      uc = xmlNewNode (ns_ows, BAD_CAST "UpperCorner");
3413      xmlAddChild (uc, xmlNewText (BAD_CAST tmp->value));
3414    }
3415
3416  tmp = getMap (boundingbox, "crs");
3417  if (tmp != NULL)
3418    xmlNewProp (n, BAD_CAST "crs", BAD_CAST tmp->value);
3419
3420  tmp = getMap (boundingbox, "dimensions");
3421  if (tmp != NULL)
3422    xmlNewProp (n, BAD_CAST "dimensions", BAD_CAST tmp->value);
3423
3424  xmlAddChild (n, lw);
3425  xmlAddChild (n, uc);
3426
3427}
3428
3429void
3430printBoundingBoxDocument (maps * m, maps * boundingbox, FILE * file)
3431{
3432  //if (file == NULL)
3433   // rewind (stdout);
3434  xmlNodePtr n;
3435  xmlDocPtr doc;
3436  xmlNsPtr ns_ows, ns_xsi;
3437  xmlChar *xmlbuff;
3438  int buffersize;
3439  char *encoding = getEncoding (m);
3440  map *tmp;
3441  if (file == NULL)
3442    {
3443      int pid = 0;
3444      tmp = getMapFromMaps (m, "lenv", "sid");
3445      if (tmp != NULL)
3446        pid = atoi (tmp->value);
3447      if (pid == getpid ())
3448        {
3449          printf
3450            ("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",
3451             encoding);
3452        }
3453      //fflush (stdout);
3454    }
3455
3456  doc = xmlNewDoc (BAD_CAST "1.0");
3457  int owsId = zooXmlAddNs (NULL, "http://www.opengis.net/ows/1.1", "ows");
3458  ns_ows = usedNs[owsId];
3459  n = xmlNewNode (ns_ows, BAD_CAST "BoundingBox");
3460  xmlNewNs (n, BAD_CAST "http://www.opengis.net/ows/1.1", BAD_CAST "ows");
3461  int xsiId =
3462    zooXmlAddNs (n, "http://www.w3.org/2001/XMLSchema-instance", "xsi");
3463  ns_xsi = usedNs[xsiId];
3464  xmlNewNsProp (n, ns_xsi, BAD_CAST "schemaLocation",
3465                BAD_CAST
3466                "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
3467  map *tmp1 = getMap (boundingbox->content, "value");
3468  tmp = parseBoundingBox (tmp1->value);
3469  printBoundingBox (ns_ows, n, tmp);
3470  xmlDocSetRootElement (doc, n);
3471
3472  xmlDocDumpFormatMemoryEnc (doc, &xmlbuff, &buffersize, encoding, 1);
3473  if (file == NULL)
3474    printf ("%s", xmlbuff);
3475  else
3476    {
3477      fprintf (file, "%s", xmlbuff);
3478    }
3479
3480  if (tmp != NULL)
3481    {
3482      freeMap (&tmp);
3483      free (tmp);
3484    }
3485  xmlFree (xmlbuff);
3486  xmlFreeDoc (doc);
3487  xmlCleanupParser ();
3488  zooXmlCleanupNs ();
3489
3490}
3491
3492
3493char *
3494getMd5 (char *url)
3495{
3496  EVP_MD_CTX md5ctx;
3497  char *fresult = (char *) malloc ((EVP_MAX_MD_SIZE + 1) * sizeof (char));
3498  unsigned char result[EVP_MAX_MD_SIZE];
3499  unsigned int len;
3500  EVP_DigestInit (&md5ctx, EVP_md5 ());
3501  EVP_DigestUpdate (&md5ctx, url, strlen (url));
3502  EVP_DigestFinal_ex (&md5ctx, result, &len);
3503  EVP_MD_CTX_cleanup (&md5ctx);
3504  int i;
3505  for (i = 0; i < len; i++)
3506    {
3507      if (i > 0)
3508        {
3509          char *tmp = strdup (fresult);
3510          sprintf (fresult, "%s%02x", tmp, result[i]);
3511          free (tmp);
3512        }
3513      else
3514        sprintf (fresult, "%02x", result[i]);
3515    }
3516  return fresult;
3517}
3518
3519/**
3520 * Cache a file for a given request
3521 */
3522void
3523addToCache (maps * conf, char *request, char *content, char *mimeType,
3524            int length)
3525{
3526  map *tmp = getMapFromMaps (conf, "main", "cacheDir");
3527  if (tmp != NULL)
3528    {
3529      char *md5str = getMd5 (request);
3530      char *fname =
3531        (char *) malloc (sizeof (char) *
3532                         (strlen (tmp->value) + strlen (md5str) + 6));
3533      sprintf (fname, "%s/%s.zca", tmp->value, md5str);
3534#ifdef DEBUG
3535      fprintf (stderr, "Cache list : %s\n", fname);
3536      fflush (stderr);
3537#endif
3538      FILE *fo = fopen (fname, "w+");
3539      if (fo == NULL)
3540        {
3541          fprintf (stderr, "Failed to open %s for writting: %s\n", fname,
3542                   strerror (errno));
3543          return;
3544        }
3545      fwrite (content, sizeof (char), length, fo);
3546      fclose (fo);
3547
3548      sprintf (fname, "%s/%s.zcm", tmp->value, md5str);
3549      fo = fopen (fname, "w+");
3550#ifdef DEBUG
3551      fprintf (stderr, "MIMETYPE: %s\n", mimeType);
3552#endif
3553      fwrite (mimeType, sizeof (char), strlen (mimeType), fo);
3554      fclose (fo);
3555
3556      free (md5str);
3557      free (fname);
3558    }
3559}
3560
3561char *
3562isInCache (maps * conf, char *request)
3563{
3564  map *tmpM = getMapFromMaps (conf, "main", "cacheDir");
3565  if (tmpM != NULL)
3566    {
3567      char *md5str = getMd5 (request);
3568#ifdef DEBUG
3569      fprintf (stderr, "MD5STR : (%s)\n\n", md5str);
3570#endif
3571      char *fname =
3572        (char *) malloc (sizeof (char) *
3573                         (strlen (tmpM->value) + strlen (md5str) + 6));
3574      sprintf (fname, "%s/%s.zca", tmpM->value, md5str);
3575      struct stat f_status;
3576      int s = stat (fname, &f_status);
3577      if (s == 0 && f_status.st_size > 0)
3578        {
3579          free (md5str);
3580          return fname;
3581        }
3582      free (md5str);
3583      free (fname);
3584    }
3585  return NULL;
3586}
3587
3588int
3589runHttpRequests (maps ** m, maps ** inputs, HINTERNET * hInternet)
3590{
3591  if (hInternet->nb > 0)
3592    {
3593      processDownloads (hInternet);
3594      maps *content = *inputs;
3595      map *tmp1;
3596      int index = 0;
3597      while (content != NULL)
3598        {
3599          if ((tmp1 = getMap (content->content, "href")) ||
3600              (tmp1 = getMap (content->content, "xlink:href")))
3601            {
3602              if (getMap (content->content, "isCached") == NULL)
3603                {
3604                  char *fcontent;
3605                  char *mimeType = NULL;
3606                  int fsize = 0;
3607
3608                  fcontent =
3609                    (char *) malloc ((hInternet->ihandle[index].nDataLen + 1)
3610                                     * sizeof (char));
3611                  if (fcontent == NULL)
3612                    {
3613                      return errorException (*m,
3614                                             _("Unable to allocate memory."),
3615                                             "InternalError", NULL,NULL);
3616                    }
3617                  size_t dwRead;
3618                  InternetReadFile (hInternet->ihandle[index],
3619                                    (LPVOID) fcontent,
3620                                    hInternet->ihandle[index].nDataLen,
3621                                    &dwRead);
3622                  fcontent[hInternet->ihandle[index].nDataLen] = 0;
3623                  fsize = hInternet->ihandle[index].nDataLen;
3624                  mimeType =
3625                    strdup ((char *) hInternet->ihandle[index].mimeType);
3626
3627                  map *tmpMap = getMapOrFill (&content->content, "value", "");
3628                  free (tmpMap->value);
3629                  tmpMap->value =
3630                    (char *) malloc ((fsize + 1) * sizeof (char));
3631                  if (tmpMap->value == NULL)
3632                    {
3633                      return errorException (*m,
3634                                             _("Unable to allocate memory."),
3635                                             "InternalError", NULL,NULL);
3636                    }
3637                  memcpy (tmpMap->value, fcontent,
3638                          (fsize + 1) * sizeof (char));
3639
3640                  char ltmp1[256];
3641                  sprintf (ltmp1, "%d", fsize);
3642                  addToMap (content->content, "size", ltmp1);
3643                  addToCache (*m, tmp1->value, fcontent, mimeType, fsize);
3644                  free (fcontent);
3645                  free (mimeType);
3646                }
3647              index++;
3648            }
3649          content = content->next;
3650        }
3651    }
3652}
3653
3654/**
3655 * loadRemoteFile:
3656 * Try to load file from cache or download a remote file if not in cache
3657 */
3658int
3659loadRemoteFile (maps ** m, map ** content, HINTERNET * hInternet, char *url)
3660{
3661  char *fcontent;
3662  char *cached = isInCache (*m, url);
3663  char *mimeType = NULL;
3664  int fsize = 0;
3665  if (cached != NULL)
3666    {
3667      struct stat f_status;
3668      int s = stat (cached, &f_status);
3669      if (s == 0)
3670        {
3671          fcontent = (char *) malloc (sizeof (char) * (f_status.st_size + 1));
3672          FILE *f = fopen (cached, "rb");
3673          fread (fcontent, f_status.st_size, 1, f);
3674          fsize = f_status.st_size;
3675          fcontent[fsize] = 0;
3676          fclose (f);
3677        }
3678      cached[strlen (cached) - 1] = 'm';
3679      s = stat (cached, &f_status);
3680      if (s == 0)
3681        {
3682          mimeType = (char *) malloc (sizeof (char) * (f_status.st_size + 1));
3683          FILE *f = fopen (cached, "rb");
3684          fread (mimeType, f_status.st_size, 1, f);
3685          mimeType[f_status.st_size] = 0;
3686          fclose (f);
3687        }
3688    }
3689  else
3690    {
3691      hInternet->waitingRequests[hInternet->nb] = strdup (url);
3692      InternetOpenUrl (hInternet, hInternet->waitingRequests[hInternet->nb],
3693                       NULL, 0, INTERNET_FLAG_NO_CACHE_WRITE, 0);
3694      return 0;
3695    }
3696  if (fsize == 0)
3697    {
3698     
3699      return errorException (*m, _("Unable to download the file."),
3700                             "InternalError", NULL,NULL);
3701    }
3702  if (mimeType != NULL)
3703    {
3704      addToMap (*content, "fmimeType", mimeType);
3705    }
3706
3707  map *tmpMap = getMapOrFill (content, "value", "");
3708
3709  free (tmpMap->value);
3710  tmpMap->value = (char *) malloc ((fsize + 1) * sizeof (char));
3711  if (tmpMap->value == NULL){
3712
3713    return errorException (*m, _("Unable to allocate memory."),
3714                           "InternalError", NULL,NULL);
3715  }
3716  memcpy (tmpMap->value, fcontent, (fsize + 1) * sizeof (char));
3717
3718  char ltmp1[256];
3719  sprintf (ltmp1, "%d", fsize);
3720  addToMap (*content, "size", ltmp1);
3721  if (cached == NULL)
3722    addToCache (*m, url, fcontent, mimeType, fsize);
3723  else
3724    addToMap (*content, "isCached", "true");
3725  free (fcontent);
3726  free (mimeType);
3727  free (cached);
3728  return 0;
3729}
3730
3731int
3732errorException (maps * m, const char *message, const char *errorcode,
3733                const char *locator,FCGX_Stream * out)
3734{
3735  map *errormap = createMap ("text", message);
3736  addToMap (errormap, "code", errorcode);
3737  if (locator != NULL)
3738    addToMap (errormap, "locator", locator);
3739  else
3740    addToMap (errormap, "locator", "NULL");
3741  printExceptionReportResponse (m, errormap,out);
3742  freeMap (&errormap);
3743  free (errormap);
3744  return -1;
3745}
3746
3747
3748char *
3749readVSIFile (maps * conf, const char *dataSource)
3750{
3751  VSILFILE *fichier = VSIFOpenL (dataSource, "rb");
3752  VSIStatBufL file_status;
3753  VSIStatL (dataSource, &file_status);
3754  if (fichier == NULL)
3755    {
3756      char tmp[1024];
3757      sprintf (tmp,
3758               "Failed to open file %s for reading purpose. File seems empty %d.",
3759               dataSource, file_status.st_size);
3760      setMapInMaps (conf, "lenv", "message", tmp);
3761      return NULL;
3762    }
3763  char *res1 = (char *) malloc (file_status.st_size * sizeof (char));
3764  VSIFReadL (res1, 1, file_status.st_size * sizeof (char), fichier);
3765  res1[file_status.st_size - 1] = 0;
3766  VSIFCloseL (fichier);
3767  VSIUnlink (dataSource);
3768  return res1;
3769}
3770
3771void
3772parseIdentifier (maps * conf, char *conf_dir, char *identifier, char *buffer)
3773{
3774  char *saveptr1;
3775  char *tmps1 = strtok_r (identifier, ".", &saveptr1);
3776  int level = 0;
3777  char key[25];
3778  char levels[18];
3779  while (tmps1 != NULL)
3780    {
3781      char *test = zStrdup (tmps1);
3782      char *tmps2 = (char *) malloc ((strlen (test) + 2) * sizeof (char));
3783      sprintf (key, "sprefix_%d", level);
3784      sprintf (tmps2, "%s.", test);
3785      sprintf (levels, "%d", level);
3786      setMapInMaps (conf, "lenv", "level", levels);
3787      setMapInMaps (conf, "lenv", key, tmps2);
3788      free (tmps2);
3789      free (test);
3790      level++;
3791      tmps1 = strtok_r (NULL, ".", &saveptr1);
3792    }
3793  int i = 0;
3794  sprintf (buffer, "%s", conf_dir);
3795  for (i = 0; i < level; i++)
3796    {
3797      char *tmp0 = zStrdup (buffer);
3798      sprintf (key, "sprefix_%d", i);
3799      map *tmp00 = getMapFromMaps (conf, "lenv", key);
3800      if (tmp00 != NULL)
3801        sprintf (buffer, "%s/%s", tmp0, tmp00->value);
3802      free (tmp0);
3803      buffer[strlen (buffer) - 1] = 0;
3804      if (i + 1 < level)
3805        {
3806          map *tmpMap = getMapFromMaps (conf, "lenv", "metapath");
3807          if (tmpMap == NULL || strlen (tmpMap->value) == 0)
3808            {
3809              char *tmp01 = zStrdup (tmp00->value);
3810              tmp01[strlen (tmp01) - 1] = 0;
3811              setMapInMaps (conf, "lenv", "metapath", tmp01);
3812              free (tmp01);
3813              tmp01 = NULL;
3814            }
3815          else
3816            {
3817              if (tmp00 != NULL && tmpMap != NULL)
3818                {
3819                  char *tmp00s = zStrdup (tmp00->value);
3820                  tmp00s[strlen (tmp00s) - 1] = 0;
3821                  char *value =
3822                    (char *)
3823                    malloc ((strlen (tmp00s) + strlen (tmpMap->value) +
3824                             2) * sizeof (char));
3825                  sprintf (value, "%s/%s", tmpMap->value, tmp00s);
3826                  setMapInMaps (conf, "lenv", "metapath", value);
3827                  free (value);
3828                  free (tmp00s);
3829                  value = NULL;
3830                }
3831            }
3832        }
3833      else
3834        {
3835          char *tmp01 = zStrdup (tmp00->value);
3836          tmp01[strlen (tmp01) - 1] = 0;
3837          setMapInMaps (conf, "lenv", "Identifier", tmp01);
3838          free (tmp01);
3839        }
3840    }
3841  char *tmp0 = zStrdup (buffer);
3842  sprintf (buffer, "%s.zcfg", tmp0);
3843  free (tmp0);
3844}
3845
3846int
3847updateStatus (maps * conf, const int percentCompleted, const char *message)
3848{
3849  char tmp[4];
3850  snprintf (tmp, 4, "%d", percentCompleted);
3851  setMapInMaps (conf, "lenv", "status", tmp);
3852  setMapInMaps (conf, "lenv", "message", message);
3853  return _updateStatus (conf);
3854}
3855
3856char *
3857getInputValue (maps * inputs, const char *parameterName,
3858               size_t * numberOfBytes)
3859{
3860  map *res = getMapFromMaps (inputs, parameterName, "value");
3861  if (res != NULL)
3862    {
3863      map *size = getMapFromMaps (inputs, parameterName, "size");
3864      if (size != NULL)
3865        {
3866          *numberOfBytes = (size_t) atoi (size->value);
3867          return res->value;
3868        }
3869      else
3870        {
3871          *numberOfBytes = strlen (res->value);
3872          return res->value;
3873        }
3874    }
3875  return NULL;
3876}
3877
3878int
3879setOutputValue (maps * outputs, const char *parameterName, char *data,
3880                size_t numberOfBytes)
3881{
3882  if (numberOfBytes == -1)
3883    {
3884      setMapInMaps (outputs, parameterName, "value", data);
3885    }
3886  else
3887    {
3888      char size[1024];
3889      map *tmp = getMapFromMaps (outputs, parameterName, "value");
3890      free (tmp->value);
3891      tmp->value = (char *) malloc ((numberOfBytes + 1) * sizeof (char));
3892      memcpy (tmp->value, data, numberOfBytes);
3893      sprintf (size, "%lu", numberOfBytes);
3894      setMapInMaps (outputs, parameterName, "size", size);
3895    }
3896  return 0;
3897}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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