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

Last change on this file since 492 was 492, checked in by djay, 9 years ago

Inputs passed by reference downloaded in parallel. Conform behavior for DescribeProcess? when the Identifier was not found.

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