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

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

Added function getLastErrorMessage() (service_internal.c). Fixed problems caused by differing return types for GetLastError?() (unsigned int) and dlerror() (char*). Added DEBUG-conditional macros for diagnostic output in zoo_service_loader.c.

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