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

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

Small fix for accessing Body node.

File size: 49.5 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     * 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 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#ifdef DEBUG
924            fprintf(stderr,"REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n",tmpv1+1);
925#endif
926#ifndef WIN32
927            if(CHECK_INET_HANDLE(hInternet))
928#endif
929              {
930                res=InternetOpenUrl(hInternet,tmpv1+1,NULL,0,
931                                    INTERNET_FLAG_NO_CACHE_WRITE,0);
932#ifdef DEBUG
933                fprintf(stderr,"(%s) content-length : %d,,res.nDataAlloc %d \n",
934                        tmpv1+1,res.nDataAlloc,res.nDataLen);
935#endif
936                char* tmpContent=(char*)calloc((res.nDataLen+1),sizeof(char));
937                if(tmpContent == NULL){
938                  return errorException(m, _("Unable to allocate memory."), "InternalError");
939                }
940                size_t dwRead;
941                InternetReadFile(res, (LPVOID)tmpContent,res.nDataLen, &dwRead);
942                map* tmpMap=getMap(tmpmaps->content,"value");
943                if(tmpMap!=NULL){
944                  free(tmpMap->value);
945                  tmpMap->value=(char*)malloc((res.nDataLen+1)*sizeof(char));
946                  memmove(tmpMap->value,tmpContent,(res.nDataLen)*sizeof(char));
947                  tmpMap->value[res.nDataLen]=0;
948                  if(strlen(tmpContent)!=res.nDataLen){
949                    char tmp[256];
950                    sprintf(tmp,"%d",res.nDataLen*sizeof(char));
951                    addToMap(tmpmaps->content,"size",tmp);
952                  }
953                }
954                free(tmpContent);
955              }
956            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
957            addToMap(tmpmaps->content,"Reference",tmpv1+1);
958          }
959          tmpc=strtok(NULL,"@");
960        }
961#ifdef DEBUG
962        dumpMaps(tmpmaps);
963        fflush(stderr);
964#endif
965        if(request_input_real_format==NULL)
966          request_input_real_format=dupMaps(&tmpmaps);
967        else
968          addMapsToMaps(&request_input_real_format,tmpmaps);
969        freeMaps(&tmpmaps);
970        free(tmpmaps);
971        tmpmaps=NULL;
972        free(tmp);
973      }
974    }
975    free(inputs_as_text);
976  }
977  else {
978    /**
979     * Parse XML request
980     */ 
981    xmlInitParser();
982#ifdef DEBUG
983    fflush(stderr);
984    fprintf(stderr,"BEFORE %s\n",postRequest->value);
985    fflush(stderr);
986#endif
987    xmlDocPtr doc =
988      xmlParseMemory(postRequest->value,cgiContentLength);
989#ifdef DEBUG
990    fprintf(stderr,"AFTER\n");
991    fflush(stderr);
992#endif
993    /**
994     * Parse every Input in DataInputs node.
995     */
996    xmlXPathObjectPtr tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='Input']");
997    xmlNodeSet* tmps=tmpsptr->nodesetval;
998#ifdef DEBUG
999    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1000#endif
1001    for(int k=0;k<tmps->nodeNr;k++){
1002      maps *tmpmaps=NULL;
1003      xmlNodePtr cur=tmps->nodeTab[k];
1004      if(tmps->nodeTab[k]->type == XML_ELEMENT_NODE) {
1005        /**
1006         * A specific Input node.
1007         */
1008#ifdef DEBUG
1009        fprintf(stderr, "= element 0 node \"%s\"\n", cur->name);
1010#endif
1011        xmlNodePtr cur2=cur->children;
1012        while(cur2!=NULL){
1013          while(cur2!=NULL && cur2->type!=XML_ELEMENT_NODE)
1014            cur2=cur2->next;
1015          if(cur2==NULL)
1016            break;
1017          /**
1018           * Indentifier
1019           */
1020          if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1021            xmlChar *val= xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1022            if(tmpmaps==NULL){
1023              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1024              if(tmpmaps == NULL){
1025                return errorException(m, _("Unable to allocate memory."), "InternalError");
1026              }
1027              tmpmaps->name=strdup((char*)val);
1028              tmpmaps->content=NULL;
1029              tmpmaps->next=NULL;
1030            }
1031            xmlFree(val);
1032          }
1033          /**
1034           * Title, Asbtract
1035           */
1036          if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1037             xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1038            xmlChar *val=
1039              xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1040            if(tmpmaps==NULL){
1041              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1042              if(tmpmaps == NULL){
1043                return errorException(m, _("Unable to allocate memory."), "InternalError");
1044              }
1045              tmpmaps->name=strdup("missingIndetifier");
1046              tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1047              tmpmaps->next=NULL;
1048            }
1049            else{
1050              if(tmpmaps->content!=NULL)
1051                addToMap(tmpmaps->content,
1052                         (char*)cur2->name,(char*)val);
1053              else
1054                tmpmaps->content=
1055                  createMap((char*)cur2->name,(char*)val);
1056            }
1057#ifdef DEBUG
1058            dumpMaps(tmpmaps);
1059#endif
1060            xmlFree(val);
1061          }
1062          /**
1063           * InputDataFormChoice (Reference or Data ?)
1064           */
1065          if(xmlStrcasecmp(cur2->name,BAD_CAST "Reference")==0){
1066            /**
1067             * Get every attribute from a Reference node
1068             * mimeType, encoding, schema, href, method
1069             * Header and Body gesture should be added here
1070             */
1071#ifdef DEBUG
1072            fprintf(stderr,"REFERENCE\n");
1073#endif
1074            const char *refs[5];
1075            refs[0]="mimeType";
1076            refs[1]="encoding";
1077            refs[2]="schema";
1078            refs[3]="method";
1079            refs[4]="href";
1080            for(int l=0;l<5;l++){
1081#ifdef DEBUG
1082              fprintf(stderr,"*** %s ***",refs[l]);
1083#endif
1084              xmlChar *val=xmlGetProp(cur2,BAD_CAST refs[l]);
1085              if(val!=NULL && xmlStrlen(val)>0){
1086                if(tmpmaps->content!=NULL)
1087                  addToMap(tmpmaps->content,refs[l],(char*)val);
1088                else
1089                  tmpmaps->content=createMap(refs[l],(char*)val);
1090                map* ltmp=getMap(tmpmaps->content,"method");
1091                if(l==4){
1092                  if(!(ltmp!=NULL && strcmp(ltmp->value,"POST")==0)
1093                     && CHECK_INET_HANDLE(hInternet)){
1094                    res=InternetOpenUrl(hInternet,(char*)val,NULL,0,
1095                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
1096                    char* tmpContent=
1097                      (char*)calloc((res.nDataLen+1),sizeof(char));
1098                    if(tmpContent == NULL){
1099                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1100                    }
1101                    size_t dwRead;
1102                    InternetReadFile(res, (LPVOID)tmpContent,
1103                                     res.nDataLen, &dwRead);
1104                    tmpContent[res.nDataLen]=0;
1105                    addToMap(tmpmaps->content,"value",tmpContent);
1106                  }
1107                }
1108              }
1109#ifdef DEBUG
1110              fprintf(stderr,"%s\n",val);
1111#endif
1112              xmlFree(val);
1113            }
1114#ifdef POST_DEBUG
1115            fprintf(stderr,"Parse Header and Body from Reference \n");
1116#endif
1117            xmlNodePtr cur3=cur2->children;
1118            hInternet.header=NULL;
1119            while(cur3){
1120              if(xmlStrcasecmp(cur3->name,BAD_CAST "Header")==0 ){
1121                const char *ha[2];
1122                ha[0]="key";
1123                ha[1]="value";
1124                int hai;
1125                char *has;
1126                char *key;
1127                for(hai=0;hai<2;hai++){
1128                  xmlChar *val=xmlGetProp(cur3,BAD_CAST ha[hai]);
1129#ifdef POST_DEBUG
1130                  fprintf(stderr,"%s = %s\n",ha[hai],(char*)val);
1131#endif
1132                  if(hai==0){
1133                    key=(char*)calloc((1+strlen((char*)val)),sizeof(char));
1134                    snprintf(key,1+strlen((char*)val),"%s",(char*)val);
1135                  }else{
1136                    has=(char*)calloc((3+strlen((char*)val)+strlen(key)),sizeof(char));
1137                    if(has == NULL){
1138                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1139                    }
1140                    snprintf(has,(3+strlen((char*)val)+strlen(key)),"%s: %s",key,(char*)val);
1141#ifdef POST_DEBUG
1142                    fprintf(stderr,"%s\n",has);
1143#endif
1144                  }
1145                }
1146                hInternet.header=curl_slist_append(hInternet.header, has);
1147                free(has);
1148              }
1149              else{
1150#ifdef POST_DEBUG
1151                fprintf(stderr,"Try to fetch the body part of the request ...\n");
1152#endif
1153                if(xmlStrcasecmp(cur3->name,BAD_CAST "Body")==0 ){
1154#ifdef POST_DEBUG
1155                  fprintf(stderr,"Body part found !!!\n",(char*)cur3->content);
1156#endif
1157                  char *tmp=new char[cgiContentLength];
1158                  memset(tmp,0,cgiContentLength);
1159                  xmlNodePtr cur4=cur3->children;
1160                  while(cur4!=NULL){
1161                    while(cur4->type!=XML_ELEMENT_NODE)
1162                      cur4=cur4->next;
1163                    xmlDocPtr bdoc = xmlNewDoc(BAD_CAST "1.0");
1164                    bdoc->encoding = xmlCharStrdup ("UTF-8");
1165                    xmlDocSetRootElement(bdoc,cur4);
1166                    xmlChar* btmps;
1167                    int bsize;
1168                    xmlDocDumpMemory(bdoc,&btmps,&bsize);
1169#ifdef POST_DEBUG
1170                    fprintf(stderr,"Body part found !!! %s %s\n",tmp,(char*)btmps);
1171#endif
1172                    if(btmps!=NULL)
1173                      sprintf(tmp,"%s",(char*)btmps);
1174                    xmlFreeDoc(bdoc);
1175                    cur4=cur4->next;
1176                  }
1177                  map *btmp=getMap(tmpmaps->content,"href");
1178                  if(btmp!=NULL){
1179#ifdef POST_DEBUG
1180                    fprintf(stderr,"%s %s\n",btmp->value,tmp);
1181                    curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1182#endif
1183                    res=InternetOpenUrl(hInternet,btmp->value,tmp,strlen(tmp),
1184                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
1185                    char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
1186                    if(tmpContent == NULL){
1187                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1188                    }
1189                    size_t dwRead;
1190                    InternetReadFile(res, (LPVOID)tmpContent,
1191                                     res.nDataLen, &dwRead);
1192                    tmpContent[res.nDataLen]=0;
1193                    if(hInternet.header!=NULL)
1194                      curl_slist_free_all(hInternet.header);
1195                    addToMap(tmpmaps->content,"value",tmpContent);
1196#ifdef POST_DEBUG
1197                    fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1198#endif
1199                  }
1200                }
1201                else
1202                  if(xmlStrcasecmp(cur3->name,BAD_CAST "BodyReference")==0 ){
1203                    xmlChar *val=xmlGetProp(cur3,BAD_CAST "href");
1204                    HINTERNET bInternet,res1;
1205                    bInternet=InternetOpen(
1206#ifndef WIN32
1207                                           (LPCTSTR)
1208#endif
1209                                           "ZooWPSClient\0",
1210                                           INTERNET_OPEN_TYPE_PRECONFIG,
1211                                           NULL,NULL, 0);
1212                    if(!CHECK_INET_HANDLE(bInternet))
1213                      fprintf(stderr,"WARNING : hInternet handle failed to initialize");
1214#ifdef POST_DEBUG
1215                    curl_easy_setopt(bInternet.handle, CURLOPT_VERBOSE, 1);
1216#endif
1217                    res1=InternetOpenUrl(bInternet,(char*)val,NULL,0,
1218                                         INTERNET_FLAG_NO_CACHE_WRITE,0);
1219                    char* tmp=
1220                      (char*)calloc((res1.nDataLen+1),sizeof(char));
1221                    if(tmp == NULL){
1222                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1223                    }
1224                    size_t bRead;
1225                    InternetReadFile(res1, (LPVOID)tmp,
1226                                     res1.nDataLen, &bRead);
1227                    tmp[res1.nDataLen]=0;
1228                    InternetCloseHandle(bInternet);
1229                    map *btmp=getMap(tmpmaps->content,"href");
1230                    if(btmp!=NULL){
1231#ifdef POST_DEBUG
1232                      fprintf(stderr,"%s %s\n",btmp->value,tmp);
1233                      curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1234#endif
1235                      res=InternetOpenUrl(hInternet,btmp->value,tmp,
1236                                          strlen(tmp),
1237                                          INTERNET_FLAG_NO_CACHE_WRITE,0);
1238                      char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
1239                      if(tmpContent == NULL){
1240                        return errorException(m, _("Unable to allocate memory."), "InternalError");
1241                      }
1242                      size_t dwRead;
1243                      InternetReadFile(res, (LPVOID)tmpContent,
1244                                       res.nDataLen, &dwRead);
1245                      tmpContent[res.nDataLen]=0;
1246                      if(hInternet.header!=NULL)
1247                        curl_slist_free_all(hInternet.header);
1248                      addToMap(tmpmaps->content,"value",tmpContent);
1249#ifdef POST_DEBUG
1250                      fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1251#endif
1252                    }
1253                  }
1254              }
1255              cur3=cur3->next;
1256            }
1257#ifdef POST_DEBUG
1258            fprintf(stderr,"Header and Body was parsed from Reference \n");
1259#endif
1260#ifdef DEBUG
1261            dumpMap(tmpmaps->content);
1262            fprintf(stderr, "= element 2 node \"%s\" = (%s)\n", 
1263                    cur2->name,cur2->content);
1264#endif
1265          }
1266          else if(xmlStrcasecmp(cur2->name,BAD_CAST "Data")==0){
1267#ifdef DEBUG
1268            fprintf(stderr,"DATA\n");
1269#endif
1270            xmlNodePtr cur4=cur2->children;
1271            while(cur4!=NULL){
1272              while(cur4!=NULL &&cur4->type!=XML_ELEMENT_NODE)
1273                cur4=cur4->next;
1274              if(cur4==NULL)
1275                break;
1276              if(xmlStrcasecmp(cur4->name, BAD_CAST "LiteralData")==0){
1277                /**
1278                 * Get every attribute from a LiteralData node
1279                 * dataType , uom
1280                 */
1281                char *list[2];
1282                list[0]=strdup("dataType");
1283                list[1]=strdup("uom");
1284                for(int l=0;l<2;l++){
1285#ifdef DEBUG
1286                  fprintf(stderr,"*** LiteralData %s ***",list[l]);
1287#endif
1288                  xmlChar *val=xmlGetProp(cur4,BAD_CAST list[l]);
1289                  if(val!=NULL && strlen((char*)val)>0){
1290                    if(tmpmaps->content!=NULL)
1291                      addToMap(tmpmaps->content,list[l],(char*)val);
1292                    else
1293                      tmpmaps->content=createMap(list[l],(char*)val);
1294                  }
1295#ifdef DEBUG
1296                  fprintf(stderr,"%s\n",val);
1297#endif
1298                  xmlFree(val);
1299                  free(list[l]);
1300                }
1301              }
1302              else if(xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0){
1303                /**
1304                 * Get every attribute from a Reference node
1305                 * mimeType, encoding, schema
1306                 */
1307                const char *coms[3];
1308                coms[0]="mimeType";
1309                coms[1]="encoding";
1310                coms[2]="schema";
1311                for(int l=0;l<3;l++){
1312#ifdef DEBUG
1313                  fprintf(stderr,"*** ComplexData %s ***",coms[l]);
1314#endif
1315                  xmlChar *val=xmlGetProp(cur4,BAD_CAST coms[l]);
1316                  if(val!=NULL && strlen((char*)val)>0){
1317                    if(tmpmaps->content!=NULL)
1318                      addToMap(tmpmaps->content,coms[l],(char*)val);
1319                    else
1320                      tmpmaps->content=createMap(coms[l],(char*)val);
1321                  }
1322#ifdef DEBUG
1323                  fprintf(stderr,"%s\n",val);
1324#endif
1325                  xmlFree(val);
1326                }
1327              }
1328              map* test=getMap(tmpmaps->content,"encoding");
1329              if(test==NULL || strcasecmp(test->value,"base64")!=0){
1330                xmlChar* mv=xmlNodeListGetString(doc,cur4->xmlChildrenNode,1);
1331                if(mv==NULL){
1332                  xmlDocPtr doc1=xmlNewDoc(BAD_CAST "1.0");
1333                  int buffersize;
1334                  xmlDocSetRootElement(doc1,cur4->xmlChildrenNode);
1335                  xmlDocDumpFormatMemoryEnc(doc1, &mv, &buffersize, "utf-8", 1);
1336                  char size[1024];
1337                  sprintf(size,"%d",buffersize);
1338                  addToMap(tmpmaps->content,"size",size);
1339                }
1340                addToMap(tmpmaps->content,"value",(char*)mv);
1341                xmlFree(mv);
1342              }else{
1343                xmlChar* tmp=xmlNodeListGetRawString(doc,cur4->xmlChildrenNode,0);
1344                addToMap(tmpmaps->content,"value",(char*)tmp);
1345                map* tmpv=getMap(tmpmaps->content,"value");
1346                char *res=NULL;
1347                char *curs=tmpv->value;
1348                for(int i=0;i<=strlen(tmpv->value)/64;i++) {
1349                  if(res==NULL)
1350                    res=(char*)malloc(67*sizeof(char));
1351                  else
1352                    res=(char*)realloc(res,(((i+1)*65)+i)*sizeof(char));
1353                  int csize=i*65;
1354                  strncpy(res + csize,curs,64);
1355                  if(i==xmlStrlen(tmp)/64)
1356                    strcat(res,"\n\0");
1357                  else{
1358                    strncpy(res + (((i+1)*64)+i),"\n\0",2);
1359                    curs+=64;
1360                  }
1361                }
1362                free(tmpv->value);
1363                tmpv->value=strdup(res);
1364                free(res);
1365                xmlFree(tmp);
1366              }
1367              cur4=cur4->next;
1368            }
1369          }
1370#ifdef DEBUG
1371          fprintf(stderr,"cur2 next \n");
1372          fflush(stderr);
1373#endif
1374          cur2=cur2->next;
1375        }
1376#ifdef DEBUG
1377        fprintf(stderr,"ADD MAPS TO REQUEST MAPS !\n");
1378        fflush(stderr);
1379#endif
1380        addMapsToMaps(&request_input_real_format,tmpmaps);
1381       
1382#ifdef DEBUG
1383        fprintf(stderr,"******TMPMAPS*****\n");
1384        dumpMaps(tmpmaps);
1385        fprintf(stderr,"******REQUESTMAPS*****\n");
1386        dumpMaps(request_input_real_format);
1387#endif
1388        freeMaps(&tmpmaps);
1389        free(tmpmaps);
1390        tmpmaps=NULL;         
1391      }
1392#ifdef DEBUG
1393      dumpMaps(tmpmaps); 
1394#endif
1395    }
1396#ifdef DEBUG
1397    fprintf(stderr,"Search for response document node\n");
1398#endif
1399    xmlXPathFreeObject(tmpsptr);
1400   
1401    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='ResponseDocument']");
1402    bool asRaw=false;
1403    tmps=tmpsptr->nodesetval;
1404    if(tmps->nodeNr==0){
1405      tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='RawDataOutput']");
1406      tmps=tmpsptr->nodesetval;
1407      asRaw=true;
1408    }
1409#ifdef DEBUG
1410    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1411#endif
1412    for(int k=0;k<tmps->nodeNr;k++){
1413      if(asRaw==true)
1414        addToMap(request_inputs,"RawDataOutput","");
1415      else
1416        addToMap(request_inputs,"ResponseDocument","");
1417      maps *tmpmaps=NULL;
1418      xmlNodePtr cur=tmps->nodeTab[k];
1419      if(cur->type == XML_ELEMENT_NODE) {
1420        /**
1421         * A specific responseDocument node.
1422         */
1423        if(tmpmaps==NULL){
1424          tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1425          if(tmpmaps == NULL){
1426            return errorException(m, _("Unable to allocate memory."), "InternalError");
1427          }
1428          tmpmaps->name=strdup("unknownIdentifier");
1429          tmpmaps->next=NULL;
1430        }
1431        /**
1432         * Get every attribute from a LiteralData node
1433         * storeExecuteResponse, lineage, status
1434         */
1435        const char *ress[3];
1436        ress[0]="storeExecuteResponse";
1437        ress[1]="lineage";
1438        ress[2]="status";
1439        xmlChar *val;
1440        for(int l=0;l<3;l++){
1441#ifdef DEBUG
1442          fprintf(stderr,"*** %s ***\t",ress[l]);
1443#endif
1444          val=xmlGetProp(cur,BAD_CAST ress[l]);
1445          if(val!=NULL && strlen((char*)val)>0){
1446            if(tmpmaps->content!=NULL)
1447              addToMap(tmpmaps->content,ress[l],(char*)val);
1448            else
1449              tmpmaps->content=createMap(ress[l],(char*)val);
1450            addToMap(request_inputs,ress[l],(char*)val);
1451          }
1452#ifdef DEBUG
1453          fprintf(stderr,"%s\n",val);
1454#endif
1455          xmlFree(val);
1456        }
1457        xmlNodePtr cur1=cur->children;
1458        while(cur1){
1459          if(xmlStrncasecmp(cur1->name,BAD_CAST "Output",xmlStrlen(cur1->name))==0){
1460            /**
1461             * Get every attribute from a Output node
1462             * mimeType, encoding, schema, uom, asReference
1463             */
1464            const char *outs[5];
1465            outs[0]="mimeType";
1466            outs[1]="encoding";
1467            outs[2]="schema";
1468            outs[3]="uom";
1469            outs[4]="asReference";
1470            for(int l=0;l<5;l++){
1471#ifdef DEBUG
1472              fprintf(stderr,"*** %s ***\t",outs[l]);
1473#endif
1474              val=xmlGetProp(cur1,BAD_CAST outs[l]);
1475              if(val!=NULL && strlen((char*)val)>0){
1476                if(tmpmaps->content!=NULL)
1477                  addToMap(tmpmaps->content,outs[l],(char*)val);
1478                else
1479                  tmpmaps->content=createMap(outs[l],(char*)val);
1480              }
1481#ifdef DEBUG
1482              fprintf(stderr,"%s\n",val);
1483#endif
1484              xmlFree(val);
1485            }
1486           
1487            xmlNodePtr cur2=cur1->children;
1488            while(cur2){
1489              /**
1490               * Indentifier
1491               */
1492              if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1493                xmlChar *val=
1494                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1495                if(tmpmaps==NULL){
1496                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1497                  if(tmpmaps == NULL){
1498                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1499                  }
1500                  tmpmaps->name=strdup((char*)val);
1501                  tmpmaps->content=NULL;
1502                  tmpmaps->next=NULL;
1503                }
1504                else
1505                  tmpmaps->name=strdup((char*)val);;
1506                xmlFree(val);
1507              }
1508              /**
1509               * Title, Asbtract
1510               */
1511              if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1512                 xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1513                xmlChar *val=
1514                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1515                if(tmpmaps==NULL){
1516                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1517                  if(tmpmaps == NULL){
1518                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1519                  }
1520                  tmpmaps->name=strdup("missingIndetifier");
1521                  tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1522                  tmpmaps->next=NULL;
1523                }
1524                else{
1525                  if(tmpmaps->content!=NULL)
1526                    addToMap(tmpmaps->content,
1527                             (char*)cur2->name,(char*)val);
1528                  else
1529                    tmpmaps->content=
1530                      createMap((char*)cur2->name,(char*)val);
1531                }
1532                xmlFree(val);
1533              }
1534              cur2=cur2->next;
1535            }
1536          }
1537          cur1=cur1->next;
1538        }
1539      }
1540      if(request_output_real_format==NULL)
1541        request_output_real_format=dupMaps(&tmpmaps);
1542      else
1543        addMapsToMaps(&request_output_real_format,tmpmaps);
1544#ifdef DEBUG
1545      dumpMaps(tmpmaps);
1546#endif
1547      freeMaps(&tmpmaps);
1548      free(tmpmaps);
1549    }
1550
1551    xmlXPathFreeObject(tmpsptr);
1552    xmlCleanupParser();
1553  }
1554 
1555  //if(CHECK_INET_HANDLE(hInternet))
1556  InternetCloseHandle(hInternet);
1557
1558#ifdef DEBUG
1559  fprintf(stderr,"\n%i\n",i);
1560  dumpMaps(request_input_real_format);
1561  dumpMaps(request_output_real_format);
1562  dumpMap(request_inputs);
1563#endif
1564
1565  /**
1566   * Ensure that each requested arguments are present in the request
1567   * DataInputs and ResponseDocument / RawDataOutput
1568   */
1569  char *dfv=addDefaultValues(&request_input_real_format,s1->inputs,m,0);
1570  if(strcmp(dfv,"")!=0){
1571    char tmps[1024];
1572    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);
1573    map* tmpe=createMap("text",tmps);
1574    addToMap(tmpe,"code","MissingParameterValue");
1575    printExceptionReportResponse(m,tmpe);
1576    freeService(&s1);
1577    free(s1);
1578    freeMap(&tmpe);
1579    free(tmpe);
1580    freeMaps(&m);
1581    free(m);
1582    free(REQUEST);
1583    free(SERVICE_URL);
1584    freeMaps(&request_input_real_format);
1585    free(request_input_real_format);
1586    freeMaps(&request_output_real_format);
1587    free(request_output_real_format);
1588    freeMaps(&tmpmaps);
1589    free(tmpmaps);
1590    return 1;
1591  }
1592  addDefaultValues(&request_output_real_format,s1->outputs,m,1);
1593
1594  ensureDecodedBase64(&request_input_real_format);
1595
1596#ifdef DEBUG
1597  fprintf(stderr,"REQUEST_INPUTS\n");
1598  dumpMaps(request_input_real_format);
1599  fprintf(stderr,"REQUEST_OUTPUTS\n");
1600  dumpMaps(request_output_real_format);
1601#endif
1602
1603  maps* curs=getMaps(m,"env");
1604  if(curs!=NULL){
1605    map* mapcs=curs->content;
1606    while(mapcs!=NULLMAP){
1607#ifndef WIN32
1608      setenv(mapcs->name,mapcs->value,1);
1609#else
1610#ifdef DEBUG
1611      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1612#endif
1613      if(mapcs->value[strlen(mapcs->value)-2]=='\r'){
1614#ifdef DEBUG
1615        fprintf(stderr,"[ZOO: Env var finish with \r]\n");
1616#endif
1617        mapcs->value[strlen(mapcs->value)-1]=0;
1618      }
1619#ifdef DEBUG
1620      fflush(stderr);
1621      fprintf(stderr,"setting variable... %s\n",
1622#endif
1623              SetEnvironmentVariable(mapcs->name,mapcs->value)
1624#ifdef DEBUG
1625              ? "OK" : "FAILED");
1626#else
1627      ;
1628#endif
1629#ifdef DEBUG
1630      fflush(stderr);
1631#endif
1632#endif
1633#ifdef DEBUG
1634      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1635      fflush(stderr);
1636#endif
1637      mapcs=mapcs->next;
1638    }
1639  }
1640 
1641#ifdef DEBUG
1642  dumpMap(request_inputs);
1643#endif
1644
1645  /**
1646   * Need to check if we need to fork to load a status enabled
1647   */
1648  r_inputs=NULL;
1649  map* store=getMap(request_inputs,"storeExecuteResponse");
1650  map* status=getMap(request_inputs,"status");
1651  /**
1652   * 05-007r7 WPS 1.0.0 page 57 :
1653   * 'If status="true" and storeExecuteResponse is "false" then the service
1654   * shall raise an exception.'
1655   */
1656  if(status!=NULL && strcmp(status->value,"true")==0 && 
1657     store!=NULL && strcmp(store->value,"false")==0){
1658    errorException(m, _("Status cannot be set to true with storeExecuteResponse to false. Please, modify your request parameters."), "InvalidParameterValue");
1659    freeService(&s1);
1660    free(s1);
1661    freeMaps(&m);
1662    free(m);
1663   
1664    freeMaps(&request_input_real_format);
1665    free(request_input_real_format);
1666   
1667    freeMaps(&request_output_real_format);
1668    free(request_output_real_format);
1669   
1670    free(REQUEST);
1671    free(SERVICE_URL);
1672    return 1;
1673  }
1674  r_inputs=getMap(request_inputs,"storeExecuteResponse");
1675  int eres=SERVICE_STARTED;
1676  int cpid=getpid();
1677
1678  maps *_tmpMaps=(maps*)malloc(MAPS_SIZE);
1679  _tmpMaps->name=strdup("lenv");
1680  char tmpBuff[100];
1681  sprintf(tmpBuff,"%i",cpid);
1682  _tmpMaps->content=createMap("sid",tmpBuff);
1683  _tmpMaps->next=NULL;
1684  addToMap(_tmpMaps->content,"status","0");
1685  if(cgiCookie!=NULL && strlen(cgiCookie)>0){
1686    addToMap(_tmpMaps->content,"sessid",strstr(cgiCookie,"=")+1);
1687    char session_file_path[1024];
1688    map *tmpPath=getMapFromMaps(m,"main","sessPath");
1689    if(tmpPath==NULL)
1690      tmpPath=getMapFromMaps(m,"main","tmpPath");
1691    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(cgiCookie,"=")+1);
1692    maps *tmpSess=(maps*)calloc(1,MAPS_SIZE);
1693    struct stat file_status;
1694    int istat = stat(session_file_path, &file_status);
1695    if(istat==0){
1696      conf_read(session_file_path,tmpSess);
1697      dumpMaps(tmpSess);
1698      addMapsToMaps(&m,tmpSess);
1699      freeMaps(&tmpSess);
1700    }
1701    free(tmpSess);
1702  }
1703  addMapsToMaps(&m,_tmpMaps);
1704  freeMaps(&_tmpMaps);
1705  free(_tmpMaps);
1706
1707#ifdef DEBUG
1708  dumpMap(request_inputs);
1709#endif
1710
1711  if(status!=NULL)
1712    if(strcasecmp(status->value,"false")==0)
1713      status=NULL;
1714  if(status==NULLMAP){
1715    loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
1716  }
1717  else{
1718    pid_t   pid;
1719#ifdef DEBUG
1720    fprintf(stderr,"\nPID : %d\n",cpid);
1721#endif
1722
1723#ifndef WIN32
1724    pid = fork ();
1725#else
1726    pid = 0;
1727#endif
1728    if (pid > 0) {
1729      /**
1730       * dady :
1731       * set status to SERVICE_ACCEPTED
1732       */
1733#ifdef DEBUG
1734      fprintf(stderr,"father pid continue (origin %d) %d ...\n",cpid,getpid());
1735#endif
1736      eres=SERVICE_ACCEPTED;
1737    }else if (pid == 0) {
1738      /**
1739       * son : have to close the stdout, stdin and stderr to let the parent
1740       * process answer to http client.
1741       */
1742      r_inputs=getMapFromMaps(m,"main","tmpPath");
1743      map* r_inputs1=getMap(s1->content,"ServiceProvider");
1744      char* fbkp=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+100)*sizeof(char));
1745      sprintf(fbkp,"%s/%s_%d.xml",r_inputs->value,r_inputs1->value,cpid);
1746      char* flog=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+100)*sizeof(char));
1747      sprintf(flog,"%s/%s_%d_error.log",r_inputs->value,r_inputs1->value,cpid);
1748#ifdef DEBUG
1749      fprintf(stderr,"RUN IN BACKGROUND MODE \n");
1750      fprintf(stderr,"son pid continue (origin %d) %d ...\n",cpid,getpid());
1751      fprintf(stderr,"\nFILE TO STORE DATA %s\n",r_inputs->value);
1752#endif
1753      freopen(fbkp , "w+", stdout);
1754      fclose(stdin);
1755      freopen(flog,"w+",stderr);
1756      free(fbkp);
1757      free(flog);
1758      /**
1759       * set status to SERVICE_STARTED and flush stdout to ensure full
1760       * content was outputed (the file used to store the ResponseDocument).
1761       * The rewind stdout to restart writing from the bgining of the file,
1762       * this way the data will be updated at the end of the process run.
1763       */
1764      updateStatus(m);
1765      printProcessResponse(m,request_inputs,cpid,
1766                            s1,r_inputs1->value,SERVICE_STARTED,
1767                            request_input_real_format,
1768                            request_output_real_format);
1769      fflush(stdout);
1770      rewind(stdout);
1771
1772      loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
1773
1774    } else {
1775      /**
1776       * error server don't accept the process need to output a valid
1777       * error response here !!!
1778       */
1779      eres=-1;
1780      errorException(m, _("Unable to run the child process properly"), "InternalError");
1781    }
1782  }
1783
1784#ifdef DEBUG
1785  dumpMaps(request_output_real_format);
1786  fprintf(stderr,"Function loaded and returned %d\n",eres);
1787  fflush(stderr);
1788#endif
1789  if(eres!=-1)
1790    outputResponse(s1,request_input_real_format,
1791                   request_output_real_format,request_inputs,
1792                   cpid,m,eres);
1793  /**
1794   * Ensure that if error occurs when freeing memory, no signal will return
1795   * an ExceptionReport document as the result was already returned to the
1796   * client.
1797   */
1798#ifndef USE_GDB
1799  (void) signal(SIGSEGV,donothing);
1800  (void) signal(SIGTERM,donothing);
1801  (void) signal(SIGINT,donothing);
1802  (void) signal(SIGILL,donothing);
1803  (void) signal(SIGFPE,donothing);
1804  (void) signal(SIGABRT,donothing);
1805#endif
1806
1807  if(((int)getpid())!=cpid){
1808    fclose(stdout);
1809    fclose(stderr);
1810    unhandleStatus(m);
1811  }
1812
1813  freeService(&s1);
1814  free(s1);
1815  freeMaps(&m);
1816  free(m);
1817 
1818  freeMaps(&request_input_real_format);
1819  free(request_input_real_format);
1820 
1821  freeMaps(&request_output_real_format);
1822  free(request_output_real_format);
1823 
1824  free(REQUEST);
1825  free(SERVICE_URL);
1826#ifdef DEBUG
1827  fprintf(stderr,"Processed response \n");
1828  fflush(stdout);
1829  fflush(stderr);
1830#endif
1831
1832  return 0;
1833}
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