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

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

Fix issue on windows platform with shared memory, pass outputs as KVP to created process.

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