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

Last change on this file since 383 was 383, checked in by djay, 11 years ago

Fix issue in JS support and for binary RawDataOutput?. Add Content-Length and Content-Disposition (optional) to response header. Add support to JS ZOO-API for sending headers and handling multi-valued inputs.

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