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

Last change on this file since 386 was 386, checked in by djay, 11 years ago

Small fix to return exception report when storing the result on disk failed. Thanks to Luca Delucchi for pointing this issue out.

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