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

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

Code cleanup, description of some functon included in the code, addition of support for multiple error output, beter internal gesture of MapArray?.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 103.6 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  fprintf(stderr,"LEN %d %s %d \n",length,__FILE__,__LINE__);
2413  for(cnt=0;cnt<length;cnt++){
2414    nc = xmlNewNode(ns, BAD_CAST "Exception");
2415   
2416    map* tmp=getMapArray(s,"code",cnt);
2417    if(tmp==NULL)
2418      tmp=getMap(s,"code");
2419    if(tmp!=NULL)
2420      xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
2421    else
2422      xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
2423   
2424    tmp=getMapArray(s,"locator",cnt);
2425    if(tmp==NULL)
2426      tmp=getMap(s,"locator");
2427    if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
2428      xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
2429
2430    tmp=getMapArray(s,"text",cnt);
2431    nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
2432    if(tmp!=NULL){
2433      xmlNodePtr txt=xmlNewText(BAD_CAST tmp->value);
2434      xmlAddChild(nc1,txt);
2435    }
2436    else{
2437      xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
2438    }
2439    xmlAddChild(nc,nc1);
2440    xmlAddChild(n,nc);
2441  }
2442  return n;
2443}
2444
2445/************************************************************************/
2446/*                           errorException()                           */
2447/************************************************************************/
2448
2449/**
2450 * Print an OWS ExceptionReport.
2451 *
2452 * @param m the conf maps
2453 * @param message the error message
2454 * @param errorcode the error code
2455 * @param locator the potential locator
2456 */
2457int errorException(maps *m, const char *message, const char *errorcode, const char *locator) 
2458{
2459  map* errormap = createMap("text", message);
2460  addToMap(errormap,"code", errorcode);
2461  if(locator!=NULL)
2462    addToMap(errormap,"locator", locator);
2463  else
2464    addToMap(errormap,"locator", "NULL");
2465  printExceptionReportResponse(m,errormap);
2466  freeMap(&errormap);
2467  free(errormap);
2468  return -1;
2469}
2470
2471/************************************************************************/
2472/*                          readGeneratedFile()                         */
2473/************************************************************************/
2474
2475/**
2476 * Read a file generated by a service.
2477 *
2478 * @param m the conf maps
2479 * @param content the output item
2480 * @param filename the file to read
2481 */
2482void readGeneratedFile(maps* m,map* content,char* filename){
2483  FILE * file=fopen(filename,"rb");
2484  if(file==NULL){
2485    fprintf(stderr,"Failed to open file %s for reading purpose.\n",filename);
2486    setMapInMaps(m,"lenv","message","Unable to read produced file. Please try again later");
2487    return ;
2488  }
2489  fseek(file, 0, SEEK_END);
2490  long count = ftell(file);
2491  rewind(file);
2492  struct stat file_status; 
2493  stat(filename, &file_status);
2494  map* tmpMap1=getMap(content,"value");
2495  if(tmpMap1==NULL){
2496    addToMap(content,"value","");
2497    tmpMap1=getMap(content,"value");
2498  }
2499  free(tmpMap1->value);
2500  tmpMap1->value=(char*) malloc((count+1)*sizeof(char)); 
2501  fread(tmpMap1->value,1,count*sizeof(char),file);
2502  fclose(file);
2503  char rsize[100];
2504  sprintf(rsize,"%ld",count*sizeof(char));
2505  addToMap(tmpMap1,"size",rsize);
2506}
2507
2508void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
2509                    map* request_inputs1,int cpid,maps* m,int res){
2510#ifdef DEBUG
2511  dumpMaps(request_inputs);
2512  dumpMaps(request_outputs);
2513  fprintf(stderr,"printProcessResponse\n");
2514#endif
2515  map* toto=getMap(request_inputs1,"RawDataOutput");
2516  int asRaw=0;
2517  if(toto!=NULL)
2518    asRaw=1;
2519 
2520  maps* tmpSess=getMaps(m,"senv");
2521  if(tmpSess!=NULL){
2522    map *_tmp=getMapFromMaps(m,"lenv","cookie");
2523    char* sessId=NULL;
2524    if(_tmp!=NULL){
2525      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
2526      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
2527      char session_file_path[100];
2528      char *tmp1=strtok(_tmp->value,";");
2529      if(tmp1!=NULL)
2530        sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
2531      else
2532        sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
2533      sessId=strdup(session_file_path);
2534    }else{
2535      maps* t=getMaps(m,"senv");
2536      map*p=t->content;
2537      while(p!=NULL){
2538        if(strstr(p->name,"ID")!=NULL){
2539          sessId=strdup(p->value);
2540          break;
2541        }
2542        p=p->next;
2543      }
2544    }
2545    char session_file_path[1024];
2546    map *tmpPath=getMapFromMaps(m,"main","sessPath");
2547    if(tmpPath==NULL)
2548      tmpPath=getMapFromMaps(m,"main","tmpPath");
2549    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
2550    FILE* teste=fopen(session_file_path,"w");
2551    if(teste==NULL){
2552      char tmpMsg[1024];
2553      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the session maps."),session_file_path);
2554      errorException(m,tmpMsg,"InternalError",NULL);
2555
2556      return;
2557    }
2558    else{
2559      fclose(teste);
2560      dumpMapsToFile(tmpSess,session_file_path);
2561    }
2562  }
2563 
2564  if(res==SERVICE_FAILED){
2565    map *lenv;
2566    lenv=getMapFromMaps(m,"lenv","message");
2567    char *tmp0;
2568    if(lenv!=NULL){
2569      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));
2570      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
2571    }
2572    else{
2573      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
2574      sprintf(tmp0,"%s",_("Unable to run the Service. No more information was returned back by the Service."));
2575    }
2576    errorException(m,tmp0,"InternalError",NULL);
2577    free(tmp0);
2578    return;
2579  }
2580
2581
2582  map *tmp1=getMapFromMaps(m,"main","tmpPath");
2583  if(asRaw==0){
2584#ifdef DEBUG
2585    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
2586    dumpMaps(request_outputs);
2587#endif
2588    maps* tmpI=request_outputs;
2589
2590    while(tmpI!=NULL){
2591#ifdef USE_MS
2592      map* testMap=getMap(tmpI->content,"useMapserver");       
2593#endif
2594      toto=getMap(tmpI->content,"asReference");
2595#ifdef USE_MS
2596      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
2597#else
2598      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
2599#endif
2600        {
2601          elements* in=getElements(s->outputs,tmpI->name);
2602          char *format=NULL;
2603          if(in!=NULL){
2604            format=strdup(in->format);
2605          }else
2606            format=strdup("LiteralData");
2607          if(strcasecmp(format,"BoundingBoxData")==0){
2608            addToMap(tmpI->content,"extension","xml");
2609            addToMap(tmpI->content,"mimeType","text/xml");
2610            addToMap(tmpI->content,"encoding","UTF-8");
2611            addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2612          }
2613
2614          map *gfile=getMap(tmpI->content,"generated_file");
2615          char *file_name;
2616          if(gfile!=NULL){
2617            gfile=getMap(tmpI->content,"expected_generated_file");
2618            if(gfile==NULL){
2619              gfile=getMap(tmpI->content,"generated_file");
2620            }
2621            readGeneratedFile(m,tmpI->content,gfile->value);       
2622            file_name=(char*)malloc((strlen(gfile->value)+strlen(tmp1->value)+1)*sizeof(char));
2623            for(int i=0;i<strlen(gfile->value);i++)
2624              file_name[i]=gfile->value[i+strlen(tmp1->value)];
2625          }
2626          else{
2627            map *ext=getMap(tmpI->content,"extension");
2628            char *file_path;
2629            bool hasExt=true;
2630            if(ext==NULL){
2631              // We can fallback to a default list of supported formats using
2632              // mimeType information if present here. Maybe we can add more formats
2633              // here.
2634              // If mimeType was not found, we then set txt as the default extension
2635              map* mtype=getMap(tmpI->content,"mimeType");
2636              if(mtype!=NULL) {
2637                if(strncasecmp(mtype->value,"text/xml",8)==0)
2638                  ext=createMap("extension","xml");
2639                else if(strncasecmp(mtype->value,"application/zip",15)==0)
2640                  ext=createMap("extension","zip");
2641                else if(strncasecmp(mtype->value,"application/json",16)==0)
2642                  ext=createMap("extension","js");
2643                else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
2644                  ext=createMap("extension","kml");
2645                else if(strncmp(mtype->value,"image/",6)==0)
2646                  ext=createMap("extension",strstr(mtype->value,"/")+1);
2647                else
2648                  ext=createMap("extension","txt");
2649              }
2650              else
2651                ext=createMap("extension","txt");
2652              hasExt=false;
2653            }
2654            file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
2655            int cpid0=cpid+time(NULL);
2656            sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
2657            file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
2658            sprintf(file_path,"%s/%s",tmp1->value,file_name);
2659            FILE *ofile=fopen(file_path,"wb");
2660            if(ofile==NULL){
2661              char tmpMsg[1024];
2662              sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
2663              errorException(m,tmpMsg,"InternalError",NULL);
2664              free(file_name);
2665              free(file_path);
2666              return;
2667            }
2668            free(file_path);
2669            if(!hasExt){
2670              freeMap(&ext);
2671              free(ext);
2672            }
2673            toto=getMap(tmpI->content,"value");
2674            if(strcasecmp(format,"BoundingBoxData")!=0){
2675              map* size=getMap(tmpI->content,"size");
2676              if(size!=NULL && toto!=NULL)
2677                fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2678              else
2679                if(toto!=NULL && toto->value!=NULL)
2680                  fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2681            }else{
2682              printBoundingBoxDocument(m,tmpI,ofile);
2683            }
2684            fclose(ofile);
2685
2686          }
2687          map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2688          map *tmp3=getMapFromMaps(m,"main","serverAddress");
2689          char *file_url;
2690          if(strncasecmp(tmp2->value,"http://",7)==0 ||
2691             strncasecmp(tmp2->value,"https://",8)==0){
2692            file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
2693            sprintf(file_url,"%s/%s",tmp2->value,file_name);
2694          }else{
2695            file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
2696            sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2697          }
2698          addToMap(tmpI->content,"Reference",file_url);
2699          free(format);
2700          free(file_name);
2701          free(file_url);       
2702         
2703        }
2704#ifdef USE_MS
2705      else{
2706        if(testMap!=NULL){
2707          setReferenceUrl(m,tmpI);
2708        }
2709      }
2710#endif
2711      tmpI=tmpI->next;
2712    }
2713    map *r_inputs=getMap(s->content,"serviceProvider");
2714#ifdef DEBUG
2715    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2716    dumpMaps(m);
2717#endif
2718    printProcessResponse(m,request_inputs1,cpid,
2719                         s,r_inputs->value,res,
2720                         request_inputs,
2721                         request_outputs);
2722  }
2723  else{
2724    /**
2725     * We get the requested output or fallback to the first one if the
2726     * requested one is not present in the resulting outputs maps.
2727     */
2728    maps* tmpI=NULL;
2729    map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2730    if(tmpIV!=NULL){
2731      tmpI=getMaps(request_outputs,tmpIV->value);
2732    }
2733    if(tmpI==NULL)
2734      tmpI=request_outputs;
2735    elements* e=getElements(s->outputs,tmpI->name);
2736    if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2737      printBoundingBoxDocument(m,tmpI,NULL);
2738    }else{
2739      map *gfile=getMap(tmpI->content,"generated_file");
2740      if(gfile!=NULL){
2741        gfile=getMap(tmpI->content,"expected_generated_file");
2742        if(gfile==NULL){
2743          gfile=getMap(tmpI->content,"generated_file");
2744        }
2745        readGeneratedFile(m,tmpI->content,gfile->value);
2746      }
2747      toto=getMap(tmpI->content,"value");
2748      if(toto==NULL){
2749        char tmpMsg[1024];
2750        sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2751        errorException(m,tmpMsg,"InvalidParameterValue","RawDataOutput");
2752        return;
2753      }
2754      map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2755      if(fname!=NULL)
2756        printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2757      map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2758      if(rs!=NULL)
2759        printf("Content-Length: %s\r\n",rs->value);
2760      printHeaders(m);
2761      char mime[1024];
2762      map* mi=getMap(tmpI->content,"mimeType");
2763#ifdef DEBUG
2764      fprintf(stderr,"SERVICE OUTPUTS\n");
2765      dumpMaps(request_outputs);
2766      fprintf(stderr,"SERVICE OUTPUTS\n");
2767#endif
2768      map* en=getMap(tmpI->content,"encoding");
2769      if(mi!=NULL && en!=NULL)
2770        sprintf(mime,
2771                "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2772                mi->value,en->value);
2773      else
2774        if(mi!=NULL)
2775          sprintf(mime,
2776                  "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2777                  mi->value);
2778        else
2779          sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2780      printf("%s",mime);
2781      if(rs!=NULL)
2782        fwrite(toto->value,1,atoi(rs->value),stdout);
2783      else
2784        fwrite(toto->value,1,strlen(toto->value),stdout);
2785#ifdef DEBUG
2786      dumpMap(toto);
2787#endif
2788    }
2789  }
2790}
2791
2792char *base64(const char *input, int length)
2793{
2794  BIO *bmem, *b64;
2795  BUF_MEM *bptr;
2796
2797  b64 = BIO_new(BIO_f_base64());
2798  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2799  bmem = BIO_new(BIO_s_mem());
2800  b64 = BIO_push(b64, bmem);
2801  BIO_write(b64, input, length+1);
2802  BIO_flush(b64);
2803  BIO_get_mem_ptr(b64, &bptr);
2804
2805  char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
2806  memcpy(buff, bptr->data, bptr->length);
2807  buff[bptr->length-1] = 0;
2808
2809  BIO_free_all(b64);
2810
2811  return buff;
2812}
2813
2814char *base64d(const char *input, int length,int* red)
2815{
2816  BIO *b64, *bmem;
2817
2818  char *buffer = (char *)malloc(length);
2819  if(buffer){
2820    memset(buffer, 0, length);
2821    b64 = BIO_new(BIO_f_base64());
2822    if(b64){
2823      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2824      bmem = BIO_push(b64, bmem);
2825      *red=BIO_read(bmem, buffer, length);
2826      buffer[length-1]=0;
2827      BIO_free_all(bmem);
2828    }
2829  }
2830  return buffer;
2831}
2832
2833void ensureDecodedBase64(maps **in){
2834  maps* cursor=*in;
2835  while(cursor!=NULL){
2836    map *tmp=getMap(cursor->content,"encoding");
2837    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2838      tmp=getMap(cursor->content,"value");
2839      addToMap(cursor->content,"base64_value",tmp->value);
2840      int size=0;
2841      char *s=strdup(tmp->value);
2842      free(tmp->value);
2843      tmp->value=base64d(s,strlen(s),&size);
2844      free(s);
2845      char sizes[1024];
2846      sprintf(sizes,"%d",size);
2847      addToMap(cursor->content,"size",sizes);
2848    }
2849    cursor=cursor->next;
2850  }
2851}
2852
2853char* addDefaultValues(maps** out,elements* in,maps* m,int type,map** err){
2854  map *res=*err;
2855  elements* tmpInputs=in;
2856  maps* out1=*out;
2857  char *result=NULL;
2858  int nb=0;
2859  if(type==1){
2860    while(out1!=NULL){
2861      if(getElements(in,out1->name)==NULL){
2862        if(res==NULL){
2863          res=createMap("value",out1->name);
2864        }else{
2865          setMapArray(res,"value",nb,out1->name);
2866        }
2867        nb++;
2868        result=out1->name;
2869      }
2870      out1=out1->next;
2871    }
2872    if(res!=NULL){
2873      *err=res;
2874      return result;
2875    }
2876    out1=*out;
2877  }
2878  while(tmpInputs!=NULL){
2879    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2880    if(tmpMaps==NULL){
2881      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2882      tmpMaps2->name=strdup(tmpInputs->name);
2883      tmpMaps2->content=NULL;
2884      tmpMaps2->next=NULL;
2885     
2886      if(type==0){
2887        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2888        if(tmpMapMinO!=NULL){
2889          if(atoi(tmpMapMinO->value)>=1){
2890            freeMaps(&tmpMaps2);
2891            free(tmpMaps2);
2892            if(res==NULL){
2893              res=createMap("value",tmpInputs->name);
2894            }else{
2895              setMapArray(res,"value",nb,tmpInputs->name);
2896            }
2897            nb++;
2898            result=tmpInputs->name;
2899          }
2900          else{
2901            if(tmpMaps2->content==NULL)
2902              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2903            else
2904              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2905          }
2906        }
2907        if(res==NULL){
2908          map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2909          if(tmpMaxO!=NULL){
2910            if(tmpMaps2->content==NULL)
2911              tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2912            else
2913              addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2914          }
2915          map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
2916          if(tmpMaxMB!=NULL){
2917            if(tmpMaps2->content==NULL)
2918              tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
2919            else
2920              addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
2921          }
2922        }
2923      }
2924
2925      if(res==NULL){
2926        iotype* tmpIoType=tmpInputs->defaults;
2927        if(tmpIoType!=NULL){
2928          map* tmpm=tmpIoType->content;
2929          while(tmpm!=NULL){
2930            if(tmpMaps2->content==NULL)
2931              tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2932            else
2933              addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2934            tmpm=tmpm->next;
2935          }
2936        }
2937        addToMap(tmpMaps2->content,"inRequest","false");
2938        if(type==0){
2939          map *tmpMap=getMap(tmpMaps2->content,"value");
2940          if(tmpMap==NULL)
2941            addToMap(tmpMaps2->content,"value","NULL");
2942        }
2943        if(out1==NULL){
2944          *out=dupMaps(&tmpMaps2);
2945          out1=*out;
2946        }
2947        else
2948          addMapsToMaps(&out1,tmpMaps2);
2949        freeMap(&tmpMaps2->content);
2950        free(tmpMaps2->content);
2951        tmpMaps2->content=NULL;
2952        freeMaps(&tmpMaps2);
2953        free(tmpMaps2);
2954        tmpMaps2=NULL;
2955      }
2956    }
2957    else{
2958      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2959                                             tmpMaps->content);
2960      if(type==0) {
2961        /**
2962         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2963         * content map.
2964         */
2965        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2966        if(tmpMap1!=NULL){
2967          if(tmpMaps->content==NULL)
2968            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2969          else
2970            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2971        }
2972        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2973        if(tmpMaxO!=NULL){
2974          if(tmpMaps->content==NULL)
2975            tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
2976          else
2977            addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
2978        }
2979        map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
2980        if(tmpMaxMB!=NULL){
2981          if(tmpMaps->content==NULL)
2982            tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
2983          else
2984            addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
2985        }
2986        /**
2987         * Parsing BoundingBoxData, fill the following map and then add it to
2988         * the content map of the Input maps:
2989         * lowerCorner, upperCorner, srs and dimensions
2990         * cf. parseBoundingBox
2991         */
2992        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2993          maps* tmpI=getMaps(*out,tmpInputs->name);
2994          if(tmpI!=NULL){
2995            map* tmpV=getMap(tmpI->content,"value");
2996            if(tmpV!=NULL){
2997              char *tmpVS=strdup(tmpV->value);
2998              map* tmp=parseBoundingBox(tmpVS);
2999              free(tmpVS);
3000              map* tmpC=tmp;
3001              while(tmpC!=NULL){
3002                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
3003                tmpC=tmpC->next;
3004              }
3005              freeMap(&tmp);
3006              free(tmp);
3007            }
3008          }
3009        }
3010      }
3011
3012      if(tmpIoType!=NULL){
3013        map* tmpContent=tmpIoType->content;
3014        map* cval=NULL;
3015        int hasPassed=-1;
3016        while(tmpContent!=NULL){
3017          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
3018#ifdef DEBUG
3019            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
3020#endif
3021            if(tmpMaps->content==NULL)
3022              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
3023            else
3024              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
3025           
3026            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
3027              map* length=getMap(tmpMaps->content,"length");
3028              int i;
3029              char *tcn=strdup(tmpContent->name);
3030              for(i=1;i<atoi(length->value);i++){
3031#ifdef DEBUG
3032                dumpMap(tmpMaps->content);
3033                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
3034#endif
3035                int len=strlen((char*) tcn);
3036                char *tmp1=(char *)malloc((len+10)*sizeof(char));
3037                sprintf(tmp1,"%s_%d",tcn,i);
3038#ifdef DEBUG
3039                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
3040#endif
3041                addToMap(tmpMaps->content,tmp1,tmpContent->value);
3042                free(tmp1);
3043                hasPassed=1;
3044              }
3045              free(tcn);
3046            }
3047          }
3048          tmpContent=tmpContent->next;
3049        }
3050#ifdef USE_MS
3051        /**
3052         * check for useMapServer presence
3053         */
3054        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
3055        if(tmpCheck!=NULL){
3056          // Get the default value
3057          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
3058          tmpCheck=getMap(tmpMaps->content,"mimeType");
3059          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
3060          map* cursor=tmpIoType->content;
3061          while(cursor!=NULL){
3062            addToMap(tmpMaps->content,cursor->name,cursor->value);
3063            cursor=cursor->next;
3064          }
3065         
3066          cursor=tmpInputs->content;
3067          while(cursor!=NULL){
3068            if(strcasecmp(cursor->name,"Title")==0 ||
3069               strcasecmp(cursor->name,"Abstract")==0)
3070              addToMap(tmpMaps->content,cursor->name,cursor->value);
3071           cursor=cursor->next;
3072          }
3073        }
3074#endif
3075      }
3076      if(tmpMaps->content==NULL)
3077        tmpMaps->content=createMap("inRequest","true");
3078      else
3079        addToMap(tmpMaps->content,"inRequest","true");
3080
3081    }
3082    tmpInputs=tmpInputs->next;
3083  }
3084  if(res!=NULL){
3085    *err=res;
3086    return result;
3087  }
3088  return "";
3089}
3090
3091/**
3092 * parseBoundingBox : parse a BoundingBox string
3093 *
3094 * OGC 06-121r3 : 10.2 Bounding box
3095 *
3096 * value is provided as : lowerCorner,upperCorner,crs,dimension
3097 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
3098 *
3099 * Need to create a map to store boundingbox informations :
3100 *  - lowerCorner : double,double (minimum within this bounding box)
3101 *  - upperCorner : double,double (maximum within this bounding box)
3102 *  - crs : URI (Reference to definition of the CRS)
3103 *  - dimensions : int
3104 *
3105 * Note : support only 2D bounding box.
3106 */
3107map* parseBoundingBox(const char* value){
3108  map *res=NULL;
3109  if(value!=NULL){
3110    char *cv,*cvp;
3111    cv=strtok_r((char*) value,",",&cvp);
3112    int cnt=0;
3113    int icnt=0;
3114    char *currentValue=NULL;
3115    while(cv){
3116      if(cnt<2)
3117        if(currentValue!=NULL){
3118          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
3119          sprintf(finalValue,"%s%s",currentValue,cv);
3120          switch(cnt){
3121          case 0:
3122            res=createMap("lowerCorner",finalValue);
3123            break;
3124          case 1:
3125            addToMap(res,"upperCorner",finalValue);
3126            icnt=-1;
3127            break;
3128          }
3129          cnt++;
3130          free(currentValue);
3131          currentValue=NULL;
3132          free(finalValue);
3133        }
3134        else{
3135          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
3136          sprintf(currentValue,"%s ",cv);
3137        }
3138      else
3139        if(cnt==2){
3140          addToMap(res,"crs",cv);
3141          cnt++;
3142        }
3143        else
3144          addToMap(res,"dimensions",cv);
3145      icnt++;
3146      cv=strtok_r(NULL,",",&cvp);
3147    }
3148  }
3149  return res;
3150}
3151
3152/**
3153 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
3154 * wps:BoundingBoxData). Set crs and dimensions attributes, add
3155 * Lower/UpperCorner nodes to a pre-existing XML node.
3156 */
3157void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
3158
3159  xmlNodePtr lw=NULL,uc=NULL;
3160
3161  map* tmp=getMap(boundingbox,"value");
3162
3163  tmp=getMap(boundingbox,"lowerCorner");
3164  if(tmp!=NULL){
3165    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
3166    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
3167  }
3168
3169  tmp=getMap(boundingbox,"upperCorner");
3170  if(tmp!=NULL){
3171    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
3172    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
3173  }
3174
3175  tmp=getMap(boundingbox,"crs");
3176  if(tmp!=NULL)
3177    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
3178
3179  tmp=getMap(boundingbox,"dimensions");
3180  if(tmp!=NULL)
3181    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
3182
3183  xmlAddChild(n,lw);
3184  xmlAddChild(n,uc);
3185
3186}
3187
3188void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
3189  if(file==NULL)
3190    rewind(stdout);
3191  xmlNodePtr n;
3192  xmlDocPtr doc;
3193  xmlNsPtr ns_ows,ns_xsi;
3194  xmlChar *xmlbuff;
3195  int buffersize;
3196  char *encoding=getEncoding(m);
3197  map *tmp;
3198  if(file==NULL){
3199    int pid=0;
3200    tmp=getMapFromMaps(m,"lenv","sid");
3201    if(tmp!=NULL)
3202      pid=atoi(tmp->value);
3203    if(pid==getpid()){
3204      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
3205    }
3206    fflush(stdout);
3207  }
3208
3209  doc = xmlNewDoc(BAD_CAST "1.0");
3210  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
3211  ns_ows=usedNs[owsId];
3212  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
3213  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
3214  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
3215  ns_xsi=usedNs[xsiId];
3216  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");
3217  map *tmp1=getMap(boundingbox->content,"value");
3218  tmp=parseBoundingBox(tmp1->value);
3219  printBoundingBox(ns_ows,n,tmp);
3220  xmlDocSetRootElement(doc, n);
3221
3222  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
3223  if(file==NULL)
3224    printf("%s",xmlbuff);
3225  else{
3226    fprintf(file,"%s",xmlbuff);
3227  }
3228
3229  if(tmp!=NULL){
3230    freeMap(&tmp);
3231    free(tmp);
3232  }
3233  xmlFree(xmlbuff);
3234  xmlFreeDoc(doc);
3235  xmlCleanupParser();
3236  zooXmlCleanupNs();
3237 
3238}
3239
3240
3241char* getMd5(char* url){
3242  EVP_MD_CTX md5ctx;
3243  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
3244  unsigned char result[EVP_MAX_MD_SIZE];
3245  unsigned int len;
3246  EVP_DigestInit(&md5ctx, EVP_md5());
3247  EVP_DigestUpdate(&md5ctx, url, strlen(url));
3248  EVP_DigestFinal_ex(&md5ctx,result,&len);
3249  EVP_MD_CTX_cleanup(&md5ctx);
3250  int i;
3251  for(i = 0; i < len; i++){
3252    if(i>0){
3253      char *tmp=strdup(fresult);
3254      sprintf(fresult,"%s%02x", tmp,result[i]);
3255      free(tmp);
3256    }
3257    else
3258      sprintf(fresult,"%02x",result[i]);
3259  }
3260  return fresult;
3261}
3262
3263/**
3264 * Cache a file for a given request
3265 */
3266void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
3267  map* tmp=getMapFromMaps(conf,"main","cacheDir");
3268  if(tmp!=NULL){
3269    char* md5str=getMd5(request);
3270    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
3271    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
3272#ifdef DEBUG
3273    fprintf(stderr,"Cache list : %s\n",fname);
3274    fflush(stderr);
3275#endif
3276    FILE* fo=fopen(fname,"w+");
3277    if(fo==NULL){
3278      fprintf (stderr, "Failed to open %s for writting: %s\n",fname, strerror(errno));
3279      return;
3280    }
3281    fwrite(content,sizeof(char),length,fo);
3282    fclose(fo);
3283
3284    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
3285    fo=fopen(fname,"w+");
3286#ifdef DEBUG
3287    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
3288#endif
3289    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
3290    fclose(fo);
3291
3292    free(md5str);
3293    free(fname);
3294  }
3295}
3296
3297char* isInCache(maps* conf,char* request){
3298  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
3299  if(tmpM!=NULL){
3300    char* md5str=getMd5(request);
3301#ifdef DEBUG
3302    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
3303#endif
3304    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
3305    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
3306    struct stat f_status;
3307    int s=stat(fname, &f_status);
3308    if(s==0 && f_status.st_size>0){
3309      free(md5str);
3310      return fname;
3311    }
3312    free(md5str);
3313    free(fname);
3314  }
3315  return NULL;
3316}
3317
3318int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet){
3319  if(hInternet->nb>0){
3320    processDownloads(hInternet);
3321    maps* content=*inputs;
3322    map* tmp1;
3323    int index=0;
3324    while(content!=NULL){
3325     
3326      map* length=getMap(content->content,"length");
3327      int shouldClean=-1;
3328      if(length==NULL){
3329        length=createMap("length","1");
3330        shouldClean=1;
3331      }
3332      for(int i=0;i<atoi(length->value);i++){
3333       
3334        char* fcontent;
3335        char *mimeType=NULL;
3336        int fsize=0;
3337        char cname[15];
3338        char vname[11];
3339        char vname1[11];
3340        char sname[9];
3341        char icname[14];
3342        char xname[16];
3343        if(index>0)
3344          sprintf(vname1,"value_%d",index);
3345        else
3346          sprintf(vname1,"value");
3347
3348        if(i>0){
3349          tmp1=getMap(content->content,cname);
3350          sprintf(cname,"cache_file_%d",i);
3351          sprintf(vname,"value_%d",i);
3352          sprintf(sname,"size_%d",i);
3353          sprintf(icname,"isCached_%d",i);
3354          sprintf(xname,"Reference_%d",i);
3355        }else{
3356          sprintf(cname,"cache_file");
3357          sprintf(vname,"value");
3358          sprintf(icname,"isCached");
3359          sprintf(sname,"size");
3360          sprintf(xname,"Reference");
3361        }
3362
3363        map* tmap=getMapFromMaps(*m,"orequests",vname1);
3364        if((tmp1=getMap(content->content,xname))!=NULL && strcasecmp(tmap->value,tmp1->value)==0 ){
3365          if(getMap(content->content,icname)==NULL){
3366           
3367            fcontent=(char*)malloc((hInternet->ihandle[index].nDataLen+1)*sizeof(char));
3368            if(fcontent == NULL){
3369              return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
3370            }
3371            size_t dwRead;
3372            InternetReadFile(hInternet->ihandle[index], 
3373                             (LPVOID)fcontent, 
3374                             hInternet->ihandle[index].nDataLen, 
3375                             &dwRead);
3376            fcontent[hInternet->ihandle[index].nDataLen]=0;
3377            fsize=hInternet->ihandle[index].nDataLen;
3378            if(hInternet->ihandle[index].mimeType==NULL)
3379              mimeType=strdup("none");
3380            else
3381                  mimeType=strdup(hInternet->ihandle[index].mimeType);       
3382           
3383            map* tmpMap=getMapOrFill(&content->content,vname,"");
3384            free(tmpMap->value);
3385            tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
3386            if(tmpMap->value==NULL){
3387              return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
3388            }
3389            memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
3390           
3391            char ltmp1[256];
3392            sprintf(ltmp1,"%d",fsize);
3393            map* tmp=getMapFromMaps(*m,"main","cacheDir");
3394            if(tmp!=NULL){
3395              char* md5str=getMd5(tmp1->value);
3396              char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
3397              sprintf(fname,"%s/%s.zca",tmp->value,md5str);
3398              addToMap(content->content,cname,fname);
3399              free(fname);
3400            }
3401            addToMap(content->content,sname,ltmp1);
3402            addToCache(*m,tmp1->value,fcontent,mimeType,fsize);
3403            free(fcontent);
3404            free(mimeType);
3405            dumpMaps(content);
3406            index++;
3407
3408          }
3409        }
3410      }
3411      if(shouldClean>0){
3412        freeMap(&length);
3413        free(length);
3414      }
3415     
3416      content=content->next;
3417    }
3418   
3419  }
3420  return 0;
3421}
3422
3423/**
3424 * loadRemoteFile:
3425 * Try to load file from cache or download a remote file if not in cache
3426 */
3427int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){
3428  char* fcontent;
3429  char* cached=isInCache(*m,url);
3430  char *mimeType=NULL;
3431  int fsize=0;
3432
3433  map* t=getMap(*content,"xlink:href");
3434  if(t==NULL){
3435    t=getMap((*content),"href");
3436    addToMap(*content,"xlink:href",url);
3437  }
3438
3439  if(cached!=NULL){
3440
3441    struct stat f_status;
3442    int s=stat(cached, &f_status);
3443    if(s==0){
3444      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
3445      FILE* f=fopen(cached,"rb");
3446      fread(fcontent,f_status.st_size,1,f);
3447      fsize=f_status.st_size;
3448      fcontent[fsize]=0;
3449      fclose(f);
3450      addToMap(*content,"cache_file",cached);
3451    }
3452    cached[strlen(cached)-1]='m';
3453    s=stat(cached, &f_status);
3454    if(s==0){
3455      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
3456      FILE* f=fopen(cached,"rb");
3457      fread(mimeType,f_status.st_size,1,f);
3458      mimeType[f_status.st_size]=0;
3459      fclose(f);
3460    }
3461
3462  }else{
3463    hInternet->waitingRequests[hInternet->nb]=strdup(url);
3464    InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
3465    maps *oreq=getMaps(*m,"orequests");
3466    if(oreq==NULL){
3467      oreq=(maps*)malloc(MAPS_SIZE);
3468      oreq->name=zStrdup("orequests");
3469      oreq->content=createMap("value",url);
3470      oreq->next=NULL;
3471      addMapsToMaps(m,oreq);
3472      freeMaps(&oreq);
3473      free(oreq);
3474    }else{
3475      setMapArray(oreq->content,"value",hInternet->nb-1,url);
3476    }
3477    return 0;
3478  }
3479  if(fsize==0){
3480    return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
3481  }
3482  if(mimeType!=NULL){
3483    addToMap(*content,"fmimeType",mimeType);
3484  }
3485
3486  map* tmpMap=getMapOrFill(content,"value","");
3487   
3488  free(tmpMap->value);
3489
3490  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
3491  if(tmpMap->value==NULL)
3492    return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
3493  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
3494
3495  char ltmp1[256];
3496  sprintf(ltmp1,"%d",fsize);
3497  addToMap(*content,"size",ltmp1);
3498  if(cached==NULL){
3499    addToCache(*m,url,fcontent,mimeType,fsize);
3500  }
3501  else{
3502    addToMap(*content,"isCached","true");
3503
3504    map* tmp=getMapFromMaps(*m,"main","cacheDir");
3505    if(tmp!=NULL){
3506      map *c=getMap((*content),"xlink:href");
3507      char* md5str=getMd5(c->value);
3508      char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
3509      sprintf(fname,"%s/%s.zca",tmp->value,md5str);
3510      addToMap(*content,"cache_file",fname);
3511      free(fname);
3512    }
3513  }
3514  free(fcontent);
3515  free(mimeType);
3516  free(cached);
3517  return 0;
3518}
3519
3520char *readVSIFile(maps* conf,const char* dataSource){
3521    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
3522    VSIStatBufL file_status;
3523    VSIStatL(dataSource, &file_status);
3524    if(fichier==NULL){
3525      char tmp[1024];
3526      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %lld.",
3527              dataSource,file_status.st_size);
3528      setMapInMaps(conf,"lenv","message",tmp);
3529      return NULL;
3530    }
3531    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
3532    VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
3533    res1[file_status.st_size-1]=0;
3534    VSIFCloseL(fichier);
3535    VSIUnlink(dataSource);
3536    return res1;
3537}
3538
3539void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
3540  setMapInMaps(conf,"lenv","oIdentifier",identifier);
3541  char *lid=zStrdup(identifier);
3542  char *saveptr1;
3543  char *tmps1=strtok_r(lid,".",&saveptr1);
3544  int level=0;
3545  char key[25];
3546  char levels[18];
3547  while(tmps1!=NULL){
3548    char *test=zStrdup(tmps1);
3549    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
3550    sprintf(key,"sprefix_%d",level);
3551    sprintf(tmps2,"%s.",test);
3552    sprintf(levels,"%d",level);
3553    setMapInMaps(conf,"lenv","level",levels);
3554    setMapInMaps(conf,"lenv",key,tmps2);
3555    free(tmps2);
3556    free(test);
3557    level++;
3558    tmps1=strtok_r(NULL,".",&saveptr1);
3559  }
3560  int i=0;
3561  sprintf(buffer,"%s",conf_dir);
3562  for(i=0;i<level;i++){
3563    char *tmp0=zStrdup(buffer);
3564    sprintf(key,"sprefix_%d",i);
3565    map* tmp00=getMapFromMaps(conf,"lenv",key);
3566    if(tmp00!=NULL)
3567      sprintf(buffer,"%s/%s",tmp0,tmp00->value);
3568    free(tmp0);
3569    buffer[strlen(buffer)-1]=0;
3570    if(i+1<level){
3571      map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
3572      if(tmpMap==NULL || strlen(tmpMap->value)==0){
3573        char *tmp01=zStrdup(tmp00->value);
3574        tmp01[strlen(tmp01)-1]=0;
3575        setMapInMaps(conf,"lenv","metapath",tmp01);
3576        free(tmp01);
3577        tmp01=NULL;
3578      }
3579      else{
3580        if(tmp00!=NULL && tmpMap!=NULL){
3581          char *tmp00s=zStrdup(tmp00->value);
3582          tmp00s[strlen(tmp00s)-1]=0;
3583          char *value=(char*)malloc((strlen(tmp00s)+strlen(tmpMap->value)+2)*sizeof(char));
3584          sprintf(value,"%s/%s",tmpMap->value,tmp00s);
3585          setMapInMaps(conf,"lenv","metapath",value);
3586          free(value);
3587          free(tmp00s);
3588          value=NULL;
3589        }
3590      }
3591    }else{
3592      char *tmp01=zStrdup(tmp00->value);
3593      tmp01[strlen(tmp01)-1]=0;
3594      setMapInMaps(conf,"lenv","Identifier",tmp01);
3595      free(tmp01);
3596    }
3597  }
3598  char *tmp0=zStrdup(buffer);
3599  sprintf(buffer,"%s.zcfg",tmp0);
3600  free(tmp0);
3601  free(lid);
3602}
3603
3604int updateStatus( maps* conf, const int percentCompleted, const char* message ){
3605  char tmp[4];
3606  snprintf(tmp,4,"%d",percentCompleted);
3607  setMapInMaps( conf, "lenv", "status", tmp );
3608  setMapInMaps( conf, "lenv", "message", message);
3609  return _updateStatus( conf );
3610}
3611
3612char* getInputValue( maps* inputs, const char* parameterName, size_t* numberOfBytes){
3613  map* res=getMapFromMaps(inputs,parameterName,"value");
3614  if(res!=NULL){
3615    map* size=getMapFromMaps(inputs,parameterName,"size");
3616    if(size!=NULL){
3617      *numberOfBytes=(size_t)atoi(size->value);
3618      return res->value;
3619    }else{
3620      *numberOfBytes=strlen(res->value);
3621      return res->value;
3622    }
3623  }
3624  return NULL;
3625}
3626
3627int  setOutputValue( maps* outputs, const char* parameterName, char* data, size_t numberOfBytes ){
3628  if(numberOfBytes==-1){
3629    setMapInMaps(outputs,parameterName,"value",data);
3630  }else{
3631    char size[1024];
3632    map* tmp=getMapFromMaps(outputs,parameterName,"value");
3633    if(tmp==NULL){
3634      setMapInMaps(outputs,parameterName,"value","");
3635      tmp=getMapFromMaps(outputs,parameterName,"value");
3636    }
3637    free(tmp->value);
3638    tmp->value=(char*) malloc((numberOfBytes+1)*sizeof(char));
3639    memcpy(tmp->value,data,numberOfBytes);
3640    sprintf(size,"%lu",numberOfBytes);
3641    setMapInMaps(outputs,parameterName,"size",size);
3642  }
3643  return 0;
3644}
3645
3646/************************************************************************/
3647/*                           checkValidValue()                          */
3648/************************************************************************/
3649
3650/**
3651 * Verify if a parameter value is valid.
3652 *
3653 * @param request the request map
3654 * @param res the error map potentially generated
3655 * @param avalues the acceptable values (or null if testing only for presence)
3656 * @param mandatory verify the presence of the parameter if mandatory > 0
3657 */
3658void checkValidValue(map* request,map** res,const char* toCheck,const char** avalues,int mandatory){
3659  map* lres=*res;
3660  map* r_inputs = getMap (request,toCheck);
3661  if (r_inputs == NULL){
3662    if(mandatory>0){
3663      char *replace=_("Mandatory parameter <%s> was not specified");
3664      char *message=(char*)malloc((strlen(replace)+strlen(toCheck)+1)*sizeof(char));
3665      sprintf(message,replace,toCheck);
3666      if(lres==NULL){
3667        lres=createMap("code","MissingParameterValue");
3668        addToMap(lres,"text",message);
3669        addToMap(lres,"locator",toCheck);       
3670      }else{
3671        int length=1;
3672        map* len=getMap(lres,"length");
3673        if(len!=NULL){
3674          length=atoi(len->value);
3675        }
3676        setMapArray(lres,"text",length,message);
3677        setMapArray(lres,"locator",length,toCheck);
3678        setMapArray(lres,"code",length,"MissingParameter");
3679      }
3680      free(message);
3681    }
3682  }else{
3683    if(avalues==NULL)
3684      return;
3685    int nb=0;
3686    int hasValidValue=-1;
3687    while(avalues[nb]!=NULL){
3688      if(strcasecmp(avalues[nb],r_inputs->value)==0){
3689        hasValidValue=1;
3690        break;
3691      }
3692      nb++;
3693    }
3694    if(hasValidValue<0){
3695      char *replace=_("Ununderstood <%s> value, %s %s the only acceptable value.");
3696      nb=0;
3697      char *vvalues=NULL;
3698      char* num=_("is");
3699      while(avalues[nb]!=NULL){
3700        char *tvalues;
3701        if(vvalues==NULL){
3702          vvalues=(char*)malloc((strlen(avalues[nb])+3)*sizeof(char));
3703          sprintf(vvalues,"%s",avalues[nb]);
3704        }
3705        else{
3706          tvalues=zStrdup(vvalues);
3707          vvalues=(char*)realloc(vvalues,(strlen(tvalues)+strlen(avalues[nb])+3)*sizeof(char));
3708          sprintf(vvalues,"%s, %s",tvalues,avalues[nb]);
3709          free(tvalues);
3710          num=_("are");
3711        }
3712        nb++;
3713      }
3714      char *message=(char*)malloc((strlen(replace)+strlen(num)+strlen(vvalues)+strlen(toCheck)+1)*sizeof(char));
3715      sprintf(message,replace,toCheck,vvalues,num);
3716      if(lres==NULL){
3717        lres=createMap("code","InvalidParameterValue");
3718        addToMap(lres,"text",message);
3719        addToMap(lres,"locator",toCheck);       
3720      }else{
3721        int length=1;
3722        map* len=getMap(lres,"length");
3723        if(len!=NULL){
3724          length=atoi(len->value);
3725        }
3726        setMapArray(lres,"text",length,message);
3727        setMapArray(lres,"locator",length,toCheck);
3728        setMapArray(lres,"code",length,"InvalidParameterValue");
3729      }
3730    }
3731  }
3732  if(lres!=NULL){
3733    *res=lres;
3734  }
3735}
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