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

Last change on this file since 451 was 451, checked in by djay, 6 years ago

Small fixes for building on windows platform.

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