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

Last change on this file since 365 was 365, checked in by djay, 12 years ago

Fix issue to compile on Linux platforms after the previous update, fix issue when @ is present in the value of a DataInputs?.

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