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

Last change on this file since 514 was 514, checked in by djay, 8 years ago

Use unique identifier as reference for asynchronous service execution.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 95.1 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  printDescription(nc,ns_ows,serv->name,serv->content);
1780
1781  xmlAddChild(n,nc);
1782
1783  nc = xmlNewNode(ns, BAD_CAST "Status");
1784  const struct tm *tm;
1785  size_t len;
1786  time_t now;
1787  char *tmp1;
1788  map *tmpStatus;
1789 
1790  now = time ( NULL );
1791  tm = localtime ( &now );
1792
1793  tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
1794
1795  len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
1796
1797  xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
1798
1799  char sMsg[2048];
1800  switch(status){
1801  case SERVICE_SUCCEEDED:
1802    nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
1803    sprintf(sMsg,_("Service \"%s\" run successfully."),serv->name);
1804    nc3=xmlNewText(BAD_CAST sMsg);
1805    xmlAddChild(nc1,nc3);
1806    break;
1807  case SERVICE_STARTED:
1808    nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
1809    tmpStatus=getMapFromMaps(m,"lenv","status");
1810    xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
1811    sprintf(sMsg,_("ZOO Service \"%s\" is currently running. Please, reload this document to get the up-to-date status of the Service."),serv->name);
1812    nc3=xmlNewText(BAD_CAST sMsg);
1813    xmlAddChild(nc1,nc3);
1814    break;
1815  case SERVICE_ACCEPTED:
1816    nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
1817    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);
1818    nc3=xmlNewText(BAD_CAST sMsg);
1819    xmlAddChild(nc1,nc3);
1820    break;
1821  case SERVICE_FAILED:
1822    nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
1823    map *errorMap;
1824    map *te;
1825    te=getMapFromMaps(m,"lenv","code");
1826    if(te!=NULL)
1827      errorMap=createMap("code",te->value);
1828    else
1829      errorMap=createMap("code","NoApplicableCode");
1830    te=getMapFromMaps(m,"lenv","message");
1831    if(te!=NULL)
1832      addToMap(errorMap,"text",_ss(te->value));
1833    else
1834      addToMap(errorMap,"text",_("No more information available"));
1835    nc3=createExceptionReportNode(m,errorMap,0);
1836    freeMap(&errorMap);
1837    free(errorMap);
1838    xmlAddChild(nc1,nc3);
1839    break;
1840  default :
1841    printf(_("error code not know : %i\n"),status);
1842    //exit(1);
1843    break;
1844  }
1845  xmlAddChild(nc,nc1);
1846  xmlAddChild(n,nc);
1847  free(tmp1);
1848
1849#ifdef DEBUG
1850  fprintf(stderr,"printProcessResponse 1 161\n");
1851#endif
1852
1853  map* lineage=getMap(request,"lineage");
1854  if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
1855    nc = xmlNewNode(ns, BAD_CAST "DataInputs");
1856    maps* mcursor=inputs;
1857    elements* scursor=NULL;
1858    while(mcursor!=NULL /*&& scursor!=NULL*/){
1859      scursor=getElements(serv->inputs,mcursor->name);
1860      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input");
1861      mcursor=mcursor->next;
1862    }
1863    xmlAddChild(n,nc);
1864   
1865#ifdef DEBUG
1866    fprintf(stderr,"printProcessResponse 1 177\n");
1867#endif
1868
1869    nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
1870    mcursor=outputs;
1871    scursor=NULL;
1872    while(mcursor!=NULL){
1873      scursor=getElements(serv->outputs,mcursor->name);
1874      printOutputDefinitions1(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
1875      mcursor=mcursor->next;
1876    }
1877    xmlAddChild(n,nc);
1878  }
1879#ifdef DEBUG
1880  fprintf(stderr,"printProcessResponse 1 190\n");
1881#endif
1882
1883  /**
1884   * Display the process output only when requested !
1885   */
1886  if(status==SERVICE_SUCCEEDED){
1887    nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
1888    maps* mcursor=outputs;
1889    elements* scursor=serv->outputs;
1890    map* testResponse=getMap(request,"RawDataOutput");
1891    if(testResponse==NULL)
1892      testResponse=getMap(request,"ResponseDocument");
1893    while(mcursor!=NULL){
1894      map* tmp0=getMap(mcursor->content,"inRequest");
1895      scursor=getElements(serv->outputs,mcursor->name);
1896      if(scursor!=NULL){
1897        if(testResponse==NULL || tmp0==NULL)
1898          printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1899        else
1900          if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0)
1901            printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1902      }else
1903        /**
1904         * In case there was no definition found in the ZCFG file but
1905         * present in the service code
1906         */
1907        printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1908      mcursor=mcursor->next;
1909    }
1910    xmlAddChild(n,nc);
1911  }
1912
1913#ifdef DEBUG
1914  fprintf(stderr,"printProcessResponse 1 202\n");
1915#endif
1916  nr=soapEnvelope(m,n);
1917  xmlDocSetRootElement(doc, nr);
1918
1919  if(hasStoredExecuteResponse==true && status!=SERVICE_STARTED){
1920    semid lid=getShmLockId(m,1);
1921    if(lid<0)
1922      return;
1923    else{
1924#ifdef DEBUG
1925      fprintf(stderr,"LOCK %s %d !\n",__FILE__,__LINE__);
1926#endif
1927      lockShm(lid);
1928      /* We need to write the ExecuteResponse Document somewhere */
1929      FILE* output=fopen(stored_path,"w");
1930      if(output==NULL){
1931        /* If the file cannot be created return an ExceptionReport */
1932        char tmpMsg[1024];
1933        sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the ExecuteResponse."),stored_path);
1934        map * errormap = createMap("text",tmpMsg);
1935        addToMap(errormap,"code", "InternalError");
1936        printExceptionReportResponse(m,errormap);
1937        freeMap(&errormap);
1938        free(errormap);
1939        xmlFreeDoc(doc);
1940        xmlCleanupParser();
1941        zooXmlCleanupNs();
1942        unlockShm(lid);
1943        return;
1944      }
1945      xmlChar *xmlbuff;
1946      int buffersize;
1947      xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
1948      fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
1949      xmlFree(xmlbuff);
1950      fclose(output);
1951#ifdef DEBUG
1952      fprintf(stderr,"UNLOCK %s %d !\n",__FILE__,__LINE__);
1953#endif
1954      unlockShm(lid);
1955      map* test1=getMap(request,"status");
1956      if(test1==NULL || strcasecmp(test1->value,"true")!=0){
1957        removeShmLock(m,1);
1958      }
1959    }
1960  }
1961  printDocument(m,doc,pid);
1962
1963  xmlCleanupParser();
1964  zooXmlCleanupNs();
1965}
1966
1967
1968void printDocument(maps* m, xmlDocPtr doc,int pid){
1969  char *encoding=getEncoding(m);
1970  if(pid==getpid()){
1971    printHeaders(m);
1972    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1973  }
1974  fflush(stdout);
1975  xmlChar *xmlbuff;
1976  int buffersize;
1977  /*
1978   * Dump the document to a buffer and print it on stdout
1979   * for demonstration purposes.
1980   */
1981  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1982  printf("%s",xmlbuff);
1983  fflush(stdout);
1984  /*
1985   * Free associated memory.
1986   */
1987  xmlFree(xmlbuff);
1988  xmlFreeDoc(doc);
1989  xmlCleanupParser();
1990  zooXmlCleanupNs();
1991}
1992
1993void printOutputDefinitions1(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
1994  xmlNodePtr nc1;
1995  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1996  map *tmp=NULL; 
1997  if(e!=NULL && e->defaults!=NULL)
1998    tmp=e->defaults->content;
1999  else{
2000    /*
2001    dumpElements(e);
2002    */
2003    return;
2004  }
2005  while(tmp!=NULL){
2006    if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
2007       || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
2008       || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
2009       || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
2010    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
2011    tmp=tmp->next;
2012  }
2013  tmp=getMap(e->defaults->content,"asReference");
2014  if(tmp==NULL)
2015    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
2016
2017  tmp=e->content;
2018
2019  printDescription(nc1,ns_ows,m->name,e->content);
2020
2021  xmlAddChild(nc,nc1);
2022
2023}
2024
2025void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,map* m,const char* type){
2026  xmlNodePtr nc1;
2027  nc1=xmlNewNode(ns_wps, BAD_CAST type);
2028  map *tmp=NULL; 
2029  if(e!=NULL && e->defaults!=NULL)
2030    tmp=e->defaults->content;
2031  else{
2032    /*
2033    dumpElements(e);
2034    */
2035    return;
2036  }
2037  while(tmp!=NULL){
2038    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
2039    tmp=tmp->next;
2040  }
2041  tmp=getMap(e->defaults->content,"asReference");
2042  if(tmp==NULL)
2043    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
2044
2045  tmp=e->content;
2046
2047  printDescription(nc1,ns_ows,m->name,e->content);
2048
2049  xmlAddChild(nc,nc1);
2050
2051}
2052
2053void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type){
2054  xmlNodePtr nc1,nc2,nc3;
2055  nc1=xmlNewNode(ns_wps, BAD_CAST type);
2056  map *tmp=NULL;
2057  if(e!=NULL)
2058    tmp=e->content;
2059  else
2060    tmp=m->content;
2061#ifdef DEBUG
2062  dumpMap(tmp);
2063  dumpElements(e);
2064#endif
2065  nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
2066  if(e!=NULL)
2067    nc3=xmlNewText(BAD_CAST e->name);
2068  else
2069    nc3=xmlNewText(BAD_CAST m->name);
2070  xmlAddChild(nc2,nc3);
2071  xmlAddChild(nc1,nc2);
2072  xmlAddChild(nc,nc1);
2073  if(e!=NULL)
2074    tmp=getMap(e->content,"Title");
2075  else
2076    tmp=getMap(m->content,"Title");
2077 
2078  if(tmp!=NULL){
2079    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
2080    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
2081    xmlAddChild(nc2,nc3); 
2082    xmlAddChild(nc1,nc2);
2083  }
2084
2085  if(e!=NULL)
2086    tmp=getMap(e->content,"Abstract");
2087  else
2088    tmp=getMap(m->content,"Abstract");
2089  if(tmp!=NULL){
2090    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
2091    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
2092    xmlAddChild(nc2,nc3); 
2093    xmlAddChild(nc1,nc2);
2094    xmlAddChild(nc,nc1);
2095  }
2096
2097  /**
2098   * IO type Reference or full Data ?
2099   */
2100#ifdef DEBUG
2101  fprintf(stderr,"FORMAT %s %s\n",e->format,e->format);
2102#endif
2103  map *tmpMap=getMap(m->content,"Reference");
2104  if(tmpMap==NULL){
2105    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
2106    if(e!=NULL){
2107      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
2108        nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
2109      else
2110        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
2111          nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
2112        else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
2113          nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
2114        else
2115          nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
2116    }
2117    else{
2118      map* tmpV=getMapFromMaps(m,"format","value");
2119      if(tmpV!=NULL)
2120        nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
2121      else
2122        nc3=xmlNewNode(ns_wps, BAD_CAST "LitteralData");
2123    } 
2124    tmp=m->content;
2125#ifdef USE_MS
2126    map* testMap=getMap(tmp,"requestedMimeType");
2127#endif
2128    while(tmp!=NULL){
2129      if(strcasecmp(tmp->name,"mimeType")==0 ||
2130         strcasecmp(tmp->name,"encoding")==0 ||
2131         strcasecmp(tmp->name,"schema")==0 ||
2132         strcasecmp(tmp->name,"datatype")==0 ||
2133         strcasecmp(tmp->name,"uom")==0){
2134#ifdef USE_MS
2135        if(testMap==NULL || (testMap!=NULL && strncasecmp(testMap->value,"text/xml",8)==0)){
2136#endif
2137          xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
2138#ifdef USE_MS
2139        }
2140        else
2141          if(strcasecmp(tmp->name,"mimeType")==0){
2142            if(testMap!=NULL)
2143              xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
2144            else 
2145              xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
2146          }
2147#endif
2148      }
2149      tmp=tmp->next;
2150      xmlAddChild(nc2,nc3);
2151    }
2152    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2153      map* bb=getMap(m->content,"value");
2154      if(bb!=NULL){
2155        map* tmpRes=parseBoundingBox(bb->value);
2156        printBoundingBox(ns_ows,nc3,tmpRes);
2157        freeMap(&tmpRes);
2158        free(tmpRes);
2159      }
2160    }else{
2161      if(e!=NULL)
2162        tmp=getMap(e->defaults->content,"mimeType");
2163      else
2164        tmp=NULL;
2165#ifdef USE_MS
2166      /**
2167       * In case of OGC WebServices output use, as the data was requested
2168       * with asReference=false we have to download the resulting OWS request
2169       * stored in the Reference map value.
2170       */
2171      map* testMap=getMap(m->content,"requestedMimeType");
2172      if(testMap!=NULL){
2173        HINTERNET hInternet;
2174        char* tmpValue;
2175        size_t dwRead;
2176        hInternet=InternetOpen(
2177#ifndef WIN32
2178                               (LPCTSTR)
2179#endif
2180                               "ZooWPSClient\0",
2181                               INTERNET_OPEN_TYPE_PRECONFIG,
2182                               NULL,NULL, 0);
2183        testMap=getMap(m->content,"Reference");
2184        loadRemoteFile(&m,&m->content,&hInternet,testMap->value);
2185        processDownloads(&hInternet);
2186        tmpValue=(char*)malloc((hInternet.ihandle[0].nDataLen+1)*sizeof(char));
2187        InternetReadFile(hInternet.ihandle[0],(LPVOID)tmpValue,hInternet.ihandle[0].nDataLen,&dwRead);
2188        InternetCloseHandle(&hInternet);
2189      }
2190#endif
2191      map* tmp1=getMap(m->content,"encoding");
2192      map* tmp2=getMap(m->content,"mimeType");
2193      map* tmp3=getMap(m->content,"value");
2194      int hasValue=1;
2195      if(tmp3==NULL){
2196        tmp3=createMap("value","");
2197        hasValue=-1;
2198      }
2199      if((tmp1!=NULL && strncmp(tmp1->value,"base64",6)==0)
2200         || (tmp2!=NULL && (strncmp(tmp2->value,"image/",6)==0 ||
2201                            (strncmp(tmp2->value,"application/",12)==0 &&
2202                             strncmp(tmp2->value,"application/json",16)!=0&&
2203                             strncmp(tmp2->value,"application/x-javascript",24)!=0&&
2204                             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)!=0))
2205             )) {
2206        map* rs=getMap(m->content,"size");
2207        bool isSized=true;
2208        if(rs==NULL){
2209          char tmp1[1024];
2210          sprintf(tmp1,"%u",strlen(tmp3->value));
2211          rs=createMap("size",tmp1);
2212          isSized=false;
2213        }
2214
2215        xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));
2216        if(tmp1==NULL || (tmp1!=NULL && strncmp(tmp1->value,"base64",6)!=0))
2217          xmlNewProp(nc3,BAD_CAST "encoding",BAD_CAST "base64");
2218        if(!isSized){
2219          freeMap(&rs);
2220          free(rs);
2221        }
2222      }
2223      else if(tmp2!=NULL){
2224        if(strncmp(tmp2->value,"text/js",7)==0 ||
2225           strncmp(tmp2->value,"application/json",16)==0)
2226          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
2227        else{
2228          if(strncmp(tmp2->value,"text/xml",8)==0 ||
2229             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)==0){
2230            int li=zooXmlAddDoc(tmp3->value);
2231            xmlDocPtr doc = iDocs[li];
2232            xmlNodePtr ir = xmlDocGetRootElement(doc);
2233            xmlAddChild(nc3,ir);
2234          }
2235          else
2236            xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
2237        }
2238        xmlAddChild(nc2,nc3);
2239      }
2240      else{
2241        xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
2242      }
2243      if(hasValue<0){
2244        freeMap(&tmp3);
2245        free(tmp3);
2246      }
2247    }
2248  }
2249  else{
2250    tmpMap=getMap(m->content,"Reference");
2251    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
2252    if(strcasecmp(type,"Output")==0)
2253      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
2254    else
2255      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
2256    tmp=m->content;
2257#ifdef USE_MS
2258    map* testMap=getMap(tmp,"requestedMimeType");
2259#endif
2260    while(tmp!=NULL){
2261      if(strcasecmp(tmp->name,"mimeType")==0 ||
2262         strcasecmp(tmp->name,"encoding")==0 ||
2263         strcasecmp(tmp->name,"schema")==0 ||
2264         strcasecmp(tmp->name,"datatype")==0 ||
2265         strcasecmp(tmp->name,"uom")==0){
2266#ifdef USE_MS
2267        if(testMap!=NULL  && strncasecmp(testMap->value,"text/xml",8)!=0){
2268          if(strcasecmp(tmp->name,"mimeType")==0)
2269            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
2270        }
2271        else
2272#endif
2273          if(strcasecmp(tmp->name,"datatype")==0)
2274            xmlNewProp(nc3,BAD_CAST "mimeType",BAD_CAST "text/plain");
2275          else
2276            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
2277      }
2278      tmp=tmp->next;
2279      xmlAddChild(nc2,nc3);
2280    }
2281  }
2282  xmlAddChild(nc1,nc2);
2283  xmlAddChild(nc,nc1);
2284
2285}
2286
2287void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
2288  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
2289 
2290  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
2291  xmlAddChild(root,nc2);
2292  map* tmp=amap;
2293  const char *tmp2[2];
2294  tmp2[0]="Title";
2295  tmp2[1]="Abstract";
2296  int j=0;
2297  for(j=0;j<2;j++){
2298    map* tmp1=getMap(tmp,tmp2[j]);
2299    if(tmp1!=NULL){
2300      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
2301      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
2302      xmlAddChild(root,nc2);
2303    }
2304  }
2305}
2306
2307char* getEncoding(maps* m){
2308  if(m!=NULL){
2309    map* tmp=getMap(m->content,"encoding");
2310    if(tmp!=NULL){
2311      return tmp->value;
2312    }
2313    else
2314      return (char*)"UTF-8";
2315  }
2316  else
2317    return (char*)"UTF-8"; 
2318}
2319
2320char* getVersion(maps* m){
2321  if(m!=NULL){
2322    map* tmp=getMap(m->content,"version");
2323    if(tmp!=NULL){
2324      return tmp->value;
2325    }
2326    else
2327      return (char*)"1.0.0";
2328  }
2329  else
2330    return (char*)"1.0.0";
2331}
2332
2333void printExceptionReportResponse(maps* m,map* s){
2334  if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
2335    return;
2336  int buffersize;
2337  xmlDocPtr doc;
2338  xmlChar *xmlbuff;
2339  xmlNodePtr n;
2340
2341  zooXmlCleanupNs();
2342  doc = xmlNewDoc(BAD_CAST "1.0");
2343  maps* tmpMap=getMaps(m,"main");
2344  char *encoding=getEncoding(tmpMap);
2345  const char *exceptionCode;
2346 
2347  map* tmp=getMap(s,"code");
2348  if(tmp!=NULL){
2349    if(strcmp(tmp->value,"OperationNotSupported")==0)
2350      exceptionCode="501 Not Implemented";
2351    else
2352      if(strcmp(tmp->value,"MissingParameterValue")==0 ||
2353         strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
2354         strcmp(tmp->value,"OptionNotSupported")==0 ||
2355         strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
2356         strcmp(tmp->value,"InvalidParameterValue")==0)
2357        exceptionCode="400 Bad request";
2358      else
2359        if(strcmp(tmp->value,"NoApplicableCode")==0)
2360          exceptionCode="501 Internal Server Error";
2361        else
2362          exceptionCode="501 Internal Server Error";
2363  }
2364  else
2365    exceptionCode="501 Internal Server Error";
2366
2367  if(m!=NULL){
2368    map *tmpSid=getMapFromMaps(m,"lenv","sid");
2369    if(tmpSid!=NULL){
2370      if( getpid()==atoi(tmpSid->value) ){
2371        printHeaders(m);
2372        printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
2373      }
2374    }
2375    else{
2376      printHeaders(m);
2377      printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
2378    }
2379  }else{
2380    printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
2381  }
2382  n=createExceptionReportNode(m,s,1);
2383  xmlDocSetRootElement(doc, n);
2384  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2385  printf("%s",xmlbuff);
2386  fflush(stdout);
2387  xmlFreeDoc(doc);
2388  xmlFree(xmlbuff);
2389  xmlCleanupParser();
2390  zooXmlCleanupNs();
2391  if(m!=NULL)
2392    setMapInMaps(m,"lenv","hasPrinted","true");
2393}
2394
2395xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
2396 
2397  xmlNsPtr ns,ns_xsi;
2398  xmlNodePtr n,nc,nc1;
2399
2400  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows","ows");
2401  ns=usedNs[nsid];
2402  if(use_ns==1){
2403    ns=NULL;
2404  }
2405  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
2406  if(use_ns==1){
2407    xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",NULL);
2408    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2409    ns_xsi=usedNs[xsiId];
2410    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");
2411  }
2412
2413
2414  addLangAttr(n,m);
2415  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
2416 
2417  nc = xmlNewNode(ns, BAD_CAST "Exception");
2418
2419  map* tmp=getMap(s,"code");
2420  if(tmp!=NULL)
2421    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
2422  else
2423    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
2424
2425  tmp=getMap(s,"locator");
2426  if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
2427    xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
2428
2429
2430  tmp=getMap(s,"text");
2431  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
2432  if(tmp!=NULL){
2433    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
2434  }
2435  else{
2436    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
2437  }
2438  xmlAddChild(nc,nc1);
2439  xmlAddChild(n,nc);
2440  return n;
2441}
2442
2443
2444void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
2445                    map* request_inputs1,int cpid,maps* m,int res){
2446#ifdef DEBUG
2447  dumpMaps(request_inputs);
2448  dumpMaps(request_outputs);
2449  fprintf(stderr,"printProcessResponse\n");
2450#endif
2451  map* toto=getMap(request_inputs1,"RawDataOutput");
2452  int asRaw=0;
2453  if(toto!=NULL)
2454    asRaw=1;
2455 
2456  maps* tmpSess=getMaps(m,"senv");
2457  if(tmpSess!=NULL){
2458    map *_tmp=getMapFromMaps(m,"lenv","cookie");
2459    char* sessId=NULL;
2460    if(_tmp!=NULL){
2461      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
2462      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
2463      char session_file_path[100];
2464      char *tmp1=strtok(_tmp->value,";");
2465      if(tmp1!=NULL)
2466        sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
2467      else
2468        sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
2469      sessId=strdup(session_file_path);
2470    }else{
2471      maps* t=getMaps(m,"senv");
2472      map*p=t->content;
2473      while(p!=NULL){
2474        if(strstr(p->name,"ID")!=NULL){
2475          sessId=strdup(p->value);
2476          break;
2477        }
2478        p=p->next;
2479      }
2480    }
2481    char session_file_path[1024];
2482    map *tmpPath=getMapFromMaps(m,"main","sessPath");
2483    if(tmpPath==NULL)
2484      tmpPath=getMapFromMaps(m,"main","tmpPath");
2485    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
2486    FILE* teste=fopen(session_file_path,"w");
2487    if(teste==NULL){
2488      char tmpMsg[1024];
2489      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the session maps."),session_file_path);
2490      map * errormap = createMap("text",tmpMsg);
2491      addToMap(errormap,"code", "InternalError");
2492     
2493      printExceptionReportResponse(m,errormap);
2494      freeMap(&errormap);
2495      free(errormap);
2496      return;
2497    }
2498    else{
2499      fclose(teste);
2500      dumpMapsToFile(tmpSess,session_file_path);
2501    }
2502  }
2503 
2504
2505  if(asRaw==0){
2506#ifdef DEBUG
2507    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
2508    dumpMaps(request_outputs);
2509#endif
2510    maps* tmpI=request_outputs;
2511    while(tmpI!=NULL){
2512#ifdef USE_MS
2513      map* testMap=getMap(tmpI->content,"useMapserver");       
2514#endif
2515      toto=getMap(tmpI->content,"asReference");
2516#ifdef USE_MS
2517      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
2518#else
2519      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
2520#endif
2521        {
2522        elements* in=getElements(s->outputs,tmpI->name);
2523        char *format=NULL;
2524        if(in!=NULL){
2525          format=strdup(in->format);
2526        }else
2527          format=strdup("LiteralData");
2528        if(strcasecmp(format,"BoundingBoxData")==0){
2529          addToMap(tmpI->content,"extension","xml");
2530          addToMap(tmpI->content,"mimeType","text/xml");
2531          addToMap(tmpI->content,"encoding","UTF-8");
2532          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2533        }
2534        map *ext=getMap(tmpI->content,"extension");
2535        map *tmp1=getMapFromMaps(m,"main","tmpPath");
2536        char *file_name,*file_path;
2537        bool hasExt=true;
2538        if(ext==NULL){
2539          // We can fallback to a default list of supported formats using
2540          // mimeType information if present here. Maybe we can add more formats
2541          // here.
2542          // If mimeType was not found, we then set txt as the default extension
2543          map* mtype=getMap(tmpI->content,"mimeType");
2544          if(mtype!=NULL){
2545            if(strcasecmp(mtype->value,"text/xml")==0)
2546              ext=createMap("extension","xml");
2547            else if(strcasecmp(mtype->value,"application/json")==0)
2548              ext=createMap("extension","js");
2549            else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
2550              ext=createMap("extension","kml");
2551            else if(strncmp(mtype->value,"image/",6)==0)
2552              ext=createMap("extension",strstr(mtype->value,"/")+1);
2553            else
2554              ext=createMap("extension","txt");
2555          }
2556          else
2557            ext=createMap("extension","txt");
2558          hasExt=false;
2559        }
2560        file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
2561        int cpid0=cpid+time(NULL);
2562        sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
2563        file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
2564        sprintf(file_path,"%s/%s",tmp1->value,file_name);
2565        FILE *ofile=fopen(file_path,"wb");
2566        if(ofile==NULL){
2567          char tmpMsg[1024];
2568          sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
2569          map * errormap = createMap("text",tmpMsg);
2570          addToMap(errormap,"code", "InternalError");
2571          printExceptionReportResponse(m,errormap);
2572          freeMap(&errormap);
2573          free(errormap);
2574          free(file_name);
2575          free(file_path);
2576          return;
2577        }
2578        free(file_path);
2579        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2580        map *tmp3=getMapFromMaps(m,"main","serverAddress");
2581        char *file_url;
2582        if(strncasecmp(tmp2->value,"http://",7)==0 ||
2583           strncasecmp(tmp2->value,"https://",8)==0){
2584          file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
2585          sprintf(file_url,"%s/%s",tmp2->value,file_name);
2586        }else{
2587          file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
2588          sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2589        }
2590        addToMap(tmpI->content,"Reference",file_url);
2591        if(!hasExt){
2592          freeMap(&ext);
2593          free(ext);
2594        }
2595        toto=getMap(tmpI->content,"value");
2596        if(strcasecmp(format,"BoundingBoxData")!=0){
2597          map* size=getMap(tmpI->content,"size");
2598          if(size!=NULL && toto!=NULL)
2599            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2600          else
2601            if(toto!=NULL && toto->value!=NULL)
2602              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2603        }else{
2604          printBoundingBoxDocument(m,tmpI,ofile);
2605        }
2606        free(format);
2607        fclose(ofile);
2608        free(file_name);
2609        free(file_url); 
2610        }
2611#ifdef USE_MS
2612      else{
2613        if(testMap!=NULL){
2614          setReferenceUrl(m,tmpI);
2615        }
2616      }
2617#endif
2618      tmpI=tmpI->next;
2619    }
2620    map *r_inputs=getMap(s->content,"serviceProvider");
2621#ifdef DEBUG
2622    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2623    dumpMaps(m);
2624#endif
2625    printProcessResponse(m,request_inputs1,cpid,
2626                         s,r_inputs->value,res,
2627                         request_inputs,
2628                         request_outputs);
2629    }
2630    else{
2631      if(res==SERVICE_FAILED){
2632        map * errormap;
2633        map *lenv;
2634        lenv=getMapFromMaps(m,"lenv","message");
2635        char *tmp0;
2636        if(lenv!=NULL){
2637          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));
2638          sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
2639        }
2640        else{
2641          tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
2642          sprintf(tmp0,_("Unable to run the Service. No more information was returned back by the Service."));
2643        }
2644        errormap = createMap("text",tmp0);
2645        free(tmp0);
2646        addToMap(errormap,"code", "InternalError");
2647        printExceptionReportResponse(m,errormap);
2648        freeMap(&errormap);
2649        free(errormap);
2650        return;
2651      }
2652      /**
2653       * We get the requested output or fallback to the first one if the
2654       * requested one is not present in the resulting outputs maps.
2655       */
2656      maps* tmpI=NULL;
2657      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2658      if(tmpIV!=NULL){
2659        tmpI=getMaps(request_outputs,tmpIV->value);
2660      }
2661      if(tmpI==NULL)
2662        tmpI=request_outputs;
2663      elements* e=getElements(s->outputs,tmpI->name);
2664      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2665        printBoundingBoxDocument(m,tmpI,NULL);
2666      }else{
2667        toto=getMap(tmpI->content,"value");
2668        if(toto==NULL){
2669          char tmpMsg[1024];
2670          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2671          map * errormap = createMap("text",tmpMsg);
2672          addToMap(errormap,"code", "InvalidParameterValue");
2673          printExceptionReportResponse(m,errormap);
2674          freeMap(&errormap);
2675          free(errormap);
2676          return;
2677        }
2678        map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2679        if(fname!=NULL)
2680          printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2681        map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2682        if(rs!=NULL)
2683          printf("Content-Length: %s\r\n",rs->value);
2684        printHeaders(m);
2685        char mime[1024];
2686        map* mi=getMap(tmpI->content,"mimeType");
2687#ifdef DEBUG
2688        fprintf(stderr,"SERVICE OUTPUTS\n");
2689        dumpMaps(request_outputs);
2690        fprintf(stderr,"SERVICE OUTPUTS\n");
2691#endif
2692        map* en=getMap(tmpI->content,"encoding");
2693        if(mi!=NULL && en!=NULL)
2694          sprintf(mime,
2695                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2696                  mi->value,en->value);
2697        else
2698          if(mi!=NULL)
2699            sprintf(mime,
2700                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2701                    mi->value);
2702          else
2703            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2704        printf("%s",mime);
2705        if(rs!=NULL)
2706          fwrite(toto->value,1,atoi(rs->value),stdout);
2707        else
2708          fwrite(toto->value,1,strlen(toto->value),stdout);
2709#ifdef DEBUG
2710        dumpMap(toto);
2711#endif
2712      }
2713    }
2714}
2715
2716char *base64(const char *input, int length)
2717{
2718  BIO *bmem, *b64;
2719  BUF_MEM *bptr;
2720
2721  b64 = BIO_new(BIO_f_base64());
2722  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2723  bmem = BIO_new(BIO_s_mem());
2724  b64 = BIO_push(b64, bmem);
2725  BIO_write(b64, input, length+1);
2726  BIO_flush(b64);
2727  BIO_get_mem_ptr(b64, &bptr);
2728
2729  char *buff = (char *)malloc((bptr->length+1)*sizeof(char));
2730  memcpy(buff, bptr->data, bptr->length);
2731  buff[bptr->length-1] = 0;
2732
2733  BIO_free_all(b64);
2734
2735  return buff;
2736}
2737
2738char *base64d(const char *input, int length,int* red)
2739{
2740  BIO *b64, *bmem;
2741
2742  char *buffer = (char *)malloc(length);
2743  if(buffer){
2744    memset(buffer, 0, length);
2745    b64 = BIO_new(BIO_f_base64());
2746    if(b64){
2747      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2748      bmem = BIO_push(b64, bmem);
2749      *red=BIO_read(bmem, buffer, length);
2750      buffer[length-1]=0;
2751      BIO_free_all(bmem);
2752    }
2753  }
2754  return buffer;
2755}
2756
2757void ensureDecodedBase64(maps **in){
2758  maps* cursor=*in;
2759  while(cursor!=NULL){
2760    map *tmp=getMap(cursor->content,"encoding");
2761    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2762      tmp=getMap(cursor->content,"value");
2763      addToMap(cursor->content,"base64_value",tmp->value);
2764      int size=0;
2765      char *s=strdup(tmp->value);
2766      free(tmp->value);
2767      tmp->value=base64d(s,strlen(s),&size);
2768      free(s);
2769      char sizes[1024];
2770      sprintf(sizes,"%d",size);
2771      addToMap(cursor->content,"size",sizes);
2772    }
2773    cursor=cursor->next;
2774  }
2775}
2776
2777char* addDefaultValues(maps** out,elements* in,maps* m,int type){
2778  elements* tmpInputs=in;
2779  maps* out1=*out;
2780  if(type==1){
2781    while(out1!=NULL){
2782      if(getElements(in,out1->name)==NULL)
2783        return out1->name;
2784      out1=out1->next;
2785    }
2786    out1=*out;
2787  }
2788  while(tmpInputs!=NULL){
2789    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2790    if(tmpMaps==NULL){
2791      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2792      tmpMaps2->name=strdup(tmpInputs->name);
2793      tmpMaps2->content=NULL;
2794      tmpMaps2->next=NULL;
2795     
2796      if(type==0){
2797        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2798        if(tmpMapMinO!=NULL){
2799          if(atoi(tmpMapMinO->value)>=1){
2800            freeMaps(&tmpMaps2);
2801            free(tmpMaps2);
2802            return tmpInputs->name;
2803          }
2804          else{
2805            if(tmpMaps2->content==NULL)
2806              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2807            else
2808              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2809          }
2810        }
2811        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2812        if(tmpMaxO!=NULL){
2813          if(tmpMaps2->content==NULL)
2814            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2815          else
2816            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2817        }
2818        map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
2819        if(tmpMaxMB!=NULL){
2820          if(tmpMaps2->content==NULL)
2821            tmpMaps2->content=createMap("maximumMegabytes",tmpMaxMB->value);
2822          else
2823            addToMap(tmpMaps2->content,"maximumMegabytes",tmpMaxMB->value);
2824        }
2825      }
2826
2827      iotype* tmpIoType=tmpInputs->defaults;
2828      if(tmpIoType!=NULL){
2829        map* tmpm=tmpIoType->content;
2830        while(tmpm!=NULL){
2831          if(tmpMaps2->content==NULL)
2832            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2833          else
2834            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2835          tmpm=tmpm->next;
2836        }
2837      }
2838      addToMap(tmpMaps2->content,"inRequest","false");
2839      if(type==0){
2840        map *tmpMap=getMap(tmpMaps2->content,"value");
2841        if(tmpMap==NULL)
2842          addToMap(tmpMaps2->content,"value","NULL");
2843      }
2844      if(out1==NULL){
2845        *out=dupMaps(&tmpMaps2);
2846        out1=*out;
2847      }
2848      else
2849        addMapsToMaps(&out1,tmpMaps2);
2850      freeMap(&tmpMaps2->content);
2851      free(tmpMaps2->content);
2852      tmpMaps2->content=NULL;
2853      freeMaps(&tmpMaps2);
2854      free(tmpMaps2);
2855      tmpMaps2=NULL;
2856    }
2857    else{
2858      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2859                                             tmpMaps->content);
2860      if(type==0) {
2861        /**
2862         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2863         * content map.
2864         */
2865        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2866        if(tmpMap1!=NULL){
2867          if(tmpMaps->content==NULL)
2868            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2869          else
2870            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2871        }
2872        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2873        if(tmpMaxO!=NULL){
2874          if(tmpMaps->content==NULL)
2875            tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
2876          else
2877            addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
2878        }
2879        map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
2880        if(tmpMaxMB!=NULL){
2881          if(tmpMaps->content==NULL)
2882            tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
2883          else
2884            addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
2885        }
2886        /**
2887         * Parsing BoundingBoxData, fill the following map and then add it to
2888         * the content map of the Input maps:
2889         * lowerCorner, upperCorner, srs and dimensions
2890         * cf. parseBoundingBox
2891         */
2892        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2893          maps* tmpI=getMaps(*out,tmpInputs->name);
2894          if(tmpI!=NULL){
2895            map* tmpV=getMap(tmpI->content,"value");
2896            if(tmpV!=NULL){
2897              char *tmpVS=strdup(tmpV->value);
2898              map* tmp=parseBoundingBox(tmpVS);
2899              free(tmpVS);
2900              map* tmpC=tmp;
2901              while(tmpC!=NULL){
2902                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2903                tmpC=tmpC->next;
2904              }
2905              freeMap(&tmp);
2906              free(tmp);
2907            }
2908          }
2909        }
2910      }
2911
2912      if(tmpIoType!=NULL){
2913        map* tmpContent=tmpIoType->content;
2914        map* cval=NULL;
2915        int hasPassed=-1;
2916        while(tmpContent!=NULL){
2917          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2918#ifdef DEBUG
2919            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2920#endif
2921            if(tmpMaps->content==NULL)
2922              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2923            else
2924              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2925           
2926            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
2927              map* length=getMap(tmpMaps->content,"length");
2928              int i;
2929              char *tcn=strdup(tmpContent->name);
2930              for(i=1;i<atoi(length->value);i++){
2931#ifdef DEBUG
2932                dumpMap(tmpMaps->content);
2933                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
2934#endif
2935                int len=strlen((char*) tcn);
2936                char *tmp1=(char *)malloc((len+10)*sizeof(char));
2937                sprintf(tmp1,"%s_%d",tcn,i);
2938#ifdef DEBUG
2939                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
2940#endif
2941                addToMap(tmpMaps->content,tmp1,tmpContent->value);
2942                free(tmp1);
2943                hasPassed=1;
2944              }
2945              free(tcn);
2946            }
2947          }
2948          tmpContent=tmpContent->next;
2949        }
2950#ifdef USE_MS
2951        /**
2952         * check for useMapServer presence
2953         */
2954        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
2955        if(tmpCheck!=NULL){
2956          // Get the default value
2957          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
2958          tmpCheck=getMap(tmpMaps->content,"mimeType");
2959          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
2960          map* cursor=tmpIoType->content;
2961          while(cursor!=NULL){
2962            addToMap(tmpMaps->content,cursor->name,cursor->value);
2963            cursor=cursor->next;
2964          }
2965         
2966          cursor=tmpInputs->content;
2967          while(cursor!=NULL){
2968            if(strcasecmp(cursor->name,"Title")==0 ||
2969               strcasecmp(cursor->name,"Abstract")==0)
2970              addToMap(tmpMaps->content,cursor->name,cursor->value);
2971           cursor=cursor->next;
2972          }
2973        }
2974#endif
2975      }
2976      if(tmpMaps->content==NULL)
2977        tmpMaps->content=createMap("inRequest","true");
2978      else
2979        addToMap(tmpMaps->content,"inRequest","true");
2980
2981    }
2982    tmpInputs=tmpInputs->next;
2983  }
2984  return "";
2985}
2986
2987/**
2988 * parseBoundingBox : parse a BoundingBox string
2989 *
2990 * OGC 06-121r3 : 10.2 Bounding box
2991 *
2992 * value is provided as : lowerCorner,upperCorner,crs,dimension
2993 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2994 *
2995 * Need to create a map to store boundingbox informations :
2996 *  - lowerCorner : double,double (minimum within this bounding box)
2997 *  - upperCorner : double,double (maximum within this bounding box)
2998 *  - crs : URI (Reference to definition of the CRS)
2999 *  - dimensions : int
3000 *
3001 * Note : support only 2D bounding box.
3002 */
3003map* parseBoundingBox(const char* value){
3004  map *res=NULL;
3005  if(value!=NULL){
3006    char *cv,*cvp;
3007    cv=strtok_r((char*) value,",",&cvp);
3008    int cnt=0;
3009    int icnt=0;
3010    char *currentValue=NULL;
3011    while(cv){
3012      if(cnt<2)
3013        if(currentValue!=NULL){
3014          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
3015          sprintf(finalValue,"%s%s",currentValue,cv);
3016          switch(cnt){
3017          case 0:
3018            res=createMap("lowerCorner",finalValue);
3019            break;
3020          case 1:
3021            addToMap(res,"upperCorner",finalValue);
3022            icnt=-1;
3023            break;
3024          }
3025          cnt++;
3026          free(currentValue);
3027          currentValue=NULL;
3028          free(finalValue);
3029        }
3030        else{
3031          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
3032          sprintf(currentValue,"%s ",cv);
3033        }
3034      else
3035        if(cnt==2){
3036          addToMap(res,"crs",cv);
3037          cnt++;
3038        }
3039        else
3040          addToMap(res,"dimensions",cv);
3041      icnt++;
3042      cv=strtok_r(NULL,",",&cvp);
3043    }
3044  }
3045  return res;
3046}
3047
3048/**
3049 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
3050 * wps:BoundingBoxData). Set crs and dimensions attributes, add
3051 * Lower/UpperCorner nodes to a pre-existing XML node.
3052 */
3053void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
3054
3055  xmlNodePtr lw=NULL,uc=NULL;
3056
3057  map* tmp=getMap(boundingbox,"value");
3058
3059  tmp=getMap(boundingbox,"lowerCorner");
3060  if(tmp!=NULL){
3061    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
3062    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
3063  }
3064
3065  tmp=getMap(boundingbox,"upperCorner");
3066  if(tmp!=NULL){
3067    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
3068    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
3069  }
3070
3071  tmp=getMap(boundingbox,"crs");
3072  if(tmp!=NULL)
3073    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
3074
3075  tmp=getMap(boundingbox,"dimensions");
3076  if(tmp!=NULL)
3077    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
3078
3079  xmlAddChild(n,lw);
3080  xmlAddChild(n,uc);
3081
3082}
3083
3084void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
3085  if(file==NULL)
3086    rewind(stdout);
3087  xmlNodePtr n;
3088  xmlDocPtr doc;
3089  xmlNsPtr ns_ows,ns_xsi;
3090  xmlChar *xmlbuff;
3091  int buffersize;
3092  char *encoding=getEncoding(m);
3093  map *tmp;
3094  if(file==NULL){
3095    int pid=0;
3096    tmp=getMapFromMaps(m,"lenv","sid");
3097    if(tmp!=NULL)
3098      pid=atoi(tmp->value);
3099    if(pid==getpid()){
3100      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
3101    }
3102    fflush(stdout);
3103  }
3104
3105  doc = xmlNewDoc(BAD_CAST "1.0");
3106  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
3107  ns_ows=usedNs[owsId];
3108  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
3109  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
3110  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
3111  ns_xsi=usedNs[xsiId];
3112  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");
3113  map *tmp1=getMap(boundingbox->content,"value");
3114  tmp=parseBoundingBox(tmp1->value);
3115  printBoundingBox(ns_ows,n,tmp);
3116  xmlDocSetRootElement(doc, n);
3117
3118  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
3119  if(file==NULL)
3120    printf("%s",xmlbuff);
3121  else{
3122    fprintf(file,"%s",xmlbuff);
3123  }
3124
3125  if(tmp!=NULL){
3126    freeMap(&tmp);
3127    free(tmp);
3128  }
3129  xmlFree(xmlbuff);
3130  xmlFreeDoc(doc);
3131  xmlCleanupParser();
3132  zooXmlCleanupNs();
3133 
3134}
3135
3136
3137char* getMd5(char* url){
3138  EVP_MD_CTX md5ctx;
3139  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
3140  unsigned char result[EVP_MAX_MD_SIZE];
3141  unsigned int len;
3142  EVP_DigestInit(&md5ctx, EVP_md5());
3143  EVP_DigestUpdate(&md5ctx, url, strlen(url));
3144  EVP_DigestFinal_ex(&md5ctx,result,&len);
3145  EVP_MD_CTX_cleanup(&md5ctx);
3146  int i;
3147  for(i = 0; i < len; i++){
3148    if(i>0){
3149      char *tmp=strdup(fresult);
3150      sprintf(fresult,"%s%02x", tmp,result[i]);
3151      free(tmp);
3152    }
3153    else
3154      sprintf(fresult,"%02x",result[i]);
3155  }
3156  return fresult;
3157}
3158
3159/**
3160 * Cache a file for a given request
3161 */
3162void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
3163  map* tmp=getMapFromMaps(conf,"main","cacheDir");
3164  if(tmp!=NULL){
3165    char* md5str=getMd5(request);
3166    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
3167    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
3168#ifdef DEBUG
3169    fprintf(stderr,"Cache list : %s\n",fname);
3170    fflush(stderr);
3171#endif
3172    FILE* fo=fopen(fname,"w+");
3173    if(fo==NULL){
3174      fprintf (stderr, "Failed to open %s for writting: %s\n",fname, strerror(errno));
3175      return;
3176    }
3177    fwrite(content,sizeof(char),length,fo);
3178    fclose(fo);
3179
3180    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
3181    fo=fopen(fname,"w+");
3182#ifdef DEBUG
3183    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
3184#endif
3185    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
3186    fclose(fo);
3187
3188    free(md5str);
3189    free(fname);
3190  }
3191}
3192
3193char* isInCache(maps* conf,char* request){
3194  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
3195  if(tmpM!=NULL){
3196    char* md5str=getMd5(request);
3197#ifdef DEBUG
3198    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
3199#endif
3200    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
3201    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
3202    struct stat f_status;
3203    int s=stat(fname, &f_status);
3204    if(s==0 && f_status.st_size>0){
3205      free(md5str);
3206      return fname;
3207    }
3208    free(md5str);
3209    free(fname);
3210  }
3211  return NULL;
3212}
3213
3214int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet){
3215  if(hInternet->nb>0){
3216    processDownloads(hInternet);
3217    maps* content=*inputs;
3218    map* tmp1;
3219    int index=0;
3220    while(content!=NULL){
3221      if((tmp1=getMap(content->content,"href")) || 
3222         (tmp1=getMap(content->content,"xlink:href"))){
3223        if(getMap(content->content,"isCached")==NULL){
3224          char* fcontent;
3225          char *mimeType=NULL;
3226          int fsize=0;
3227
3228          fcontent=(char*)malloc((hInternet->ihandle[index].nDataLen+1)*sizeof(char));
3229          if(fcontent == NULL){
3230            return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
3231          }
3232          size_t dwRead;
3233          InternetReadFile(hInternet->ihandle[index], 
3234                           (LPVOID)fcontent, 
3235                           hInternet->ihandle[index].nDataLen, 
3236                           &dwRead);
3237          fcontent[hInternet->ihandle[index].nDataLen]=0;
3238          fsize=hInternet->ihandle[index].nDataLen;
3239          if(hInternet->ihandle[index].mimeType==NULL)
3240            mimeType=strdup("none");
3241          else
3242            mimeType=strdup((char*)hInternet->ihandle[index].mimeType);
3243         
3244          map* tmpMap=getMapOrFill(&content->content,"value","");
3245          free(tmpMap->value);
3246          tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
3247          if(tmpMap->value==NULL){
3248            return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
3249          }
3250          memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
3251         
3252          char ltmp1[256];
3253          sprintf(ltmp1,"%d",fsize);
3254          addToMap(content->content,"size",ltmp1);
3255          addToCache(*m,tmp1->value,fcontent,mimeType,fsize);
3256          free(fcontent);
3257          free(mimeType);
3258        }
3259        index++;
3260      }
3261      content=content->next;
3262    }
3263  }
3264}
3265
3266/**
3267 * loadRemoteFile:
3268 * Try to load file from cache or download a remote file if not in cache
3269 */
3270int loadRemoteFile(maps** m,map** content,HINTERNET* hInternet,char *url){
3271  char* fcontent;
3272  char* cached=isInCache(*m,url);
3273  char *mimeType=NULL;
3274  int fsize=0;
3275  if(cached!=NULL){
3276    struct stat f_status;
3277    int s=stat(cached, &f_status);
3278    if(s==0){
3279      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
3280      FILE* f=fopen(cached,"rb");
3281      fread(fcontent,f_status.st_size,1,f);
3282      fsize=f_status.st_size;
3283      fcontent[fsize]=0;
3284      fclose(f);
3285    }
3286    cached[strlen(cached)-1]='m';
3287    s=stat(cached, &f_status);
3288    if(s==0){
3289      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
3290      FILE* f=fopen(cached,"rb");
3291      fread(mimeType,f_status.st_size,1,f);
3292      mimeType[f_status.st_size]=0;
3293      fclose(f);
3294    }
3295  }else{
3296    hInternet->waitingRequests[hInternet->nb]=strdup(url);
3297    InternetOpenUrl(hInternet,hInternet->waitingRequests[hInternet->nb],NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
3298    return 0;
3299  }
3300  if(fsize==0){
3301    return errorException(*m, _("Unable to download the file."), "InternalError",NULL);
3302  }
3303  if(mimeType!=NULL){
3304    addToMap(*content,"fmimeType",mimeType);
3305  }
3306
3307  map* tmpMap=getMapOrFill(content,"value","");
3308   
3309  free(tmpMap->value);
3310  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
3311  if(tmpMap->value==NULL)
3312    return errorException(*m, _("Unable to allocate memory."), "InternalError",NULL);
3313  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
3314 
3315  char ltmp1[256];
3316  sprintf(ltmp1,"%d",fsize);
3317  addToMap(*content,"size",ltmp1);
3318  if(cached==NULL)
3319    addToCache(*m,url,fcontent,mimeType,fsize);
3320  else
3321    addToMap(*content,"isCached","true");
3322  free(fcontent);
3323  free(mimeType);
3324  free(cached);
3325  return 0;
3326}
3327
3328int errorException(maps *m, const char *message, const char *errorcode, const char *locator) 
3329{
3330  map* errormap = createMap("text", message);
3331  addToMap(errormap,"code", errorcode);
3332  if(locator!=NULL)
3333    addToMap(errormap,"locator", locator);
3334  else
3335    addToMap(errormap,"locator", "NULL");
3336  printExceptionReportResponse(m,errormap);
3337  freeMap(&errormap);
3338  free(errormap);
3339  return -1;
3340}
3341
3342
3343char *readVSIFile(maps* conf,const char* dataSource){
3344    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
3345    VSIStatBufL file_status;
3346    VSIStatL(dataSource, &file_status);
3347    if(fichier==NULL){
3348      char tmp[1024];
3349      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %d.",
3350              dataSource,file_status.st_size);
3351      setMapInMaps(conf,"lenv","message",tmp);
3352      return NULL;
3353    }
3354    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
3355    VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
3356    res1[file_status.st_size-1]=0;
3357    VSIFCloseL(fichier);
3358    VSIUnlink(dataSource);
3359    return res1;
3360}
3361
3362void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
3363  char *saveptr1;
3364  char *tmps1=strtok_r(identifier,".",&saveptr1);
3365  int level=0;
3366  char key[25];
3367  char levels[18];
3368  while(tmps1!=NULL){
3369    char *test=zStrdup(tmps1);
3370    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
3371    sprintf(key,"sprefix_%d",level);
3372    sprintf(tmps2,"%s.",test);
3373    sprintf(levels,"%d",level);
3374    setMapInMaps(conf,"lenv","level",levels);
3375    setMapInMaps(conf,"lenv",key,tmps2);
3376    free(tmps2);
3377    free(test);
3378    level++;
3379    tmps1=strtok_r(NULL,".",&saveptr1);
3380  }
3381  int i=0;
3382  sprintf(buffer,"%s",conf_dir);
3383  for(i=0;i<level;i++){
3384    char *tmp0=zStrdup(buffer);
3385    sprintf(key,"sprefix_%d",i);
3386    map* tmp00=getMapFromMaps(conf,"lenv",key);
3387    if(tmp00!=NULL)
3388      sprintf(buffer,"%s/%s",tmp0,tmp00->value);
3389    free(tmp0);
3390    buffer[strlen(buffer)-1]=0;
3391    if(i+1<level){
3392      map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
3393      if(tmpMap==NULL || strlen(tmpMap->value)==0){
3394        char *tmp01=zStrdup(tmp00->value);
3395        tmp01[strlen(tmp01)-1]=0;
3396        setMapInMaps(conf,"lenv","metapath",tmp01);
3397        free(tmp01);
3398        tmp01=NULL;
3399      }
3400      else{
3401        if(tmp00!=NULL && tmpMap!=NULL){
3402          char *tmp00s=zStrdup(tmp00->value);
3403          tmp00s[strlen(tmp00s)-1]=0;
3404          char *value=(char*)malloc((strlen(tmp00s)+strlen(tmpMap->value)+2)*sizeof(char));
3405          sprintf(value,"%s/%s",tmpMap->value,tmp00s);
3406          setMapInMaps(conf,"lenv","metapath",value);
3407          free(value);
3408          free(tmp00s);
3409          value=NULL;
3410        }
3411      }
3412    }else{
3413      char *tmp01=zStrdup(tmp00->value);
3414      tmp01[strlen(tmp01)-1]=0;
3415      setMapInMaps(conf,"lenv","Identifier",tmp01);
3416      free(tmp01);
3417    }
3418  }
3419  char *tmp0=zStrdup(buffer);
3420  sprintf(buffer,"%s.zcfg",tmp0);
3421  free(tmp0);
3422}
3423
3424int updateStatus( maps* conf, const int percentCompleted, const char* message ){
3425  char tmp[4];
3426  snprintf(tmp,4,"%d",percentCompleted);
3427  setMapInMaps( conf, "lenv", "status", tmp );
3428  setMapInMaps( conf, "lenv", "message", message);
3429  return _updateStatus( conf );
3430}
3431
3432char* getInputValue( maps* inputs, const char* parameterName, size_t* numberOfBytes){
3433  map* res=getMapFromMaps(inputs,parameterName,"value");
3434  if(res!=NULL){
3435    map* size=getMapFromMaps(inputs,parameterName,"size");
3436    if(size!=NULL){
3437      *numberOfBytes=(size_t)atoi(size->value);
3438      return res->value;
3439    }else{
3440      *numberOfBytes=strlen(res->value);
3441      return res->value;
3442    }
3443  }
3444  return NULL;
3445}
3446
3447int  setOutputValue( maps* outputs, const char* parameterName, char* data, size_t numberOfBytes ){
3448  if(numberOfBytes==-1){
3449    setMapInMaps(outputs,parameterName,"value",data);
3450  }else{
3451    char size[1024];
3452    map* tmp=getMapFromMaps(outputs,parameterName,"value");
3453    free(tmp->value);
3454    tmp->value=(char*) malloc((numberOfBytes+1)*sizeof(char));
3455    memcpy(tmp->value,data,numberOfBytes);
3456    sprintf(size,"%lu",numberOfBytes);
3457    setMapInMaps(outputs,parameterName,"size",size);
3458  }
3459  return 0;
3460}
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