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

Last change on this file since 518 was 516, checked in by djay, 10 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