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

Last change on this file since 492 was 492, checked in by djay, 10 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