source: branches/PublicaMundi_David-devel/zoo-project/zoo-kernel/service_internal.c @ 530

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

Fixes for metapath definition with prefixed names.

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