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

Last change on this file since 472 was 471, checked in by djay, 10 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