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

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

Fix some issue in background execution on windows platform (basic array and xlink). Fix issue #89.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 75.1 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[7];
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
894  xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7;
895  elements* e=elem;
896  map* tmp1=NULL;
897  while(e!=NULL){
898    int default1=0;
899    int isAnyValue=1;
900    nc2 = xmlNewNode(NULL, BAD_CAST type);
901    tmp1=getMap(e->content,"minOccurs");
902    if(tmp1){
903      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
904    }
905    tmp1=getMap(e->content,"maxOccurs");
906    if(tmp1){
907      xmlNewProp(nc2,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
908    }
909
910    printDescription(nc2,ns_ows,e->name,e->content);
911
912    if(strncmp(type,"Output",6)==0){
913      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
914        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralOutput");
915      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
916        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexOutput");
917      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
918        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
919      else
920        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
921    }else{
922      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0){
923        nc3 = xmlNewNode(NULL, BAD_CAST "LiteralData");
924      }
925      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
926        nc3 = xmlNewNode(NULL, BAD_CAST "ComplexData");
927      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
928        nc3 = xmlNewNode(NULL, BAD_CAST "BoundingBoxData");
929      else
930        nc3 = xmlNewNode(NULL, BAD_CAST e->format);
931    }
932    iotype* _tmp=e->defaults;
933    int datatype=0;
934    bool hasDefault=false;
935    bool hasUOM=false;
936    if(_tmp!=NULL){
937      if(strcmp(e->format,"LiteralOutput")==0 ||
938         strcmp(e->format,"LiteralData")==0){
939        datatype=1;
940        nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
941        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
942      }
943      else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
944              strcmp(e->format,"BoundingBoxData")==0){
945        datatype=2;
946        //nc4 = xmlNewNode(NULL, BAD_CAST "BoundingBoxOutput");
947        nc5 = xmlNewNode(NULL, BAD_CAST "Default");
948      }
949      else{
950        nc4 = xmlNewNode(NULL, BAD_CAST "Default");
951        nc5 = xmlNewNode(NULL, BAD_CAST "Format");
952      }
953     
954      tmp1=_tmp->content;
955      int avcnt=0;
956      int dcnt=0;
957      int oI=0;
958      for(oI=0;oI<7;oI++)
959        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
960          //while(tmp1!=NULL){
961#ifdef DEBUG
962          printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
963#endif
964          if(strncasecmp(tmp1->name,"DataType",8)==0){
965            nc6 = xmlNewNode(ns_ows, BAD_CAST "DataType");
966            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
967            char tmp[1024];
968            sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
969            xmlNewNsProp(nc6,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
970            xmlAddChild(nc3,nc6);
971            tmp1=tmp1->next;
972            datatype=1;
973            continue;
974          }
975          if(strcmp(tmp1->name,"asReference")!=0 &&
976             strncasecmp(tmp1->name,"DataType",8)!=0 &&
977             strcasecmp(tmp1->name,"extension")!=0 &&
978             strcasecmp(tmp1->name,"value")!=0 &&
979             strncasecmp(tmp1->name,"AllowedValues",13)!=0){
980            if(datatype!=1){
981              char *tmp2=zCapitalize1(tmp1->name);
982              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
983              free(tmp2);
984            }
985            else{
986              char *tmp2=zCapitalize(tmp1->name);
987              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
988              free(tmp2);
989            }
990            xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
991            xmlAddChild(nc5,nc6);
992            hasUOM=true;
993          }else 
994            if(strncmp(type,"Input",5)==0){
995              if(strcmp(tmp1->name,"value")==0){
996                nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
997                xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
998                default1=1;
999              }
1000              if(strncasecmp(tmp1->name,"AllowedValues",13)==0){
1001                nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
1002                fprintf(stderr,"ALLOWED VALUE %s\n",tmp1->value);
1003                char *token,*saveptr1;
1004                token=strtok_r(tmp1->value,",",&saveptr1);
1005                while(token!=NULL){
1006                  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
1007                  char *tmps=strdup(token);
1008                  tmps[strlen(tmps)]=0;
1009                  xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
1010                  fprintf(stderr,"strgin : %s\n",tmps);
1011                  xmlAddChild(nc6,nc7);
1012                  token=strtok_r(NULL,",",&saveptr1);
1013                }
1014                xmlAddChild(nc3,nc6);
1015                isAnyValue=-1;
1016              }
1017              hasDefault=true;
1018            }
1019          tmp1=tmp1->next;
1020          if(datatype!=2){
1021            if(hasUOM==true){
1022              xmlAddChild(nc4,nc5);
1023              xmlAddChild(nc3,nc4);
1024            }
1025          }else{
1026            xmlAddChild(nc3,nc5);
1027          }
1028         
1029          if(strncmp(type,"Input",5)==0){
1030            if(datatype==1 && isAnyValue==1 && avcnt==0){
1031              xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1032              hasDefault=true;
1033              avcnt++;
1034            }
1035            if(datatype==1 && default1>0){
1036              xmlAddChild(nc3,nc7);
1037            }
1038          }
1039        }
1040    }
1041
1042    _tmp=e->supported;
1043    if(_tmp==NULL && (getMap(e->defaults->content,"uom")!=NULL || datatype!=1))
1044      _tmp=e->defaults;
1045
1046    int hasSupported=-1;
1047    while(_tmp!=NULL){
1048      if(hasSupported<0){
1049        if(datatype==0){
1050          nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
1051          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1052        }
1053        else
1054          nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
1055        hasSupported=0;
1056      }else
1057        if(datatype==0)
1058          nc5 = xmlNewNode(NULL, BAD_CAST "Format");
1059      tmp1=_tmp->content;
1060      int oI=0;
1061      for(oI=0;oI<6;oI++)
1062        if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
1063#ifdef DEBUG
1064          printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
1065#endif
1066          if(strcmp(tmp1->name,"asReference")!=0 && 
1067             strcmp(tmp1->name,"DataType")!=0 &&
1068             strcasecmp(tmp1->name,"extension")!=0){
1069            if(datatype!=1){
1070              char *tmp2=zCapitalize1(tmp1->name);
1071              nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1072              free(tmp2);
1073            }
1074            else{
1075              char *tmp2=zCapitalize(tmp1->name);
1076              nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
1077              free(tmp2);
1078            }
1079            if(datatype==2){
1080              char *tmpv,*tmps;
1081              tmps=strtok_r(tmp1->value,",",&tmpv);
1082              while(tmps){
1083                xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
1084                xmlAddChild(nc5,nc6);
1085                tmps=strtok_r(NULL,",",&tmpv);
1086                if(tmps){
1087                  char *tmp2=zCapitalize1(tmp1->name);
1088                  nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
1089                  free(tmp2);
1090                }
1091              }
1092            }
1093            else{
1094              xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
1095              xmlAddChild(nc5,nc6);
1096            }
1097          }
1098          tmp1=tmp1->next;
1099        }
1100      if(hasSupported<=0){
1101        if(datatype!=2){
1102          xmlAddChild(nc4,nc5);
1103          xmlAddChild(nc3,nc4);
1104        }else
1105          xmlAddChild(nc3,nc5);
1106        hasSupported=1;
1107      }
1108      else
1109        if(datatype!=2){
1110          xmlAddChild(nc4,nc5);
1111        }
1112        else
1113          xmlAddChild(nc3,nc5);
1114      _tmp=_tmp->next;
1115    }
1116    xmlAddChild(nc2,nc3);
1117   
1118    if(datatype!=2 && hasUOM==true){
1119      xmlAddChild(nc3,nc4);
1120      xmlAddChild(nc2,nc3);
1121    }else if(datatype!=2){
1122      if(hasDefault!=true && strncmp(type,"Input",5)==0)
1123        xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
1124    }
1125   
1126    xmlAddChild(nc1,nc2);
1127   
1128    e=e->next;
1129  }
1130}
1131
1132void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
1133  xmlNsPtr ns,ns1,ns_ows,ns_xlink,ns_xsi;
1134  xmlNodePtr nr,n,nc,nc1,nc2,nc3,pseudor;
1135  xmlDocPtr doc;
1136  xmlChar *xmlbuff;
1137  int buffersize;
1138  time_t time1; 
1139  time(&time1);
1140  nr=NULL;
1141  /**
1142   * Create the document and its temporary root.
1143   */
1144  doc = xmlNewDoc(BAD_CAST "1.0");
1145  int wpsId=zooXmlAddNs(NULL,"http://www.opengis.net/wps/1.0.0","wps");
1146  ns=usedNs[wpsId];
1147
1148  n = xmlNewNode(ns, BAD_CAST "ExecuteResponse");
1149  xmlNewNs(n,BAD_CAST "http://www.opengis.net/wps/1.0.0",BAD_CAST "wps");
1150  int owsId=zooXmlAddNs(n,"http://www.opengis.net/ows/1.1","ows");
1151  ns_ows=usedNs[owsId];
1152  int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1153  ns_xlink=usedNs[xlinkId];
1154  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1155  ns_xsi=usedNs[xsiId];
1156 
1157  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");
1158 
1159  xmlNewProp(n,BAD_CAST "service",BAD_CAST "WPS");
1160  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.0.0");
1161  addLangAttr(n,m);
1162
1163  char tmp[256];
1164  char url[1024];
1165  char stored_path[1024];
1166  memset(tmp,0,256);
1167  memset(url,0,1024);
1168  memset(stored_path,0,1024);
1169  maps* tmp_maps=getMaps(m,"main");
1170  if(tmp_maps!=NULL){
1171    map* tmpm1=getMap(tmp_maps->content,"serverAddress");
1172    /**
1173     * Check if the ZOO Service GetStatus is available in the local directory.
1174     * If yes, then it uses a reference to an URL which the client can access
1175     * to get information on the status of a running Service (using the
1176     * percentCompleted attribute).
1177     * Else fallback to the initial method using the xml file to write in ...
1178     */
1179    char ntmp[1024];
1180#ifndef WIN32
1181    getcwd(ntmp,1024);
1182#else
1183    _getcwd(ntmp,1024);
1184#endif
1185    struct stat myFileInfo;
1186    int statRes;
1187    char file_path[1024];
1188    sprintf(file_path,"%s/GetStatus.zcfg",ntmp);
1189    statRes=stat(file_path,&myFileInfo);
1190    if(statRes==0){
1191      char currentSid[128];
1192      map* tmpm=getMap(tmp_maps->content,"rewriteUrl");
1193      map *tmp_lenv=NULL;
1194      tmp_lenv=getMapFromMaps(m,"lenv","sid");
1195      if(tmp_lenv==NULL)
1196        sprintf(currentSid,"%i",pid);
1197      else
1198        sprintf(currentSid,"%s",tmp_lenv->value);
1199      if(tmpm==NULL || strcasecmp(tmpm->value,"false")==0){
1200        sprintf(url,"%s?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1201      }else{
1202        if(strlen(tmpm->value)>0)
1203          if(strcasecmp(tmpm->value,"true")!=0)
1204            sprintf(url,"%s/%s/GetStatus/%s",tmpm1->value,tmpm->value,currentSid);
1205          else
1206            sprintf(url,"%s/GetStatus/%s",tmpm1->value,currentSid);
1207        else
1208          sprintf(url,"%s/?request=Execute&service=WPS&version=1.0.0&Identifier=GetStatus&DataInputs=sid=%s&RawDataOutput=Result",tmpm1->value,currentSid);
1209      }
1210    }else{
1211      map* tmpm2=getMap(tmp_maps->content,"tmpUrl");
1212      if(tmpm1!=NULL && tmpm2!=NULL){
1213        if( strncasecmp( tmpm2->value, "http://", 7) == 0 ||
1214            strncasecmp( tmpm2->value, "https://", 8 ) == 0 ){
1215          sprintf(url,"%s/%s_%i.xml",tmpm2->value,service,pid);
1216        }else
1217          sprintf(url,"%s/%s/%s_%i.xml",tmpm1->value,tmpm2->value,service,pid);
1218      }
1219    }
1220    if(tmpm1!=NULL)
1221      sprintf(tmp,"%s",tmpm1->value);
1222    tmpm1=getMapFromMaps(m,"main","TmpPath");
1223    sprintf(stored_path,"%s/%s_%i.xml",tmpm1->value,service,pid);
1224  }
1225
1226
1227
1228  xmlNewProp(n,BAD_CAST "serviceInstance",BAD_CAST tmp);
1229  map* test=getMap(request,"storeExecuteResponse");
1230  bool hasStoredExecuteResponse=false;
1231  if(test!=NULL && strcasecmp(test->value,"true")==0){
1232    xmlNewProp(n,BAD_CAST "statusLocation",BAD_CAST url);
1233    hasStoredExecuteResponse=true;
1234  }
1235
1236  nc = xmlNewNode(ns, BAD_CAST "Process");
1237  map* tmp2=getMap(serv->content,"processVersion");
1238  if(tmp2!=NULL)
1239    xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp2->value);
1240 
1241  printDescription(nc,ns_ows,serv->name,serv->content);
1242
1243  xmlAddChild(n,nc);
1244
1245  nc = xmlNewNode(ns, BAD_CAST "Status");
1246  const struct tm *tm;
1247  size_t len;
1248  time_t now;
1249  char *tmp1;
1250  map *tmpStatus;
1251 
1252  now = time ( NULL );
1253  tm = localtime ( &now );
1254
1255  tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
1256
1257  len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
1258
1259  xmlNewProp(nc,BAD_CAST "creationTime",BAD_CAST tmp1);
1260
1261  char sMsg[2048];
1262  switch(status){
1263  case SERVICE_SUCCEEDED:
1264    nc1 = xmlNewNode(ns, BAD_CAST "ProcessSucceeded");
1265    sprintf(sMsg,_("Service \"%s\" run successfully."),serv->name);
1266    nc3=xmlNewText(BAD_CAST sMsg);
1267    xmlAddChild(nc1,nc3);
1268    break;
1269  case SERVICE_STARTED:
1270    nc1 = xmlNewNode(ns, BAD_CAST "ProcessStarted");
1271    tmpStatus=getMapFromMaps(m,"lenv","status");
1272    xmlNewProp(nc1,BAD_CAST "percentCompleted",BAD_CAST tmpStatus->value);
1273    sprintf(sMsg,_("ZOO Service \"%s\" is currently running. Please, reload this document to get the up-to-date status of the Service."),serv->name);
1274    nc3=xmlNewText(BAD_CAST sMsg);
1275    xmlAddChild(nc1,nc3);
1276    break;
1277  case SERVICE_ACCEPTED:
1278    nc1 = xmlNewNode(ns, BAD_CAST "ProcessAccepted");
1279    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);
1280    nc3=xmlNewText(BAD_CAST sMsg);
1281    xmlAddChild(nc1,nc3);
1282    break;
1283  case SERVICE_FAILED:
1284    nc1 = xmlNewNode(ns, BAD_CAST "ProcessFailed");
1285    map *errorMap;
1286    map *te;
1287    te=getMapFromMaps(m,"lenv","code");
1288    if(te!=NULL)
1289      errorMap=createMap("code",te->value);
1290    else
1291      errorMap=createMap("code","NoApplicableCode");
1292    te=getMapFromMaps(m,"lenv","message");
1293    if(te!=NULL)
1294      addToMap(errorMap,"text",_ss(te->value));
1295    else
1296      addToMap(errorMap,"text",_("No more information available"));
1297    nc3=createExceptionReportNode(m,errorMap,0);
1298    freeMap(&errorMap);
1299    free(errorMap);
1300    xmlAddChild(nc1,nc3);
1301    break;
1302  default :
1303    printf(_("error code not know : %i\n"),status);
1304    //exit(1);
1305    break;
1306  }
1307  xmlAddChild(nc,nc1);
1308  xmlAddChild(n,nc);
1309  free(tmp1);
1310
1311#ifdef DEBUG
1312  fprintf(stderr,"printProcessResponse 1 161\n");
1313#endif
1314
1315  map* lineage=getMap(request,"lineage");
1316  if(lineage!=NULL && strcasecmp(lineage->value,"true")==0){
1317    nc = xmlNewNode(ns, BAD_CAST "DataInputs");
1318    int i;
1319    maps* mcursor=inputs;
1320    elements* scursor=NULL;
1321    while(mcursor!=NULL /*&& scursor!=NULL*/){
1322      scursor=getElements(serv->inputs,mcursor->name);
1323      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Input");
1324      mcursor=mcursor->next;
1325    }
1326    xmlAddChild(n,nc);
1327   
1328#ifdef DEBUG
1329    fprintf(stderr,"printProcessResponse 1 177\n");
1330#endif
1331
1332    nc = xmlNewNode(ns, BAD_CAST "OutputDefinitions");
1333    mcursor=outputs;
1334    scursor=NULL;
1335    while(mcursor!=NULL){
1336      scursor=getElements(serv->outputs,mcursor->name);
1337      printOutputDefinitions1(doc,nc,ns,ns_ows,scursor,mcursor,"Output");
1338      mcursor=mcursor->next;
1339    }
1340    xmlAddChild(n,nc);
1341  }
1342#ifdef DEBUG
1343  fprintf(stderr,"printProcessResponse 1 190\n");
1344#endif
1345
1346  /**
1347   * Display the process output only when requested !
1348   */
1349  if(status==SERVICE_SUCCEEDED){
1350    nc = xmlNewNode(ns, BAD_CAST "ProcessOutputs");
1351    maps* mcursor=outputs;
1352    elements* scursor=serv->outputs;
1353    map* testResponse=getMap(request,"RawDataOutput");
1354    if(testResponse==NULL)
1355      testResponse=getMap(request,"ResponseDocument");
1356    while(mcursor!=NULL){
1357      map* tmp0=getMap(mcursor->content,"inRequest");
1358      scursor=getElements(serv->outputs,mcursor->name);
1359      if(scursor!=NULL){
1360        if(testResponse==NULL || tmp0==NULL)
1361          printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1362        else
1363          if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0)
1364            printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1365      }else
1366        /**
1367         * In case there was no definition found in the ZCFG file but
1368         * present in the service code
1369         */
1370        printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output");
1371      mcursor=mcursor->next;
1372    }
1373    xmlAddChild(n,nc);
1374  }
1375
1376#ifdef DEBUG
1377  fprintf(stderr,"printProcessResponse 1 202\n");
1378#endif
1379  nr=soapEnvelope(m,n);
1380  xmlDocSetRootElement(doc, nr);
1381
1382  if(hasStoredExecuteResponse==true){
1383    /* We need to write the ExecuteResponse Document somewhere */
1384    FILE* output=fopen(stored_path,"w");
1385    if(output==NULL){
1386      /* If the file cannot be created return an ExceptionReport */
1387      char tmpMsg[1024];
1388      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the ExecuteResponse."),stored_path);
1389      map * errormap = createMap("text",tmpMsg);
1390      addToMap(errormap,"code", "InternalError");
1391      printExceptionReportResponse(m,errormap);
1392      freeMap(&errormap);
1393      free(errormap);
1394      xmlCleanupParser();
1395      zooXmlCleanupNs();
1396      return;
1397    }
1398    xmlChar *xmlbuff;
1399    int buffersize;
1400    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1);
1401    fwrite(xmlbuff,1,xmlStrlen(xmlbuff)*sizeof(char),output);
1402    xmlFree(xmlbuff);
1403    fclose(output);
1404  }
1405  printDocument(m,doc,pid);
1406
1407  xmlCleanupParser();
1408  zooXmlCleanupNs();
1409}
1410
1411
1412void printDocument(maps* m, xmlDocPtr doc,int pid){
1413  char *encoding=getEncoding(m);
1414  if(pid==getpid()){
1415    printHeaders(m);
1416    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1417  }
1418  fflush(stdout);
1419  xmlChar *xmlbuff;
1420  int buffersize;
1421  /*
1422   * Dump the document to a buffer and print it on stdout
1423   * for demonstration purposes.
1424   */
1425  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1426  printf("%s",xmlbuff);
1427  fflush(stdout);
1428  /*
1429   * Free associated memory.
1430   */
1431  xmlFree(xmlbuff);
1432  xmlFreeDoc(doc);
1433  xmlCleanupParser();
1434  zooXmlCleanupNs();
1435}
1436
1437void printOutputDefinitions1(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,maps* m,const char* type){
1438  xmlNodePtr nc1;
1439  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1440  map *tmp=NULL; 
1441  if(e!=NULL && e->defaults!=NULL)
1442    tmp=e->defaults->content;
1443  else{
1444    /*
1445    dumpElements(e);
1446    */
1447    return;
1448  }
1449  while(tmp!=NULL){
1450    if(strncasecmp(tmp->name,"MIMETYPE",strlen(tmp->name))==0
1451       || strncasecmp(tmp->name,"ENCODING",strlen(tmp->name))==0
1452       || strncasecmp(tmp->name,"SCHEMA",strlen(tmp->name))==0
1453       || strncasecmp(tmp->name,"UOM",strlen(tmp->name))==0)
1454    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1455    tmp=tmp->next;
1456  }
1457  tmp=getMap(e->defaults->content,"asReference");
1458  if(tmp==NULL)
1459    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1460
1461  tmp=e->content;
1462
1463  printDescription(nc1,ns_ows,m->name,e->content);
1464
1465  xmlAddChild(nc,nc1);
1466
1467}
1468
1469void printOutputDefinitions(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,elements* e,map* m,const char* type){
1470  xmlNodePtr nc1,nc2,nc3;
1471  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1472  map *tmp=NULL; 
1473  if(e!=NULL && e->defaults!=NULL)
1474    tmp=e->defaults->content;
1475  else{
1476    /*
1477    dumpElements(e);
1478    */
1479    return;
1480  }
1481  while(tmp!=NULL){
1482    xmlNewProp(nc1,BAD_CAST tmp->name,BAD_CAST tmp->value);
1483    tmp=tmp->next;
1484  }
1485  tmp=getMap(e->defaults->content,"asReference");
1486  if(tmp==NULL)
1487    xmlNewProp(nc1,BAD_CAST "asReference",BAD_CAST "false");
1488
1489  tmp=e->content;
1490
1491  printDescription(nc1,ns_ows,m->name,e->content);
1492
1493  xmlAddChild(nc,nc1);
1494
1495}
1496
1497void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type){
1498  xmlNodePtr nc1,nc2,nc3;
1499  nc1=xmlNewNode(ns_wps, BAD_CAST type);
1500  map *tmp=NULL;
1501  if(e!=NULL)
1502    tmp=e->content;
1503  else
1504    tmp=m->content;
1505#ifdef DEBUG
1506  dumpMap(tmp);
1507  dumpElements(e);
1508#endif
1509  nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
1510  if(e!=NULL)
1511    nc3=xmlNewText(BAD_CAST e->name);
1512  else
1513    nc3=xmlNewText(BAD_CAST m->name);
1514  xmlAddChild(nc2,nc3);
1515  xmlAddChild(nc1,nc2);
1516  xmlAddChild(nc,nc1);
1517  // Extract Title required to be first element in the ZCFG file !
1518  bool isTitle=TRUE;
1519  if(e!=NULL)
1520    tmp=getMap(e->content,"Title");
1521  else
1522    tmp=getMap(m->content,"Title");
1523 
1524  if(tmp!=NULL){
1525    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1526    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1527    xmlAddChild(nc2,nc3); 
1528    xmlAddChild(nc1,nc2);
1529  }
1530
1531  if(e!=NULL)
1532    tmp=getMap(e->content,"Abstract");
1533  else
1534    tmp=getMap(m->content,"Abstract");
1535  if(tmp!=NULL){
1536    nc2=xmlNewNode(ns_ows, BAD_CAST tmp->name);
1537    nc3=xmlNewText(BAD_CAST _ss(tmp->value));
1538    xmlAddChild(nc2,nc3); 
1539    xmlAddChild(nc1,nc2);
1540    xmlAddChild(nc,nc1);
1541  }
1542
1543  /**
1544   * IO type Reference or full Data ?
1545   */
1546#ifdef DEBUG
1547  fprintf(stderr,"FORMAT %s %s\n",e->format,e->format);
1548#endif
1549  map *tmpMap=getMap(m->content,"Reference");
1550  if(tmpMap==NULL){
1551    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
1552    if(e!=NULL){
1553      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
1554        nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
1555      else
1556        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
1557          nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
1558        else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
1559          nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
1560        else
1561          nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
1562    }
1563    else{
1564      map* tmpV=getMapFromMaps(m,"format","value");
1565      if(tmpV!=NULL)
1566        nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
1567      else
1568        nc3=xmlNewNode(ns_wps, BAD_CAST "LitteralData");
1569    } 
1570    tmp=m->content;
1571#ifdef USE_MS
1572    map* testMap=getMap(tmp,"requestedMimeType");
1573#endif
1574    while(tmp!=NULL){
1575      if(strcasecmp(tmp->name,"mimeType")==0 ||
1576         strcasecmp(tmp->name,"encoding")==0 ||
1577         strcasecmp(tmp->name,"schema")==0 ||
1578         strcasecmp(tmp->name,"datatype")==0 ||
1579         strcasecmp(tmp->name,"uom")==0)
1580#ifdef USE_MS
1581        if(testMap==NULL || (testMap!=NULL && strncasecmp(testMap->value,"text/xml",8)==0)){
1582#endif
1583        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1584#ifdef USE_MS
1585        }
1586      else
1587        if(strcasecmp(tmp->name,"mimeType")==0)
1588          if(testMap!=NULL)
1589            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1590          else 
1591            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1592#endif
1593      tmp=tmp->next;
1594      xmlAddChild(nc2,nc3);
1595    }
1596    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
1597      map* bb=getMap(m->content,"value");
1598      if(bb!=NULL){
1599        map* tmpRes=parseBoundingBox(bb->value);
1600        printBoundingBox(ns_ows,nc3,tmpRes);
1601        freeMap(&tmpRes);
1602        free(tmpRes);
1603      }
1604    }else{
1605      if(e!=NULL)
1606        tmp=getMap(e->defaults->content,"mimeType");
1607      else
1608        tmp=NULL;
1609#ifdef USE_MS
1610      /**
1611       * In case of OGC WebServices output use, as the data was requested
1612       * with asReference=false we have to download the resulting OWS request
1613       * stored in the Reference map value.
1614       */
1615      map* testMap=getMap(m->content,"requestedMimeType");
1616      if(testMap!=NULL){
1617        HINTERNET hInternet;
1618        hInternet=InternetOpen(
1619#ifndef WIN32
1620                               (LPCTSTR)
1621#endif
1622                               "ZooWPSClient\0",
1623                               INTERNET_OPEN_TYPE_PRECONFIG,
1624                               NULL,NULL, 0);
1625        testMap=getMap(m->content,"Reference");
1626        loadRemoteFile(m,m->content,hInternet,testMap->value);
1627        InternetCloseHandle(hInternet);
1628      }
1629#endif
1630      map* tmp1=getMap(m->content,"encoding");
1631      map* tmp2=getMap(m->content,"mimeType");
1632      map* tmp3=getMap(m->content,"value");
1633      int hasValue=1;
1634      if(tmp3==NULL){
1635        tmp3=createMap("value","");
1636        hasValue=-1;
1637      }
1638      if((tmp1!=NULL && strncmp(tmp1->value,"base64",6)==0)
1639         || (tmp2!=NULL && (strncmp(tmp2->value,"image/",6)==0 ||
1640                            (strncmp(tmp2->value,"application/",12)==0) &&
1641                            strncmp(tmp2->value,"application/json",16)!=0&&
1642                            strncmp(tmp2->value,"application/x-javascript",24)!=0&&
1643                            strncmp(tmp2->value,"application/vnd.google-earth.kml",32)!=0)
1644             )) {
1645        map* rs=getMap(m->content,"size");
1646        bool isSized=true;
1647        if(rs==NULL){
1648          char tmp1[1024];
1649          sprintf(tmp1,"%d",strlen(tmp3->value));
1650          rs=createMap("size",tmp1);
1651          isSized=false;
1652        }
1653
1654        xmlAddChild(nc3,xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));
1655        if(!isSized){
1656          freeMap(&rs);
1657          free(rs);
1658        }
1659      }
1660      else if(tmp2!=NULL){
1661        if(strncmp(tmp2->value,"text/js",7)==0 ||
1662           strncmp(tmp2->value,"application/json",16)==0)
1663          xmlAddChild(nc3,xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
1664        else{
1665          if(strncmp(tmp2->value,"text/xml",8)==0 ||
1666             strncmp(tmp2->value,"application/vnd.google-earth.kml",32)==0){
1667            xmlDocPtr doc =
1668              xmlParseMemory(tmp3->value,strlen(tmp3->value));
1669            xmlNodePtr ir = xmlDocGetRootElement(doc);
1670            xmlAddChild(nc3,ir);
1671          }
1672          else
1673            xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1674        }
1675        xmlAddChild(nc2,nc3);
1676      }
1677      else{
1678        xmlAddChild(nc3,xmlNewText(BAD_CAST tmp3->value));
1679      }
1680      if(hasValue<0){
1681        freeMap(&tmp3);
1682        free(tmp3);
1683      }
1684    }
1685  }
1686  else{
1687    tmpMap=getMap(m->content,"Reference");
1688    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
1689    if(strcasecmp(type,"Output")==0)
1690      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
1691    else
1692      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
1693    tmp=m->content;
1694#ifdef USE_MS
1695    map* testMap=getMap(tmp,"requestedMimeType");
1696#endif
1697    while(tmp!=NULL){
1698      if(strcasecmp(tmp->name,"mimeType")==0 ||
1699         strcasecmp(tmp->name,"encoding")==0 ||
1700         strcasecmp(tmp->name,"schema")==0 ||
1701         strcasecmp(tmp->name,"datatype")==0 ||
1702         strcasecmp(tmp->name,"uom")==0)
1703#ifdef USE_MS
1704        if(testMap!=NULL  && strncasecmp(testMap->value,"text/xml",8)!=0){
1705          if(strcasecmp(tmp->name,"mimeType")==0)
1706            xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST testMap->value);
1707        }
1708        else
1709#endif
1710        xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
1711      tmp=tmp->next;
1712      xmlAddChild(nc2,nc3);
1713    }
1714  }
1715  xmlAddChild(nc1,nc2);
1716  xmlAddChild(nc,nc1);
1717
1718}
1719
1720void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
1721  xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
1722  xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
1723  xmlAddChild(root,nc2);
1724  map* tmp=amap;
1725  char *tmp2[2];
1726  tmp2[0]="Title";
1727  tmp2[1]="Abstract";
1728  int j=0;
1729  for(j=0;j<2;j++){
1730    map* tmp1=getMap(tmp,tmp2[j]);
1731    if(tmp1!=NULL){
1732      nc2 = xmlNewNode(ns_ows, BAD_CAST tmp2[j]);
1733      xmlAddChild(nc2,xmlNewText(BAD_CAST _ss(tmp1->value)));
1734      xmlAddChild(root,nc2);
1735    }
1736  }
1737}
1738
1739char* getEncoding(maps* m){
1740  if(m!=NULL){
1741    map* tmp=getMap(m->content,"encoding");
1742    if(tmp!=NULL){
1743      return tmp->value;
1744    }
1745    else
1746      return "UTF-8";
1747  }
1748  else
1749    return "UTF-8"; 
1750}
1751
1752char* getVersion(maps* m){
1753  if(m!=NULL){
1754    map* tmp=getMap(m->content,"version");
1755    if(tmp!=NULL){
1756      return tmp->value;
1757    }
1758    else
1759      return "1.0.0";
1760  }
1761  else
1762    return "1.0.0";
1763}
1764
1765void printExceptionReportResponse(maps* m,map* s){
1766  int buffersize;
1767  xmlDocPtr doc;
1768  xmlChar *xmlbuff;
1769  xmlNodePtr n;
1770
1771  doc = xmlNewDoc(BAD_CAST "1.0");
1772  maps* tmpMap=getMaps(m,"main");
1773  char *encoding=getEncoding(tmpMap);
1774  if(m!=NULL){
1775    map *tmpSid=getMapFromMaps(m,"lenv","sid");
1776    if(tmpSid!=NULL){
1777      if( getpid()==atoi(tmpSid->value) ){
1778        printHeaders(m);
1779        printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1780      }
1781    }
1782    else{
1783      printHeaders(m);
1784      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1785    }
1786  }else{
1787    printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1788  }
1789  n=createExceptionReportNode(m,s,1);
1790  xmlDocSetRootElement(doc, n);
1791  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
1792  printf("%s",xmlbuff);
1793  fflush(stdout);
1794  xmlFreeDoc(doc);
1795  xmlFree(xmlbuff);
1796  xmlCleanupParser();
1797  zooXmlCleanupNs();
1798}
1799
1800xmlNodePtr createExceptionReportNode(maps* m,map* s,int use_ns){
1801 
1802  int buffersize;
1803  xmlChar *xmlbuff;
1804  xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
1805  xmlNodePtr n,nc,nc1,nc2;
1806
1807  maps* tmpMap=getMaps(m,"main");
1808
1809  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
1810  ns=usedNs[nsid];
1811  n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
1812
1813  if(use_ns==1){
1814    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
1815    int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
1816    ns_xsi=usedNs[xsiId];
1817    int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
1818    ns_xlink=usedNs[xlinkId];
1819    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");
1820  }
1821  addLangAttr(n,m);
1822  xmlNewProp(n,BAD_CAST "version",BAD_CAST "1.1.0");
1823 
1824  nc = xmlNewNode(ns, BAD_CAST "Exception");
1825
1826  map* tmp=getMap(s,"code");
1827  if(tmp!=NULL)
1828    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST tmp->value);
1829  else
1830    xmlNewProp(nc,BAD_CAST "exceptionCode",BAD_CAST "NoApplicableCode");
1831
1832  tmp=getMap(s,"text");
1833  nc1 = xmlNewNode(ns, BAD_CAST "ExceptionText");
1834  nc2=NULL;
1835  if(tmp!=NULL){
1836    xmlNodeSetContent(nc1, BAD_CAST tmp->value);
1837  }
1838  else{
1839    xmlNodeSetContent(nc1, BAD_CAST _("No debug message available"));
1840  }
1841  xmlAddChild(nc,nc1);
1842  xmlAddChild(n,nc);
1843  return n;
1844}
1845
1846
1847void outputResponse(service* s,maps* request_inputs,maps* request_outputs,
1848                    map* request_inputs1,int cpid,maps* m,int res){
1849#ifdef DEBUG
1850  dumpMaps(request_inputs);
1851  dumpMaps(request_outputs);
1852  fprintf(stderr,"printProcessResponse\n");
1853#endif
1854  map* toto=getMap(request_inputs1,"RawDataOutput");
1855  int asRaw=0;
1856  if(toto!=NULL)
1857    asRaw=1;
1858 
1859  maps* tmpSess=getMaps(m,"senv");
1860  if(tmpSess!=NULL){
1861    map *_tmp=getMapFromMaps(m,"lenv","cookie");
1862    char* sessId;
1863    if(_tmp!=NULL){
1864      printf("Set-Cookie: %s; HttpOnly\r\n",_tmp->value);
1865      printf("P3P: CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"\r\n");
1866      char session_file_path[100];
1867      char *tmp1=strtok(_tmp->value,";");
1868      if(tmp1!=NULL)
1869        sprintf(session_file_path,"%s",strstr(tmp1,"=")+1);
1870      else
1871        sprintf(session_file_path,"%s",strstr(_tmp->value,"=")+1);
1872      sessId=strdup(session_file_path);
1873    }else{
1874      maps* t=getMaps(m,"senv");
1875      map*p=t->content;
1876      while(p!=NULL){
1877        if(strstr(p->name,"ID")!=NULL){
1878          sessId=strdup(p->value);
1879          break;
1880        }
1881        p=p->next;
1882      }
1883    }
1884    char session_file_path[1024];
1885    map *tmpPath=getMapFromMaps(m,"main","sessPath");
1886    if(tmpPath==NULL)
1887      tmpPath=getMapFromMaps(m,"main","tmpPath");
1888    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,sessId);
1889    FILE* teste=fopen(session_file_path,"w");
1890    if(teste==NULL){
1891      char tmpMsg[1024];
1892      sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the session maps."),session_file_path);
1893      map * errormap = createMap("text",tmpMsg);
1894      addToMap(errormap,"code", "InternalError");
1895     
1896      printExceptionReportResponse(m,errormap);
1897      freeMap(&errormap);
1898      free(errormap);
1899      return;
1900    }
1901    else{
1902      fclose(teste);
1903      dumpMapsToFile(tmpSess,session_file_path);
1904    }
1905  }
1906 
1907  if(res==SERVICE_FAILED){
1908    map * errormap;
1909    map *lenv;
1910    lenv=getMapFromMaps(m,"lenv","message");
1911    char *tmp0;
1912    if(lenv!=NULL){
1913      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));
1914      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
1915    }
1916    else{
1917      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
1918      sprintf(tmp0,_("Unable to run the Service. No more information was returned back by the Service."));
1919    }
1920    errormap = createMap("text",tmp0);
1921    free(tmp0);
1922    addToMap(errormap,"code", "InternalError");
1923    printExceptionReportResponse(m,errormap);
1924    freeMap(&errormap);
1925    free(errormap);
1926    return;
1927  }
1928
1929  if(asRaw==0){
1930#ifdef DEBUG
1931    fprintf(stderr,"REQUEST_OUTPUTS FINAL\n");
1932    dumpMaps(request_outputs);
1933#endif
1934    maps* tmpI=request_outputs;
1935    while(tmpI!=NULL){
1936#ifdef USE_MS
1937      map* testMap=getMap(tmpI->content,"useMapserver");       
1938#endif
1939      toto=getMap(tmpI->content,"asReference");
1940#ifdef USE_MS
1941      if(toto!=NULL && strcasecmp(toto->value,"true")==0 && testMap==NULL)
1942#else
1943      if(toto!=NULL && strcasecmp(toto->value,"true")==0)
1944#endif
1945        {
1946        elements* in=getElements(s->outputs,tmpI->name);
1947        char *format=NULL;
1948        if(in!=NULL){
1949          format=strdup(in->format);
1950        }else
1951          format=strdup("LiteralData");
1952        if(strcasecmp(format,"BoundingBoxData")==0){
1953          addToMap(tmpI->content,"extension","xml");
1954          addToMap(tmpI->content,"mimeType","text/xml");
1955          addToMap(tmpI->content,"encoding","UTF-8");
1956          addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
1957        }
1958        map *ext=getMap(tmpI->content,"extension");
1959        map *tmp1=getMapFromMaps(m,"main","tmpPath");
1960        char *file_name,*file_path;
1961        bool hasExt=true;
1962        if(ext==NULL){
1963          // We can fallback to a default list of supported formats using
1964          // mimeType information if present here. Maybe we can add more formats
1965          // here.
1966          // If mimeType was not found, we then set txt as the default extension
1967          map* mtype=getMap(tmpI->content,"mimeType");
1968          if(mtype!=NULL){
1969            if(strcasecmp(mtype->value,"text/xml")==0)
1970              ext=createMap("extension","xml");
1971            else if(strcasecmp(mtype->value,"application/json")==0)
1972              ext=createMap("extension","js");
1973            else if(strncmp(mtype->value,"application/vnd.google-earth.kml",32)==0)
1974              ext=createMap("extension","kml");
1975            else if(strncmp(mtype->value,"image/",6)==0)
1976              ext=createMap("extension",strstr(mtype->value,"/")+1);
1977            else
1978              ext=createMap("extension","txt");
1979          }
1980          else
1981            ext=createMap("extension","txt");
1982          hasExt=false;
1983        }
1984        file_name=(char*)malloc((strlen(s->name)+strlen(ext->value)+strlen(tmpI->name)+1024)*sizeof(char));
1985        int cpid0=cpid+time(NULL);
1986        sprintf(file_name,"%s_%s_%i.%s",s->name,tmpI->name,cpid0,ext->value);
1987        file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
1988        sprintf(file_path,"%s/%s",tmp1->value,file_name);
1989        FILE *ofile=fopen(file_path,"wb");
1990        if(ofile==NULL){
1991          char tmpMsg[1024];
1992          sprintf(tmpMsg,_("Unable to create the file : \"%s\" for storing the %s final result."),file_name,tmpI->name);
1993          map * errormap = createMap("text",tmpMsg);
1994          addToMap(errormap,"code", "InternalError");
1995          printExceptionReportResponse(m,errormap);
1996          freeMap(&errormap);
1997          free(errormap);
1998          free(file_name);
1999          free(file_path);
2000          return;
2001        }
2002        free(file_path);
2003        map *tmp2=getMapFromMaps(m,"main","tmpUrl");
2004        map *tmp3=getMapFromMaps(m,"main","serverAddress");
2005        char *file_url;
2006        if(strncasecmp(tmp2->value,"http://",7)==0 ||
2007           strncasecmp(tmp2->value,"https://",8)==0){
2008          file_url=(char*)malloc((strlen(tmp2->value)+strlen(file_name)+2)*sizeof(char));
2009          sprintf(file_url,"%s/%s",tmp2->value,file_name);
2010        }else{
2011          file_url=(char*)malloc((strlen(tmp3->value)+strlen(tmp2->value)+strlen(file_name)+3)*sizeof(char));
2012          sprintf(file_url,"%s/%s/%s",tmp3->value,tmp2->value,file_name);
2013        }
2014        addToMap(tmpI->content,"Reference",file_url);
2015        if(!hasExt){
2016          freeMap(&ext);
2017          free(ext);
2018        }
2019        toto=getMap(tmpI->content,"value");
2020        if(strcasecmp(format,"BoundingBoxData")!=0){
2021          map* size=getMap(tmpI->content,"size");
2022          if(size!=NULL && toto!=NULL)
2023            fwrite(toto->value,1,atoi(size->value)*sizeof(char),ofile);
2024          else
2025            if(toto!=NULL && toto->value!=NULL)
2026              fwrite(toto->value,1,strlen(toto->value)*sizeof(char),ofile);
2027        }else{
2028          printBoundingBoxDocument(m,tmpI,ofile);
2029        }
2030        free(format);
2031        fclose(ofile);
2032        free(file_name);
2033        free(file_url); 
2034      }
2035#ifdef USE_MS
2036      else{
2037        if(testMap!=NULL){
2038          setReferenceUrl(m,tmpI);
2039        }
2040      }
2041#endif
2042      tmpI=tmpI->next;
2043    }
2044    map *r_inputs=getMap(s->content,"serviceProvider");
2045#ifdef DEBUG
2046    fprintf(stderr,"SERVICE : %s\n",r_inputs->value);
2047    dumpMaps(m);
2048#endif
2049    printProcessResponse(m,request_inputs1,cpid,
2050                         s,r_inputs->value,res,
2051                         request_inputs,
2052                         request_outputs);
2053    }
2054    else{
2055      /**
2056       * We get the requested output or fallback to the first one if the
2057       * requested one is not present in the resulting outputs maps.
2058       */
2059      maps* tmpI=NULL;
2060      map* tmpIV=getMap(request_inputs1,"RawDataOutput");
2061      if(tmpIV!=NULL){
2062        tmpI=getMaps(request_outputs,tmpIV->value);
2063      }
2064      if(tmpI==NULL)
2065        tmpI=request_outputs;
2066      elements* e=getElements(s->outputs,tmpI->name);
2067      if(e!=NULL && strcasecmp(e->format,"BoundingBoxData")==0){
2068        printBoundingBoxDocument(m,tmpI,NULL);
2069      }else{
2070        toto=getMap(tmpI->content,"value");
2071        if(toto==NULL){
2072          char tmpMsg[1024];
2073          sprintf(tmpMsg,_("Wrong RawDataOutput parameter, unable to fetch any result for the name your provided : \"%s\"."),tmpI->name);
2074          map * errormap = createMap("text",tmpMsg);
2075          addToMap(errormap,"code", "InvalidParameterValue");
2076          printExceptionReportResponse(m,errormap);
2077          freeMap(&errormap);
2078          free(errormap);
2079          return;
2080        }
2081        map* fname=getMapFromMaps(tmpI,tmpI->name,"filename");
2082        if(fname!=NULL)
2083          printf("Content-Disposition: attachment; filename=\"%s\"\r\n",fname->value);
2084        map* rs=getMapFromMaps(tmpI,tmpI->name,"size");
2085        if(rs!=NULL)
2086          printf("Content-Length: %s\r\n",rs->value);
2087        printHeaders(m);
2088        char mime[1024];
2089        map* mi=getMap(tmpI->content,"mimeType");
2090#ifdef DEBUG
2091        fprintf(stderr,"SERVICE OUTPUTS\n");
2092        dumpMaps(request_outputs);
2093        fprintf(stderr,"SERVICE OUTPUTS\n");
2094#endif
2095        map* en=getMap(tmpI->content,"encoding");
2096        if(mi!=NULL && en!=NULL)
2097          sprintf(mime,
2098                  "Content-Type: %s; charset=%s\r\nStatus: 200 OK\r\n\r\n",
2099                  mi->value,en->value);
2100        else
2101          if(mi!=NULL)
2102            sprintf(mime,
2103                    "Content-Type: %s; charset=UTF-8\r\nStatus: 200 OK\r\n\r\n",
2104                    mi->value);
2105          else
2106            sprintf(mime,"Content-Type: text/plain; charset=utf-8\r\nStatus: 200 OK\r\n\r\n");
2107        printf("%s",mime);
2108        if(rs!=NULL)
2109          fwrite(toto->value,1,atoi(rs->value),stdout);
2110        else
2111          fwrite(toto->value,1,strlen(toto->value),stdout);
2112#ifdef DEBUG
2113        dumpMap(toto);
2114#endif
2115      }
2116    }
2117}
2118
2119char *base64(const char *input, int length)
2120{
2121  BIO *bmem, *b64;
2122  BUF_MEM *bptr;
2123
2124  b64 = BIO_new(BIO_f_base64());
2125  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2126  bmem = BIO_new(BIO_s_mem());
2127  b64 = BIO_push(b64, bmem);
2128  BIO_write(b64, input, length);
2129  BIO_flush(b64);
2130  BIO_get_mem_ptr(b64, &bptr);
2131
2132  char *buff = (char *)malloc((bptr->length)*sizeof(char));
2133  memcpy(buff, bptr->data, bptr->length-1);
2134  buff[bptr->length-1] = 0;
2135
2136  BIO_free_all(b64);
2137
2138  return buff;
2139}
2140
2141char *base64d(const char *input, int length,int* red)
2142{
2143  BIO *b64, *bmem;
2144
2145  char *buffer = (char *)malloc(length);
2146  if(buffer){
2147    memset(buffer, 0, length);
2148    b64 = BIO_new(BIO_f_base64());
2149    if(b64){
2150      bmem = BIO_new_mem_buf((unsigned char*)input,length);
2151      bmem = BIO_push(b64, bmem);
2152      *red=BIO_read(bmem, buffer, length);
2153      buffer[length-1]=0;
2154      BIO_free_all(bmem);
2155    }
2156  }
2157  return buffer;
2158}
2159
2160void ensureDecodedBase64(maps **in){
2161  maps* cursor=*in;
2162  while(cursor!=NULL){
2163    map *tmp=getMap(cursor->content,"encoding");
2164    if(tmp!=NULL && strncasecmp(tmp->value,"base64",6)==0){
2165      tmp=getMap(cursor->content,"value");
2166      addToMap(cursor->content,"base64_value",tmp->value);
2167      int size=0;
2168      char *s=strdup(tmp->value);
2169      free(tmp->value);
2170      tmp->value=base64d(s,strlen(s),&size);
2171      free(s);
2172      char sizes[1024];
2173      sprintf(sizes,"%d",size);
2174      addToMap(cursor->content,"size",sizes);
2175    }
2176    cursor=cursor->next;
2177  }
2178}
2179
2180char* addDefaultValues(maps** out,elements* in,maps* m,int type){
2181  elements* tmpInputs=in;
2182  maps* out1=*out;
2183  if(type==1){
2184    while(out1!=NULL){
2185      if(getElements(in,out1->name)==NULL)
2186        return out1->name;
2187      out1=out1->next;
2188    }
2189    out1=*out;
2190  }
2191  while(tmpInputs!=NULL){
2192    maps *tmpMaps=getMaps(out1,tmpInputs->name);
2193    if(tmpMaps==NULL){
2194      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
2195      tmpMaps2->name=strdup(tmpInputs->name);
2196      tmpMaps2->content=NULL;
2197      tmpMaps2->next=NULL;
2198     
2199      if(type==0){
2200        map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
2201        if(tmpMapMinO!=NULL)
2202          if(atoi(tmpMapMinO->value)>=1){
2203            freeMaps(&tmpMaps2);
2204            free(tmpMaps2);
2205            return tmpInputs->name;
2206          }
2207          else{
2208            if(tmpMaps2->content==NULL)
2209              tmpMaps2->content=createMap("minOccurs",tmpMapMinO->value);
2210            else
2211              addToMap(tmpMaps2->content,"minOccurs",tmpMapMinO->value);
2212          }
2213        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2214        if(tmpMaxO!=NULL)
2215          if(tmpMaps2->content==NULL)
2216            tmpMaps2->content=createMap("maxOccurs",tmpMaxO->value);
2217          else
2218            addToMap(tmpMaps2->content,"maxOccurs",tmpMaxO->value);
2219      }
2220
2221      iotype* tmpIoType=tmpInputs->defaults;
2222      if(tmpIoType!=NULL){
2223        map* tmpm=tmpIoType->content;
2224        while(tmpm!=NULL){
2225          if(tmpMaps2->content==NULL)
2226            tmpMaps2->content=createMap(tmpm->name,tmpm->value);
2227          else
2228            addToMap(tmpMaps2->content,tmpm->name,tmpm->value);
2229          tmpm=tmpm->next;
2230        }
2231      }
2232      addToMap(tmpMaps2->content,"inRequest","false");
2233      if(type==0){
2234        map *tmpMap=getMap(tmpMaps2->content,"value");
2235        if(tmpMap==NULL)
2236          addToMap(tmpMaps2->content,"value","NULL");
2237      }
2238      if(out1==NULL){
2239        *out=dupMaps(&tmpMaps2);
2240        out1=*out;
2241      }
2242      else
2243        addMapsToMaps(&out1,tmpMaps2);
2244      freeMap(&tmpMaps2->content);
2245      free(tmpMaps2->content);
2246      tmpMaps2->content=NULL;
2247      freeMaps(&tmpMaps2);
2248      free(tmpMaps2);
2249      tmpMaps2=NULL;
2250    }
2251    else{
2252      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
2253                                             tmpMaps->content);
2254      if(type==0) {
2255        /**
2256         * In case of an Input maps, then add the minOccurs and maxOccurs to the
2257         * content map.
2258         */
2259        map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
2260        if(tmpMap1!=NULL){
2261          if(tmpMaps->content==NULL)
2262            tmpMaps->content=createMap("minOccurs",tmpMap1->value);
2263          else
2264            addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
2265        }
2266        map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
2267        if(tmpMaxO!=NULL){
2268          if(tmpMaps->content==NULL)
2269            tmpMaps->content=createMap("maxOccurs",tmpMap1->value);
2270          else
2271            addToMap(tmpMaps->content,"maxOccurs",tmpMap1->value);
2272        }
2273        /**
2274         * Parsing BoundingBoxData, fill the following map and then add it to
2275         * the content map of the Input maps:
2276         * lowerCorner, upperCorner, srs and dimensions
2277         * cf. parseBoundingBox
2278         */
2279        if(strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
2280          maps* tmpI=getMaps(*out,tmpInputs->name);
2281          if(tmpI!=NULL){
2282            map* tmpV=getMap(tmpI->content,"value");
2283            if(tmpV!=NULL){
2284              char *tmpVS=strdup(tmpV->value);
2285              map* tmp=parseBoundingBox(tmpVS);
2286              free(tmpVS);
2287              map* tmpC=tmp;
2288              while(tmpC!=NULL){
2289                addToMap(tmpMaps->content,tmpC->name,tmpC->value);
2290                tmpC=tmpC->next;
2291              }
2292              freeMap(&tmp);
2293              free(tmp);
2294            }
2295          }
2296        }
2297      }
2298
2299      if(tmpIoType!=NULL){
2300        map* tmpContent=tmpIoType->content;
2301        map* cval=NULL;
2302        int hasPassed=-1;
2303        while(tmpContent!=NULL){
2304          if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
2305#ifdef DEBUG
2306            fprintf(stderr,"addDefaultValues %s => %s\n",tmpContent->name,tmpContent->value);
2307#endif
2308            if(tmpMaps->content==NULL)
2309              tmpMaps->content=createMap(tmpContent->name,tmpContent->value);
2310            else
2311              addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
2312           
2313            if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
2314              map* length=getMap(tmpMaps->content,"length");
2315              int i;
2316              char *tcn=strdup(tmpContent->name);
2317              for(i=1;i<atoi(length->value);i++){
2318#ifdef DEBUG
2319                dumpMap(tmpMaps->content);
2320                fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
2321#endif
2322                int len=strlen((char*) tcn);
2323                char *tmp1=(char *)malloc((len+10)*sizeof(char));
2324                sprintf(tmp1,"%s_%d",tcn,i);
2325#ifdef DEBUG
2326                fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
2327#endif
2328                addToMap(tmpMaps->content,tmp1,tmpContent->value);
2329                free(tmp1);
2330                hasPassed=1;
2331              }
2332              free(tcn);
2333            }
2334          }
2335          tmpContent=tmpContent->next;
2336        }
2337#ifdef USE_MS
2338        /**
2339         * check for useMapServer presence
2340         */
2341        map* tmpCheck=getMap(tmpIoType->content,"useMapServer");
2342        if(tmpCheck!=NULL){
2343          // Get the default value
2344          tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,NULL);
2345          tmpCheck=getMap(tmpMaps->content,"mimeType");
2346          addToMap(tmpMaps->content,"requestedMimeType",tmpCheck->value);
2347          map* cursor=tmpIoType->content;
2348          while(cursor!=NULL){
2349            addToMap(tmpMaps->content,cursor->name,cursor->value);
2350            cursor=cursor->next;
2351          }
2352         
2353          cursor=tmpInputs->content;
2354          while(cursor!=NULL){
2355            if(strcasecmp(cursor->name,"Title")==0 ||
2356               strcasecmp(cursor->name,"Abstract")==0)
2357              addToMap(tmpMaps->content,cursor->name,cursor->value);
2358           cursor=cursor->next;
2359          }
2360        }
2361#endif
2362      }
2363      if(tmpMaps->content==NULL)
2364        tmpMaps->content=createMap("inRequest","true");
2365      else
2366        addToMap(tmpMaps->content,"inRequest","true");
2367
2368    }
2369    tmpInputs=tmpInputs->next;
2370  }
2371  return "";
2372}
2373
2374/**
2375 * parseBoundingBox : parse a BoundingBox string
2376 *
2377 * OGC 06-121r3 : 10.2 Bounding box
2378 *
2379 * value is provided as : lowerCorner,upperCorner,crs,dimension
2380 * exemple : 189000,834000,285000,962000,urn:ogc:def:crs:OGC:1.3:CRS84
2381 *
2382 * Need to create a map to store boundingbox informations :
2383 *  - lowerCorner : double,double (minimum within this bounding box)
2384 *  - upperCorner : double,double (maximum within this bounding box)
2385 *  - crs : URI (Reference to definition of the CRS)
2386 *  - dimensions : int
2387 *
2388 * Note : support only 2D bounding box.
2389 */
2390map* parseBoundingBox(const char* value){
2391  map *res=NULL;
2392  if(value!=NULL){
2393    char *cv,*cvp;
2394    cv=strtok_r((char*) value,",",&cvp);
2395    int cnt=0;
2396    int icnt=0;
2397    char *currentValue=NULL;
2398    while(cv){
2399      if(cnt<2)
2400        if(currentValue!=NULL){
2401          char *finalValue=(char*)malloc((strlen(currentValue)+strlen(cv)+1)*sizeof(char));
2402          sprintf(finalValue,"%s%s",currentValue,cv);
2403          switch(cnt){
2404          case 0:
2405            res=createMap("lowerCorner",finalValue);
2406            break;
2407          case 1:
2408            addToMap(res,"upperCorner",finalValue);
2409            icnt=-1;
2410            break;
2411          }
2412          cnt++;
2413          free(currentValue);
2414          currentValue=NULL;
2415          free(finalValue);
2416        }
2417        else{
2418          currentValue=(char*)malloc((strlen(cv)+2)*sizeof(char));
2419          sprintf(currentValue,"%s ",cv);
2420        }
2421      else
2422        if(cnt==2){
2423          addToMap(res,"crs",cv);
2424          cnt++;
2425        }
2426        else
2427          addToMap(res,"dimensions",cv);
2428      icnt++;
2429      cv=strtok_r(NULL,",",&cvp);
2430    }
2431  }
2432  return res;
2433}
2434
2435/**
2436 * printBoundingBox : fill a BoundingBox node (ows:BoundingBox or
2437 * wps:BoundingBoxData). Set crs and dimensions attributes, add
2438 * Lower/UpperCorner nodes to a pre-existing XML node.
2439 */
2440void printBoundingBox(xmlNsPtr ns_ows,xmlNodePtr n,map* boundingbox){
2441
2442  xmlNodePtr bb,lw,uc;
2443
2444  map* tmp=getMap(boundingbox,"value");
2445
2446  tmp=getMap(boundingbox,"lowerCorner");
2447  if(tmp!=NULL){
2448    lw=xmlNewNode(ns_ows,BAD_CAST "LowerCorner");
2449    xmlAddChild(lw,xmlNewText(BAD_CAST tmp->value));
2450  }
2451
2452  tmp=getMap(boundingbox,"upperCorner");
2453  if(tmp!=NULL){
2454    uc=xmlNewNode(ns_ows,BAD_CAST "UpperCorner");
2455    xmlAddChild(uc,xmlNewText(BAD_CAST tmp->value));
2456  }
2457
2458  tmp=getMap(boundingbox,"crs");
2459  if(tmp!=NULL)
2460    xmlNewProp(n,BAD_CAST "crs",BAD_CAST tmp->value);
2461
2462  tmp=getMap(boundingbox,"dimensions");
2463  if(tmp!=NULL)
2464    xmlNewProp(n,BAD_CAST "dimensions",BAD_CAST tmp->value);
2465
2466  xmlAddChild(n,lw);
2467  xmlAddChild(n,uc);
2468
2469}
2470
2471void printBoundingBoxDocument(maps* m,maps* boundingbox,FILE* file){
2472  if(file==NULL)
2473    rewind(stdout);
2474  xmlNodePtr n;
2475  xmlDocPtr doc;
2476  xmlNsPtr ns_ows,ns_xsi;
2477  xmlChar *xmlbuff;
2478  int buffersize;
2479  char *encoding=getEncoding(m);
2480  map *tmp;
2481  if(file==NULL){
2482    int pid=0;
2483    tmp=getMapFromMaps(m,"lenv","sid");
2484    if(tmp!=NULL)
2485      pid=atoi(tmp->value);
2486    if(pid==getpid()){
2487      printf("Content-Type: text/xml; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
2488    }
2489    fflush(stdout);
2490  }
2491
2492  doc = xmlNewDoc(BAD_CAST "1.0");
2493  int owsId=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
2494  ns_ows=usedNs[owsId];
2495  n = xmlNewNode(ns_ows, BAD_CAST "BoundingBox");
2496  xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
2497  int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
2498  ns_xsi=usedNs[xsiId];
2499  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");
2500  map *tmp1=getMap(boundingbox->content,"value");
2501  tmp=parseBoundingBox(tmp1->value);
2502  printBoundingBox(ns_ows,n,tmp);
2503  xmlDocSetRootElement(doc, n);
2504
2505  xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, encoding, 1);
2506  if(file==NULL)
2507    printf("%s",xmlbuff);
2508  else{
2509    fprintf(file,"%s",xmlbuff);
2510  }
2511
2512  if(tmp!=NULL){
2513    freeMap(&tmp);
2514    free(tmp);
2515  }
2516  xmlFree(xmlbuff);
2517  xmlFreeDoc(doc);
2518  xmlCleanupParser();
2519  zooXmlCleanupNs();
2520 
2521}
2522
2523
2524char* getMd5(char* url){
2525  EVP_MD_CTX md5ctx;
2526  char* fresult=(char*)malloc((EVP_MAX_MD_SIZE+1)*sizeof(char));
2527  unsigned char result[EVP_MAX_MD_SIZE];
2528  unsigned int len;
2529  EVP_DigestInit(&md5ctx, EVP_md5());
2530  EVP_DigestUpdate(&md5ctx, url, strlen(url));
2531  EVP_DigestFinal_ex(&md5ctx,result,&len);
2532  EVP_MD_CTX_cleanup(&md5ctx);
2533  int i;
2534  for(i = 0; i < len; i++){
2535    if(i>0){
2536      char *tmp=strdup(fresult);
2537      sprintf(fresult,"%s%02x", tmp,result[i]);
2538      free(tmp);
2539    }
2540    else
2541      sprintf(fresult,"%02x",result[i]);
2542  }
2543  return fresult;
2544}
2545
2546/**
2547 * Cache a file for a given request
2548 */
2549void addToCache(maps* conf,char* request,char* content,char* mimeType,int length){
2550  map* tmp=getMapFromMaps(conf,"main","cacheDir");
2551  if(tmp!=NULL){
2552    char* md5str=getMd5(request);
2553    char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
2554    sprintf(fname,"%s/%s.zca",tmp->value,md5str);
2555#ifdef DEBUG
2556    fprintf(stderr,"Cache list : %s\n",fname);
2557    fflush(stderr);
2558#endif
2559    FILE* fo=fopen(fname,"w+");
2560    fwrite(content,sizeof(char),length,fo);
2561    fclose(fo);
2562
2563    sprintf(fname,"%s/%s.zcm",tmp->value,md5str);
2564    fo=fopen(fname,"w+");
2565#ifdef DEBUG
2566    fprintf(stderr,"MIMETYPE: %s\n",mimeType);
2567#endif
2568    fwrite(mimeType,sizeof(char),strlen(mimeType),fo);
2569    fclose(fo);
2570
2571    free(md5str);
2572    free(fname);
2573  }
2574}
2575
2576char* isInCache(maps* conf,char* request){
2577  map* tmpM=getMapFromMaps(conf,"main","cacheDir");
2578  if(tmpM!=NULL){
2579    char* md5str=getMd5(request);
2580#ifdef DEBUG
2581    fprintf(stderr,"MD5STR : (%s)\n\n",md5str);
2582#endif
2583    char* fname=(char*)malloc(sizeof(char)*(strlen(tmpM->value)+strlen(md5str)+6));
2584    sprintf(fname,"%s/%s.zca",tmpM->value,md5str);
2585    struct stat f_status;
2586    int s=stat(fname, &f_status);
2587    if(s==0 && f_status.st_size>0){
2588      free(md5str);
2589      return fname;
2590    }
2591    free(md5str);
2592    free(fname);
2593  }
2594  return NULL;
2595}
2596
2597/**
2598 * loadRemoteFile:
2599 * Try to load file from cache or download a remote file if not in cache
2600 */
2601int loadRemoteFile(maps* m,map* content,HINTERNET hInternet,char *url){
2602  HINTERNET res;
2603  char* fcontent;
2604  char* cached=isInCache(m,url);
2605  char *mimeType=NULL;
2606  int fsize;
2607  int hasF=-1;
2608  if(cached!=NULL){
2609    struct stat f_status;
2610    int s=stat(cached, &f_status);
2611    if(s==0){
2612      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2613      FILE* f=fopen(cached,"rb");
2614      int len=fread(fcontent,f_status.st_size,1,f);
2615      fsize=f_status.st_size;
2616      fcontent[fsize]=0;
2617      fclose(f);
2618    }
2619    cached[strlen(cached)-1]='m';
2620    s=stat(cached, &f_status);
2621    if(s==0){
2622      mimeType=(char*)malloc(sizeof(char)*(f_status.st_size+1));
2623      FILE* f=fopen(cached,"rb");
2624      int len=fread(mimeType,f_status.st_size,1,f);
2625      mimeType[f_status.st_size]=0;
2626      fclose(f);
2627    }
2628  }else{
2629    res=InternetOpenUrl(hInternet,url,NULL,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
2630    fcontent=(char*)malloc((res.nDataLen+1)*sizeof(char));
2631    if(fcontent == NULL){
2632      return errorException(m, _("Unable to allocate memory."), "InternalError");
2633    }
2634    size_t dwRead;
2635    InternetReadFile(res, (LPVOID)fcontent, res.nDataLen, &dwRead);
2636    fcontent[res.nDataLen]=0;
2637    fsize=res.nDataLen;
2638    mimeType=(char*)res.mimeType;
2639  }
2640  if(fsize==0){
2641    return errorException(m, _("Unable to download the file."), "InternalError");
2642  }
2643
2644  if(mimeType!=NULL){
2645    addToMap(content,"fmimeType",mimeType);
2646  }
2647
2648  map* tmpMap=getMapOrFill(content,"value","");
2649   
2650  free(tmpMap->value);
2651  tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
2652  if(tmpMap->value==NULL)
2653    fprintf(stderr,"Unable to allocate memory!\n");
2654  //snprintf(tmpMap->value,(fsize+1)*sizeof(char),fcontent);
2655  memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
2656 
2657  char ltmp1[256];
2658  sprintf(ltmp1,"%d",fsize);
2659  addToMap(content,"size",ltmp1);
2660  if(cached==NULL)
2661    addToCache(m,url,fcontent,mimeType,fsize);
2662  else{
2663    free(fcontent);
2664    free(mimeType);
2665    free(cached);
2666  }
2667  return 0;
2668}
2669
2670int errorException(maps *m, const char *message, const char *errorcode) 
2671{
2672  map* errormap = createMap("text", message);
2673  addToMap(errormap,"code", errorcode);
2674  printExceptionReportResponse(m,errormap);
2675  freeMap(&errormap);
2676  free(errormap);
2677  return -1;
2678}
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