source: trunk/zoo-project/zoo-kernel/service_internal.c @ 465

Last change on this file since 465 was 465, checked in by djay, 10 years ago

Add the optional YAML ZCFG support #4 and the zcfg2yaml converter. Return error messages that enable the service provider to quickly identify the root cause of errors due to configuration file syntax #90. Fix logic in addMapToMap #91. Enable multiple range definition using default and supported blocks. Add the lastest revision number in version.h (available from Python ZOO-API as zoo.VERSION).

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 80.2 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2013 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal.h"
26#ifdef USE_MS
27#include "service_internal_ms.h"
28#endif
29
30#ifndef TRUE
31#define TRUE 1
32#endif
33#ifndef FALSE
34#define FALSE -1
35#endif
36
37int readServiceFile(maps* conf, char* file,service** service,char *name){
38  int t=getServiceFromFile(conf,file,service);
39#ifdef YAML
40  if(t<0){
41    t=getServiceFromYAML(conf,file,service,name);
42  }
43#endif
44  return t;
45}
46
47void printHeaders(maps* m){
48  maps *_tmp=getMaps(m,"headers");
49  if(_tmp!=NULL){
50    map* _tmp1=_tmp->content;
51    while(_tmp1!=NULL){
52      printf("%s: %s\r\n",_tmp1->name,_tmp1->value);
53      _tmp1=_tmp1->next;
54    }
55  }
56}
57
58void addLangAttr(xmlNodePtr n,maps *m){
59  map *tmpLmap=getMapFromMaps(m,"main","language");
60  if(tmpLmap!=NULL)
61    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST tmpLmap->value);
62  else
63    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST "en-US");
64}
65
66/* Converts a hex character to its integer value */
67char from_hex(char ch) {
68  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
69}
70
71/* Converts an integer value to its hex character*/
72char to_hex(char code) {
73  static char hex[] = "0123456789abcdef";
74  return hex[code & 15];
75}
76
77#ifdef WIN32
78
79#include <windows.h>
80#include <stdio.h>
81#include <conio.h>
82#include <tchar.h>
83
84#define SHMEMSIZE 4096
85
86static LPVOID lpvMemG = NULL;      // pointer to shared memory
87static HANDLE hMapObjectG = NULL;  // handle to file mapping
88
89void updateStatus(maps *conf){
90  LPWSTR lpszTmp;
91  BOOL fInit;
92  char *final_string=NULL;
93  char *s=NULL;
94  map *tmpMap1;
95  map *tmpMap=getMapFromMaps(conf,"lenv","sid");
96  if(hMapObjectG==NULL)
97    hMapObjectG = CreateFileMapping( 
98                                    INVALID_HANDLE_VALUE,   // use paging file
99                                    NULL,                   // default security attributes
100                                    PAGE_READWRITE,         // read/write access
101                                    0,                      // size: high 32-bits
102                                    SHMEMSIZE,              // size: low 32-bits
103                                    TEXT(tmpMap->value));   // name of map object
104  if (hMapObjectG == NULL){
105    fprintf(stderr,"Unable to create share memory segment %s !! \n",tmpMap->value);
106    return ;
107  }
108  fInit = (GetLastError() != ERROR_ALREADY_EXISTS); 
109  if(lpvMemG==NULL)
110    lpvMemG = MapViewOfFile( 
111                            hMapObjectG,     // object to map view of
112                            FILE_MAP_WRITE, // read/write access
113                            0,              // high offset:  map from
114                            0,              // low offset:   beginning
115                            0);             // default: map entire file
116  if (lpvMemG == NULL){
117    fprintf(stderr,"Unable to create or access the shared memory segment %s !! \n",tmpMap->value);
118    return ;
119  } 
120  memset(lpvMemG, '\0', SHMEMSIZE);
121  tmpMap=getMapFromMaps(conf,"lenv","status");
122  tmpMap1=NULL;
123  tmpMap1=getMapFromMaps(conf,"lenv","message");
124  lpszTmp = (LPWSTR) lpvMemG;
125  final_string=(char*)malloc((strlen(tmpMap1->value)+strlen(tmpMap->value)+2)*sizeof(char));
126  sprintf(final_string,"%s|%s",tmpMap->value,tmpMap1->value);
127  for(s=final_string;*s!='\0';*s++){
128    *lpszTmp++ = *s;
129  }
130  *lpszTmp++ = '\0';
131  free(final_string);
132}
133
134char* getStatus(int pid){
135  char lpszBuf[SHMEMSIZE];
136  int i=0;
137  LPWSTR lpszTmp=NULL;
138  LPVOID lpvMem = NULL;
139  HANDLE hMapObject = NULL;
140  BOOL fIgnore,fInit;
141  char tmp[100];
142  sprintf(tmp,"%i",pid);
143  if(hMapObject==NULL)
144    hMapObject = CreateFileMapping( 
145                                   INVALID_HANDLE_VALUE,   // use paging file
146                                   NULL,                   // default security attributes
147                                   PAGE_READWRITE,         // read/write access
148                                   0,                      // size: high 32-bits
149                                   4096,                   // size: low 32-bits
150                                   TEXT(tmp));   // name of map object
151  if (hMapObject == NULL) 
152    return FALSE;
153  if((GetLastError() != ERROR_ALREADY_EXISTS)){
154    fIgnore = UnmapViewOfFile(lpvMem); 
155    fIgnore = CloseHandle(hMapObject);
156    return "-1";
157  }
158  fInit=TRUE;
159  if(lpvMem==NULL)
160    lpvMem = MapViewOfFile( 
161                           hMapObject,     // object to map view of
162                           FILE_MAP_READ,  // read/write access
163                           0,              // high offset:  map from
164                           0,              // low offset:   beginning
165                           0);             // default: map entire file
166  if (lpvMem == NULL) 
167    return "-1"; 
168  lpszTmp = (LPWSTR) lpvMem;
169  while (*lpszTmp){
170    lpszBuf[i] = (char)*lpszTmp;
171    *lpszTmp++; 
172    lpszBuf[i+1] = '\0'; 
173    i++;
174  }
175  fprintf(stderr,"READING STRING S %s\n",lpszBuf);
176  return (char*)lpszBuf;
177}
178
179void unhandleStatus(maps *conf){
180  BOOL fIgnore;
181  fIgnore = UnmapViewOfFile(lpvMemG); 
182  fIgnore = CloseHandle(hMapObjectG);
183}
184#else
185
186void unhandleStatus(maps *conf){
187  int shmid,i;
188  key_t key;
189  void *shm;
190  struct shmid_ds shmids;
191  char *s,*s1;
192  map *tmpMap=getMapFromMaps(conf,"lenv","sid");
193  if(tmpMap!=NULL){
194    key=atoi(tmpMap->value);
195    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
196#ifdef DEBUG
197      fprintf(stderr,"shmget failed to update value\n");
198#endif
199    }else{
200      if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
201#ifdef DEBUG
202        fprintf(stderr,"shmat failed to update value\n");
203#endif
204      }else{
205        shmdt(shm);
206        shmctl(shmid,IPC_RMID,&shmids);
207      }
208    }
209  }
210}
211
212void updateStatus(maps *conf){
213  int shmid,i;
214  key_t key;
215  char *shm,*s,*s1;
216  map *tmpMap=NULL;
217  tmpMap=getMapFromMaps(conf,"lenv","sid");
218  if(tmpMap!=NULL){
219    key=atoi(tmpMap->value);
220    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
221#ifdef DEBUG
222      fprintf(stderr,"shmget failed to create new Shared memory segment\n");
223#endif
224    }else{
225      if ((shm = (char*) shmat(shmid, NULL, 0)) == (char *) -1) {
226#ifdef DEBUG
227        fprintf(stderr,"shmat failed to update value\n");
228#endif
229      }
230      else{
231        tmpMap=getMapFromMaps(conf,"lenv","status");
232        s1=shm;
233        for(s=tmpMap->value;*s!=NULL && *s!=0;s++){
234          *s1++=*s;
235        }
236        *s1++='|';
237        tmpMap=getMapFromMaps(conf,"lenv","message");
238        if(tmpMap!=NULL)
239          for(s=tmpMap->value;*s!=NULL && *s!=0;s++){
240            *s1++=*s;
241        }
242        *s1=NULL;
243        shmdt((void *)shm);
244      }
245    }
246  }
247}
248
249char* getStatus(int pid){
250  int shmid,i;
251  key_t key;
252  void *shm;
253  char *s;
254  key=pid;
255  if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
256#ifdef DEBUG
257    fprintf(stderr,"shmget failed in getStatus\n");
258#endif
259  }else{
260    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
261#ifdef DEBUG
262      fprintf(stderr,"shmat failed in getStatus\n");
263#endif
264    }else{
265      return (char*)shm;
266    }
267  }
268  return "-1";
269}
270
271#endif
272
273#ifdef USE_JS
274
275JSBool
276JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
277{
278  jsval *argv = JS_ARGV(cx,argv1);
279  JS_MaybeGC(cx);
280  char *sid;
281  int istatus=0;
282  char *status=NULL;
283  maps *conf;
284  int i=0;
285  if(argc>2){
286#ifdef JS_DEBUG
287    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
288#endif
289    return JS_FALSE;
290  }
291  conf=mapsFromJSObject(cx,argv[0]);
292  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
293    char tmpStatus[4];
294    sprintf(tmpStatus,"%i",istatus);
295    tmpStatus[3]=0;
296    status=strdup(tmpStatus);
297  }
298  if(getMapFromMaps(conf,"lenv","status")!=NULL){
299    if(status!=NULL){
300      setMapInMaps(conf,"lenv","status",status);
301      free(status);
302    }
303    else
304      setMapInMaps(conf,"lenv","status","15");
305    updateStatus(conf);
306  }
307  freeMaps(&conf);
308  free(conf);
309  JS_MaybeGC(cx);
310  return JS_TRUE;
311}
312
313#endif
314
315
316
317/* Returns a url-encoded version of str */
318/* IMPORTANT: be sure to free() the returned string after use */
319char *url_encode(char *str) {
320  char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
321  while (*pstr) {
322    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
323      *pbuf++ = *pstr;
324    else if (*pstr == ' ') 
325      *pbuf++ = '+';
326    else 
327      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
328    pstr++;
329  }
330  *pbuf = '\0';
331  return buf;
332}
333
334/* Returns a url-decoded version of str */
335/* IMPORTANT: be sure to free() the returned string after use */
336char *url_decode(char *str) {
337  char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
338  while (*pstr) {
339    if (*pstr == '%') {
340      if (pstr[1] && pstr[2]) {
341        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
342        pstr += 2;
343      }
344    } else if (*pstr == '+') { 
345      *pbuf++ = ' ';
346    } else {
347      *pbuf++ = *pstr;
348    }
349    pstr++;
350  }
351  *pbuf = '\0';
352  return buf;
353}
354
355char *zCapitalize1(char *tmp){
356        char *res=strdup(tmp);
357        if(res[0]>=97 && res[0]<=122)
358                res[0]-=32;
359        return res;
360}
361
362char *zCapitalize(char *tmp){
363  int i=0;
364  char *res=strdup(tmp);
365  for(i=0;i<strlen(res);i++)
366    if(res[i]>=97 && res[i]<=122)
367      res[i]-=32;
368  return res;
369}
370
371
372int zooXmlSearchForNs(const char* name){
373  int i;
374  int res=-1;
375  for(i=0;i<nbNs;i++)
376    if(strncasecmp(name,nsName[i],strlen(nsName[i]))==0){
377      res=i;
378      break;
379    }
380  return res;
381}
382
383int zooXmlAddNs(xmlNodePtr nr,const char* url,const char* name){
384#ifdef DEBUG
385  fprintf(stderr,"zooXmlAddNs %d \n",nbNs);
386#endif
387  int currId=-1;
388  int currNode=-1;
389  if(nbNs==0){
390    nbNs++;
391    currId=0;
392    nsName[currId]=strdup(name);
393    usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
394  }else{
395    currId=zooXmlSearchForNs(name);
396    if(currId<0){
397      nbNs++;
398      currId=nbNs-1;
399      nsName[currId]=strdup(name);
400      usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
401    }
402  }
403  return currId;
404}
405
406void zooXmlCleanupNs(){
407  int j;
408#ifdef DEBUG
409  fprintf(stderr,"zooXmlCleanup %d\n",nbNs);
410#endif
411  for(j=nbNs-1;j>=0;j--){
412#ifdef DEBUG
413    fprintf(stderr,"zooXmlCleanup %d\n",j);
414#endif
415    if(j==0)
416      xmlFreeNs(usedNs[j]);
417    free(nsName[j]);
418    nbNs--;
419  }
420  nbNs=0;
421}
422
423xmlNodePtr soapEnvelope(maps* conf,xmlNodePtr n){
424  map* soap=getMapFromMaps(conf,"main","isSoap");
425  if(soap!=NULL && strcasecmp(soap->value,"true")==0){
426    int lNbNs=nbNs;
427    nsName[lNbNs]=strdup("soap");
428    usedNs[lNbNs]=xmlNewNs(NULL,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
429    nbNs++;
430    xmlNodePtr nr = xmlNewNode(usedNs[lNbNs], BAD_CAST "Envelope");
431    nsName[nbNs]=strdup("soap");
432    usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
433    nbNs++;
434    nsName[nbNs]=strdup("xsi");
435    usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
436    nbNs++;
437    xmlNsPtr ns_xsi=usedNs[nbNs-1];
438    xmlNewNsProp(nr,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.w3.org/2003/05/soap-envelope http://www.w3.org/2003/05/soap-envelope");
439    xmlNodePtr nr1 = xmlNewNode(usedNs[lNbNs], BAD_CAST "Body");
440    xmlAddChild(nr1,n);
441    xmlAddChild(nr,nr1);
442    return nr;
443  }else
444    return n;
445}
446
447xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr doc,const char* service,maps* m){
448
449  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
450  xmlNodePtr n,nc,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
451  xmlChar *xmlbuff;
452  int buffersize;
453  /**
454   * Create the document and its temporary root.
455   */
456  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
457  ns=usedNs[wpsId];
458  maps* toto1=getMaps(m,"main");
459
460  n = xmlNewNode(ns, BAD_CAST "Capabilities");
461  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
462  ns_ows=usedNs[owsId];
463  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
464  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
465  ns_xsi=usedNs[xsiId];
466  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
467  ns_xlink=usedNs[xlinkId];
468  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsGetCapabilities_response.xsd"); 
469  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
470  addLangAttr(n,m);
471 
472  if(toto1!=NULL){
473    map* tmp=getMap(toto1->content,"version");
474    if(tmp!=NULL){
475      xmlNewProp(n,BAD_CAST "version",BAD_CAST tmp->value);
476    }
477    else
478      xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
479  }
480  else
481    xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
482
483  char tmp[256];
484 
485  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceIdentification");
486  maps* tmp4=getMaps(m,"identification");
487  if(tmp4!=NULL){
488    map* tmp2=tmp4->content;
489    char *orderedFields[5];
490    orderedFields[0]="Title";
491    orderedFields[1]="Abstract";
492    orderedFields[2]="Keywords";
493    orderedFields[3]="Fees";
494    orderedFields[4]="AccessConstraints";
495    int oI=0;
496    for(oI=0;oI<5;oI++)
497      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
498        if(strcasecmp(tmp2->name,"abstract")==0 ||
499           strcasecmp(tmp2->name,"title")==0 ||
500           strcasecmp(tmp2->name,"accessConstraints")==0 ||
501           strcasecmp(tmp2->name,"fees")==0){
502          tmp2->name[0]=toupper(tmp2->name[0]);
503          nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
504          xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
505          xmlAddChild(nc,nc1);
506        }
507        else
508          if(strcmp(tmp2->name,"keywords")==0){
509            nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
510            char *toto=tmp2->value;
511            char buff[256];
512            int i=0;
513            int j=0;
514            while(toto[i]){
515              if(toto[i]!=',' && toto[i]!=0){
516                buff[j]=toto[i];
517                buff[j+1]=0;
518                j++;
519              }
520              else{
521                nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
522                xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
523                xmlAddChild(nc1,nc2);
524                j=0;
525              }
526              i++;
527            }
528            if(strlen(buff)>0){
529              nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
530              xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
531              xmlAddChild(nc1,nc2);
532            }
533            xmlAddChild(nc,nc1);
534            nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceType");
535            xmlAddChild(nc2,xmlNewText(BAD_CAST "WPS"));
536            xmlAddChild(nc,nc2);
537            nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceTypeVersion");
538            xmlAddChild(nc2,xmlNewText(BAD_CAST "1.0.0"));
539            xmlAddChild(nc,nc2);         
540          }
541        tmp2=tmp2->next;
542      }
543  }
544  else{
545    fprintf(stderr,"TMP4 NOT FOUND !!");
546    return NULL;
547  }
548  xmlAddChild(n,nc);
549
550  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceProvider");
551  nc3 = xmlNewNode(ns_ows, BAD_CAST "ServiceContact");
552  nc4 = xmlNewNode(ns_ows, BAD_CAST "ContactInfo");
553  nc5 = xmlNewNode(ns_ows, BAD_CAST "Phone");
554  nc6 = xmlNewNode(ns_ows, BAD_CAST "Address");
555  tmp4=getMaps(m,"provider");
556  if(tmp4!=NULL){
557    map* tmp2=tmp4->content;
558    char *tmpAddress[6];
559    tmpAddress[0]="addressDeliveryPoint";
560    tmpAddress[1]="addressCity";
561    tmpAddress[2]="addressAdministrativeArea";
562    tmpAddress[3]="addressPostalCode";
563    tmpAddress[4]="addressCountry";
564    tmpAddress[5]="addressElectronicMailAddress";
565    char *tmpPhone[2];
566    tmpPhone[0]="phoneVoice";
567    tmpPhone[1]="phoneFacsimile";
568    char *orderedFields[12];
569    orderedFields[0]="providerName";
570    orderedFields[1]="providerSite";
571    orderedFields[2]="individualName";
572    orderedFields[3]="positionName";
573    orderedFields[4]=tmpPhone[0];
574    orderedFields[5]=tmpPhone[1];
575    orderedFields[6]=tmpAddress[0];
576    orderedFields[7]=tmpAddress[1];
577    orderedFields[8]=tmpAddress[2];
578    orderedFields[9]=tmpAddress[3];
579    orderedFields[10]=tmpAddress[4];
580    orderedFields[11]=tmpAddress[5];
581    int oI=0;
582    for(oI=0;oI<12;oI++)
583      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
584        if(strcmp(tmp2->name,"keywords")!=0 &&
585           strcmp(tmp2->name,"serverAddress")!=0 &&
586           strcmp(tmp2->name,"lang")!=0){
587          tmp2->name[0]=toupper(tmp2->name[0]);
588          if(strcmp(tmp2->name,"ProviderName")==0){
589            nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
590            xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
591            xmlAddChild(nc,nc1);
592          }
593          else{
594            if(strcmp(tmp2->name,"ProviderSite")==0){
595              nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
596              xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST tmp2->value);
597              xmlAddChild(nc,nc1);
598            } 
599            else 
600              if(strcmp(tmp2->name,"IndividualName")==0 || 
601                 strcmp(tmp2->name,"PositionName")==0){
602                nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
603                xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
604                xmlAddChild(nc3,nc1);
605              } 
606              else 
607                if(strncmp(tmp2->name,"Phone",5)==0){
608                  int j;
609                  for(j=0;j<2;j++)
610                    if(strcasecmp(tmp2->name,tmpPhone[j])==0){
611                      char *toto=NULL;
612                      char *toto1=tmp2->name;
613                      toto=strstr(toto1,"Phone");
614                      nc1 = xmlNewNode(ns_ows, BAD_CAST toto1+5);
615                      xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
616                      xmlAddChild(nc5,nc1);
617                    }
618                }
619                else 
620                  if(strncmp(tmp2->name,"Address",7)==0){
621                    int j;
622                    for(j=0;j<6;j++)
623                      if(strcasecmp(tmp2->name,tmpAddress[j])==0){
624                        char *toto=NULL;
625                        char *toto1=tmp2->name;
626                        toto=strstr(toto1,"Address");
627                        nc1 = xmlNewNode(ns_ows, BAD_CAST toto1+7);
628                        xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
629                        xmlAddChild(nc6,nc1);
630                      }
631                  }
632          }
633        }
634        else
635          if(strcmp(tmp2->name,"keywords")==0){
636            nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
637            char *toto=tmp2->value;
638            char buff[256];
639            int i=0;
640            int j=0;
641            while(toto[i]){
642              if(toto[i]!=',' && toto[i]!=0){
643                buff[j]=toto[i];
644                buff[j+1]=0;
645                j++;
646              }
647              else{
648                nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
649                xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
650                xmlAddChild(nc1,nc2);
651                j=0;
652              }
653              i++;
654            }
655            if(strlen(buff)>0){
656              nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
657              xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
658              xmlAddChild(nc1,nc2);
659            }
660            xmlAddChild(nc,nc1);
661          }
662        tmp2=tmp2->next;
663      }
664  }
665  else{
666    fprintf(stderr,"TMP4 NOT FOUND !!");
667  }
668  xmlAddChild(nc4,nc5);
669  xmlAddChild(nc4,nc6);
670  xmlAddChild(nc3,nc4);
671  xmlAddChild(nc,nc3);
672  xmlAddChild(n,nc);
673
674
675  nc = xmlNewNode(ns_ows, BAD_CAST "OperationsMetadata");
676  char *tmp2[3];
677  tmp2[0]=strdup("GetCapabilities");
678  tmp2[1]=strdup("DescribeProcess");
679  tmp2[2]=strdup("Execute");
680  int j=0;
681
682  if(toto1!=NULL){
683    map* tmp=getMap(toto1->content,"serverAddress");
684    if(tmp!=NULL){
685      SERVICE_URL = strdup(tmp->value);
686    }
687    else
688      SERVICE_URL = strdup("not_found");
689  }
690  else
691    SERVICE_URL = strdup("not_found");
692
693  for(j=0;j<3;j++){
694    nc1 = xmlNewNode(ns_ows, BAD_CAST "Operation");
695    xmlNewProp(nc1,BAD_CAST "name",BAD_CAST tmp2[j]);
696    nc2 = xmlNewNode(ns_ows, BAD_CAST "DCP");
697    nc3 = xmlNewNode(ns_ows, BAD_CAST "HTTP");
698    nc4 = xmlNewNode(ns_ows, BAD_CAST "Get");
699    sprintf(tmp,"%s/%s",SERVICE_URL,service);
700    xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
701    xmlAddChild(nc3,nc4);
702    if(j>0){
703      nc4 = xmlNewNode(ns_ows, BAD_CAST "Post");
704      xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
705      xmlAddChild(nc3,nc4);
706    }
707    xmlAddChild(nc2,nc3);
708    xmlAddChild(nc1,nc2);   
709    xmlAddChild(nc,nc1);   
710  }
711  for(j=2;j>=0;j--)
712    free(tmp2[j]);
713  xmlAddChild(n,nc);
714
715  nc = xmlNewNode(ns, BAD_CAST "ProcessOfferings");
716  xmlAddChild(n,nc);
717
718  nc1 = xmlNewNode(ns, BAD_CAST "Languages");
719  nc2 = xmlNewNode(ns, BAD_CAST "Default");
720  nc3 = xmlNewNode(ns, BAD_CAST "Supported");
721 
722  toto1=getMaps(m,"main");
723  if(toto1!=NULL){
724    map* tmp1=getMap(toto1->content,"lang");
725    char *toto=tmp1->value;
726    char buff[256];
727    int i=0;
728    int j=0;
729    int dcount=0;
730    while(toto[i]){
731      if(toto[i]!=',' && toto[i]!=0){
732        buff[j]=toto[i];
733        buff[j+1]=0;
734        j++;
735      }
736      else{
737        nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
738        xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
739        if(dcount==0){
740          xmlAddChild(nc2,nc4);
741          xmlAddChild(nc1,nc2);
742          dcount++;
743        }
744        nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
745        xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
746        xmlAddChild(nc3,nc4);
747        j=0;
748        buff[j]=0;
749      }
750      i++;
751    }
752    if(strlen(buff)>0){
753      nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
754      xmlAddChild(nc4,xmlNewText(BAD_CAST buff));             
755      xmlAddChild(nc3,nc4);
756    }
757  }
758  xmlAddChild(nc1,nc3);
759  xmlAddChild(n,nc1);
760 
761  xmlNodePtr fn=soapEnvelope(m,n);
762  xmlDocSetRootElement(doc, fn);
763  //xmlFreeNs(ns);
764  free(SERVICE_URL);
765  return nc;
766}
767
768void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
769  xmlNsPtr ns,ns_ows,ns_xlink;
770  xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
771  /**
772   * Initialize or get existing namspaces
773   */
774  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
775  ns=usedNs[wpsId];
776  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
777  ns_ows=usedNs[owsId];
778  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
779  ns_xlink=usedNs[xlinkId];
780
781  int cursor=0;
782  map* tmp1;
783  if(serv->content!=NULL){
784    nc1 = xmlNewNode(ns, BAD_CAST "Process");
785    tmp1=getMap(serv->content,"processVersion");
786    if(tmp1!=NULL)
787      xmlNewNsProp(nc1,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);
788    printDescription(nc1,ns_ows,serv->name,serv->content);
789    tmp1=serv->metadata;
790    while(tmp1!=NULL){
791      nc2 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
792      xmlNewNsProp(nc2,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
793      xmlAddChild(nc1,nc2);
794      tmp1=tmp1->next;
795    }
796    xmlAddChild(nc,nc1);
797  }
798}
799
800xmlNodePtr printDescribeProcessHeader(xmlDocPtr doc,const char* service,maps* m){
801
802  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
803  xmlNodePtr n,nr;
804  xmlChar *xmlbuff;
805  int buffersize;
806
807  int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
808  ns=usedNs[wpsId];
809  n = xmlNewNode(ns, BAD_CAST "ProcessDescriptions");
810  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
811  ns_ows=usedNs[owsId];
812  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
813  zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
814  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
815  ns_xsi=usedNs[xsiId];
816 
817  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd");
818  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
819  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
820  addLangAttr(n,m);
821
822  xmlNodePtr fn=soapEnvelope(m,n);
823  xmlDocSetRootElement(doc, fn);
824
825  return n;
826}
827
828void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv,int sc){
829  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
830  xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
831
832  char tmp[256];
833  n=nc;
834 
835  int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
836  ns=usedNs[wpsId];
837  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
838  ns_ows=usedNs[owsId];
839  int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
840  ns_xlink=usedNs[xlinkId];
841
842  nc = xmlNewNode(NULL, BAD_CAST "ProcessDescription");
843  char *tmp4[3];
844  tmp4[0]="processVersion";
845  tmp4[1]="storeSupported";
846  tmp4[2]="statusSupported";
847  int j=0;
848  map* tmp1=NULL;
849  for(j=0;j<3;j++){
850    tmp1=getMap(serv->content,tmp4[j]);
851    if(tmp1!=NULL){
852      if(j==0)
853        xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);     
854      else
855        xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value);     
856    }
857    else{
858      if(j>0)
859        xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "false");     
860    }
861  }
862 
863  printDescription(nc,ns_ows,serv->name,serv->content);
864
865  tmp1=serv->metadata;
866  while(tmp1!=NULL){
867    nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
868    xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
869    xmlAddChild(nc,nc1);
870    tmp1=tmp1->next;
871  }
872
873  tmp1=getMap(serv->content,"Profile");
874  if(tmp1!=NULL){
875    nc1 = xmlNewNode(ns, BAD_CAST "Profile");
876    xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
877    xmlAddChild(nc,nc1);
878  }
879
880  nc1 = xmlNewNode(NULL, BAD_CAST "DataInputs");
881  elements* e=serv->inputs;
882  printFullDescription(e,"Input",ns_ows,nc1);
883  xmlAddChild(nc,nc1);
884
885  nc1 = xmlNewNode(NULL, BAD_CAST "ProcessOutputs");
886  e=serv->outputs;
887  printFullDescription(e,"Output",ns_ows,nc1);
888  xmlAddChild(nc,nc1);
889
890  xmlAddChild(n,nc);
891
892}
893
894void printFullDescription(elements *elem,const char* type,xmlNsPtr ns_ows,xmlNodePtr nc1){
895  char *orderedFields[13];
896  orderedFields[0]="mimeType";
897  orderedFields[1]="encoding";
898  orderedFields[2]="schema";
899  orderedFields[3]="dataType";
900  orderedFields[4]="uom";
901  orderedFields[5]="CRS";
902  orderedFields[6]="value";
903  orderedFields[7]="AllowedValues";
904  orderedFields[8]="range";
905  orderedFields[9]="rangeMin";
906  orderedFields[10]="rangeMax";
907  orderedFields[11]="rangeClosure";
908  orderedFields[12]="rangeSpace";
909
910  xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8;
911  elements* e=elem;
912  map* tmp1=NULL;
913  while(e!=NULL){
914    int default1=0;
915    int isAnyValue=1;
916    nc2 = xmlNewNode(NULL, BAD_CAST type);
917    tmp1=getMap(e->content,"minOccurs");
918    if(tmp1){
919      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
920    }
921    tmp1=getMap(e->content,"maxOccurs");
922    if(tmp1){
923      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
924    }
925
926    printDescription(nc2,ns_ows,e->name,e->content);
927
928    if(strncmp(type,"Output",6)==0){
929      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
930        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralOutput");
931      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
932        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexOutput");
933      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
934        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
935      else
936        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
937    }else{
938      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0){
939        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralData");
940      }
941      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
942        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexData");
943      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
944        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxData");
945      else
946        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
947    }
948    iotype* _tmp0=NULL;
949    iotype* _tmp=e->defaults;
950    int datatype=0;
951    bool hasDefault=false;
952    bool hasUOM=false;
953    if(_tmp!=NULL){
954      if(strcmp(e->format,"LiteralOutput")==0 ||
955         strcmp(e->format,"LiteralData")==0){
956        datatype=1;
957        nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
958        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
959      }
960      else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
961              strcmp(e->format,"BoundingBoxData")==0){
962        datatype=2;
963        //nc4 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
964        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
965      }
966      else{
967        nc4 = xmlNewNode(NULL, BAD_CAST "Default");
968        nc5 = xmlNewNode(NULL, BAD_CAST "Format");
969      }
970     
971      tmp1=_tmp->content;
972      int avcnt=0;
973      int dcnt=0;
974      int oI=0;
975      for(oI=0;oI<13;oI++)
976        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
977          //while(tmp1!=NULL){
978#ifdef DEBUG
979          printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
980#endif
981          if(strncasecmp(tmp1->name,"DataType",8)==0){
982            nc6 = xmlNewNode(ns_ows, BAD_CAST "DataType");
983            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
984            char tmp[1024];
985            sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
986            xmlNewNsProp(nc6,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
987            xmlAddChild(nc3,nc6);
988            tmp1=tmp1->next;
989            datatype=1;
990            continue;
991          }
992          if(strcmp(tmp1->name,"asReference")!=0 &&
993             strncasecmp(tmp1->name,"DataType",8)!=0 &&
994             strcasecmp(tmp1->name,"extension")!=0 &&
995             strcasecmp(tmp1->name,"value")!=0 &&
996             strncasecmp(tmp1->name,"AllowedValues",13)!=0&&
997             strncasecmp(tmp1->name,"range",5)!=0){
998            if(datatype!=1){
999              char *tmp2=zCapitalize1(tmp1->name);
1000              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1001              free(tmp2);
1002            }
1003            else{
1004              char *tmp2=zCapitalize(tmp1->name);
1005              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
1006              free(tmp2);
1007            }
1008            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
1009            xmlAddChild(nc5,nc6);
1010            hasUOM=true;
1011          }else 
1012            if(strncmp(type,"Input",5)==0){
1013
1014              if(strcmp(tmp1->name,"value")==0){
1015                nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
1016                xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
1017                default1=1;
1018                hasDefault=true;
1019              }
1020              if(strncasecmp(tmp1->name,"AllowedValues",13)==0){
1021                nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
1022                char *token,*saveptr1;
1023                token=strtok_r(tmp1->value,",",&saveptr1);
1024                while(token!=NULL){
1025                  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
1026                  char *tmps=strdup(token);
1027                  tmps[strlen(tmps)]=0;
1028                  xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
1029                  xmlAddChild(nc6,nc7);
1030                  token=strtok_r(NULL,",",&saveptr1);
1031                }
1032                if(getMap(_tmp->content,"range")!=NULL ||
1033                   getMap(_tmp->content,"rangeMin")!=NULL ||
1034                   getMap(_tmp->content,"rangeMax")!=NULL ||
1035                   getMap(_tmp->content,"rangeClosure")!=NULL )
1036                  goto doRange;
1037                xmlAddChild(nc3,nc6);
1038                isAnyValue=-1;
1039              }
1040              if(strncasecmp(tmp1->name,"range",5)==0){
1041                if(isAnyValue==1){
1042                  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
1043                doRange:
1044                 
1045                  /**
1046                   * Range: Table 46 OGC Web Services Common Standard
1047                   */
1048                  nc8 = xmlNewNode(ns_ows, BAD_CAST "Range");
1049
1050                  map* tmp0=getMap(tmp1,"range");
1051                  if(tmp0!=NULL){
1052                    char* pToken;
1053                    char* orig=zStrdup(tmp0->value);
1054                    /**
1055                     * RangeClosure: Table 47 OGC Web Services Common Standard
1056                     */
1057                    char *tmp="closed";
1058                    if(orig[0]=='[' && orig[strlen(orig)-1]=='[')
1059                      tmp="closed-open";
1060                    else
1061                      if(orig[0]==']' && orig[strlen(orig)-1]==']')
1062                        tmp="open-closed";
1063                      else
1064                        if(orig[0]==']' && orig[strlen(orig)-1]=='[')
1065                          tmp="open";
1066                    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
1067                    pToken=strtok(orig,",");
1068                    int nci0=0;
1069                    while(pToken!=NULL){
1070                      char *tmpStr=(char*) malloc((strlen(pToken))*sizeof(char));
1071                      if(nci0==0){
1072                        nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
1073                        int nci=1;
1074                        for(nci=1;nci<strlen(pToken);nci++){
1075                          tmpStr[nci-1]=pToken[nci];
1076                        }
1077                      }else{
1078                        nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
1079                        int nci=0;
1080                        for(nci=0;nci<strlen(pToken)-1;nci++){
1081                          tmpStr[nci]=pToken[nci];
1082                        }
1083                      }
1084                      xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr));
1085                      xmlAddChild(nc8,nc7);
1086                      nci0++;
1087                      pToken = strtok(NULL,",");
1088                    }               
1089                    if(getMap(tmp1,"rangeSpacing")==NULL){
1090                      nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
1091                      xmlAddChild(nc7,xmlNewText(BAD_CAST "1"));
1092                      xmlAddChild(nc8,nc7);
1093                    }
1094                  }else{
1095
1096                  tmp0=getMap(tmp1,"rangeMin");
1097                  if(tmp0!=NULL){
1098                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
1099                    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
1100                    xmlAddChild(nc8,nc7);
1101                  }else{
1102                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
1103                    xmlAddChild(nc8,nc7);
1104                  }
1105                  tmp0=getMap(tmp1,"rangeMax");
1106                  if(tmp0!=NULL){
1107                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
1108                    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
1109                    xmlAddChild(nc8,nc7);
1110                  }else{
1111                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
1112                    xmlAddChild(nc8,nc7);
1113                  }
1114                  tmp0=getMap(tmp1,"rangeSpacing");
1115                  if(tmp0!=NULL){
1116                    nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
1117                    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
1118                    xmlAddChild(nc8,nc7);
1119                  }
1120                  tmp0=getMap(tmp1,"rangeClosure");
1121                  if(tmp0!=NULL){
1122                    char *tmp="closed";
1123                    if(strcasecmp(tmp0->value,"co")==0)
1124                      tmp="closed-open";
1125                    else
1126                      if(strcasecmp(tmp0->value,"oc")==0)
1127                        tmp="open-closed";
1128                      else
1129                        if(strcasecmp(tmp0->value,"o")==0)
1130                          tmp="open";
1131                    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
1132                  }else
1133                    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
1134                  }
1135                  if(_tmp0==NULL){
1136                    xmlAddChild(nc6,nc8);
1137                    _tmp0=e->supported;
1138                    tmp1=_tmp0->content;
1139                    goto doRange;
1140                  }else{
1141                    _tmp0=_tmp0->next;
1142                    if(_tmp0!=NULL){
1143                      xmlAddChild(nc6,nc8);
1144                      tmp1=_tmp0->content;
1145                      goto doRange;
1146                    }
1147                 
1148                  }
1149                  xmlAddChild(nc6,nc8);
1150                  xmlAddChild(nc3,nc6);
1151                  isAnyValue=-1;
1152                }
1153              }
1154            }
1155          tmp1=tmp1->next;
1156          if(datatype!=2){
1157            if(hasUOM==true){
1158              xmlAddChild(nc4,nc5);
1159              xmlAddChild(nc3,nc4);
1160            }
1161          }else{
1162            xmlAddChild(nc3,nc5);
1163          }
1164          if(strncmp(type,"Input",5)==0){
1165            if(datatype==1 && isAnyValue==1 && default1>0){
1166              xmlAddChild(nc3,nc7);
1167            }
1168          }
1169         
1170        }
1171      if(strncmp(type,"Input",5)==0){
1172        if(datatype==1 && isAnyValue==1 && avcnt==0){
1173          xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1174          hasDefault=true;
1175          avcnt++;
1176        }
1177      }
1178     
1179      map* metadata=e->metadata;
1180      xmlNodePtr n;
1181      int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1182      xmlNsPtr ns_xlink=usedNs[xlinkId];
1183
1184      while(metadata!=NULL){
1185        nc6=xmlNewNode(ns_ows, BAD_CAST "MetaData");
1186        xmlNewNsProp(nc6,ns_xlink,BAD_CAST metadata->name,BAD_CAST metadata->value);
1187        xmlAddChild(nc2,nc6);
1188        metadata=metadata->next;
1189      }
1190    }
1191
1192    _tmp=e->supported;
1193    if(_tmp==NULL && (getMap(e->defaults->content,"uom")!=NULL || datatype!=1))
1194      _tmp=e->defaults;
1195
1196    int hasSupported=-1;
1197    while(_tmp!=NULL){
1198      if(hasSupported<0){
1199        if(datatype==0){
1200          nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
1201          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1202        }
1203        else
1204          nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
1205        hasSupported=0;
1206      }else
1207        if(datatype==0)
1208          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1209      tmp1=_tmp->content;
1210      int oI=0;
1211      for(oI=0;oI<6;oI++)
1212        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
1213#ifdef DEBUG
1214          printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
1215#endif
1216          if(strcmp(tmp1->name,"asReference")!=0 && 
1217             strcmp(tmp1->name,"DataType")!=0 &&
1218             strcasecmp(tmp1->name,"extension")!=0){
1219            if(datatype!=1){
1220              char *tmp2=zCapitalize1(tmp1->name);
1221              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1222              free(tmp2);
1223            }
1224            else{
1225              char *tmp2=zCapitalize(tmp1->name);
1226              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
1227              free(tmp2);
1228            }
1229            if(datatype==2){
1230              char *tmpv,*tmps;
1231              tmps=strtok_r(tmp1->value,",",&tmpv);
1232              while(tmps){
1233                xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
1234                xmlAddChild(nc5,nc6);
1235                tmps=strtok_r(NULL,",",&tmpv);
1236                if(tmps){
1237                  char *tmp2=zCapitalize1(tmp1->name);
1238                  nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1239                  free(tmp2);
1240                }
1241              }
1242            }
1243            else{
1244              xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
1245              xmlAddChild(nc5,nc6);
1246            }
1247          }
1248          tmp1=tmp1->next;
1249        }
1250      if(hasSupported<=0){
1251        if(datatype!=2){
1252          xmlAddChild(nc4,nc5);
1253          xmlAddChild(nc3,nc4);
1254        }else
1255          xmlAddChild(nc3,nc5);
1256        hasSupported=1;
1257      }
1258      else
1259        if(datatype!=2){
1260          xmlAddChild(nc4,nc5);
1261        }
1262        else
1263          xmlAddChild(nc3,nc5);
1264      _tmp=_tmp->next;
1265    }
1266    xmlAddChild(nc2,nc3);
1267   
1268    if(datatype!=2 && hasUOM==true){
1269      xmlAddChild(nc3,nc4);
1270      xmlAddChild(nc2,nc3);
1271    }/*else if(datatype!=2){
1272      if(hasDefault!=true && strncmp(type,"Input",5)==0 && isAnyValue==1)
1273        xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1274        }*/
1275   
1276    xmlAddChild(nc1,nc2);
1277   
1278    e=e->next;
1279  }
1280}
1281
1282void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
1283  xmlNsPtr ns,ns1,ns_ows,ns_xlink,ns_xsi;
1284  xmlNodePtr nr,n,nc,nc1,nc2,nc3,pseudor;
1285  xmlDocPtr doc;
1286  xmlChar *xmlbuff;
1287  int buffersize;
1288  time_t time1; 
1289  time(&time1);
1290  nr=NULL;
1291  /**
1292   * Create the document and its temporary root.
1293   */
1294  doc = xmlNewDoc(BAD_CAST "1.0");
1295  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
1296  ns=usedNs[wpsId];
1297
1298  n = xmlNewNode(ns, BAD_CAST "ExecuteResponse");
1299  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
1300  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
1301  ns_ows=usedNs[owsId];
1302  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1303  ns_xlink=usedNs[xlinkId];
1304  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1305  ns_xsi=usedNs[xsiId];
1306 
1307  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_response.xsd");
1308 
1309  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
1310  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
1311  addLangAttr(n,m);
1312
1313  char tmp[256];
1314  char url[1024];
1315  char stored_path[1024];
1316  memset(tmp,0,256);
1317  memset(url,0,1024);
1318  memset(stored_path,0,1024);
1319  maps* tmp_maps=getMaps(m,"main");
1320  if(tmp_maps!=NULL){
1321    map* tmpm1=getMap(tmp_maps->content,"serverAddress");
1322    /**
1323     * Check if the ZOO Service GetStatus is available in the local directory.
1324     * If yes, then it uses a reference to an URL which the client can access
1325     * to get information on the status of a running Service (using the
1326     * percentCompleted attribute).
1327     * Else fallback to the initial method using the xml file to write in ...
1328     */
1329    char ntmp[1024];
1330#ifndef WIN32
1331    getcwd(ntmp,1024);
1332#else
1333    _getcwd(ntmp,1024);
1334#endif
1335    struct stat myFileInfo;
1336    int statRes;
1337    char file_path[1024];
1338    sprintf(file_path,"%s/GetStatus.zcfg",ntmp);
1339    statRes=stat(file_path,&myFileInfo);
1340    if(statRes==0){
1341      char currentSid[128];
1342      map* tmpm=getMap(tmp_maps->content,"rewriteUrl");
1343      map *tmp_lenv=NULL;
1344      tmp_lenv=getMapFromMaps(m,"lenv","sid");
1345      if(tmp_lenv==NULL)
1346        sprintf(currentSid,"%i",pid);
1347      else
1348        sprintf(currentSid,"%s",tmp_lenv->value);
1349      if(tmpm==NULL || strcasecmp(tmpm->value,"false")==0){
1350        sprintf(url,"%s?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1351      }else{
1352        if(strlen(tmpm->value)>0)
1353          if(strcasecmp(tmpm->value,"true")!=0)
1354            sprintf(url,"%s/%s/GetStatus/%s",tmpm1->value,tmpm->value,currentSid);
1355          else
1356            sprintf(url,"%s/GetStatus/%s",tmpm1->value,currentSid);
1357        else
1358          sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1359      }
1360    }else{
1361      map* tmpm2=getMap(tmp_maps->content,"tmpUrl");
1362      if(tmpm1!=NULL && tmpm2!=NULL){
1363        if( strncasecmp( tmpm2->value, "http://", 7) == 0 ||
1364            strncasecmp( tmpm2->value, "https://", 8 ) == 0 ){
1365          sprintf(url,"%s/%s_%i.xml",tmpm2->value,service,pid);
1366        }else
1367          sprintf(url,"%s/%s/%s_%i.xml",tmpm1->value,tmpm2->value,service,pid);
1368      }
1369    }
1370    if(tmpm1!=NULL)
1371      sprintf(tmp,"%s",tmpm1->value);
1372    tmpm1=getMapFromMaps(m,"main","TmpPath");
1373    sprintf(stored_path,"%s/%s_%i.xml",tmpm1->value,service,pid);
1374  }
1375
1376
1377
1378  xmlNewProp(n,BAD_CAST "serviceInstance",BAD_CAST tmp);
1379  map* test=getMap(request,"storeExecuteResponse");
1380  bool hasStoredExecuteResponse=false;
1381  if(test!=NULL && strcasecmp(test->value,"true")==0){
1382    xmlNewProp(n,BAD_CAST "statusLocation",BAD_CAST url);
1383    hasStoredExecuteResponse=true;
1384  }
1385
1386  nc = xmlNewNode(ns, BAD_CAST "Process");
1387  map* tmp2=getMap(serv->content,"processVersion");
1388  if(tmp2!=NULL)
1389    xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp2->value);
1390 
1391  printDescription(nc,ns_ows,serv->name,serv->content);
1392
1393  xmlAddChild(n,nc);
1394
1395  nc = xmlNewNode(ns, BAD_CAST "Status");
1396  const struct tm *tm;
1397  size_t len;
1398  time_t now;
1399  char *tmp1;
1400  map *tmpStatus;
1401 
1402  now = time ( NULL );
1403  tm = localtime ( &now );
1404
1405  tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
1406
1407  len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
1408
1409  xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
1410
1411  char sMsg[2048];
1412  switch(status){
1413  case SERVICE_SUCCEEDED:
1414    nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
1415    sprintf(sMsg,_("Service \"%s\" run successfully."),serv->name);
1416    nc3=xmlNewText(BAD_CAST sMsg);
1417    xmlAddChild(nc1,nc3);
1418    break;
1419  case SERVICE_STARTED:
1420    nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
1421    tmpStatus=getMapFromMaps(m,"lenv","status");
1422    xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
1423    sprintf(sMsg,_("ZOO Service \"%s\" is currently running. Please, reload this document to get the up-to-date status of the Service."),serv->name);
1424    nc3=xmlNewText(BAD_CAST sMsg);
1425    xmlAddChild(nc1,nc3);
1426    break;
1427  case SERVICE_ACCEPTED:
1428    nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
1429    sprintf(sMsg,_("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."),serv->name);
1430    nc3=xmlNewText(BAD_CAST sMsg);
1431    xmlAddChild(nc1,nc3);
1432    break;
1433  case SERVICE_FAILED:
1434    nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
1435    map *errorMap;
1436    map *te;
1437    te=getMapFromMaps(m,"lenv","code");
1438    if(te!=NULL)
1439      errorMap=createMap("code",te->value);
1440    else
1441      errorMap=createMap("code","NoApplicableCode");
1442    te=getMapFromMaps(m,"lenv","message");
1443    if(te!=NULL)
1444      addToMap(errorMap,"text",_ss(te->value));
1445    else
1446      addToMap(errorMap,"text",_("No more information available"));
1447    nc3=createExceptionReportNode(m,errorMap,0);
1448    freeMap(&errorMap);
1449    free(errorMap);
1450    xmlAddChild(nc1,nc3);
1451    break;
1452  default :
1453    printf(_("error code not know : %i\n"),status);
1454    //exit(1);
1455    break;
1456  }
1457  xmlAddChild(nc,nc1);
1458  xmlAddChild(n,nc);
1459  free(tmp1);
1460
1461#ifdef DEBUG
1462  fprintf(stderr,"printProcessResponse 1 161\n");
1463#endif
1464
1465  map* lineage=getMap(request,"lineage");
1466  if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
1467    nc = xmlNewNode(ns, BAD_CAST "DataInputs");
1468    int i;
1469    maps* mcursor=inputs;
1470    elements* scursor=NULL;
1471    while(mcursor!=NULL /*&& scursor!=NULL*/){
1472      scursor=getElements(serv->inputs,mcursor->name);
1473      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input");
1474      mcursor=mcursor->next;
1475    }
1476    xmlAddChild(n,nc);
1477   
1478#ifdef DEBUG
1479    fprintf(stderr,"printProcessResponse 1 177\n");
1480#endif
1481
1482    nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
1483    mcursor=outputs;
1484    scursor=NULL;
1485    while(mcursor!=NULL){
1486      scursor=getElements(serv->outputs,mcursor->name);
1487      printOutputDefinitions1(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
1488      mcursor=mcursor->next;
1489    }
1490    xmlAddChild(n,nc);
1491  }
1492#ifdef DEBUG
1493  fprintf(stderr,"printProcessResponse 1 190\n");
1494#endif
1495
1496  /**
1497   * Display the process output only when requested !
1498   */
1499  if(status==SERVICE_SUCCEEDED){
1500    nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
1501    maps* mcursor=outputs;
1502    elements* scursor=serv->outputs;
1503    map* testResponse=getMap(request,"RawDataOutput");
1504    if(testResponse==NULL)
1505      testResponse=getMap(request,"ResponseDocument");
1506    while(mcursor!=NULL){
1507      map* tmp0=getMap(mcursor->content,"inRequest");
1508      scursor=getElements(serv->outputs,mcursor->name);
1509      if(scursor!=NULL){
1510        if(testResponse==NULL || tmp0==NULL)
1511          printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1512        else
1513          if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0)
1514            printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1515      }else
1516        /**
1517         * In case there was no definition found in the ZCFG file but
1518         * present in the service code
1519         */
1520        printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1521      mcursor=mcursor->next;
1522    }
1523    xmlAddChild(n,nc);
1524  }
1525
1526#ifdef DEBUG
1527  fprintf(stderr,"printProcessResponse 1 202\n");
1528#endif
1529  nr=soapEnvelope(m,n);
1530  xmlDocSetRootElement(doc, nr);
1531
1532  if(hasStoredExecuteResponse==true){
1533    /* We need to write the ExecuteResponse Document somewhere */
1534    FILE* output=fopen(stored_path,"w");
1535    if(output==NULL){
1536      /* If the file cannot be created return an ExceptionReport */
1537      char tmpMsg[1024];
1538      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the ExecuteResponse."),stored_path);
1539      map * errormap = createMap("text",tmpMsg);
1540      addToMap(errormap,"code", "InternalError");
1541      printExceptionReportResponse(m,errormap);
1542      freeMap(&errormap);
1543      free(errormap);
1544      xmlCleanupParser();
1545      zooXmlCleanupNs();
1546      return;
1547    }
1548    xmlChar *xmlbuff;
1549    int buffersize;
1550    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
1551    fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
1552    xmlFree(xmlbuff);
1553    fclose(output);
1554  }
1555  printDocument(m,doc,pid);
1556
1557  xmlCleanupParser();
1558  zooXmlCleanupNs();
1559}
1560
1561
1562void printDocument(maps* m, xmlDocPtr doc,int pid){
1563  char *encoding=getEncoding(m);
1564  if(pid==getpid()){
1565    printHeaders(m);
1566    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1567  }
1568  fflush(stdout);
1569  xmlChar *xmlbuff;
1570  int buffersize;
1571  /*
1572   * Dump the document to a buffer and print it on stdout
1573   * for demonstration purposes.
1574   */
1575  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1576  printf("%s",xmlbuff);
1577  fflush(stdout);
1578  /*
1579   * Free associated memory.
1580   */
1581  xmlFree(xmlbuff);
1582  xmlFreeDoc(doc);
1583  xmlCleanupParser();
1584  zooXmlCleanupNs();
1585}
1586
1587void printOutputDefinitions1(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
1588  xmlNodePtr nc1;
1589  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1590  map *tmp=NULL; 
1591  if(e!=NULL && e->defaults!=NULL)
1592    tmp=e->defaults->content;
1593  else{
1594    /*
1595    dumpElements(e);
1596    */
1597    return;
1598  }
1599  while(tmp!=NULL){
1600    if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
1601       || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
1602       || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
1603       || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
1604    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1605    tmp=tmp->next;
1606  }
1607  tmp=getMap(e->defaults->content,"asReference");
1608  if(tmp==NULL)
1609    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1610
1611  tmp=e->content;
1612
1613  printDescription(nc1,ns_ows,m->name,e->content);
1614
1615  xmlAddChild(nc,nc1);
1616
1617}
1618
1619void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,map* m,const char* type){
1620  xmlNodePtr nc1,nc2,nc3;
1621  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1622  map *tmp=NULL; 
1623  if(e!=NULL && e->defaults!=NULL)
1624    tmp=e->defaults->content;
1625  else{
1626    /*
1627    dumpElements(e);
1628    */
1629    return;
1630  }
1631  while(tmp!=NULL){
1632    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1633    tmp=tmp->next;
1634  }
1635  tmp=getMap(e->defaults->content,"asReference");
1636  if(tmp==NULL)
1637    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1638
1639  tmp=e->content;
1640
1641  printDescription(nc1,ns_ows,m->name,e->content);
1642
1643  xmlAddChild(nc,nc1);
1644
1645}
1646
1647void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type){
1648  xmlNodePtr nc1,nc2,nc3;
1649  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1650  map *tmp=NULL;
1651  if(e!=NULL)
1652    tmp=e->content;
1653  else
1654    tmp=m->content;
1655#ifdef DEBUG
1656  dumpMap(tmp);
1657  dumpElements(e);
1658#endif
1659  nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
1660  if(e!=NULL)
1661    nc3=xmlNewText(BAD_CAST e->name);
1662  else
1663    nc3=xmlNewText(BAD_CAST m->name);
1664  xmlAddChild(nc2,nc3);
1665  xmlAddChild(nc1,nc2);
1666  xmlAddChild(nc,nc1);
1667  // Extract Title required to be first element in the ZCFG file !
1668  bool isTitle=TRUE;
1669  if(e!=NULL)
1670    tmp=getMap(e->content,"Title");
1671  else
1672    tmp=getMap(m->content,"Title");
1673 
1674  if(tmp!=NULL){
1675    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1676    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1677    xmlAddChild(nc2,nc3); 
1678    xmlAddChild(nc1,nc2);
1679  }
1680
1681  if(e!=NULL)
1682    tmp=getMap(e->content,"Abstract");
1683  else
1684    tmp=getMap(m->content,"Abstract");
1685  if(tmp!=NULL){
1686    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1687    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1688    xmlAddChild(nc2,nc3); 
1689    xmlAddChild(nc1,nc2);
1690    xmlAddChild(nc,nc1);
1691  }
1692
1693  /**
1694   * IO type Reference or full Data ?
1695   */
1696#ifdef DEBUG
1697  fprintf(stderr,"FORMAT %s %s\n",e->format,e->format);
1698#endif
1699  map *tmpMap=getMap(m->content,"Reference");
1700  if(tmpMap==NULL){
1701    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
1702    if(e!=NULL){
1703      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
1704        nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
1705      else
1706        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
1707          nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
1708        else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
1709          nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
1710        else
1711          nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
1712    }
1713    else{
1714      map* tmpV=getMapFromMaps(m,"format","value");
1715      if(tmpV!=NULL)
1716        nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
1717      else
1718        nc3=xmlNewNode(ns_wps, BAD_CAST "LitteralData");
1719    } 
1720    tmp=m->content;
1721#ifdef USE_MS
1722    map* testMap=getMap(tmp,"requestedMimeType");
1723#endif
1724    while(tmp!=NULL){
1725      if(strcasecmp(tmp->name,"mimeType")==0 ||
1726         strcasecmp(tmp->name,"encoding")==0 ||
1727         strcasecmp(tmp->name,"schema")==0 ||
1728         strcasecmp(tmp->name,"datatype")==0 ||
1729         strcasecmp(tmp->name,"uom")==0)
1730#ifdef USE_MS
1731        if(testMap==NULL || (testMap!=NULL && strncasecmp(testMap->value,"text/xml",8)==0)){
1732#endif
1733        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1734#ifdef USE_MS
1735        }
1736      else
1737        if(strcasecmp(tmp->name,"mimeType")==0)
1738          if(testMap!=NULL)
1739            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1740          else 
1741            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1742#endif
1743      tmp=tmp->next;
1744      xmlAddChild(nc2,nc3);
1745    }
1746    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
1747      map* bb=getMap(m->content,"value");
1748      if(bb!=NULL){
1749        map* tmpRes=parseBoundingBox(bb->value);
1750        printBoundingBox(ns_ows,nc3,tmpRes);
1751        freeMap(&tmpRes);
1752        free(tmpRes);
1753      }
1754    }else{
1755      if(e!=NULL)
1756        tmp=getMap(e->defaults->content,"mimeType");
1757      else
1758        tmp=NULL;
1759#ifdef USE_MS
1760      /**
1761       * In case of OGC WebServices output use, as the data was requested
1762       * with asReference=false we have to download the resulting OWS request
1763       * stored in the Reference map value.
1764       */
1765      map* testMap=getMap(m->content,"requestedMimeType");
1766      if(testMap!=NULL){
1767        HINTERNET hInternet;
1768        hInternet=InternetOpen(
1769#ifndef WIN32
1770                               (LPCTSTR)
1771#endif
1772                               "ZooWPSClient\0",
1773                               INTERNET_OPEN_TYPE_PRECONFIG,
1774                               NULL,NULL, 0);
1775        testMap=getMap(m->content,"Reference");
1776        loadRemoteFile(m,m->content,hInternet,testMap->value);
1777        InternetCloseHandle(hInternet);
1778      }
1779#endif
1780      map* tmp1=getMap(m->content,"encoding");
1781      map* tmp2=getMap(m->content,"mimeType");
1782      map* tmp3=getMap(m->content,"value");
1783      int hasValue=1;
1784      if(tmp3==NULL){
1785        tmp3=createMap("value","");
1786        hasValue=-1;
1787      }
1788      if((tmp1!=NULL && strncmp(tmp1->value,"base64",6)==0)
1789         || (tmp2!=NULL && (strncmp(tmp2->value,"image/",6)==0 ||
1790                            (strncmp(tmp2->value,"application/",12)==0) &&
1791                            strncmp(tmp2->value,"application/json",16)!=0&&
1792                            strncmp(tmp2->value,"application/x-javascript",24)!=0&&
1793                            strncmp(tmp2->value,"application/vnd.google-earth.kml",32)!=0)
1794             )) {
1795        map* rs=getMap(m->content,"size");
1796        bool isSized=true;
1797        if(rs==NULL){
1798          char tmp1[1024];
1799          sprintf(tmp1,"%d",strlen(tmp3->value));
1800          rs=createMap("size",tmp1);
1801          isSized=false;
1802        }
1803
1804        xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));
1805        if(!isSized){
1806          freeMap(&rs);
1807          free(rs);
1808        }
1809      }
1810      else if(tmp2!=NULL){
1811        if(strncmp(tmp2->value,"text/js",7)==0 ||
1812           strncmp(tmp2->value,"application/json",16)==0)
1813          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
1814        else{
1815          if(strncmp(tmp2->value,"text/xml",8)==0 ||
1816             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)==0){
1817            xmlDocPtr doc =
1818              xmlParseMemory(tmp3->value,strlen(tmp3->value));
1819            xmlNodePtr ir = xmlDocGetRootElement(doc);
1820            xmlAddChild(nc3,ir);
1821          }
1822          else
1823            xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1824        }
1825        xmlAddChild(nc2,nc3);
1826      }
1827      else{
1828        xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1829      }
1830      if(hasValue<0){
1831        freeMap(&tmp3);
1832        free(tmp3);
1833      }
1834    }
1835  }
1836  else{
1837    tmpMap=getMap(m->content,"Reference");
1838    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
1839    if(strcasecmp(type,"Output")==0)
1840      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
1841    else
1842      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
1843    tmp=m->content;
1844#ifdef USE_MS
1845    map* testMap=getMap(tmp,"requestedMimeType");
1846#endif
1847    while(tmp!=NULL){
1848      if(strcasecmp(tmp->name,"mimeType")==0 ||
1849         strcasecmp(tmp->name,"encoding")==0 ||
1850         strcasecmp(tmp->name,"schema")==0 ||
1851         strcasecmp(tmp->name,"datatype")==0 ||
1852         strcasecmp(tmp->name,"uom")==0)
1853#ifdef USE_MS
1854        if(testMap!=NULL  && strncasecmp(testMap->value,"text/xml",8)!=0){
1855          if(strcasecmp(tmp->name,"mimeType")==0)
1856            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1857        }
1858        else
1859#endif
1860        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1861      tmp=tmp->next;
1862      xmlAddChild(nc2,nc3);
1863    }
1864  }
1865  xmlAddChild(nc1,nc2);
1866  xmlAddChild(nc,nc1);
1867
1868}
1869
1870void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
1871  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
1872  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
1873  xmlAddChild(root,nc2);
1874  map* tmp=amap;
1875  char *tmp2[2];
1876  tmp2[0]="Title";
1877  tmp2[1]="Abstract";
1878  int j=0;
1879  for(j=0;j<2;j++){
1880    map* tmp1=getMap(tmp,tmp2[j]);
1881    if(tmp1!=NULL){
1882      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
1883      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
1884      xmlAddChild(root,nc2);
1885    }
1886  }
1887}
1888
1889char* getEncoding(maps* m){
1890  if(m!=NULL){
1891    map* tmp=getMap(m->content,"encoding");
1892    if(tmp!=NULL){
1893      return tmp->value;
1894    }
1895    else
1896      return "UTF-8";
1897  }
1898  else
1899    return "UTF-8"; 
1900}
1901
1902char* getVersion(maps* m){
1903  if(m!=NULL){
1904    map* tmp=getMap(m->content,"version");
1905    if(tmp!=NULL){
1906      return tmp->value;
1907    }
1908    else
1909      return "1.0.0";
1910  }
1911  else
1912    return "1.0.0";
1913}
1914
1915void printExceptionReportResponse(maps* m,map* s){
1916  int buffersize;
1917  xmlDocPtr doc;
1918  xmlChar *xmlbuff;
1919  xmlNodePtr n;
1920
1921  doc = xmlNewDoc(BAD_CAST "1.0");
1922  maps* tmpMap=getMaps(m,"main");
1923  char *encoding=getEncoding(tmpMap);
1924  char *exceptionCode;
1925 
1926  map* tmp=getMap(s,"code");
1927  if(tmp!=NULL){
1928    if(strcmp(tmp->value,"OperationNotSupported")==0)
1929      exceptionCode="501 Not Implemented";
1930    else
1931      if(strcmp(tmp->value,"MissingParameterValue")==0 ||
1932         strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
1933         strcmp(tmp->value,"OptionNotSupported")==0 ||
1934         strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
1935         strcmp(tmp->value,"InvalidParameterValue")==0)
1936        exceptionCode="400 Bad request";
1937      else
1938        if(strcmp(tmp->value,"NoApplicableCode")==0)
1939          exceptionCode="501 Internal Server Error";
1940        else
1941          exceptionCode="501 Internal Server Error";
1942  }
1943  else
1944    exceptionCode="501 Internal Server Error";
1945
1946  if(m!=NULL){
1947    map *tmpSid=getMapFromMaps(m,"lenv","sid");
1948    if(tmpSid!=NULL){
1949      if( getpid()==atoi(tmpSid->value) ){
1950        printHeaders(m);
1951        printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
1952      }
1953    }
1954    else{
1955      printHeaders(m);
1956      printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
1957    }
1958  }else{
1959    printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
1960  }
1961  n=createExceptionReportNode(m,s,1);
1962  xmlDocSetRootElement(doc, n);
1963  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1964  printf("%s",xmlbuff);
1965  fflush(stdout);
1966  xmlFreeDoc(doc);
1967  xmlFree(xmlbuff);
1968  xmlCleanupParser();
1969  zooXmlCleanupNs();
1970}
1971
1972xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
1973 
1974  int buffersize;
1975  xmlChar *xmlbuff;
1976  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
1977  xmlNodePtr n,nc,nc1,nc2;
1978
1979  maps* tmpMap=getMaps(m,"main");
1980
1981  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
1982  ns=usedNs[nsid];
1983  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
1984
1985  if(use_ns==1){
1986    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
1987    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1988    ns_xsi=usedNs[xsiId];
1989    int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1990    ns_xlink=usedNs[xlinkId];
1991    xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd");
1992  }
1993  addLangAttr(n,m);
1994  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
1995 
1996  nc = xmlNewNode(ns, BAD_CAST "Exception");
1997
1998  map* tmp=getMap(s,"code");
1999  if(tmp!=NULL)
2000    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
2001  else
2002    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
2003
2004  tmp=getMap(s,"locator");
2005  if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
2006    xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
2007
2008
2009  tmp=getMap(s,"text");
2010  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
2011  nc2=NULL;
2012  if(tmp!=NULL){
2013    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
2014  }
2015  else{
2016    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
2017  }
2018  xmlAddChild(nc,nc1);
2019  xmlAddChild(n,nc);
2020  return n;
2021}
2022
2023
2024void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
2025                    map* request_inputs1,int cpid,maps* m,int res){
2026#ifdef DEBUG
2027  dumpMaps(request_inputs);
2028  dumpMaps(request_outputs);
2029  fprintf(stderr,"printProcessResponse\n");
2030#endif
2031  map* toto=getMap(request_inputs1,"RawDataOutput");
2032  int asRaw=0;
2033  if(toto!=NULL)
2034    asRaw=1;
2035 
2036  maps* tmpSess=getMaps(m,"senv");
2037  if(tmpSess!=NULL){
2038    map *_tmp=getMapFromMaps(m,"lenv","cookie");
2039    char* sessId;
2040    if(_tmp!=NULL){
2041      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
2042      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
2043      char session_file_path[100];
2044      char *tmp1=strtok(_tmp->value,";");
2045      if(tmp1!=NULL)
2046        sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
2047      else
2048        sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
2049      sessId=strdup(session_file_path);
2050    }else{
2051      maps* t=getMaps(m,"senv");
2052      map*p=t->content;
2053      while(p!=NULL){
2054        if(strstr(p->name,"ID")!=NULL){
2055          sessId=strdup(p->value);
2056          break;
2057        }
2058        p=p->next;
2059      }
2060    }
2061    char session_file_path[1024];
2062    map *tmpPath=getMapFromMaps(m,"main","sessPath");
2063    if(tmpPath==NULL)
2064      tmpPath=getMapFromMaps(m,"main","tmpPath");
2065    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
2066    FILE* teste=fopen(session_file_path,"w");
2067    if(teste==NULL){
2068      char tmpMsg[1024];
2069      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the session maps."),session_file_path);
2070      map * errormap = createMap("text",tmpMsg);
2071      addToMap(errormap,"code", "InternalError");
2072     
2073      printExceptionReportResponse(m,errormap);
2074      freeMap(&errormap);
2075      free(errormap);
2076      return;
2077    }
2078    else{
2079      fclose(teste);
2080      dumpMapsToFile(tmpSess,session_file_path);
2081    }
2082  }
2083 
2084  if(res==SERVICE_FAILED){
2085    map * errormap;
2086    map *lenv;
2087    lenv=getMapFromMaps(m,"lenv","message");
2088    char *tmp0;
2089    if(lenv!=NULL){
2090      tmp0=(char*)malloc((strlen(lenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "))+1)*sizeof(char));
2091      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
2092    }
2093    else{
2094      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
2095      sprintf(tmp0,_("Unable to run the Service. No more information was returned back by the Service."));
2096    }
2097    errormap = createMap("text",tmp0);
2098    free(tmp0);
2099    addToMap(errormap,"code", "InternalError");
2100    printExceptionReportResponse(m,errormap);
2101    freeMap(&errormap);
2102    free(errormap);
2103    return;
2104  }
2105
2106  if(asRaw==0){
2107#ifdef DEBUG
2108    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
2109    dumpMaps(request_outputs);
2110#endif
2111    maps* tmpI=request_outputs;
2112    while(tmpI!=NULL){
2113#ifdef USE_MS
2114      map* testMap=getMap(tmpI->content,"useMapserver");       
2115#endif
2116      toto=getMap(tmpI->content,"asReference");
2117#ifdef USE_MS
2118      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
2119#else
2120      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
2121#endif
2122        {
2123        elements* in=getElements(s->outputs,tmpI->name);
2124        char *format=NULL;
2125        if(in!=NULL){
2126          format=strdup(in->format);
2127        }else
2128          format=strdup("LiteralData");
2129        if(strcasecmp(format,"BoundingBoxData")==0){
2130          addToMap(tmpI->content,"extension","xml");
2131          addToMap(tmpI->content,"mimeType","text/xml");
2132          addToMap(tmpI->content,"encoding","UTF-8");
2133          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2134        }
2135        map *ext=getMap(tmpI->content,"extension");
2136        map *tmp1=getMapFromMaps(m,"main","tmpPath");
2137        char *file_name,*file_path;
2138        bool hasExt=true;
2139        if(ext==NULL){
2140          // We can fallback to a default list of supported formats using
2141          // mimeType information if present here. Maybe we can add more formats
2142          // here.
2143          // If mimeType was not found, we then set txt as the default extension
2144          map* mtype=getMap(tmpI->content,"mimeType");
2145          if(mtype!=NULL){
2146            if(strcasecmp(mtype->value,"text/xml")==0)
2147              ext=createMap("extension","xml");
2148            else if(strcasecmp(mtype->value,"application/json")==0)
2149              ext=createMap("extension","js");
2150            else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
2151              ext=createMap("extension","kml");
2152            else if(strncmp(mtype->value,"image/",6)==0)
2153              ext=createMap("extension",strstr(mtype->value,"/")+1);
2154            else
2155              ext=createMap("extension","txt");
2156          }
2157          else
2158            ext=createMap("extension","txt");
2159          hasExt=false;
2160        }
2161        file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
2162        int cpid0=cpid+time(NULL);
2163        sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
2164        file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
2165        sprintf(file_path,"%s/%s",tmp1->value,file_name);
2166        FILE *ofile=fopen(file_path,"wb");
2167        if(ofile==NULL){
2168          char tmpMsg[1024];
2169          sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
2170          map * errormap = createMap("text",tmpMsg);
2171          addToMap(errormap,"code", "InternalError");
2172          printExceptionReportResponse(m,errormap);
2173          freeMap(&errormap);
2174          free(errormap);
2175          free(file_name);
2176          free(file_path);
2177          return;
2178        }
2179        free(file_path);
2180        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2181        map *tmp3=getMapFromMaps(m,"main","serverAddress");
2182        char *file_url;
2183        if(strncasecmp(tmp2->value,"http://",7)==0 ||
2184           strncasecmp(tmp2->value,"https://",8)==0){
2185          file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
2186          sprintf(file_url,"%s/%s",tmp2->value,file_name);
2187        }else{
2188          file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
2189          sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2190        }
2191        addToMap(tmpI->content,"Reference",file_url);
2192        if(!hasExt){
2193          freeMap(&ext);
2194          free(ext);
2195        }
2196        toto=getMap(tmpI->content,"value");
2197        if(strcasecmp(format,"BoundingBoxData")!=0){
2198          map* size=getMap(tmpI->content,"size");
2199          if(size!=NULL && toto!=NULL)
2200            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2201          else
2202            if(toto!=NULL && toto->value!=NULL)
2203              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2204        }else{
2205          printBoundingBoxDocument(m,tmpI,ofile);
2206        }
2207        free(format);
2208        fclose(ofile);
2209        free(file_name);
2210        free(file_url); 
2211      }
2212#ifdef USE_MS
2213      else{
2214        if(testMap!=NULL){
2215          setReferenceUrl(m,tmpI);
2216        }
2217      }
2218#endif
2219      tmpI=tmpI->next;
2220    }
2221    map *r_inputs=getMap(s->content,"serviceProvider");
2222#ifdef DEBUG
2223    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2224    dumpMaps(m);
2225#endif
2226    printProcessResponse(m,request_inputs1,cpid,
2227                         s,r_inputs->value,res,
2228                         request_inputs,
2229                         request_outputs);
2230    }
2231    else{
2232      /**
2233       * We get the requested output or fallback to the first one if the
2234       * requested one is not present in the resulting outputs maps.
2235       */
2236      maps* tmpI=NULL;
2237      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2238      if(tmpIV!=NULL){
2239        tmpI=getMaps(request_outputs,tmpIV->value);
2240      }
2241      if(tmpI==NULL)
2242        tmpI=request_outputs;
2243      elements* e=getElements(s->outputs,tmpI->name);
2244      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2245        printBoundingBoxDocument(m,tmpI,NULL);
2246      }else{
2247        toto=getMap(tmpI->content,"value");
2248        if(toto==NULL){
2249          char tmpMsg[1024];
2250          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2251          map * errormap = createMap("text",tmpMsg);
2252          addToMap(errormap,"code", "InvalidParameterValue");
2253          printExceptionReportResponse(m,errormap);
2254          freeMap(&errormap);
2255          free(errormap);
2256          return;
2257        }
2258        map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2259        if(fname!=NULL)
2260          printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2261        map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2262        if(rs!=NULL)
2263          printf("Content-Length: %s\r\n",rs->value);
2264        printHeaders(m);
2265        char mime[1024];
2266        map* mi=getMap(tmpI->content,"mimeType");
2267#ifdef DEBUG
2268        fprintf(stderr,"SERVICE OUTPUTS\n");
2269        dumpMaps(request_outputs);
2270        fprintf(stderr,"SERVICE OUTPUTS\n");
2271#endif
2272        map* en=getMap(tmpI->content,"encoding");
2273        if(mi!=NULL && en!=NULL)
2274          sprintf(mime,
2275                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2276                  mi->value,en->value);
2277        else
2278          if(mi!=NULL)
2279            sprintf(mime,
2280                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2281                    mi->value);
2282          else
2283            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2284        printf("%s",mime);
2285        if(rs!=NULL)
2286          fwrite(toto->value,1,atoi(rs->value),stdout);
2287        else
2288          fwrite(toto->value,1,strlen(toto->value),stdout);
2289#ifdef DEBUG
2290        dumpMap(toto);
2291#endif
2292      }
2293    }
2294}
2295
2296char *base64(const char *input, int length)
2297{
2298  BIO *bmem, *b64;
2299  BUF_MEM *bptr;
2300
2301  b64 = BIO_new(BIO_f_base64());
2302  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2303  bmem = BIO_new(BIO_s_mem());
2304  b64 = BIO_push(b64, bmem);
2305  BIO_write(b64, input, length);
2306  BIO_flush(b64);
2307  BIO_get_mem_ptr(b64, &bptr);
2308
2309  char *buff = (char *)malloc((bptr->length)*sizeof(char));
2310  memcpy(buff, bptr->data, bptr->length-1);
2311  buff[bptr->length-1] = 0;
2312
2313  BIO_free_all(b64);
2314
2315  return buff;
2316}
2317
2318char *base64d(const char *input, int length,int* red)
2319{
2320  BIO *b64, *bmem;
2321
2322  char *buffer = (char *)malloc(length);
2323  if(buffer){
2324    memset(buffer, 0, length);
2325    b64 = BIO_new(BIO_f_base64());
2326    if(b64){
2327      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2328      bmem = BIO_push(b64, bmem);
2329      *red=BIO_read(bmem, buffer, length);
2330      buffer[length-1]=0;
2331      BIO_free_all(bmem);
2332    }
2333  }
2334  return buffer;
2335}
2336
2337void ensureDecodedBase64(maps **in){
2338  maps* cursor=*in;
2339  while(cursor!=NULL){
2340    map *tmp=getMap(cursor->content,"encoding");
2341    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2342      tmp=getMap(cursor->content,"value");
2343      addToMap(cursor->content,"base64_value",tmp->value);
2344      int size=0;
2345      char *s=strdup(tmp->value);
2346      free(tmp->value);
2347      tmp->value=base64d(s,strlen(s),&size);
2348      free(s);
2349      char sizes[1024];
2350      sprintf(sizes,"%d",size);
2351      addToMap(cursor->content,"size",sizes);
2352    }
2353    cursor=cursor->next;
2354  }
2355}
2356
2357char* addDefaultValues(maps** out,elements* in,maps* m,int type){
2358  elements* tmpInputs=in;
2359  maps* out1=*out;
2360  if(type==1){
2361    while(out1!=NULL){
2362      if(getElements(in,out1->name)==NULL)
2363        return out1->name;
2364      out1=out1->next;
2365    }
2366    out1=*out;
2367  }
2368  while(tmpInputs!=NULL){
2369    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2370    if(tmpMaps==NULL){
2371      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2372      tmpMaps2->name=strdup(tmpInputs->name);
2373      tmpMaps2->content=NULL;
2374      tmpMaps2->next=NULL;
2375     
2376      if(type==0){
2377        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2378        if(tmpMapMinO!=NULL)
2379          if(atoi(tmpMapMinO->value)>=1){
2380            freeMaps(&tmpMaps2);
2381            free(tmpMaps2);
2382            return tmpInputs->name;
2383          }
2384          else{
2385            if(tmpMaps2->content==NULL)
2386              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2387            else
2388              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2389          }
2390        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2391        if(tmpMaxO!=NULL)
2392          if(tmpMaps2->content==NULL)
2393            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2394          else
2395            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2396      }
2397
2398      iotype* tmpIoType=tmpInputs->defaults;
2399      if(tmpIoType!=NULL){
2400        map* tmpm=tmpIoType->content;
2401        while(tmpm!=NULL){
2402          if(tmpMaps2->content==NULL)
2403            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2404          else
2405            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2406          tmpm=tmpm->next;
2407        }
2408      }
2409      addToMap(tmpMaps2->content,"inRequest","false");
2410      if(type==0){
2411        map *tmpMap=getMap(tmpMaps2->content,"value");
2412        if(tmpMap==NULL)
2413          addToMap(tmpMaps2->content,"value","NULL");
2414      }
2415      if(out1==NULL){
2416        *out=dupMaps(&tmpMaps2);
2417        out1=*out;
2418      }
2419      else
2420        addMapsToMaps(&out1,tmpMaps2);
2421      freeMap(&tmpMaps2->content);
2422      free(tmpMaps2->content);
2423      tmpMaps2->content=NULL;
2424      freeMaps(&tmpMaps2);
2425      free(tmpMaps2);
2426      tmpMaps2=NULL;
2427    }
2428    else{
2429      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2430                                             tmpMaps->content);
2431      if(type==0) {
2432        /**
2433         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2434         * content map.
2435         */
2436        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2437        if(tmpMap1!=NULL){
2438          if(tmpMaps->content==NULL)
2439            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2440          else
2441            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2442        }
2443        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2444        if(tmpMaxO!=NULL){
2445          if(tmpMaps->content==NULL)
2446            tmpMaps->content=createMap("maxOccurs",tmpMap1->value);
2447          else
2448            addToMap(tmpMaps->content,"maxOccurs",tmpMap1->value);
2449        }
2450        /**
2451         * Parsing BoundingBoxData, fill the following map and then add it to
2452         * the content map of the Input maps:
2453         * lowerCorner, upperCorner, srs and dimensions
2454         * cf. parseBoundingBox
2455         */
2456        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2457          maps* tmpI=getMaps(*out,tmpInputs->name);
2458          if(tmpI!=NULL){
2459            map* tmpV=getMap(tmpI->content,"value");
2460            if(tmpV!=NULL){
2461              char *tmpVS=strdup(tmpV->value);
2462              map* tmp=parseBoundingBox(tmpVS);
2463              free(tmpVS);
2464              map* tmpC=tmp;
2465              while(tmpC!=NULL){
2466                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2467                tmpC=tmpC->next;
2468              }
2469              freeMap(&tmp);
2470              free(tmp);
2471            }
2472          }
2473        }
2474      }
2475
2476      if(tmpIoType!=NULL){
2477        map* tmpContent=tmpIoType->content;
2478        map* cval=NULL;
2479        int hasPassed=-1;
2480        while(tmpContent!=NULL){
2481          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2482#ifdef DEBUG
2483            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2484#endif
2485            if(tmpMaps->content==NULL)
2486              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2487            else
2488              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2489           
2490            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
2491              map* length=getMap(tmpMaps->content,"length");
2492              int i;
2493              char *tcn=strdup(tmpContent->name);
2494              for(i=1;i<atoi(length->value);i++){
2495#ifdef DEBUG
2496                dumpMap(tmpMaps->content);
2497                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
2498#endif
2499                int len=strlen((char*) tcn);
2500                char *tmp1=(char *)malloc((len+10)*sizeof(char));
2501                sprintf(tmp1,"%s_%d",tcn,i);
2502#ifdef DEBUG
2503                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
2504#endif
2505                addToMap(tmpMaps->content,tmp1,tmpContent->value);
2506                free(tmp1);
2507                hasPassed=1;
2508              }
2509              free(tcn);
2510            }
2511          }
2512          tmpContent=tmpContent->next;
2513        }
2514#ifdef USE_MS
2515        /**
2516         * check for useMapServer presence
2517         */
2518        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
2519        if(tmpCheck!=NULL){
2520          // Get the default value
2521          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
2522          tmpCheck=getMap(tmpMaps->content,"mimeType");
2523          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
2524          map* cursor=tmpIoType->content;
2525          while(cursor!=NULL){
2526            addToMap(tmpMaps->content,cursor->name,cursor->value);
2527            cursor=cursor->next;
2528          }
2529         
2530          cursor=tmpInputs->content;
2531          while(cursor!=NULL){
2532            if(strcasecmp(cursor->name,"Title")==0 ||
2533               strcasecmp(cursor->name,"Abstract")==0)
2534              addToMap(tmpMaps->content,cursor->name,cursor->value);
2535           cursor=cursor->next;
2536          }
2537        }
2538#endif
2539      }
2540      if(tmpMaps->content==NULL)
2541        tmpMaps->content=createMap("inRequest","true");
2542      else
2543        addToMap(tmpMaps->content,"inRequest","true");
2544
2545    }
2546    tmpInputs=tmpInputs->next;
2547  }
2548  return "";
2549}
2550
2551/**
2552 * parseBoundingBox : parse a BoundingBox string
2553 *
2554 * OGC 06-121r3 : 10.2 Bounding box
2555 *
2556 * value is provided as : lowerCorner,upperCorner,crs,dimension
2557 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2558 *
2559 * Need to create a map to store boundingbox informations :
2560 *  - lowerCorner : double,double (minimum within this bounding box)
2561 *  - upperCorner : double,double (maximum within this bounding box)
2562 *  - crs : URI (Reference to definition of the CRS)
2563 *  - dimensions : int
2564 *
2565 * Note : support only 2D bounding box.
2566 */
2567map* parseBoundingBox(const char* value){
2568  map *res=NULL;
2569  if(value!=NULL){
2570    char *cv,*cvp;
2571    cv=strtok_r((char*) value,",",&cvp);
2572    int cnt=0;
2573    int icnt=0;
2574    char *currentValue=NULL;
2575    while(cv){
2576      if(cnt<2)
2577        if(currentValue!=NULL){
2578          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
2579          sprintf(finalValue,"%s%s",currentValue,cv);
2580          switch(cnt){
2581          case 0:
2582            res=createMap("lowerCorner",finalValue);
2583            break;
2584          case 1:
2585            addToMap(res,"upperCorner",finalValue);
2586            icnt=-1;
2587            break;
2588          }
2589          cnt++;
2590          free(currentValue);
2591          currentValue=NULL;
2592          free(finalValue);
2593        }
2594        else{
2595          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
2596          sprintf(currentValue,"%s ",cv);
2597        }
2598      else
2599        if(cnt==2){
2600          addToMap(res,"crs",cv);
2601          cnt++;
2602        }
2603        else
2604          addToMap(res,"dimensions",cv);
2605      icnt++;
2606      cv=strtok_r(NULL,",",&cvp);
2607    }
2608  }
2609  return res;
2610}
2611
2612/**
2613 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2614 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2615 * Lower/UpperCorner nodes to a pre-existing XML node.
2616 */
2617void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2618
2619  xmlNodePtr bb,lw,uc;
2620
2621  map* tmp=getMap(boundingbox,"value");
2622
2623  tmp=getMap(boundingbox,"lowerCorner");
2624  if(tmp!=NULL){
2625    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2626    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2627  }
2628
2629  tmp=getMap(boundingbox,"upperCorner");
2630  if(tmp!=NULL){
2631    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2632    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2633  }
2634
2635  tmp=getMap(boundingbox,"crs");
2636  if(tmp!=NULL)
2637    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2638
2639  tmp=getMap(boundingbox,"dimensions");
2640  if(tmp!=NULL)
2641    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2642
2643  xmlAddChild(n,lw);
2644  xmlAddChild(n,uc);
2645
2646}
2647
2648void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2649  if(file==NULL)
2650    rewind(stdout);
2651  xmlNodePtr n;
2652  xmlDocPtr doc;
2653  xmlNsPtr ns_ows,ns_xsi;
2654  xmlChar *xmlbuff;
2655  int buffersize;
2656  char *encoding=getEncoding(m);
2657  map *tmp;
2658  if(file==NULL){
2659    int pid=0;
2660    tmp=getMapFromMaps(m,"lenv","sid");
2661    if(tmp!=NULL)
2662      pid=atoi(tmp->value);
2663    if(pid==getpid()){
2664      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2665    }
2666    fflush(stdout);
2667  }
2668
2669  doc = xmlNewDoc(BAD_CAST "1.0");
2670  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2671  ns_ows=usedNs[owsId];
2672  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2673  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
2674  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2675  ns_xsi=usedNs[xsiId];
2676  xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2677  map *tmp1=getMap(boundingbox->content,"value");
2678  tmp=parseBoundingBox(tmp1->value);
2679  printBoundingBox(ns_ows,n,tmp);
2680  xmlDocSetRootElement(doc, n);
2681
2682  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2683  if(file==NULL)
2684    printf("%s",xmlbuff);
2685  else{
2686    fprintf(file,"%s",xmlbuff);
2687  }
2688
2689  if(tmp!=NULL){
2690    freeMap(&tmp);
2691    free(tmp);
2692  }
2693  xmlFree(xmlbuff);
2694  xmlFreeDoc(doc);
2695  xmlCleanupParser();
2696  zooXmlCleanupNs();
2697 
2698}
2699
2700
2701char* getMd5(char* url){
2702  EVP_MD_CTX md5ctx;
2703  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
2704  unsigned char result[EVP_MAX_MD_SIZE];
2705  unsigned int len;
2706  EVP_DigestInit(&md5ctx, EVP_md5());
2707  EVP_DigestUpdate(&md5ctx, url, strlen(url));
2708  EVP_DigestFinal_ex(&md5ctx,result,&len);
2709  EVP_MD_CTX_cleanup(&md5ctx);
2710  int i;
2711  for(i = 0; i < len; i++){
2712    if(i>0){
2713      char *tmp=strdup(fresult);
2714      sprintf(fresult,"%s%02x", tmp,result[i]);
2715      free(tmp);
2716    }
2717    else
2718      sprintf(fresult,"%02x",result[i]);
2719  }
2720  return fresult;
2721}
2722
2723/**
2724 * Cache a file for a given request
2725 */
2726void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
2727  map* tmp=getMapFromMaps(conf,"main","cacheDir");
2728  if(tmp!=NULL){
2729    char* md5str=getMd5(request);
2730    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
2731    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
2732#ifdef DEBUG
2733    fprintf(stderr,"Cache list : %s\n",fname);
2734    fflush(stderr);
2735#endif
2736    FILE* fo=fopen(fname,"w+");
2737    fwrite(content,sizeof(char),length,fo);
2738    fclose(fo);
2739
2740    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
2741    fo=fopen(fname,"w+");
2742#ifdef DEBUG
2743    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
2744#endif
2745    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
2746    fclose(fo);
2747
2748    free(md5str);
2749    free(fname);
2750  }
2751}
2752
2753char* isInCache(maps* conf,char* request){
2754  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
2755  if(tmpM!=NULL){
2756    char* md5str=getMd5(request);
2757#ifdef DEBUG
2758    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
2759#endif
2760    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
2761    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
2762    struct stat f_status;
2763    int s=stat(fname, &f_status);
2764    if(s==0 && f_status.st_size>0){
2765      free(md5str);
2766      return fname;
2767    }
2768    free(md5str);
2769    free(fname);
2770  }
2771  return NULL;
2772}
2773
2774/**
2775 * loadRemoteFile:
2776 * Try to load file from cache or download a remote file if not in cache
2777 */
2778int loadRemoteFile(maps* m,map* content,HINTERNET hInternet,char *url){
2779  HINTERNET res;
2780  char* fcontent;
2781  char* cached=isInCache(m,url);
2782  char *mimeType=NULL;
2783  int fsize;
2784  int hasF=-1;
2785  if(cached!=NULL){
2786    struct stat f_status;
2787    int s=stat(cached, &f_status);
2788    if(s==0){
2789      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2790      FILE* f=fopen(cached,"rb");
2791      int len=fread(fcontent,f_status.st_size,1,f);
2792      fsize=f_status.st_size;
2793      fcontent[fsize]=0;
2794      fclose(f);
2795    }
2796    cached[strlen(cached)-1]='m';
2797    s=stat(cached, &f_status);
2798    if(s==0){
2799      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2800      FILE* f=fopen(cached,"rb");
2801      int len=fread(mimeType,f_status.st_size,1,f);
2802      mimeType[f_status.st_size]=0;
2803      fclose(f);
2804    }
2805  }else{
2806    res=InternetOpenUrl(hInternet,url,NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
2807    fcontent=(char*)malloc((res.nDataLen+1)*sizeof(char));
2808    if(fcontent == NULL){
2809      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2810    }
2811    size_t dwRead;
2812    InternetReadFile(res, (LPVOID)fcontent, res.nDataLen, &dwRead);
2813    fcontent[res.nDataLen]=0;
2814    fsize=res.nDataLen;
2815    mimeType=(char*)res.mimeType;
2816  }
2817  if(fsize==0){
2818    return errorException(m, _("Unable to download the file."), "InternalError",NULL);
2819  }
2820
2821  if(mimeType!=NULL){
2822    addToMap(content,"fmimeType",mimeType);
2823  }
2824
2825  map* tmpMap=getMapOrFill(content,"value","");
2826   
2827  free(tmpMap->value);
2828  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
2829  if(tmpMap->value==NULL)
2830    fprintf(stderr,"Unable to allocate memory!\n");
2831  //snprintf(tmpMap->value,(fsize+1)*sizeof(char),fcontent);
2832  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
2833 
2834  char ltmp1[256];
2835  sprintf(ltmp1,"%d",fsize);
2836  addToMap(content,"size",ltmp1);
2837  if(cached==NULL)
2838    addToCache(m,url,fcontent,mimeType,fsize);
2839  else{
2840    free(fcontent);
2841    free(mimeType);
2842    free(cached);
2843  }
2844  return 0;
2845}
2846
2847int errorException(maps *m, const char *message, const char *errorcode, const char *locator) 
2848{
2849  map* errormap = createMap("text", message);
2850  addToMap(errormap,"code", errorcode);
2851  if(locator!=NULL)
2852    addToMap(errormap,"locator", locator);
2853  else
2854    addToMap(errormap,"locator", "NULL");
2855  printExceptionReportResponse(m,errormap);
2856  freeMap(&errormap);
2857  free(errormap);
2858  return -1;
2859}
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