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

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

Fix yaml service naming. Add javax javaxx optional sections in the main.cfg #105.

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