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

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

Update of both ZOO Kernel and ZOO Services (ogr base-vect-ops ServicesProvider?).
All the ZCFG files have been corrected to remove all references to wrong metadata (Test = Demo) to avoid validation issues.
Main Memory leaks has been removed from this version.
Addition of the Simplify Service in the C ogr base-vect-ops ServicesProvider? and addition of the Python version (without Simplify).
Update of the configure.ac and Makefile.in to follow dicussions on the mailing list and ensure to use our cgic206 and not another one, path to our cgic library is now directly in the Makefile.in file.
Accept the "-" character to name inputs, to solve issue on GRASS 7 integration.
Addition of the extension keyword for ZCFG file to be able to store resulting outputs in a file name using the extension suffix.
This version after a testing period shall be considerate as 1.0.1 version of the ZOO Project.

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