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

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

Code cleanup to avoid most of the warning messages at compilation time.

File size: 49.4 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                    xmlDocPtr bdoc = xmlNewDoc(BAD_CAST "1.0");
1162                    bdoc->encoding = xmlCharStrdup ("UTF-8");
1163                    xmlDocSetRootElement(bdoc,cur4);
1164                    xmlChar* btmps;
1165                    int bsize;
1166                    xmlDocDumpMemory(bdoc,&btmps,&bsize);
1167#ifdef POST_DEBUG
1168                    fprintf(stderr,"Body part found !!! %s %s\n",tmp,(char*)btmps);
1169#endif
1170                    if(btmps!=NULL)
1171                      sprintf(tmp,"%s",(char*)btmps);
1172                    xmlFreeDoc(bdoc);
1173                    cur4=cur4->next;
1174                  }
1175                  map *btmp=getMap(tmpmaps->content,"href");
1176                  if(btmp!=NULL){
1177#ifdef POST_DEBUG
1178                    fprintf(stderr,"%s %s\n",btmp->value,tmp);
1179                    curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1180#endif
1181                    res=InternetOpenUrl(hInternet,btmp->value,tmp,strlen(tmp),
1182                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
1183                    char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
1184                    if(tmpContent == NULL){
1185                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1186                    }
1187                    size_t dwRead;
1188                    InternetReadFile(res, (LPVOID)tmpContent,
1189                                     res.nDataLen, &dwRead);
1190                    tmpContent[res.nDataLen]=0;
1191                    if(hInternet.header!=NULL)
1192                      curl_slist_free_all(hInternet.header);
1193                    addToMap(tmpmaps->content,"value",tmpContent);
1194#ifdef POST_DEBUG
1195                    fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1196#endif
1197                  }
1198                }
1199                else
1200                  if(xmlStrcasecmp(cur3->name,BAD_CAST "BodyReference")==0 ){
1201                    xmlChar *val=xmlGetProp(cur3,BAD_CAST "href");
1202                    HINTERNET bInternet,res1;
1203                    bInternet=InternetOpen(
1204#ifndef WIN32
1205                                           (LPCTSTR)
1206#endif
1207                                           "ZooWPSClient\0",
1208                                           INTERNET_OPEN_TYPE_PRECONFIG,
1209                                           NULL,NULL, 0);
1210                    if(!CHECK_INET_HANDLE(bInternet))
1211                      fprintf(stderr,"WARNING : hInternet handle failed to initialize");
1212#ifdef POST_DEBUG
1213                    curl_easy_setopt(bInternet.handle, CURLOPT_VERBOSE, 1);
1214#endif
1215                    res1=InternetOpenUrl(bInternet,(char*)val,NULL,0,
1216                                         INTERNET_FLAG_NO_CACHE_WRITE,0);
1217                    char* tmp=
1218                      (char*)calloc((res1.nDataLen+1),sizeof(char));
1219                    if(tmp == NULL){
1220                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1221                    }
1222                    size_t bRead;
1223                    InternetReadFile(res1, (LPVOID)tmp,
1224                                     res1.nDataLen, &bRead);
1225                    tmp[res1.nDataLen]=0;
1226                    InternetCloseHandle(bInternet);
1227                    map *btmp=getMap(tmpmaps->content,"href");
1228                    if(btmp!=NULL){
1229#ifdef POST_DEBUG
1230                      fprintf(stderr,"%s %s\n",btmp->value,tmp);
1231                      curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1232#endif
1233                      res=InternetOpenUrl(hInternet,btmp->value,tmp,
1234                                          strlen(tmp),
1235                                          INTERNET_FLAG_NO_CACHE_WRITE,0);
1236                      char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
1237                      if(tmpContent == NULL){
1238                        return errorException(m, _("Unable to allocate memory."), "InternalError");
1239                      }
1240                      size_t dwRead;
1241                      InternetReadFile(res, (LPVOID)tmpContent,
1242                                       res.nDataLen, &dwRead);
1243                      tmpContent[res.nDataLen]=0;
1244                      if(hInternet.header!=NULL)
1245                        curl_slist_free_all(hInternet.header);
1246                      addToMap(tmpmaps->content,"value",tmpContent);
1247#ifdef POST_DEBUG
1248                      fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1249#endif
1250                    }
1251                  }
1252              }
1253              cur3=cur3->next;
1254            }
1255#ifdef POST_DEBUG
1256            fprintf(stderr,"Header and Body was parsed from Reference \n");
1257#endif
1258#ifdef DEBUG
1259            dumpMap(tmpmaps->content);
1260            fprintf(stderr, "= element 2 node \"%s\" = (%s)\n", 
1261                    cur2->name,cur2->content);
1262#endif
1263          }
1264          else if(xmlStrcasecmp(cur2->name,BAD_CAST "Data")==0){
1265#ifdef DEBUG
1266            fprintf(stderr,"DATA\n");
1267#endif
1268            xmlNodePtr cur4=cur2->children;
1269            while(cur4!=NULL){
1270              while(cur4!=NULL &&cur4->type!=XML_ELEMENT_NODE)
1271                cur4=cur4->next;
1272              if(cur4==NULL)
1273                break;
1274              if(xmlStrcasecmp(cur4->name, BAD_CAST "LiteralData")==0){
1275                /**
1276                 * Get every attribute from a LiteralData node
1277                 * dataType , uom
1278                 */
1279                char *list[2];
1280                list[0]=strdup("dataType");
1281                list[1]=strdup("uom");
1282                for(int l=0;l<2;l++){
1283#ifdef DEBUG
1284                  fprintf(stderr,"*** LiteralData %s ***",list[l]);
1285#endif
1286                  xmlChar *val=xmlGetProp(cur4,BAD_CAST list[l]);
1287                  if(val!=NULL && strlen((char*)val)>0){
1288                    if(tmpmaps->content!=NULL)
1289                      addToMap(tmpmaps->content,list[l],(char*)val);
1290                    else
1291                      tmpmaps->content=createMap(list[l],(char*)val);
1292                  }
1293#ifdef DEBUG
1294                  fprintf(stderr,"%s\n",val);
1295#endif
1296                  xmlFree(val);
1297                  free(list[l]);
1298                }
1299              }
1300              else if(xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0){
1301                /**
1302                 * Get every attribute from a Reference node
1303                 * mimeType, encoding, schema
1304                 */
1305                const char *coms[3];
1306                coms[0]="mimeType";
1307                coms[1]="encoding";
1308                coms[2]="schema";
1309                for(int l=0;l<3;l++){
1310#ifdef DEBUG
1311                  fprintf(stderr,"*** ComplexData %s ***",coms[l]);
1312#endif
1313                  xmlChar *val=xmlGetProp(cur4,BAD_CAST coms[l]);
1314                  if(val!=NULL && strlen((char*)val)>0){
1315                    if(tmpmaps->content!=NULL)
1316                      addToMap(tmpmaps->content,coms[l],(char*)val);
1317                    else
1318                      tmpmaps->content=createMap(coms[l],(char*)val);
1319                  }
1320#ifdef DEBUG
1321                  fprintf(stderr,"%s\n",val);
1322#endif
1323                  xmlFree(val);
1324                }
1325              }
1326              map* test=getMap(tmpmaps->content,"encoding");
1327              if(test==NULL || strcasecmp(test->value,"base64")!=0){
1328                xmlChar* mv=xmlNodeListGetString(doc,cur4->xmlChildrenNode,1);
1329                if(mv==NULL){
1330                  xmlDocPtr doc1=xmlNewDoc(BAD_CAST "1.0");
1331                  int buffersize;
1332                  xmlDocSetRootElement(doc1,cur4->xmlChildrenNode);
1333                  xmlDocDumpFormatMemoryEnc(doc1, &mv, &buffersize, "utf-8", 1);
1334                  char size[1024];
1335                  sprintf(size,"%d",buffersize);
1336                  addToMap(tmpmaps->content,"size",size);
1337                }
1338                addToMap(tmpmaps->content,"value",(char*)mv);
1339                xmlFree(mv);
1340              }else{
1341                xmlChar* tmp=xmlNodeListGetRawString(doc,cur4->xmlChildrenNode,0);
1342                addToMap(tmpmaps->content,"value",(char*)tmp);
1343                map* tmpv=getMap(tmpmaps->content,"value");
1344                char *res=NULL;
1345                char *curs=tmpv->value;
1346                for(int i=0;i<=strlen(tmpv->value)/64;i++) {
1347                  if(res==NULL)
1348                    res=(char*)malloc(67*sizeof(char));
1349                  else
1350                    res=(char*)realloc(res,(((i+1)*65)+i)*sizeof(char));
1351                  int csize=i*65;
1352                  strncpy(res + csize,curs,64);
1353                  if(i==xmlStrlen(tmp)/64)
1354                    strcat(res,"\n\0");
1355                  else{
1356                    strncpy(res + (((i+1)*64)+i),"\n\0",2);
1357                    curs+=64;
1358                  }
1359                }
1360                free(tmpv->value);
1361                tmpv->value=strdup(res);
1362                free(res);
1363                xmlFree(tmp);
1364              }
1365              cur4=cur4->next;
1366            }
1367          }
1368#ifdef DEBUG
1369          fprintf(stderr,"cur2 next \n");
1370          fflush(stderr);
1371#endif
1372          cur2=cur2->next;
1373        }
1374#ifdef DEBUG
1375        fprintf(stderr,"ADD MAPS TO REQUEST MAPS !\n");
1376        fflush(stderr);
1377#endif
1378        addMapsToMaps(&request_input_real_format,tmpmaps);
1379       
1380#ifdef DEBUG
1381        fprintf(stderr,"******TMPMAPS*****\n");
1382        dumpMaps(tmpmaps);
1383        fprintf(stderr,"******REQUESTMAPS*****\n");
1384        dumpMaps(request_input_real_format);
1385#endif
1386        freeMaps(&tmpmaps);
1387        free(tmpmaps);
1388        tmpmaps=NULL;         
1389      }
1390#ifdef DEBUG
1391      dumpMaps(tmpmaps); 
1392#endif
1393    }
1394#ifdef DEBUG
1395    fprintf(stderr,"Search for response document node\n");
1396#endif
1397    xmlXPathFreeObject(tmpsptr);
1398   
1399    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='ResponseDocument']");
1400    bool asRaw=false;
1401    tmps=tmpsptr->nodesetval;
1402    if(tmps->nodeNr==0){
1403      tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='RawDataOutput']");
1404      tmps=tmpsptr->nodesetval;
1405      asRaw=true;
1406    }
1407#ifdef DEBUG
1408    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1409#endif
1410    for(int k=0;k<tmps->nodeNr;k++){
1411      if(asRaw==true)
1412        addToMap(request_inputs,"RawDataOutput","");
1413      else
1414        addToMap(request_inputs,"ResponseDocument","");
1415      maps *tmpmaps=NULL;
1416      xmlNodePtr cur=tmps->nodeTab[k];
1417      if(cur->type == XML_ELEMENT_NODE) {
1418        /**
1419         * A specific responseDocument node.
1420         */
1421        if(tmpmaps==NULL){
1422          tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1423          if(tmpmaps == NULL){
1424            return errorException(m, _("Unable to allocate memory."), "InternalError");
1425          }
1426          tmpmaps->name=strdup("unknownIdentifier");
1427          tmpmaps->next=NULL;
1428        }
1429        /**
1430         * Get every attribute from a LiteralData node
1431         * storeExecuteResponse, lineage, status
1432         */
1433        const char *ress[3];
1434        ress[0]="storeExecuteResponse";
1435        ress[1]="lineage";
1436        ress[2]="status";
1437        xmlChar *val;
1438        for(int l=0;l<3;l++){
1439#ifdef DEBUG
1440          fprintf(stderr,"*** %s ***\t",ress[l]);
1441#endif
1442          val=xmlGetProp(cur,BAD_CAST ress[l]);
1443          if(val!=NULL && strlen((char*)val)>0){
1444            if(tmpmaps->content!=NULL)
1445              addToMap(tmpmaps->content,ress[l],(char*)val);
1446            else
1447              tmpmaps->content=createMap(ress[l],(char*)val);
1448            addToMap(request_inputs,ress[l],(char*)val);
1449          }
1450#ifdef DEBUG
1451          fprintf(stderr,"%s\n",val);
1452#endif
1453          xmlFree(val);
1454        }
1455        xmlNodePtr cur1=cur->children;
1456        while(cur1){
1457          if(xmlStrncasecmp(cur1->name,BAD_CAST "Output",xmlStrlen(cur1->name))==0){
1458            /**
1459             * Get every attribute from a Output node
1460             * mimeType, encoding, schema, uom, asReference
1461             */
1462            const char *outs[5];
1463            outs[0]="mimeType";
1464            outs[1]="encoding";
1465            outs[2]="schema";
1466            outs[3]="uom";
1467            outs[4]="asReference";
1468            for(int l=0;l<5;l++){
1469#ifdef DEBUG
1470              fprintf(stderr,"*** %s ***\t",outs[l]);
1471#endif
1472              val=xmlGetProp(cur1,BAD_CAST outs[l]);
1473              if(val!=NULL && strlen((char*)val)>0){
1474                if(tmpmaps->content!=NULL)
1475                  addToMap(tmpmaps->content,outs[l],(char*)val);
1476                else
1477                  tmpmaps->content=createMap(outs[l],(char*)val);
1478              }
1479#ifdef DEBUG
1480              fprintf(stderr,"%s\n",val);
1481#endif
1482              xmlFree(val);
1483            }
1484           
1485            xmlNodePtr cur2=cur1->children;
1486            while(cur2){
1487              /**
1488               * Indentifier
1489               */
1490              if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1491                xmlChar *val=
1492                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1493                if(tmpmaps==NULL){
1494                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1495                  if(tmpmaps == NULL){
1496                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1497                  }
1498                  tmpmaps->name=strdup((char*)val);
1499                  tmpmaps->content=NULL;
1500                  tmpmaps->next=NULL;
1501                }
1502                else
1503                  tmpmaps->name=strdup((char*)val);;
1504                xmlFree(val);
1505              }
1506              /**
1507               * Title, Asbtract
1508               */
1509              if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1510                 xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1511                xmlChar *val=
1512                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1513                if(tmpmaps==NULL){
1514                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1515                  if(tmpmaps == NULL){
1516                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1517                  }
1518                  tmpmaps->name=strdup("missingIndetifier");
1519                  tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1520                  tmpmaps->next=NULL;
1521                }
1522                else{
1523                  if(tmpmaps->content!=NULL)
1524                    addToMap(tmpmaps->content,
1525                             (char*)cur2->name,(char*)val);
1526                  else
1527                    tmpmaps->content=
1528                      createMap((char*)cur2->name,(char*)val);
1529                }
1530                xmlFree(val);
1531              }
1532              cur2=cur2->next;
1533            }
1534          }
1535          cur1=cur1->next;
1536        }
1537      }
1538      if(request_output_real_format==NULL)
1539        request_output_real_format=dupMaps(&tmpmaps);
1540      else
1541        addMapsToMaps(&request_output_real_format,tmpmaps);
1542#ifdef DEBUG
1543      dumpMaps(tmpmaps);
1544#endif
1545      freeMaps(&tmpmaps);
1546      free(tmpmaps);
1547    }
1548
1549    xmlXPathFreeObject(tmpsptr);
1550    xmlCleanupParser();
1551  }
1552 
1553  //if(CHECK_INET_HANDLE(hInternet))
1554  InternetCloseHandle(hInternet);
1555
1556#ifdef DEBUG
1557  fprintf(stderr,"\n%i\n",i);
1558  dumpMaps(request_input_real_format);
1559  dumpMaps(request_output_real_format);
1560  dumpMap(request_inputs);
1561#endif
1562
1563  /**
1564   * Ensure that each requested arguments are present in the request
1565   * DataInputs and ResponseDocument / RawDataOutput
1566   */
1567  char *dfv=addDefaultValues(&request_input_real_format,s1->inputs,m,0);
1568  if(strcmp(dfv,"")!=0){
1569    char tmps[1024];
1570    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);
1571    map* tmpe=createMap("text",tmps);
1572    addToMap(tmpe,"code","MissingParameterValue");
1573    printExceptionReportResponse(m,tmpe);
1574    freeService(&s1);
1575    free(s1);
1576    freeMap(&tmpe);
1577    free(tmpe);
1578    freeMaps(&m);
1579    free(m);
1580    free(REQUEST);
1581    free(SERVICE_URL);
1582    freeMaps(&request_input_real_format);
1583    free(request_input_real_format);
1584    freeMaps(&request_output_real_format);
1585    free(request_output_real_format);
1586    freeMaps(&tmpmaps);
1587    free(tmpmaps);
1588    return 1;
1589  }
1590  addDefaultValues(&request_output_real_format,s1->outputs,m,1);
1591
1592  ensureDecodedBase64(&request_input_real_format);
1593
1594#ifdef DEBUG
1595  fprintf(stderr,"REQUEST_INPUTS\n");
1596  dumpMaps(request_input_real_format);
1597  fprintf(stderr,"REQUEST_OUTPUTS\n");
1598  dumpMaps(request_output_real_format);
1599#endif
1600
1601  maps* curs=getMaps(m,"env");
1602  if(curs!=NULL){
1603    map* mapcs=curs->content;
1604    while(mapcs!=NULLMAP){
1605#ifndef WIN32
1606      setenv(mapcs->name,mapcs->value,1);
1607#else
1608#ifdef DEBUG
1609      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1610#endif
1611      if(mapcs->value[strlen(mapcs->value)-2]=='\r'){
1612#ifdef DEBUG
1613        fprintf(stderr,"[ZOO: Env var finish with \r]\n");
1614#endif
1615        mapcs->value[strlen(mapcs->value)-1]=0;
1616      }
1617#ifdef DEBUG
1618      fflush(stderr);
1619      fprintf(stderr,"setting variable... %s\n",
1620#endif
1621              SetEnvironmentVariable(mapcs->name,mapcs->value)
1622#ifdef DEBUG
1623              ? "OK" : "FAILED");
1624#else
1625      ;
1626#endif
1627#ifdef DEBUG
1628      fflush(stderr);
1629#endif
1630#endif
1631#ifdef DEBUG
1632      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1633      fflush(stderr);
1634#endif
1635      mapcs=mapcs->next;
1636    }
1637  }
1638 
1639#ifdef DEBUG
1640  dumpMap(request_inputs);
1641#endif
1642
1643  /**
1644   * Need to check if we need to fork to load a status enabled
1645   */
1646  r_inputs=NULL;
1647  map* store=getMap(request_inputs,"storeExecuteResponse");
1648  map* status=getMap(request_inputs,"status");
1649  /**
1650   * 05-007r7 WPS 1.0.0 page 57 :
1651   * 'If status="true" and storeExecuteResponse is "false" then the service
1652   * shall raise an exception.'
1653   */
1654  if(status!=NULL && strcmp(status->value,"true")==0 && 
1655     store!=NULL && strcmp(store->value,"false")==0){
1656    errorException(m, _("Status cannot be set to true with storeExecuteResponse to false. Please, modify your request parameters."), "InvalidParameterValue");
1657    freeService(&s1);
1658    free(s1);
1659    freeMaps(&m);
1660    free(m);
1661   
1662    freeMaps(&request_input_real_format);
1663    free(request_input_real_format);
1664   
1665    freeMaps(&request_output_real_format);
1666    free(request_output_real_format);
1667   
1668    free(REQUEST);
1669    free(SERVICE_URL);
1670    return 1;
1671  }
1672  r_inputs=getMap(request_inputs,"storeExecuteResponse");
1673  int eres=SERVICE_STARTED;
1674  int cpid=getpid();
1675
1676  maps *_tmpMaps=(maps*)malloc(MAPS_SIZE);
1677  _tmpMaps->name=strdup("lenv");
1678  char tmpBuff[100];
1679  sprintf(tmpBuff,"%i",cpid);
1680  _tmpMaps->content=createMap("sid",tmpBuff);
1681  _tmpMaps->next=NULL;
1682  addToMap(_tmpMaps->content,"status","0");
1683  if(cgiCookie!=NULL && strlen(cgiCookie)>0){
1684    addToMap(_tmpMaps->content,"sessid",strstr(cgiCookie,"=")+1);
1685    char session_file_path[1024];
1686    map *tmpPath=getMapFromMaps(m,"main","sessPath");
1687    if(tmpPath==NULL)
1688      tmpPath=getMapFromMaps(m,"main","tmpPath");
1689    sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(cgiCookie,"=")+1);
1690    maps *tmpSess=(maps*)calloc(1,MAPS_SIZE);
1691    struct stat file_status;
1692    int istat = stat(session_file_path, &file_status);
1693    if(istat==0){
1694      conf_read(session_file_path,tmpSess);
1695      dumpMaps(tmpSess);
1696      addMapsToMaps(&m,tmpSess);
1697      freeMaps(&tmpSess);
1698    }
1699    free(tmpSess);
1700  }
1701  addMapsToMaps(&m,_tmpMaps);
1702  freeMaps(&_tmpMaps);
1703  free(_tmpMaps);
1704
1705#ifdef DEBUG
1706  dumpMap(request_inputs);
1707#endif
1708
1709  if(status!=NULL)
1710    if(strcasecmp(status->value,"false")==0)
1711      status=NULL;
1712  if(status==NULLMAP){
1713    loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
1714  }
1715  else{
1716    pid_t   pid;
1717#ifdef DEBUG
1718    fprintf(stderr,"\nPID : %d\n",cpid);
1719#endif
1720
1721#ifndef WIN32
1722    pid = fork ();
1723#else
1724    pid = 0;
1725#endif
1726    if (pid > 0) {
1727      /**
1728       * dady :
1729       * set status to SERVICE_ACCEPTED
1730       */
1731#ifdef DEBUG
1732      fprintf(stderr,"father pid continue (origin %d) %d ...\n",cpid,getpid());
1733#endif
1734      eres=SERVICE_ACCEPTED;
1735    }else if (pid == 0) {
1736      /**
1737       * son : have to close the stdout, stdin and stderr to let the parent
1738       * process answer to http client.
1739       */
1740      r_inputs=getMapFromMaps(m,"main","tmpPath");
1741      map* r_inputs1=getMap(s1->content,"ServiceProvider");
1742      char* fbkp=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+100)*sizeof(char));
1743      sprintf(fbkp,"%s/%s_%d.xml",r_inputs->value,r_inputs1->value,cpid);
1744      char* flog=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+100)*sizeof(char));
1745      sprintf(flog,"%s/%s_%d_error.log",r_inputs->value,r_inputs1->value,cpid);
1746#ifdef DEBUG
1747      fprintf(stderr,"RUN IN BACKGROUND MODE \n");
1748      fprintf(stderr,"son pid continue (origin %d) %d ...\n",cpid,getpid());
1749      fprintf(stderr,"\nFILE TO STORE DATA %s\n",r_inputs->value);
1750#endif
1751      freopen(fbkp , "w+", stdout);
1752      fclose(stdin);
1753      freopen(flog,"w+",stderr);
1754      free(fbkp);
1755      free(flog);
1756      /**
1757       * set status to SERVICE_STARTED and flush stdout to ensure full
1758       * content was outputed (the file used to store the ResponseDocument).
1759       * The rewind stdout to restart writing from the bgining of the file,
1760       * this way the data will be updated at the end of the process run.
1761       */
1762      updateStatus(m);
1763      printProcessResponse(m,request_inputs,cpid,
1764                            s1,r_inputs1->value,SERVICE_STARTED,
1765                            request_input_real_format,
1766                            request_output_real_format);
1767      fflush(stdout);
1768      rewind(stdout);
1769
1770      loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
1771
1772    } else {
1773      /**
1774       * error server don't accept the process need to output a valid
1775       * error response here !!!
1776       */
1777      eres=-1;
1778      errorException(m, _("Unable to run the child process properly"), "InternalError");
1779    }
1780  }
1781
1782#ifdef DEBUG
1783  dumpMaps(request_output_real_format);
1784  fprintf(stderr,"Function loaded and returned %d\n",eres);
1785  fflush(stderr);
1786#endif
1787  if(eres!=-1)
1788    outputResponse(s1,request_input_real_format,
1789                   request_output_real_format,request_inputs,
1790                   cpid,m,eres);
1791  /**
1792   * Ensure that if error occurs when freeing memory, no signal will return
1793   * an ExceptionReport document as the result was already returned to the
1794   * client.
1795   */
1796#ifndef USE_GDB
1797  (void) signal(SIGSEGV,donothing);
1798  (void) signal(SIGTERM,donothing);
1799  (void) signal(SIGINT,donothing);
1800  (void) signal(SIGILL,donothing);
1801  (void) signal(SIGFPE,donothing);
1802  (void) signal(SIGABRT,donothing);
1803#endif
1804
1805  if(((int)getpid())!=cpid){
1806    fclose(stdout);
1807    fclose(stderr);
1808    unhandleStatus(m);
1809  }
1810
1811  freeService(&s1);
1812  free(s1);
1813  freeMaps(&m);
1814  free(m);
1815 
1816  freeMaps(&request_input_real_format);
1817  free(request_input_real_format);
1818 
1819  freeMaps(&request_output_real_format);
1820  free(request_output_real_format);
1821 
1822  free(REQUEST);
1823  free(SERVICE_URL);
1824#ifdef DEBUG
1825  fprintf(stderr,"Processed response \n");
1826  fflush(stdout);
1827  fflush(stderr);
1828#endif
1829
1830  return 0;
1831}
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