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

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

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png