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

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

Add concurrency gesture for background services. Fix tickets #102 and #103.

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