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

Last change on this file since 577 was 577, checked in by djay, 9 years ago

Remove uneeded debug message.

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