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

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

Add support of maximumMegabytes keyword for size limitation of ComplexData? inputs

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