Ticket #86: service_internal.c

File service_internal.c, 77.5 KB (added by landmark, 10 years ago)

service_internal.c (modified from revision # 452)

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

Search

Context Navigation

ZOO Sponsors

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

Become a sponsor !

Knowledge partners

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

Become a knowledge partner

Related links

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