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

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

Remove memory leaks in parseIdentifier and use thread safe CURL version.

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