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

Last change on this file since 556 was 554, checked in by knut, 9 years ago

Changed the WIN32 version of function zGettimeofday. Changed return type for getShmLockId (WIN32). Changed type of _HINTERNET.mimeType from unsigned char* to char*. Fixed interconnected memory issues in functions getKeyValue and getShmLockId (WIN32). Added code to transfer the correct unique process identifier (usid) to background processes (applies to WIN32 version).

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