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

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

Use unique identifier as reference for asynchronous service execution.

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