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

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

Add otb2zcfg and OTB applications support without observer by now. Fix issue with maxOccurs and multiple downloaded value for the same input.

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