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

Last change on this file since 471 was 471, checked in by djay, 9 years ago

Remove leaks from DescribeProcess? and JavaScript? support. Fix wrong ulinet update on previous commit. Use the new updateStatus/setOutputValue functions as described in #88 from longProcess. Add default value for QREncode service in ZCFG. Fix name of profile service in the ZCFG file.

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