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

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

Fix issue #92, thanks Knut for reporting this bug.

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