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

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

Fix issue reported on mailing list about base64 encoding.

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