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

Last change on this file since 501 was 501, checked in by djay, 10 years ago

Version for testing through ogc-cite with 29 passed tests

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