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

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

Fix for use of status and storeExecuteResponse parameters.

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