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

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

Add the optional Ruby Language Support to the ZOO-Kernel with an API similar to the Python ZOO-API. Small rewrite of Python support. Fix issue #86 and #87. Add usid in [lenv] section, this value is used to generate an unique identifier based on time and the process identifier. This usid is now used to name the stored result or the mapfile generated. Remove *some* warning messages displayed at compilation time.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 75.0 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2013 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal.h"
26#ifdef USE_MS
27#include "service_internal_ms.h"
28#endif
29
30#ifndef TRUE
31#define TRUE 1
32#endif
33#ifndef FALSE
34#define FALSE -1
35#endif
36
37void printHeaders(maps* m){
38  maps *_tmp=getMaps(m,"headers");
39  if(_tmp!=NULL){
40    map* _tmp1=_tmp->content;
41    while(_tmp1!=NULL){
42      printf("%s: %s\r\n",_tmp1->name,_tmp1->value);
43      _tmp1=_tmp1->next;
44    }
45  }
46}
47
48void addLangAttr(xmlNodePtr n,maps *m){
49  map *tmpLmap=getMapFromMaps(m,"main","language");
50  if(tmpLmap!=NULL)
51    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST tmpLmap->value);
52  else
53    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST "en-US");
54}
55
56/* Converts a hex character to its integer value */
57char from_hex(char ch) {
58  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
59}
60
61/* Converts an integer value to its hex character*/
62char to_hex(char code) {
63  static char hex[] = "0123456789abcdef";
64  return hex[code & 15];
65}
66
67#ifdef WIN32
68
69#include <windows.h>
70#include <stdio.h>
71#include <conio.h>
72#include <tchar.h>
73
74#define SHMEMSIZE 4096
75
76static LPVOID lpvMemG = NULL;      // pointer to shared memory
77static HANDLE hMapObjectG = NULL;  // handle to file mapping
78
79void updateStatus(maps *conf){
80  LPWSTR lpszTmp;
81  BOOL fInit;
82  char *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 ||
1215            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     
1896      printExceptionReportResponse(m,errormap);
1897      freeMap(&errormap);
1898      free(errormap);
1899      return;
1900    }
1901    else{
1902      fclose(teste);
1903      dumpMapsToFile(tmpSess,session_file_path);
1904    }
1905  }
1906 
1907  if(res==SERVICE_FAILED){
1908    map * errormap;
1909    map *lenv;
1910    lenv=getMapFromMaps(m,"lenv","message");
1911    char *tmp0;
1912    if(lenv!=NULL){
1913      tmp0=(char*)malloc((strlen(lenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "+1)))*sizeof(char));
1914      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
1915    }
1916    else{
1917      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
1918      sprintf(tmp0,_("Unable to run the Service. No more information was returned back by the Service."));
1919    }
1920    errormap = createMap("text",tmp0);
1921    free(tmp0);
1922    addToMap(errormap,"code", "InternalError");
1923    printExceptionReportResponse(m,errormap);
1924    freeMap(&errormap);
1925    free(errormap);
1926    return;
1927  }
1928
1929  if(asRaw==0){
1930#ifdef DEBUG
1931    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
1932    dumpMaps(request_outputs);
1933#endif
1934    maps* tmpI=request_outputs;
1935    while(tmpI!=NULL){
1936#ifdef USE_MS
1937      map* testMap=getMap(tmpI->content,"useMapserver");       
1938#endif
1939      toto=getMap(tmpI->content,"asReference");
1940#ifdef USE_MS
1941      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
1942#else
1943      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
1944#endif
1945        {
1946        elements* in=getElements(s->outputs,tmpI->name);
1947        char *format=NULL;
1948        if(in!=NULL){
1949          format=strdup(in->format);
1950        }else
1951          format=strdup("LiteralData");
1952        if(strcasecmp(format,"BoundingBoxData")==0){
1953          addToMap(tmpI->content,"extension","xml");
1954          addToMap(tmpI->content,"mimeType","text/xml");
1955          addToMap(tmpI->content,"encoding","UTF-8");
1956          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
1957        }
1958        map *ext=getMap(tmpI->content,"extension");
1959        map *tmp1=getMapFromMaps(m,"main","tmpPath");
1960        char *file_name,*file_path;
1961        bool hasExt=true;
1962        if(ext==NULL){
1963          // We can fallback to a default list of supported formats using
1964          // mimeType information if present here. Maybe we can add more formats
1965          // here.
1966          // If mimeType was not found, we then set txt as the default extension
1967          map* mtype=getMap(tmpI->content,"mimeType");
1968          if(mtype!=NULL){
1969            if(strcasecmp(mtype->value,"text/xml")==0)
1970              ext=createMap("extension","xml");
1971            else if(strcasecmp(mtype->value,"application/json")==0)
1972              ext=createMap("extension","js");
1973            else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
1974              ext=createMap("extension","kml");
1975            else if(strncmp(mtype->value,"image/",6)==0)
1976              ext=createMap("extension",strstr(mtype->value,"/")+1);
1977            else
1978              ext=createMap("extension","txt");
1979          }
1980          else
1981            ext=createMap("extension","txt");
1982          hasExt=false;
1983        }
1984        file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
1985        int cpid0=cpid+time(NULL);
1986        sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
1987        file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
1988        sprintf(file_path,"%s/%s",tmp1->value,file_name);
1989        FILE *ofile=fopen(file_path,"wb");
1990        if(ofile==NULL){
1991          char tmpMsg[1024];
1992          sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
1993          map * errormap = createMap("text",tmpMsg);
1994          addToMap(errormap,"code", "InternalError");
1995          printExceptionReportResponse(m,errormap);
1996          freeMap(&errormap);
1997          free(errormap);
1998          free(file_name);
1999          free(file_path);
2000          return;
2001        }
2002        free(file_path);
2003        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2004        map *tmp3=getMapFromMaps(m,"main","serverAddress");
2005        char *file_url;
2006        if(strncasecmp(tmp2->value,"http://",7)==0){
2007          file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name))*sizeof(char));
2008          sprintf(file_url,"%s/%s",tmp2->value,file_name);
2009        }else{
2010          file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name))*sizeof(char));
2011          sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2012        }
2013        addToMap(tmpI->content,"Reference",file_url);
2014        if(!hasExt){
2015          freeMap(&ext);
2016          free(ext);
2017        }
2018        toto=getMap(tmpI->content,"value");
2019        if(strcasecmp(format,"BoundingBoxData")!=0){
2020          map* size=getMap(tmpI->content,"size");
2021          if(size!=NULL && toto!=NULL)
2022            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2023          else
2024            if(toto!=NULL && toto->value!=NULL)
2025              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2026        }else{
2027          printBoundingBoxDocument(m,tmpI,ofile);
2028        }
2029        free(format);
2030        fclose(ofile);
2031        free(file_name);
2032        free(file_url); 
2033      }
2034#ifdef USE_MS
2035      else{
2036        if(testMap!=NULL){
2037          setReferenceUrl(m,tmpI);
2038        }
2039      }
2040#endif
2041      tmpI=tmpI->next;
2042    }
2043    map *r_inputs=getMap(s->content,"serviceProvider");
2044#ifdef DEBUG
2045    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2046    dumpMaps(m);
2047#endif
2048    printProcessResponse(m,request_inputs1,cpid,
2049                         s,r_inputs->value,res,
2050                         request_inputs,
2051                         request_outputs);
2052    }
2053    else{
2054      /**
2055       * We get the requested output or fallback to the first one if the
2056       * requested one is not present in the resulting outputs maps.
2057       */
2058      maps* tmpI=NULL;
2059      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2060      if(tmpIV!=NULL){
2061        tmpI=getMaps(request_outputs,tmpIV->value);
2062      }
2063      if(tmpI==NULL)
2064        tmpI=request_outputs;
2065      elements* e=getElements(s->outputs,tmpI->name);
2066      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2067        printBoundingBoxDocument(m,tmpI,NULL);
2068      }else{
2069        toto=getMap(tmpI->content,"value");
2070        if(toto==NULL){
2071          char tmpMsg[1024];
2072          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2073          map * errormap = createMap("text",tmpMsg);
2074          addToMap(errormap,"code", "InvalidParameterValue");
2075          printExceptionReportResponse(m,errormap);
2076          freeMap(&errormap);
2077          free(errormap);
2078          return;
2079        }
2080        map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2081        if(fname!=NULL)
2082          printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2083        map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2084        if(rs!=NULL)
2085          printf("Content-Length: %s\r\n",rs->value);
2086        printHeaders(m);
2087        char mime[1024];
2088        map* mi=getMap(tmpI->content,"mimeType");
2089#ifdef DEBUG
2090        fprintf(stderr,"SERVICE OUTPUTS\n");
2091        dumpMaps(request_outputs);
2092        fprintf(stderr,"SERVICE OUTPUTS\n");
2093#endif
2094        map* en=getMap(tmpI->content,"encoding");
2095        if(mi!=NULL && en!=NULL)
2096          sprintf(mime,
2097                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2098                  mi->value,en->value);
2099        else
2100          if(mi!=NULL)
2101            sprintf(mime,
2102                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2103                    mi->value);
2104          else
2105            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2106        printf("%s",mime);
2107        if(rs!=NULL)
2108          fwrite(toto->value,1,atoi(rs->value),stdout);
2109        else
2110          fwrite(toto->value,1,strlen(toto->value),stdout);
2111#ifdef DEBUG
2112        dumpMap(toto);
2113#endif
2114      }
2115    }
2116}
2117
2118char *base64(const char *input, int length)
2119{
2120  BIO *bmem, *b64;
2121  BUF_MEM *bptr;
2122
2123  b64 = BIO_new(BIO_f_base64());
2124  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2125  bmem = BIO_new(BIO_s_mem());
2126  b64 = BIO_push(b64, bmem);
2127  BIO_write(b64, input, length);
2128  BIO_flush(b64);
2129  BIO_get_mem_ptr(b64, &bptr);
2130
2131  char *buff = (char *)malloc((bptr->length)*sizeof(char));
2132  memcpy(buff, bptr->data, bptr->length-1);
2133  buff[bptr->length-1] = 0;
2134
2135  BIO_free_all(b64);
2136
2137  return buff;
2138}
2139
2140char *base64d(const char *input, int length,int* red)
2141{
2142  BIO *b64, *bmem;
2143
2144  char *buffer = (char *)malloc(length);
2145  if(buffer){
2146    memset(buffer, 0, length);
2147    b64 = BIO_new(BIO_f_base64());
2148    if(b64){
2149      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2150      bmem = BIO_push(b64, bmem);
2151      *red=BIO_read(bmem, buffer, length);
2152      buffer[length-1]=0;
2153      BIO_free_all(bmem);
2154    }
2155  }
2156  return buffer;
2157}
2158
2159void ensureDecodedBase64(maps **in){
2160  maps* cursor=*in;
2161  while(cursor!=NULL){
2162    map *tmp=getMap(cursor->content,"encoding");
2163    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2164      tmp=getMap(cursor->content,"value");
2165      addToMap(cursor->content,"base64_value",tmp->value);
2166      int size=0;
2167      char *s=strdup(tmp->value);
2168      free(tmp->value);
2169      tmp->value=base64d(s,strlen(s),&size);
2170      free(s);
2171      char sizes[1024];
2172      sprintf(sizes,"%d",size);
2173      addToMap(cursor->content,"size",sizes);
2174    }
2175    cursor=cursor->next;
2176  }
2177}
2178
2179char* addDefaultValues(maps** out,elements* in,maps* m,int type){
2180  elements* tmpInputs=in;
2181  maps* out1=*out;
2182  if(type==1){
2183    while(out1!=NULL){
2184      if(getElements(in,out1->name)==NULL)
2185        return out1->name;
2186      out1=out1->next;
2187    }
2188    out1=*out;
2189  }
2190  while(tmpInputs!=NULL){
2191    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2192    if(tmpMaps==NULL){
2193      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2194      tmpMaps2->name=strdup(tmpInputs->name);
2195      tmpMaps2->content=NULL;
2196      tmpMaps2->next=NULL;
2197     
2198      if(type==0){
2199        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2200        if(tmpMapMinO!=NULL)
2201          if(atoi(tmpMapMinO->value)>=1){
2202            freeMaps(&tmpMaps2);
2203            free(tmpMaps2);
2204            return tmpInputs->name;
2205          }
2206          else{
2207            if(tmpMaps2->content==NULL)
2208              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2209            else
2210              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2211          }
2212        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2213        if(tmpMaxO!=NULL)
2214          if(tmpMaps2->content==NULL)
2215            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2216          else
2217            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2218      }
2219
2220      iotype* tmpIoType=tmpInputs->defaults;
2221      if(tmpIoType!=NULL){
2222        map* tmpm=tmpIoType->content;
2223        while(tmpm!=NULL){
2224          if(tmpMaps2->content==NULL)
2225            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2226          else
2227            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2228          tmpm=tmpm->next;
2229        }
2230      }
2231      addToMap(tmpMaps2->content,"inRequest","false");
2232      if(type==0){
2233        map *tmpMap=getMap(tmpMaps2->content,"value");
2234        if(tmpMap==NULL)
2235          addToMap(tmpMaps2->content,"value","NULL");
2236      }
2237      if(out1==NULL){
2238        *out=dupMaps(&tmpMaps2);
2239        out1=*out;
2240      }
2241      else
2242        addMapsToMaps(&out1,tmpMaps2);
2243      freeMap(&tmpMaps2->content);
2244      free(tmpMaps2->content);
2245      tmpMaps2->content=NULL;
2246      freeMaps(&tmpMaps2);
2247      free(tmpMaps2);
2248      tmpMaps2=NULL;
2249    }
2250    else{
2251      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2252                                             tmpMaps->content);
2253      if(type==0) {
2254        /**
2255         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2256         * content map.
2257         */
2258        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2259        if(tmpMap1!=NULL){
2260          if(tmpMaps->content==NULL)
2261            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2262          else
2263            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2264        }
2265        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2266        if(tmpMaxO!=NULL){
2267          if(tmpMaps->content==NULL)
2268            tmpMaps->content=createMap("maxOccurs",tmpMap1->value);
2269          else
2270            addToMap(tmpMaps->content,"maxOccurs",tmpMap1->value);
2271        }
2272        /**
2273         * Parsing BoundingBoxData, fill the following map and then add it to
2274         * the content map of the Input maps:
2275         * lowerCorner, upperCorner, srs and dimensions
2276         * cf. parseBoundingBox
2277         */
2278        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2279          maps* tmpI=getMaps(*out,tmpInputs->name);
2280          if(tmpI!=NULL){
2281            map* tmpV=getMap(tmpI->content,"value");
2282            if(tmpV!=NULL){
2283              char *tmpVS=strdup(tmpV->value);
2284              map* tmp=parseBoundingBox(tmpVS);
2285              free(tmpVS);
2286              map* tmpC=tmp;
2287              while(tmpC!=NULL){
2288                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2289                tmpC=tmpC->next;
2290              }
2291              freeMap(&tmp);
2292              free(tmp);
2293            }
2294          }
2295        }
2296      }
2297
2298      if(tmpIoType!=NULL){
2299        map* tmpContent=tmpIoType->content;
2300        map* cval=NULL;
2301        int hasPassed=-1;
2302        while(tmpContent!=NULL){
2303          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2304#ifdef DEBUG
2305            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2306#endif
2307            if(tmpMaps->content==NULL)
2308              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2309            else
2310              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2311           
2312            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
2313              map* length=getMap(tmpMaps->content,"length");
2314              int i;
2315              char *tcn=strdup(tmpContent->name);
2316              for(i=1;i<atoi(length->value);i++){
2317#ifdef DEBUG
2318                dumpMap(tmpMaps->content);
2319                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
2320#endif
2321                int len=strlen((char*) tcn);
2322                char *tmp1=(char *)malloc((len+10)*sizeof(char));
2323                sprintf(tmp1,"%s_%d",tcn,i);
2324#ifdef DEBUG
2325                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
2326#endif
2327                addToMap(tmpMaps->content,tmp1,tmpContent->value);
2328                free(tmp1);
2329                hasPassed=1;
2330              }
2331              free(tcn);
2332            }
2333          }
2334          tmpContent=tmpContent->next;
2335        }
2336#ifdef USE_MS
2337        /**
2338         * check for useMapServer presence
2339         */
2340        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
2341        if(tmpCheck!=NULL){
2342          // Get the default value
2343          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
2344          tmpCheck=getMap(tmpMaps->content,"mimeType");
2345          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
2346          map* cursor=tmpIoType->content;
2347          while(cursor!=NULL){
2348            addToMap(tmpMaps->content,cursor->name,cursor->value);
2349            cursor=cursor->next;
2350          }
2351         
2352          cursor=tmpInputs->content;
2353          while(cursor!=NULL){
2354            if(strcasecmp(cursor->name,"Title")==0 ||
2355               strcasecmp(cursor->name,"Abstract")==0)
2356              addToMap(tmpMaps->content,cursor->name,cursor->value);
2357           cursor=cursor->next;
2358          }
2359        }
2360#endif
2361      }
2362      if(tmpMaps->content==NULL)
2363        tmpMaps->content=createMap("inRequest","true");
2364      else
2365        addToMap(tmpMaps->content,"inRequest","true");
2366
2367    }
2368    tmpInputs=tmpInputs->next;
2369  }
2370  return "";
2371}
2372
2373/**
2374 * parseBoundingBox : parse a BoundingBox string
2375 *
2376 * OGC 06-121r3 : 10.2 Bounding box
2377 *
2378 * value is provided as : lowerCorner,upperCorner,crs,dimension
2379 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2380 *
2381 * Need to create a map to store boundingbox informations :
2382 *  - lowerCorner : double,double (minimum within this bounding box)
2383 *  - upperCorner : double,double (maximum within this bounding box)
2384 *  - crs : URI (Reference to definition of the CRS)
2385 *  - dimensions : int
2386 *
2387 * Note : support only 2D bounding box.
2388 */
2389map* parseBoundingBox(const char* value){
2390  map *res=NULL;
2391  if(value!=NULL){
2392    char *cv,*cvp;
2393    cv=strtok_r((char*) value,",",&cvp);
2394    int cnt=0;
2395    int icnt=0;
2396    char *currentValue=NULL;
2397    while(cv){
2398      if(cnt<2)
2399        if(currentValue!=NULL){
2400          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
2401          sprintf(finalValue,"%s%s",currentValue,cv);
2402          switch(cnt){
2403          case 0:
2404            res=createMap("lowerCorner",finalValue);
2405            break;
2406          case 1:
2407            addToMap(res,"upperCorner",finalValue);
2408            icnt=-1;
2409            break;
2410          }
2411          cnt++;
2412          free(currentValue);
2413          currentValue=NULL;
2414          free(finalValue);
2415        }
2416        else{
2417          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
2418          sprintf(currentValue,"%s ",cv);
2419        }
2420      else
2421        if(cnt==2){
2422          addToMap(res,"crs",cv);
2423          cnt++;
2424        }
2425        else
2426          addToMap(res,"dimensions",cv);
2427      icnt++;
2428      cv=strtok_r(NULL,",",&cvp);
2429    }
2430  }
2431  return res;
2432}
2433
2434/**
2435 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2436 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2437 * Lower/UpperCorner nodes to a pre-existing XML node.
2438 */
2439void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2440
2441  xmlNodePtr bb,lw,uc;
2442
2443  map* tmp=getMap(boundingbox,"value");
2444
2445  tmp=getMap(boundingbox,"lowerCorner");
2446  if(tmp!=NULL){
2447    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2448    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2449  }
2450
2451  tmp=getMap(boundingbox,"upperCorner");
2452  if(tmp!=NULL){
2453    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2454    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2455  }
2456
2457  tmp=getMap(boundingbox,"crs");
2458  if(tmp!=NULL)
2459    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2460
2461  tmp=getMap(boundingbox,"dimensions");
2462  if(tmp!=NULL)
2463    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2464
2465  xmlAddChild(n,lw);
2466  xmlAddChild(n,uc);
2467
2468}
2469
2470void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2471  if(file==NULL)
2472    rewind(stdout);
2473  xmlNodePtr n;
2474  xmlDocPtr doc;
2475  xmlNsPtr ns_ows,ns_xsi;
2476  xmlChar *xmlbuff;
2477  int buffersize;
2478  char *encoding=getEncoding(m);
2479  map *tmp;
2480  if(file==NULL){
2481    int pid=0;
2482    tmp=getMapFromMaps(m,"lenv","sid");
2483    if(tmp!=NULL)
2484      pid=atoi(tmp->value);
2485    if(pid==getpid()){
2486      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2487    }
2488    fflush(stdout);
2489  }
2490
2491  doc = xmlNewDoc(BAD_CAST "1.0");
2492  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2493  ns_ows=usedNs[owsId];
2494  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2495  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
2496  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2497  ns_xsi=usedNs[xsiId];
2498  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");
2499  map *tmp1=getMap(boundingbox->content,"value");
2500  tmp=parseBoundingBox(tmp1->value);
2501  printBoundingBox(ns_ows,n,tmp);
2502  xmlDocSetRootElement(doc, n);
2503
2504  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2505  if(file==NULL)
2506    printf("%s",xmlbuff);
2507  else{
2508    fprintf(file,"%s",xmlbuff);
2509  }
2510
2511  if(tmp!=NULL){
2512    freeMap(&tmp);
2513    free(tmp);
2514  }
2515  xmlFree(xmlbuff);
2516  xmlFreeDoc(doc);
2517  xmlCleanupParser();
2518  zooXmlCleanupNs();
2519 
2520}
2521
2522
2523char* getMd5(char* url){
2524  EVP_MD_CTX md5ctx;
2525  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
2526  unsigned char result[EVP_MAX_MD_SIZE];
2527  unsigned int len;
2528  EVP_DigestInit(&md5ctx, EVP_md5());
2529  EVP_DigestUpdate(&md5ctx, url, strlen(url));
2530  EVP_DigestFinal_ex(&md5ctx,result,&len);
2531  EVP_MD_CTX_cleanup(&md5ctx);
2532  int i;
2533  for(i = 0; i < len; i++){
2534    if(i>0){
2535      char *tmp=strdup(fresult);
2536      sprintf(fresult,"%s%02x", tmp,result[i]);
2537      free(tmp);
2538    }
2539    else
2540      sprintf(fresult,"%02x",result[i]);
2541  }
2542  return fresult;
2543}
2544
2545/**
2546 * Cache a file for a given request
2547 */
2548void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
2549  map* tmp=getMapFromMaps(conf,"main","cacheDir");
2550  if(tmp!=NULL){
2551    char* md5str=getMd5(request);
2552    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
2553    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
2554#ifdef DEBUG
2555    fprintf(stderr,"Cache list : %s\n",fname);
2556    fflush(stderr);
2557#endif
2558    FILE* fo=fopen(fname,"w+");
2559    fwrite(content,sizeof(char),length,fo);
2560    fclose(fo);
2561
2562    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
2563    fo=fopen(fname,"w+");
2564#ifdef DEBUG
2565    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
2566#endif
2567    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
2568    fclose(fo);
2569
2570    free(md5str);
2571    free(fname);
2572  }
2573}
2574
2575char* isInCache(maps* conf,char* request){
2576  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
2577  if(tmpM!=NULL){
2578    char* md5str=getMd5(request);
2579#ifdef DEBUG
2580    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
2581#endif
2582    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
2583    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
2584    struct stat f_status;
2585    int s=stat(fname, &f_status);
2586    if(s==0 && f_status.st_size>0){
2587      free(md5str);
2588      return fname;
2589    }
2590    free(md5str);
2591    free(fname);
2592  }
2593  return NULL;
2594}
2595
2596/**
2597 * loadRemoteFile:
2598 * Try to load file from cache or download a remote file if not in cache
2599 */
2600int loadRemoteFile(maps* m,map* content,HINTERNET hInternet,char *url){
2601  HINTERNET res;
2602  char* fcontent;
2603  char* cached=isInCache(m,url);
2604  char *mimeType=NULL;
2605  int fsize;
2606  int hasF=-1;
2607  if(cached!=NULL){
2608    struct stat f_status;
2609    int s=stat(cached, &f_status);
2610    if(s==0){
2611      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2612      FILE* f=fopen(cached,"rb");
2613      int len=fread(fcontent,f_status.st_size,1,f);
2614      fsize=f_status.st_size;
2615      fcontent[fsize]=0;
2616      fclose(f);
2617    }
2618    cached[strlen(cached)-1]='m';
2619    s=stat(cached, &f_status);
2620    if(s==0){
2621      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2622      FILE* f=fopen(cached,"rb");
2623      int len=fread(mimeType,f_status.st_size,1,f);
2624      mimeType[f_status.st_size]=0;
2625      fclose(f);
2626    }
2627  }else{
2628    res=InternetOpenUrl(hInternet,url,NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
2629    fcontent=(char*)malloc((res.nDataLen+1)*sizeof(char));
2630    if(fcontent == NULL){
2631      return errorException(m, _("Unable to allocate memory."), "InternalError");
2632    }
2633    size_t dwRead;
2634    InternetReadFile(res, (LPVOID)fcontent, res.nDataLen, &dwRead);
2635    fcontent[res.nDataLen]=0;
2636    fsize=res.nDataLen;
2637    mimeType=(char*)res.mimeType;
2638  }
2639  if(fsize==0){
2640    return errorException(m, _("Unable to download the file."), "InternalError");
2641  }
2642
2643  if(mimeType!=NULL){
2644    addToMap(content,"fmimeType",mimeType);
2645  }
2646
2647  map* tmpMap=getMapOrFill(content,"value","");
2648   
2649  free(tmpMap->value);
2650  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
2651  if(tmpMap->value==NULL)
2652    fprintf(stderr,"Unable to allocate memory!\n");
2653  //snprintf(tmpMap->value,(fsize+1)*sizeof(char),fcontent);
2654  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
2655 
2656  char ltmp1[256];
2657  sprintf(ltmp1,"%d",fsize);
2658  addToMap(content,"size",ltmp1);
2659  if(cached==NULL)
2660    addToCache(m,url,fcontent,mimeType,fsize);
2661  else{
2662    free(fcontent);
2663    free(mimeType);
2664    free(cached);
2665  }
2666  return 0;
2667}
2668
2669int errorException(maps *m, const char *message, const char *errorcode) 
2670{
2671  map* errormap = createMap("text", message);
2672  addToMap(errormap,"code", errorcode);
2673  printExceptionReportResponse(m,errormap);
2674  freeMap(&errormap);
2675  free(errormap);
2676  return -1;
2677}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

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

Become a sponsor !

Knowledge partners

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

Become a knowledge partner

Related links

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