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

Last change on this file since 25 was 25, checked in by david, 14 years ago

ajout support perl (beta)

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