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

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

Call exit from the child processes and make sure to remove zombies from process list.

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