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

Last change on this file since 476 was 476, checked in by djay, 6 years ago

Upgrade dirent-win32 to dirent API for Microsoft Visual Studio. Fix for second empty range node.

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