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

Last change on this file since 459 was 459, checked in by djay, 10 years ago

Initial introduction of Value and Range in AllowedValues?, update zcfg documentation. Return valid Status code when returning ExceptionRepport?.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 77.9 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#endif
29
30#ifndef TRUE
31#define TRUE 1
32#endif
33#ifndef FALSE
34#define FALSE -1
35#endif
36
37void printHeaders(maps* m){
38  maps *_tmp=getMaps(m,"headers");
39  if(_tmp!=NULL){
40    map* _tmp1=_tmp->content;
41    while(_tmp1!=NULL){
42      printf("%s: %s\r\n",_tmp1->name,_tmp1->value);
43      _tmp1=_tmp1->next;
44    }
45  }
46}
47
48void addLangAttr(xmlNodePtr n,maps *m){
49  map *tmpLmap=getMapFromMaps(m,"main","language");
50  if(tmpLmap!=NULL)
51    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST tmpLmap->value);
52  else
53    xmlNewProp(n,BAD_CAST "xml:lang",BAD_CAST "en-US");
54}
55
56/* Converts a hex character to its integer value */
57char from_hex(char ch) {
58  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
59}
60
61/* Converts an integer value to its hex character*/
62char to_hex(char code) {
63  static char hex[] = "0123456789abcdef";
64  return hex[code & 15];
65}
66
67#ifdef WIN32
68
69#include <windows.h>
70#include <stdio.h>
71#include <conio.h>
72#include <tchar.h>
73
74#define SHMEMSIZE 4096
75
76static LPVOID lpvMemG = NULL;      // pointer to shared memory
77static HANDLE hMapObjectG = NULL;  // handle to file mapping
78
79void updateStatus(maps *conf){
80  LPWSTR lpszTmp;
81  BOOL fInit;
82  char *final_string=NULL;
83  char *s=NULL;
84  map *tmpMap1;
85  map *tmpMap=getMapFromMaps(conf,"lenv","sid");
86  if(hMapObjectG==NULL)
87    hMapObjectG = CreateFileMapping( 
88                                    INVALID_HANDLE_VALUE,   // use paging file
89                                    NULL,                   // default security attributes
90                                    PAGE_READWRITE,         // read/write access
91                                    0,                      // size: high 32-bits
92                                    SHMEMSIZE,              // size: low 32-bits
93                                    TEXT(tmpMap->value));   // name of map object
94  if (hMapObjectG == NULL){
95    fprintf(stderr,"Unable to create share memory segment %s !! \n",tmpMap->value);
96    return ;
97  }
98  fInit = (GetLastError() != ERROR_ALREADY_EXISTS); 
99  if(lpvMemG==NULL)
100    lpvMemG = MapViewOfFile( 
101                            hMapObjectG,     // object to map view of
102                            FILE_MAP_WRITE, // read/write access
103                            0,              // high offset:  map from
104                            0,              // low offset:   beginning
105                            0);             // default: map entire file
106  if (lpvMemG == NULL){
107    fprintf(stderr,"Unable to create or access the shared memory segment %s !! \n",tmpMap->value);
108    return ;
109  } 
110  memset(lpvMemG, '\0', SHMEMSIZE);
111  tmpMap=getMapFromMaps(conf,"lenv","status");
112  tmpMap1=NULL;
113  tmpMap1=getMapFromMaps(conf,"lenv","message");
114  lpszTmp = (LPWSTR) lpvMemG;
115  final_string=(char*)malloc((strlen(tmpMap1->value)+strlen(tmpMap->value)+2)*sizeof(char));
116  sprintf(final_string,"%s|%s",tmpMap->value,tmpMap1->value);
117  for(s=final_string;*s!='\0';*s++){
118    *lpszTmp++ = *s;
119  }
120  *lpszTmp++ = '\0';
121  free(final_string);
122}
123
124char* getStatus(int pid){
125  char lpszBuf[SHMEMSIZE];
126  int i=0;
127  LPWSTR lpszTmp=NULL;
128  LPVOID lpvMem = NULL;
129  HANDLE hMapObject = NULL;
130  BOOL fIgnore,fInit;
131  char tmp[100];
132  sprintf(tmp,"%i",pid);
133  if(hMapObject==NULL)
134    hMapObject = CreateFileMapping( 
135                                   INVALID_HANDLE_VALUE,   // use paging file
136                                   NULL,                   // default security attributes
137                                   PAGE_READWRITE,         // read/write access
138                                   0,                      // size: high 32-bits
139                                   4096,                   // size: low 32-bits
140                                   TEXT(tmp));   // name of map object
141  if (hMapObject == NULL) 
142    return FALSE;
143  if((GetLastError() != ERROR_ALREADY_EXISTS)){
144    fIgnore = UnmapViewOfFile(lpvMem); 
145    fIgnore = CloseHandle(hMapObject);
146    return "-1";
147  }
148  fInit=TRUE;
149  if(lpvMem==NULL)
150    lpvMem = MapViewOfFile( 
151                           hMapObject,     // object to map view of
152                           FILE_MAP_READ,  // read/write access
153                           0,              // high offset:  map from
154                           0,              // low offset:   beginning
155                           0);             // default: map entire file
156  if (lpvMem == NULL) 
157    return "-1"; 
158  lpszTmp = (LPWSTR) lpvMem;
159  while (*lpszTmp){
160    lpszBuf[i] = (char)*lpszTmp;
161    *lpszTmp++; 
162    lpszBuf[i+1] = '\0'; 
163    i++;
164  }
165  fprintf(stderr,"READING STRING S %s\n",lpszBuf);
166  return (char*)lpszBuf;
167}
168
169void unhandleStatus(maps *conf){
170  BOOL fIgnore;
171  fIgnore = UnmapViewOfFile(lpvMemG); 
172  fIgnore = CloseHandle(hMapObjectG);
173}
174#else
175
176void unhandleStatus(maps *conf){
177  int shmid,i;
178  key_t key;
179  void *shm;
180  struct shmid_ds shmids;
181  char *s,*s1;
182  map *tmpMap=getMapFromMaps(conf,"lenv","sid");
183  if(tmpMap!=NULL){
184    key=atoi(tmpMap->value);
185    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
186#ifdef DEBUG
187      fprintf(stderr,"shmget failed to update value\n");
188#endif
189    }else{
190      if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
191#ifdef DEBUG
192        fprintf(stderr,"shmat failed to update value\n");
193#endif
194      }else{
195        shmdt(shm);
196        shmctl(shmid,IPC_RMID,&shmids);
197      }
198    }
199  }
200}
201
202void updateStatus(maps *conf){
203  int shmid,i;
204  key_t key;
205  char *shm,*s,*s1;
206  map *tmpMap=NULL;
207  tmpMap=getMapFromMaps(conf,"lenv","sid");
208  if(tmpMap!=NULL){
209    key=atoi(tmpMap->value);
210    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
211#ifdef DEBUG
212      fprintf(stderr,"shmget failed to create new Shared memory segment\n");
213#endif
214    }else{
215      if ((shm = (char*) shmat(shmid, NULL, 0)) == (char *) -1) {
216#ifdef DEBUG
217        fprintf(stderr,"shmat failed to update value\n");
218#endif
219      }
220      else{
221        tmpMap=getMapFromMaps(conf,"lenv","status");
222        s1=shm;
223        for(s=tmpMap->value;*s!=NULL && *s!=0;s++){
224          *s1++=*s;
225        }
226        *s1++='|';
227        tmpMap=getMapFromMaps(conf,"lenv","message");
228        if(tmpMap!=NULL)
229          for(s=tmpMap->value;*s!=NULL && *s!=0;s++){
230            *s1++=*s;
231        }
232        *s1=NULL;
233        shmdt((void *)shm);
234      }
235    }
236  }
237}
238
239char* getStatus(int pid){
240  int shmid,i;
241  key_t key;
242  void *shm;
243  char *s;
244  key=pid;
245  if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
246#ifdef DEBUG
247    fprintf(stderr,"shmget failed in getStatus\n");
248#endif
249  }else{
250    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
251#ifdef DEBUG
252      fprintf(stderr,"shmat failed in getStatus\n");
253#endif
254    }else{
255      return (char*)shm;
256    }
257  }
258  return "-1";
259}
260
261#endif
262
263#ifdef USE_JS
264
265JSBool
266JSUpdateStatus(JSContext *cx, uintN argc, jsval *argv1)
267{
268  jsval *argv = JS_ARGV(cx,argv1);
269  JS_MaybeGC(cx);
270  char *sid;
271  int istatus=0;
272  char *status=NULL;
273  maps *conf;
274  int i=0;
275  if(argc>2){
276#ifdef JS_DEBUG
277    fprintf(stderr,"Number of arguments used to call the function : %i",argc);
278#endif
279    return JS_FALSE;
280  }
281  conf=mapsFromJSObject(cx,argv[0]);
282  if(JS_ValueToInt32(cx,argv[1],&istatus)==JS_TRUE){
283    char tmpStatus[4];
284    sprintf(tmpStatus,"%i",istatus);
285    tmpStatus[3]=0;
286    status=strdup(tmpStatus);
287  }
288  if(getMapFromMaps(conf,"lenv","status")!=NULL){
289    if(status!=NULL){
290      setMapInMaps(conf,"lenv","status",status);
291      free(status);
292    }
293    else
294      setMapInMaps(conf,"lenv","status","15");
295    updateStatus(conf);
296  }
297  freeMaps(&conf);
298  free(conf);
299  JS_MaybeGC(cx);
300  return JS_TRUE;
301}
302
303#endif
304
305
306
307/* Returns a url-encoded version of str */
308/* IMPORTANT: be sure to free() the returned string after use */
309char *url_encode(char *str) {
310  char *pstr = str, *buf = (char*) malloc(strlen(str) * 3 + 1), *pbuf = buf;
311  while (*pstr) {
312    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
313      *pbuf++ = *pstr;
314    else if (*pstr == ' ') 
315      *pbuf++ = '+';
316    else 
317      *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
318    pstr++;
319  }
320  *pbuf = '\0';
321  return buf;
322}
323
324/* Returns a url-decoded version of str */
325/* IMPORTANT: be sure to free() the returned string after use */
326char *url_decode(char *str) {
327  char *pstr = str, *buf = (char*) malloc(strlen(str) + 1), *pbuf = buf;
328  while (*pstr) {
329    if (*pstr == '%') {
330      if (pstr[1] && pstr[2]) {
331        *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
332        pstr += 2;
333      }
334    } else if (*pstr == '+') { 
335      *pbuf++ = ' ';
336    } else {
337      *pbuf++ = *pstr;
338    }
339    pstr++;
340  }
341  *pbuf = '\0';
342  return buf;
343}
344
345char *zCapitalize1(char *tmp){
346        char *res=strdup(tmp);
347        if(res[0]>=97 && res[0]<=122)
348                res[0]-=32;
349        return res;
350}
351
352char *zCapitalize(char *tmp){
353  int i=0;
354  char *res=strdup(tmp);
355  for(i=0;i<strlen(res);i++)
356    if(res[i]>=97 && res[i]<=122)
357      res[i]-=32;
358  return res;
359}
360
361
362int zooXmlSearchForNs(const char* name){
363  int i;
364  int res=-1;
365  for(i=0;i<nbNs;i++)
366    if(strncasecmp(name,nsName[i],strlen(nsName[i]))==0){
367      res=i;
368      break;
369    }
370  return res;
371}
372
373int zooXmlAddNs(xmlNodePtr nr,const char* url,const char* name){
374#ifdef DEBUG
375  fprintf(stderr,"zooXmlAddNs %d \n",nbNs);
376#endif
377  int currId=-1;
378  int currNode=-1;
379  if(nbNs==0){
380    nbNs++;
381    currId=0;
382    nsName[currId]=strdup(name);
383    usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
384  }else{
385    currId=zooXmlSearchForNs(name);
386    if(currId<0){
387      nbNs++;
388      currId=nbNs-1;
389      nsName[currId]=strdup(name);
390      usedNs[currId]=xmlNewNs(nr,BAD_CAST url,BAD_CAST name);
391    }
392  }
393  return currId;
394}
395
396void zooXmlCleanupNs(){
397  int j;
398#ifdef DEBUG
399  fprintf(stderr,"zooXmlCleanup %d\n",nbNs);
400#endif
401  for(j=nbNs-1;j>=0;j--){
402#ifdef DEBUG
403    fprintf(stderr,"zooXmlCleanup %d\n",j);
404#endif
405    if(j==0)
406      xmlFreeNs(usedNs[j]);
407    free(nsName[j]);
408    nbNs--;
409  }
410  nbNs=0;
411}
412
413xmlNodePtr soapEnvelope(maps* conf,xmlNodePtr n){
414  map* soap=getMapFromMaps(conf,"main","isSoap");
415  if(soap!=NULL && strcasecmp(soap->value,"true")==0){
416    int lNbNs=nbNs;
417    nsName[lNbNs]=strdup("soap");
418    usedNs[lNbNs]=xmlNewNs(NULL,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
419    nbNs++;
420    xmlNodePtr nr = xmlNewNode(usedNs[lNbNs], BAD_CAST "Envelope");
421    nsName[nbNs]=strdup("soap");
422    usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2003/05/soap-envelope",BAD_CAST "soap");
423    nbNs++;
424    nsName[nbNs]=strdup("xsi");
425    usedNs[nbNs]=xmlNewNs(nr,BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
426    nbNs++;
427    xmlNsPtr ns_xsi=usedNs[nbNs-1];
428    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");
429    xmlNodePtr nr1 = xmlNewNode(usedNs[lNbNs], BAD_CAST "Body");
430    xmlAddChild(nr1,n);
431    xmlAddChild(nr,nr1);
432    return nr;
433  }else
434    return n;
435}
436
437xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr doc,const char* service,maps* m){
438
439  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
440  xmlNodePtr n,nc,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
441  xmlChar *xmlbuff;
442  int buffersize;
443  /**
444   * Create the document and its temporary root.
445   */
446  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
447  ns=usedNs[wpsId];
448  maps* toto1=getMaps(m,"main");
449
450  n = xmlNewNode(ns, BAD_CAST "Capabilities");
451  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
452  ns_ows=usedNs[owsId];
453  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
454  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
455  ns_xsi=usedNs[xsiId];
456  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
457  ns_xlink=usedNs[xlinkId];
458  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"); 
459  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
460  addLangAttr(n,m);
461 
462  if(toto1!=NULL){
463    map* tmp=getMap(toto1->content,"version");
464    if(tmp!=NULL){
465      xmlNewProp(n,BAD_CAST "version",BAD_CAST tmp->value);
466    }
467    else
468      xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
469  }
470  else
471    xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
472
473  char tmp[256];
474 
475  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceIdentification");
476  maps* tmp4=getMaps(m,"identification");
477  if(tmp4!=NULL){
478    map* tmp2=tmp4->content;
479    char *orderedFields[5];
480    orderedFields[0]="Title";
481    orderedFields[1]="Abstract";
482    orderedFields[2]="Keywords";
483    orderedFields[3]="Fees";
484    orderedFields[4]="AccessConstraints";
485    int oI=0;
486    for(oI=0;oI<5;oI++)
487      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
488        if(strcasecmp(tmp2->name,"abstract")==0 ||
489           strcasecmp(tmp2->name,"title")==0 ||
490           strcasecmp(tmp2->name,"accessConstraints")==0 ||
491           strcasecmp(tmp2->name,"fees")==0){
492          tmp2->name[0]=toupper(tmp2->name[0]);
493          nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
494          xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
495          xmlAddChild(nc,nc1);
496        }
497        else
498          if(strcmp(tmp2->name,"keywords")==0){
499            nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
500            char *toto=tmp2->value;
501            char buff[256];
502            int i=0;
503            int j=0;
504            while(toto[i]){
505              if(toto[i]!=',' && toto[i]!=0){
506                buff[j]=toto[i];
507                buff[j+1]=0;
508                j++;
509              }
510              else{
511                nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
512                xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
513                xmlAddChild(nc1,nc2);
514                j=0;
515              }
516              i++;
517            }
518            if(strlen(buff)>0){
519              nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
520              xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
521              xmlAddChild(nc1,nc2);
522            }
523            xmlAddChild(nc,nc1);
524            nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceType");
525            xmlAddChild(nc2,xmlNewText(BAD_CAST "WPS"));
526            xmlAddChild(nc,nc2);
527            nc2 = xmlNewNode(ns_ows, BAD_CAST "ServiceTypeVersion");
528            xmlAddChild(nc2,xmlNewText(BAD_CAST "1.0.0"));
529            xmlAddChild(nc,nc2);         
530          }
531        tmp2=tmp2->next;
532      }
533  }
534  else{
535    fprintf(stderr,"TMP4 NOT FOUND !!");
536    return NULL;
537  }
538  xmlAddChild(n,nc);
539
540  nc = xmlNewNode(ns_ows, BAD_CAST "ServiceProvider");
541  nc3 = xmlNewNode(ns_ows, BAD_CAST "ServiceContact");
542  nc4 = xmlNewNode(ns_ows, BAD_CAST "ContactInfo");
543  nc5 = xmlNewNode(ns_ows, BAD_CAST "Phone");
544  nc6 = xmlNewNode(ns_ows, BAD_CAST "Address");
545  tmp4=getMaps(m,"provider");
546  if(tmp4!=NULL){
547    map* tmp2=tmp4->content;
548    char *tmpAddress[6];
549    tmpAddress[0]="addressDeliveryPoint";
550    tmpAddress[1]="addressCity";
551    tmpAddress[2]="addressAdministrativeArea";
552    tmpAddress[3]="addressPostalCode";
553    tmpAddress[4]="addressCountry";
554    tmpAddress[5]="addressElectronicMailAddress";
555    char *tmpPhone[2];
556    tmpPhone[0]="phoneVoice";
557    tmpPhone[1]="phoneFacsimile";
558    char *orderedFields[12];
559    orderedFields[0]="providerName";
560    orderedFields[1]="providerSite";
561    orderedFields[2]="individualName";
562    orderedFields[3]="positionName";
563    orderedFields[4]=tmpPhone[0];
564    orderedFields[5]=tmpPhone[1];
565    orderedFields[6]=tmpAddress[0];
566    orderedFields[7]=tmpAddress[1];
567    orderedFields[8]=tmpAddress[2];
568    orderedFields[9]=tmpAddress[3];
569    orderedFields[10]=tmpAddress[4];
570    orderedFields[11]=tmpAddress[5];
571    int oI=0;
572    for(oI=0;oI<12;oI++)
573      if((tmp2=getMap(tmp4->content,orderedFields[oI]))!=NULL){
574        if(strcmp(tmp2->name,"keywords")!=0 &&
575           strcmp(tmp2->name,"serverAddress")!=0 &&
576           strcmp(tmp2->name,"lang")!=0){
577          tmp2->name[0]=toupper(tmp2->name[0]);
578          if(strcmp(tmp2->name,"ProviderName")==0){
579            nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
580            xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
581            xmlAddChild(nc,nc1);
582          }
583          else{
584            if(strcmp(tmp2->name,"ProviderSite")==0){
585              nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
586              xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST tmp2->value);
587              xmlAddChild(nc,nc1);
588            } 
589            else 
590              if(strcmp(tmp2->name,"IndividualName")==0 || 
591                 strcmp(tmp2->name,"PositionName")==0){
592                nc1 = xmlNewNode(ns_ows, BAD_CAST tmp2->name);
593                xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
594                xmlAddChild(nc3,nc1);
595              } 
596              else 
597                if(strncmp(tmp2->name,"Phone",5)==0){
598                  int j;
599                  for(j=0;j<2;j++)
600                    if(strcasecmp(tmp2->name,tmpPhone[j])==0){
601                      char *toto=NULL;
602                      char *toto1=tmp2->name;
603                      toto=strstr(toto1,"Phone");
604                      nc1 = xmlNewNode(ns_ows, BAD_CAST toto1+5);
605                      xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
606                      xmlAddChild(nc5,nc1);
607                    }
608                }
609                else 
610                  if(strncmp(tmp2->name,"Address",7)==0){
611                    int j;
612                    for(j=0;j<6;j++)
613                      if(strcasecmp(tmp2->name,tmpAddress[j])==0){
614                        char *toto=NULL;
615                        char *toto1=tmp2->name;
616                        toto=strstr(toto1,"Address");
617                        nc1 = xmlNewNode(ns_ows, BAD_CAST toto1+7);
618                        xmlAddChild(nc1,xmlNewText(BAD_CAST tmp2->value));
619                        xmlAddChild(nc6,nc1);
620                      }
621                  }
622          }
623        }
624        else
625          if(strcmp(tmp2->name,"keywords")==0){
626            nc1 = xmlNewNode(ns_ows, BAD_CAST "Keywords");
627            char *toto=tmp2->value;
628            char buff[256];
629            int i=0;
630            int j=0;
631            while(toto[i]){
632              if(toto[i]!=',' && toto[i]!=0){
633                buff[j]=toto[i];
634                buff[j+1]=0;
635                j++;
636              }
637              else{
638                nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
639                xmlAddChild(nc2,xmlNewText(BAD_CAST buff));           
640                xmlAddChild(nc1,nc2);
641                j=0;
642              }
643              i++;
644            }
645            if(strlen(buff)>0){
646              nc2 = xmlNewNode(ns_ows, BAD_CAST "Keyword");
647              xmlAddChild(nc2,xmlNewText(BAD_CAST buff));             
648              xmlAddChild(nc1,nc2);
649            }
650            xmlAddChild(nc,nc1);
651          }
652        tmp2=tmp2->next;
653      }
654  }
655  else{
656    fprintf(stderr,"TMP4 NOT FOUND !!");
657  }
658  xmlAddChild(nc4,nc5);
659  xmlAddChild(nc4,nc6);
660  xmlAddChild(nc3,nc4);
661  xmlAddChild(nc,nc3);
662  xmlAddChild(n,nc);
663
664
665  nc = xmlNewNode(ns_ows, BAD_CAST "OperationsMetadata");
666  char *tmp2[3];
667  tmp2[0]=strdup("GetCapabilities");
668  tmp2[1]=strdup("DescribeProcess");
669  tmp2[2]=strdup("Execute");
670  int j=0;
671
672  if(toto1!=NULL){
673    map* tmp=getMap(toto1->content,"serverAddress");
674    if(tmp!=NULL){
675      SERVICE_URL = strdup(tmp->value);
676    }
677    else
678      SERVICE_URL = strdup("not_found");
679  }
680  else
681    SERVICE_URL = strdup("not_found");
682
683  for(j=0;j<3;j++){
684    nc1 = xmlNewNode(ns_ows, BAD_CAST "Operation");
685    xmlNewProp(nc1,BAD_CAST "name",BAD_CAST tmp2[j]);
686    nc2 = xmlNewNode(ns_ows, BAD_CAST "DCP");
687    nc3 = xmlNewNode(ns_ows, BAD_CAST "HTTP");
688    nc4 = xmlNewNode(ns_ows, BAD_CAST "Get");
689    sprintf(tmp,"%s/%s",SERVICE_URL,service);
690    xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
691    xmlAddChild(nc3,nc4);
692    if(j>0){
693      nc4 = xmlNewNode(ns_ows, BAD_CAST "Post");
694      xmlNewNsProp(nc4,ns_xlink,BAD_CAST "href",BAD_CAST tmp);
695      xmlAddChild(nc3,nc4);
696    }
697    xmlAddChild(nc2,nc3);
698    xmlAddChild(nc1,nc2);   
699    xmlAddChild(nc,nc1);   
700  }
701  for(j=2;j>=0;j--)
702    free(tmp2[j]);
703  xmlAddChild(n,nc);
704
705  nc = xmlNewNode(ns, BAD_CAST "ProcessOfferings");
706  xmlAddChild(n,nc);
707
708  nc1 = xmlNewNode(ns, BAD_CAST "Languages");
709  nc2 = xmlNewNode(ns, BAD_CAST "Default");
710  nc3 = xmlNewNode(ns, BAD_CAST "Supported");
711 
712  toto1=getMaps(m,"main");
713  if(toto1!=NULL){
714    map* tmp1=getMap(toto1->content,"lang");
715    char *toto=tmp1->value;
716    char buff[256];
717    int i=0;
718    int j=0;
719    int dcount=0;
720    while(toto[i]){
721      if(toto[i]!=',' && toto[i]!=0){
722        buff[j]=toto[i];
723        buff[j+1]=0;
724        j++;
725      }
726      else{
727        nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
728        xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
729        if(dcount==0){
730          xmlAddChild(nc2,nc4);
731          xmlAddChild(nc1,nc2);
732          dcount++;
733        }
734        nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
735        xmlAddChild(nc4,xmlNewText(BAD_CAST buff));
736        xmlAddChild(nc3,nc4);
737        j=0;
738        buff[j]=0;
739      }
740      i++;
741    }
742    if(strlen(buff)>0){
743      nc4 = xmlNewNode(ns_ows, BAD_CAST "Language");
744      xmlAddChild(nc4,xmlNewText(BAD_CAST buff));             
745      xmlAddChild(nc3,nc4);
746    }
747  }
748  xmlAddChild(nc1,nc3);
749  xmlAddChild(n,nc1);
750 
751  xmlNodePtr fn=soapEnvelope(m,n);
752  xmlDocSetRootElement(doc, fn);
753  //xmlFreeNs(ns);
754  free(SERVICE_URL);
755  return nc;
756}
757
758void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
759  xmlNsPtr ns,ns_ows,ns_xlink;
760  xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
761  /**
762   * Initialize or get existing namspaces
763   */
764  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
765  ns=usedNs[wpsId];
766  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
767  ns_ows=usedNs[owsId];
768  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
769  ns_xlink=usedNs[xlinkId];
770
771  int cursor=0;
772  map* tmp1;
773  if(serv->content!=NULL){
774    nc1 = xmlNewNode(ns, BAD_CAST "Process");
775    tmp1=getMap(serv->content,"processVersion");
776    if(tmp1!=NULL)
777      xmlNewNsProp(nc1,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);
778    printDescription(nc1,ns_ows,serv->name,serv->content);
779    tmp1=serv->metadata;
780    while(tmp1!=NULL){
781      nc2 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
782      xmlNewNsProp(nc2,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
783      xmlAddChild(nc1,nc2);
784      tmp1=tmp1->next;
785    }
786    xmlAddChild(nc,nc1);
787  }
788}
789
790xmlNodePtr printDescribeProcessHeader(xmlDocPtr doc,const char* service,maps* m){
791
792  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
793  xmlNodePtr n,nr;
794  xmlChar *xmlbuff;
795  int buffersize;
796
797  int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
798  ns=usedNs[wpsId];
799  n = xmlNewNode(ns, BAD_CAST "ProcessDescriptions");
800  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
801  ns_ows=usedNs[owsId];
802  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
803  zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
804  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
805  ns_xsi=usedNs[xsiId];
806 
807  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");
808  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
809  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
810  addLangAttr(n,m);
811
812  xmlNodePtr fn=soapEnvelope(m,n);
813  xmlDocSetRootElement(doc, fn);
814
815  return n;
816}
817
818void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv,int sc){
819  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
820  xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
821
822  char tmp[256];
823  n=nc;
824 
825  int wpsId=zooXmlAddNs(NULL,"http://schemas.opengis.net/wps/1.0.0","wps");
826  ns=usedNs[wpsId];
827  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
828  ns_ows=usedNs[owsId];
829  int xlinkId=zooXmlAddNs(NULL,"http://www.w3.org/1999/xlink","xlink");
830  ns_xlink=usedNs[xlinkId];
831
832  nc = xmlNewNode(NULL, BAD_CAST "ProcessDescription");
833  char *tmp4[3];
834  tmp4[0]="processVersion";
835  tmp4[1]="storeSupported";
836  tmp4[2]="statusSupported";
837  int j=0;
838  map* tmp1=NULL;
839  for(j=0;j<3;j++){
840    tmp1=getMap(serv->content,tmp4[j]);
841    if(tmp1!=NULL){
842      if(j==0)
843        xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);     
844      else
845        xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value);     
846    }
847    else{
848      if(j>0)
849        xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "false");     
850    }
851  }
852 
853  printDescription(nc,ns_ows,serv->name,serv->content);
854
855  tmp1=serv->metadata;
856  while(tmp1!=NULL){
857    nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
858    xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
859    xmlAddChild(nc,nc1);
860    tmp1=tmp1->next;
861  }
862
863  tmp1=getMap(serv->content,"Profile");
864  if(tmp1!=NULL){
865    nc1 = xmlNewNode(ns, BAD_CAST "Profile");
866    xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
867    xmlAddChild(nc,nc1);
868  }
869
870  nc1 = xmlNewNode(NULL, BAD_CAST "DataInputs");
871  elements* e=serv->inputs;
872  printFullDescription(e,"Input",ns_ows,nc1);
873  xmlAddChild(nc,nc1);
874
875  nc1 = xmlNewNode(NULL, BAD_CAST "ProcessOutputs");
876  e=serv->outputs;
877  printFullDescription(e,"Output",ns_ows,nc1);
878  xmlAddChild(nc,nc1);
879
880  xmlAddChild(n,nc);
881
882}
883
884void printFullDescription(elements *elem,const char* type,xmlNsPtr ns_ows,xmlNodePtr nc1){
885  char *orderedFields[12];
886  orderedFields[0]="mimeType";
887  orderedFields[1]="encoding";
888  orderedFields[2]="schema";
889  orderedFields[3]="dataType";
890  orderedFields[4]="uom";
891  orderedFields[5]="CRS";
892  orderedFields[6]="value";
893  orderedFields[7]="AllowedValues";
894  orderedFields[8]="rangeMin";
895  orderedFields[9]="rangeMax";
896  orderedFields[10]="rangeClosure";
897  orderedFields[11]="rangeSpace";
898
899  xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8;
900  elements* e=elem;
901  map* tmp1=NULL;
902  while(e!=NULL){
903    int default1=0;
904    int isAnyValue=1;
905    nc2 = xmlNewNode(NULL, BAD_CAST type);
906    tmp1=getMap(e->content,"minOccurs");
907    if(tmp1){
908      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
909    }
910    tmp1=getMap(e->content,"maxOccurs");
911    if(tmp1){
912      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
913    }
914
915    printDescription(nc2,ns_ows,e->name,e->content);
916
917    if(strncmp(type,"Output",6)==0){
918      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
919        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralOutput");
920      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
921        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexOutput");
922      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
923        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
924      else
925        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
926    }else{
927      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0){
928        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralData");
929      }
930      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
931        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexData");
932      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
933        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxData");
934      else
935        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
936    }
937    iotype* _tmp=e->defaults;
938    int datatype=0;
939    bool hasDefault=false;
940    bool hasUOM=false;
941    if(_tmp!=NULL){
942      if(strcmp(e->format,"LiteralOutput")==0 ||
943         strcmp(e->format,"LiteralData")==0){
944        datatype=1;
945        nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
946        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
947      }
948      else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
949              strcmp(e->format,"BoundingBoxData")==0){
950        datatype=2;
951        //nc4 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
952        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
953      }
954      else{
955        nc4 = xmlNewNode(NULL, BAD_CAST "Default");
956        nc5 = xmlNewNode(NULL, BAD_CAST "Format");
957      }
958     
959      tmp1=_tmp->content;
960      int avcnt=0;
961      int dcnt=0;
962      int oI=0;
963      for(oI=0;oI<12;oI++)
964        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
965          //while(tmp1!=NULL){
966#ifdef DEBUG
967          printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
968#endif
969          if(strncasecmp(tmp1->name,"DataType",8)==0){
970            nc6 = xmlNewNode(ns_ows, BAD_CAST "DataType");
971            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
972            char tmp[1024];
973            sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
974            xmlNewNsProp(nc6,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
975            xmlAddChild(nc3,nc6);
976            tmp1=tmp1->next;
977            datatype=1;
978            continue;
979          }
980          if(strcmp(tmp1->name,"asReference")!=0 &&
981             strncasecmp(tmp1->name,"DataType",8)!=0 &&
982             strcasecmp(tmp1->name,"extension")!=0 &&
983             strcasecmp(tmp1->name,"value")!=0 &&
984             strncasecmp(tmp1->name,"AllowedValues",13)!=0&&
985             strncasecmp(tmp1->name,"range",5)!=0){
986            if(datatype!=1){
987              char *tmp2=zCapitalize1(tmp1->name);
988              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
989              free(tmp2);
990            }
991            else{
992              char *tmp2=zCapitalize(tmp1->name);
993              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
994              free(tmp2);
995            }
996            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
997            xmlAddChild(nc5,nc6);
998            hasUOM=true;
999          }else 
1000            if(strncmp(type,"Input",5)==0){
1001
1002              if(strcmp(tmp1->name,"value")==0){
1003                nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
1004                xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
1005                default1=1;
1006                hasDefault=true;
1007              }
1008              if(strncasecmp(tmp1->name,"AllowedValues",13)==0){
1009                nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
1010                char *token,*saveptr1;
1011                token=strtok_r(tmp1->value,",",&saveptr1);
1012                while(token!=NULL){
1013                  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
1014                  char *tmps=strdup(token);
1015                  tmps[strlen(tmps)]=0;
1016                  xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
1017                  xmlAddChild(nc6,nc7);
1018                  token=strtok_r(NULL,",",&saveptr1);
1019                }
1020                if(getMap(_tmp->content,"rangeMin")!=NULL ||
1021                   getMap(_tmp->content,"rangeMax")!=NULL ||
1022                   getMap(_tmp->content,"rangeClosure")!=NULL )
1023                  goto doRange;
1024                xmlAddChild(nc3,nc6);
1025                isAnyValue=-1;
1026              }
1027              if(strncasecmp(tmp1->name,"range",5)==0){
1028                if(isAnyValue==1){
1029                  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
1030                doRange:
1031                  nc8 = xmlNewNode(ns_ows, BAD_CAST "Range");
1032                  map *tmp0=getMap(tmp1,"rangeMin");
1033                  if(tmp0!=NULL){
1034                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
1035                    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
1036                    xmlAddChild(nc8,nc7);
1037                  }else{
1038                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
1039                    xmlAddChild(nc8,nc7);
1040                  }
1041                  tmp0=getMap(tmp1,"rangeMax");
1042                  if(tmp0!=NULL){
1043                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
1044                    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
1045                    xmlAddChild(nc8,nc7);
1046                  }else{
1047                    nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
1048                    xmlAddChild(nc8,nc7);
1049                  }
1050                  tmp0=getMap(tmp1,"rangeSpacing");
1051                  if(tmp0!=NULL){
1052                    nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
1053                    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
1054                    xmlAddChild(nc8,nc7);
1055                  }
1056                  tmp0=getMap(tmp1,"rangeClosure");
1057                  if(tmp0!=NULL){
1058                    char *tmp="closed";
1059                    if(strcasecmp(tmp0->value,"co")==0)
1060                      tmp="closed-open";
1061                    else
1062                      if(strcasecmp(tmp0->value,"oc")==0)
1063                        tmp="open-closed";
1064                      else
1065                        if(strcasecmp(tmp0->value,"o")==0)
1066                          tmp="open";
1067                    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
1068                  }else
1069                    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
1070                }
1071                xmlAddChild(nc6,nc8);
1072                xmlAddChild(nc3,nc6);
1073                isAnyValue=-1;
1074              }
1075            }
1076          tmp1=tmp1->next;
1077          if(datatype!=2){
1078            if(hasUOM==true){
1079              xmlAddChild(nc4,nc5);
1080              xmlAddChild(nc3,nc4);
1081            }
1082          }else{
1083            xmlAddChild(nc3,nc5);
1084          }
1085          if(strncmp(type,"Input",5)==0){
1086            if(datatype==1 && isAnyValue==1 && default1>0){
1087              xmlAddChild(nc3,nc7);
1088            }
1089          }
1090         
1091        }
1092      if(strncmp(type,"Input",5)==0){
1093        if(datatype==1 && isAnyValue==1 && avcnt==0){
1094          xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1095          hasDefault=true;
1096          avcnt++;
1097        }
1098      }
1099    }
1100
1101    _tmp=e->supported;
1102    if(_tmp==NULL && (getMap(e->defaults->content,"uom")!=NULL || datatype!=1))
1103      _tmp=e->defaults;
1104
1105    int hasSupported=-1;
1106    while(_tmp!=NULL){
1107      if(hasSupported<0){
1108        if(datatype==0){
1109          nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
1110          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1111        }
1112        else
1113          nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
1114        hasSupported=0;
1115      }else
1116        if(datatype==0)
1117          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1118      tmp1=_tmp->content;
1119      int oI=0;
1120      for(oI=0;oI<6;oI++)
1121        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
1122#ifdef DEBUG
1123          printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
1124#endif
1125          if(strcmp(tmp1->name,"asReference")!=0 && 
1126             strcmp(tmp1->name,"DataType")!=0 &&
1127             strcasecmp(tmp1->name,"extension")!=0){
1128            if(datatype!=1){
1129              char *tmp2=zCapitalize1(tmp1->name);
1130              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1131              free(tmp2);
1132            }
1133            else{
1134              char *tmp2=zCapitalize(tmp1->name);
1135              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
1136              free(tmp2);
1137            }
1138            if(datatype==2){
1139              char *tmpv,*tmps;
1140              tmps=strtok_r(tmp1->value,",",&tmpv);
1141              while(tmps){
1142                xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
1143                xmlAddChild(nc5,nc6);
1144                tmps=strtok_r(NULL,",",&tmpv);
1145                if(tmps){
1146                  char *tmp2=zCapitalize1(tmp1->name);
1147                  nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1148                  free(tmp2);
1149                }
1150              }
1151            }
1152            else{
1153              xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
1154              xmlAddChild(nc5,nc6);
1155            }
1156          }
1157          tmp1=tmp1->next;
1158        }
1159      if(hasSupported<=0){
1160        if(datatype!=2){
1161          xmlAddChild(nc4,nc5);
1162          xmlAddChild(nc3,nc4);
1163        }else
1164          xmlAddChild(nc3,nc5);
1165        hasSupported=1;
1166      }
1167      else
1168        if(datatype!=2){
1169          xmlAddChild(nc4,nc5);
1170        }
1171        else
1172          xmlAddChild(nc3,nc5);
1173      _tmp=_tmp->next;
1174    }
1175    xmlAddChild(nc2,nc3);
1176   
1177    if(datatype!=2 && hasUOM==true){
1178      xmlAddChild(nc3,nc4);
1179      xmlAddChild(nc2,nc3);
1180    }/*else if(datatype!=2){
1181      if(hasDefault!=true && strncmp(type,"Input",5)==0 && isAnyValue==1)
1182        xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1183        }*/
1184   
1185    xmlAddChild(nc1,nc2);
1186   
1187    e=e->next;
1188  }
1189}
1190
1191void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
1192  xmlNsPtr ns,ns1,ns_ows,ns_xlink,ns_xsi;
1193  xmlNodePtr nr,n,nc,nc1,nc2,nc3,pseudor;
1194  xmlDocPtr doc;
1195  xmlChar *xmlbuff;
1196  int buffersize;
1197  time_t time1; 
1198  time(&time1);
1199  nr=NULL;
1200  /**
1201   * Create the document and its temporary root.
1202   */
1203  doc = xmlNewDoc(BAD_CAST "1.0");
1204  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
1205  ns=usedNs[wpsId];
1206
1207  n = xmlNewNode(ns, BAD_CAST "ExecuteResponse");
1208  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
1209  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
1210  ns_ows=usedNs[owsId];
1211  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1212  ns_xlink=usedNs[xlinkId];
1213  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1214  ns_xsi=usedNs[xsiId];
1215 
1216  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");
1217 
1218  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
1219  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
1220  addLangAttr(n,m);
1221
1222  char tmp[256];
1223  char url[1024];
1224  char stored_path[1024];
1225  memset(tmp,0,256);
1226  memset(url,0,1024);
1227  memset(stored_path,0,1024);
1228  maps* tmp_maps=getMaps(m,"main");
1229  if(tmp_maps!=NULL){
1230    map* tmpm1=getMap(tmp_maps->content,"serverAddress");
1231    /**
1232     * Check if the ZOO Service GetStatus is available in the local directory.
1233     * If yes, then it uses a reference to an URL which the client can access
1234     * to get information on the status of a running Service (using the
1235     * percentCompleted attribute).
1236     * Else fallback to the initial method using the xml file to write in ...
1237     */
1238    char ntmp[1024];
1239#ifndef WIN32
1240    getcwd(ntmp,1024);
1241#else
1242    _getcwd(ntmp,1024);
1243#endif
1244    struct stat myFileInfo;
1245    int statRes;
1246    char file_path[1024];
1247    sprintf(file_path,"%s/GetStatus.zcfg",ntmp);
1248    statRes=stat(file_path,&myFileInfo);
1249    if(statRes==0){
1250      char currentSid[128];
1251      map* tmpm=getMap(tmp_maps->content,"rewriteUrl");
1252      map *tmp_lenv=NULL;
1253      tmp_lenv=getMapFromMaps(m,"lenv","sid");
1254      if(tmp_lenv==NULL)
1255        sprintf(currentSid,"%i",pid);
1256      else
1257        sprintf(currentSid,"%s",tmp_lenv->value);
1258      if(tmpm==NULL || strcasecmp(tmpm->value,"false")==0){
1259        sprintf(url,"%s?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1260      }else{
1261        if(strlen(tmpm->value)>0)
1262          if(strcasecmp(tmpm->value,"true")!=0)
1263            sprintf(url,"%s/%s/GetStatus/%s",tmpm1->value,tmpm->value,currentSid);
1264          else
1265            sprintf(url,"%s/GetStatus/%s",tmpm1->value,currentSid);
1266        else
1267          sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1268      }
1269    }else{
1270      map* tmpm2=getMap(tmp_maps->content,"tmpUrl");
1271      if(tmpm1!=NULL && tmpm2!=NULL){
1272        if( strncasecmp( tmpm2->value, "http://", 7) == 0 ||
1273            strncasecmp( tmpm2->value, "https://", 8 ) == 0 ){
1274          sprintf(url,"%s/%s_%i.xml",tmpm2->value,service,pid);
1275        }else
1276          sprintf(url,"%s/%s/%s_%i.xml",tmpm1->value,tmpm2->value,service,pid);
1277      }
1278    }
1279    if(tmpm1!=NULL)
1280      sprintf(tmp,"%s",tmpm1->value);
1281    tmpm1=getMapFromMaps(m,"main","TmpPath");
1282    sprintf(stored_path,"%s/%s_%i.xml",tmpm1->value,service,pid);
1283  }
1284
1285
1286
1287  xmlNewProp(n,BAD_CAST "serviceInstance",BAD_CAST tmp);
1288  map* test=getMap(request,"storeExecuteResponse");
1289  bool hasStoredExecuteResponse=false;
1290  if(test!=NULL && strcasecmp(test->value,"true")==0){
1291    xmlNewProp(n,BAD_CAST "statusLocation",BAD_CAST url);
1292    hasStoredExecuteResponse=true;
1293  }
1294
1295  nc = xmlNewNode(ns, BAD_CAST "Process");
1296  map* tmp2=getMap(serv->content,"processVersion");
1297  if(tmp2!=NULL)
1298    xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp2->value);
1299 
1300  printDescription(nc,ns_ows,serv->name,serv->content);
1301
1302  xmlAddChild(n,nc);
1303
1304  nc = xmlNewNode(ns, BAD_CAST "Status");
1305  const struct tm *tm;
1306  size_t len;
1307  time_t now;
1308  char *tmp1;
1309  map *tmpStatus;
1310 
1311  now = time ( NULL );
1312  tm = localtime ( &now );
1313
1314  tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
1315
1316  len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
1317
1318  xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
1319
1320  char sMsg[2048];
1321  switch(status){
1322  case SERVICE_SUCCEEDED:
1323    nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
1324    sprintf(sMsg,_("Service \"%s\" run successfully."),serv->name);
1325    nc3=xmlNewText(BAD_CAST sMsg);
1326    xmlAddChild(nc1,nc3);
1327    break;
1328  case SERVICE_STARTED:
1329    nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
1330    tmpStatus=getMapFromMaps(m,"lenv","status");
1331    xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
1332    sprintf(sMsg,_("ZOO Service \"%s\" is currently running. Please, reload this document to get the up-to-date status of the Service."),serv->name);
1333    nc3=xmlNewText(BAD_CAST sMsg);
1334    xmlAddChild(nc1,nc3);
1335    break;
1336  case SERVICE_ACCEPTED:
1337    nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
1338    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);
1339    nc3=xmlNewText(BAD_CAST sMsg);
1340    xmlAddChild(nc1,nc3);
1341    break;
1342  case SERVICE_FAILED:
1343    nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
1344    map *errorMap;
1345    map *te;
1346    te=getMapFromMaps(m,"lenv","code");
1347    if(te!=NULL)
1348      errorMap=createMap("code",te->value);
1349    else
1350      errorMap=createMap("code","NoApplicableCode");
1351    te=getMapFromMaps(m,"lenv","message");
1352    if(te!=NULL)
1353      addToMap(errorMap,"text",_ss(te->value));
1354    else
1355      addToMap(errorMap,"text",_("No more information available"));
1356    nc3=createExceptionReportNode(m,errorMap,0);
1357    freeMap(&errorMap);
1358    free(errorMap);
1359    xmlAddChild(nc1,nc3);
1360    break;
1361  default :
1362    printf(_("error code not know : %i\n"),status);
1363    //exit(1);
1364    break;
1365  }
1366  xmlAddChild(nc,nc1);
1367  xmlAddChild(n,nc);
1368  free(tmp1);
1369
1370#ifdef DEBUG
1371  fprintf(stderr,"printProcessResponse 1 161\n");
1372#endif
1373
1374  map* lineage=getMap(request,"lineage");
1375  if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
1376    nc = xmlNewNode(ns, BAD_CAST "DataInputs");
1377    int i;
1378    maps* mcursor=inputs;
1379    elements* scursor=NULL;
1380    while(mcursor!=NULL /*&& scursor!=NULL*/){
1381      scursor=getElements(serv->inputs,mcursor->name);
1382      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input");
1383      mcursor=mcursor->next;
1384    }
1385    xmlAddChild(n,nc);
1386   
1387#ifdef DEBUG
1388    fprintf(stderr,"printProcessResponse 1 177\n");
1389#endif
1390
1391    nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
1392    mcursor=outputs;
1393    scursor=NULL;
1394    while(mcursor!=NULL){
1395      scursor=getElements(serv->outputs,mcursor->name);
1396      printOutputDefinitions1(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
1397      mcursor=mcursor->next;
1398    }
1399    xmlAddChild(n,nc);
1400  }
1401#ifdef DEBUG
1402  fprintf(stderr,"printProcessResponse 1 190\n");
1403#endif
1404
1405  /**
1406   * Display the process output only when requested !
1407   */
1408  if(status==SERVICE_SUCCEEDED){
1409    nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
1410    maps* mcursor=outputs;
1411    elements* scursor=serv->outputs;
1412    map* testResponse=getMap(request,"RawDataOutput");
1413    if(testResponse==NULL)
1414      testResponse=getMap(request,"ResponseDocument");
1415    while(mcursor!=NULL){
1416      map* tmp0=getMap(mcursor->content,"inRequest");
1417      scursor=getElements(serv->outputs,mcursor->name);
1418      if(scursor!=NULL){
1419        if(testResponse==NULL || tmp0==NULL)
1420          printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1421        else
1422          if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0)
1423            printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1424      }else
1425        /**
1426         * In case there was no definition found in the ZCFG file but
1427         * present in the service code
1428         */
1429        printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1430      mcursor=mcursor->next;
1431    }
1432    xmlAddChild(n,nc);
1433  }
1434
1435#ifdef DEBUG
1436  fprintf(stderr,"printProcessResponse 1 202\n");
1437#endif
1438  nr=soapEnvelope(m,n);
1439  xmlDocSetRootElement(doc, nr);
1440
1441  if(hasStoredExecuteResponse==true){
1442    /* We need to write the ExecuteResponse Document somewhere */
1443    FILE* output=fopen(stored_path,"w");
1444    if(output==NULL){
1445      /* If the file cannot be created return an ExceptionReport */
1446      char tmpMsg[1024];
1447      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the ExecuteResponse."),stored_path);
1448      map * errormap = createMap("text",tmpMsg);
1449      addToMap(errormap,"code", "InternalError");
1450      printExceptionReportResponse(m,errormap);
1451      freeMap(&errormap);
1452      free(errormap);
1453      xmlCleanupParser();
1454      zooXmlCleanupNs();
1455      return;
1456    }
1457    xmlChar *xmlbuff;
1458    int buffersize;
1459    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
1460    fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
1461    xmlFree(xmlbuff);
1462    fclose(output);
1463  }
1464  printDocument(m,doc,pid);
1465
1466  xmlCleanupParser();
1467  zooXmlCleanupNs();
1468}
1469
1470
1471void printDocument(maps* m, xmlDocPtr doc,int pid){
1472  char *encoding=getEncoding(m);
1473  if(pid==getpid()){
1474    printHeaders(m);
1475    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1476  }
1477  fflush(stdout);
1478  xmlChar *xmlbuff;
1479  int buffersize;
1480  /*
1481   * Dump the document to a buffer and print it on stdout
1482   * for demonstration purposes.
1483   */
1484  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1485  printf("%s",xmlbuff);
1486  fflush(stdout);
1487  /*
1488   * Free associated memory.
1489   */
1490  xmlFree(xmlbuff);
1491  xmlFreeDoc(doc);
1492  xmlCleanupParser();
1493  zooXmlCleanupNs();
1494}
1495
1496void printOutputDefinitions1(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
1497  xmlNodePtr nc1;
1498  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1499  map *tmp=NULL; 
1500  if(e!=NULL && e->defaults!=NULL)
1501    tmp=e->defaults->content;
1502  else{
1503    /*
1504    dumpElements(e);
1505    */
1506    return;
1507  }
1508  while(tmp!=NULL){
1509    if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
1510       || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
1511       || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
1512       || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
1513    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1514    tmp=tmp->next;
1515  }
1516  tmp=getMap(e->defaults->content,"asReference");
1517  if(tmp==NULL)
1518    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1519
1520  tmp=e->content;
1521
1522  printDescription(nc1,ns_ows,m->name,e->content);
1523
1524  xmlAddChild(nc,nc1);
1525
1526}
1527
1528void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,map* m,const char* type){
1529  xmlNodePtr nc1,nc2,nc3;
1530  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1531  map *tmp=NULL; 
1532  if(e!=NULL && e->defaults!=NULL)
1533    tmp=e->defaults->content;
1534  else{
1535    /*
1536    dumpElements(e);
1537    */
1538    return;
1539  }
1540  while(tmp!=NULL){
1541    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1542    tmp=tmp->next;
1543  }
1544  tmp=getMap(e->defaults->content,"asReference");
1545  if(tmp==NULL)
1546    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1547
1548  tmp=e->content;
1549
1550  printDescription(nc1,ns_ows,m->name,e->content);
1551
1552  xmlAddChild(nc,nc1);
1553
1554}
1555
1556void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type){
1557  xmlNodePtr nc1,nc2,nc3;
1558  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1559  map *tmp=NULL;
1560  if(e!=NULL)
1561    tmp=e->content;
1562  else
1563    tmp=m->content;
1564#ifdef DEBUG
1565  dumpMap(tmp);
1566  dumpElements(e);
1567#endif
1568  nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
1569  if(e!=NULL)
1570    nc3=xmlNewText(BAD_CAST e->name);
1571  else
1572    nc3=xmlNewText(BAD_CAST m->name);
1573  xmlAddChild(nc2,nc3);
1574  xmlAddChild(nc1,nc2);
1575  xmlAddChild(nc,nc1);
1576  // Extract Title required to be first element in the ZCFG file !
1577  bool isTitle=TRUE;
1578  if(e!=NULL)
1579    tmp=getMap(e->content,"Title");
1580  else
1581    tmp=getMap(m->content,"Title");
1582 
1583  if(tmp!=NULL){
1584    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1585    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1586    xmlAddChild(nc2,nc3); 
1587    xmlAddChild(nc1,nc2);
1588  }
1589
1590  if(e!=NULL)
1591    tmp=getMap(e->content,"Abstract");
1592  else
1593    tmp=getMap(m->content,"Abstract");
1594  if(tmp!=NULL){
1595    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1596    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1597    xmlAddChild(nc2,nc3); 
1598    xmlAddChild(nc1,nc2);
1599    xmlAddChild(nc,nc1);
1600  }
1601
1602  /**
1603   * IO type Reference or full Data ?
1604   */
1605#ifdef DEBUG
1606  fprintf(stderr,"FORMAT %s %s\n",e->format,e->format);
1607#endif
1608  map *tmpMap=getMap(m->content,"Reference");
1609  if(tmpMap==NULL){
1610    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
1611    if(e!=NULL){
1612      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
1613        nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
1614      else
1615        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
1616          nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
1617        else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
1618          nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
1619        else
1620          nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
1621    }
1622    else{
1623      map* tmpV=getMapFromMaps(m,"format","value");
1624      if(tmpV!=NULL)
1625        nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
1626      else
1627        nc3=xmlNewNode(ns_wps, BAD_CAST "LitteralData");
1628    } 
1629    tmp=m->content;
1630#ifdef USE_MS
1631    map* testMap=getMap(tmp,"requestedMimeType");
1632#endif
1633    while(tmp!=NULL){
1634      if(strcasecmp(tmp->name,"mimeType")==0 ||
1635         strcasecmp(tmp->name,"encoding")==0 ||
1636         strcasecmp(tmp->name,"schema")==0 ||
1637         strcasecmp(tmp->name,"datatype")==0 ||
1638         strcasecmp(tmp->name,"uom")==0)
1639#ifdef USE_MS
1640        if(testMap==NULL || (testMap!=NULL && strncasecmp(testMap->value,"text/xml",8)==0)){
1641#endif
1642        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1643#ifdef USE_MS
1644        }
1645      else
1646        if(strcasecmp(tmp->name,"mimeType")==0)
1647          if(testMap!=NULL)
1648            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1649          else 
1650            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1651#endif
1652      tmp=tmp->next;
1653      xmlAddChild(nc2,nc3);
1654    }
1655    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
1656      map* bb=getMap(m->content,"value");
1657      if(bb!=NULL){
1658        map* tmpRes=parseBoundingBox(bb->value);
1659        printBoundingBox(ns_ows,nc3,tmpRes);
1660        freeMap(&tmpRes);
1661        free(tmpRes);
1662      }
1663    }else{
1664      if(e!=NULL)
1665        tmp=getMap(e->defaults->content,"mimeType");
1666      else
1667        tmp=NULL;
1668#ifdef USE_MS
1669      /**
1670       * In case of OGC WebServices output use, as the data was requested
1671       * with asReference=false we have to download the resulting OWS request
1672       * stored in the Reference map value.
1673       */
1674      map* testMap=getMap(m->content,"requestedMimeType");
1675      if(testMap!=NULL){
1676        HINTERNET hInternet;
1677        hInternet=InternetOpen(
1678#ifndef WIN32
1679                               (LPCTSTR)
1680#endif
1681                               "ZooWPSClient\0",
1682                               INTERNET_OPEN_TYPE_PRECONFIG,
1683                               NULL,NULL, 0);
1684        testMap=getMap(m->content,"Reference");
1685        loadRemoteFile(m,m->content,hInternet,testMap->value);
1686        InternetCloseHandle(hInternet);
1687      }
1688#endif
1689      map* tmp1=getMap(m->content,"encoding");
1690      map* tmp2=getMap(m->content,"mimeType");
1691      map* tmp3=getMap(m->content,"value");
1692      int hasValue=1;
1693      if(tmp3==NULL){
1694        tmp3=createMap("value","");
1695        hasValue=-1;
1696      }
1697      if((tmp1!=NULL && strncmp(tmp1->value,"base64",6)==0)
1698         || (tmp2!=NULL && (strncmp(tmp2->value,"image/",6)==0 ||
1699                            (strncmp(tmp2->value,"application/",12)==0) &&
1700                            strncmp(tmp2->value,"application/json",16)!=0&&
1701                            strncmp(tmp2->value,"application/x-javascript",24)!=0&&
1702                            strncmp(tmp2->value,"application/vnd.google-earth.kml",32)!=0)
1703             )) {
1704        map* rs=getMap(m->content,"size");
1705        bool isSized=true;
1706        if(rs==NULL){
1707          char tmp1[1024];
1708          sprintf(tmp1,"%d",strlen(tmp3->value));
1709          rs=createMap("size",tmp1);
1710          isSized=false;
1711        }
1712
1713        xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));
1714        if(!isSized){
1715          freeMap(&rs);
1716          free(rs);
1717        }
1718      }
1719      else if(tmp2!=NULL){
1720        if(strncmp(tmp2->value,"text/js",7)==0 ||
1721           strncmp(tmp2->value,"application/json",16)==0)
1722          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
1723        else{
1724          if(strncmp(tmp2->value,"text/xml",8)==0 ||
1725             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)==0){
1726            xmlDocPtr doc =
1727              xmlParseMemory(tmp3->value,strlen(tmp3->value));
1728            xmlNodePtr ir = xmlDocGetRootElement(doc);
1729            xmlAddChild(nc3,ir);
1730          }
1731          else
1732            xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1733        }
1734        xmlAddChild(nc2,nc3);
1735      }
1736      else{
1737        xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1738      }
1739      if(hasValue<0){
1740        freeMap(&tmp3);
1741        free(tmp3);
1742      }
1743    }
1744  }
1745  else{
1746    tmpMap=getMap(m->content,"Reference");
1747    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
1748    if(strcasecmp(type,"Output")==0)
1749      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
1750    else
1751      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
1752    tmp=m->content;
1753#ifdef USE_MS
1754    map* testMap=getMap(tmp,"requestedMimeType");
1755#endif
1756    while(tmp!=NULL){
1757      if(strcasecmp(tmp->name,"mimeType")==0 ||
1758         strcasecmp(tmp->name,"encoding")==0 ||
1759         strcasecmp(tmp->name,"schema")==0 ||
1760         strcasecmp(tmp->name,"datatype")==0 ||
1761         strcasecmp(tmp->name,"uom")==0)
1762#ifdef USE_MS
1763        if(testMap!=NULL  && strncasecmp(testMap->value,"text/xml",8)!=0){
1764          if(strcasecmp(tmp->name,"mimeType")==0)
1765            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1766        }
1767        else
1768#endif
1769        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1770      tmp=tmp->next;
1771      xmlAddChild(nc2,nc3);
1772    }
1773  }
1774  xmlAddChild(nc1,nc2);
1775  xmlAddChild(nc,nc1);
1776
1777}
1778
1779void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
1780  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
1781  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
1782  xmlAddChild(root,nc2);
1783  map* tmp=amap;
1784  char *tmp2[2];
1785  tmp2[0]="Title";
1786  tmp2[1]="Abstract";
1787  int j=0;
1788  for(j=0;j<2;j++){
1789    map* tmp1=getMap(tmp,tmp2[j]);
1790    if(tmp1!=NULL){
1791      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
1792      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
1793      xmlAddChild(root,nc2);
1794    }
1795  }
1796}
1797
1798char* getEncoding(maps* m){
1799  if(m!=NULL){
1800    map* tmp=getMap(m->content,"encoding");
1801    if(tmp!=NULL){
1802      return tmp->value;
1803    }
1804    else
1805      return "UTF-8";
1806  }
1807  else
1808    return "UTF-8"; 
1809}
1810
1811char* getVersion(maps* m){
1812  if(m!=NULL){
1813    map* tmp=getMap(m->content,"version");
1814    if(tmp!=NULL){
1815      return tmp->value;
1816    }
1817    else
1818      return "1.0.0";
1819  }
1820  else
1821    return "1.0.0";
1822}
1823
1824void printExceptionReportResponse(maps* m,map* s){
1825  int buffersize;
1826  xmlDocPtr doc;
1827  xmlChar *xmlbuff;
1828  xmlNodePtr n;
1829
1830  doc = xmlNewDoc(BAD_CAST "1.0");
1831  maps* tmpMap=getMaps(m,"main");
1832  char *encoding=getEncoding(tmpMap);
1833  char *exceptionCode;
1834 
1835  map* tmp=getMap(s,"code");
1836  if(tmp!=NULL){
1837    if(strcmp(tmp->value,"OperationNotSupported")==0)
1838      exceptionCode="501 Not Implemented";
1839    else
1840      if(strcmp(tmp->value,"MissingParameterValue")==0 ||
1841         strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
1842         strcmp(tmp->value,"OptionNotSupported")==0 ||
1843         strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
1844         strcmp(tmp->value,"InvalidParameterValue")==0)
1845        exceptionCode="400 Bad request";
1846      else
1847        if(strcmp(tmp->value,"NoApplicableCode")==0)
1848          exceptionCode="501 Internal Server Error";
1849        else
1850          exceptionCode="501 Internal Server Error";
1851  }
1852  else
1853    exceptionCode="501 Internal Server Error";
1854
1855  if(m!=NULL){
1856    map *tmpSid=getMapFromMaps(m,"lenv","sid");
1857    if(tmpSid!=NULL){
1858      if( getpid()==atoi(tmpSid->value) ){
1859        printHeaders(m);
1860        printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
1861      }
1862    }
1863    else{
1864      printHeaders(m);
1865      printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
1866    }
1867  }else{
1868    printf("Content-Type: text/xml; charset=%s\r\nStatus: %s\r\n\r\n",encoding,exceptionCode);
1869  }
1870  n=createExceptionReportNode(m,s,1);
1871  xmlDocSetRootElement(doc, n);
1872  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1873  printf("%s",xmlbuff);
1874  fflush(stdout);
1875  xmlFreeDoc(doc);
1876  xmlFree(xmlbuff);
1877  xmlCleanupParser();
1878  zooXmlCleanupNs();
1879}
1880
1881xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
1882 
1883  int buffersize;
1884  xmlChar *xmlbuff;
1885  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
1886  xmlNodePtr n,nc,nc1,nc2;
1887
1888  maps* tmpMap=getMaps(m,"main");
1889
1890  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
1891  ns=usedNs[nsid];
1892  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
1893
1894  if(use_ns==1){
1895    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
1896    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1897    ns_xsi=usedNs[xsiId];
1898    int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1899    ns_xlink=usedNs[xlinkId];
1900    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");
1901  }
1902  addLangAttr(n,m);
1903  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
1904 
1905  nc = xmlNewNode(ns, BAD_CAST "Exception");
1906
1907  map* tmp=getMap(s,"code");
1908  if(tmp!=NULL)
1909    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
1910  else
1911    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
1912
1913  tmp=getMap(s,"locator");
1914  if(tmp!=NULL && strcasecmp(tmp->value,"NULL")!=0)
1915    xmlNewProp(nc,BAD_CAST "locator",BAD_CAST tmp->value);
1916
1917
1918  tmp=getMap(s,"text");
1919  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
1920  nc2=NULL;
1921  if(tmp!=NULL){
1922    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
1923  }
1924  else{
1925    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
1926  }
1927  xmlAddChild(nc,nc1);
1928  xmlAddChild(n,nc);
1929  return n;
1930}
1931
1932
1933void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
1934                    map* request_inputs1,int cpid,maps* m,int res){
1935#ifdef DEBUG
1936  dumpMaps(request_inputs);
1937  dumpMaps(request_outputs);
1938  fprintf(stderr,"printProcessResponse\n");
1939#endif
1940  map* toto=getMap(request_inputs1,"RawDataOutput");
1941  int asRaw=0;
1942  if(toto!=NULL)
1943    asRaw=1;
1944 
1945  maps* tmpSess=getMaps(m,"senv");
1946  if(tmpSess!=NULL){
1947    map *_tmp=getMapFromMaps(m,"lenv","cookie");
1948    char* sessId;
1949    if(_tmp!=NULL){
1950      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
1951      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
1952      char session_file_path[100];
1953      char *tmp1=strtok(_tmp->value,";");
1954      if(tmp1!=NULL)
1955        sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
1956      else
1957        sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
1958      sessId=strdup(session_file_path);
1959    }else{
1960      maps* t=getMaps(m,"senv");
1961      map*p=t->content;
1962      while(p!=NULL){
1963        if(strstr(p->name,"ID")!=NULL){
1964          sessId=strdup(p->value);
1965          break;
1966        }
1967        p=p->next;
1968      }
1969    }
1970    char session_file_path[1024];
1971    map *tmpPath=getMapFromMaps(m,"main","sessPath");
1972    if(tmpPath==NULL)
1973      tmpPath=getMapFromMaps(m,"main","tmpPath");
1974    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
1975    FILE* teste=fopen(session_file_path,"w");
1976    if(teste==NULL){
1977      char tmpMsg[1024];
1978      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the session maps."),session_file_path);
1979      map * errormap = createMap("text",tmpMsg);
1980      addToMap(errormap,"code", "InternalError");
1981     
1982      printExceptionReportResponse(m,errormap);
1983      freeMap(&errormap);
1984      free(errormap);
1985      return;
1986    }
1987    else{
1988      fclose(teste);
1989      dumpMapsToFile(tmpSess,session_file_path);
1990    }
1991  }
1992 
1993  if(res==SERVICE_FAILED){
1994    map * errormap;
1995    map *lenv;
1996    lenv=getMapFromMaps(m,"lenv","message");
1997    char *tmp0;
1998    if(lenv!=NULL){
1999      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));
2000      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
2001    }
2002    else{
2003      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
2004      sprintf(tmp0,_("Unable to run the Service. No more information was returned back by the Service."));
2005    }
2006    errormap = createMap("text",tmp0);
2007    free(tmp0);
2008    addToMap(errormap,"code", "InternalError");
2009    printExceptionReportResponse(m,errormap);
2010    freeMap(&errormap);
2011    free(errormap);
2012    return;
2013  }
2014
2015  if(asRaw==0){
2016#ifdef DEBUG
2017    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
2018    dumpMaps(request_outputs);
2019#endif
2020    maps* tmpI=request_outputs;
2021    while(tmpI!=NULL){
2022#ifdef USE_MS
2023      map* testMap=getMap(tmpI->content,"useMapserver");       
2024#endif
2025      toto=getMap(tmpI->content,"asReference");
2026#ifdef USE_MS
2027      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
2028#else
2029      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
2030#endif
2031        {
2032        elements* in=getElements(s->outputs,tmpI->name);
2033        char *format=NULL;
2034        if(in!=NULL){
2035          format=strdup(in->format);
2036        }else
2037          format=strdup("LiteralData");
2038        if(strcasecmp(format,"BoundingBoxData")==0){
2039          addToMap(tmpI->content,"extension","xml");
2040          addToMap(tmpI->content,"mimeType","text/xml");
2041          addToMap(tmpI->content,"encoding","UTF-8");
2042          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
2043        }
2044        map *ext=getMap(tmpI->content,"extension");
2045        map *tmp1=getMapFromMaps(m,"main","tmpPath");
2046        char *file_name,*file_path;
2047        bool hasExt=true;
2048        if(ext==NULL){
2049          // We can fallback to a default list of supported formats using
2050          // mimeType information if present here. Maybe we can add more formats
2051          // here.
2052          // If mimeType was not found, we then set txt as the default extension
2053          map* mtype=getMap(tmpI->content,"mimeType");
2054          if(mtype!=NULL){
2055            if(strcasecmp(mtype->value,"text/xml")==0)
2056              ext=createMap("extension","xml");
2057            else if(strcasecmp(mtype->value,"application/json")==0)
2058              ext=createMap("extension","js");
2059            else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
2060              ext=createMap("extension","kml");
2061            else if(strncmp(mtype->value,"image/",6)==0)
2062              ext=createMap("extension",strstr(mtype->value,"/")+1);
2063            else
2064              ext=createMap("extension","txt");
2065          }
2066          else
2067            ext=createMap("extension","txt");
2068          hasExt=false;
2069        }
2070        file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
2071        int cpid0=cpid+time(NULL);
2072        sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
2073        file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
2074        sprintf(file_path,"%s/%s",tmp1->value,file_name);
2075        FILE *ofile=fopen(file_path,"wb");
2076        if(ofile==NULL){
2077          char tmpMsg[1024];
2078          sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
2079          map * errormap = createMap("text",tmpMsg);
2080          addToMap(errormap,"code", "InternalError");
2081          printExceptionReportResponse(m,errormap);
2082          freeMap(&errormap);
2083          free(errormap);
2084          free(file_name);
2085          free(file_path);
2086          return;
2087        }
2088        free(file_path);
2089        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2090        map *tmp3=getMapFromMaps(m,"main","serverAddress");
2091        char *file_url;
2092        if(strncasecmp(tmp2->value,"http://",7)==0 ||
2093           strncasecmp(tmp2->value,"https://",8)==0){
2094          file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
2095          sprintf(file_url,"%s/%s",tmp2->value,file_name);
2096        }else{
2097          file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
2098          sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2099        }
2100        addToMap(tmpI->content,"Reference",file_url);
2101        if(!hasExt){
2102          freeMap(&ext);
2103          free(ext);
2104        }
2105        toto=getMap(tmpI->content,"value");
2106        if(strcasecmp(format,"BoundingBoxData")!=0){
2107          map* size=getMap(tmpI->content,"size");
2108          if(size!=NULL && toto!=NULL)
2109            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2110          else
2111            if(toto!=NULL && toto->value!=NULL)
2112              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2113        }else{
2114          printBoundingBoxDocument(m,tmpI,ofile);
2115        }
2116        free(format);
2117        fclose(ofile);
2118        free(file_name);
2119        free(file_url); 
2120      }
2121#ifdef USE_MS
2122      else{
2123        if(testMap!=NULL){
2124          setReferenceUrl(m,tmpI);
2125        }
2126      }
2127#endif
2128      tmpI=tmpI->next;
2129    }
2130    map *r_inputs=getMap(s->content,"serviceProvider");
2131#ifdef DEBUG
2132    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2133    dumpMaps(m);
2134#endif
2135    printProcessResponse(m,request_inputs1,cpid,
2136                         s,r_inputs->value,res,
2137                         request_inputs,
2138                         request_outputs);
2139    }
2140    else{
2141      /**
2142       * We get the requested output or fallback to the first one if the
2143       * requested one is not present in the resulting outputs maps.
2144       */
2145      maps* tmpI=NULL;
2146      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2147      if(tmpIV!=NULL){
2148        tmpI=getMaps(request_outputs,tmpIV->value);
2149      }
2150      if(tmpI==NULL)
2151        tmpI=request_outputs;
2152      elements* e=getElements(s->outputs,tmpI->name);
2153      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2154        printBoundingBoxDocument(m,tmpI,NULL);
2155      }else{
2156        toto=getMap(tmpI->content,"value");
2157        if(toto==NULL){
2158          char tmpMsg[1024];
2159          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2160          map * errormap = createMap("text",tmpMsg);
2161          addToMap(errormap,"code", "InvalidParameterValue");
2162          printExceptionReportResponse(m,errormap);
2163          freeMap(&errormap);
2164          free(errormap);
2165          return;
2166        }
2167        map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2168        if(fname!=NULL)
2169          printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2170        map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2171        if(rs!=NULL)
2172          printf("Content-Length: %s\r\n",rs->value);
2173        printHeaders(m);
2174        char mime[1024];
2175        map* mi=getMap(tmpI->content,"mimeType");
2176#ifdef DEBUG
2177        fprintf(stderr,"SERVICE OUTPUTS\n");
2178        dumpMaps(request_outputs);
2179        fprintf(stderr,"SERVICE OUTPUTS\n");
2180#endif
2181        map* en=getMap(tmpI->content,"encoding");
2182        if(mi!=NULL && en!=NULL)
2183          sprintf(mime,
2184                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2185                  mi->value,en->value);
2186        else
2187          if(mi!=NULL)
2188            sprintf(mime,
2189                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2190                    mi->value);
2191          else
2192            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2193        printf("%s",mime);
2194        if(rs!=NULL)
2195          fwrite(toto->value,1,atoi(rs->value),stdout);
2196        else
2197          fwrite(toto->value,1,strlen(toto->value),stdout);
2198#ifdef DEBUG
2199        dumpMap(toto);
2200#endif
2201      }
2202    }
2203}
2204
2205char *base64(const char *input, int length)
2206{
2207  BIO *bmem, *b64;
2208  BUF_MEM *bptr;
2209
2210  b64 = BIO_new(BIO_f_base64());
2211  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2212  bmem = BIO_new(BIO_s_mem());
2213  b64 = BIO_push(b64, bmem);
2214  BIO_write(b64, input, length);
2215  BIO_flush(b64);
2216  BIO_get_mem_ptr(b64, &bptr);
2217
2218  char *buff = (char *)malloc((bptr->length)*sizeof(char));
2219  memcpy(buff, bptr->data, bptr->length-1);
2220  buff[bptr->length-1] = 0;
2221
2222  BIO_free_all(b64);
2223
2224  return buff;
2225}
2226
2227char *base64d(const char *input, int length,int* red)
2228{
2229  BIO *b64, *bmem;
2230
2231  char *buffer = (char *)malloc(length);
2232  if(buffer){
2233    memset(buffer, 0, length);
2234    b64 = BIO_new(BIO_f_base64());
2235    if(b64){
2236      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2237      bmem = BIO_push(b64, bmem);
2238      *red=BIO_read(bmem, buffer, length);
2239      buffer[length-1]=0;
2240      BIO_free_all(bmem);
2241    }
2242  }
2243  return buffer;
2244}
2245
2246void ensureDecodedBase64(maps **in){
2247  maps* cursor=*in;
2248  while(cursor!=NULL){
2249    map *tmp=getMap(cursor->content,"encoding");
2250    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2251      tmp=getMap(cursor->content,"value");
2252      addToMap(cursor->content,"base64_value",tmp->value);
2253      int size=0;
2254      char *s=strdup(tmp->value);
2255      free(tmp->value);
2256      tmp->value=base64d(s,strlen(s),&size);
2257      free(s);
2258      char sizes[1024];
2259      sprintf(sizes,"%d",size);
2260      addToMap(cursor->content,"size",sizes);
2261    }
2262    cursor=cursor->next;
2263  }
2264}
2265
2266char* addDefaultValues(maps** out,elements* in,maps* m,int type){
2267  elements* tmpInputs=in;
2268  maps* out1=*out;
2269  if(type==1){
2270    while(out1!=NULL){
2271      if(getElements(in,out1->name)==NULL)
2272        return out1->name;
2273      out1=out1->next;
2274    }
2275    out1=*out;
2276  }
2277  while(tmpInputs!=NULL){
2278    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2279    if(tmpMaps==NULL){
2280      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2281      tmpMaps2->name=strdup(tmpInputs->name);
2282      tmpMaps2->content=NULL;
2283      tmpMaps2->next=NULL;
2284     
2285      if(type==0){
2286        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2287        if(tmpMapMinO!=NULL)
2288          if(atoi(tmpMapMinO->value)>=1){
2289            freeMaps(&tmpMaps2);
2290            free(tmpMaps2);
2291            return tmpInputs->name;
2292          }
2293          else{
2294            if(tmpMaps2->content==NULL)
2295              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2296            else
2297              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2298          }
2299        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2300        if(tmpMaxO!=NULL)
2301          if(tmpMaps2->content==NULL)
2302            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2303          else
2304            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2305      }
2306
2307      iotype* tmpIoType=tmpInputs->defaults;
2308      if(tmpIoType!=NULL){
2309        map* tmpm=tmpIoType->content;
2310        while(tmpm!=NULL){
2311          if(tmpMaps2->content==NULL)
2312            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2313          else
2314            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2315          tmpm=tmpm->next;
2316        }
2317      }
2318      addToMap(tmpMaps2->content,"inRequest","false");
2319      if(type==0){
2320        map *tmpMap=getMap(tmpMaps2->content,"value");
2321        if(tmpMap==NULL)
2322          addToMap(tmpMaps2->content,"value","NULL");
2323      }
2324      if(out1==NULL){
2325        *out=dupMaps(&tmpMaps2);
2326        out1=*out;
2327      }
2328      else
2329        addMapsToMaps(&out1,tmpMaps2);
2330      freeMap(&tmpMaps2->content);
2331      free(tmpMaps2->content);
2332      tmpMaps2->content=NULL;
2333      freeMaps(&tmpMaps2);
2334      free(tmpMaps2);
2335      tmpMaps2=NULL;
2336    }
2337    else{
2338      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2339                                             tmpMaps->content);
2340      if(type==0) {
2341        /**
2342         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2343         * content map.
2344         */
2345        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2346        if(tmpMap1!=NULL){
2347          if(tmpMaps->content==NULL)
2348            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2349          else
2350            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2351        }
2352        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2353        if(tmpMaxO!=NULL){
2354          if(tmpMaps->content==NULL)
2355            tmpMaps->content=createMap("maxOccurs",tmpMap1->value);
2356          else
2357            addToMap(tmpMaps->content,"maxOccurs",tmpMap1->value);
2358        }
2359        /**
2360         * Parsing BoundingBoxData, fill the following map and then add it to
2361         * the content map of the Input maps:
2362         * lowerCorner, upperCorner, srs and dimensions
2363         * cf. parseBoundingBox
2364         */
2365        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2366          maps* tmpI=getMaps(*out,tmpInputs->name);
2367          if(tmpI!=NULL){
2368            map* tmpV=getMap(tmpI->content,"value");
2369            if(tmpV!=NULL){
2370              char *tmpVS=strdup(tmpV->value);
2371              map* tmp=parseBoundingBox(tmpVS);
2372              free(tmpVS);
2373              map* tmpC=tmp;
2374              while(tmpC!=NULL){
2375                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2376                tmpC=tmpC->next;
2377              }
2378              freeMap(&tmp);
2379              free(tmp);
2380            }
2381          }
2382        }
2383      }
2384
2385      if(tmpIoType!=NULL){
2386        map* tmpContent=tmpIoType->content;
2387        map* cval=NULL;
2388        int hasPassed=-1;
2389        while(tmpContent!=NULL){
2390          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2391#ifdef DEBUG
2392            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2393#endif
2394            if(tmpMaps->content==NULL)
2395              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2396            else
2397              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2398           
2399            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
2400              map* length=getMap(tmpMaps->content,"length");
2401              int i;
2402              char *tcn=strdup(tmpContent->name);
2403              for(i=1;i<atoi(length->value);i++){
2404#ifdef DEBUG
2405                dumpMap(tmpMaps->content);
2406                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
2407#endif
2408                int len=strlen((char*) tcn);
2409                char *tmp1=(char *)malloc((len+10)*sizeof(char));
2410                sprintf(tmp1,"%s_%d",tcn,i);
2411#ifdef DEBUG
2412                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
2413#endif
2414                addToMap(tmpMaps->content,tmp1,tmpContent->value);
2415                free(tmp1);
2416                hasPassed=1;
2417              }
2418              free(tcn);
2419            }
2420          }
2421          tmpContent=tmpContent->next;
2422        }
2423#ifdef USE_MS
2424        /**
2425         * check for useMapServer presence
2426         */
2427        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
2428        if(tmpCheck!=NULL){
2429          // Get the default value
2430          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
2431          tmpCheck=getMap(tmpMaps->content,"mimeType");
2432          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
2433          map* cursor=tmpIoType->content;
2434          while(cursor!=NULL){
2435            addToMap(tmpMaps->content,cursor->name,cursor->value);
2436            cursor=cursor->next;
2437          }
2438         
2439          cursor=tmpInputs->content;
2440          while(cursor!=NULL){
2441            if(strcasecmp(cursor->name,"Title")==0 ||
2442               strcasecmp(cursor->name,"Abstract")==0)
2443              addToMap(tmpMaps->content,cursor->name,cursor->value);
2444           cursor=cursor->next;
2445          }
2446        }
2447#endif
2448      }
2449      if(tmpMaps->content==NULL)
2450        tmpMaps->content=createMap("inRequest","true");
2451      else
2452        addToMap(tmpMaps->content,"inRequest","true");
2453
2454    }
2455    tmpInputs=tmpInputs->next;
2456  }
2457  return "";
2458}
2459
2460/**
2461 * parseBoundingBox : parse a BoundingBox string
2462 *
2463 * OGC 06-121r3 : 10.2 Bounding box
2464 *
2465 * value is provided as : lowerCorner,upperCorner,crs,dimension
2466 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2467 *
2468 * Need to create a map to store boundingbox informations :
2469 *  - lowerCorner : double,double (minimum within this bounding box)
2470 *  - upperCorner : double,double (maximum within this bounding box)
2471 *  - crs : URI (Reference to definition of the CRS)
2472 *  - dimensions : int
2473 *
2474 * Note : support only 2D bounding box.
2475 */
2476map* parseBoundingBox(const char* value){
2477  map *res=NULL;
2478  if(value!=NULL){
2479    char *cv,*cvp;
2480    cv=strtok_r((char*) value,",",&cvp);
2481    int cnt=0;
2482    int icnt=0;
2483    char *currentValue=NULL;
2484    while(cv){
2485      if(cnt<2)
2486        if(currentValue!=NULL){
2487          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
2488          sprintf(finalValue,"%s%s",currentValue,cv);
2489          switch(cnt){
2490          case 0:
2491            res=createMap("lowerCorner",finalValue);
2492            break;
2493          case 1:
2494            addToMap(res,"upperCorner",finalValue);
2495            icnt=-1;
2496            break;
2497          }
2498          cnt++;
2499          free(currentValue);
2500          currentValue=NULL;
2501          free(finalValue);
2502        }
2503        else{
2504          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
2505          sprintf(currentValue,"%s ",cv);
2506        }
2507      else
2508        if(cnt==2){
2509          addToMap(res,"crs",cv);
2510          cnt++;
2511        }
2512        else
2513          addToMap(res,"dimensions",cv);
2514      icnt++;
2515      cv=strtok_r(NULL,",",&cvp);
2516    }
2517  }
2518  return res;
2519}
2520
2521/**
2522 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2523 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2524 * Lower/UpperCorner nodes to a pre-existing XML node.
2525 */
2526void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2527
2528  xmlNodePtr bb,lw,uc;
2529
2530  map* tmp=getMap(boundingbox,"value");
2531
2532  tmp=getMap(boundingbox,"lowerCorner");
2533  if(tmp!=NULL){
2534    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2535    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2536  }
2537
2538  tmp=getMap(boundingbox,"upperCorner");
2539  if(tmp!=NULL){
2540    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2541    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2542  }
2543
2544  tmp=getMap(boundingbox,"crs");
2545  if(tmp!=NULL)
2546    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2547
2548  tmp=getMap(boundingbox,"dimensions");
2549  if(tmp!=NULL)
2550    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2551
2552  xmlAddChild(n,lw);
2553  xmlAddChild(n,uc);
2554
2555}
2556
2557void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2558  if(file==NULL)
2559    rewind(stdout);
2560  xmlNodePtr n;
2561  xmlDocPtr doc;
2562  xmlNsPtr ns_ows,ns_xsi;
2563  xmlChar *xmlbuff;
2564  int buffersize;
2565  char *encoding=getEncoding(m);
2566  map *tmp;
2567  if(file==NULL){
2568    int pid=0;
2569    tmp=getMapFromMaps(m,"lenv","sid");
2570    if(tmp!=NULL)
2571      pid=atoi(tmp->value);
2572    if(pid==getpid()){
2573      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2574    }
2575    fflush(stdout);
2576  }
2577
2578  doc = xmlNewDoc(BAD_CAST "1.0");
2579  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2580  ns_ows=usedNs[owsId];
2581  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2582  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
2583  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2584  ns_xsi=usedNs[xsiId];
2585  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");
2586  map *tmp1=getMap(boundingbox->content,"value");
2587  tmp=parseBoundingBox(tmp1->value);
2588  printBoundingBox(ns_ows,n,tmp);
2589  xmlDocSetRootElement(doc, n);
2590
2591  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2592  if(file==NULL)
2593    printf("%s",xmlbuff);
2594  else{
2595    fprintf(file,"%s",xmlbuff);
2596  }
2597
2598  if(tmp!=NULL){
2599    freeMap(&tmp);
2600    free(tmp);
2601  }
2602  xmlFree(xmlbuff);
2603  xmlFreeDoc(doc);
2604  xmlCleanupParser();
2605  zooXmlCleanupNs();
2606 
2607}
2608
2609
2610char* getMd5(char* url){
2611  EVP_MD_CTX md5ctx;
2612  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
2613  unsigned char result[EVP_MAX_MD_SIZE];
2614  unsigned int len;
2615  EVP_DigestInit(&md5ctx, EVP_md5());
2616  EVP_DigestUpdate(&md5ctx, url, strlen(url));
2617  EVP_DigestFinal_ex(&md5ctx,result,&len);
2618  EVP_MD_CTX_cleanup(&md5ctx);
2619  int i;
2620  for(i = 0; i < len; i++){
2621    if(i>0){
2622      char *tmp=strdup(fresult);
2623      sprintf(fresult,"%s%02x", tmp,result[i]);
2624      free(tmp);
2625    }
2626    else
2627      sprintf(fresult,"%02x",result[i]);
2628  }
2629  return fresult;
2630}
2631
2632/**
2633 * Cache a file for a given request
2634 */
2635void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
2636  map* tmp=getMapFromMaps(conf,"main","cacheDir");
2637  if(tmp!=NULL){
2638    char* md5str=getMd5(request);
2639    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
2640    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
2641#ifdef DEBUG
2642    fprintf(stderr,"Cache list : %s\n",fname);
2643    fflush(stderr);
2644#endif
2645    FILE* fo=fopen(fname,"w+");
2646    fwrite(content,sizeof(char),length,fo);
2647    fclose(fo);
2648
2649    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
2650    fo=fopen(fname,"w+");
2651#ifdef DEBUG
2652    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
2653#endif
2654    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
2655    fclose(fo);
2656
2657    free(md5str);
2658    free(fname);
2659  }
2660}
2661
2662char* isInCache(maps* conf,char* request){
2663  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
2664  if(tmpM!=NULL){
2665    char* md5str=getMd5(request);
2666#ifdef DEBUG
2667    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
2668#endif
2669    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
2670    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
2671    struct stat f_status;
2672    int s=stat(fname, &f_status);
2673    if(s==0 && f_status.st_size>0){
2674      free(md5str);
2675      return fname;
2676    }
2677    free(md5str);
2678    free(fname);
2679  }
2680  return NULL;
2681}
2682
2683/**
2684 * loadRemoteFile:
2685 * Try to load file from cache or download a remote file if not in cache
2686 */
2687int loadRemoteFile(maps* m,map* content,HINTERNET hInternet,char *url){
2688  HINTERNET res;
2689  char* fcontent;
2690  char* cached=isInCache(m,url);
2691  char *mimeType=NULL;
2692  int fsize;
2693  int hasF=-1;
2694  if(cached!=NULL){
2695    struct stat f_status;
2696    int s=stat(cached, &f_status);
2697    if(s==0){
2698      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2699      FILE* f=fopen(cached,"rb");
2700      int len=fread(fcontent,f_status.st_size,1,f);
2701      fsize=f_status.st_size;
2702      fcontent[fsize]=0;
2703      fclose(f);
2704    }
2705    cached[strlen(cached)-1]='m';
2706    s=stat(cached, &f_status);
2707    if(s==0){
2708      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2709      FILE* f=fopen(cached,"rb");
2710      int len=fread(mimeType,f_status.st_size,1,f);
2711      mimeType[f_status.st_size]=0;
2712      fclose(f);
2713    }
2714  }else{
2715    res=InternetOpenUrl(hInternet,url,NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
2716    fcontent=(char*)malloc((res.nDataLen+1)*sizeof(char));
2717    if(fcontent == NULL){
2718      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2719    }
2720    size_t dwRead;
2721    InternetReadFile(res, (LPVOID)fcontent, res.nDataLen, &dwRead);
2722    fcontent[res.nDataLen]=0;
2723    fsize=res.nDataLen;
2724    mimeType=(char*)res.mimeType;
2725  }
2726  if(fsize==0){
2727    return errorException(m, _("Unable to download the file."), "InternalError",NULL);
2728  }
2729
2730  if(mimeType!=NULL){
2731    addToMap(content,"fmimeType",mimeType);
2732  }
2733
2734  map* tmpMap=getMapOrFill(content,"value","");
2735   
2736  free(tmpMap->value);
2737  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
2738  if(tmpMap->value==NULL)
2739    fprintf(stderr,"Unable to allocate memory!\n");
2740  //snprintf(tmpMap->value,(fsize+1)*sizeof(char),fcontent);
2741  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
2742 
2743  char ltmp1[256];
2744  sprintf(ltmp1,"%d",fsize);
2745  addToMap(content,"size",ltmp1);
2746  if(cached==NULL)
2747    addToCache(m,url,fcontent,mimeType,fsize);
2748  else{
2749    free(fcontent);
2750    free(mimeType);
2751    free(cached);
2752  }
2753  return 0;
2754}
2755
2756int errorException(maps *m, const char *message, const char *errorcode, const char *locator) 
2757{
2758  map* errormap = createMap("text", message);
2759  addToMap(errormap,"code", errorcode);
2760  if(locator!=NULL)
2761    addToMap(errormap,"locator", locator);
2762  else
2763    addToMap(errormap,"locator", "NULL");
2764  printExceptionReportResponse(m,errormap);
2765  freeMap(&errormap);
2766  free(errormap);
2767  return -1;
2768}
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