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

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