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

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

Remove memory leaks from ZOO-Kernel. Fix issue #99.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 86.6 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        hInternet=InternetOpen(
1874#ifndef WIN32
1875                               (LPCTSTR)
1876#endif
1877                               "ZooWPSClient\0",
1878                               INTERNET_OPEN_TYPE_PRECONFIG,
1879                               NULL,NULL, 0);
1880        testMap=getMap(m->content,"Reference");
1881        loadRemoteFile(&m,&m->content,hInternet,testMap->value);
1882        InternetCloseHandle(hInternet);
1883      }
1884#endif
1885      map* tmp1=getMap(m->content,"encoding");
1886      map* tmp2=getMap(m->content,"mimeType");
1887      map* tmp3=getMap(m->content,"value");
1888      int hasValue=1;
1889      if(tmp3==NULL){
1890        tmp3=createMap("value","");
1891        hasValue=-1;
1892      }
1893      if((tmp1!=NULL && strncmp(tmp1->value,"base64",6)==0)
1894         || (tmp2!=NULL && (strncmp(tmp2->value,"image/",6)==0 ||
1895                            (strncmp(tmp2->value,"application/",12)==0 &&
1896                             strncmp(tmp2->value,"application/json",16)!=0&&
1897                             strncmp(tmp2->value,"application/x-javascript",24)!=0&&
1898                             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)!=0))
1899             )) {
1900        map* rs=getMap(m->content,"size");
1901        bool isSized=true;
1902        if(rs==NULL){
1903          char tmp1[1024];
1904          sprintf(tmp1,"%u",strlen(tmp3->value));
1905          rs=createMap("size",tmp1);
1906          isSized=false;
1907        }
1908
1909        xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));
1910        if(!isSized){
1911          freeMap(&rs);
1912          free(rs);
1913        }
1914      }
1915      else if(tmp2!=NULL){
1916        if(strncmp(tmp2->value,"text/js",7)==0 ||
1917           strncmp(tmp2->value,"application/json",16)==0)
1918          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
1919        else{
1920          if(strncmp(tmp2->value,"text/xml",8)==0 ||
1921             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)==0){
1922            int li=zooXmlAddDoc(tmp3->value);
1923            xmlDocPtr doc = iDocs[li];
1924            xmlNodePtr ir = xmlDocGetRootElement(doc);
1925            xmlAddChild(nc3,ir);
1926          }
1927          else
1928            xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1929        }
1930        xmlAddChild(nc2,nc3);
1931      }
1932      else{
1933        xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1934      }
1935      if(hasValue<0){
1936        freeMap(&tmp3);
1937        free(tmp3);
1938      }
1939    }
1940  }
1941  else{
1942    tmpMap=getMap(m->content,"Reference");
1943    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
1944    if(strcasecmp(type,"Output")==0)
1945      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
1946    else
1947      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
1948    tmp=m->content;
1949#ifdef USE_MS
1950    map* testMap=getMap(tmp,"requestedMimeType");
1951#endif
1952    while(tmp!=NULL){
1953      if(strcasecmp(tmp->name,"mimeType")==0 ||
1954         strcasecmp(tmp->name,"encoding")==0 ||
1955         strcasecmp(tmp->name,"schema")==0 ||
1956         strcasecmp(tmp->name,"datatype")==0 ||
1957         strcasecmp(tmp->name,"uom")==0){
1958#ifdef USE_MS
1959        if(testMap!=NULL  && strncasecmp(testMap->value,"text/xml",8)!=0){
1960          if(strcasecmp(tmp->name,"mimeType")==0)
1961            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1962        }
1963        else
1964#endif
1965          xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1966      }
1967      tmp=tmp->next;
1968      xmlAddChild(nc2,nc3);
1969    }
1970  }
1971  xmlAddChild(nc1,nc2);
1972  xmlAddChild(nc,nc1);
1973
1974}
1975
1976void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
1977  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
1978 
1979  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
1980  xmlAddChild(root,nc2);
1981  map* tmp=amap;
1982  const char *tmp2[2];
1983  tmp2[0]="Title";
1984  tmp2[1]="Abstract";
1985  int j=0;
1986  for(j=0;j<2;j++){
1987    map* tmp1=getMap(tmp,tmp2[j]);
1988    if(tmp1!=NULL){
1989      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
1990      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
1991      xmlAddChild(root,nc2);
1992    }
1993  }
1994}
1995
1996char* getEncoding(maps* m){
1997  if(m!=NULL){
1998    map* tmp=getMap(m->content,"encoding");
1999    if(tmp!=NULL){
2000      return tmp->value;
2001    }
2002    else
2003      return (char*)"UTF-8";
2004  }
2005  else
2006    return (char*)"UTF-8"; 
2007}
2008
2009char* getVersion(maps* m){
2010  if(m!=NULL){
2011    map* tmp=getMap(m->content,"version");
2012    if(tmp!=NULL){
2013      return tmp->value;
2014    }
2015    else
2016      return (char*)"1.0.0";
2017  }
2018  else
2019    return (char*)"1.0.0";
2020}
2021
2022void printExceptionReportResponse(maps* m,map* s){
2023  if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
2024    return;
2025  int buffersize;
2026  xmlDocPtr doc;
2027  xmlChar *xmlbuff;
2028  xmlNodePtr n;
2029
2030  zooXmlCleanupNs();
2031  doc = xmlNewDoc(BAD_CAST "1.0");
2032  maps* tmpMap=getMaps(m,"main");
2033  char *encoding=getEncoding(tmpMap);
2034  const char *exceptionCode;
2035 
2036  map* tmp=getMap(s,"code");
2037  if(tmp!=NULL){
2038    if(strcmp(tmp->value,"OperationNotSupported")==0)
2039      exceptionCode="501 Not Implemented";
2040    else
2041      if(strcmp(tmp->value,"MissingParameterValue")==0 ||
2042         strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
2043         strcmp(tmp->value,"OptionNotSupported")==0 ||
2044         strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
2045         strcmp(tmp->value,"InvalidParameterValue")==0)
2046        exceptionCode="400 Bad request";
2047      else
2048        if(strcmp(tmp->value,"NoApplicableCode")==0)
2049          exceptionCode="501 Internal Server Error";
2050        else
2051          exceptionCode="501 Internal Server Error";
2052  }
2053  else
2054    exceptionCode="501 Internal Server Error";
2055
2056  if(m!=NULL){
2057    map *tmpSid=getMapFromMaps(m,"lenv","sid");
2058    if(tmpSid!=NULL){
2059      if( getpid()==atoi(tmpSid->value) ){
2060        printHeaders(m);
2061        printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
2062      }
2063    }
2064    else{
2065      printHeaders(m);
2066      printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
2067    }
2068  }else{
2069    printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
2070  }
2071  n=createExceptionReportNode(m,s,1);
2072  xmlDocSetRootElement(doc, n);
2073  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2074  printf("%s",xmlbuff);
2075  fflush(stdout);
2076  xmlFreeDoc(doc);
2077  xmlFree(xmlbuff);
2078  xmlCleanupParser();
2079  zooXmlCleanupNs();
2080  if(m!=NULL)
2081    setMapInMaps(m,"lenv","hasPrinted","true");
2082}
2083
2084xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
2085 
2086  xmlNsPtr ns,ns_xsi;
2087  xmlNodePtr n,nc,nc1;
2088
2089  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows","ows");
2090  ns=usedNs[nsid];
2091  if(use_ns==1){
2092    ns=NULL;
2093  }
2094  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
2095  if(use_ns==1){
2096    xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",NULL);
2097    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2098    ns_xsi=usedNs[xsiId];
2099    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");
2100  }
2101
2102
2103  addLangAttr(n,m);
2104  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
2105 
2106  nc = xmlNewNode(ns, BAD_CAST "Exception");
2107
2108  map* tmp=getMap(s,"code");
2109  if(tmp!=NULL)
2110    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
2111  else
2112    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
2113
2114  tmp=getMap(s,"locator");
2115  if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
2116    xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
2117
2118
2119  tmp=getMap(s,"text");
2120  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
2121  if(tmp!=NULL){
2122    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
2123  }
2124  else{
2125    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
2126  }
2127  xmlAddChild(nc,nc1);
2128  xmlAddChild(n,nc);
2129  return n;
2130}
2131
2132
2133void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
2134                    map* request_inputs1,int cpid,maps* m,int res){
2135#ifdef DEBUG
2136  dumpMaps(request_inputs);
2137  dumpMaps(request_outputs);
2138  fprintf(stderr,"printProcessResponse\n");
2139#endif
2140  map* toto=getMap(request_inputs1,"RawDataOutput");
2141  int asRaw=0;
2142  if(toto!=NULL)
2143    asRaw=1;
2144 
2145  maps* tmpSess=getMaps(m,"senv");
2146  if(tmpSess!=NULL){
2147    map *_tmp=getMapFromMaps(m,"lenv","cookie");
2148    char* sessId=NULL;
2149    if(_tmp!=NULL){
2150      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
2151      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
2152      char session_file_path[100];
2153      char *tmp1=strtok(_tmp->value,";");
2154      if(tmp1!=NULL)
2155        sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
2156      else
2157        sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
2158      sessId=strdup(session_file_path);
2159    }else{
2160      maps* t=getMaps(m,"senv");
2161      map*p=t->content;
2162      while(p!=NULL){
2163        if(strstr(p->name,"ID")!=NULL){
2164          sessId=strdup(p->value);
2165          break;
2166        }
2167        p=p->next;
2168      }
2169    }
2170    char session_file_path[1024];
2171    map *tmpPath=getMapFromMaps(m,"main","sessPath");
2172    if(tmpPath==NULL)
2173      tmpPath=getMapFromMaps(m,"main","tmpPath");
2174    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
2175    FILE* teste=fopen(session_file_path,"w");
2176    if(teste==NULL){
2177      char tmpMsg[1024];
2178      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the session maps."),session_file_path);
2179      map * errormap = createMap("text",tmpMsg);
2180      addToMap(errormap,"code", "InternalError");
2181     
2182      printExceptionReportResponse(m,errormap);
2183      freeMap(&errormap);
2184      free(errormap);
2185      return;
2186    }
2187    else{
2188      fclose(teste);
2189      dumpMapsToFile(tmpSess,session_file_path);
2190    }
2191  }
2192 
2193
2194  if(asRaw==0){
2195#ifdef DEBUG
2196    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
2197    dumpMaps(request_outputs);
2198#endif
2199    maps* tmpI=request_outputs;
2200    while(tmpI!=NULL){
2201#ifdef USE_MS
2202      map* testMap=getMap(tmpI->content,"useMapserver");       
2203#endif
2204      toto=getMap(tmpI->content,"asReference");
2205#ifdef USE_MS
2206      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
2207#else
2208      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
2209#endif
2210        {
2211        elements* in=getElements(s->outputs,tmpI->name);
2212        char *format=NULL;
2213        if(in!=NULL){
2214          format=strdup(in->format);
2215        }else
2216          format=strdup("LiteralData");
2217        if(strcasecmp(format,"BoundingBoxData")==0){
2218          addToMap(tmpI->content,"extension","xml");
2219          addToMap(tmpI->content,"mimeType","text/xml");
2220          addToMap(tmpI->content,"encoding","UTF-8");
2221          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2222        }
2223        map *ext=getMap(tmpI->content,"extension");
2224        map *tmp1=getMapFromMaps(m,"main","tmpPath");
2225        char *file_name,*file_path;
2226        bool hasExt=true;
2227        if(ext==NULL){
2228          // We can fallback to a default list of supported formats using
2229          // mimeType information if present here. Maybe we can add more formats
2230          // here.
2231          // If mimeType was not found, we then set txt as the default extension
2232          map* mtype=getMap(tmpI->content,"mimeType");
2233          if(mtype!=NULL){
2234            if(strcasecmp(mtype->value,"text/xml")==0)
2235              ext=createMap("extension","xml");
2236            else if(strcasecmp(mtype->value,"application/json")==0)
2237              ext=createMap("extension","js");
2238            else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
2239              ext=createMap("extension","kml");
2240            else if(strncmp(mtype->value,"image/",6)==0)
2241              ext=createMap("extension",strstr(mtype->value,"/")+1);
2242            else
2243              ext=createMap("extension","txt");
2244          }
2245          else
2246            ext=createMap("extension","txt");
2247          hasExt=false;
2248        }
2249        file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
2250        int cpid0=cpid+time(NULL);
2251        sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
2252        file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
2253        sprintf(file_path,"%s/%s",tmp1->value,file_name);
2254        FILE *ofile=fopen(file_path,"wb");
2255        if(ofile==NULL){
2256          char tmpMsg[1024];
2257          sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
2258          map * errormap = createMap("text",tmpMsg);
2259          addToMap(errormap,"code", "InternalError");
2260          printExceptionReportResponse(m,errormap);
2261          freeMap(&errormap);
2262          free(errormap);
2263          free(file_name);
2264          free(file_path);
2265          return;
2266        }
2267        free(file_path);
2268        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2269        map *tmp3=getMapFromMaps(m,"main","serverAddress");
2270        char *file_url;
2271        if(strncasecmp(tmp2->value,"http://",7)==0 ||
2272           strncasecmp(tmp2->value,"https://",8)==0){
2273          file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
2274          sprintf(file_url,"%s/%s",tmp2->value,file_name);
2275        }else{
2276          file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
2277          sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2278        }
2279        addToMap(tmpI->content,"Reference",file_url);
2280        if(!hasExt){
2281          freeMap(&ext);
2282          free(ext);
2283        }
2284        toto=getMap(tmpI->content,"value");
2285        if(strcasecmp(format,"BoundingBoxData")!=0){
2286          map* size=getMap(tmpI->content,"size");
2287          if(size!=NULL && toto!=NULL)
2288            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2289          else
2290            if(toto!=NULL && toto->value!=NULL)
2291              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2292        }else{
2293          printBoundingBoxDocument(m,tmpI,ofile);
2294        }
2295        free(format);
2296        fclose(ofile);
2297        free(file_name);
2298        free(file_url); 
2299      }
2300#ifdef USE_MS
2301      else{
2302        if(testMap!=NULL){
2303          setReferenceUrl(m,tmpI);
2304        }
2305      }
2306#endif
2307      tmpI=tmpI->next;
2308    }
2309    map *r_inputs=getMap(s->content,"serviceProvider");
2310#ifdef DEBUG
2311    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2312    dumpMaps(m);
2313#endif
2314    printProcessResponse(m,request_inputs1,cpid,
2315                         s,r_inputs->value,res,
2316                         request_inputs,
2317                         request_outputs);
2318    }
2319    else{
2320      if(res==SERVICE_FAILED){
2321        map * errormap;
2322        map *lenv;
2323        lenv=getMapFromMaps(m,"lenv","message");
2324        char *tmp0;
2325        if(lenv!=NULL){
2326          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));
2327          sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
2328        }
2329        else{
2330          tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
2331          sprintf(tmp0,_("Unable to run the Service. No more information was returned back by the Service."));
2332        }
2333        errormap = createMap("text",tmp0);
2334        free(tmp0);
2335        addToMap(errormap,"code", "InternalError");
2336        printExceptionReportResponse(m,errormap);
2337        freeMap(&errormap);
2338        free(errormap);
2339        return;
2340      }
2341      /**
2342       * We get the requested output or fallback to the first one if the
2343       * requested one is not present in the resulting outputs maps.
2344       */
2345      maps* tmpI=NULL;
2346      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2347      if(tmpIV!=NULL){
2348        tmpI=getMaps(request_outputs,tmpIV->value);
2349      }
2350      if(tmpI==NULL)
2351        tmpI=request_outputs;
2352      elements* e=getElements(s->outputs,tmpI->name);
2353      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2354        printBoundingBoxDocument(m,tmpI,NULL);
2355      }else{
2356        toto=getMap(tmpI->content,"value");
2357        if(toto==NULL){
2358          char tmpMsg[1024];
2359          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2360          map * errormap = createMap("text",tmpMsg);
2361          addToMap(errormap,"code", "InvalidParameterValue");
2362          printExceptionReportResponse(m,errormap);
2363          freeMap(&errormap);
2364          free(errormap);
2365          return;
2366        }
2367        map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2368        if(fname!=NULL)
2369          printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2370        map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2371        if(rs!=NULL)
2372          printf("Content-Length: %s\r\n",rs->value);
2373        printHeaders(m);
2374        char mime[1024];
2375        map* mi=getMap(tmpI->content,"mimeType");
2376#ifdef DEBUG
2377        fprintf(stderr,"SERVICE OUTPUTS\n");
2378        dumpMaps(request_outputs);
2379        fprintf(stderr,"SERVICE OUTPUTS\n");
2380#endif
2381        map* en=getMap(tmpI->content,"encoding");
2382        if(mi!=NULL && en!=NULL)
2383          sprintf(mime,
2384                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2385                  mi->value,en->value);
2386        else
2387          if(mi!=NULL)
2388            sprintf(mime,
2389                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2390                    mi->value);
2391          else
2392            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2393        printf("%s",mime);
2394        if(rs!=NULL)
2395          fwrite(toto->value,1,atoi(rs->value),stdout);
2396        else
2397          fwrite(toto->value,1,strlen(toto->value),stdout);
2398#ifdef DEBUG
2399        dumpMap(toto);
2400#endif
2401      }
2402    }
2403}
2404
2405char *base64(const char *input, int length)
2406{
2407  BIO *bmem, *b64;
2408  BUF_MEM *bptr;
2409
2410  b64 = BIO_new(BIO_f_base64());
2411  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2412  bmem = BIO_new(BIO_s_mem());
2413  b64 = BIO_push(b64, bmem);
2414  BIO_write(b64, input, length);
2415  BIO_flush(b64);
2416  BIO_get_mem_ptr(b64, &bptr);
2417
2418  char *buff = (char *)malloc((bptr->length)*sizeof(char));
2419  memcpy(buff, bptr->data, bptr->length-1);
2420  buff[bptr->length-1] = 0;
2421
2422  BIO_free_all(b64);
2423
2424  return buff;
2425}
2426
2427char *base64d(const char *input, int length,int* red)
2428{
2429  BIO *b64, *bmem;
2430
2431  char *buffer = (char *)malloc(length);
2432  if(buffer){
2433    memset(buffer, 0, length);
2434    b64 = BIO_new(BIO_f_base64());
2435    if(b64){
2436      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2437      bmem = BIO_push(b64, bmem);
2438      *red=BIO_read(bmem, buffer, length);
2439      buffer[length-1]=0;
2440      BIO_free_all(bmem);
2441    }
2442  }
2443  return buffer;
2444}
2445
2446void ensureDecodedBase64(maps **in){
2447  maps* cursor=*in;
2448  while(cursor!=NULL){
2449    map *tmp=getMap(cursor->content,"encoding");
2450    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2451      tmp=getMap(cursor->content,"value");
2452      addToMap(cursor->content,"base64_value",tmp->value);
2453      int size=0;
2454      char *s=strdup(tmp->value);
2455      free(tmp->value);
2456      tmp->value=base64d(s,strlen(s),&size);
2457      free(s);
2458      char sizes[1024];
2459      sprintf(sizes,"%d",size);
2460      addToMap(cursor->content,"size",sizes);
2461    }
2462    cursor=cursor->next;
2463  }
2464}
2465
2466char* addDefaultValues(maps** out,elements* in,maps* m,int type){
2467  elements* tmpInputs=in;
2468  maps* out1=*out;
2469  if(type==1){
2470    while(out1!=NULL){
2471      if(getElements(in,out1->name)==NULL)
2472        return out1->name;
2473      out1=out1->next;
2474    }
2475    out1=*out;
2476  }
2477  while(tmpInputs!=NULL){
2478    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2479    if(tmpMaps==NULL){
2480      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2481      tmpMaps2->name=strdup(tmpInputs->name);
2482      tmpMaps2->content=NULL;
2483      tmpMaps2->next=NULL;
2484     
2485      if(type==0){
2486        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2487        if(tmpMapMinO!=NULL){
2488          if(atoi(tmpMapMinO->value)>=1){
2489            freeMaps(&tmpMaps2);
2490            free(tmpMaps2);
2491            return tmpInputs->name;
2492          }
2493          else{
2494            if(tmpMaps2->content==NULL)
2495              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2496            else
2497              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2498          }
2499        }
2500        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2501        if(tmpMaxO!=NULL){
2502          if(tmpMaps2->content==NULL)
2503            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2504          else
2505            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2506        }
2507        map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
2508        if(tmpMaxMB!=NULL){
2509          if(tmpMaps2->content==NULL)
2510            tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
2511          else
2512            addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
2513        }
2514      }
2515
2516      iotype* tmpIoType=tmpInputs->defaults;
2517      if(tmpIoType!=NULL){
2518        map* tmpm=tmpIoType->content;
2519        while(tmpm!=NULL){
2520          if(tmpMaps2->content==NULL)
2521            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2522          else
2523            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2524          tmpm=tmpm->next;
2525        }
2526      }
2527      addToMap(tmpMaps2->content,"inRequest","false");
2528      if(type==0){
2529        map *tmpMap=getMap(tmpMaps2->content,"value");
2530        if(tmpMap==NULL)
2531          addToMap(tmpMaps2->content,"value","NULL");
2532      }
2533      if(out1==NULL){
2534        *out=dupMaps(&tmpMaps2);
2535        out1=*out;
2536      }
2537      else
2538        addMapsToMaps(&out1,tmpMaps2);
2539      freeMap(&tmpMaps2->content);
2540      free(tmpMaps2->content);
2541      tmpMaps2->content=NULL;
2542      freeMaps(&tmpMaps2);
2543      free(tmpMaps2);
2544      tmpMaps2=NULL;
2545    }
2546    else{
2547      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2548                                             tmpMaps->content);
2549      if(type==0) {
2550        /**
2551         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2552         * content map.
2553         */
2554        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2555        if(tmpMap1!=NULL){
2556          if(tmpMaps->content==NULL)
2557            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2558          else
2559            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2560        }
2561        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2562        if(tmpMaxO!=NULL){
2563          if(tmpMaps->content==NULL)
2564            tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
2565          else
2566            addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
2567        }
2568        map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
2569        if(tmpMaxMB!=NULL){
2570          if(tmpMaps->content==NULL)
2571            tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
2572          else
2573            addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
2574        }
2575        /**
2576         * Parsing BoundingBoxData, fill the following map and then add it to
2577         * the content map of the Input maps:
2578         * lowerCorner, upperCorner, srs and dimensions
2579         * cf. parseBoundingBox
2580         */
2581        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2582          maps* tmpI=getMaps(*out,tmpInputs->name);
2583          if(tmpI!=NULL){
2584            map* tmpV=getMap(tmpI->content,"value");
2585            if(tmpV!=NULL){
2586              char *tmpVS=strdup(tmpV->value);
2587              map* tmp=parseBoundingBox(tmpVS);
2588              free(tmpVS);
2589              map* tmpC=tmp;
2590              while(tmpC!=NULL){
2591                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2592                tmpC=tmpC->next;
2593              }
2594              freeMap(&tmp);
2595              free(tmp);
2596            }
2597          }
2598        }
2599      }
2600
2601      if(tmpIoType!=NULL){
2602        map* tmpContent=tmpIoType->content;
2603        map* cval=NULL;
2604        int hasPassed=-1;
2605        while(tmpContent!=NULL){
2606          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2607#ifdef DEBUG
2608            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2609#endif
2610            if(tmpMaps->content==NULL)
2611              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2612            else
2613              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2614           
2615            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
2616              map* length=getMap(tmpMaps->content,"length");
2617              int i;
2618              char *tcn=strdup(tmpContent->name);
2619              for(i=1;i<atoi(length->value);i++){
2620#ifdef DEBUG
2621                dumpMap(tmpMaps->content);
2622                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
2623#endif
2624                int len=strlen((char*) tcn);
2625                char *tmp1=(char *)malloc((len+10)*sizeof(char));
2626                sprintf(tmp1,"%s_%d",tcn,i);
2627#ifdef DEBUG
2628                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
2629#endif
2630                addToMap(tmpMaps->content,tmp1,tmpContent->value);
2631                free(tmp1);
2632                hasPassed=1;
2633              }
2634              free(tcn);
2635            }
2636          }
2637          tmpContent=tmpContent->next;
2638        }
2639#ifdef USE_MS
2640        /**
2641         * check for useMapServer presence
2642         */
2643        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
2644        if(tmpCheck!=NULL){
2645          // Get the default value
2646          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
2647          tmpCheck=getMap(tmpMaps->content,"mimeType");
2648          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
2649          map* cursor=tmpIoType->content;
2650          while(cursor!=NULL){
2651            addToMap(tmpMaps->content,cursor->name,cursor->value);
2652            cursor=cursor->next;
2653          }
2654         
2655          cursor=tmpInputs->content;
2656          while(cursor!=NULL){
2657            if(strcasecmp(cursor->name,"Title")==0 ||
2658               strcasecmp(cursor->name,"Abstract")==0)
2659              addToMap(tmpMaps->content,cursor->name,cursor->value);
2660           cursor=cursor->next;
2661          }
2662        }
2663#endif
2664      }
2665      if(tmpMaps->content==NULL)
2666        tmpMaps->content=createMap("inRequest","true");
2667      else
2668        addToMap(tmpMaps->content,"inRequest","true");
2669
2670    }
2671    tmpInputs=tmpInputs->next;
2672  }
2673  return "";
2674}
2675
2676/**
2677 * parseBoundingBox : parse a BoundingBox string
2678 *
2679 * OGC 06-121r3 : 10.2 Bounding box
2680 *
2681 * value is provided as : lowerCorner,upperCorner,crs,dimension
2682 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2683 *
2684 * Need to create a map to store boundingbox informations :
2685 *  - lowerCorner : double,double (minimum within this bounding box)
2686 *  - upperCorner : double,double (maximum within this bounding box)
2687 *  - crs : URI (Reference to definition of the CRS)
2688 *  - dimensions : int
2689 *
2690 * Note : support only 2D bounding box.
2691 */
2692map* parseBoundingBox(const char* value){
2693  map *res=NULL;
2694  if(value!=NULL){
2695    char *cv,*cvp;
2696    cv=strtok_r((char*) value,",",&cvp);
2697    int cnt=0;
2698    int icnt=0;
2699    char *currentValue=NULL;
2700    while(cv){
2701      if(cnt<2)
2702        if(currentValue!=NULL){
2703          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
2704          sprintf(finalValue,"%s%s",currentValue,cv);
2705          switch(cnt){
2706          case 0:
2707            res=createMap("lowerCorner",finalValue);
2708            break;
2709          case 1:
2710            addToMap(res,"upperCorner",finalValue);
2711            icnt=-1;
2712            break;
2713          }
2714          cnt++;
2715          free(currentValue);
2716          currentValue=NULL;
2717          free(finalValue);
2718        }
2719        else{
2720          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
2721          sprintf(currentValue,"%s ",cv);
2722        }
2723      else
2724        if(cnt==2){
2725          addToMap(res,"crs",cv);
2726          cnt++;
2727        }
2728        else
2729          addToMap(res,"dimensions",cv);
2730      icnt++;
2731      cv=strtok_r(NULL,",",&cvp);
2732    }
2733  }
2734  return res;
2735}
2736
2737/**
2738 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2739 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2740 * Lower/UpperCorner nodes to a pre-existing XML node.
2741 */
2742void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2743
2744  xmlNodePtr lw=NULL,uc=NULL;
2745
2746  map* tmp=getMap(boundingbox,"value");
2747
2748  tmp=getMap(boundingbox,"lowerCorner");
2749  if(tmp!=NULL){
2750    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2751    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2752  }
2753
2754  tmp=getMap(boundingbox,"upperCorner");
2755  if(tmp!=NULL){
2756    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2757    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2758  }
2759
2760  tmp=getMap(boundingbox,"crs");
2761  if(tmp!=NULL)
2762    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2763
2764  tmp=getMap(boundingbox,"dimensions");
2765  if(tmp!=NULL)
2766    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2767
2768  xmlAddChild(n,lw);
2769  xmlAddChild(n,uc);
2770
2771}
2772
2773void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2774  if(file==NULL)
2775    rewind(stdout);
2776  xmlNodePtr n;
2777  xmlDocPtr doc;
2778  xmlNsPtr ns_ows,ns_xsi;
2779  xmlChar *xmlbuff;
2780  int buffersize;
2781  char *encoding=getEncoding(m);
2782  map *tmp;
2783  if(file==NULL){
2784    int pid=0;
2785    tmp=getMapFromMaps(m,"lenv","sid");
2786    if(tmp!=NULL)
2787      pid=atoi(tmp->value);
2788    if(pid==getpid()){
2789      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2790    }
2791    fflush(stdout);
2792  }
2793
2794  doc = xmlNewDoc(BAD_CAST "1.0");
2795  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2796  ns_ows=usedNs[owsId];
2797  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2798  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
2799  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2800  ns_xsi=usedNs[xsiId];
2801  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");
2802  map *tmp1=getMap(boundingbox->content,"value");
2803  tmp=parseBoundingBox(tmp1->value);
2804  printBoundingBox(ns_ows,n,tmp);
2805  xmlDocSetRootElement(doc, n);
2806
2807  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2808  if(file==NULL)
2809    printf("%s",xmlbuff);
2810  else{
2811    fprintf(file,"%s",xmlbuff);
2812  }
2813
2814  if(tmp!=NULL){
2815    freeMap(&tmp);
2816    free(tmp);
2817  }
2818  xmlFree(xmlbuff);
2819  xmlFreeDoc(doc);
2820  xmlCleanupParser();
2821  zooXmlCleanupNs();
2822 
2823}
2824
2825
2826char* getMd5(char* url){
2827  EVP_MD_CTX md5ctx;
2828  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
2829  unsigned char result[EVP_MAX_MD_SIZE];
2830  unsigned int len;
2831  EVP_DigestInit(&md5ctx, EVP_md5());
2832  EVP_DigestUpdate(&md5ctx, url, strlen(url));
2833  EVP_DigestFinal_ex(&md5ctx,result,&len);
2834  EVP_MD_CTX_cleanup(&md5ctx);
2835  int i;
2836  for(i = 0; i < len; i++){
2837    if(i>0){
2838      char *tmp=strdup(fresult);
2839      sprintf(fresult,"%s%02x", tmp,result[i]);
2840      free(tmp);
2841    }
2842    else
2843      sprintf(fresult,"%02x",result[i]);
2844  }
2845  return fresult;
2846}
2847
2848/**
2849 * Cache a file for a given request
2850 */
2851void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
2852  map* tmp=getMapFromMaps(conf,"main","cacheDir");
2853  if(tmp!=NULL){
2854    char* md5str=getMd5(request);
2855    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
2856    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
2857#ifdef DEBUG
2858    fprintf(stderr,"Cache list : %s\n",fname);
2859    fflush(stderr);
2860#endif
2861    FILE* fo=fopen(fname,"w+");
2862    if(fo==NULL){
2863      fprintf (stderr, "Failed to open %s for writting: %s\n",fname, strerror(errno));
2864      return;
2865    }
2866    fwrite(content,sizeof(char),length,fo);
2867    fclose(fo);
2868
2869    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
2870    fo=fopen(fname,"w+");
2871#ifdef DEBUG
2872    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
2873#endif
2874    fwrite(mimeType,1,strlen(mimeType),fo);
2875    fclose(fo);
2876
2877    free(md5str);
2878    free(fname);
2879  }
2880}
2881
2882char* isInCache(maps* conf,char* request){
2883  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
2884  if(tmpM!=NULL){
2885    char* md5str=getMd5(request);
2886#ifdef DEBUG
2887    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
2888#endif
2889    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
2890    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
2891    struct stat f_status;
2892    int s=stat(fname, &f_status);
2893    if(s==0 && f_status.st_size>0){
2894      free(md5str);
2895      return fname;
2896    }
2897    free(md5str);
2898    free(fname);
2899  }
2900  return NULL;
2901}
2902
2903/**
2904 * loadRemoteFile:
2905 * Try to load file from cache or download a remote file if not in cache
2906 */
2907int loadRemoteFile(maps** m,map** content,HINTERNET hInternet,char *url){
2908  HINTERNET res;
2909  char* fcontent;
2910  char* cached=isInCache(*m,url);
2911  char *mimeType=NULL;
2912  int fsize=0;
2913  if(cached!=NULL){
2914    struct stat f_status;
2915    int s=stat(cached, &f_status);
2916    if(s==0){
2917      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2918      FILE* f=fopen(cached,"rb");
2919      fread(fcontent,f_status.st_size,1,f);
2920      fsize=f_status.st_size;
2921      fcontent[fsize]=0;
2922      fclose(f);
2923    }
2924    cached[strlen(cached)-1]='m';
2925    s=stat(cached, &f_status);
2926    if(s==0){
2927      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2928      FILE* f=fopen(cached,"rb");
2929      fread(mimeType,f_status.st_size,1,f);
2930      mimeType[f_status.st_size]=0;
2931      fclose(f);
2932    }
2933  }else{
2934    res=InternetOpenUrl(hInternet,url,NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
2935    fcontent=(char*)malloc((res.nDataLen+1)*sizeof(char));
2936    if(fcontent == NULL){
2937      return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
2938    }
2939    size_t dwRead;
2940    InternetReadFile(res, (LPVOID)fcontent, res.nDataLen, &dwRead);
2941    fcontent[res.nDataLen]=0;
2942    fsize=res.nDataLen;
2943    mimeType=(char*)res.mimeType;
2944  }
2945  if(fsize==0){
2946    return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
2947  }
2948
2949  if(mimeType!=NULL){
2950    addToMap(*content,"fmimeType",mimeType);
2951  }
2952
2953  map* tmpMap=getMapOrFill(content,"value","");
2954   
2955  free(tmpMap->value);
2956  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
2957  if(tmpMap->value==NULL)
2958    return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
2959  //snprintf(tmpMap->value,(fsize+1)*sizeof(char),fcontent);
2960  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
2961 
2962  char ltmp1[256];
2963  sprintf(ltmp1,"%d",fsize);
2964  addToMap(*content,"size",ltmp1);
2965  if(cached==NULL)
2966    addToCache(*m,url,fcontent,mimeType,fsize);
2967  free(fcontent);
2968  free(mimeType);
2969  free(cached);
2970  return 0;
2971}
2972
2973int errorException(maps *m, const char *message, const char *errorcode, const char *locator) 
2974{
2975  map* errormap = createMap("text", message);
2976  addToMap(errormap,"code", errorcode);
2977  if(locator!=NULL)
2978    addToMap(errormap,"locator", locator);
2979  else
2980    addToMap(errormap,"locator", "NULL");
2981  printExceptionReportResponse(m,errormap);
2982  freeMap(&errormap);
2983  free(errormap);
2984  return -1;
2985}
2986
2987
2988char *readVSIFile(maps* conf,const char* dataSource){
2989    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
2990    VSIStatBufL file_status;
2991    VSIStatL(dataSource, &file_status);
2992    if(fichier==NULL){
2993      char tmp[1024];
2994      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %d.",
2995              dataSource,file_status.st_size);
2996      setMapInMaps(conf,"lenv","message",tmp);
2997      return NULL;
2998    }
2999    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
3000    VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
3001    res1[file_status.st_size-1]=0;
3002    VSIFCloseL(fichier);
3003    VSIUnlink(dataSource);
3004    return res1;
3005}
3006
3007void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
3008  char *saveptr1;
3009  char *tmps1=strtok_r(identifier,".",&saveptr1);
3010  int level=0;
3011  char key[25];
3012  char levels[18];
3013  while(tmps1!=NULL){
3014    char *test=zStrdup(tmps1);
3015    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
3016    sprintf(key,"sprefix_%d",level);
3017    sprintf(tmps2,"%s.",test);
3018    sprintf(levels,"%d",level);
3019    setMapInMaps(conf,"lenv","level",levels);
3020    setMapInMaps(conf,"lenv",key,tmps2);
3021    free(tmps2);
3022    free(test);
3023    level++;
3024    tmps1=strtok_r(NULL,".",&saveptr1);
3025  }
3026  int i=0;
3027  sprintf(buffer,"%s",conf_dir);
3028  for(i=0;i<level;i++){
3029    char *tmp0=zStrdup(buffer);
3030    sprintf(key,"sprefix_%d",i);
3031    map* tmp00=getMapFromMaps(conf,"lenv",key);
3032    sprintf(buffer,"%s/%s",tmp0,tmp00->value);
3033    free(tmp0);
3034    buffer[strlen(buffer)-1]=0;
3035    if(i+1<level){
3036      map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
3037      if(tmpMap==NULL || strlen(tmpMap->value)==0){
3038        char *tmp01=zStrdup(tmp00->value);
3039        tmp01[strlen(tmp01)-1]=0;
3040        setMapInMaps(conf,"lenv","metapath",tmp01);
3041        free(tmp01);
3042      }
3043      else{
3044        char *value=(char*)malloc((strlen(tmp00->value)+strlen(tmpMap->value)+2)*sizeof(char));
3045        sprintf(value,"%s/%s",tmpMap->value,tmp00->value);
3046        value[strlen(value)-1]=0;
3047        setMapInMaps(conf,"lenv","metapath",value);
3048        free(value);
3049      }
3050    }else{
3051      char *tmp01=zStrdup(tmp00->value);
3052      tmp01[strlen(tmp01)-1]=0;
3053      setMapInMaps(conf,"lenv","Identifier",tmp01);
3054      free(tmp01);
3055    }
3056  }
3057  char *tmp0=zStrdup(buffer);
3058  sprintf(buffer,"%s.zcfg",tmp0);
3059  free(tmp0);
3060}
3061
3062int updateStatus( maps* conf, const int percentCompleted, const char* message ){
3063  char tmp[4];
3064  snprintf(tmp,4,"%d",percentCompleted);
3065  setMapInMaps( conf, "lenv", "status", tmp );
3066  setMapInMaps( conf, "lenv", "message", message);
3067  return _updateStatus( conf );
3068}
3069
3070char* getInputValue( maps* inputs, const char* parameterName, size_t* numberOfBytes){
3071  map* res=getMapFromMaps(inputs,parameterName,"value");
3072  if(res!=NULL){
3073    map* size=getMapFromMaps(inputs,parameterName,"size");
3074    if(size!=NULL){
3075      *numberOfBytes=(size_t)atoi(size->value);
3076      return res->value;
3077    }else{
3078      *numberOfBytes=strlen(res->value);
3079      return res->value;
3080    }
3081  }
3082  return NULL;
3083}
3084
3085int  setOutputValue( maps* outputs, const char* parameterName, char* data, size_t numberOfBytes ){
3086  if(numberOfBytes==-1){
3087    setMapInMaps(outputs,parameterName,"value",data);
3088  }else{
3089    char size[1024];
3090    map* tmp=getMapFromMaps(outputs,parameterName,"value");
3091    free(tmp->value);
3092    tmp->value=(char*) malloc((numberOfBytes+1)*sizeof(char));
3093    memcpy(tmp->value,data,numberOfBytes);
3094    sprintf(size,"%lu",numberOfBytes);
3095    setMapInMaps(outputs,parameterName,"size",size);
3096  }
3097  return 0;
3098}
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