source: trunk/zoo-kernel/zoo_service_loader.c @ 30

Last change on this file since 30 was 30, checked in by david, 10 years ago

-support python optionnel

File size: 50.9 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2008-2009 GeoLabs SARL. All rights reserved.
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#define length(x) (sizeof(x) / sizeof(x[0]))
26
27extern "C" int yylex();
28extern "C" int crlex();
29
30
31extern "C" {
32#include <libxml/tree.h>
33#include <libxml/xmlmemory.h>
34#include <libxml/parser.h>
35#include <libxml/xpath.h>
36#include <libxml/xpathInternals.h>
37}
38
39#include "cgic.h"
40#include "ulinet.h"
41
42#include <string.h>
43
44#include "service.h"
45#include "service_internal.h"
46
47
48#ifdef USE_PYTHON
49#include "service_internal_python.h"
50#endif
51
52#ifdef USE_JAVA
53#include "service_internal_java.h"
54#endif
55
56#ifdef USE_PHP
57#include "service_internal_php.h"
58#endif
59
60#ifdef USE_JS
61#include "service_internal_js.h"
62#endif
63
64#ifdef USE_PERL
65#include "service_internal_perl.h"
66#endif
67
68
69
70#include <dirent.h>
71#include <signal.h>
72#include <unistd.h>
73#ifndef WIN32
74#include <dlfcn.h>
75#include <libgen.h>
76#else
77#include <windows.h>
78#include <direct.h>
79#endif
80#include <fcntl.h>
81#include <time.h>
82#include <stdarg.h>
83
84xmlXPathObjectPtr extractFromDoc(xmlDocPtr doc,char* search){
85  xmlXPathContextPtr xpathCtx;
86  xmlXPathObjectPtr xpathObj;
87  xpathCtx = xmlXPathNewContext(doc);
88  xpathObj = xmlXPathEvalExpression(BAD_CAST search,xpathCtx);
89  xmlXPathFreeContext(xpathCtx);
90  return xpathObj;
91}
92
93void sig_handler(int sig){
94  char tmp[100];
95  char *ssig;
96  switch(sig){
97  case SIGSEGV:
98    ssig="SIGSEGV";
99    break;
100  case SIGTERM:
101    ssig="SIGTERM";
102    break;
103  case SIGINT:
104    ssig="SIGINT";
105    break;
106  case SIGILL:
107    ssig="SIGILL";
108    break;
109  case SIGFPE:
110    ssig="SIGFPE";
111    break;
112  case SIGABRT:
113    ssig="SIGABRT";
114    break;
115  default:
116    ssig="UNKNOWN";
117    break;
118  }
119  sprintf(tmp,"ZOO Kernel failed to process your request receiving signal %d = %s",sig,ssig);
120  errorException(NULL, tmp, "InternalError");
121#ifdef DEBUG
122  fprintf(stderr,"Not this time!\n");
123#endif
124  exit(0);
125}
126
127int runRequest(map* request_inputs)
128{
129
130  (void) signal(SIGSEGV,sig_handler);
131  (void) signal(SIGTERM,sig_handler);
132  (void) signal(SIGINT,sig_handler);
133  (void) signal(SIGILL,sig_handler);
134  (void) signal(SIGFPE,sig_handler);
135  (void) signal(SIGABRT,sig_handler);
136
137  map* r_inputs=NULL,*tmps=NULL;
138  maps* m=NULL;
139  int argc=count(request_inputs);
140
141  char* REQUEST=NULL;
142  /**
143   * Parsing service specfic configuration file
144   */
145  m=(maps*)calloc(1,MAPS_SIZE);
146  if(m == NULL){
147    return errorException(m, "Unable to allocate memory.", "InternalError");
148  }
149  char ntmp[1024];
150#ifndef WIN32
151  getcwd(ntmp,1024);
152#else
153  _getcwd(ntmp,1024);
154#endif
155  r_inputs=getMap(request_inputs,"metapath");
156  if(r_inputs==NULL){
157    if(request_inputs==NULL)
158      request_inputs=createMap("metapath","");
159    else
160      addToMap(request_inputs,"metapath","");
161#ifdef DEBUG
162    fprintf(stderr,"ADD METAPATH\n");
163    dumpMap(request_inputs);
164#endif
165    r_inputs=getMap(request_inputs,"metapath");
166  }
167  char conf_file[10240];
168  snprintf(conf_file,10240,"%s/%s/main.cfg",ntmp,r_inputs->value);
169  conf_read(conf_file,m);
170#ifdef DEBUG
171  fprintf(stderr, "***** BEGIN MAPS\n"); 
172  dumpMaps(m);
173  fprintf(stderr, "***** END MAPS\n");
174#endif
175
176  /**
177   * Check for minimum inputs
178   */
179  r_inputs=getMap(request_inputs,"Request");
180  if(request_inputs==NULL || r_inputs==NULL){ 
181    errorException(m, "Parameter <request> was not specified","MissingParameterValue");
182    freeMaps(&m);
183    free(m);
184    freeMap(&request_inputs);
185    free(request_inputs);
186    return 1;
187  }
188  else{
189    REQUEST=strdup(r_inputs->value);
190    if(strncasecmp(r_inputs->value,"GetCapabilities",15)!=0
191       && strncasecmp(r_inputs->value,"DescribeProcess",15)!=0
192       && strncasecmp(r_inputs->value,"Execute",7)!=0){ 
193      errorException(m, "Unenderstood <request> value. Please check that it was set to GetCapabilities, DescribeProcess or Execute.", "InvalidParameterValue");
194      freeMaps(&m);
195      free(m);
196      freeMap(&request_inputs);
197      free(request_inputs);
198      free(REQUEST);
199      return 1;
200    }
201  }
202  r_inputs=NULL;
203  r_inputs=getMap(request_inputs,"Service");
204  if(r_inputs==NULLMAP){
205    errorException(m, "Parameter <service> was not specified","MissingParameterValue");
206    freeMaps(&m);
207    free(m);
208    free(REQUEST);
209    return 1;
210  }
211  if(strncasecmp(REQUEST,"GetCapabilities",15)!=0){
212    r_inputs=getMap(request_inputs,"Version");
213    if(r_inputs==NULL){ 
214      errorException(m, "Parameter <version> was not specified","MissingParameterValue");
215      freeMaps(&m);
216      free(m);
217      free(REQUEST);
218      return 1;
219    }
220  }
221
222  r_inputs=getMap(request_inputs,"serviceprovider");
223  if(r_inputs==NULL){
224    addToMap(request_inputs,"serviceprovider","");
225  }
226
227  map* outputs=NULL;
228  maps* request_output_real_format=NULL;
229  map* tmpm=getMapFromMaps(m,"main","serverAddress");
230  if(tmpm!=NULL)
231    SERVICE_URL=strdup(tmpm->value);
232  else
233    SERVICE_URL=DEFAULT_SERVICE_URL;
234
235  service* s[100];
236  service* s1;
237  int scount=0;
238
239#ifdef DEBUG
240  dumpMap(r_inputs);
241#endif
242  char conf_dir[1024];
243  int t;
244  char tmps1[1024];
245
246  r_inputs=NULL;
247  r_inputs=getMap(request_inputs,"metapath");
248  if(r_inputs!=NULL)
249    snprintf(conf_dir,1024,"%s/%s",ntmp,r_inputs->value);
250  else
251    snprintf(conf_dir,1024,"%s",ntmp);
252
253  if(strncasecmp(REQUEST,"GetCapabilities",15)==0){
254    int i=0;
255    struct dirent *dp;
256#ifdef DEBUG
257    dumpMap(r_inputs);
258#endif
259    DIR *dirp = opendir(conf_dir);
260    if(dirp==NULL){
261      return errorException(m, "The specified path doesn't exist.","InvalidParameterValue");
262    }
263    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
264    r_inputs=NULL;
265    r_inputs=getMap(request_inputs,"ServiceProvider");
266    xmlNodePtr n;
267    //dumpMap(request_inputs);
268    if(r_inputs!=NULL)
269      n = printGetCapabilitiesHeader(doc,r_inputs->value,m);
270    else
271      n = printGetCapabilitiesHeader(doc,"",m);
272    /**
273     * Strange, here we need to close stdout to ensure that no uneeded
274     * char will be printed (parser issue ?)
275     */
276    int saved_stdout = dup(fileno(stdout));
277    dup2(fileno(stderr),fileno(stdout));
278    while ((dp = readdir(dirp)) != NULL)
279      if(strstr(dp->d_name,".zcfg")!=0){
280        memset(tmps1,0,1024);
281        snprintf(tmps1,1024,"%s/%s",conf_dir,dp->d_name);
282        s1=(service*)calloc(1,SERVICE_SIZE);
283        if(s1 == NULL){ 
284          return errorException(m, "Unable to allocate memory.","InternalError");
285        }
286#ifdef DEBUG
287        fprintf(stderr,"#################\n%s\n#################\n",tmps1);
288#endif
289        t=getServiceFromFile(tmps1,&s1);
290#ifdef DEBUG
291        dumpService(s1);
292        fflush(stdout);
293        fflush(stderr);
294#endif
295        printGetCapabilitiesForProcess(m,n,s1);
296        freeService(&s1);
297        free(s1);
298        scount++;
299      }
300    (void)closedir(dirp);
301    fflush(stdout);
302    dup2(saved_stdout,fileno(stdout));
303    printDocument(m,doc,getpid());
304    freeMaps(&m);
305    free(m);
306    free(REQUEST);
307    free(SERVICE_URL);
308    fflush(stdout);
309    return 0;
310  }
311  else{
312    r_inputs=getMap(request_inputs,"Identifier");
313    if(r_inputs==NULL 
314       || strlen(r_inputs->name)==0 || strlen(r_inputs->value)==0){ 
315      errorException(m, "Mandatory <identifier> was not specified","MissingParameterValue");
316      freeMaps(&m);
317      free(m);
318      free(REQUEST);
319      free(SERVICE_URL);
320      return 0;
321    }
322
323    struct dirent *dp;
324    DIR *dirp = opendir(conf_dir);
325    if(dirp==NULL){
326      errorException(m, "The specified path path doesn't exist.","InvalidParameterValue");
327      freeMaps(&m);
328      free(m);
329      free(REQUEST);
330      free(SERVICE_URL);
331      return 0;
332    }
333    if(strncasecmp(REQUEST,"DescribeProcess",15)==0){
334      /**
335       * Loop over Identifier list
336       */
337      xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
338      r_inputs=NULL;
339      r_inputs=getMap(request_inputs,"ServiceProvider");
340
341      xmlNodePtr n;
342      if(r_inputs!=NULL)
343        n = printDescribeProcessHeader(doc,r_inputs->value,m);
344      else
345        n = printDescribeProcessHeader(doc,"",m);
346
347      r_inputs=getMap(request_inputs,"Identifier");
348      char *tmps=strtok(r_inputs->value,",");
349     
350      char buff[256];
351      char buff1[1024];
352      int i=0;
353      int j=0;
354      int end=-1;
355      int saved_stdout = dup(fileno(stdout));
356      dup2(fileno(stderr),fileno(stdout));
357      while(tmps){
358        memset(buff,0,256);
359        snprintf(buff,256,"%s.zcfg",tmps);
360        memset(buff1,0,1024);
361#ifdef DEBUG
362        fprintf(stderr,"\n#######%s\n########\n",buff1);
363#endif
364        while ((dp = readdir(dirp)) != NULL)
365          if(strcmp(dp->d_name,buff)==0){
366            memset(buff1,0,1024);
367            snprintf(buff1,1024,"%s/%s",conf_dir,dp->d_name);
368            //s1=(service*)malloc(sizeof(service*));
369            s1=(service*)calloc(1,SERVICE_SIZE);
370            if(s1 == NULL){
371              return errorException(m, "Unable to allocate memory.","InternalError");
372            }
373#ifdef DEBUG
374            fprintf(stderr,"#################\n%s\n#################\n",buff1);
375#endif
376            t=getServiceFromFile(buff1,&s1);
377#ifdef DEBUG
378            dumpService(s1);
379#endif
380            printDescribeProcessForProcess(m,n,s1,1);
381            freeService(&s1);
382            free(s1);
383            scount++;
384          }
385        rewinddir(dirp);
386        tmps=strtok(NULL,",");
387      }
388      closedir(dirp);
389      fflush(stdout);
390      dup2(saved_stdout,fileno(stdout));
391      printDocument(m,doc,getpid());
392      freeMaps(&m);
393      free(m);
394      free(REQUEST);
395      free(SERVICE_URL);
396      fflush(stdout);
397      //xmlFree(n);
398#ifndef LINUX_FREE_ISSUE
399      if(s1)
400        free(s1);
401#endif
402      return 0;
403    }
404    else
405      if(strncasecmp(REQUEST,"Execute",strlen(REQUEST))!=0){
406        errorException(m, "Unenderstood <request> value. Please check that it was set to GetCapabilities, DescribeProcess or Execute.", "InvalidParameterValue");
407#ifdef DEBUG
408        fprintf(stderr,"No request found %s",REQUEST);
409#endif 
410        closedir(dirp);
411        free(s);
412        return 0;
413      }
414    closedir(dirp);
415  }
416 
417  s1=NULL;
418  s1=(service*)calloc(1,SERVICE_SIZE);
419  if(s1 == NULL){
420    return errorException(m, "Unable to allocate memory.","InternalError");
421  }
422  r_inputs=getMap(request_inputs,"MetaPath");
423  if(r_inputs!=NULL)
424    snprintf(tmps1,1024,"%s/%s",ntmp,r_inputs->value);
425  else
426    snprintf(tmps1,1024,"%s/",ntmp);
427  r_inputs=getMap(request_inputs,"Identifier");
428  char *ttmp=strdup(tmps1);
429  snprintf(tmps1,1024,"%s/%s.zcfg",ttmp,r_inputs->value);
430  free(ttmp);
431#ifdef DEBUG
432  fprintf(stderr,"Trying to load %s\n", tmps1);
433#endif
434  int saved_stdout = dup(fileno(stdout));
435  dup2(fileno(stderr),fileno(stdout));
436  t=getServiceFromFile(tmps1,&s1);
437  fflush(stdout);
438  dup2(saved_stdout,fileno(stdout));
439  if(t==22){
440    errorException(m, "The value for <indetifier> seems to be wrong. Please, ensure that the process exsits using the GetCapabilities request.", "InvalidParameterValue");
441    exit(0);
442  }
443  //s[0]=s1;
444
445#ifdef DEBUG
446  dumpService(s1);
447#endif
448  map* inputs=NULL;
449  elements* c_inputs=s1->inputs;
450  int j;
451 
452  /**
453   * Create the input maps data structure
454   */
455  int i=0;
456  HINTERNET hInternet;
457  HINTERNET res;
458  hInternet=InternetOpen(
459#ifndef WIN32
460                         (LPCTSTR)
461#endif
462                         "ZooWPSClient\0",
463                         INTERNET_OPEN_TYPE_PRECONFIG,
464                         NULL,NULL, 0);
465
466#ifndef WIN32
467  if(!CHECK_INET_HANDLE(hInternet))
468    fprintf(stderr,"WARNING : hInternet handle failed to initialize");
469#endif
470  maps* request_input_real_format=NULL;
471  maps* tmpmaps = request_input_real_format;
472  map* postRequest=NULL;
473  postRequest=getMap(request_inputs,"xrequest");
474  if(postRequest==NULLMAP){
475    /**
476     * Parsing outputs provided as KVP
477     */
478    r_inputs=NULL;
479#ifdef DEBUG
480    fprintf(stderr,"OUTPUT Parsing ... \n");
481#endif
482    r_inputs=getMap(request_inputs,"ResponseDocument"); 
483    if(r_inputs==NULL) r_inputs=getMap(request_inputs,"RawDataOutput");
484   
485    //#ifdef DEBUG
486    fprintf(stderr,"OUTPUT Parsing ... \n");
487    //#endif
488    if(r_inputs!=NULL){
489      //#ifdef DEBUG
490      fprintf(stderr,"OUTPUT Parsing start now ... \n");
491      //#endif
492      char current_output_as_string[10240];
493      char cursor_output[10240];
494      char *cotmp=strdup(r_inputs->value);
495      snprintf(cursor_output,10240,"%s",cotmp);
496      free(cotmp);
497      j=0;
498      map* request_kvp_outputs=NULL;
499       
500      /**
501       * Put each Output into the outputs_as_text array
502       */
503      char * pToken;
504      maps* tmp_output=NULL;
505#ifdef DEBUG
506      fprintf(stderr,"OUTPUT [%s]\n",cursor_output);
507#endif
508      pToken=strtok(cursor_output,";");
509      char** outputs_as_text=(char**)calloc(128,sizeof(char*));
510      if(outputs_as_text == NULL) {
511        return errorException(m, "Unable to allocate memory", "InternalError");
512      }
513      i=0;
514      while(pToken!=NULL){
515#ifdef DEBUG
516        fprintf(stderr,"***%s***\n",pToken);
517        fflush(stderr);
518        fprintf(stderr,"***%s***\n",pToken);
519#endif
520        outputs_as_text[i]=(char*)calloc(strlen(pToken)+1,sizeof(char));
521        if(outputs_as_text[i] == NULL) {
522          return errorException(m, "Unable to allocate memory", "InternalError");
523        }
524        snprintf(outputs_as_text[i],strlen(pToken)+1,"%s",pToken);
525        pToken = strtok(NULL,";");
526        i++;
527      }
528      for(j=0;j<i;j++){
529        char *tmp=strdup(outputs_as_text[j]);
530        free(outputs_as_text[j]);
531        char *tmpc;
532        tmpc=strtok(tmp,"@");
533        int k=0;
534        while(tmpc!=NULL){
535          if(k==0){
536            if(tmp_output==NULL){
537              tmp_output=(maps*)calloc(1,MAPS_SIZE);
538              if(tmp_output == NULL){
539                return errorException(m, "Unable to allocate memory.", "InternalError");
540              }
541              tmp_output->name=strdup(tmpc);
542              tmp_output->content=NULL;
543              tmp_output->next=NULL;
544            }
545          }
546          else{
547            char *tmpv=strstr(tmpc,"=");
548            char tmpn[256];
549            memset(tmpn,0,256);
550            strncpy(tmpn,tmpc,(strlen(tmpc)-strlen(tmpv))*sizeof(char));
551            tmpn[strlen(tmpc)-strlen(tmpv)]=0;
552#ifdef DEBUG
553            fprintf(stderr,"OUTPUT DEF [%s]=[%s]\n",tmpn,tmpv+1);
554#endif
555            if(tmp_output->content==NULL){
556              tmp_output->content=createMap(tmpn,tmpv+1);
557              tmp_output->content->next=NULL;
558            }
559            else
560              addToMap(tmp_output->content,tmpn,tmpv+1);
561          }
562          k++;
563#ifdef DEBUG
564          fprintf(stderr,"***%s***\n",tmpc);
565#endif
566          tmpc=strtok(NULL,"@");
567        }
568        if(request_output_real_format==NULL)
569          request_output_real_format=dupMaps(&tmp_output);
570        else
571          addMapsToMaps(&request_output_real_format,tmp_output);
572        freeMaps(&tmp_output);
573        free(tmp_output);
574        tmp_output=NULL;
575#ifdef DEBUG
576        dumpMaps(tmp_output);
577        fflush(stderr);
578#endif
579        //tmp_output=tmp_output->next;
580        free(tmp);
581      }
582      free(outputs_as_text);
583    }
584
585
586    /**
587     * Parsing inputs provided as KVP
588     */
589    r_inputs=getMap(request_inputs,"DataInputs");
590#ifdef DEBUG
591    fprintf(stderr,"DATA INPUTS [%s]\n",r_inputs->value);
592#endif
593    char current_input_as_string[40960];
594    char cursor_input[40960];
595    if(r_inputs!=NULL)
596      snprintf(cursor_input,40960,"%s",r_inputs->value);
597    else{
598      errorException(m, "Parameter <DataInputs> was not specified","MissingParameterValue");
599      freeMaps(&m);
600      free(m);
601      free(REQUEST);
602      free(SERVICE_URL);
603      return 0;
604    }
605    j=0;
606    map* request_kvp_inputs=NULL;
607 
608    /**
609     * Put each DataInputs into the inputs_as_text array
610     */
611    char * pToken;
612    pToken=strtok(cursor_input,";");
613    char** inputs_as_text=(char**)calloc(100,sizeof(char*));
614    if(inputs_as_text == NULL){
615      return errorException(m, "Unable to allocate memory.", "InternalError");
616    }
617    i=0;
618    while(pToken!=NULL){
619#ifdef DEBUG
620      fprintf(stderr,"***%s***\n",pToken);
621#endif
622      fflush(stderr);
623#ifdef DEBUG
624      fprintf(stderr,"***%s***\n",pToken);
625#endif
626      inputs_as_text[i]=(char*)calloc(strlen(pToken)+1,sizeof(char));
627      snprintf(inputs_as_text[i],strlen(pToken)+1,"%s",pToken);
628      if(inputs_as_text[i] == NULL){
629        return errorException(m, "Unable to allocate memory.", "InternalError");
630      }
631      pToken = strtok(NULL,";");
632      i++;
633    }
634
635    for(j=0;j<i;j++){
636      char *tmp=strdup(inputs_as_text[j]);
637      free(inputs_as_text[j]);
638      char *tmpc;
639      tmpc=strtok(tmp,"@");
640      while(tmpc!=NULL){
641#ifdef DEBUG
642        fprintf(stderr,"***\n***%s***\n",tmpc);
643#endif
644        char *tmpv=strstr(tmpc,"=");
645        char tmpn[256];
646        memset(tmpn,0,256);
647        strncpy(tmpn,tmpc,(strlen(tmpc)-strlen(tmpv))*sizeof(char));
648        tmpn[strlen(tmpc)-strlen(tmpv)]=0;
649        int cnt=0;
650#ifdef DEBUG
651        fprintf(stderr,"***\n*** %s = %s ***\n",tmpn,tmpv+1);
652#endif
653        if(tmpmaps==NULL){
654          tmpmaps=(maps*)calloc(1,MAPS_SIZE);
655          if(tmpmaps == NULL){
656            return errorException(m, "Unable to allocate memory.", "InternalError");
657          }
658          tmpmaps->name=strdup(tmpn);
659          tmpmaps->content=createMap("value",tmpv+1);
660          tmpmaps->next=NULL;
661        }
662        tmpc=strtok(NULL,"@");
663        while(tmpc!=NULL){
664#ifdef DEBUG
665          fprintf(stderr,"*** KVP NON URL-ENCODED \n***%s***\n",tmpc);
666#endif
667          char *tmpv1=strstr(tmpc,"=");
668#ifdef DEBUG
669          fprintf(stderr,"*** VALUE NON URL-ENCODED \n***%s***\n",tmpv1+1);
670#endif
671          char tmpn1[1024];
672          memset(tmpn1,0,1024);
673          strncpy(tmpn1,tmpc,strlen(tmpc)-strlen(tmpv1));
674          tmpn1[strlen(tmpc)-strlen(tmpv1)]=0;
675#ifdef DEBUG
676          fprintf(stderr,"*** NAME NON URL-ENCODED \n***%s***\n",tmpn1);
677          fprintf(stderr,"*** VALUE NON URL-ENCODED \n***%s***\n",tmpv1+1);
678#endif
679          if(strcmp(tmpn1,"xlink:href")!=0)
680            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
681          else{
682#ifdef DEBUG
683            fprintf(stderr,"REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n",tmpv1+1);
684#endif
685#ifndef WIN32
686            if(CHECK_INET_HANDLE(hInternet))
687#endif
688              {
689                res=InternetOpenUrl(hInternet,tmpv1+1,NULL,0,
690                                    INTERNET_FLAG_NO_CACHE_WRITE,0);
691#ifdef DEBUG
692                fprintf(stderr,"(%s) content-length : %d,,res.nDataAlloc %d \n",
693                        tmpv1+1,res.nDataAlloc,res.nDataLen);
694#endif
695                char* tmpContent=(char*)calloc((res.nDataLen+1),sizeof(char));
696                if(tmpContent == NULL){
697                  return errorException(m, "Unable to allocate memory.", "InternalError");
698                }
699                size_t dwRead;
700                InternetReadFile(res, (LPVOID)tmpContent,res.nDataLen, &dwRead);
701                map* tmpMap=getMap(tmpmaps->content,"value");
702                if(tmpMap!=NULL)
703                  tmpMap->value=strdup(tmpContent);
704                free(tmpContent);
705              }
706            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
707          }
708          tmpc=strtok(NULL,"@");
709        }
710#ifdef DEBUG
711        dumpMaps(tmpmaps);
712        fflush(stderr);
713#endif
714        if(request_input_real_format==NULL)
715          request_input_real_format=dupMaps(&tmpmaps);
716        else
717          addMapsToMaps(&request_input_real_format,tmpmaps);
718        /*freeMap(&tmpmaps->content);
719        free(tmpmaps->content);
720        tmpmaps->content=NULL;*/
721        freeMaps(&tmpmaps);
722        free(tmpmaps);
723          //}
724        tmpmaps=NULL;
725        free(tmp);
726      }
727    }
728    free(inputs_as_text);
729  }
730  else {
731    /**
732     * Parse XML request
733     */ 
734    xmlInitParser();
735#ifdef DEBUG
736    fflush(stderr);
737    fprintf(stderr,"BEFORE %s\n",postRequest->value);
738    fflush(stderr);
739#endif
740    xmlDocPtr doc =
741      xmlParseMemory(postRequest->value,cgiContentLength);
742#ifdef DEBUG
743    fprintf(stderr,"AFTER\n");
744    fflush(stderr);
745#endif
746    xmlNodePtr cur = xmlDocGetRootElement(doc);
747    /**
748     * Parse every Input in DataInputs node.
749     */
750    maps* tempMaps=NULL;
751    xmlXPathObjectPtr tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='Input']");
752    xmlNodeSet* tmps=tmpsptr->nodesetval;
753#ifdef DEBUG
754    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
755#endif
756    for(int k=0;k<tmps->nodeNr;k++){
757      maps *tmpmaps=NULL;
758      xmlNodePtr cur=tmps->nodeTab[k];
759      if(tmps->nodeTab[k]->type == XML_ELEMENT_NODE) {
760        /**
761         * A specific Input node.
762         */
763#ifdef DEBUG
764        fprintf(stderr, "= element 0 node \"%s\"\n", cur->name);
765#endif
766        xmlNodePtr cur2=cur->children;
767        while(cur2){
768          while(cur2->type!=XML_ELEMENT_NODE)
769            cur2=cur2->next;
770          /**
771           * Indentifier
772           */
773          if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
774            xmlChar *val= xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
775            if(tmpmaps==NULL){
776              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
777              if(tmpmaps == NULL){
778                return errorException(m, "Unable to allocate memory.", "InternalError");
779              }
780              tmpmaps->name=strdup((char*)val);
781              tmpmaps->content=NULL;
782              tmpmaps->next=NULL;
783            }
784            xmlFree(val);
785          }
786          /**
787           * Title, Asbtract
788           */
789          if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
790             xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
791            xmlChar *val=
792              xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
793            if(tmpmaps==NULL){
794              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
795              if(tmpmaps == NULL){
796                return errorException(m, "Unable to allocate memory.", "InternalError");
797              }
798              tmpmaps->name="missingIndetifier";
799              tmpmaps->content=createMap((char*)cur2->name,(char*)val);
800              tmpmaps->next=NULL;
801            }
802            else{
803              if(tmpmaps->content!=NULL)
804                addToMap(tmpmaps->content,
805                         (char*)cur2->name,(char*)val);
806              else
807                tmpmaps->content=
808                  createMap((char*)cur2->name,(char*)val);
809            }
810#ifdef DEBUG
811            dumpMaps(tmpmaps);
812#endif
813            xmlFree(val);
814          }
815          /**
816           * InputDataFormChoice (Reference or Data ?)
817           */
818          if(xmlStrcasecmp(cur2->name,BAD_CAST "Reference")==0){
819            /**
820             * Get every attribute from a Reference node
821             * mimeType, encoding, schema, href, method
822             * Header and Body gesture should be added here
823             */
824#ifdef DEBUG
825            fprintf(stderr,"REFERENCE\n");
826#endif
827            map* referenceMap=NULL;
828            char *refs[5];
829            refs[0]="mimeType";
830            refs[1]="encoding";
831            refs[2]="schema";
832            refs[3]="method";
833            refs[4]="href";
834            char*url;
835            for(int l=0;l<5;l++){
836#ifdef DEBUG
837              fprintf(stderr,"*** %s ***",refs[l]);
838#endif
839              xmlChar *val=xmlGetProp(cur2,BAD_CAST refs[l]);
840              if(val!=NULL && xmlStrlen(val)>0){
841                if(tmpmaps->content!=NULL)
842                  addToMap(tmpmaps->content,refs[l],(char*)val);
843                else
844                  tmpmaps->content=createMap(refs[l],(char*)val);
845                map* ltmp=getMap(tmpmaps->content,"method");
846                if(l==4){
847                  if(!(ltmp!=NULL && strcmp(ltmp->value,"POST")==0)
848                     && CHECK_INET_HANDLE(hInternet)){
849                    res=InternetOpenUrl(hInternet,(char*)val,NULL,0,
850                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
851                    char* tmpContent=
852                      (char*)calloc((res.nDataLen+1),sizeof(char));
853                    if(tmpContent == NULL){
854                      return errorException(m, "Unable to allocate memory.", "InternalError");
855                    }
856                    size_t dwRead;
857                    InternetReadFile(res, (LPVOID)tmpContent,
858                                     res.nDataLen, &dwRead);
859                    tmpContent[res.nDataLen]=0;
860                    addToMap(tmpmaps->content,"value",tmpContent);
861                  }
862                }
863              }
864#ifdef DEBUG
865              fprintf(stderr,"%s\n",val);
866#endif
867              xmlFree(val);
868            }
869#ifdef POST_DEBUG
870            fprintf(stderr,"Parse Header and Body from Reference \n");
871#endif
872            xmlNodePtr cur3=cur2->children;
873            hInternet.header=NULL;
874            while(cur3){
875              if(xmlStrcasecmp(cur3->name,BAD_CAST "Header")==0 ){
876                xmlNodePtr cur4=cur3;
877                char *tmp=new char[cgiContentLength];
878                char *ha[2];
879                ha[0]="key";
880                ha[1]="value";
881                int hai;
882                char *has;
883                char *key;
884                for(hai=0;hai<2;hai++){
885                  xmlChar *val=xmlGetProp(cur3,BAD_CAST ha[hai]);
886#ifdef POST_DEBUG
887                  fprintf(stderr,"%s = %s\n",ha[hai],(char*)val);
888#endif
889                  if(hai==0){
890                    key=(char*)calloc((1+strlen((char*)val)),sizeof(char));
891                    snprintf(key,1+strlen((char*)val),"%s",(char*)val);
892                  }else{
893                    has=(char*)calloc((3+strlen((char*)val)+strlen(key)),sizeof(char));
894                    if(has == NULL){
895                      return errorException(m, "Unable to allocate memory.", "InternalError");
896                    }
897                    snprintf(has,(3+strlen((char*)val)+strlen(key)),"%s: %s",key,(char*)val);
898#ifdef POST_DEBUG
899                    fprintf(stderr,"%s\n",has);
900#endif
901                  }
902                }
903                hInternet.header=curl_slist_append(hInternet.header, has);
904                //free(has);
905              }
906              else{
907#ifdef POST_DEBUG
908                fprintf(stderr,"Try to fetch the body part of the request ...\n");
909#endif
910                if(xmlStrcasecmp(cur3->name,BAD_CAST "Body")==0 ){
911#ifdef POST_DEBUG
912                  fprintf(stderr,"Body part found !!!\n",(char*)cur3->content);
913#endif
914                  char *tmp=new char[cgiContentLength];
915                  memset(tmp,0,cgiContentLength);
916                  xmlNodePtr cur4=cur3->children;
917                  while(cur4!=NULL){
918                    xmlDocPtr bdoc = xmlNewDoc(BAD_CAST "1.0");
919                    bdoc->encoding = xmlCharStrdup ("UTF-8");
920                    xmlDocSetRootElement(bdoc,cur4);
921                    xmlChar* btmps;
922                    int bsize;
923                    xmlDocDumpMemory(bdoc,&btmps,&bsize);
924#ifdef POST_DEBUG
925                    fprintf(stderr,"Body part found !!! %s %s\n",tmp,(char*)btmps);
926#endif
927                    if(btmps!=NULL)
928                      sprintf(tmp,"%s",(char*)btmps);
929                    xmlFreeDoc(bdoc);
930                    cur4=cur4->next;
931                  }
932                  map *btmp=getMap(tmpmaps->content,"href");
933                  if(btmp!=NULL){
934#ifdef POST_DEBUG
935                    fprintf(stderr,"%s %s\n",btmp->value,tmp);
936                    curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
937#endif
938                    res=InternetOpenUrl(hInternet,btmp->value,tmp,strlen(tmp),
939                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
940                    char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
941                    if(tmpContent == NULL){
942                      return errorException(m, "Unable to allocate memory.", "InternalError");
943                    }
944                    size_t dwRead;
945                    InternetReadFile(res, (LPVOID)tmpContent,
946                                     res.nDataLen, &dwRead);
947                    tmpContent[res.nDataLen]=0;
948                    if(hInternet.header!=NULL)
949                      curl_slist_free_all(hInternet.header);
950                    addToMap(tmpmaps->content,"value",tmpContent);
951#ifdef POST_DEBUG
952                    fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
953#endif
954                  }
955                }
956                else
957                  if(xmlStrcasecmp(cur3->name,BAD_CAST "BodyReference")==0 ){
958                    xmlChar *val=xmlGetProp(cur3,BAD_CAST "href");
959                    HINTERNET bInternet,res1;
960                    bInternet=InternetOpen(
961#ifndef WIN32
962                                           (LPCTSTR)
963#endif
964                                           "ZooWPSClient\0",
965                                           INTERNET_OPEN_TYPE_PRECONFIG,
966                                           NULL,NULL, 0);
967                    if(!CHECK_INET_HANDLE(bInternet))
968                      fprintf(stderr,"WARNING : hInternet handle failed to initialize");
969#ifdef POST_DEBUG
970                    curl_easy_setopt(bInternet.handle, CURLOPT_VERBOSE, 1);
971#endif
972                    res1=InternetOpenUrl(bInternet,(char*)val,NULL,0,
973                                         INTERNET_FLAG_NO_CACHE_WRITE,0);
974                    char* tmp=
975                      (char*)calloc((res1.nDataLen+1),sizeof(char));
976                    if(tmp == NULL){
977                      return errorException(m, "Unable to allocate memory.", "InternalError");
978                    }
979                    size_t bRead;
980                    InternetReadFile(res1, (LPVOID)tmp,
981                                     res1.nDataLen, &bRead);
982                    tmp[res1.nDataLen]=0;
983                    InternetCloseHandle(bInternet);
984                    map *btmp=getMap(tmpmaps->content,"href");
985                    if(btmp!=NULL){
986#ifdef POST_DEBUG
987                      fprintf(stderr,"%s %s\n",btmp->value,tmp);
988                      curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
989#endif
990                      res=InternetOpenUrl(hInternet,btmp->value,tmp,
991                                          strlen(tmp),
992                                          INTERNET_FLAG_NO_CACHE_WRITE,0);
993                      char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
994                      if(tmpContent == NULL){
995                        return errorException(m, "Unable to allocate memory.", "InternalError");
996                      }
997                      size_t dwRead;
998                      InternetReadFile(res, (LPVOID)tmpContent,
999                                       res.nDataLen, &dwRead);
1000                      tmpContent[res.nDataLen]=0;
1001                      if(hInternet.header!=NULL)
1002                        curl_slist_free_all(hInternet.header);
1003                      addToMap(tmpmaps->content,"value",tmpContent);
1004#ifdef POST_DEBUG
1005                      fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1006#endif
1007                    }
1008                  }
1009              }
1010              cur3=cur3->next;
1011            }
1012#ifdef POST_DEBUG
1013            fprintf(stderr,"Header and Body was parsed from Reference \n");
1014#endif
1015#ifdef DEBUG
1016            dumpMap(tmpmaps->content);
1017            fprintf(stderr, "= element 2 node \"%s\" = (%s)\n", 
1018                    cur2->name,cur2->content);
1019#endif
1020          }
1021          else if(xmlStrcasecmp(cur2->name,BAD_CAST "Data")==0){
1022#ifdef DEBUG
1023            fprintf(stderr,"DATA\n");
1024#endif
1025            xmlNodePtr cur4=cur2->children;
1026            while(cur4){
1027              while(cur4->type!=XML_ELEMENT_NODE)
1028                cur4=cur4->next;
1029
1030              if(xmlStrcasecmp(cur4->name, BAD_CAST "LiteralData")==0){
1031                /**
1032                 * Get every attribute from a LiteralData node
1033                 * dataType , uom
1034                 */
1035                char *lits[2];
1036                lits[0]="dataType";
1037                lits[1]="uom";
1038                for(int l=0;l<2;l++){
1039#ifdef DEBUG
1040                  fprintf(stderr,"*** LiteralData %s ***",lits[l]);
1041#endif
1042                  xmlChar *val=xmlGetProp(cur4,BAD_CAST lits[l]);
1043                  if(val!=NULL && strlen((char*)val)>0){
1044                    if(tmpmaps->content!=NULL)
1045                      addToMap(tmpmaps->content,lits[l],(char*)val);
1046                    else
1047                      tmpmaps->content=createMap(lits[l],(char*)val);
1048                  }
1049#ifdef DEBUG
1050                  fprintf(stderr,"%s\n",val);
1051#endif
1052                  xmlFree(val);
1053                }
1054              }
1055              else if(xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0){
1056                /**
1057                 * Get every attribute from a Reference node
1058                 * mimeType, encoding, schema
1059                 */
1060                char *coms[3];
1061                coms[0]="mimeType";
1062                coms[1]="encoding";
1063                coms[2]="schema";
1064                for(int l=0;l<3;l++){
1065#ifdef DEBUG
1066                  fprintf(stderr,"*** ComplexData %s ***",coms[l]);
1067#endif
1068                  xmlChar *val=xmlGetProp(cur4,BAD_CAST coms[l]);
1069                  if(val!=NULL && strlen((char*)val)>0){
1070                    if(tmpmaps->content!=NULL)
1071                      addToMap(tmpmaps->content,coms[l],(char*)val);
1072                    else
1073                      tmpmaps->content=createMap(coms[l],(char*)val);
1074                  }
1075#ifdef DEBUG
1076                  fprintf(stderr,"%s\n",val);
1077#endif
1078                  xmlFree(val);
1079                }
1080              }
1081              xmlChar* mv=xmlNodeListGetString(doc,cur4->xmlChildrenNode,1);
1082              addToMap(tmpmaps->content,"value",(char*)mv);
1083              xmlFree(mv);
1084              cur4=cur4->next;
1085            }
1086          }
1087#ifdef DEBUG
1088          fprintf(stderr,"cur2 next \n");
1089          fflush(stderr);
1090#endif
1091          cur2=cur2->next;
1092        }
1093#ifdef DEBUG
1094        fprintf(stderr,"ADD MAPS TO REQUEST MAPS !\n");
1095        fflush(stderr);
1096#endif
1097        addMapsToMaps(&request_input_real_format,tmpmaps);
1098       
1099#ifdef DEBUG
1100        fprintf(stderr,"******TMPMAPS*****\n");
1101        dumpMaps(tmpmaps);
1102        fprintf(stderr,"******REQUESTMAPS*****\n");
1103        dumpMaps(request_input_real_format);
1104#endif
1105        tmpmaps=tmpmaps->next;
1106             
1107      }
1108#ifdef DEBUG
1109      dumpMaps(tmpmaps); 
1110#endif
1111    }
1112#ifdef DEBUG
1113    fprintf(stderr,"Search for response document node\n");
1114#endif
1115    xmlXPathFreeObject(tmpsptr);
1116    //xmlFree(tmps);
1117    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='ResponseDocument']");
1118    tmps=tmpsptr->nodesetval;
1119#ifdef DEBUG
1120    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1121#endif
1122    for(int k=0;k<tmps->nodeNr;k++){
1123      addToMap(request_inputs,"ResponseDocument","");
1124      request_output_real_format;
1125      maps *tmpmaps=NULL;
1126      xmlNodePtr cur=tmps->nodeTab[k];
1127      if(cur->type == XML_ELEMENT_NODE) {
1128        /**
1129         * A specific responseDocument node.
1130         */
1131        if(tmpmaps==NULL){
1132          tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1133          if(tmpmaps == NULL){
1134            return errorException(m, "Unable to allocate memory.", "InternalError");
1135          }
1136          tmpmaps->name="unknownIdentifier";
1137          tmpmaps->next=NULL;
1138        }
1139        /**
1140         * Get every attribute from a LiteralData node
1141         * storeExecuteResponse, lineage, status
1142         */
1143        char *ress[3];
1144        ress[0]="storeExecuteResponse";
1145        ress[1]="lineage";
1146        ress[2]="status";
1147        xmlChar *val;
1148        for(int l=0;l<3;l++){
1149#ifdef DEBUG
1150          fprintf(stderr,"*** %s ***\t",ress[l]);
1151#endif
1152          val=xmlGetProp(cur,BAD_CAST ress[l]);
1153          if(val!=NULL && strlen((char*)val)>0){
1154            if(tmpmaps->content!=NULL)
1155              addToMap(tmpmaps->content,ress[l],(char*)val);
1156            else
1157              tmpmaps->content=createMap(ress[l],(char*)val);
1158            addToMap(request_inputs,ress[l],(char*)val);
1159          }
1160#ifdef DEBUG
1161          fprintf(stderr,"%s\n",val);
1162#endif
1163          xmlFree(val);
1164        }
1165        xmlNodePtr cur1=cur->children;
1166        while(cur1){
1167          if(xmlStrncasecmp(cur1->name,BAD_CAST "Output",xmlStrlen(cur1->name))==0){
1168            /**
1169             * Get every attribute from a Output node
1170             * mimeType, encoding, schema, uom, asReference
1171             */
1172            char *outs[5];
1173            outs[0]="mimeType";
1174            outs[1]="encoding";
1175            outs[2]="schema";
1176            outs[3]="uom";
1177            outs[4]="asReference";
1178            for(int l=0;l<5;l++){
1179#ifdef DEBUG
1180              fprintf(stderr,"*** %s ***\t",outs[l]);
1181#endif
1182              val=xmlGetProp(cur1,BAD_CAST outs[l]);
1183              if(val!=NULL && strlen((char*)val)>0){
1184                if(tmpmaps->content!=NULL)
1185                  addToMap(tmpmaps->content,outs[l],(char*)val);
1186                else
1187                  tmpmaps->content=createMap(outs[l],(char*)val);
1188              }
1189#ifdef DEBUG
1190              fprintf(stderr,"%s\n",val);
1191#endif
1192              xmlFree(val);
1193            }
1194           
1195            xmlNodePtr cur2=cur1->children;
1196            while(cur2){
1197              /**
1198               * Indentifier
1199               */
1200              if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1201                xmlChar *val=
1202                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1203                if(tmpmaps==NULL){
1204                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1205                  if(tmpmaps == NULL){
1206                    return errorException(m, "Unable to allocate memory.", "InternalError");
1207                  }
1208                  tmpmaps->name=strdup((char*)val);
1209                  tmpmaps->content=NULL;
1210                  tmpmaps->next=NULL;
1211                }
1212                else
1213                  tmpmaps->name=strdup((char*)val);;
1214                xmlFree(val);
1215              }
1216              /**
1217               * Title, Asbtract
1218               */
1219              if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1220                 xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1221                xmlChar *val=
1222                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1223                if(tmpmaps==NULL){
1224                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1225                  if(tmpmaps == NULL){
1226                    return errorException(m, "Unable to allocate memory.", "InternalError");
1227                  }
1228                  tmpmaps->name="missingIndetifier";
1229                  tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1230                  tmpmaps->next=NULL;
1231                }
1232                else{
1233                  if(tmpmaps->content!=NULL)
1234                    addToMap(tmpmaps->content,
1235                             (char*)cur2->name,(char*)val);
1236                  else
1237                    tmpmaps->content=
1238                      createMap((char*)cur2->name,(char*)val);
1239                }
1240                xmlFree(val);
1241              }
1242              cur2=cur2->next;
1243            }
1244          }
1245          cur1=cur1->next;
1246        }
1247      }
1248      //xmlFree(cur);
1249      if(request_output_real_format==NULL)
1250        request_output_real_format=tmpmaps;
1251      else
1252        addMapsToMaps(&request_output_real_format,tmpmaps);
1253#ifdef DEBUG
1254      dumpMaps(tmpmaps);
1255#endif
1256    }
1257    xmlXPathFreeObject(tmpsptr);
1258    //xmlFree(tmps);
1259    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='RawDataOutput']");
1260    tmps=tmpsptr->nodesetval;
1261#ifdef DEBUG
1262    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1263#endif
1264    for(int k=0;k<tmps->nodeNr;k++){
1265      addToMap(request_inputs,"RawDataOutput","");
1266      xmlNodePtr cur1=tmps->nodeTab[k];
1267      xmlChar *val;
1268      /**
1269       * Get every attribute from a Output node
1270       * mimeType, encoding, schema, uom, asReference
1271       */
1272      char *outs[4];
1273      outs[0]="mimeType";
1274      outs[1]="encoding";
1275      outs[2]="schema";
1276      outs[3]="uom";
1277      for(int l=0;l<4;l++){
1278#ifdef DEBUG
1279        fprintf(stderr,"*** %s ***\t",outs[l]);
1280#endif
1281        val=xmlGetProp(cur1,BAD_CAST outs[l]);
1282        if(val!=NULL && strlen((char*)val)>0){
1283          if(tmpmaps==NULL){
1284            tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1285            if(tmpmaps == NULL){
1286              return errorException(m, "Unable to allocate memory.", "InternalError");
1287            }
1288            tmpmaps->name="unknownIdentifier";
1289            tmpmaps->content=createMap(outs[l],(char*)val);
1290            tmpmaps->next=NULL;
1291          }
1292          else
1293            addToMap(tmpmaps->content,outs[l],(char*)val);
1294        }
1295#ifdef DEBUG
1296        fprintf(stderr,"%s\n",val);
1297#endif
1298        xmlFree(val);
1299      }
1300           
1301      xmlNodePtr cur2=cur1->children;
1302      while(cur2){
1303        /**
1304         * Indentifier
1305         */
1306        if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1307          val=
1308            xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1309          if(tmpmaps==NULL){
1310            tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1311            if(tmpmaps == NULL){
1312              return errorException(m, "Unable to allocate memory.", "InternalError");
1313            }
1314            tmpmaps->name=strdup((char*)val);
1315            tmpmaps->content=NULL;
1316            tmpmaps->next=NULL;
1317          }
1318          else
1319            tmpmaps->name=strdup((char*)val);;
1320          xmlFree(val);
1321        }
1322        cur2=cur2->next;
1323      }
1324      if(request_output_real_format==NULL)
1325        request_output_real_format=tmpmaps;
1326      else
1327        addMapsToMaps(&request_output_real_format,tmpmaps);
1328#ifdef DEBUG
1329      dumpMaps(tmpmaps);
1330#endif
1331    }
1332    xmlXPathFreeObject(tmpsptr);
1333    //xmlFree(tmps);
1334    xmlCleanupParser();
1335  }
1336
1337  //if(CHECK_INET_HANDLE(hInternet))
1338  InternetCloseHandle(hInternet);
1339
1340#ifdef DEBUG
1341  fprintf(stderr,"\n%i\n",i);
1342  dumpMaps(request_input_real_format);
1343  dumpMaps(request_output_real_format);
1344  dumpMap(request_inputs);
1345#endif
1346
1347  /**
1348   * Ensure that each requested arguments are present in the request
1349   * DataInputs and ResponseDocument / RawDataOutput
1350   */ 
1351  char *dfv=addDefaultValues(&request_input_real_format,s1->inputs,m,"inputs");
1352  if(strcmp(dfv,"")!=0){
1353    char tmps[1024];
1354    snprintf(tmps,1024,"The <%s> argument was not specified in DataInputs but defined as requested in ZOO ServicesProvider configuration file, please correct your query or the ZOO Configuration file.",dfv);
1355    map* tmpe=createMap("text",tmps);
1356    addToMap(tmpe,"code","MissingParameterValue");
1357    printExceptionReportResponse(m,tmpe);
1358    freeMap(&tmpe);
1359    free(tmpe);
1360    freeMaps(&m);
1361    free(m);
1362    free(REQUEST);
1363    freeMaps(&request_input_real_format);
1364    free(request_input_real_format);
1365    freeMaps(&request_output_real_format);
1366    free(request_output_real_format);
1367    freeMaps(&tmpmaps);
1368    free(tmpmaps);
1369    return 1;
1370  }
1371  addDefaultValues(&request_output_real_format,s1->outputs,m,"outputs");
1372
1373#ifdef DEBUG
1374  fprintf(stderr,"REQUEST_INPUTS\n");
1375  dumpMaps(request_input_real_format);
1376  fprintf(stderr,"REQUEST_OUTPUTS\n");
1377  dumpMaps(request_output_real_format);
1378#endif
1379
1380  maps* curs=getMaps(m,"env");
1381  if(curs!=NULL){
1382    map* mapcs=curs->content;
1383    while(mapcs!=NULLMAP){
1384#ifndef WIN32
1385      setenv(mapcs->name,mapcs->value,1);
1386#else
1387#ifdef DEBUG
1388      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1389#endif
1390      if(mapcs->value[strlen(mapcs->value)-2]=='\r'){
1391#ifdef DEBUG
1392        fprintf(stderr,"[ZOO: Env var finish with \r]\n");
1393#endif
1394        mapcs->value[strlen(mapcs->value)-1]=0;
1395      }
1396#ifdef DEBUG
1397      fflush(stderr);
1398      fprintf(stderr,"setting variable... %s\n",
1399#endif
1400              SetEnvironmentVariable(mapcs->name,mapcs->value)
1401#ifdef DEBUG
1402              ? "OK" : "FAILED");
1403#else
1404      ;
1405#endif
1406#ifdef DEBUG
1407      fflush(stderr);
1408#endif
1409#endif
1410#ifdef DEBUG
1411      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1412      fflush(stderr);
1413#endif
1414      mapcs=mapcs->next;
1415    }
1416  }
1417 
1418#ifdef DEBUG
1419  dumpMap(request_inputs);
1420#endif
1421
1422  /**
1423   * Need to check if we need to fork to load a status enabled
1424   */
1425  r_inputs=NULL;
1426  r_inputs=getMap(request_inputs,"storeExecuteResponse");
1427  int eres=SERVICE_STARTED;
1428  int cpid=getpid();
1429#ifdef DEBUG
1430  dumpMap(request_inputs);
1431#endif
1432
1433  if(r_inputs!=NULL)
1434    if(strcasecmp(r_inputs->value,"false")==0)
1435      r_inputs=NULL;
1436  if(r_inputs==NULLMAP){
1437    /**
1438     * Extract serviceType to know what kind of service shoudl be loaded
1439     */
1440    r_inputs=NULL;
1441    r_inputs=getMap(s1->content,"serviceType");
1442#ifdef DEBUG
1443    fprintf(stderr,"LOAD A %s SERVICE PROVIDER IN NORMAL MODE \n",r_inputs->value);
1444    fflush(stderr);
1445#endif
1446    if(strncasecmp(r_inputs->value,"C",1)==0){
1447      r_inputs=getMap(request_inputs,"metapath");
1448      if(r_inputs!=NULL)
1449        sprintf(tmps1,"%s/%s",ntmp,r_inputs->value);
1450      else
1451        sprintf(tmps1,"%s/",ntmp);
1452      char *altPath=strdup(tmps1);
1453      r_inputs=getMap(s1->content,"ServiceProvider");
1454      sprintf(tmps1,"%s/%s",altPath,r_inputs->value);
1455      free(altPath);
1456#ifdef DEBUG
1457      fprintf(stderr,"Trying to load %s\n",tmps1);
1458#endif
1459#ifdef WIN32
1460      HINSTANCE so = LoadLibraryEx(tmps1,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1461#else
1462      void* so = dlopen(tmps1, RTLD_LAZY);
1463#endif
1464#ifdef DEBUG
1465#ifdef WIN32
1466      DWORD errstr;
1467      errstr = GetLastError();
1468      fprintf(stderr,"%s loaded (%d) \n",tmps1,errstr);
1469#else
1470      char *errstr;
1471      errstr = dlerror();
1472#endif
1473#endif
1474
1475      if( so != NULL ) {
1476#ifdef DEBUG
1477        fprintf(stderr,"Library loaded %s \n",errstr);
1478        fprintf(stderr,"Service Shared Object = %s\n",r_inputs->value);
1479#endif
1480        r_inputs=getMap(s1->content,"serviceType");
1481#ifdef DEBUG
1482        dumpMap(r_inputs);
1483        fprintf(stderr,"%s\n",r_inputs->value);
1484        fflush(stderr);
1485#endif
1486        if(strncasecmp(r_inputs->value,"C-FORTRAN",9)==0){
1487#ifdef WIN32
1488          //Strange return value needed here !
1489          return 1;
1490#endif
1491          r_inputs=getMap(request_inputs,"Identifier");
1492          char fname[1024];
1493          sprintf(fname,"%s_",r_inputs->value);
1494#ifdef DEBUG
1495          fprintf(stderr,"Try to load function %s\n",fname);
1496#endif
1497#ifdef WIN32
1498          typedef int (CALLBACK* execute_t)(char***,char***,char***);
1499          execute_t execute=(execute_t)GetProcAddress(so,fname);
1500#else
1501          typedef int (*execute_t)(char***,char***,char***);
1502          execute_t execute=(execute_t)dlsym(so,fname);
1503#endif
1504#ifdef DEBUG
1505#ifdef WIN32
1506          errstr = GetLastError();
1507#else
1508          errstr = dlerror();
1509#endif
1510          fprintf(stderr,"Function loaded %s\n",errstr);
1511#endif 
1512
1513          char main_conf[10][30][1024];
1514          char inputs[10][30][1024];
1515          char outputs[10][30][1024];
1516          for(int i=0;i<10;i++){
1517            for(int j=0;j<30;j++){
1518              memset(main_conf[i][j],0,1024);
1519              memset(inputs[i][j],0,1024);
1520              memset(outputs[i][j],0,1024);
1521            }
1522          }
1523          mapsToCharXXX(m,(char***)main_conf);
1524          mapsToCharXXX(request_input_real_format,(char***)inputs);
1525          mapsToCharXXX(request_output_real_format,(char***)outputs);
1526          eres=execute((char***)&main_conf[0],(char***)&inputs[0],(char***)&outputs[0]);
1527#ifdef DEBUG
1528          fprintf(stderr,"Function run successfully \n");
1529#endif
1530          charxxxToMaps((char***)&outputs[0],&request_output_real_format);
1531        }else{
1532#ifdef DEBUG
1533#ifdef WIN32
1534          errstr = GetLastError();
1535          fprintf(stderr,"Function %s failed to load because of %d\n",r_inputs->value,errstr);
1536#endif
1537#endif
1538          r_inputs=getMap(request_inputs,"Identifier");
1539#ifdef DEBUG
1540          fprintf(stderr,"Try to load function %s\n",r_inputs->value);
1541#endif
1542          typedef int (*execute_t)(maps**,maps**,maps**);
1543#ifdef WIN32
1544          execute_t execute=(execute_t)GetProcAddress(so,r_inputs->value); 
1545#ifdef DEBUG
1546          errstr = GetLastError();
1547          fprintf(stderr,"Function %s failed to load because of %d\n",r_inputs->value,errstr);
1548#endif
1549#else
1550          execute_t execute=(execute_t)dlsym(so,r_inputs->value);
1551#endif
1552
1553#ifdef DEBUG
1554#ifdef WIN32
1555          errstr = GetLastError();
1556#else
1557          errstr = dlerror();
1558#endif
1559          fprintf(stderr,"Function loaded %s\n",errstr);
1560#endif 
1561
1562#ifdef DEBUG
1563          fprintf(stderr,"Now run the function \n");
1564          fflush(stderr);
1565#endif
1566          eres=execute(&m,&request_input_real_format,&request_output_real_format);
1567#ifdef DEBUG
1568          fprintf(stderr,"Function loaded and returned %d\n",eres);
1569          fflush(stderr);
1570#endif
1571        }
1572        dlclose(so);
1573      } else {
1574        /**
1575         * Unable to load the specified shared library
1576         */
1577        char tmps[1024];
1578#ifdef WIN32
1579        DWORD errstr = GetLastError();
1580#else
1581        char* errstr = dlerror();
1582#endif
1583        sprintf(tmps,"C Library can't be loaded %s \n",errstr);
1584        map* tmps1=createMap("text",tmps);
1585        printExceptionReportResponse(m,tmps1);
1586        exit(1);
1587      }
1588    }
1589    else{
1590#ifdef USE_PYTHON
1591      if(strncasecmp(r_inputs->value,"PYTHON",6)==0){
1592        eres=zoo_python_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1593      }
1594      else
1595#endif
1596       
1597#ifdef USE_JAVA
1598        if(strncasecmp(r_inputs->value,"JAVA",4)==0){
1599          eres=zoo_java_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1600        }
1601        else
1602#endif
1603
1604#ifdef USE_PHP
1605          if(strncasecmp(r_inputs->value,"PHP",3)==0){
1606            eres=zoo_php_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1607          }
1608          else
1609#endif
1610
1611
1612#ifdef USE_PERL
1613          if(strncasecmp(r_inputs->value,"PERL",4)==0){
1614            eres=zoo_perl_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1615          }
1616          else
1617#endif
1618
1619#ifdef USE_JS
1620            if(strncasecmp(r_inputs->value,"JS",2)==0){
1621              eres=zoo_js_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1622            }
1623            else
1624#endif
1625              {
1626                char tmpv[1024];
1627                sprintf(tmpv,"Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n",r_inputs->value);
1628                map* tmps=createMap("text",tmpv);
1629                printExceptionReportResponse(m,tmps);
1630                return(-1);
1631              }
1632    }
1633  }
1634  else{
1635
1636    pid_t   pid;
1637#ifdef DEBUG
1638    fprintf(stderr,"\nPID : %d\n",cpid);
1639#endif
1640
1641#ifndef WIN32
1642    pid = fork ();
1643#else
1644    pid = 0;
1645#endif
1646    if (pid > 0) {
1647      /**
1648       * dady :
1649       * set status to SERVICE_ACCEPTED
1650       */
1651#ifdef DEBUG
1652      fprintf(stderr,"father pid continue (origin %d) %d ...\n",cpid,getpid());
1653#endif
1654      eres=SERVICE_ACCEPTED;
1655    }else if (pid == 0) {
1656      /**
1657       * son : have to close the stdout, stdin and stderr to let the parent
1658       * process answer to http client.
1659       */
1660      r_inputs=getMapFromMaps(m,"main","tmpPath");
1661      map* r_inputs1=getMap(s1->content,"ServiceProvider");
1662      char* fbkp=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+16)*sizeof(char));
1663      sprintf(fbkp,"%s/%s_%d.xml",r_inputs->value,r_inputs1->value,cpid);
1664      char* flog=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+22)*sizeof(char));
1665      sprintf(flog,"%s/%s_%d_error.log",r_inputs->value,r_inputs1->value,cpid);
1666      fprintf(stderr,"File to use as backup %s\n",fbkp);
1667#ifdef DEBUG
1668      fprintf(stderr,"RUN IN BACKGROUND MODE \n");
1669      fprintf(stderr,"son pid continue (origin %d) %d ...\n",cpid,getpid());
1670      fprintf(stderr,"\nFILE TO STORE DATA %s\n",r_inputs->value);
1671#endif
1672      freopen(fbkp , "w+", stdout);
1673      fclose(stdin);
1674      freopen(flog,"w+",stderr);
1675      free(fbkp);
1676      free(flog);
1677      /**
1678       * set status to SERVICE_STARTED and flush stdout to ensure full
1679       * content was outputed (the file used to store the ResponseDocument).
1680       * The rewind stdout to restart writing from the bgining of the file,
1681       * this way the data will be updated at the end of the process run.
1682       */
1683      printProcessResponse(m,request_inputs,cpid,
1684                            s1,r_inputs->value,SERVICE_STARTED,
1685                            request_input_real_format,
1686                            request_output_real_format);
1687      fflush(stdout);
1688      rewind(stdout);
1689      /**
1690       * Extract serviceType to know what kind of service shoudl be loaded
1691       */
1692      r_inputs=NULL;
1693      r_inputs=getMap(s1->content,"serviceType");
1694#ifdef DEBUG
1695      fprintf(stderr,"LOAD A %s SERVICE PROVIDER IN BACKGROUND MODE \n",r_inputs->value);
1696#endif
1697
1698      if(strncasecmp(r_inputs->value,"C",1)==0){
1699
1700        r_inputs=getMap(request_inputs,"metapath");
1701        if(r_inputs!=NULL){
1702          sprintf(tmps1,"%s/%s",ntmp,r_inputs->value);
1703          r_inputs=getMap(s1->content,"ServiceProvider");
1704          if(r_inputs!=NULL)
1705            sprintf(tmps1,"%s/%s",strdup(tmps1),r_inputs->value);
1706        }else{
1707          sprintf(tmps1,"%s/",ntmp);
1708        }
1709         
1710 
1711#ifdef DEBUG
1712        fprintf(stderr,"Trying to load %s\n",tmps1);
1713#endif
1714#ifdef WIN32
1715        HINSTANCE so = LoadLibraryEx(tmps1,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1716#else
1717        void* so = dlopen(tmps1, RTLD_LAZY);
1718#endif
1719#ifdef WIN32
1720        DWORD errstr;
1721        errstr = GetLastError();
1722#else
1723        char *errstr;
1724        errstr = dlerror();
1725#endif
1726        if( so != NULL ) {
1727          r_inputs=getMap(s1->content,"serviceType");
1728#ifdef DEBUG
1729          fprintf(stderr,"r_inputs->value = %s\n",r_inputs->value);
1730#endif
1731          if(strncasecmp(r_inputs->value,"C-FORTRAN",9)==0){
1732            r_inputs=getMap(request_inputs,"Identifier");
1733#ifdef DEBUG
1734            fprintf(stderr,"Try to load function %s\n",r_inputs->value);
1735#endif
1736            typedef int (*execute_t)(char***,char***,char***);
1737            char fname[1024];
1738            sprintf(fname,"%s_",r_inputs->value);
1739#ifdef DEBUG
1740            fprintf(stderr,"Try to load function %s\n",fname);
1741#endif
1742#ifdef WIN32
1743            execute_t execute=(execute_t)GetProcAddress(so,fname); 
1744#else
1745            execute_t execute=(execute_t)dlsym(so,fname);
1746#endif
1747#ifdef DEBUG
1748#ifdef WIN32
1749            errstr = GetLastError();
1750#else
1751            errstr = dlerror();
1752#endif
1753#endif 
1754            char main_conf[10][10][1024];
1755            char inputs[10][10][1024];
1756            char outputs[10][10][1024];
1757            for(int i=0;i<10;i++){
1758              for(int j=0;j<10;j++){
1759                memset(main_conf[i][j],0,1024);
1760                memset(inputs[i][j],0,1024);
1761                memset(outputs[i][j],0,1024);
1762              }
1763            }
1764            mapsToCharXXX(m,(char***)main_conf);
1765            mapsToCharXXX(request_input_real_format,(char***)inputs);
1766            //mapsToCharXXX(request_output_real_format,(char***)outputs);
1767            eres=execute((char***)&main_conf[0],(char***)&inputs[0],(char***)&outputs[0]);
1768            charxxxToMaps((char***)&outputs[0],&request_output_real_format);
1769
1770          }else{
1771
1772            typedef int (*execute_t)(maps**,maps**,maps**);
1773#ifdef DEBUG
1774            fprintf(stderr,"Library loaded %s \n",errstr);
1775#endif
1776            r_inputs=getMap(request_inputs,"Identifier");
1777#ifdef DEBUG
1778            fprintf(stderr,"Try to load function %s\n",r_inputs->value);
1779#endif
1780#ifdef WIN32
1781            execute_t execute=(execute_t)GetProcAddress(so,r_inputs->value); 
1782#else
1783            execute_t execute=(execute_t)dlsym(so,r_inputs->value);
1784#endif
1785#ifdef DEBUG
1786#ifdef WIN32
1787            errstr = GetLastError();
1788#else
1789            errstr = dlerror();
1790#endif
1791            fprintf(stderr,"Function loaded %s\n",errstr);
1792#endif 
1793            /**
1794             * set the status code value returned by the service function itself
1795             */
1796            eres=execute(&m,&request_input_real_format,&request_output_real_format);
1797          }
1798          dlclose(so);
1799        } else {
1800          /**
1801           * Unable to load the requested C Library
1802           */
1803          char tmps2[1024];
1804          sprintf(tmps1,"C Library can't be loaded %s \n",errstr);
1805          map* tmps=createMap("text",tmps1);
1806          printExceptionReportResponse(m,tmps);
1807          freeMap(&tmps);
1808          free(tmps);
1809          exit(1);
1810        }
1811      } else{
1812
1813#ifdef USE_PYTHON
1814        if(strncasecmp(r_inputs->value,"PYTHON",6)==0){
1815          eres=zoo_python_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1816        }
1817        else
1818#endif
1819
1820#ifdef USE_JAVA
1821          if(strncasecmp(r_inputs->value,"JAVA",4)==0){
1822            eres=zoo_java_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1823          }
1824          else
1825#endif
1826           
1827#ifdef USE_PHP
1828            if(strncasecmp(r_inputs->value,"PHP",3)==0){
1829              eres=zoo_php_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1830            }
1831            else
1832#endif
1833             
1834#ifdef USE_PERL
1835          if(strncasecmp(r_inputs->value,"PERL",4)==0){
1836            eres=zoo_perl_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1837          }
1838          else
1839#endif
1840#ifdef USE_JS
1841              if(strncasecmp(r_inputs->value,"JS",2)==0){
1842                eres=zoo_js_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
1843              }
1844              else
1845#endif
1846                {
1847                  char tmpv[1024];
1848                  sprintf(tmpv,"Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n",r_inputs->value);
1849                  map* tmps=createMap("text",tmpv);
1850                  printExceptionReportResponse(m,tmps);
1851                  return -1;
1852                }
1853      }
1854 
1855      //res=execute(&m,&request_input_real_format,&request_output_real_format);
1856    } else {
1857      /**
1858       * error server don't accept the process need to output a valid
1859       * error response here !!!
1860       */
1861    }
1862       
1863  }
1864
1865#ifdef DEBUG
1866  dumpMaps(request_output_real_format);
1867  fprintf(stderr,"Function loaded and returned %d\n",eres);
1868  fflush(stderr);
1869#endif
1870  if(eres!=-1)
1871    outputResponse(s1,request_input_real_format,
1872                   request_output_real_format,request_inputs,
1873                   cpid,m,eres);
1874
1875  //if(getpid()==cpid){
1876  freeService(&s1);
1877  free(s1);
1878  freeMaps(&m);
1879  free(m);
1880  freeMaps(&tmpmaps);
1881  free(tmpmaps);
1882 
1883  freeMaps(&request_input_real_format);
1884  free(request_input_real_format);
1885 
1886  //freeMap(&request_inputs);
1887  //free(request_inputs);
1888   
1889  /* The following is requested but get issue using with Python support :/ */
1890  /* freeMaps(&request_output_real_format);
1891     free(request_output_real_format);
1892  */
1893 
1894  free(REQUEST);
1895  free(SERVICE_URL);
1896#ifdef DEBUG
1897  fprintf(stderr,"Processed response \n");
1898  fflush(stdout);
1899  fflush(stderr);
1900#endif
1901    //}
1902
1903  return 0;
1904}
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