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

Last change on this file since 214 was 214, checked in by djay, 13 years ago

Small fix for remote input data download checking for protocol (supporting http anf ftp). Add the tabulation character support in ZCFG to avoid requirement of duplicate stdout, which is still in place for characters not supported in the ZCFG files.

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