source: trunk/zoo-project/zoo-kernel/zoo_service_loader.c @ 527

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

Fix #106 and #108

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 76.9 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2008-2013 GeoLabs SARL. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#define length(x) (sizeof(x) / sizeof(x[0]))
26
27extern "C" int yylex();
28extern "C" int crlex();
29
30#include "cgic.h"
31
32extern "C" {
33#include <libxml/tree.h>
34#include <libxml/xmlmemory.h>
35#include <libxml/parser.h>
36#include <libxml/xpath.h>
37#include <libxml/xpathInternals.h>
38}
39
40#include "ulinet.h"
41
42#include <libintl.h>
43#include <locale.h>
44#include <string.h>
45
46#include "service.h"
47
48#include "service_internal.h"
49
50#ifdef USE_PYTHON
51#include "service_internal_python.h"
52#endif
53
54#ifdef USE_JAVA
55#include "service_internal_java.h"
56#endif
57
58#ifdef USE_PHP
59#include "service_internal_php.h"
60#endif
61
62#ifdef USE_JS
63#include "service_internal_js.h"
64#endif
65
66#ifdef USE_RUBY
67#include "service_internal_ruby.h"
68#endif
69
70#ifdef USE_PERL
71#include "service_internal_perl.h"
72#endif
73
74#include <dirent.h>
75#include <signal.h>
76#include <unistd.h>
77#ifndef WIN32
78#include <dlfcn.h>
79#include <libgen.h>
80#else
81#include <windows.h>
82#include <direct.h>
83#include <sys/types.h>
84#include <sys/stat.h>
85#include <unistd.h>
86#define pid_t int;
87#endif
88#include <fcntl.h>
89#include <time.h>
90#include <stdarg.h>
91
92#ifdef WIN32
93extern "C" {
94  __declspec(dllexport) char *strcasestr(char const *a, char const *b)
95#ifndef USE_MS
96 { 
97  char *x=zStrdup(a); 
98  char *y=zStrdup(b); 
99 
100  x=_strlwr(x); 
101  y=_strlwr(y); 
102  char *pos = strstr(x, y); 
103  char *ret = pos == NULL ? NULL : (char *)(a + (pos-x)); 
104  free(x); 
105  free(y); 
106  return ret; 
107 };
108#else
109  ;
110#endif
111}
112#endif
113
114#define _(String) dgettext ("zoo-kernel",String)
115#define __(String) dgettext ("zoo-service",String)
116
117extern   int getServiceFromFile(maps*,const char*,service**);
118
119int readServiceFile(maps* conf, char* file,service** service,char *name){
120  int t=getServiceFromFile(conf,file,service);
121#ifdef YAML
122  if(t<0){
123    t=getServiceFromYAML(conf,file,service,name);
124  }
125#endif
126  return t;
127}
128
129void translateChar(char* str,char toReplace,char toReplaceBy){
130  int i=0,len=strlen(str);
131  for(i=0;i<len;i++){
132    if(str[i]==toReplace)
133      str[i]=toReplaceBy;
134  }
135}
136
137/**
138 * Create (or append to) an array valued maps
139 * value = "["",""]"
140 */
141int appendMapsToMaps(maps* m,maps* mo,maps* mi,elements* elem){
142  maps* tmpMaps=getMaps(mo,mi->name);
143  map* tmap=getMapType(tmpMaps->content);
144  elements* el=getElements(elem,mi->name);
145  int hasEl=1;
146  if(el==NULL)
147    hasEl=-1;
148  if(tmap==NULL){
149    if(hasEl>0)
150      tmap=getMapType(el->defaults->content);     
151  }
152
153  map* testMap=NULL;
154  if(hasEl>0){
155    testMap=getMap(el->content,"maxOccurs");
156  }else{
157    testMap=createMap("maxOccurs","unbounded");
158  }
159
160  if(testMap!=NULL){
161    if(strncasecmp(testMap->value,"unbounded",9)!=0 && atoi(testMap->value)>1){
162      if(addMapsArrayToMaps(&mo,mi,tmap->name)<0){
163        char emsg[1024];
164        sprintf(emsg,_("You set maximum occurences for <%s> as %i but you tried to use it more than the limit you set. Please correct your ZCFG file or your request."),mi->name,atoi(testMap->value));
165        errorException(m,emsg,"InternalError",NULL);
166        return -1;
167      }
168    }else{
169      if(strncasecmp(testMap->value,"unbounded",9)==0){
170        if(hasEl<0){
171          freeMap(&testMap);
172          free(testMap);
173        }
174        if(addMapsArrayToMaps(&mo,mi,tmap->name)<0){
175          char emsg[1024];
176          map* tmpMap=getMap(mi->content,"length");
177          sprintf(emsg,_("ZOO-Kernel was unable to load your data for %s position %s."),mi->name,tmpMap->value);
178          errorException(m,emsg,"InternalError",NULL);
179          return -1;
180        }
181      }
182      else{
183        char emsg[1024];
184        sprintf(emsg,_("You set maximum occurences for <%s> to one but you tried to use it more than once. Please correct your ZCFG file or your request."),mi->name);
185        errorException(m,emsg,"InternalError",NULL);
186        return -1;
187      }
188    }
189  }
190  return 0;
191}
192
193int recursReaddirF(maps* m,xmlNodePtr n,char *conf_dir,char *prefix,int saved_stdout,int level,void (func) (maps*,xmlNodePtr,service*)){
194  struct dirent *dp;
195  int scount=0;
196
197  if(conf_dir==NULL)
198    return 1;
199  DIR *dirp = opendir(conf_dir);
200  if(dirp==NULL){
201    if(level>0)
202      return 1;
203    else
204      return -1;
205  }
206  char tmp1[25];
207  sprintf(tmp1,"sprefix_%d",level);
208  char levels[17];
209  sprintf(levels,"%d",level);
210  setMapInMaps(m,"lenv","level",levels);
211  while ((dp = readdir(dirp)) != NULL)
212    if((dp->d_type==DT_DIR || dp->d_type==DT_LNK) && dp->d_name[0]!='.' && strstr(dp->d_name,".")==NULL){
213
214      char *tmp=(char*)malloc((strlen(conf_dir)+strlen(dp->d_name)+2)*sizeof(char));
215      sprintf(tmp,"%s/%s",conf_dir,dp->d_name);
216
217      if(prefix!=NULL){
218        prefix=NULL;
219      }
220      prefix=(char*)malloc((strlen(dp->d_name)+2)*sizeof(char));
221      sprintf(prefix,"%s.",dp->d_name);
222     
223      //map* tmpMap=getMapFromMaps(m,"lenv",tmp1);
224     
225      int res;
226      if(prefix!=NULL){
227        setMapInMaps(m,"lenv",tmp1,prefix);
228        char levels1[17];
229        sprintf(levels1,"%d",level+1);
230        setMapInMaps(m,"lenv","level",levels1);
231        res=recursReaddirF(m,n,tmp,prefix,saved_stdout,level+1,func);
232        sprintf(levels1,"%d",level);
233        setMapInMaps(m,"lenv","level",levels1);
234        free(prefix);
235        prefix=NULL;
236      }else
237        res=-1;
238      free(tmp);
239      if(res<0){
240        return res;
241      }
242    }
243    else{
244      if(dp->d_name[0]!='.' && strstr(dp->d_name,".zcfg")!=0){
245        int t;
246        char tmps1[1024];
247        memset(tmps1,0,1024);
248        snprintf(tmps1,1024,"%s/%s",conf_dir,dp->d_name);
249        service* s1=(service*)malloc(SERVICE_SIZE);
250        if(s1 == NULL){ 
251          dup2(saved_stdout,fileno(stdout));
252          errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
253          return -1;
254        }
255#ifdef DEBUG
256        fprintf(stderr,"#################\n%s\n#################\n",tmps1);
257#endif
258        t=readServiceFile(m,tmps1,&s1,dp->d_name);
259
260        if(t<0){
261          map* tmp00=getMapFromMaps(m,"lenv","message");
262          char tmp01[1024];
263          if(tmp00!=NULL)
264            sprintf(tmp01,_("Unable to parse the ZCFG file: %s (%s)"),dp->d_name,tmp00->value);
265          else
266            sprintf(tmp01,_("Unable to parse the ZCFG file: %s."),dp->d_name);
267          dup2(saved_stdout,fileno(stdout));
268          errorException(m, tmp01,"InternalError",NULL);
269          return -1;
270        }
271#ifdef DEBUG
272        dumpService(s1);
273        fflush(stdout);
274        fflush(stderr);
275#endif
276        func(m,n,s1);
277        freeService(&s1);
278        free(s1);
279        scount++;
280      }
281    }
282  (void)closedir(dirp);
283  return 1;
284}
285
286xmlXPathObjectPtr extractFromDoc(xmlDocPtr doc,const char* search){
287  xmlXPathContextPtr xpathCtx;
288  xmlXPathObjectPtr xpathObj;
289  xpathCtx = xmlXPathNewContext(doc);
290  xpathObj = xmlXPathEvalExpression(BAD_CAST search,xpathCtx);
291  xmlXPathFreeContext(xpathCtx);
292  return xpathObj;
293}
294
295void donothing(int sig){
296#ifdef DEBUG
297  fprintf(stderr,"Signal %d after the ZOO-Kernel returned result !\n",sig);
298#endif
299  exit(0);
300}
301
302void sig_handler(int sig){
303  char tmp[100];
304  const char *ssig;
305  switch(sig){
306  case SIGSEGV:
307    ssig="SIGSEGV";
308    break;
309  case SIGTERM:
310    ssig="SIGTERM";
311    break;
312  case SIGINT:
313    ssig="SIGINT";
314    break;
315  case SIGILL:
316    ssig="SIGILL";
317    break;
318  case SIGFPE:
319    ssig="SIGFPE";
320    break;
321  case SIGABRT:
322    ssig="SIGABRT";
323    break;
324  default:
325    ssig="UNKNOWN";
326    break;
327  }
328  sprintf(tmp,_("ZOO Kernel failed to process your request receiving signal %d = %s"),sig,ssig);
329  errorException(NULL, tmp, "InternalError",NULL);
330#ifdef DEBUG
331  fprintf(stderr,"Not this time!\n");
332#endif
333  exit(0);
334}
335
336void loadServiceAndRun(maps **myMap,service* s1,map* request_inputs,maps **inputs,maps** ioutputs,int* eres){
337  char tmps1[1024];
338  char ntmp[1024];
339  maps *m=*myMap;
340  maps *request_output_real_format=*ioutputs;
341  maps *request_input_real_format=*inputs;
342  /**
343   * Extract serviceType to know what kind of service should be loaded
344   */
345  map* r_inputs=NULL;
346#ifndef WIN32
347  getcwd(ntmp,1024);
348#else
349  _getcwd(ntmp,1024);
350#endif
351  r_inputs=getMap(s1->content,"serviceType");
352#ifdef DEBUG
353  fprintf(stderr,"LOAD A %s SERVICE PROVIDER \n",r_inputs->value);
354  fflush(stderr);
355#endif
356  if(strlen(r_inputs->value)==1 && strncasecmp(r_inputs->value,"C",1)==0){
357    r_inputs=getMap(request_inputs,"metapath");
358    if(r_inputs!=NULL)
359      sprintf(tmps1,"%s/%s",ntmp,r_inputs->value);
360    else
361      sprintf(tmps1,"%s/",ntmp);
362    char *altPath=zStrdup(tmps1);
363    r_inputs=getMap(s1->content,"ServiceProvider");
364    sprintf(tmps1,"%s/%s",altPath,r_inputs->value);
365    free(altPath);
366#ifdef DEBUG
367    fprintf(stderr,"Trying to load %s\n",tmps1);
368#endif
369#ifdef WIN32
370    HINSTANCE so = LoadLibraryEx(tmps1,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
371#else
372    void* so = dlopen(tmps1, RTLD_LAZY);
373#endif
374#ifdef WIN32
375    DWORD errstr;
376    errstr = GetLastError();
377#else
378    char *errstr;
379    errstr = dlerror();
380#endif
381#ifdef DEBUG
382    fprintf(stderr,"%s loaded (%d) \n",tmps1,errstr);
383#endif
384    if( so != NULL ) {
385#ifdef DEBUG
386      fprintf(stderr,"Library loaded %s \n",errstr);
387      fprintf(stderr,"Service Shared Object = %s\n",r_inputs->value);
388#endif
389      r_inputs=getMap(s1->content,"serviceType");
390#ifdef DEBUG
391      dumpMap(r_inputs);
392      fprintf(stderr,"%s\n",r_inputs->value);
393      fflush(stderr);
394#endif
395      if(strncasecmp(r_inputs->value,"C-FORTRAN",9)==0){
396        r_inputs=getMap(request_inputs,"Identifier");
397        char fname[1024];
398        sprintf(fname,"%s_",r_inputs->value);
399#ifdef DEBUG
400        fprintf(stderr,"Try to load function %s\n",fname);
401#endif
402#ifdef WIN32
403        typedef int (CALLBACK* execute_t)(char***,char***,char***);
404        execute_t execute=(execute_t)GetProcAddress(so,fname);
405#else
406        typedef int (*execute_t)(char***,char***,char***);
407        execute_t execute=(execute_t)dlsym(so,fname);
408#endif
409#ifdef DEBUG
410#ifdef WIN32
411        errstr = GetLastError();
412#else
413        errstr = dlerror();
414#endif
415        fprintf(stderr,"Function loaded %s\n",errstr);
416#endif 
417
418        char main_conf[10][30][1024];
419        char inputs[10][30][1024];
420        char outputs[10][30][1024];
421        for(int i=0;i<10;i++){
422          for(int j=0;j<30;j++){
423            memset(main_conf[i][j],0,1024);
424            memset(inputs[i][j],0,1024);
425            memset(outputs[i][j],0,1024);
426          }
427        }
428        mapsToCharXXX(m,(char***)main_conf);
429        mapsToCharXXX(request_input_real_format,(char***)inputs);
430        mapsToCharXXX(request_output_real_format,(char***)outputs);
431        *eres=execute((char***)&main_conf[0],(char***)&inputs[0],(char***)&outputs[0]);
432#ifdef DEBUG
433        fprintf(stderr,"Function run successfully \n");
434#endif
435        charxxxToMaps((char***)&outputs[0],&request_output_real_format);
436      }else{
437#ifdef DEBUG
438#ifdef WIN32
439        errstr = GetLastError();
440        fprintf(stderr,"Function %s failed to load because of %d\n",r_inputs->value,errstr);
441#endif
442#endif
443        r_inputs=getMapFromMaps(m,"lenv","Identifier");
444#ifdef DEBUG
445        fprintf(stderr,"Try to load function %s\n",r_inputs->value);
446#endif
447        typedef int (*execute_t)(maps**,maps**,maps**);
448#ifdef WIN32
449        execute_t execute=(execute_t)GetProcAddress(so,r_inputs->value); 
450#else
451        execute_t execute=(execute_t)dlsym(so,r_inputs->value);
452#endif
453
454        if(execute==NULL){
455#ifdef WIN32
456          errstr = GetLastError();
457#else
458          errstr = dlerror();
459#endif
460          char *tmpMsg=(char*)malloc(2048+strlen(r_inputs->value));
461          sprintf(tmpMsg,_("Error occured while running the %s function: %s"),r_inputs->value,errstr);
462          errorException(m, tmpMsg, "InternalError",NULL);
463          free(tmpMsg);
464#ifdef DEBUG
465          fprintf(stderr,"Function %s error %s\n",r_inputs->value,errstr);
466#endif
467          *eres=-1;
468          return;
469        }
470
471#ifdef DEBUG
472#ifdef WIN32
473        errstr = GetLastError();
474#else
475        errstr = dlerror();
476#endif
477        fprintf(stderr,"Function loaded %s\n",errstr);
478#endif 
479
480#ifdef DEBUG
481        fprintf(stderr,"Now run the function \n");
482        fflush(stderr);
483#endif
484        *eres=execute(&m,&request_input_real_format,&request_output_real_format);
485#ifdef DEBUG
486        fprintf(stderr,"Function loaded and returned %d\n",eres);
487        fflush(stderr);
488#endif
489      }
490#ifdef WIN32
491      *ioutputs=dupMaps(&request_output_real_format);
492      FreeLibrary(so);
493#else
494      dlclose(so);
495#endif
496    } else {
497      /**
498       * Unable to load the specified shared library
499       */
500      char tmps[1024];
501#ifdef WIN32
502      DWORD errstr = GetLastError();
503#else
504      char* errstr = dlerror();
505#endif
506      sprintf(tmps,_("C Library can't be loaded %s"),errstr);
507      map* tmps1=createMap("text",tmps);
508      printExceptionReportResponse(m,tmps1);
509      *eres=-1;
510      freeMap(&tmps1);
511      free(tmps1);
512    }
513  }
514  else
515#ifdef USE_PYTHON
516    if(strncasecmp(r_inputs->value,"PYTHON",6)==0){
517      *eres=zoo_python_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
518    }
519    else
520#endif
521       
522#ifdef USE_JAVA
523      if(strncasecmp(r_inputs->value,"JAVA",4)==0){
524        *eres=zoo_java_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
525      }
526      else
527#endif
528
529#ifdef USE_PHP
530        if(strncasecmp(r_inputs->value,"PHP",3)==0){
531          *eres=zoo_php_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
532        }
533        else
534#endif
535           
536           
537#ifdef USE_PERL
538          if(strncasecmp(r_inputs->value,"PERL",4)==0){
539            *eres=zoo_perl_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
540          }
541          else
542#endif
543
544#ifdef USE_JS
545            if(strncasecmp(r_inputs->value,"JS",2)==0){
546              *eres=zoo_js_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
547            }
548            else
549#endif
550
551#ifdef USE_RUBY
552          if(strncasecmp(r_inputs->value,"Ruby",4)==0){
553            *eres=zoo_ruby_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
554          }
555          else
556#endif
557
558              {
559                char tmpv[1024];
560                sprintf(tmpv,_("Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n"),r_inputs->value);
561                map* tmps=createMap("text",tmpv);
562                printExceptionReportResponse(m,tmps);
563                *eres=-1;
564              }
565  *myMap=m;
566  *ioutputs=request_output_real_format;
567}
568
569
570#ifdef WIN32
571/**
572 * createProcess function: create a new process after setting some env variables
573 */
574void createProcess(maps* m,map* request_inputs,service* s1,char* opts,int cpid, maps* inputs,maps* outputs){
575  STARTUPINFO si;
576  PROCESS_INFORMATION pi;
577  ZeroMemory( &si, sizeof(si) );
578  si.cb = sizeof(si);
579  ZeroMemory( &pi, sizeof(pi) );
580  char *tmp=(char *)malloc((1024+cgiContentLength)*sizeof(char));
581  char *tmpq=(char *)malloc((1024+cgiContentLength)*sizeof(char));
582  map *req=getMap(request_inputs,"request");
583  map *id=getMap(request_inputs,"identifier");
584  map *di=getMap(request_inputs,"DataInputs");
585
586  char *dataInputsKVP=getMapsAsKVP(inputs,cgiContentLength,0);
587  char *dataOutputsKVP=getMapsAsKVP(outputs,cgiContentLength,1);
588#ifdef DEBUG
589  fprintf(stderr,"DATAINPUTSKVP %s\n",dataInputsKVP);
590  fprintf(stderr,"DATAOUTPUTSKVP %s\n",dataOutputsKVP);
591#endif
592  map *sid=getMapFromMaps(m,"lenv","sid");
593  map* r_inputs=getMapFromMaps(m,"main","tmpPath");
594  map* r_inputs1=getMap(request_inputs,"metapath");
595  int hasIn=-1;
596  if(r_inputs1==NULL){
597    r_inputs1=createMap("metapath","");
598    hasIn=1;
599  }
600  map* r_inputs2=getMap(request_inputs,"ResponseDocument");
601  if(r_inputs2==NULL)
602    r_inputs2=getMap(request_inputs,"RawDataOutput");
603  map *tmpPath=getMapFromMaps(m,"lenv","cwd");
604
605  map *tmpReq=getMap(request_inputs,"xrequest");
606  if(r_inputs2!=NULL){
607    sprintf(tmp,"\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s&cgiSid=%s\"",r_inputs1->value,req->value,id->value,dataInputsKVP,r_inputs2->name,dataOutputsKVP,sid->value);
608    sprintf(tmpq,"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s",r_inputs1->value,req->value,id->value,dataInputsKVP,r_inputs2->name,dataOutputsKVP);
609  }
610  else{
611    sprintf(tmp,"\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&cgiSid=%s\"",r_inputs1->value,req->value,id->value,dataInputsKVP,sid->value);
612    sprintf(tmpq,"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s",r_inputs1->value,req->value,id->value,dataInputsKVP,sid->value);
613  }
614 
615  if(hasIn>0){
616    freeMap(&r_inputs1);
617    free(r_inputs1);
618  }
619  char *tmp1=zStrdup(tmp);
620  sprintf(tmp,"\"zoo_loader.cgi\" %s \"%s\"",tmp1,sid->value);
621 
622  free(dataInputsKVP);
623  free(dataOutputsKVP);
624#ifdef DEBUG
625  fprintf(stderr,"REQUEST IS : %s \n",tmp);
626#endif
627  SetEnvironmentVariable("CGISID",TEXT(sid->value));
628  SetEnvironmentVariable("QUERY_STRING",TEXT(tmpq));
629  char clen[1000];
630  sprintf(clen,"%d",strlen(tmpq));
631  SetEnvironmentVariable("CONTENT_LENGTH",TEXT(clen));
632 
633  if( !CreateProcess( NULL,             // No module name (use command line)
634                      TEXT(tmp),        // Command line
635                      NULL,             // Process handle not inheritable
636                      NULL,             // Thread handle not inheritable
637                      FALSE,            // Set handle inheritance to FALSE
638                      CREATE_NO_WINDOW, // Apache won't wait until the end
639                      NULL,             // Use parent's environment block
640                      NULL,             // Use parent's starting directory
641                      &si,              // Pointer to STARTUPINFO struct
642                      &pi )             // Pointer to PROCESS_INFORMATION struct
643      ) 
644    { 
645#ifdef DEBUG
646      fprintf( stderr, "CreateProcess failed (%d).\n", GetLastError() );
647#endif
648      return ;
649    }else{
650#ifdef DEBUG
651    fprintf( stderr, "CreateProcess successfull (%d).\n\n\n\n", GetLastError() );
652#endif
653  }
654  CloseHandle( pi.hProcess );
655  CloseHandle( pi.hThread );
656#ifdef DEBUG
657  fprintf(stderr,"CreateProcess finished !\n");
658#endif
659}
660#endif
661
662int runRequest(map** inputs)
663{
664 
665#ifndef USE_GDB
666  signal(SIGCHLD, SIG_IGN);
667  signal(SIGSEGV,sig_handler);
668  signal(SIGTERM,sig_handler);
669  signal(SIGINT,sig_handler);
670  signal(SIGILL,sig_handler);
671  signal(SIGFPE,sig_handler);
672  signal(SIGABRT,sig_handler);
673#endif
674
675  map* r_inputs=NULL;
676  map* request_inputs=*inputs;
677  maps* m=NULL;
678  char* REQUEST=NULL;
679  /**
680   * Parsing service specfic configuration file
681   */
682  m=(maps*)malloc(MAPS_SIZE);
683  if(m == NULL){
684    return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
685  }
686  char ntmp[1024];
687#ifndef WIN32
688  getcwd(ntmp,1024);
689#else
690  _getcwd(ntmp,1024);
691#endif
692  r_inputs=getMapOrFill(&request_inputs,"metapath","");
693
694
695  char conf_file[10240];
696  snprintf(conf_file,10240,"%s/%s/main.cfg",ntmp,r_inputs->value);
697  if(conf_read(conf_file,m)==2){
698    errorException(NULL, _("Unable to load the main.cfg file."),"InternalError",NULL);
699    free(m);
700    return 1;
701  }
702#ifdef DEBUG
703  fprintf(stderr, "***** BEGIN MAPS\n"); 
704  dumpMaps(m);
705  fprintf(stderr, "***** END MAPS\n");
706#endif
707
708  map *getPath=getMapFromMaps(m,"main","gettextPath");
709  if(getPath!=NULL){
710    bindtextdomain ("zoo-kernel",getPath->value);
711    bindtextdomain ("zoo-services",getPath->value);   
712  }else{
713    bindtextdomain ("zoo-kernel","/usr/share/locale/");
714    bindtextdomain ("zoo-services","/usr/share/locale/");
715  }
716
717
718  /**
719   * Manage our own error log file (usefull to separate standard apache debug
720   * messages from the ZOO-Kernel ones but also for IIS users to avoid wrong
721   * headers messages returned by the CGI due to wrong redirection of stderr)
722   */
723  FILE * fstde=NULL;
724  map* fstdem=getMapFromMaps(m,"main","logPath");
725  if(fstdem!=NULL)
726    fstde = freopen(fstdem->value, "a+", stderr) ;
727
728  r_inputs=getMap(request_inputs,"language");
729  if(r_inputs==NULL)
730    r_inputs=getMapFromMaps(m,"main","language");
731  if(r_inputs!=NULL){
732    if(isValidLang(m,r_inputs->value)<0){
733      char tmp[1024];
734      sprintf(tmp,_("The value %s is not supported for the <language> parameter"),
735              r_inputs->value);
736      errorException(m, tmp,"InvalidParameterValue","language");
737      freeMaps(&m);
738      free(m);
739      free(REQUEST);
740      return 1;
741
742    }
743    char *tmp=zStrdup(r_inputs->value);
744    setMapInMaps(m,"main","language",tmp);
745#ifdef DEB
746    char tmp2[12];
747    sprintf(tmp2,"%s.utf-8",tmp);
748    translateChar(tmp2,'-','_');
749    setlocale (LC_ALL, tmp2);
750#else
751    translateChar(tmp,'-','_');
752    setlocale (LC_ALL, tmp);
753#endif
754#ifndef WIN32
755    setenv("LC_ALL",tmp,1);
756#else
757    char tmp1[12];
758    sprintf(tmp1,"LC_ALL=%s",tmp);
759    putenv(tmp1);
760#endif
761    free(tmp);
762  }
763  else{
764    setlocale (LC_ALL, "en_US");
765#ifndef WIN32
766    setenv("LC_ALL","en_US",1);
767#else
768    char tmp1[12];
769    sprintf(tmp1,"LC_ALL=en_US");
770    putenv(tmp1);
771#endif
772    setMapInMaps(m,"main","language","en-US");
773  }
774  setlocale (LC_NUMERIC, "en_US");
775  bind_textdomain_codeset("zoo-kernel","UTF-8");
776  textdomain("zoo-kernel");
777  bind_textdomain_codeset("zoo-services","UTF-8");
778  textdomain("zoo-services");
779
780  map* lsoap=getMap(request_inputs,"soap");
781  if(lsoap!=NULL && strcasecmp(lsoap->value,"true")==0)
782    setMapInMaps(m,"main","isSoap","true");
783  else
784    setMapInMaps(m,"main","isSoap","false");
785
786  if(strlen(cgiServerName)>0){
787    char tmpUrl[1024];
788    if(strncmp(cgiServerPort,"80",2)==0){
789      sprintf(tmpUrl,"http://%s%s",cgiServerName,cgiScriptName);
790    }else{
791      sprintf(tmpUrl,"http://%s:%s%s",cgiServerName,cgiServerPort,cgiScriptName);
792    }
793#ifdef DEBUG
794    fprintf(stderr,"*** %s ***\n",tmpUrl);
795#endif
796    setMapInMaps(m,"main","serverAddress",tmpUrl);
797  }
798
799  /**
800   * Check for minimum inputs
801   */
802  r_inputs=getMap(request_inputs,"Request");
803  if(request_inputs==NULL || r_inputs==NULL){ 
804    errorException(m, _("Parameter <request> was not specified"),"MissingParameterValue","request");
805    if(count(request_inputs)==1){
806      freeMap(&request_inputs);
807      free(request_inputs);
808    }
809    freeMaps(&m);
810    free(m);
811    return 1;
812  }
813  else{
814    REQUEST=zStrdup(r_inputs->value);
815    if(strncasecmp(r_inputs->value,"GetCapabilities",15)!=0
816       && strncasecmp(r_inputs->value,"DescribeProcess",15)!=0
817       && strncasecmp(r_inputs->value,"Execute",7)!=0){ 
818      errorException(m, _("Unenderstood <request> value. Please check that it was set to GetCapabilities, DescribeProcess or Execute."), "OperationNotSupported",r_inputs->value);
819      freeMaps(&m);
820      free(m);
821      free(REQUEST);
822      return 1;
823    }
824  }
825  r_inputs=NULL;
826  r_inputs=getMap(request_inputs,"Service");
827  if(r_inputs==NULLMAP){
828    errorException(m, _("Parameter <service> was not specified"),"MissingParameterValue","service");
829    freeMaps(&m);
830    free(m);
831    free(REQUEST);
832    return 1;
833  }else{
834    if(strcasecmp(r_inputs->value,"WPS")!=0){
835      errorException(m, _("Unenderstood <service> value, WPS is the only acceptable value."), "InvalidParameterValue","service");
836      freeMaps(&m);
837      free(m);
838      free(REQUEST);
839      return 1;
840    }
841  }
842  if(strncasecmp(REQUEST,"GetCapabilities",15)!=0){
843    r_inputs=getMap(request_inputs,"Version");
844    if(r_inputs==NULL){ 
845      errorException(m, _("Parameter <version> was not specified"),"MissingParameterValue","version");
846      freeMaps(&m);
847      free(m);
848      free(REQUEST);
849      return 1;
850    }else{
851      if(strcasecmp(r_inputs->value,"1.0.0")!=0){
852        errorException(m, _("Unenderstood <version> value, 1.0.0 is the only acceptable value."), "InvalidParameterValue","service");
853        freeMaps(&m);
854        free(m);
855        free(REQUEST);
856        return 1;
857      }
858    } 
859  }else{
860    r_inputs=getMap(request_inputs,"AcceptVersions");
861    if(r_inputs!=NULL){ 
862      if(strncmp(r_inputs->value,"1.0.0",5)!=0){
863        errorException(m, _("Unenderstood <AcceptVersions> value, 1.0.0 is the only acceptable value."), "VersionNegotiationFailed",NULL);
864        freeMaps(&m);
865        free(m);
866        free(REQUEST);
867        return 1;
868      }
869    }
870  }
871
872  r_inputs=getMap(request_inputs,"serviceprovider");
873  if(r_inputs==NULL){
874    addToMap(request_inputs,"serviceprovider","");
875  }
876
877  maps* request_output_real_format=NULL;
878  map* tmpm=getMapFromMaps(m,"main","serverAddress");
879  if(tmpm!=NULL)
880    SERVICE_URL=zStrdup(tmpm->value);
881  else
882    SERVICE_URL=zStrdup(DEFAULT_SERVICE_URL);
883
884  service* s1;
885  int scount=0;
886#ifdef DEBUG
887  dumpMap(r_inputs);
888#endif
889  char conf_dir[1024];
890  int t;
891  char tmps1[1024];
892
893  r_inputs=NULL;
894  r_inputs=getMap(request_inputs,"metapath");
895  if(r_inputs!=NULL)
896    snprintf(conf_dir,1024,"%s/%s",ntmp,r_inputs->value);
897  else
898    snprintf(conf_dir,1024,"%s",ntmp);
899
900  if(strncasecmp(REQUEST,"GetCapabilities",15)==0){
901#ifdef DEBUG
902    dumpMap(r_inputs);
903#endif
904    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
905    r_inputs=NULL;
906    r_inputs=getMap(request_inputs,"ServiceProvider");
907    xmlNodePtr n;
908    if(r_inputs!=NULL)
909      n = printGetCapabilitiesHeader(doc,r_inputs->value,m);
910    else
911      n = printGetCapabilitiesHeader(doc,"",m);
912    /**
913     * Here we need to close stdout to ensure that not supported chars
914     * has been found in the zcfg and then printed on stdout
915     */
916    int saved_stdout = dup(fileno(stdout));
917    dup2(fileno(stderr),fileno(stdout));
918    if(int res=recursReaddirF(m,n,conf_dir,NULL,saved_stdout,0,printGetCapabilitiesForProcess)<0){
919      freeMaps(&m);
920      free(m);
921      free(REQUEST);
922      free(SERVICE_URL);
923      fflush(stdout);
924      return res;
925    }
926    dup2(saved_stdout,fileno(stdout));
927    printDocument(m,doc,getpid());
928    freeMaps(&m);
929    free(m);
930    free(REQUEST);
931    free(SERVICE_URL);
932    fflush(stdout);
933    return 0;
934  }
935  else{
936    r_inputs=getMap(request_inputs,"Identifier");
937    if(r_inputs==NULL 
938       || strlen(r_inputs->name)==0 || strlen(r_inputs->value)==0){ 
939      errorException(m, _("Mandatory <identifier> was not specified"),"MissingParameterValue","identifier");
940      freeMaps(&m);
941      free(m);
942      free(REQUEST);
943      free(SERVICE_URL);
944      return 0;
945    }
946
947    struct dirent *dp;
948    DIR *dirp = opendir(conf_dir);
949    if(dirp==NULL){
950      errorException(m, _("The specified path path doesn't exist."),"InvalidParameterValue",conf_dir);
951      freeMaps(&m);
952      free(m);
953      free(REQUEST);
954      free(SERVICE_URL);
955      return 0;
956    }
957    if(strncasecmp(REQUEST,"DescribeProcess",15)==0){
958      /**
959       * Loop over Identifier list
960       */
961      xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
962      r_inputs=NULL;
963      r_inputs=getMap(request_inputs,"ServiceProvider");
964
965      xmlNodePtr n;
966      if(r_inputs!=NULL)
967        n = printDescribeProcessHeader(doc,r_inputs->value,m);
968      else
969        n = printDescribeProcessHeader(doc,"",m);
970
971      r_inputs=getMap(request_inputs,"Identifier");
972     
973      char *orig=zStrdup(r_inputs->value);
974
975      int saved_stdout = dup(fileno(stdout));
976      dup2(fileno(stderr),fileno(stdout));
977      if(strcasecmp("all",orig)==0){
978        if(int res=recursReaddirF(m,n,conf_dir,NULL,saved_stdout,0,printDescribeProcessForProcess)<0)
979          return res;
980      }
981      else{
982        char *saveptr;
983        char *tmps=strtok_r(orig,",",&saveptr);
984       
985        char buff[256];
986        char buff1[1024];
987        while(tmps!=NULL){
988          int hasVal=-1;
989          char *corig=zStrdup(tmps);
990          if(strstr(corig,".")!=NULL){
991           
992            parseIdentifier(m,conf_dir,corig,buff1);
993            map* tmpMap=getMapFromMaps(m,"lenv","metapath");
994            if(tmpMap!=NULL)
995              addToMap(request_inputs,"metapath",tmpMap->value);
996
997            s1=(service*)malloc(SERVICE_SIZE);
998            t=readServiceFile(m,buff1,&s1,corig);
999            if(t<0){
1000              map* tmp00=getMapFromMaps(m,"lenv","message");
1001              char tmp01[1024];
1002              if(tmp00!=NULL)
1003                sprintf(tmp01,_("Unable to parse the ZCFG file for the following ZOO-Service: %s. Message: %s"),tmps,tmp00->value);
1004              else
1005                sprintf(tmp01,_("Unable to parse the ZCFG file for the following ZOO-Service: %s."),tmps);
1006              dup2(saved_stdout,fileno(stdout));
1007              errorException(m, tmp01,"InvalidParameterValue","identifier");
1008              freeMaps(&m);
1009              free(m);
1010              free(REQUEST);
1011              free(corig);
1012              free(orig);
1013              free(SERVICE_URL);
1014              free(s1);
1015              closedir(dirp);
1016              xmlFreeDoc(doc);
1017              xmlCleanupParser();
1018              zooXmlCleanupNs();
1019              return 1;
1020            }
1021#ifdef DEBUG
1022            dumpService(s1);
1023#endif
1024            printDescribeProcessForProcess(m,n,s1);
1025            freeService(&s1);
1026            free(s1);
1027            s1=NULL;
1028            scount++;
1029            hasVal=1;
1030            setMapInMaps(m,"lenv","level","0");
1031          }else{
1032            memset(buff,0,256);
1033            snprintf(buff,256,"%s.zcfg",corig);
1034            memset(buff1,0,1024);
1035#ifdef DEBUG
1036            printf("\n#######%s\n########\n",buff);
1037#endif
1038            while ((dp = readdir(dirp)) != NULL){
1039              if( strcasecmp(dp->d_name,buff)==0 ){
1040                memset(buff1,0,1024);
1041                snprintf(buff1,1024,"%s/%s",conf_dir,dp->d_name);
1042                s1=(service*)malloc(SERVICE_SIZE);
1043                if(s1 == NULL){
1044                  dup2(saved_stdout,fileno(stdout));
1045                  return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
1046                }
1047#ifdef DEBUG
1048                printf("#################\n(%s) %s\n#################\n",r_inputs->value,buff1);
1049#endif
1050                char *tmp0=zStrdup(dp->d_name);
1051                tmp0[strlen(tmp0)-5]=0;
1052                t=readServiceFile(m,buff1,&s1,tmp0);
1053                free(tmp0);
1054                if(t<0){
1055                  map* tmp00=getMapFromMaps(m,"lenv","message");
1056                  char tmp01[1024];
1057                  if(tmp00!=NULL)
1058                    sprintf(tmp01,_("Unable to parse the ZCFG file: %s (%s)"),dp->d_name,tmp00->value);
1059                  else
1060                    sprintf(tmp01,_("Unable to parse the ZCFG file: %s."),dp->d_name);
1061                  dup2(saved_stdout,fileno(stdout));
1062                  errorException(m, tmp01,"InternalError",NULL);
1063                  freeMaps(&m);
1064                  free(m);
1065                  free(orig);
1066                  free(REQUEST);
1067                  closedir(dirp);
1068                  xmlFreeDoc(doc);
1069                  xmlCleanupParser();
1070                  zooXmlCleanupNs();
1071                  return 1;
1072                }
1073#ifdef DEBUG
1074                dumpService(s1);
1075#endif
1076                printDescribeProcessForProcess(m,n,s1);
1077                freeService(&s1);
1078                free(s1);
1079                s1=NULL;
1080                scount++;
1081                hasVal=1;
1082              }
1083            }
1084          }
1085          if(hasVal<0){
1086            map* tmp00=getMapFromMaps(m,"lenv","message");
1087            char tmp01[1024];
1088            if(tmp00!=NULL)
1089              sprintf(tmp01,_("Unable to parse the ZCFG file: %s (%s)"),buff,tmp00->value);
1090            else
1091              sprintf(tmp01,_("Unable to parse the ZCFG file: %s."),buff);
1092            dup2(saved_stdout,fileno(stdout));
1093            errorException(m, tmp01,"InvalidParameterValue","Identifier");
1094            freeMaps(&m);
1095            free(m);
1096            free(orig);
1097            free(REQUEST);
1098            closedir(dirp);
1099            xmlFreeDoc(doc);
1100            xmlCleanupParser();
1101            zooXmlCleanupNs();
1102            return 1;
1103          }
1104          rewinddir(dirp);
1105          tmps=strtok_r(NULL,",",&saveptr);
1106          if(corig!=NULL)
1107            free(corig);
1108        }
1109      }
1110      closedir(dirp);
1111      fflush(stdout);
1112      dup2(saved_stdout,fileno(stdout));
1113      free(orig);
1114      printDocument(m,doc,getpid());
1115      freeMaps(&m);
1116      free(m);
1117      free(REQUEST);
1118      free(SERVICE_URL);
1119      fflush(stdout);
1120      return 0;
1121    }
1122    else
1123      if(strncasecmp(REQUEST,"Execute",strlen(REQUEST))!=0){
1124        errorException(m, _("Unenderstood <request> value. Please check that it was set to GetCapabilities, DescribeProcess or Execute."), "InvalidParameterValue","request");
1125#ifdef DEBUG
1126        fprintf(stderr,"No request found %s",REQUEST);
1127#endif 
1128        closedir(dirp);
1129        freeMaps(&m);
1130        free(m);
1131        free(REQUEST);
1132        free(SERVICE_URL);
1133        fflush(stdout);
1134        return 0;
1135      }
1136    closedir(dirp);
1137  }
1138 
1139  s1=NULL;
1140  s1=(service*)malloc(SERVICE_SIZE);
1141  if(s1 == NULL){
1142    freeMaps(&m);
1143    free(m);
1144    free(REQUEST);
1145    free(SERVICE_URL);
1146    return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
1147  }
1148  r_inputs=getMap(request_inputs,"MetaPath");
1149  if(r_inputs!=NULL)
1150    snprintf(tmps1,1024,"%s/%s",ntmp,r_inputs->value);
1151  else
1152    snprintf(tmps1,1024,"%s/",ntmp);
1153  r_inputs=getMap(request_inputs,"Identifier");
1154  char *ttmp=zStrdup(tmps1);
1155  snprintf(tmps1,1024,"%s/%s.zcfg",ttmp,r_inputs->value);
1156  free(ttmp);
1157#ifdef DEBUG
1158  fprintf(stderr,"Trying to load %s\n", tmps1);
1159#endif
1160  if(strstr(r_inputs->value,".")!=NULL){
1161    char *identifier=zStrdup(r_inputs->value);
1162    parseIdentifier(m,conf_dir,identifier,tmps1);
1163    map* tmpMap=getMapFromMaps(m,"lenv","metapath");
1164    if(tmpMap!=NULL)
1165      addToMap(request_inputs,"metapath",tmpMap->value);
1166    free(identifier);
1167  }else
1168    setMapInMaps(m,"lenv","Identifier",r_inputs->value);
1169  int saved_stdout = dup(fileno(stdout));
1170  dup2(fileno(stderr),fileno(stdout));
1171  t=readServiceFile(m,tmps1,&s1,r_inputs->value);
1172  fflush(stdout);
1173  dup2(saved_stdout,fileno(stdout));
1174  if(t<0){
1175    char *tmpMsg=(char*)malloc(2048+strlen(r_inputs->value));
1176    sprintf(tmpMsg,_("The value for <indetifier> seems to be wrong (%s). Please, ensure that the process exist using the GetCapabilities request."),r_inputs->value);
1177    errorException(m, tmpMsg, "InvalidParameterValue","identifier");
1178    free(tmpMsg);
1179    free(s1);
1180    freeMaps(&m);
1181    free(m);
1182    free(REQUEST);
1183    free(SERVICE_URL);
1184    return 0;
1185  }
1186  close(saved_stdout);
1187
1188#ifdef DEBUG
1189  dumpService(s1);
1190#endif
1191  int j;
1192 
1193
1194  /**
1195   * Create the input and output maps data structure
1196   */
1197  int i=0;
1198  HINTERNET hInternet;
1199  HINTERNET res;
1200  hInternet=InternetOpen(
1201#ifndef WIN32
1202                         (LPCTSTR)
1203#endif
1204                         "ZooWPSClient\0",
1205                         INTERNET_OPEN_TYPE_PRECONFIG,
1206                         NULL,NULL, 0);
1207
1208#ifndef WIN32
1209  if(!CHECK_INET_HANDLE(hInternet))
1210    fprintf(stderr,"WARNING : hInternet handle failed to initialize");
1211#endif
1212  maps* request_input_real_format=NULL;
1213  maps* tmpmaps = request_input_real_format;
1214  map* postRequest=NULL;
1215  postRequest=getMap(request_inputs,"xrequest");
1216  if(postRequest==NULLMAP){
1217    /**
1218     * Parsing outputs provided as KVP
1219     */
1220    r_inputs=NULL;
1221#ifdef DEBUG
1222    fprintf(stderr,"OUTPUT Parsing ... \n");
1223#endif
1224    r_inputs=getMap(request_inputs,"ResponseDocument"); 
1225    if(r_inputs==NULL) r_inputs=getMap(request_inputs,"RawDataOutput");
1226   
1227#ifdef DEBUG
1228    fprintf(stderr,"OUTPUT Parsing ... \n");
1229#endif
1230    if(r_inputs!=NULL){
1231#ifdef DEBUG
1232      fprintf(stderr,"OUTPUT Parsing start now ... \n");
1233#endif
1234      char cursor_output[10240];
1235      char *cotmp=zStrdup(r_inputs->value);
1236      snprintf(cursor_output,10240,"%s",cotmp);
1237      free(cotmp);
1238      j=0;
1239       
1240      /**
1241       * Put each Output into the outputs_as_text array
1242       */
1243      char * pToken;
1244      maps* tmp_output=NULL;
1245#ifdef DEBUG
1246      fprintf(stderr,"OUTPUT [%s]\n",cursor_output);
1247#endif
1248      pToken=strtok(cursor_output,";");
1249      char** outputs_as_text=(char**)malloc(128*sizeof(char*));
1250      if(outputs_as_text == NULL) {
1251        return errorException(m, _("Unable to allocate memory"), "InternalError",NULL);
1252      }
1253      i=0;
1254      while(pToken!=NULL){
1255#ifdef DEBUG
1256        fprintf(stderr,"***%s***\n",pToken);
1257        fflush(stderr);
1258        fprintf(stderr,"***%s***\n",pToken);
1259#endif
1260        outputs_as_text[i]=(char*)malloc((strlen(pToken)+1)*sizeof(char));
1261        if(outputs_as_text[i] == NULL) {
1262          return errorException(m, _("Unable to allocate memory"), "InternalError",NULL);
1263        }
1264        snprintf(outputs_as_text[i],strlen(pToken)+1,"%s",pToken);
1265        pToken = strtok(NULL,";");
1266        i++;
1267      }
1268      for(j=0;j<i;j++){
1269        char *tmp=zStrdup(outputs_as_text[j]);
1270        free(outputs_as_text[j]);
1271        char *tmpc;
1272        tmpc=strtok(tmp,"@");
1273        int k=0;
1274        while(tmpc!=NULL){
1275          if(k==0){
1276            if(tmp_output==NULL){
1277              tmp_output=(maps*)malloc(MAPS_SIZE);
1278              if(tmp_output == NULL){
1279                return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1280              }
1281              tmp_output->name=zStrdup(tmpc);
1282              tmp_output->content=NULL;
1283              tmp_output->next=NULL;
1284            }
1285          }
1286          else{
1287            char *tmpv=strstr(tmpc,"=");
1288            char tmpn[256];
1289            memset(tmpn,0,256);
1290            strncpy(tmpn,tmpc,(strlen(tmpc)-strlen(tmpv))*sizeof(char));
1291            tmpn[strlen(tmpc)-strlen(tmpv)]=0;
1292#ifdef DEBUG
1293            fprintf(stderr,"OUTPUT DEF [%s]=[%s]\n",tmpn,tmpv+1);
1294#endif
1295            if(tmp_output->content==NULL){
1296              tmp_output->content=createMap(tmpn,tmpv+1);
1297              tmp_output->content->next=NULL;
1298            }
1299            else
1300              addToMap(tmp_output->content,tmpn,tmpv+1);
1301          }
1302          k++;
1303#ifdef DEBUG
1304          fprintf(stderr,"***%s***\n",tmpc);
1305#endif
1306          tmpc=strtok(NULL,"@");
1307        }
1308        if(request_output_real_format==NULL)
1309          request_output_real_format=dupMaps(&tmp_output);
1310        else
1311          addMapsToMaps(&request_output_real_format,tmp_output);
1312        freeMaps(&tmp_output);
1313        free(tmp_output);
1314        tmp_output=NULL;
1315#ifdef DEBUG
1316        dumpMaps(tmp_output);
1317        fflush(stderr);
1318#endif
1319        free(tmp);
1320      }
1321      free(outputs_as_text);
1322    }
1323
1324
1325    /**
1326     * Parsing inputs provided as KVP
1327     */
1328    r_inputs=getMap(request_inputs,"DataInputs");
1329#ifdef DEBUG
1330    fprintf(stderr,"DATA INPUTS [%s]\n",r_inputs->value);
1331#endif
1332    char cursor_input[40960];
1333    if(r_inputs!=NULL)
1334      snprintf(cursor_input,40960,"%s",r_inputs->value);
1335    else{
1336      errorException(m, _("Parameter <DataInputs> was not specified"),"MissingParameterValue","DataInputs");
1337      freeMaps(&m);
1338      free(m);
1339      free(REQUEST);
1340      free(SERVICE_URL);
1341      InternetCloseHandle(&hInternet);
1342      freeService(&s1);
1343      free(s1);
1344      return 0;
1345    }
1346    j=0;
1347 
1348    /**
1349     * Put each DataInputs into the inputs_as_text array
1350     */
1351    char *tmp1=zStrdup(cursor_input);
1352    char * pToken;
1353    pToken=strtok(cursor_input,";");
1354    if(pToken!=NULL && strncasecmp(pToken,tmp1,strlen(tmp1))==0){
1355      char* tmp2=url_decode(tmp1);
1356      snprintf(cursor_input,(strlen(tmp2)+1)*sizeof(char),"%s",tmp2);
1357      free(tmp2);
1358      pToken=strtok(cursor_input,";");
1359    }
1360    free(tmp1);
1361
1362    char** inputs_as_text=(char**)malloc(100*sizeof(char*));
1363    if(inputs_as_text == NULL){
1364      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1365    }
1366    i=0;
1367    while(pToken!=NULL){
1368#ifdef DEBUG
1369      fprintf(stderr,"***%s***\n",pToken);
1370#endif
1371      fflush(stderr);
1372#ifdef DEBUG
1373      fprintf(stderr,"***%s***\n",pToken);
1374#endif
1375      inputs_as_text[i]=(char*)malloc((strlen(pToken)+1)*sizeof(char));
1376      snprintf(inputs_as_text[i],strlen(pToken)+1,"%s",pToken);
1377      if(inputs_as_text[i] == NULL){
1378        return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1379      }
1380      pToken = strtok(NULL,";");
1381      i++;
1382    }
1383
1384    for(j=0;j<i;j++){
1385      char *tmp=zStrdup(inputs_as_text[j]);
1386      free(inputs_as_text[j]);
1387      char *tmpc;
1388      tmpc=strtok(tmp,"@");
1389      while(tmpc!=NULL){
1390#ifdef DEBUG
1391        fprintf(stderr,"***\n***%s***\n",tmpc);
1392#endif
1393        char *tmpv=strstr(tmpc,"=");
1394        char tmpn[256];
1395        memset(tmpn,0,256);
1396        if(tmpv!=NULL){
1397          strncpy(tmpn,tmpc,(strlen(tmpc)-strlen(tmpv))*sizeof(char));
1398          tmpn[strlen(tmpc)-strlen(tmpv)]=0;
1399        }
1400        else{
1401          strncpy(tmpn,tmpc,strlen(tmpc)*sizeof(char));
1402          tmpn[strlen(tmpc)]=0;
1403        }
1404#ifdef DEBUG
1405        fprintf(stderr,"***\n*** %s = %s ***\n",tmpn,tmpv+1);
1406#endif
1407        if(tmpmaps==NULL){
1408          tmpmaps=(maps*)malloc(MAPS_SIZE);
1409          if(tmpmaps == NULL){
1410            return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1411          }
1412          tmpmaps->name=zStrdup(tmpn);
1413          if(tmpv!=NULL){
1414            char *tmpvf=url_decode(tmpv+1);
1415            tmpmaps->content=createMap("value",tmpvf);
1416            free(tmpvf);
1417          }
1418          else
1419            tmpmaps->content=createMap("value","Reference");
1420          tmpmaps->next=NULL;
1421        }
1422        tmpc=strtok(NULL,"@");
1423        while(tmpc!=NULL){
1424#ifdef DEBUG
1425          fprintf(stderr,"*** KVP NON URL-ENCODED \n***%s***\n",tmpc);
1426#endif
1427          char *tmpv1=strstr(tmpc,"=");
1428#ifdef DEBUG
1429          fprintf(stderr,"*** VALUE NON URL-ENCODED \n***%s***\n",tmpv1+1);
1430#endif
1431          char tmpn1[1024];
1432          memset(tmpn1,0,1024);
1433          if(tmpv1!=NULL){
1434            strncpy(tmpn1,tmpc,strlen(tmpc)-strlen(tmpv1));
1435            tmpn1[strlen(tmpc)-strlen(tmpv1)]=0;
1436            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
1437          }
1438          else{
1439            strncpy(tmpn1,tmpc,strlen(tmpc));
1440            tmpn1[strlen(tmpc)]=0;
1441            map* lmap=getLastMap(tmpmaps->content);
1442            char *tmpValue=(char*)malloc((strlen(tmpv)+strlen(tmpc)+1)*sizeof(char));
1443            sprintf(tmpValue,"%s@%s",tmpv+1,tmpc);
1444            free(lmap->value);
1445            lmap->value=zStrdup(tmpValue);
1446            free(tmpValue);
1447            tmpc=strtok(NULL,"@");
1448            continue;
1449          }
1450#ifdef DEBUG
1451          fprintf(stderr,"*** NAME NON URL-ENCODED \n***%s***\n",tmpn1);
1452          fprintf(stderr,"*** VALUE NON URL-ENCODED \n***%s***\n",tmpv1+1);
1453#endif
1454          if(strcmp(tmpn1,"xlink:href")!=0)
1455            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
1456          else
1457            if(tmpv1!=NULL){
1458              char *tmpx2=url_decode(tmpv1+1);
1459              if(strncasecmp(tmpx2,"http://",7)!=0 &&
1460                 strncasecmp(tmpx2,"ftp://",6)!=0 &&
1461                 strncasecmp(tmpx2,"https://",8)!=0){
1462                char emsg[1024];
1463                sprintf(emsg,_("Unable to find a valid protocol to download the remote file %s"),tmpv1+1);
1464                errorException(m,emsg,"InternalError",NULL);
1465                freeMaps(&m);
1466                free(m);
1467                free(REQUEST);
1468                free(SERVICE_URL);
1469                InternetCloseHandle(&hInternet);
1470                freeService(&s1);
1471                free(s1);
1472                return 0;
1473              }
1474#ifdef DEBUG
1475              fprintf(stderr,"REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n",tmpv1+1);
1476#endif
1477              addToMap(tmpmaps->content,tmpn1,tmpx2);         
1478#ifndef WIN32
1479              if(CHECK_INET_HANDLE(hInternet))
1480#endif
1481                {
1482                  if(loadRemoteFile(&m,&tmpmaps->content,&hInternet,tmpx2)<0){
1483                    freeMaps(&m);
1484                    free(m);
1485                    free(REQUEST);
1486                    free(SERVICE_URL);
1487                    InternetCloseHandle(&hInternet);
1488                    freeService(&s1);
1489                    free(s1);
1490                    return 0;
1491                  }
1492                }
1493              free(tmpx2);
1494              addToMap(tmpmaps->content,"Reference",tmpv1+1);
1495            }
1496          tmpc=strtok(NULL,"@");
1497        }
1498#ifdef DEBUG
1499        dumpMaps(tmpmaps);
1500        fflush(stderr);
1501#endif
1502        if(request_input_real_format==NULL)
1503          request_input_real_format=dupMaps(&tmpmaps);
1504        else{
1505          maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
1506          if(testPresence!=NULL){
1507            elements* elem=getElements(s1->inputs,tmpmaps->name);
1508            if(elem!=NULL){
1509              if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
1510                freeMaps(&m);
1511                free(m);
1512                free(REQUEST);
1513                free(SERVICE_URL);
1514                InternetCloseHandle(&hInternet);
1515                freeService(&s1);
1516                free(s1);
1517                return 0;
1518              }
1519            }
1520          }
1521          else
1522            addMapsToMaps(&request_input_real_format,tmpmaps);
1523        }
1524        freeMaps(&tmpmaps);
1525        free(tmpmaps);
1526        tmpmaps=NULL;
1527        free(tmp);
1528      }
1529    }
1530    free(inputs_as_text);
1531  }
1532  else {
1533    /**
1534     * Parse XML request
1535     */ 
1536    xmlInitParser();
1537#ifdef DEBUG
1538    fflush(stderr);
1539    fprintf(stderr,"BEFORE %s\n",postRequest->value);
1540    fflush(stderr);
1541#endif
1542    xmlDocPtr doc =
1543      xmlParseMemory(postRequest->value,cgiContentLength);
1544#ifdef DEBUG
1545    fprintf(stderr,"AFTER\n");
1546    fflush(stderr);
1547#endif
1548    /**
1549     * Parse every Input in DataInputs node.
1550     */
1551    xmlXPathObjectPtr tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='Input']");
1552    xmlNodeSet* tmps=tmpsptr->nodesetval;
1553#ifdef DEBUG
1554    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1555#endif
1556    for(int k=0;k<tmps->nodeNr;k++){
1557      maps *tmpmaps=NULL;
1558      xmlNodePtr cur=tmps->nodeTab[k];
1559      if(tmps->nodeTab[k]->type == XML_ELEMENT_NODE) {
1560        /**
1561         * A specific Input node.
1562         */
1563#ifdef DEBUG
1564        fprintf(stderr, "= element 0 node \"%s\"\n", cur->name);
1565#endif
1566        xmlNodePtr cur2=cur->children;
1567        while(cur2!=NULL){
1568          while(cur2!=NULL && cur2->type!=XML_ELEMENT_NODE)
1569            cur2=cur2->next;
1570          if(cur2==NULL)
1571            break;
1572          /**
1573           * Indentifier
1574           */
1575          if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1576            xmlChar *val= xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1577            if(tmpmaps==NULL){
1578              tmpmaps=(maps*)malloc(MAPS_SIZE);
1579              if(tmpmaps == NULL){
1580                return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1581              }
1582              tmpmaps->name=zStrdup((char*)val);
1583              tmpmaps->content=NULL;
1584              tmpmaps->next=NULL;
1585            }
1586            xmlFree(val);
1587          }
1588          /**
1589           * Title, Asbtract
1590           */
1591          if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1592             xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1593            xmlChar *val=
1594              xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1595            if(tmpmaps==NULL){
1596              tmpmaps=(maps*)malloc(MAPS_SIZE);
1597              if(tmpmaps == NULL){
1598                return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1599              }
1600              tmpmaps->name=zStrdup("missingIndetifier");
1601              tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1602              tmpmaps->next=NULL;
1603            }
1604            else{
1605              if(tmpmaps->content!=NULL)
1606                addToMap(tmpmaps->content,
1607                         (char*)cur2->name,(char*)val);
1608              else
1609                tmpmaps->content=
1610                  createMap((char*)cur2->name,(char*)val);
1611            }
1612#ifdef DEBUG
1613            dumpMaps(tmpmaps);
1614#endif
1615            xmlFree(val);
1616          }
1617          /**
1618           * InputDataFormChoice (Reference or Data ?)
1619           */
1620          if(xmlStrcasecmp(cur2->name,BAD_CAST "Reference")==0){
1621            /**
1622             * Get every attribute from a Reference node
1623             * mimeType, encoding, schema, href, method
1624             * Header and Body gesture should be added here
1625             */
1626#ifdef DEBUG
1627            fprintf(stderr,"REFERENCE\n");
1628#endif
1629            const char *refs[5]={"mimeType","encoding","schema","method","href"};
1630            for(int l=0;l<5;l++){
1631#ifdef DEBUG
1632              fprintf(stderr,"*** %s ***",refs[l]);
1633#endif
1634              xmlChar *val=xmlGetProp(cur2,BAD_CAST refs[l]);
1635              if(val!=NULL && xmlStrlen(val)>0){
1636                if(tmpmaps->content!=NULL)
1637                  addToMap(tmpmaps->content,refs[l],(char*)val);
1638                else
1639                  tmpmaps->content=createMap(refs[l],(char*)val);
1640                map* ltmp=getMap(tmpmaps->content,"method");
1641                if(l==4){
1642                  if(!(ltmp!=NULL && strncmp(ltmp->value,"POST",4)==0)
1643                     && CHECK_INET_HANDLE(hInternet)){
1644                    if(loadRemoteFile(&m,&tmpmaps->content,&hInternet,(char*)val)!=0){
1645                      freeMaps(&m);
1646                      free(m);
1647                      free(REQUEST);
1648                      free(SERVICE_URL);
1649                      InternetCloseHandle(&hInternet);
1650                      freeService(&s1);
1651                      free(s1);
1652                      return 0;
1653                    }
1654                  }
1655                }
1656              }
1657#ifdef DEBUG
1658              fprintf(stderr,"%s\n",val);
1659#endif
1660              xmlFree(val);
1661            }
1662#ifdef POST_DEBUG
1663            fprintf(stderr,"Parse Header and Body from Reference \n");
1664#endif
1665            xmlNodePtr cur3=cur2->children;
1666            /*      HINTERNET hInternetP;
1667                    hInternetP=InternetOpen(
1668                    #ifndef WIN32
1669                    (LPCTSTR)
1670                    #endif
1671                    "ZooWPSClient\0",
1672                    INTERNET_OPEN_TYPE_PRECONFIG,
1673                    NULL,NULL, 0);*/
1674            //hInternet.ihandle[hInternet.nb].header=NULL;
1675            while(cur3!=NULL){
1676              while(cur3!=NULL && cur3->type!=XML_ELEMENT_NODE)
1677                cur3=cur3->next;
1678              if(cur3==NULL)
1679                break;
1680              if(xmlStrcasecmp(cur3->name,BAD_CAST "Header")==0 ){
1681                const char *ha[2];
1682                ha[0]="key";
1683                ha[1]="value";
1684                int hai;
1685                char *has;
1686                char *key;
1687                for(hai=0;hai<2;hai++){
1688                  xmlChar *val=xmlGetProp(cur3,BAD_CAST ha[hai]);
1689#ifdef POST_DEBUG
1690                  fprintf(stderr,"%s = %s\n",ha[hai],(char*)val);
1691#endif
1692                  if(hai==0){
1693                    key=zStrdup((char*)val);
1694                  }else{
1695                    has=(char*)malloc((4+xmlStrlen(val)+strlen(key))*sizeof(char));
1696                    if(has == NULL){
1697                      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1698                    }
1699                    snprintf(has,(3+xmlStrlen(val)+strlen(key)),"%s: %s",key,(char*)val);
1700                    free(key);
1701#ifdef POST_DEBUG
1702                    fprintf(stderr,"%s\n",has);
1703#endif
1704                  }
1705                  xmlFree(val);
1706                }
1707                hInternet.ihandle[hInternet.nb].header=curl_slist_append(hInternet.ihandle[hInternet.nb].header, has);
1708                if(has!=NULL)
1709                  free(has);
1710              }
1711              else{
1712#ifdef POST_DEBUG
1713                fprintf(stderr,"Try to fetch the body part of the request ...\n");
1714#endif
1715                if(xmlStrcasecmp(cur3->name,BAD_CAST "Body")==0 ){
1716#ifdef POST_DEBUG
1717                  fprintf(stderr,"Body part found !!!\n",(char*)cur3->content);
1718#endif
1719                  char *tmp=(char*)malloc(cgiContentLength+1*sizeof(char));
1720                  memset(tmp,0,cgiContentLength);
1721                  xmlNodePtr cur4=cur3->children;
1722                  while(cur4!=NULL){
1723                    while(cur4->type!=XML_ELEMENT_NODE)
1724                      cur4=cur4->next;
1725                    xmlDocPtr bdoc = xmlNewDoc(BAD_CAST "1.0");
1726                    bdoc->encoding = xmlCharStrdup ("UTF-8");
1727                    xmlDocSetRootElement(bdoc,cur4);
1728                    xmlChar* btmps;
1729                    int bsize;
1730                    xmlDocDumpMemory(bdoc,&btmps,&bsize);
1731#ifdef POST_DEBUG
1732                    fprintf(stderr,"Body part found !!! %s %s\n",tmp,(char*)btmps);
1733#endif
1734                    if(btmps!=NULL)
1735                      sprintf(tmp,"%s",(char*)btmps);
1736                    xmlFree(btmps);
1737                    cur4=cur4->next;
1738                    xmlFreeDoc(bdoc);
1739                  }
1740                  map *btmp=getMap(tmpmaps->content,"href");
1741                  if(btmp!=NULL){
1742#ifdef POST_DEBUG
1743                    fprintf(stderr,"%s %s\n",btmp->value,tmp);
1744                    curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1745#endif
1746                    hInternet.waitingRequests[hInternet.nb]=strdup(tmp);
1747                    InternetOpenUrl(&hInternet,btmp->value,hInternet.waitingRequests[hInternet.nb],strlen(hInternet.waitingRequests[hInternet.nb]),
1748                                    INTERNET_FLAG_NO_CACHE_WRITE,0);
1749                  }
1750                  free(tmp);
1751                }
1752                else
1753                  if(xmlStrcasecmp(cur3->name,BAD_CAST "BodyReference")==0 ){
1754                    xmlChar *val=xmlGetProp(cur3,BAD_CAST "href");
1755                    HINTERNET bInternet,res1;
1756                    bInternet=InternetOpen(
1757#ifndef WIN32
1758                                           (LPCTSTR)
1759#endif
1760                                           "ZooWPSClient\0",
1761                                           INTERNET_OPEN_TYPE_PRECONFIG,
1762                                           NULL,NULL, 0);
1763                    if(!CHECK_INET_HANDLE(hInternet))
1764                      fprintf(stderr,"WARNING : hInternet handle failed to initialize");
1765#ifdef POST_DEBUG
1766                    curl_easy_setopt(bInternet.handle, CURLOPT_VERBOSE, 1);
1767#endif
1768                    bInternet.waitingRequests[0]=strdup((char*)val);
1769                    res1=InternetOpenUrl(&bInternet,bInternet.waitingRequests[0],NULL,0,
1770                                         INTERNET_FLAG_NO_CACHE_WRITE,0);
1771                    processDownloads(&bInternet);
1772                    char* tmp=
1773                      (char*)malloc((bInternet.ihandle[0].nDataLen+1)*sizeof(char));
1774                    if(tmp == NULL){
1775                      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1776                    }
1777                    size_t bRead;
1778                    InternetReadFile(bInternet.ihandle[0], (LPVOID)tmp,
1779                                     bInternet.ihandle[0].nDataLen, &bRead);
1780                    tmp[bInternet.ihandle[0].nDataLen]=0;
1781                    InternetCloseHandle(&bInternet);
1782                    map *btmp=getMap(tmpmaps->content,"href");
1783                    if(btmp!=NULL){
1784#ifdef POST_DEBUG
1785                      fprintf(stderr,"%s %s\n",btmp->value,tmp);
1786#endif
1787                      hInternet.waitingRequests[hInternet.nb]=strdup(tmp);
1788                      res=InternetOpenUrl(&hInternet,btmp->value,hInternet.waitingRequests[hInternet.nb],
1789                                          strlen(hInternet.waitingRequests[hInternet.nb]),
1790                                          INTERNET_FLAG_NO_CACHE_WRITE,0);
1791                    }
1792                    free(tmp);
1793                  }
1794              }
1795              cur3=cur3->next;
1796            }
1797#ifdef POST_DEBUG
1798            fprintf(stderr,"Header and Body was parsed from Reference \n");
1799#endif
1800#ifdef DEBUG
1801            dumpMap(tmpmaps->content);
1802            fprintf(stderr, "= element 2 node \"%s\" = (%s)\n", 
1803                    cur2->name,cur2->content);
1804#endif
1805          }
1806          else if(xmlStrcasecmp(cur2->name,BAD_CAST "Data")==0){
1807#ifdef DEBUG
1808            fprintf(stderr,"DATA\n");
1809#endif
1810            xmlNodePtr cur4=cur2->children;
1811            while(cur4!=NULL){
1812              while(cur4!=NULL &&cur4->type!=XML_ELEMENT_NODE)
1813                cur4=cur4->next;
1814              if(cur4==NULL)
1815                break;
1816              if(xmlStrcasecmp(cur4->name, BAD_CAST "LiteralData")==0){
1817                /**
1818                 * Get every attribute from a LiteralData node
1819                 * dataType , uom
1820                 */
1821                char *list[2];
1822                list[0]=zStrdup("dataType");
1823                list[1]=zStrdup("uom");
1824                for(int l=0;l<2;l++){
1825#ifdef DEBUG
1826                  fprintf(stderr,"*** LiteralData %s ***",list[l]);
1827#endif
1828                  xmlChar *val=xmlGetProp(cur4,BAD_CAST list[l]);
1829                  if(val!=NULL && strlen((char*)val)>0){
1830                    if(tmpmaps->content!=NULL)
1831                      addToMap(tmpmaps->content,list[l],(char*)val);
1832                    else
1833                      tmpmaps->content=createMap(list[l],(char*)val);
1834#ifdef DEBUG
1835                    fprintf(stderr,"%s\n",val);
1836#endif
1837                  }
1838                  xmlFree(val);
1839                  free(list[l]);                 
1840                }
1841              }
1842              else if(xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0){
1843                /**
1844                 * Get every attribute from a Reference node
1845                 * mimeType, encoding, schema
1846                 */
1847                const char *coms[3]={"mimeType","encoding","schema"};
1848                for(int l=0;l<3;l++){
1849#ifdef DEBUG
1850                  fprintf(stderr,"*** ComplexData %s ***\n",coms[l]);
1851#endif
1852                  xmlChar *val=xmlGetProp(cur4,BAD_CAST coms[l]);
1853                  if(val!=NULL && strlen((char*)val)>0){
1854                    if(tmpmaps->content!=NULL)
1855                      addToMap(tmpmaps->content,coms[l],(char*)val);
1856                    else
1857                      tmpmaps->content=createMap(coms[l],(char*)val);
1858#ifdef DEBUG
1859                    fprintf(stderr,"%s\n",val);
1860#endif
1861                  }
1862                  xmlFree(val);
1863                }
1864              }
1865
1866              map* test=getMap(tmpmaps->content,"encoding");
1867              if(test==NULL){
1868                if(tmpmaps->content!=NULL)
1869                  addToMap(tmpmaps->content,"encoding","utf-8");
1870                else
1871                  tmpmaps->content=createMap("encoding","utf-8");
1872                test=getMap(tmpmaps->content,"encoding");
1873              }
1874
1875              if(strcasecmp(test->value,"base64")!=0){
1876                xmlChar* mv=xmlNodeListGetString(doc,cur4->xmlChildrenNode,1);
1877                map* ltmp=getMap(tmpmaps->content,"mimeType");
1878                if(mv==NULL || 
1879                   (xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0 &&
1880                    (ltmp==NULL || strncasecmp(ltmp->value,"text/xml",8)==0) )){
1881                  xmlDocPtr doc1=xmlNewDoc(BAD_CAST "1.0");
1882                  int buffersize;
1883                  xmlNodePtr cur5=cur4->children;
1884                  while(cur5!=NULL && cur5->type!=XML_ELEMENT_NODE && cur5->type!=XML_CDATA_SECTION_NODE)
1885                    cur5=cur5->next;
1886                  if(cur5!=NULL && cur5->type!=XML_CDATA_SECTION_NODE){
1887                    xmlDocSetRootElement(doc1,cur5);
1888                    xmlDocDumpFormatMemoryEnc(doc1, &mv, &buffersize, "utf-8", 1);
1889                    char size[1024];
1890                    sprintf(size,"%d",buffersize);
1891                    addToMap(tmpmaps->content,"size",size);
1892                    xmlFreeDoc(doc1);
1893                  }
1894                }
1895                if(mv!=NULL){
1896                  addToMap(tmpmaps->content,"value",(char*)mv);
1897                  xmlFree(mv);
1898                }
1899              }else{
1900                xmlChar* tmp=xmlNodeListGetRawString(doc,cur4->xmlChildrenNode,0);
1901                addToMap(tmpmaps->content,"value",(char*)tmp);
1902                map* tmpv=getMap(tmpmaps->content,"value");
1903                char *res=NULL;
1904                char *curs=tmpv->value;
1905                for(int i=0;i<=strlen(tmpv->value)/64;i++) {
1906                  if(res==NULL)
1907                    res=(char*)malloc(67*sizeof(char));
1908                  else
1909                    res=(char*)realloc(res,(((i+1)*65)+i)*sizeof(char));
1910                  int csize=i*65;
1911                  strncpy(res + csize,curs,64);
1912                  if(i==xmlStrlen(tmp)/64)
1913                    strcat(res,"\n\0");
1914                  else{
1915                    strncpy(res + (((i+1)*64)+i),"\n\0",2);
1916                    curs+=64;
1917                  }
1918                }
1919                free(tmpv->value);
1920                tmpv->value=zStrdup(res);
1921                free(res);
1922                xmlFree(tmp);
1923              }
1924              cur4=cur4->next;
1925            }
1926          }
1927#ifdef DEBUG
1928          fprintf(stderr,"cur2 next \n");
1929          fflush(stderr);
1930#endif
1931          cur2=cur2->next;
1932        }
1933#ifdef DEBUG
1934        fprintf(stderr,"ADD MAPS TO REQUEST MAPS !\n");
1935        fflush(stderr);
1936#endif
1937
1938        {
1939          maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
1940          if(testPresence!=NULL){
1941            elements* elem=getElements(s1->inputs,tmpmaps->name);
1942            if(elem!=NULL){
1943              if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
1944                freeMaps(&m);
1945                free(m);
1946                free(REQUEST);
1947                free(SERVICE_URL);
1948                InternetCloseHandle(&hInternet);
1949                freeService(&s1);
1950                free(s1);
1951                return 0;
1952              }
1953            }
1954          }
1955          else
1956            addMapsToMaps(&request_input_real_format,tmpmaps);
1957        }
1958
1959#ifdef DEBUG
1960        fprintf(stderr,"******TMPMAPS*****\n");
1961        dumpMaps(tmpmaps);
1962        fprintf(stderr,"******REQUESTMAPS*****\n");
1963        dumpMaps(request_input_real_format);
1964#endif
1965        freeMaps(&tmpmaps);
1966        free(tmpmaps);
1967        tmpmaps=NULL;         
1968      }
1969#ifdef DEBUG
1970      dumpMaps(tmpmaps); 
1971#endif
1972    }
1973#ifdef DEBUG
1974    fprintf(stderr,"Search for response document node\n");
1975#endif
1976    xmlXPathFreeObject(tmpsptr);
1977   
1978    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='ResponseDocument']");
1979    bool asRaw=false;
1980    tmps=tmpsptr->nodesetval;
1981    if(tmps->nodeNr==0){
1982      xmlXPathFreeObject(tmpsptr);
1983      tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='RawDataOutput']");
1984      tmps=tmpsptr->nodesetval;
1985      asRaw=true;
1986    }
1987#ifdef DEBUG
1988    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1989#endif
1990    if(asRaw==true){
1991      addToMap(request_inputs,"RawDataOutput","");
1992      xmlNodePtr cur0=tmps->nodeTab[0];
1993      if(cur0->type == XML_ELEMENT_NODE) {
1994       
1995        maps* tmpmaps=(maps*)malloc(MAPS_SIZE);
1996        if(tmpmaps == NULL){
1997          return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
1998        }
1999        tmpmaps->name=zStrdup("unknownIdentifier");
2000        tmpmaps->content=NULL;
2001        tmpmaps->next=NULL;
2002       
2003        /**
2004         * Get every attribute from a RawDataOutput node
2005         * mimeType, encoding, schema, uom
2006         */
2007        const char *outs[4]={"mimeType","encoding","schema","uom"};
2008        for(int l=0;l<4;l++){
2009#ifdef DEBUG
2010          fprintf(stderr,"*** %s ***\t",outs[l]);
2011#endif
2012          xmlChar *val=xmlGetProp(cur0,BAD_CAST outs[l]);
2013          if(val!=NULL){
2014            if(strlen((char*)val)>0){
2015              if(tmpmaps->content!=NULL)
2016                addToMap(tmpmaps->content,outs[l],(char*)val);
2017              else
2018                tmpmaps->content=createMap(outs[l],(char*)val);
2019            }
2020            xmlFree(val);
2021          }
2022        }
2023        xmlNodePtr cur2=cur0->children;
2024        while(cur2!=NULL && cur2->type != XML_ELEMENT_NODE)
2025          cur2=cur2->next;
2026        int cur1cnt=0;
2027        while(cur2!=NULL){
2028          if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
2029            xmlChar *val=
2030              xmlNodeListGetString(NULL,cur2->xmlChildrenNode,1);
2031            free(tmpmaps->name);
2032            tmpmaps->name=zStrdup((char*)val);
2033            xmlFree(val);
2034          }
2035          cur2=cur2->next;
2036          while(cur2!=NULL && cur2->type != XML_ELEMENT_NODE)
2037            cur2=cur2->next;
2038        }
2039        if(request_output_real_format==NULL)
2040          request_output_real_format=dupMaps(&tmpmaps);
2041        else
2042          addMapsToMaps(&request_output_real_format,tmpmaps);
2043        if(tmpmaps!=NULL){
2044          freeMaps(&tmpmaps);
2045          free(tmpmaps);
2046          tmpmaps=NULL;
2047        }
2048      }
2049    }
2050    else
2051      for(int k=0;k<tmps->nodeNr;k++){
2052        //else
2053        addToMap(request_inputs,"ResponseDocument","");
2054        maps *tmpmaps=NULL;
2055        xmlNodePtr cur=tmps->nodeTab[k];
2056        if(cur->type == XML_ELEMENT_NODE) {
2057          /**
2058           * A specific responseDocument node.
2059           */
2060          if(tmpmaps==NULL){
2061            tmpmaps=(maps*)malloc(MAPS_SIZE);
2062            if(tmpmaps == NULL){
2063              return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2064            }
2065            tmpmaps->name=zStrdup("unknownIdentifier");
2066            tmpmaps->content=NULL;
2067            tmpmaps->next=NULL;
2068          }
2069          /**
2070           * Get every attribute: storeExecuteResponse, lineage, status
2071           */
2072          const char *ress[3]={"storeExecuteResponse","lineage","status"};
2073          xmlChar *val;
2074          for(int l=0;l<3;l++){
2075#ifdef DEBUG
2076            fprintf(stderr,"*** %s ***\t",ress[l]);
2077#endif
2078            val=xmlGetProp(cur,BAD_CAST ress[l]);
2079            if(val!=NULL && strlen((char*)val)>0){
2080              if(tmpmaps->content!=NULL)
2081                addToMap(tmpmaps->content,ress[l],(char*)val);
2082              else
2083                tmpmaps->content=createMap(ress[l],(char*)val);
2084              addToMap(request_inputs,ress[l],(char*)val);
2085            }
2086#ifdef DEBUG
2087            fprintf(stderr,"%s\n",val);
2088#endif
2089            xmlFree(val);
2090          }
2091          xmlNodePtr cur1=cur->children;
2092          while(cur1!=NULL && cur1->type != XML_ELEMENT_NODE)
2093            cur1=cur1->next;
2094          int cur1cnt=0;
2095          while(cur1){
2096            /**
2097             * Indentifier
2098             */
2099            if(xmlStrncasecmp(cur1->name,BAD_CAST "Identifier",xmlStrlen(cur1->name))==0){
2100              xmlChar *val=
2101                xmlNodeListGetString(doc,cur1->xmlChildrenNode,1);
2102              if(tmpmaps==NULL){
2103                tmpmaps=(maps*)malloc(MAPS_SIZE);
2104                if(tmpmaps == NULL){
2105                  return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2106                }
2107                tmpmaps->name=zStrdup((char*)val);
2108                tmpmaps->content=NULL;
2109                tmpmaps->next=NULL;
2110              }
2111              else{
2112                free(tmpmaps->name);
2113                tmpmaps->name=zStrdup((char*)val);
2114              }
2115              if(asRaw==true)
2116                addToMap(request_inputs,"RawDataOutput",(char*)val);
2117              else{
2118                if(cur1cnt==0)
2119                  addToMap(request_inputs,"ResponseDocument",(char*)val);
2120                else{
2121                  map* tt=getMap(request_inputs,"ResponseDocument");
2122                  char* tmp=zStrdup(tt->value);
2123                  free(tt->value);
2124                  tt->value=(char*)malloc((strlen(tmp)+strlen((char*)val)+1)*sizeof(char));
2125                  sprintf(tt->value,"%s;%s",tmp,(char*)val);
2126                  free(tmp);
2127                }
2128              }
2129              cur1cnt+=1;
2130              xmlFree(val);
2131            }
2132            /**
2133             * Title, Asbtract
2134             */
2135            else if(xmlStrncasecmp(cur1->name,BAD_CAST "Title",xmlStrlen(cur1->name))==0 ||
2136                    xmlStrncasecmp(cur1->name,BAD_CAST "Abstract",xmlStrlen(cur1->name))==0){
2137              xmlChar *val=
2138                xmlNodeListGetString(doc,cur1->xmlChildrenNode,1);
2139              if(tmpmaps==NULL){
2140                tmpmaps=(maps*)malloc(MAPS_SIZE);
2141                if(tmpmaps == NULL){
2142                  return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2143                }
2144                tmpmaps->name=zStrdup("missingIndetifier");
2145                tmpmaps->content=createMap((char*)cur1->name,(char*)val);
2146                tmpmaps->next=NULL;
2147              }
2148              else{
2149                if(tmpmaps->content!=NULL)
2150                  addToMap(tmpmaps->content,(char*)cur1->name,(char*)val);
2151                else
2152                  tmpmaps->content=createMap((char*)cur1->name,(char*)val);
2153              }
2154              xmlFree(val);
2155            }
2156            else if(xmlStrncasecmp(cur1->name,BAD_CAST "Output",xmlStrlen(cur1->name))==0){
2157              /**
2158               * Get every attribute from a Output node
2159               * mimeType, encoding, schema, uom, asReference
2160               */
2161              const char *outs[5]={"mimeType","encoding","schema","uom","asReference"};
2162              for(int l=0;l<5;l++){
2163#ifdef DEBUG
2164                fprintf(stderr,"*** %s ***\t",outs[l]);
2165#endif
2166                xmlChar *val=xmlGetProp(cur1,BAD_CAST outs[l]);
2167                if(val!=NULL && strlen((char*)val)>0){
2168                  if(tmpmaps->content!=NULL)
2169                    addToMap(tmpmaps->content,outs[l],(char*)val);
2170                  else
2171                    tmpmaps->content=createMap(outs[l],(char*)val);
2172                }
2173#ifdef DEBUG
2174                fprintf(stderr,"%s\n",val);
2175#endif
2176                xmlFree(val);
2177              }
2178              xmlNodePtr cur2=cur1->children;
2179              while(cur2!=NULL && cur2->type != XML_ELEMENT_NODE)
2180                cur2=cur2->next;
2181              while(cur2){
2182                /**
2183                 * Indentifier
2184                 */
2185                if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
2186                  xmlChar *val=
2187                    xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
2188                  if(tmpmaps==NULL){
2189                    tmpmaps=(maps*)malloc(MAPS_SIZE);
2190                    if(tmpmaps == NULL){
2191                      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2192                    }
2193                    tmpmaps->name=zStrdup((char*)val);
2194                    tmpmaps->content=NULL;
2195                    tmpmaps->next=NULL;
2196                  }
2197                  else{
2198                    if(tmpmaps->name!=NULL)
2199                      free(tmpmaps->name);
2200                    tmpmaps->name=zStrdup((char*)val);;
2201                  }
2202                  xmlFree(val);
2203                }
2204                /**
2205                 * Title, Asbtract
2206                 */
2207                else if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
2208                        xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
2209                  xmlChar *val=
2210                    xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
2211                  if(tmpmaps==NULL){
2212                    tmpmaps=(maps*)malloc(MAPS_SIZE);
2213                    if(tmpmaps == NULL){
2214                      return errorException(m, _("Unable to allocate memory."), "InternalError",NULL);
2215                    }
2216                    tmpmaps->name=zStrdup("missingIndetifier");
2217                    tmpmaps->content=createMap((char*)cur2->name,(char*)val);
2218                    tmpmaps->next=NULL;
2219                  }
2220                  else{
2221                    if(tmpmaps->content!=NULL)
2222                      addToMap(tmpmaps->content,
2223                               (char*)cur2->name,(char*)val);
2224                    else
2225                      tmpmaps->content=
2226                        createMap((char*)cur2->name,(char*)val);
2227                  }
2228                  xmlFree(val);
2229                }
2230                cur2=cur2->next;
2231                while(cur2!=NULL && cur2->type != XML_ELEMENT_NODE)
2232                  cur2=cur2->next;
2233              }
2234            }
2235            cur1=cur1->next;
2236            while(cur1!=NULL && cur1->type != XML_ELEMENT_NODE)
2237              cur1=cur1->next;
2238          }
2239        }
2240        if(request_output_real_format==NULL)
2241          request_output_real_format=dupMaps(&tmpmaps);
2242        else
2243          addMapsToMaps(&request_output_real_format,tmpmaps);
2244        if(tmpmaps!=NULL){
2245          freeMaps(&tmpmaps);
2246          free(tmpmaps);
2247          tmpmaps=NULL;
2248        }
2249      }
2250    xmlXPathFreeObject(tmpsptr);
2251    xmlFreeDoc(doc);
2252    xmlCleanupParser();
2253  }
2254 
2255  runHttpRequests(&m,&request_input_real_format,&hInternet);
2256
2257  //  if(CHECK_INET_HANDLE(hInternet))
2258  InternetCloseHandle(&hInternet);
2259
2260#ifdef DEBUG
2261  fprintf(stderr,"\n%d\n",__LINE__);
2262  fflush(stderr);
2263  dumpMaps(request_input_real_format);
2264  dumpMaps(request_output_real_format);
2265  dumpMap(request_inputs);
2266  fprintf(stderr,"\n%d\n",__LINE__);
2267  fflush(stderr);
2268#endif
2269
2270  /**
2271   * Ensure that each requested arguments are present in the request
2272   * DataInputs and ResponseDocument / RawDataOutput
2273   */
2274  char *dfv=addDefaultValues(&request_input_real_format,s1->inputs,m,0);
2275  maps *ptr=request_input_real_format;
2276  while(ptr!=NULL){
2277    map *tmp0=getMap(ptr->content,"size");
2278    map *tmp1=getMap(ptr->content,"maximumMegabytes");
2279    if(tmp1!=NULL && tmp0!=NULL){
2280      float i=atof(tmp0->value)/1048576.0;
2281      if(i>=atoi(tmp1->value)){
2282        char tmps[1024];
2283        map* tmpe=createMap("code","FileSizeExceeded");
2284        snprintf(tmps,1024,_("The <%s> parameter has a limited size (%sMB) defined in ZOO ServicesProvider configuration file but the reference you provided exceed this limitation (%fMB), please correct your query or the ZOO Configuration file."),ptr->name,tmp1->value,i);
2285        addToMap(tmpe,"locator",ptr->name);
2286        addToMap(tmpe,"text",tmps);
2287        printExceptionReportResponse(m,tmpe);
2288        freeService(&s1);
2289        free(s1);
2290        freeMap(&tmpe);
2291        free(tmpe);
2292        freeMaps(&m);
2293        free(m);
2294        free(REQUEST);
2295        free(SERVICE_URL);
2296        freeMaps(&request_input_real_format);
2297        free(request_input_real_format);
2298        freeMaps(&request_output_real_format);
2299        free(request_output_real_format);
2300        freeMaps(&tmpmaps);
2301        free(tmpmaps);
2302        return 1;
2303      }
2304    }
2305    ptr=ptr->next;
2306  }
2307
2308  char *dfv1=addDefaultValues(&request_output_real_format,s1->outputs,m,1);
2309  if(strcmp(dfv1,"")!=0 || strcmp(dfv,"")!=0){
2310    char tmps[1024];
2311    map* tmpe=createMap("code","MissingParameterValue");
2312    if(strcmp(dfv,"")!=0){
2313      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);
2314      addToMap(tmpe,"locator",dfv);
2315    }
2316    else if(strcmp(dfv1,"")!=0){
2317      snprintf(tmps,1024,_("The <%s> argument was specified as Output identifier but not defined in the ZOO Configuration File. Please, correct your query or the ZOO Configuration File."),dfv1);
2318      addToMap(tmpe,"locator",dfv1);
2319    }
2320    addToMap(tmpe,"text",tmps);
2321    printExceptionReportResponse(m,tmpe);
2322    freeService(&s1);
2323    free(s1);
2324    freeMap(&tmpe);
2325    free(tmpe);
2326    freeMaps(&m);
2327    free(m);
2328    free(REQUEST);
2329    free(SERVICE_URL);
2330    freeMaps(&request_input_real_format);
2331    free(request_input_real_format);
2332    freeMaps(&request_output_real_format);
2333    free(request_output_real_format);
2334    freeMaps(&tmpmaps);
2335    free(tmpmaps);
2336    return 1;
2337  }
2338  maps* tmpReqI=request_input_real_format;
2339  while(tmpReqI!=NULL){
2340    char name[1024];
2341    if(getMap(tmpReqI->content,"isFile")!=NULL){
2342      if (cgiFormFileName(tmpReqI->name, name, sizeof(name)) == cgiFormSuccess) {
2343        int BufferLen=1024;
2344        cgiFilePtr file;
2345        int targetFile;
2346        char storageNameOnServer[2048];
2347        char fileNameOnServer[64];
2348        char contentType[1024];
2349        char buffer[1024];
2350        char *tmpStr=NULL;
2351        int size;
2352        int got,t;
2353        map *path=getMapFromMaps(m,"main","tmpPath");
2354        cgiFormFileSize(tmpReqI->name, &size);
2355        cgiFormFileContentType(tmpReqI->name, contentType, sizeof(contentType));
2356        if (cgiFormFileOpen(tmpReqI->name, &file) == cgiFormSuccess) {
2357          t=-1;
2358          while(1){
2359            tmpStr=strstr(name+t+1,"\\");
2360            if(NULL==tmpStr)
2361              tmpStr=strstr(name+t+1,"/");
2362            if(NULL!=tmpStr)
2363              t=(int)(tmpStr-name);
2364            else
2365              break;
2366          }
2367          strcpy(fileNameOnServer,name+t+1);
2368         
2369          sprintf(storageNameOnServer,"%s/%s",path->value,fileNameOnServer);
2370#ifdef DEBUG
2371          fprintf(stderr,"Name on server %s\n",storageNameOnServer);
2372          fprintf(stderr,"fileNameOnServer: %s\n",fileNameOnServer);
2373#endif
2374          targetFile = open (storageNameOnServer,O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP|S_IROTH);
2375          if(targetFile<0){
2376#ifdef DEBUG
2377            fprintf(stderr,"could not create the new file,%s\n",fileNameOnServer);         
2378#endif
2379          }else{
2380            while (cgiFormFileRead(file, buffer, BufferLen, &got) ==cgiFormSuccess){
2381              if(got>0)
2382                write(targetFile,buffer,got);
2383            }
2384          }
2385          addToMap(tmpReqI->content,"lref",storageNameOnServer);
2386          cgiFormFileClose(file);
2387          close(targetFile);
2388#ifdef DEBUG
2389          fprintf(stderr,"File \"%s\" has been uploaded",fileNameOnServer);
2390#endif
2391        }
2392      }
2393    }
2394    tmpReqI=tmpReqI->next;
2395  }
2396
2397  ensureDecodedBase64(&request_input_real_format);
2398
2399#ifdef DEBUG
2400  fprintf(stderr,"REQUEST_INPUTS\n");
2401  dumpMaps(request_input_real_format);
2402  fprintf(stderr,"REQUEST_OUTPUTS\n");
2403  dumpMaps(request_output_real_format);
2404#endif
2405
2406  maps* curs=getMaps(m,"env");
2407  if(curs!=NULL){
2408    map* mapcs=curs->content;
2409    while(mapcs!=NULLMAP){
2410#ifndef WIN32
2411      setenv(mapcs->name,mapcs->value,1);
2412#else
2413#ifdef DEBUG
2414      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
2415#endif
2416      if(mapcs->value[strlen(mapcs->value)-2]=='\r'){
2417#ifdef DEBUG
2418        fprintf(stderr,"[ZOO: Env var finish with \r]\n");
2419#endif
2420        mapcs->value[strlen(mapcs->value)-1]=0;
2421      }
2422#ifdef DEBUG
2423      fflush(stderr);
2424      fprintf(stderr,"setting variable... %s\n",(
2425#endif
2426                                                 SetEnvironmentVariable(mapcs->name,mapcs->value)
2427#ifdef DEBUG
2428                                                 ==0)? "OK" : "FAILED");
2429#else
2430      ;
2431#endif
2432      char* toto=(char*)malloc((strlen(mapcs->name)+strlen(mapcs->value)+2)*sizeof(char));
2433      sprintf(toto,"%s=%s",mapcs->name,mapcs->value);
2434      putenv(toto);
2435#ifdef DEBUG
2436      fflush(stderr);
2437#endif
2438#endif
2439#ifdef DEBUG
2440      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
2441      fflush(stderr);
2442#endif
2443      mapcs=mapcs->next;
2444    }
2445  }
2446 
2447#ifdef DEBUG
2448  dumpMap(request_inputs);
2449#endif
2450
2451  /**
2452   * Need to check if we need to fork to load a status enabled
2453   */
2454  r_inputs=NULL;
2455  map* store=getMap(request_inputs,"storeExecuteResponse");
2456  map* status=getMap(request_inputs,"status");
2457  /**
2458   * 05-007r7 WPS 1.0.0 page 57 :
2459   * 'If status="true" and storeExecuteResponse is "false" then the service
2460   * shall raise an exception.'
2461   */
2462  if(status!=NULL && strcmp(status->value,"true")==0 && 
2463     store!=NULL && strcmp(store->value,"false")==0){
2464    errorException(m, _("Status cannot be set to true with storeExecuteResponse to false. Please, modify your request parameters."), "InvalidParameterValue","storeExecuteResponse");
2465    freeService(&s1);
2466    free(s1);
2467    freeMaps(&m);
2468    free(m);
2469   
2470    freeMaps(&request_input_real_format);
2471    free(request_input_real_format);
2472   
2473    freeMaps(&request_output_real_format);
2474    free(request_output_real_format);
2475   
2476    free(REQUEST);
2477    free(SERVICE_URL);
2478    return 1;
2479  }
2480  r_inputs=getMap(request_inputs,"storeExecuteResponse");
2481  int eres=SERVICE_STARTED;
2482  int cpid=getpid();
2483
2484  /**
2485   * Initialize the specific [lenv] section which contains runtime variables:
2486   *
2487   *  - usid : it is an unique identification number
2488   *  - sid : it is the process idenfitication number (OS)
2489   *  - status : value between 0 and 100 to express the  completude of
2490   * the operations of the running service
2491   *  - message : is a string where you can store error messages, in case
2492   * service is failing, or o provide details on the ongoing operation.
2493   *  - cwd : is the current working directory
2494   *  - soap : is a boolean value, true if the request was contained in a SOAP
2495   * Envelop
2496   *  - sessid : string storing the session identifier (only when cookie is
2497   * used)
2498   *  - cgiSid : only defined on Window platforms (for being able to identify
2499   * the created process)
2500   *
2501   */
2502  maps *_tmpMaps=(maps*)malloc(MAPS_SIZE);
2503  _tmpMaps->name=zStrdup("lenv");
2504  char tmpBuff[100];
2505  int lid=getShmLockId(NULL,1);
2506  lockShm(lid);
2507  struct ztimeval tp;
2508  if(zGettimeofday(&tp,NULL)==0)
2509    sprintf(tmpBuff,"%i",(cpid+((int)tp.tv_sec+(int)tp.tv_usec)));
2510  else
2511    sprintf(tmpBuff,"%i",(cpid+(int)time(NULL)));
2512  unlockShm(lid);
2513  removeShmLock(NULL,1);
2514  _tmpMaps->content=createMap("usid",tmpBuff);
2515  _tmpMaps->next=NULL;
2516  sprintf(tmpBuff,"%i",cpid);
2517  addToMap(_tmpMaps->content,"sid",tmpBuff);
2518  addToMap(_tmpMaps->content,"status","0");
2519  addToMap(_tmpMaps->content,"cwd",ntmp);
2520  addToMap(_tmpMaps->content,"message",_("No message provided"));
2521  map* ltmp=getMap(request_inputs,"soap");
2522  if(ltmp!=NULL)
2523    addToMap(_tmpMaps->content,"soap",ltmp->value);
2524  else
2525    addToMap(_tmpMaps->content,"soap","false");
2526  if(cgiCookie!=NULL && strlen(cgiCookie)>0){
2527    int hasValidCookie=-1;
2528    char *tcook=zStrdup(cgiCookie);
2529    char *tmp=NULL;
2530    map* testing=getMapFromMaps(m,"main","cookiePrefix");
2531    if(testing==NULL){
2532      tmp=zStrdup("ID=");
2533    }else{
2534      tmp=(char*)malloc((strlen(testing->value)+2)*sizeof(char));
2535      sprintf(tmp,"%s=",testing->value);
2536    }
2537    if(strstr(cgiCookie,";")!=NULL){
2538      char *token,*saveptr;
2539      token=strtok_r(cgiCookie,";",&saveptr);
2540      while(token!=NULL){
2541        if(strcasestr(token,tmp)!=NULL){
2542          if(tcook!=NULL)
2543            free(tcook);
2544          tcook=zStrdup(token);
2545          hasValidCookie=1;
2546        }
2547        token=strtok_r(NULL,";",&saveptr);
2548      }
2549    }else{
2550      if(strstr(cgiCookie,"=")!=NULL && strcasestr(cgiCookie,tmp)!=NULL){
2551        tcook=zStrdup(cgiCookie);
2552        hasValidCookie=1;
2553      }
2554      if(tmp!=NULL){
2555        free(tmp);
2556      }
2557    }
2558    if(hasValidCookie>0){
2559      addToMap(_tmpMaps->content,"sessid",strstr(tcook,"=")+1);
2560      char session_file_path[1024];
2561      map *tmpPath=getMapFromMaps(m,"main","sessPath");
2562      if(tmpPath==NULL)
2563        tmpPath=getMapFromMaps(m,"main","tmpPath");
2564      char *tmp1=strtok(tcook,";");
2565      if(tmp1!=NULL)
2566        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(tmp1,"=")+1);
2567      else
2568        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(cgiCookie,"=")+1);
2569      free(tcook);
2570      maps *tmpSess=(maps*)malloc(MAPS_SIZE);
2571      struct stat file_status;
2572      int istat = stat(session_file_path, &file_status);
2573      if(istat==0 && file_status.st_size>0){
2574        conf_read(session_file_path,tmpSess);
2575        addMapsToMaps(&m,tmpSess);
2576        freeMaps(&tmpSess);
2577        free(tmpSess);
2578      }
2579    }
2580  }
2581  addMapsToMaps(&m,_tmpMaps);
2582  freeMaps(&_tmpMaps);
2583  free(_tmpMaps);
2584
2585#ifdef DEBUG
2586  dumpMap(request_inputs);
2587#endif
2588#ifdef WIN32
2589  char *cgiSidL=NULL;
2590  if(getenv("CGISID")!=NULL)
2591    addToMap(request_inputs,"cgiSid",getenv("CGISID"));
2592  map* test1=getMap(request_inputs,"cgiSid");
2593  if(test1!=NULL){
2594    cgiSid=test1->value;
2595    addToMap(request_inputs,"storeExecuteResponse","true");
2596    addToMap(request_inputs,"status","true");
2597    setMapInMaps(m,"lenv","sid",test1->value);
2598    status=getMap(request_inputs,"status");
2599  }
2600#endif
2601  char *fbkp,*fbkp1;
2602  FILE *f0,*f1;
2603  if(status!=NULL)
2604    if(strcasecmp(status->value,"false")==0)
2605      status=NULLMAP;
2606  if(status==NULLMAP){
2607    loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
2608  }
2609  else{
2610    int   pid;
2611#ifdef DEBUG
2612    fprintf(stderr,"\nPID : %d\n",cpid);
2613#endif
2614
2615#ifndef WIN32
2616    pid = fork ();
2617#else
2618    if(cgiSid==NULL){
2619      createProcess(m,request_inputs,s1,NULL,cpid,request_input_real_format,request_output_real_format);
2620      pid = cpid;
2621    }else{
2622      pid=0;
2623      cpid=atoi(cgiSid);
2624    }
2625#endif
2626    if (pid > 0) {
2627      /**
2628       * dady :
2629       * set status to SERVICE_ACCEPTED
2630       */
2631#ifdef DEBUG
2632      fprintf(stderr,"father pid continue (origin %d) %d ...\n",cpid,getpid());
2633#endif
2634      eres=SERVICE_ACCEPTED;
2635    }else if (pid == 0) {
2636      /**
2637       * son : have to close the stdout, stdin and stderr to let the parent
2638       * process answer to http client.
2639       */
2640#ifndef WIN32
2641      zSleep(1);
2642#endif
2643      r_inputs=getMapFromMaps(m,"lenv","usid");
2644      int cpid=atoi(r_inputs->value);
2645      r_inputs=getMapFromMaps(m,"main","tmpPath");
2646      map* r_inputs1=getMap(s1->content,"ServiceProvider");
2647      fbkp=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+1024)*sizeof(char));
2648      sprintf(fbkp,"%s/%s_%d.xml",r_inputs->value,r_inputs1->value,cpid);
2649      char* flog=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+1024)*sizeof(char));
2650      sprintf(flog,"%s/%s_%d_error.log",r_inputs->value,r_inputs1->value,cpid);
2651#ifdef DEBUG
2652      fprintf(stderr,"RUN IN BACKGROUND MODE \n");
2653      fprintf(stderr,"son pid continue (origin %d) %d ...\n",cpid,getpid());
2654      fprintf(stderr,"\nFILE TO STORE DATA %s\n",r_inputs->value);
2655#endif
2656      freopen(flog, "w+", stderr);
2657      semid lid=getShmLockId(m,1);
2658      fflush(stderr);
2659      if(lid<0){
2660        fprintf(stderr,"ERROR %s %d\n",__FILE__,__LINE__);
2661        fflush(stderr);
2662        return -1;
2663      }
2664      else{
2665        if(lockShm(lid)<0){
2666          fprintf(stderr,"ERROR %s %d\n",__FILE__,__LINE__);
2667          fflush(stderr);
2668          return -1;
2669        }
2670        fflush(stderr);
2671      }
2672      f0=freopen(fbkp , "w+", stdout);
2673      rewind(stdout);
2674#ifndef WIN32
2675      fclose(stdin);
2676#endif
2677      free(flog);
2678      /**
2679       * set status to SERVICE_STARTED and flush stdout to ensure full
2680       * content was outputed (the file used to store the ResponseDocument).
2681       * The rewind stdout to restart writing from the bgining of the file,
2682       * this way the data will be updated at the end of the process run.
2683       */
2684      printProcessResponse(m,request_inputs,cpid,s1,r_inputs1->value,SERVICE_STARTED,
2685                           request_input_real_format,request_output_real_format);
2686      fflush(stdout);
2687      unlockShm(lid);
2688      fflush(stderr);
2689      fbkp1=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+1024)*sizeof(char));
2690      sprintf(fbkp1,"%s/%s_final_%d.xml",r_inputs->value,r_inputs1->value,cpid);
2691      f1=freopen(fbkp1 , "w+", stdout);
2692      loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
2693    } else {
2694      /**
2695       * error server don't accept the process need to output a valid
2696       * error response here !!!
2697       */
2698      eres=-1;
2699      errorException(m, _("Unable to run the child process properly"), "InternalError",NULL);
2700    }
2701  }
2702
2703#ifdef DEBUG
2704  dumpMaps(request_output_real_format);
2705#endif
2706  if(eres!=-1)
2707    outputResponse(s1,request_input_real_format,
2708                   request_output_real_format,request_inputs,
2709                   cpid,m,eres);
2710  fflush(stdout);
2711  /**
2712   * Ensure that if error occurs when freeing memory, no signal will return
2713   * an ExceptionReport document as the result was already returned to the
2714   * client.
2715   */
2716#ifndef USE_GDB
2717  signal(SIGSEGV,donothing);
2718  signal(SIGTERM,donothing);
2719  signal(SIGINT,donothing);
2720  signal(SIGILL,donothing);
2721  signal(SIGFPE,donothing);
2722  signal(SIGABRT,donothing);
2723#endif
2724  if(((int)getpid())!=cpid || cgiSid!=NULL){
2725    fclose(stdout);
2726    fclose(stderr);
2727    /**
2728     * Dump back the final file fbkp1 to fbkp
2729     */
2730    fclose(f0);
2731    fclose(f1);
2732    FILE* f2=fopen(fbkp1,"rb");
2733    semid lid=getShmLockId(m,1);
2734    if(lid<0)
2735      return -1;
2736    lockShm(lid);
2737    FILE* f3=fopen(fbkp,"wb+");
2738    free(fbkp);
2739    fseek(f2,0,SEEK_END);
2740    long flen=ftell(f2);
2741    fseek(f2,0,SEEK_SET);
2742    char *tmps1=(char*)malloc((flen+1)*sizeof(char));
2743    fread(tmps1,flen,1,f2);
2744    fwrite(tmps1,1,flen,f3);
2745    fclose(f2);
2746    fclose(f3);
2747    unlockShm(lid);
2748    unlink(fbkp1);
2749    free(fbkp1);
2750    free(tmps1);
2751    unhandleStatus(m);
2752  }
2753
2754  freeService(&s1);
2755  free(s1);
2756  freeMaps(&m);
2757  free(m);
2758 
2759  freeMaps(&request_input_real_format);
2760  free(request_input_real_format);
2761 
2762  freeMaps(&request_output_real_format);
2763  free(request_output_real_format);
2764 
2765  free(REQUEST);
2766  free(SERVICE_URL);
2767#ifdef DEBUG
2768  fprintf(stderr,"Processed response \n");
2769  fflush(stdout);
2770  fflush(stderr);
2771#endif
2772
2773  if(((int)getpid())!=cpid || cgiSid!=NULL){
2774    exit(0);
2775  }
2776
2777  return 0;
2778}
2779
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