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

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

Update to make ZOO-Kernel able to compile and run from Windows Platforms. A special thanks to Espen Messel, Knut Landmark and Benrd Härtwig for providing many patches that I can successfully apply on the SVN source tree and to Farkas for continuing requesting for ZOO-Kernel to run on Windows platforms privately and through the ZOO-Discuss mailing list.

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