source: trunk/zoo-kernel/service_internal.c @ 283

Last change on this file since 283 was 283, checked in by djay, 13 years ago

Fix XML validation when only Default node is provided in the ZCFG file.

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