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

Last change on this file since 370 was 370, checked in by djay, 11 years ago

Add the capability to use a specific Python version by detecting if python-VERS-config exists or if python-config-VERS exists. Add NEED_STRCASESTR to nmake.opt for MapServer? support. Fix for the name of layer class on Unix/Windows?. Provide definition of strcasestr if and only if MapServer? was not activated.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 61.7 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2008-2012 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
30extern "C" {
31#include <libxml/tree.h>
32#include <libxml/xmlmemory.h>
33#include <libxml/parser.h>
34#include <libxml/xpath.h>
35#include <libxml/xpathInternals.h>
36}
37
38#include "cgic.h"
39#include "ulinet.h"
40
41#include <libintl.h>
42#include <locale.h>
43#include <string.h>
44
45#include "service.h"
46
47#include "service_internal.h"
48
49#ifdef USE_PYTHON
50#include "service_internal_python.h"
51#endif
52
53#ifdef USE_JAVA
54#include "service_internal_java.h"
55#endif
56
57#ifdef USE_PHP
58#include "service_internal_php.h"
59#endif
60
61#ifdef USE_JS
62#include "service_internal_js.h"
63#endif
64
65#ifdef USE_PERL
66#include "service_internal_perl.h"
67#endif
68
69#include <dirent.h>
70#include <signal.h>
71#include <unistd.h>
72#ifndef WIN32
73#include <dlfcn.h>
74#include <libgen.h>
75#else
76#include <windows.h>
77#include <direct.h>
78#include <sys/types.h>
79#include <sys/stat.h>
80#include <unistd.h>
81#define pid_t int;
82#endif
83#include <fcntl.h>
84#include <time.h>
85#include <stdarg.h>
86
87#ifdef WIN32
88extern "C" {
89  __declspec(dllexport) char *strcasestr(char const *a, char const *b)
90#ifndef USE_MS
91 { 
92  char *x=_strdup(a); 
93  char *y=_strdup(b); 
94 
95  x=_strlwr(x); 
96  y=_strlwr(y); 
97  char *pos = strstr(x, y); 
98  char *ret = pos == NULL ? NULL : (char *)(a + (pos-x)); 
99  free(x); 
100  free(y); 
101  return ret; 
102 };
103#else
104  ;
105#endif
106}
107#endif
108
109#define _(String) dgettext ("zoo-kernel",String)
110
111
112void translateChar(char* str,char toReplace,char toReplaceBy){
113  int i=0,len=strlen(str);
114  for(i=0;i<len;i++){
115    if(str[i]==toReplace)
116      str[i]=toReplaceBy;
117  }
118}
119
120/**
121 * Create (or append to) an array valued maps
122 * value = "["",""]"
123 */
124int appendMapsToMaps(maps* m,maps* mo,maps* mi,elements* elem){
125  maps* tmpMaps=getMaps(mo,mi->name);
126  map* tmap=getMapType(tmpMaps->content);
127  elements* el=getElements(elem,mi->name);
128  int hasEl=1;
129  if(el==NULL)
130    hasEl=-1;
131  if(tmap==NULL){
132    if(hasEl>0)
133      tmap=getMapType(el->defaults->content);     
134  }
135
136  map* testMap=NULL;
137  if(hasEl>0){
138    testMap=getMap(el->content,"maxOccurs");
139  }else{
140    testMap=createMap("maxOccurs","unbounded");
141  }
142
143  if(testMap!=NULL){
144    if(strncasecmp(testMap->value,"unbounded",9)!=0 && atoi(testMap->value)>1){
145      if(addMapsArrayToMaps(&mo,mi,tmap->name)<0){
146        char emsg[1024];
147        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));
148        errorException(m,emsg,"InternalError");
149        return -1;
150      }
151    }else{
152      if(strncasecmp(testMap->value,"unbounded",9)==0){
153        if(hasEl<0){
154          freeMap(&testMap);
155          free(testMap);
156        }
157        if(addMapsArrayToMaps(&mo,mi,tmap->name)<0){
158          char emsg[1024];
159          map* tmpMap=getMap(mi->content,"length");
160          sprintf(emsg,_("ZOO-Kernel was unable to load your data for %s position %s."),mi->name,tmpMap->value);
161          errorException(m,emsg,"InternalError");
162          return -1;
163        }
164      }
165      else{
166        char emsg[1024];
167        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);
168        errorException(m,emsg,"InternalError");
169        return -1;
170      }
171    }
172  }
173  return 0;
174}
175
176xmlXPathObjectPtr extractFromDoc(xmlDocPtr doc,const char* search){
177  xmlXPathContextPtr xpathCtx;
178  xmlXPathObjectPtr xpathObj;
179  xpathCtx = xmlXPathNewContext(doc);
180  xpathObj = xmlXPathEvalExpression(BAD_CAST search,xpathCtx);
181  xmlXPathFreeContext(xpathCtx);
182  return xpathObj;
183}
184
185void donothing(int sig){
186  fprintf(stderr,"Signal %d after the ZOO-Kernel returned result !\n",sig);
187  exit(0);
188}
189
190void sig_handler(int sig){
191  char tmp[100];
192  const char *ssig;
193  switch(sig){
194  case SIGSEGV:
195    ssig="SIGSEGV";
196    break;
197  case SIGTERM:
198    ssig="SIGTERM";
199    break;
200  case SIGINT:
201    ssig="SIGINT";
202    break;
203  case SIGILL:
204    ssig="SIGILL";
205    break;
206  case SIGFPE:
207    ssig="SIGFPE";
208    break;
209  case SIGABRT:
210    ssig="SIGABRT";
211    break;
212  default:
213    ssig="UNKNOWN";
214    break;
215  }
216  sprintf(tmp,_("ZOO Kernel failed to process your request receiving signal %d = %s"),sig,ssig);
217  errorException(NULL, tmp, "InternalError");
218#ifdef DEBUG
219  fprintf(stderr,"Not this time!\n");
220#endif
221  exit(0);
222}
223
224void loadServiceAndRun(maps **myMap,service* s1,map* request_inputs,maps **inputs,maps** ioutputs,int* eres){
225  char tmps1[1024];
226  char ntmp[1024];
227  maps *m=*myMap;
228  maps *request_output_real_format=*ioutputs;
229  maps *request_input_real_format=*inputs;
230  /**
231   * Extract serviceType to know what kind of service should be loaded
232   */
233  map* r_inputs=NULL;
234#ifndef WIN32
235  char* pntmp=getcwd(ntmp,1024);
236#else
237  _getcwd(ntmp,1024);
238#endif
239  r_inputs=getMap(s1->content,"serviceType");
240#ifdef DEBUG
241  fprintf(stderr,"LOAD A %s SERVICE PROVIDER \n",r_inputs->value);
242  fflush(stderr);
243#endif
244  if(strlen(r_inputs->value)==1 && strncasecmp(r_inputs->value,"C",1)==0){
245    r_inputs=getMap(request_inputs,"metapath");
246    if(r_inputs!=NULL)
247      sprintf(tmps1,"%s/%s",ntmp,r_inputs->value);
248    else
249      sprintf(tmps1,"%s/",ntmp);
250    char *altPath=strdup(tmps1);
251    r_inputs=getMap(s1->content,"ServiceProvider");
252    sprintf(tmps1,"%s/%s",altPath,r_inputs->value);
253    free(altPath);
254#ifdef DEBUG
255    fprintf(stderr,"Trying to load %s\n",tmps1);
256#endif
257#ifdef WIN32
258    HINSTANCE so = LoadLibraryEx(tmps1,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
259#else
260    void* so = dlopen(tmps1, RTLD_LAZY);
261#endif
262#ifdef DEBUG
263#ifdef WIN32
264    DWORD errstr;
265    errstr = GetLastError();
266    fprintf(stderr,"%s loaded (%d) \n",tmps1,errstr);
267#else
268    char *errstr;
269    errstr = dlerror();
270#endif
271#endif
272
273    if( so != NULL ) {
274#ifdef DEBUG
275      fprintf(stderr,"Library loaded %s \n",errstr);
276      fprintf(stderr,"Service Shared Object = %s\n",r_inputs->value);
277#endif
278      r_inputs=getMap(s1->content,"serviceType");
279#ifdef DEBUG
280      dumpMap(r_inputs);
281      fprintf(stderr,"%s\n",r_inputs->value);
282      fflush(stderr);
283#endif
284      if(strncasecmp(r_inputs->value,"C-FORTRAN",9)==0){
285        r_inputs=getMap(request_inputs,"Identifier");
286        char fname[1024];
287        sprintf(fname,"%s_",r_inputs->value);
288#ifdef DEBUG
289        fprintf(stderr,"Try to load function %s\n",fname);
290#endif
291#ifdef WIN32
292        typedef int (CALLBACK* execute_t)(char***,char***,char***);
293        execute_t execute=(execute_t)GetProcAddress(so,fname);
294#else
295        typedef int (*execute_t)(char***,char***,char***);
296        execute_t execute=(execute_t)dlsym(so,fname);
297#endif
298#ifdef DEBUG
299#ifdef WIN32
300        errstr = GetLastError();
301#else
302        errstr = dlerror();
303#endif
304        fprintf(stderr,"Function loaded %s\n",errstr);
305#endif 
306
307        char main_conf[10][30][1024];
308        char inputs[10][30][1024];
309        char outputs[10][30][1024];
310        for(int i=0;i<10;i++){
311          for(int j=0;j<30;j++){
312            memset(main_conf[i][j],0,1024);
313            memset(inputs[i][j],0,1024);
314            memset(outputs[i][j],0,1024);
315          }
316        }
317        mapsToCharXXX(m,(char***)main_conf);
318        mapsToCharXXX(request_input_real_format,(char***)inputs);
319        mapsToCharXXX(request_output_real_format,(char***)outputs);
320        *eres=execute((char***)&main_conf[0],(char***)&inputs[0],(char***)&outputs[0]);
321#ifdef DEBUG
322        fprintf(stderr,"Function run successfully \n");
323#endif
324        charxxxToMaps((char***)&outputs[0],&request_output_real_format);
325      }else{
326#ifdef DEBUG
327#ifdef WIN32
328        errstr = GetLastError();
329        fprintf(stderr,"Function %s failed to load because of %d\n",r_inputs->value,errstr);
330#endif
331#endif
332        r_inputs=getMap(request_inputs,"Identifier");
333#ifdef DEBUG
334        fprintf(stderr,"Try to load function %s\n",r_inputs->value);
335#endif
336        typedef int (*execute_t)(maps**,maps**,maps**);
337#ifdef WIN32
338        execute_t execute=(execute_t)GetProcAddress(so,r_inputs->value); 
339#else
340        execute_t execute=(execute_t)dlsym(so,r_inputs->value);
341#endif
342
343#ifdef DEBUG
344#ifdef WIN32
345        errstr = GetLastError();
346#else
347        errstr = dlerror();
348#endif
349        fprintf(stderr,"Function loaded %s\n",errstr);
350#endif 
351
352#ifdef DEBUG
353        fprintf(stderr,"Now run the function \n");
354        fflush(stderr);
355#endif
356        *eres=execute(&m,&request_input_real_format,&request_output_real_format);
357#ifdef DEBUG
358        fprintf(stderr,"Function loaded and returned %d\n",eres);
359        fflush(stderr);
360#endif
361      }
362#ifdef WIN32
363      *ioutputs=dupMaps(&request_output_real_format);
364      FreeLibrary(so);
365#else
366      dlclose(so);
367#endif
368    } else {
369      /**
370       * Unable to load the specified shared library
371       */
372      char tmps[1024];
373#ifdef WIN32
374      DWORD errstr = GetLastError();
375#else
376      char* errstr = dlerror();
377#endif
378      sprintf(tmps,_("C Library can't be loaded %s \n"),errstr);
379      map* tmps1=createMap("text",tmps);
380      printExceptionReportResponse(m,tmps1);
381      *eres=-1;
382    }
383  }
384  else
385#ifdef USE_PYTHON
386    if(strncasecmp(r_inputs->value,"PYTHON",6)==0){
387      *eres=zoo_python_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
388    }
389    else
390#endif
391       
392#ifdef USE_JAVA
393      if(strncasecmp(r_inputs->value,"JAVA",4)==0){
394        *eres=zoo_java_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
395      }
396      else
397#endif
398
399#ifdef USE_PHP
400        if(strncasecmp(r_inputs->value,"PHP",3)==0){
401          *eres=zoo_php_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
402        }
403        else
404#endif
405           
406           
407#ifdef USE_PERL
408          if(strncasecmp(r_inputs->value,"PERL",4)==0){
409            *eres=zoo_perl_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
410          }
411          else
412#endif
413
414#ifdef USE_JS
415            if(strncasecmp(r_inputs->value,"JS",2)==0){
416              *eres=zoo_js_support(&m,request_inputs,s1,&request_input_real_format,&request_output_real_format);
417            }
418            else
419#endif
420              {
421                char tmpv[1024];
422                sprintf(tmpv,_("Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n"),r_inputs->value);
423                map* tmps=createMap("text",tmpv);
424                printExceptionReportResponse(m,tmps);
425                *eres=-1;
426              }
427  *myMap=m;
428  *ioutputs=request_output_real_format;
429}
430
431#ifdef WIN32
432/**
433 * createProcess function: create a new process after setting some env variables
434 */
435void createProcess(maps* m,map* request_inputs,service* s1,char* opts,int cpid, maps* inputs,maps* outputs){
436  STARTUPINFO si;
437  PROCESS_INFORMATION pi;
438  ZeroMemory( &si, sizeof(si) );
439  si.cb = sizeof(si);
440  ZeroMemory( &pi, sizeof(pi) );
441  char *tmp=(char *)malloc((1024+cgiContentLength)*sizeof(char));
442  char *tmpq=(char *)malloc((1024+cgiContentLength)*sizeof(char));
443  map *req=getMap(request_inputs,"request");
444  map *id=getMap(request_inputs,"identifier");
445  map *di=getMap(request_inputs,"DataInputs");
446
447  char *dataInputsKVP=getMapsAsKVP(inputs,cgiContentLength,0);
448  char *dataOutputsKVP=getMapsAsKVP(outputs,cgiContentLength,1);
449  fprintf(stderr,"DATAINPUTSKVP %s\n",dataInputsKVP);
450  fprintf(stderr,"DATAOUTPUTSKVP %s\n",dataOutputsKVP);
451  map *sid=getMapFromMaps(m,"lenv","sid");
452  map* r_inputs=getMapFromMaps(m,"main","tmpPath");
453  map* r_inputs1=getMap(s1->content,"ServiceProvider");
454  map* r_inputs2=getMap(s1->content,"ResponseDocument");
455  if(r_inputs2==NULL)
456    r_inputs2=getMap(s1->content,"RawDataOutput");
457  map *tmpPath=getMapFromMaps(m,"lenv","cwd");
458
459  if(r_inputs2!=NULL){
460    sprintf(tmp,"\"request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s&cgiSid=%s\"",req->value,id->value,dataInputsKVP,r_inputs2->name,r_inputs2->value,sid->value);
461        sprintf(tmpq,"request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s",req->value,id->value,dataInputsKVP,r_inputs2->name,dataOutputsKVP);
462  }
463  else{
464    sprintf(tmp,"\"request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&cgiSid=%s\"",req->value,id->value,dataInputsKVP,sid->value);
465    sprintf(tmpq,"request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s",req->value,id->value,dataInputsKVP,sid->value);
466  }
467
468  char *tmp1=strdup(tmp);
469  sprintf(tmp,"zoo_loader.cgi %s \"%s\"",tmp1,sid->value);
470
471  free(dataInputsKVP);
472  free(dataOutputsKVP);
473  fprintf(stderr,"REQUEST IS : %s \n",tmp);
474  SetEnvironmentVariable("CGISID",TEXT(sid->value));
475  SetEnvironmentVariable("QUERY_STRING",TEXT(tmpq));
476  char clen[1000];
477  sprintf(clen,"%d",strlen(tmpq));
478  SetEnvironmentVariable("CONTENT_LENGTH",TEXT(clen));
479
480  if( !CreateProcess( NULL,             // No module name (use command line)
481                      TEXT(tmp),        // Command line
482                      NULL,             // Process handle not inheritable
483                      NULL,             // Thread handle not inheritable
484                      FALSE,            // Set handle inheritance to FALSE
485                      CREATE_NO_WINDOW, // Apache won't wait until the end
486                      NULL,             // Use parent's environment block
487                      NULL,             // Use parent's starting directory
488                      &si,              // Pointer to STARTUPINFO struct
489                      &pi )             // Pointer to PROCESS_INFORMATION struct
490      ) 
491    { 
492      fprintf( stderr, "CreateProcess failed (%d).\n", GetLastError() );
493      return ;
494    }else{
495    fprintf( stderr, "CreateProcess successfull (%d).\n\n\n\n", GetLastError() );
496  }
497  CloseHandle( pi.hProcess );
498  CloseHandle( pi.hThread );
499  fprintf(stderr,"CreateProcess finished !\n");
500}
501#endif
502
503int runRequest(map* request_inputs)
504{
505
506#ifndef USE_GDB
507  (void) signal(SIGSEGV,sig_handler);
508  (void) signal(SIGTERM,sig_handler);
509  (void) signal(SIGINT,sig_handler);
510  (void) signal(SIGILL,sig_handler);
511  (void) signal(SIGFPE,sig_handler);
512  (void) signal(SIGABRT,sig_handler);
513#endif
514
515  map* r_inputs=NULL;
516  maps* m=NULL;
517
518  char* REQUEST=NULL;
519  /**
520   * Parsing service specfic configuration file
521   */
522  m=(maps*)calloc(1,MAPS_SIZE);
523  if(m == NULL){
524    return errorException(m, _("Unable to allocate memory."), "InternalError");
525  }
526  char ntmp[1024];
527#ifndef WIN32
528  char *pntmp=getcwd(ntmp,1024);
529#else
530  _getcwd(ntmp,1024);
531#endif
532  r_inputs=getMapOrFill(request_inputs,"metapath","");
533
534  char conf_file[10240];
535  snprintf(conf_file,10240,"%s/%s/main.cfg",ntmp,r_inputs->value);
536  conf_read(conf_file,m);
537#ifdef DEBUG
538  fprintf(stderr, "***** BEGIN MAPS\n"); 
539  dumpMaps(m);
540  fprintf(stderr, "***** END MAPS\n");
541#endif
542
543  bindtextdomain ("zoo-kernel","/usr/share/locale/");
544  bindtextdomain ("zoo-services","/usr/share/locale/");
545
546  /**
547   * Manage our own error log file (usefull to separate standard apache debug
548   * messages from the ZOO-Kernel ones but also for IIS users to avoid wrong
549   * headers messages returned by the CGI due to wrong redirection of stderr)
550   */
551  FILE * fstde=NULL;
552  map* fstdem=getMapFromMaps(m,"main","logPath");
553  if(fstdem!=NULL)
554        fstde = freopen(fstdem->value, "a+", stderr) ;
555
556  if((r_inputs=getMap(request_inputs,"language"))!=NULL){
557    char *tmp=strdup(r_inputs->value);
558    translateChar(tmp,'-','_');
559    setlocale (LC_ALL, tmp);
560    free(tmp);
561    setMapInMaps(m,"main","language",r_inputs->value);
562  }
563  else{
564    setlocale (LC_ALL, "en_US");
565    setMapInMaps(m,"main","language","en-US");
566  }
567  setlocale (LC_NUMERIC, "en_US");
568  bind_textdomain_codeset("zoo-kernel","UTF-8");
569  textdomain("zoo-kernel");
570  bind_textdomain_codeset("zoo-services","UTF-8");
571  textdomain("zoo-services");
572
573  map* lsoap=getMap(request_inputs,"soap");
574  if(lsoap!=NULL && strcasecmp(lsoap->value,"true")==0)
575    setMapInMaps(m,"main","isSoap","true");
576  else
577    setMapInMaps(m,"main","isSoap","false");
578
579  /**
580   * Check for minimum inputs
581   */
582  r_inputs=getMap(request_inputs,"Request");
583  if(request_inputs==NULL || r_inputs==NULL){ 
584    errorException(m, _("Parameter <request> was not specified"),"MissingParameterValue");
585    freeMaps(&m);
586    free(m);
587    freeMap(&request_inputs);
588    free(request_inputs);
589    free(REQUEST);
590    return 1;
591  }
592  else{
593    REQUEST=strdup(r_inputs->value);
594    if(strncasecmp(r_inputs->value,"GetCapabilities",15)!=0
595       && strncasecmp(r_inputs->value,"DescribeProcess",15)!=0
596       && strncasecmp(r_inputs->value,"Execute",7)!=0){ 
597      errorException(m, _("Unenderstood <request> value. Please check that it was set to GetCapabilities, DescribeProcess or Execute."), "InvalidParameterValue");
598      freeMaps(&m);
599      free(m);
600      free(REQUEST);
601      return 1;
602    }
603  }
604  r_inputs=NULL;
605  r_inputs=getMap(request_inputs,"Service");
606  if(r_inputs==NULLMAP){
607    errorException(m, _("Parameter <service> was not specified"),"MissingParameterValue");
608    freeMaps(&m);
609    free(m);
610    free(REQUEST);
611    return 1;
612  }
613  if(strncasecmp(REQUEST,"GetCapabilities",15)!=0){
614    r_inputs=getMap(request_inputs,"Version");
615    if(r_inputs==NULL){ 
616      errorException(m, _("Parameter <version> was not specified"),"MissingParameterValue");
617      freeMaps(&m);
618      free(m);
619      free(REQUEST);
620      return 1;
621    }
622  }
623
624  r_inputs=getMap(request_inputs,"serviceprovider");
625  if(r_inputs==NULL){
626    addToMap(request_inputs,"serviceprovider","");
627  }
628
629  maps* request_output_real_format=NULL;
630  map* tmpm=getMapFromMaps(m,"main","serverAddress");
631  if(tmpm!=NULL)
632    SERVICE_URL=strdup(tmpm->value);
633  else
634    SERVICE_URL=strdup(DEFAULT_SERVICE_URL);
635
636  service* s1;
637  int scount=0;
638#ifdef DEBUG
639  dumpMap(r_inputs);
640#endif
641  char conf_dir[1024];
642  int t;
643  char tmps1[1024];
644
645  r_inputs=NULL;
646  r_inputs=getMap(request_inputs,"metapath");
647  if(r_inputs!=NULL)
648    snprintf(conf_dir,1024,"%s/%s",ntmp,r_inputs->value);
649  else
650    snprintf(conf_dir,1024,"%s",ntmp);
651
652  if(strncasecmp(REQUEST,"GetCapabilities",15)==0){
653    struct dirent *dp;
654#ifdef DEBUG
655    dumpMap(r_inputs);
656#endif
657    DIR *dirp = opendir(conf_dir);
658    if(dirp==NULL){
659      return errorException(m, _("The specified path doesn't exist."),"InvalidParameterValue");
660    }
661    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
662    r_inputs=NULL;
663    r_inputs=getMap(request_inputs,"ServiceProvider");
664    xmlNodePtr n;
665    if(r_inputs!=NULL)
666      n = printGetCapabilitiesHeader(doc,r_inputs->value,m);
667    else
668      n = printGetCapabilitiesHeader(doc,"",m);
669    /**
670     * Here we need to close stdout to ensure that not supported chars
671     * has been found in the zcfg and then printed on stdout
672     */
673    int saved_stdout = dup(fileno(stdout));
674    dup2(fileno(stderr),fileno(stdout));
675    while ((dp = readdir(dirp)) != NULL)
676      if(strstr(dp->d_name,".zcfg")!=0){
677        memset(tmps1,0,1024);
678        snprintf(tmps1,1024,"%s/%s",conf_dir,dp->d_name);
679        s1=(service*)calloc(1,SERVICE_SIZE);
680        if(s1 == NULL){ 
681          return errorException(m, _("Unable to allocate memory."),"InternalError");
682        }
683#ifdef DEBUG
684        fprintf(stderr,"#################\n%s\n#################\n",tmps1);
685#endif
686        t=getServiceFromFile(tmps1,&s1);
687#ifdef DEBUG
688        dumpService(s1);
689        fflush(stdout);
690        fflush(stderr);
691#endif
692        printGetCapabilitiesForProcess(m,n,s1);
693        freeService(&s1);
694        free(s1);
695        scount++;
696      }
697    (void)closedir(dirp);
698    fflush(stdout);
699    dup2(saved_stdout,fileno(stdout));
700    printDocument(m,doc,getpid());
701    freeMaps(&m);
702    free(m);
703    free(REQUEST);
704    free(SERVICE_URL);
705    fflush(stdout);
706    return 0;
707  }
708  else{
709    r_inputs=getMap(request_inputs,"Identifier");
710    if(r_inputs==NULL 
711       || strlen(r_inputs->name)==0 || strlen(r_inputs->value)==0){ 
712      errorException(m, _("Mandatory <identifier> was not specified"),"MissingParameterValue");
713      freeMaps(&m);
714      free(m);
715      free(REQUEST);
716      free(SERVICE_URL);
717      return 0;
718    }
719
720    struct dirent *dp;
721    DIR *dirp = opendir(conf_dir);
722    if(dirp==NULL){
723      errorException(m, _("The specified path path doesn't exist."),"InvalidParameterValue");
724      freeMaps(&m);
725      free(m);
726      free(REQUEST);
727      free(SERVICE_URL);
728      return 0;
729    }
730    if(strncasecmp(REQUEST,"DescribeProcess",15)==0){
731      /**
732       * Loop over Identifier list
733       */
734      xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
735      r_inputs=NULL;
736      r_inputs=getMap(request_inputs,"ServiceProvider");
737
738      xmlNodePtr n;
739      if(r_inputs!=NULL)
740        n = printDescribeProcessHeader(doc,r_inputs->value,m);
741      else
742        n = printDescribeProcessHeader(doc,"",m);
743
744      r_inputs=getMap(request_inputs,"Identifier");
745      char *tmps=strtok(r_inputs->value,",");
746     
747      char buff[256];
748      char buff1[1024];
749      int saved_stdout = dup(fileno(stdout));
750      dup2(fileno(stderr),fileno(stdout));
751      while(tmps){
752        memset(buff,0,256);
753        snprintf(buff,256,"%s.zcfg",tmps);
754        memset(buff1,0,1024);
755#ifdef DEBUG
756        fprintf(stderr,"\n#######%s\n########\n",buff1);
757#endif
758        while ((dp = readdir(dirp)) != NULL)
759          if((strcasecmp("all.zcfg",buff)==0 && strstr(dp->d_name,".zcfg")>0)
760             || strcasecmp(dp->d_name,buff)==0){
761            memset(buff1,0,1024);
762            snprintf(buff1,1024,"%s/%s",conf_dir,dp->d_name);
763            s1=(service*)calloc(1,SERVICE_SIZE);
764            if(s1 == NULL){
765              return errorException(m, _("Unable to allocate memory."),"InternalError");
766            }
767#ifdef DEBUG
768            fprintf(stderr,"#################\n%s\n#################\n",buff1);
769#endif
770            t=getServiceFromFile(buff1,&s1);
771#ifdef DEBUG
772            dumpService(s1);
773#endif
774            printDescribeProcessForProcess(m,n,s1,1);
775            freeService(&s1);
776            free(s1);
777            scount++;
778          }
779        rewinddir(dirp);
780        tmps=strtok(NULL,",");
781      }
782      closedir(dirp);
783      fflush(stdout);
784      dup2(saved_stdout,fileno(stdout));
785      printDocument(m,doc,getpid());
786      freeMaps(&m);
787      free(m);
788      free(REQUEST);
789      free(SERVICE_URL);
790      fflush(stdout);
791#ifndef LINUX_FREE_ISSUE
792      if(s1)
793        free(s1);
794#endif
795      return 0;
796    }
797    else
798      if(strncasecmp(REQUEST,"Execute",strlen(REQUEST))!=0){
799        errorException(m, _("Unenderstood <request> value. Please check that it was set to GetCapabilities, DescribeProcess or Execute."), "InvalidParameterValue");
800#ifdef DEBUG
801        fprintf(stderr,"No request found %s",REQUEST);
802#endif 
803        closedir(dirp);
804        return 0;
805      }
806    closedir(dirp);
807  }
808 
809  s1=NULL;
810  s1=(service*)calloc(1,SERVICE_SIZE);
811  if(s1 == NULL){
812    freeMaps(&m);
813    free(m);
814    free(REQUEST);
815    free(SERVICE_URL);
816    return errorException(m, _("Unable to allocate memory."),"InternalError");
817  }
818  r_inputs=getMap(request_inputs,"MetaPath");
819  if(r_inputs!=NULL)
820    snprintf(tmps1,1024,"%s/%s",ntmp,r_inputs->value);
821  else
822    snprintf(tmps1,1024,"%s/",ntmp);
823  r_inputs=getMap(request_inputs,"Identifier");
824  char *ttmp=strdup(tmps1);
825  snprintf(tmps1,1024,"%s/%s.zcfg",ttmp,r_inputs->value);
826  free(ttmp);
827#ifdef DEBUG
828  fprintf(stderr,"Trying to load %s\n", tmps1);
829#endif
830  int saved_stdout = dup(fileno(stdout));
831  dup2(fileno(stderr),fileno(stdout));
832  t=getServiceFromFile(tmps1,&s1);
833  fflush(stdout);
834  dup2(saved_stdout,fileno(stdout));
835  if(t<0){
836    char *tmpMsg=(char*)malloc(2048+strlen(r_inputs->value));
837   
838    sprintf(tmpMsg,_("The value for <indetifier> seems to be wrong (%s). Please, ensure that the process exist using the GetCapabilities request."),r_inputs->value);
839    errorException(m, tmpMsg, "InvalidParameterValue");
840    free(tmpMsg);
841    freeService(&s1);
842    free(s1);
843    freeMaps(&m);
844    free(m);
845    free(REQUEST);
846    free(SERVICE_URL);
847    return 0;
848  }
849  close(saved_stdout);
850
851#ifdef DEBUG
852  dumpService(s1);
853#endif
854  int j;
855 
856  /**
857   * Create the input and output maps data structure
858   */
859  int i=0;
860  HINTERNET hInternet;
861  HINTERNET res;
862  hInternet=InternetOpen(
863#ifndef WIN32
864                         (LPCTSTR)
865#endif
866                         "ZooWPSClient\0",
867                         INTERNET_OPEN_TYPE_PRECONFIG,
868                         NULL,NULL, 0);
869
870#ifndef WIN32
871  if(!CHECK_INET_HANDLE(hInternet))
872    fprintf(stderr,"WARNING : hInternet handle failed to initialize");
873#endif
874  maps* request_input_real_format=NULL;
875  maps* tmpmaps = request_input_real_format;
876  map* postRequest=NULL;
877  postRequest=getMap(request_inputs,"xrequest");
878  if(postRequest==NULLMAP){
879    /**
880     * Parsing outputs provided as KVP
881     */
882    r_inputs=NULL;
883#ifdef DEBUG
884    fprintf(stderr,"OUTPUT Parsing ... \n");
885#endif
886    r_inputs=getMap(request_inputs,"ResponseDocument"); 
887    if(r_inputs==NULL) r_inputs=getMap(request_inputs,"RawDataOutput");
888   
889#ifdef DEBUG
890    fprintf(stderr,"OUTPUT Parsing ... \n");
891#endif
892    if(r_inputs!=NULL){
893#ifdef DEBUG
894      fprintf(stderr,"OUTPUT Parsing start now ... \n");
895#endif
896      char cursor_output[10240];
897      char *cotmp=strdup(r_inputs->value);
898      snprintf(cursor_output,10240,"%s",cotmp);
899      free(cotmp);
900      j=0;
901       
902      /**
903       * Put each Output into the outputs_as_text array
904       */
905      char * pToken;
906      maps* tmp_output=NULL;
907#ifdef DEBUG
908      fprintf(stderr,"OUTPUT [%s]\n",cursor_output);
909#endif
910      pToken=strtok(cursor_output,";");
911      char** outputs_as_text=(char**)calloc(128,sizeof(char*));
912      if(outputs_as_text == NULL) {
913        return errorException(m, _("Unable to allocate memory"), "InternalError");
914      }
915      i=0;
916      while(pToken!=NULL){
917#ifdef DEBUG
918        fprintf(stderr,"***%s***\n",pToken);
919        fflush(stderr);
920        fprintf(stderr,"***%s***\n",pToken);
921#endif
922        outputs_as_text[i]=(char*)calloc(strlen(pToken)+1,sizeof(char));
923        if(outputs_as_text[i] == NULL) {
924          return errorException(m, _("Unable to allocate memory"), "InternalError");
925        }
926        snprintf(outputs_as_text[i],strlen(pToken)+1,"%s",pToken);
927        pToken = strtok(NULL,";");
928        i++;
929      }
930      for(j=0;j<i;j++){
931        char *tmp=strdup(outputs_as_text[j]);
932        free(outputs_as_text[j]);
933        char *tmpc;
934        tmpc=strtok(tmp,"@");
935        int k=0;
936        while(tmpc!=NULL){
937          if(k==0){
938            if(tmp_output==NULL){
939              tmp_output=(maps*)calloc(1,MAPS_SIZE);
940              if(tmp_output == NULL){
941                return errorException(m, _("Unable to allocate memory."), "InternalError");
942              }
943              tmp_output->name=strdup(tmpc);
944              tmp_output->content=NULL;
945              tmp_output->next=NULL;
946            }
947          }
948          else{
949            char *tmpv=strstr(tmpc,"=");
950            char tmpn[256];
951            memset(tmpn,0,256);
952            strncpy(tmpn,tmpc,(strlen(tmpc)-strlen(tmpv))*sizeof(char));
953            tmpn[strlen(tmpc)-strlen(tmpv)]=0;
954#ifdef DEBUG
955            fprintf(stderr,"OUTPUT DEF [%s]=[%s]\n",tmpn,tmpv+1);
956#endif
957            if(tmp_output->content==NULL){
958              tmp_output->content=createMap(tmpn,tmpv+1);
959              tmp_output->content->next=NULL;
960            }
961            else
962              addToMap(tmp_output->content,tmpn,tmpv+1);
963          }
964          k++;
965#ifdef DEBUG
966          fprintf(stderr,"***%s***\n",tmpc);
967#endif
968          tmpc=strtok(NULL,"@");
969        }
970        if(request_output_real_format==NULL)
971          request_output_real_format=dupMaps(&tmp_output);
972        else
973          addMapsToMaps(&request_output_real_format,tmp_output);
974        freeMaps(&tmp_output);
975        free(tmp_output);
976        tmp_output=NULL;
977#ifdef DEBUG
978        dumpMaps(tmp_output);
979        fflush(stderr);
980#endif
981        free(tmp);
982      }
983      free(outputs_as_text);
984    }
985
986
987    /**
988     * Parsing inputs provided as KVP
989     */
990    r_inputs=getMap(request_inputs,"DataInputs");
991#ifdef DEBUG
992    fprintf(stderr,"DATA INPUTS [%s]\n",r_inputs->value);
993#endif
994    char cursor_input[40960];
995    if(r_inputs!=NULL)
996      snprintf(cursor_input,40960,"%s",r_inputs->value);
997    else{
998      errorException(m, _("Parameter <DataInputs> was not specified"),"MissingParameterValue");
999      freeMaps(&m);
1000      free(m);
1001      free(REQUEST);
1002      free(SERVICE_URL);
1003      InternetCloseHandle(hInternet);
1004      freeService(&s1);
1005      free(s1);
1006      return 0;
1007    }
1008    j=0;
1009 
1010    /**
1011     * Put each DataInputs into the inputs_as_text array
1012     */
1013    char *tmp1=strdup(cursor_input);
1014    char * pToken;
1015    pToken=strtok(cursor_input,";");
1016    if(pToken!=NULL && strncasecmp(pToken,tmp1,strlen(tmp1))==0){
1017      char* tmp2=url_decode(tmp1);
1018      snprintf(cursor_input,(strlen(tmp2)+1)*sizeof(char),"%s",tmp2);
1019      free(tmp2);
1020      pToken=strtok(cursor_input,";");
1021    }
1022    free(tmp1);
1023
1024    char** inputs_as_text=(char**)calloc(100,sizeof(char*));
1025    if(inputs_as_text == NULL){
1026      return errorException(m, _("Unable to allocate memory."), "InternalError");
1027    }
1028    i=0;
1029    while(pToken!=NULL){
1030#ifdef DEBUG
1031      fprintf(stderr,"***%s***\n",pToken);
1032#endif
1033      fflush(stderr);
1034#ifdef DEBUG
1035      fprintf(stderr,"***%s***\n",pToken);
1036#endif
1037      inputs_as_text[i]=(char*)calloc(strlen(pToken)+1,sizeof(char));
1038      snprintf(inputs_as_text[i],strlen(pToken)+1,"%s",pToken);
1039      if(inputs_as_text[i] == NULL){
1040        return errorException(m, _("Unable to allocate memory."), "InternalError");
1041      }
1042      pToken = strtok(NULL,";");
1043      i++;
1044    }
1045
1046    for(j=0;j<i;j++){
1047      char *tmp=strdup(inputs_as_text[j]);
1048      free(inputs_as_text[j]);
1049      char *tmpc;
1050      tmpc=strtok(tmp,"@");
1051      while(tmpc!=NULL){
1052#ifdef DEBUG
1053        fprintf(stderr,"***\n***%s***\n",tmpc);
1054#endif
1055        char *tmpv=strstr(tmpc,"=");
1056        char tmpn[256];
1057        memset(tmpn,0,256);
1058        if(tmpv!=NULL){
1059          strncpy(tmpn,tmpc,(strlen(tmpc)-strlen(tmpv))*sizeof(char));
1060          tmpn[strlen(tmpc)-strlen(tmpv)]=0;
1061        }
1062        else{
1063          strncpy(tmpn,tmpc,strlen(tmpc)*sizeof(char));
1064          tmpn[strlen(tmpc)]=0;
1065        }
1066#ifdef DEBUG
1067        fprintf(stderr,"***\n*** %s = %s ***\n",tmpn,tmpv+1);
1068#endif
1069        if(tmpmaps==NULL){
1070          tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1071          if(tmpmaps == NULL){
1072            return errorException(m, _("Unable to allocate memory."), "InternalError");
1073          }
1074          tmpmaps->name=strdup(tmpn);
1075          if(tmpv!=NULL){
1076            char *tmpvf=url_decode(tmpv+1);
1077            tmpmaps->content=createMap("value",tmpvf);
1078            free(tmpvf);
1079          }
1080          else
1081            tmpmaps->content=createMap("value","Reference");
1082          tmpmaps->next=NULL;
1083        }
1084        tmpc=strtok(NULL,"@");
1085        while(tmpc!=NULL){
1086#ifdef DEBUG
1087          fprintf(stderr,"*** KVP NON URL-ENCODED \n***%s***\n",tmpc);
1088#endif
1089          char *tmpv1=strstr(tmpc,"=");
1090#ifdef DEBUG
1091          fprintf(stderr,"*** VALUE NON URL-ENCODED \n***%s***\n",tmpv1+1);
1092#endif
1093          char tmpn1[1024];
1094          memset(tmpn1,0,1024);
1095          if(tmpv1!=NULL){
1096            strncpy(tmpn1,tmpc,strlen(tmpc)-strlen(tmpv1));
1097            tmpn1[strlen(tmpc)-strlen(tmpv1)]=0;
1098            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
1099          }
1100          else{
1101            strncpy(tmpn1,tmpc,strlen(tmpc));
1102            tmpn1[strlen(tmpc)]=0;
1103            map* lmap=getLastMap(tmpmaps->content);
1104            char *tmpValue=(char*)calloc((strlen(tmpv)+strlen(tmpc)+1),sizeof(char));
1105            sprintf(tmpValue,"%s@%s",tmpv+1,tmpc);
1106            free(lmap->value);
1107            lmap->value=strdup(tmpValue);
1108            free(tmpValue);
1109            tmpc=strtok(NULL,"@");
1110            continue;
1111          }
1112#ifdef DEBUG
1113          fprintf(stderr,"*** NAME NON URL-ENCODED \n***%s***\n",tmpn1);
1114          fprintf(stderr,"*** VALUE NON URL-ENCODED \n***%s***\n",tmpv1+1);
1115#endif
1116          if(strcmp(tmpn1,"xlink:href")!=0)
1117            addToMap(tmpmaps->content,tmpn1,tmpv1+1);
1118          else
1119            if(tmpv1!=NULL){
1120              char *tmpx2=url_decode(tmpv1+1);
1121              if(strncasecmp(tmpx2,"http://",7)!=0 &&
1122                 strncasecmp(tmpx2,"ftp://",6)!=0){
1123                char emsg[1024];
1124                sprintf(emsg,_("Unable to find a valid protocol to download the remote file %s"),tmpv1+1);
1125                errorException(m,emsg,"InternalError");
1126                freeMaps(&m);
1127                free(m);
1128                free(REQUEST);
1129                free(SERVICE_URL);
1130                InternetCloseHandle(hInternet);
1131                freeService(&s1);
1132                free(s1);
1133                return 0;
1134              }
1135#ifdef DEBUG
1136              fprintf(stderr,"REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n",tmpv1+1);
1137#endif
1138              addToMap(tmpmaps->content,tmpn1,tmpx2);
1139             
1140#ifndef WIN32
1141              if(CHECK_INET_HANDLE(hInternet))
1142#endif
1143                {
1144                  if(loadRemoteFile(m,tmpmaps->content,hInternet,tmpx2)<0){
1145                    freeMaps(&m);
1146                    free(m);
1147                    free(REQUEST);
1148                    free(SERVICE_URL);
1149                    InternetCloseHandle(hInternet);
1150                    freeService(&s1);
1151                    free(s1);
1152                    return 0;
1153                  }
1154                }
1155              free(tmpx2);
1156              addToMap(tmpmaps->content,"Reference",tmpv1+1);
1157            }
1158          tmpc=strtok(NULL,"@");
1159        }
1160#ifdef DEBUG
1161        dumpMaps(tmpmaps);
1162        fflush(stderr);
1163#endif
1164        if(request_input_real_format==NULL)
1165          request_input_real_format=dupMaps(&tmpmaps);
1166        else{
1167          maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
1168          if(testPresence!=NULL){
1169            elements* elem=getElements(s1->inputs,tmpmaps->name);
1170            if(elem!=NULL){
1171              if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
1172                freeMaps(&m);
1173                free(m);
1174                free(REQUEST);
1175                free(SERVICE_URL);
1176                InternetCloseHandle(hInternet);
1177                freeService(&s1);
1178                free(s1);
1179                return 0;
1180              }
1181            }
1182          }
1183          else
1184            addMapsToMaps(&request_input_real_format,tmpmaps);
1185        }
1186        freeMaps(&tmpmaps);
1187        free(tmpmaps);
1188        tmpmaps=NULL;
1189        free(tmp);
1190      }
1191    }
1192    free(inputs_as_text);
1193  }
1194  else {
1195    /**
1196     * Parse XML request
1197     */ 
1198    xmlInitParser();
1199#ifdef DEBUG
1200    fflush(stderr);
1201    fprintf(stderr,"BEFORE %s\n",postRequest->value);
1202    fflush(stderr);
1203#endif
1204    xmlDocPtr doc =
1205      xmlParseMemory(postRequest->value,cgiContentLength);
1206#ifdef DEBUG
1207    fprintf(stderr,"AFTER\n");
1208    fflush(stderr);
1209#endif
1210    /**
1211     * Parse every Input in DataInputs node.
1212     */
1213    xmlXPathObjectPtr tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='Input']");
1214    xmlNodeSet* tmps=tmpsptr->nodesetval;
1215#ifdef DEBUG
1216    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1217#endif
1218    for(int k=0;k<tmps->nodeNr;k++){
1219      maps *tmpmaps=NULL;
1220      xmlNodePtr cur=tmps->nodeTab[k];
1221      if(tmps->nodeTab[k]->type == XML_ELEMENT_NODE) {
1222        /**
1223         * A specific Input node.
1224         */
1225#ifdef DEBUG
1226        fprintf(stderr, "= element 0 node \"%s\"\n", cur->name);
1227#endif
1228        xmlNodePtr cur2=cur->children;
1229        while(cur2!=NULL){
1230          while(cur2!=NULL && cur2->type!=XML_ELEMENT_NODE)
1231            cur2=cur2->next;
1232          if(cur2==NULL)
1233            break;
1234          /**
1235           * Indentifier
1236           */
1237          if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1238            xmlChar *val= xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1239            if(tmpmaps==NULL){
1240              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1241              if(tmpmaps == NULL){
1242                return errorException(m, _("Unable to allocate memory."), "InternalError");
1243              }
1244              tmpmaps->name=strdup((char*)val);
1245              tmpmaps->content=NULL;
1246              tmpmaps->next=NULL;
1247            }
1248            xmlFree(val);
1249          }
1250          /**
1251           * Title, Asbtract
1252           */
1253          if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1254             xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1255            xmlChar *val=
1256              xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1257            if(tmpmaps==NULL){
1258              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1259              if(tmpmaps == NULL){
1260                return errorException(m, _("Unable to allocate memory."), "InternalError");
1261              }
1262              tmpmaps->name=strdup("missingIndetifier");
1263              tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1264              tmpmaps->next=NULL;
1265            }
1266            else{
1267              if(tmpmaps->content!=NULL)
1268                addToMap(tmpmaps->content,
1269                         (char*)cur2->name,(char*)val);
1270              else
1271                tmpmaps->content=
1272                  createMap((char*)cur2->name,(char*)val);
1273            }
1274#ifdef DEBUG
1275            dumpMaps(tmpmaps);
1276#endif
1277            xmlFree(val);
1278          }
1279          /**
1280           * InputDataFormChoice (Reference or Data ?)
1281           */
1282          if(xmlStrcasecmp(cur2->name,BAD_CAST "Reference")==0){
1283            /**
1284             * Get every attribute from a Reference node
1285             * mimeType, encoding, schema, href, method
1286             * Header and Body gesture should be added here
1287             */
1288#ifdef DEBUG
1289            fprintf(stderr,"REFERENCE\n");
1290#endif
1291            const char *refs[5]={"mimeType","encoding","schema","method","href"};
1292            for(int l=0;l<5;l++){
1293#ifdef DEBUG
1294              fprintf(stderr,"*** %s ***",refs[l]);
1295#endif
1296              xmlChar *val=xmlGetProp(cur2,BAD_CAST refs[l]);
1297              if(val!=NULL && xmlStrlen(val)>0){
1298                if(tmpmaps->content!=NULL)
1299                  addToMap(tmpmaps->content,refs[l],(char*)val);
1300                else
1301                  tmpmaps->content=createMap(refs[l],(char*)val);
1302                map* ltmp=getMap(tmpmaps->content,"method");
1303                if(l==4){
1304                  if(!(ltmp!=NULL && strcmp(ltmp->value,"POST")==0)
1305                     && CHECK_INET_HANDLE(hInternet)){
1306                    if(loadRemoteFile(m,tmpmaps->content,hInternet,(char*)val)){
1307                      freeMaps(&m);
1308                      free(m);
1309                      free(REQUEST);
1310                      free(SERVICE_URL);
1311                      InternetCloseHandle(hInternet);
1312                      freeService(&s1);
1313                      free(s1);
1314                      return 0;
1315                    }
1316                  }
1317                }
1318              }
1319#ifdef DEBUG
1320              fprintf(stderr,"%s\n",val);
1321#endif
1322              xmlFree(val);
1323            }
1324#ifdef POST_DEBUG
1325            fprintf(stderr,"Parse Header and Body from Reference \n");
1326#endif
1327            xmlNodePtr cur3=cur2->children;
1328            hInternet.header=NULL;
1329            while(cur3){
1330              while(cur3!=NULL && cur3->type!=XML_ELEMENT_NODE)
1331                cur2=cur3->next;
1332              if(xmlStrcasecmp(cur3->name,BAD_CAST "Header")==0 ){
1333                const char *ha[2];
1334                ha[0]="key";
1335                ha[1]="value";
1336                int hai;
1337                char *has;
1338                char *key;
1339                for(hai=0;hai<2;hai++){
1340                  xmlChar *val=xmlGetProp(cur3,BAD_CAST ha[hai]);
1341#ifdef POST_DEBUG
1342                  fprintf(stderr,"%s = %s\n",ha[hai],(char*)val);
1343#endif
1344                  if(hai==0){
1345                    key=(char*)calloc((1+strlen((char*)val)),sizeof(char));
1346                    snprintf(key,1+strlen((char*)val),"%s",(char*)val);
1347                  }else{
1348                    has=(char*)calloc((3+strlen((char*)val)+strlen(key)),sizeof(char));
1349                    if(has == NULL){
1350                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1351                    }
1352                    snprintf(has,(3+strlen((char*)val)+strlen(key)),"%s: %s",key,(char*)val);
1353#ifdef POST_DEBUG
1354                    fprintf(stderr,"%s\n",has);
1355#endif
1356                  }
1357                }
1358                hInternet.header=curl_slist_append(hInternet.header, has);
1359                free(has);
1360              }
1361              else{
1362#ifdef POST_DEBUG
1363                fprintf(stderr,"Try to fetch the body part of the request ...\n");
1364#endif
1365                if(xmlStrcasecmp(cur3->name,BAD_CAST "Body")==0 ){
1366#ifdef POST_DEBUG
1367                  fprintf(stderr,"Body part found !!!\n",(char*)cur3->content);
1368#endif
1369                  char *tmp=new char[cgiContentLength];
1370                  memset(tmp,0,cgiContentLength);
1371                  xmlNodePtr cur4=cur3->children;
1372                  while(cur4!=NULL){
1373                    while(cur4->type!=XML_ELEMENT_NODE)
1374                      cur4=cur4->next;
1375                    xmlDocPtr bdoc = xmlNewDoc(BAD_CAST "1.0");
1376                    bdoc->encoding = xmlCharStrdup ("UTF-8");
1377                    xmlDocSetRootElement(bdoc,cur4);
1378                    xmlChar* btmps;
1379                    int bsize;
1380                    xmlDocDumpMemory(bdoc,&btmps,&bsize);
1381#ifdef POST_DEBUG
1382                    fprintf(stderr,"Body part found !!! %s %s\n",tmp,(char*)btmps);
1383#endif
1384                    if(btmps!=NULL)
1385                      sprintf(tmp,"%s",(char*)btmps);
1386                    xmlFreeDoc(bdoc);
1387                    cur4=cur4->next;
1388                  }
1389                  map *btmp=getMap(tmpmaps->content,"href");
1390                  if(btmp!=NULL){
1391#ifdef POST_DEBUG
1392                    fprintf(stderr,"%s %s\n",btmp->value,tmp);
1393                    curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1394#endif
1395                    res=InternetOpenUrl(hInternet,btmp->value,tmp,strlen(tmp),
1396                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
1397                    char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
1398                    if(tmpContent == NULL){
1399                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1400                    }
1401                    size_t dwRead;
1402                    InternetReadFile(res, (LPVOID)tmpContent,
1403                                     res.nDataLen, &dwRead);
1404                    tmpContent[res.nDataLen]=0;
1405                    if(hInternet.header!=NULL)
1406                      curl_slist_free_all(hInternet.header);
1407                    addToMap(tmpmaps->content,"value",tmpContent);
1408#ifdef POST_DEBUG
1409                    fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1410#endif
1411                  }
1412                }
1413                else
1414                  if(xmlStrcasecmp(cur3->name,BAD_CAST "BodyReference")==0 ){
1415                    xmlChar *val=xmlGetProp(cur3,BAD_CAST "href");
1416                    HINTERNET bInternet,res1;
1417                    bInternet=InternetOpen(
1418#ifndef WIN32
1419                                           (LPCTSTR)
1420#endif
1421                                           "ZooWPSClient\0",
1422                                           INTERNET_OPEN_TYPE_PRECONFIG,
1423                                           NULL,NULL, 0);
1424                    if(!CHECK_INET_HANDLE(bInternet))
1425                      fprintf(stderr,"WARNING : hInternet handle failed to initialize");
1426#ifdef POST_DEBUG
1427                    curl_easy_setopt(bInternet.handle, CURLOPT_VERBOSE, 1);
1428#endif
1429                    res1=InternetOpenUrl(bInternet,(char*)val,NULL,0,
1430                                         INTERNET_FLAG_NO_CACHE_WRITE,0);
1431                    char* tmp=
1432                      (char*)calloc((res1.nDataLen+1),sizeof(char));
1433                    if(tmp == NULL){
1434                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1435                    }
1436                    size_t bRead;
1437                    InternetReadFile(res1, (LPVOID)tmp,
1438                                     res1.nDataLen, &bRead);
1439                    tmp[res1.nDataLen]=0;
1440                    InternetCloseHandle(bInternet);
1441                    map *btmp=getMap(tmpmaps->content,"href");
1442                    if(btmp!=NULL){
1443#ifdef POST_DEBUG
1444                      fprintf(stderr,"%s %s\n",btmp->value,tmp);
1445                      curl_easy_setopt(hInternet.handle, CURLOPT_VERBOSE, 1);
1446#endif
1447                      res=InternetOpenUrl(hInternet,btmp->value,tmp,
1448                                          strlen(tmp),
1449                                          INTERNET_FLAG_NO_CACHE_WRITE,0);
1450                      char* tmpContent = (char*)calloc((res.nDataLen+1),sizeof(char));
1451                      if(tmpContent == NULL){
1452                        return errorException(m, _("Unable to allocate memory."), "InternalError");
1453                      }
1454                      size_t dwRead;
1455                      InternetReadFile(res, (LPVOID)tmpContent,
1456                                       res.nDataLen, &dwRead);
1457                      tmpContent[res.nDataLen]=0;
1458                      if(hInternet.header!=NULL)
1459                        curl_slist_free_all(hInternet.header);
1460                      addToMap(tmpmaps->content,"value",tmpContent);
1461#ifdef POST_DEBUG
1462                      fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1463#endif
1464                    }
1465                  }
1466              }
1467              cur3=cur3->next;
1468            }
1469#ifdef POST_DEBUG
1470            fprintf(stderr,"Header and Body was parsed from Reference \n");
1471#endif
1472#ifdef DEBUG
1473            dumpMap(tmpmaps->content);
1474            fprintf(stderr, "= element 2 node \"%s\" = (%s)\n", 
1475                    cur2->name,cur2->content);
1476#endif
1477          }
1478          else if(xmlStrcasecmp(cur2->name,BAD_CAST "Data")==0){
1479#ifdef DEBUG
1480            fprintf(stderr,"DATA\n");
1481#endif
1482            xmlNodePtr cur4=cur2->children;
1483            while(cur4!=NULL){
1484              while(cur4!=NULL &&cur4->type!=XML_ELEMENT_NODE)
1485                cur4=cur4->next;
1486              if(cur4==NULL)
1487                break;
1488              if(xmlStrcasecmp(cur4->name, BAD_CAST "LiteralData")==0){
1489                /**
1490                 * Get every attribute from a LiteralData node
1491                 * dataType , uom
1492                 */
1493                char *list[2];
1494                list[0]=strdup("dataType");
1495                list[1]=strdup("uom");
1496                for(int l=0;l<2;l++){
1497#ifdef DEBUG
1498                  fprintf(stderr,"*** LiteralData %s ***",list[l]);
1499#endif
1500                  xmlChar *val=xmlGetProp(cur4,BAD_CAST list[l]);
1501                  if(val!=NULL && strlen((char*)val)>0){
1502                    if(tmpmaps->content!=NULL)
1503                      addToMap(tmpmaps->content,list[l],(char*)val);
1504                    else
1505                      tmpmaps->content=createMap(list[l],(char*)val);
1506#ifdef DEBUG
1507                    fprintf(stderr,"%s\n",val);
1508#endif
1509                  }
1510                  xmlFree(val);
1511                  free(list[l]);                 
1512                }
1513              }
1514              else if(xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0){
1515                /**
1516                 * Get every attribute from a Reference node
1517                 * mimeType, encoding, schema
1518                 */
1519                const char *coms[3]={"mimeType","encoding","schema"};
1520                for(int l=0;l<3;l++){
1521#ifdef DEBUG
1522                  fprintf(stderr,"*** ComplexData %s ***\n",coms[l]);
1523#endif
1524                  xmlChar *val=xmlGetProp(cur4,BAD_CAST coms[l]);
1525                  if(val!=NULL && strlen((char*)val)>0){
1526                    if(tmpmaps->content!=NULL)
1527                      addToMap(tmpmaps->content,coms[l],(char*)val);
1528                    else
1529                      tmpmaps->content=createMap(coms[l],(char*)val);
1530#ifdef DEBUG
1531                    fprintf(stderr,"%s\n",val);
1532#endif
1533                  }
1534                  xmlFree(val);
1535                }
1536              }
1537
1538              map* test=getMap(tmpmaps->content,"encoding");
1539              if(test==NULL){
1540                if(tmpmaps->content!=NULL)
1541                  addToMap(tmpmaps->content,"encoding","utf-8");
1542                else
1543                  tmpmaps->content=createMap("encoding","utf-8");
1544                test=getMap(tmpmaps->content,"encoding");
1545              }
1546
1547              if(strcasecmp(test->value,"base64")!=0){
1548                xmlChar* mv=xmlNodeListGetString(doc,cur4->xmlChildrenNode,1);
1549                map* ltmp=getMap(tmpmaps->content,"mimeType");
1550                if(mv==NULL || 
1551                   (xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0 &&
1552                    (ltmp==NULL || strncasecmp(ltmp->value,"text/xml",8)==0) )){
1553                  xmlDocPtr doc1=xmlNewDoc(BAD_CAST "1.0");
1554                  int buffersize;
1555                  xmlNodePtr cur5=cur4->children;
1556                  while(cur5!=NULL &&cur5->type!=XML_ELEMENT_NODE)
1557                    cur5=cur5->next;
1558                  xmlDocSetRootElement(doc1,cur5);
1559                  xmlDocDumpFormatMemoryEnc(doc1, &mv, &buffersize, "utf-8", 1);
1560                  char size[1024];
1561                  sprintf(size,"%d",buffersize);
1562                  addToMap(tmpmaps->content,"size",size);
1563                }
1564                addToMap(tmpmaps->content,"value",(char*)mv);
1565                xmlFree(mv);
1566              }else{
1567                xmlChar* tmp=xmlNodeListGetRawString(doc,cur4->xmlChildrenNode,0);
1568                addToMap(tmpmaps->content,"value",(char*)tmp);
1569                map* tmpv=getMap(tmpmaps->content,"value");
1570                char *res=NULL;
1571                char *curs=tmpv->value;
1572                for(int i=0;i<=strlen(tmpv->value)/64;i++) {
1573                  if(res==NULL)
1574                    res=(char*)malloc(67*sizeof(char));
1575                  else
1576                    res=(char*)realloc(res,(((i+1)*65)+i)*sizeof(char));
1577                  int csize=i*65;
1578                  strncpy(res + csize,curs,64);
1579                  if(i==xmlStrlen(tmp)/64)
1580                    strcat(res,"\n\0");
1581                  else{
1582                    strncpy(res + (((i+1)*64)+i),"\n\0",2);
1583                    curs+=64;
1584                  }
1585                }
1586                free(tmpv->value);
1587                tmpv->value=strdup(res);
1588                free(res);
1589                xmlFree(tmp);
1590              }
1591              cur4=cur4->next;
1592            }
1593          }
1594#ifdef DEBUG
1595          fprintf(stderr,"cur2 next \n");
1596          fflush(stderr);
1597#endif
1598          cur2=cur2->next;
1599        }
1600#ifdef DEBUG
1601        fprintf(stderr,"ADD MAPS TO REQUEST MAPS !\n");
1602        fflush(stderr);
1603#endif
1604
1605        {
1606          maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
1607          if(testPresence!=NULL){
1608            elements* elem=getElements(s1->inputs,tmpmaps->name);
1609            if(elem!=NULL){
1610              if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
1611                freeMaps(&m);
1612                free(m);
1613                free(REQUEST);
1614                free(SERVICE_URL);
1615                InternetCloseHandle(hInternet);
1616                freeService(&s1);
1617                free(s1);
1618                return 0;
1619              }
1620            }
1621          }
1622          else
1623            addMapsToMaps(&request_input_real_format,tmpmaps);
1624        }
1625       
1626#ifdef DEBUG
1627        fprintf(stderr,"******TMPMAPS*****\n");
1628        dumpMaps(tmpmaps);
1629        fprintf(stderr,"******REQUESTMAPS*****\n");
1630        dumpMaps(request_input_real_format);
1631#endif
1632        freeMaps(&tmpmaps);
1633        free(tmpmaps);
1634        tmpmaps=NULL;         
1635      }
1636#ifdef DEBUG
1637      dumpMaps(tmpmaps); 
1638#endif
1639    }
1640#ifdef DEBUG
1641    fprintf(stderr,"Search for response document node\n");
1642#endif
1643    xmlXPathFreeObject(tmpsptr);
1644   
1645    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='ResponseDocument']");
1646    bool asRaw=false;
1647    tmps=tmpsptr->nodesetval;
1648    if(tmps->nodeNr==0){
1649      tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='RawDataOutput']");
1650      tmps=tmpsptr->nodesetval;
1651      asRaw=true;
1652    }
1653#ifdef DEBUG
1654    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1655#endif
1656    for(int k=0;k<tmps->nodeNr;k++){
1657      if(asRaw==true)
1658        addToMap(request_inputs,"RawDataOutput","");
1659      else
1660        addToMap(request_inputs,"ResponseDocument","");
1661      maps *tmpmaps=NULL;
1662      xmlNodePtr cur=tmps->nodeTab[k];
1663      if(cur->type == XML_ELEMENT_NODE) {
1664        /**
1665         * A specific responseDocument node.
1666         */
1667        if(tmpmaps==NULL){
1668          tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1669          if(tmpmaps == NULL){
1670            return errorException(m, _("Unable to allocate memory."), "InternalError");
1671          }
1672          tmpmaps->name=strdup("unknownIdentifier");
1673          tmpmaps->next=NULL;
1674        }
1675        /**
1676         * Get every attribute from a LiteralData node
1677         * storeExecuteResponse, lineage, status
1678         */
1679        const char *ress[3]={"storeExecuteResponse","lineage","status"};
1680        xmlChar *val;
1681        for(int l=0;l<3;l++){
1682#ifdef DEBUG
1683          fprintf(stderr,"*** %s ***\t",ress[l]);
1684#endif
1685          val=xmlGetProp(cur,BAD_CAST ress[l]);
1686          if(val!=NULL && strlen((char*)val)>0){
1687            if(tmpmaps->content!=NULL)
1688              addToMap(tmpmaps->content,ress[l],(char*)val);
1689            else
1690              tmpmaps->content=createMap(ress[l],(char*)val);
1691            addToMap(request_inputs,ress[l],(char*)val);
1692          }
1693#ifdef DEBUG
1694          fprintf(stderr,"%s\n",val);
1695#endif
1696          xmlFree(val);
1697        }
1698        xmlNodePtr cur1=cur->children;
1699        while(cur1){
1700          /**
1701           * Indentifier
1702           */
1703          if(xmlStrncasecmp(cur1->name,BAD_CAST "Identifier",xmlStrlen(cur1->name))==0){
1704            xmlChar *val=
1705              xmlNodeListGetString(doc,cur1->xmlChildrenNode,1);
1706            if(tmpmaps==NULL){
1707              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1708              if(tmpmaps == NULL){
1709                return errorException(m, _("Unable to allocate memory."), "InternalError");
1710              }
1711              tmpmaps->name=strdup((char*)val);
1712              tmpmaps->content=NULL;
1713              tmpmaps->next=NULL;
1714            }
1715            else
1716              tmpmaps->name=strdup((char*)val);;
1717            xmlFree(val);
1718          }
1719          /**
1720           * Title, Asbtract
1721           */
1722          else if(xmlStrncasecmp(cur1->name,BAD_CAST "Title",xmlStrlen(cur1->name))==0 ||
1723                  xmlStrncasecmp(cur1->name,BAD_CAST "Abstract",xmlStrlen(cur1->name))==0){
1724            xmlChar *val=
1725              xmlNodeListGetString(doc,cur1->xmlChildrenNode,1);
1726            if(tmpmaps==NULL){
1727              tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1728              if(tmpmaps == NULL){
1729                return errorException(m, _("Unable to allocate memory."), "InternalError");
1730              }
1731              tmpmaps->name=strdup("missingIndetifier");
1732              tmpmaps->content=createMap((char*)cur1->name,(char*)val);
1733              tmpmaps->next=NULL;
1734            }
1735            else{
1736              if(tmpmaps->content!=NULL)
1737                addToMap(tmpmaps->content,
1738                         (char*)cur1->name,(char*)val);
1739              else
1740                tmpmaps->content=
1741                  createMap((char*)cur1->name,(char*)val);
1742            }
1743            xmlFree(val);
1744          }
1745          else if(xmlStrncasecmp(cur1->name,BAD_CAST "Output",xmlStrlen(cur1->name))==0){
1746            /**
1747             * Get every attribute from a Output node
1748             * mimeType, encoding, schema, uom, asReference
1749             */
1750            const char *outs[5]={"mimeType","encoding","schema","uom","asReference"};
1751            for(int l=0;l<5;l++){
1752#ifdef DEBUG
1753              fprintf(stderr,"*** %s ***\t",outs[l]);
1754#endif
1755              val=xmlGetProp(cur1,BAD_CAST outs[l]);
1756              if(val!=NULL && strlen((char*)val)>0){
1757                if(tmpmaps->content!=NULL)
1758                  addToMap(tmpmaps->content,outs[l],(char*)val);
1759                else
1760                  tmpmaps->content=createMap(outs[l],(char*)val);
1761              }
1762#ifdef DEBUG
1763              fprintf(stderr,"%s\n",val);
1764#endif
1765              xmlFree(val);
1766            }
1767           
1768            xmlNodePtr cur2=cur1->children;
1769            while(cur2){
1770              /**
1771               * Indentifier
1772               */
1773              if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1774                xmlChar *val=
1775                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1776                if(tmpmaps==NULL){
1777                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1778                  if(tmpmaps == NULL){
1779                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1780                  }
1781                  tmpmaps->name=strdup((char*)val);
1782                  tmpmaps->content=NULL;
1783                  tmpmaps->next=NULL;
1784                }
1785                else
1786                  tmpmaps->name=strdup((char*)val);;
1787                xmlFree(val);
1788              }
1789              /**
1790               * Title, Asbtract
1791               */
1792              else if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1793                      xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1794                xmlChar *val=
1795                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1796                if(tmpmaps==NULL){
1797                  tmpmaps=(maps*)calloc(1,MAPS_SIZE);
1798                  if(tmpmaps == NULL){
1799                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1800                  }
1801                  tmpmaps->name=strdup("missingIndetifier");
1802                  tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1803                  tmpmaps->next=NULL;
1804                }
1805                else{
1806                  if(tmpmaps->content!=NULL)
1807                    addToMap(tmpmaps->content,
1808                             (char*)cur2->name,(char*)val);
1809                  else
1810                    tmpmaps->content=
1811                      createMap((char*)cur2->name,(char*)val);
1812                }
1813                xmlFree(val);
1814              }
1815              cur2=cur2->next;
1816            }
1817          }
1818          cur1=cur1->next;
1819        }
1820      }
1821      if(request_output_real_format==NULL)
1822        request_output_real_format=dupMaps(&tmpmaps);
1823      else
1824        addMapsToMaps(&request_output_real_format,tmpmaps);
1825#ifdef DEBUG
1826      dumpMaps(tmpmaps);
1827#endif
1828      freeMaps(&tmpmaps);
1829      free(tmpmaps);
1830    }
1831
1832    xmlXPathFreeObject(tmpsptr);
1833    xmlCleanupParser();
1834  }
1835 
1836  //if(CHECK_INET_HANDLE(hInternet))
1837  InternetCloseHandle(hInternet);
1838
1839#ifdef DEBUG
1840  fprintf(stderr,"\n%i\n",i);
1841  dumpMaps(request_input_real_format);
1842  dumpMaps(request_output_real_format);
1843  dumpMap(request_inputs);
1844  fprintf(stderr,"\n%i\n",i);
1845#endif
1846
1847  /**
1848   * Ensure that each requested arguments are present in the request
1849   * DataInputs and ResponseDocument / RawDataOutput
1850   */
1851  char *dfv=addDefaultValues(&request_input_real_format,s1->inputs,m,0);
1852  char *dfv1=addDefaultValues(&request_output_real_format,s1->outputs,m,1);
1853  if(strcmp(dfv1,"")!=0 || strcmp(dfv,"")!=0){
1854    char tmps[1024];
1855    if(strcmp(dfv,"")!=0){
1856      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);
1857    }
1858    else if(strcmp(dfv1,"")!=0){
1859      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);
1860    }
1861    map* tmpe=createMap("text",tmps);
1862    addToMap(tmpe,"code","MissingParameterValue");
1863    printExceptionReportResponse(m,tmpe);
1864    freeService(&s1);
1865    free(s1);
1866    freeMap(&tmpe);
1867    free(tmpe);
1868    freeMaps(&m);
1869    free(m);
1870    free(REQUEST);
1871    free(SERVICE_URL);
1872    freeMaps(&request_input_real_format);
1873    free(request_input_real_format);
1874    freeMaps(&request_output_real_format);
1875    free(request_output_real_format);
1876    freeMaps(&tmpmaps);
1877    free(tmpmaps);
1878    return 1;
1879  }
1880  maps* tmpReqI=request_input_real_format;
1881  while(tmpReqI!=NULL){
1882    char name[1024];
1883    if(getMap(tmpReqI->content,"isFile")!=NULL){
1884      if (cgiFormFileName(tmpReqI->name, name, sizeof(name)) == cgiFormSuccess) {
1885        int BufferLen=1024;
1886        cgiFilePtr file;
1887        int targetFile;
1888        mode_t mode;
1889        char storageNameOnServer[2048];
1890        char fileNameOnServer[64];
1891        char contentType[1024];
1892        char buffer[1024];
1893        char *tmpStr=NULL;
1894        int size;
1895        int got,t;
1896        map *path=getMapFromMaps(m,"main","tmpPath");
1897        cgiFormFileSize(tmpReqI->name, &size);
1898        cgiFormFileContentType(tmpReqI->name, contentType, sizeof(contentType));
1899        if (cgiFormFileOpen(tmpReqI->name, &file) == cgiFormSuccess) {
1900          t=-1;
1901          while(1){
1902            tmpStr=strstr(name+t+1,"\\");
1903            if(NULL==tmpStr)
1904              tmpStr=strstr(name+t+1,"/");
1905            if(NULL!=tmpStr)
1906              t=(int)(tmpStr-name);
1907            else
1908              break;
1909          }
1910          strcpy(fileNameOnServer,name+t+1);
1911         
1912          sprintf(storageNameOnServer,"%s/%s",path->value,fileNameOnServer);
1913          fprintf(stderr,"Name on server %s\n",storageNameOnServer);
1914          fprintf(stderr,"fileNameOnServer: %s\n",fileNameOnServer);
1915          mode=S_IRWXU|S_IRGRP|S_IROTH;
1916          targetFile = open (storageNameOnServer,O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP|S_IROTH);
1917          if(targetFile<0){
1918            fprintf(stderr,"could not create the new file,%s\n",fileNameOnServer);         
1919          }else{
1920            while (cgiFormFileRead(file, buffer, BufferLen, &got) ==cgiFormSuccess){
1921              if(got>0)
1922                write(targetFile,buffer,got);
1923            }
1924          }
1925          addToMap(tmpReqI->content,"lref",storageNameOnServer);
1926          cgiFormFileClose(file);
1927          close(targetFile);
1928          fprintf(stderr,"File \"%s\" has been uploaded",fileNameOnServer);
1929        }
1930      }
1931    }
1932    tmpReqI=tmpReqI->next;
1933  }
1934
1935  ensureDecodedBase64(&request_input_real_format);
1936
1937#ifdef DEBUG
1938  fprintf(stderr,"REQUEST_INPUTS\n");
1939  dumpMaps(request_input_real_format);
1940  fprintf(stderr,"REQUEST_OUTPUTS\n");
1941  dumpMaps(request_output_real_format);
1942#endif
1943
1944  maps* curs=getMaps(m,"env");
1945  if(curs!=NULL){
1946    map* mapcs=curs->content;
1947    while(mapcs!=NULLMAP){
1948#ifndef WIN32
1949      setenv(mapcs->name,mapcs->value,1);
1950#else
1951#ifdef DEBUG
1952      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1953#endif
1954      if(mapcs->value[strlen(mapcs->value)-2]=='\r'){
1955#ifdef DEBUG
1956        fprintf(stderr,"[ZOO: Env var finish with \r]\n");
1957#endif
1958        mapcs->value[strlen(mapcs->value)-1]=0;
1959      }
1960#ifdef DEBUG
1961      fflush(stderr);
1962      fprintf(stderr,"setting variable... %s\n",(
1963#endif
1964              SetEnvironmentVariable(mapcs->name,mapcs->value)
1965#ifdef DEBUG
1966              ==0)? "OK" : "FAILED");
1967#else
1968      ;
1969#endif
1970          char* toto=(char*)malloc((strlen(mapcs->name)+strlen(mapcs->value)+2)*sizeof(char));
1971      sprintf(toto,"%s=%s",mapcs->name,mapcs->value);
1972          putenv(toto);
1973#ifdef DEBUG
1974      fflush(stderr);
1975#endif
1976#endif
1977#ifdef DEBUG
1978      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
1979      fflush(stderr);
1980#endif
1981      mapcs=mapcs->next;
1982    }
1983  }
1984 
1985#ifdef DEBUG
1986  dumpMap(request_inputs);
1987#endif
1988
1989  /**
1990   * Need to check if we need to fork to load a status enabled
1991   */
1992  r_inputs=NULL;
1993  map* store=getMap(request_inputs,"storeExecuteResponse");
1994  map* status=getMap(request_inputs,"status");
1995  /**
1996   * 05-007r7 WPS 1.0.0 page 57 :
1997   * 'If status="true" and storeExecuteResponse is "false" then the service
1998   * shall raise an exception.'
1999   */
2000  if(status!=NULL && strcmp(status->value,"true")==0 && 
2001     store!=NULL && strcmp(store->value,"false")==0){
2002    errorException(m, _("Status cannot be set to true with storeExecuteResponse to false. Please, modify your request parameters."), "InvalidParameterValue");
2003    freeService(&s1);
2004    free(s1);
2005    freeMaps(&m);
2006    free(m);
2007   
2008    freeMaps(&request_input_real_format);
2009    free(request_input_real_format);
2010   
2011    freeMaps(&request_output_real_format);
2012    free(request_output_real_format);
2013   
2014    free(REQUEST);
2015    free(SERVICE_URL);
2016    return 1;
2017  }
2018  r_inputs=getMap(request_inputs,"storeExecuteResponse");
2019  int eres=SERVICE_STARTED;
2020  int cpid=getpid();
2021
2022  maps *_tmpMaps=(maps*)malloc(MAPS_SIZE);
2023  _tmpMaps->name=strdup("lenv");
2024  char tmpBuff[100];
2025  sprintf(tmpBuff,"%i",cpid);
2026  _tmpMaps->content=createMap("sid",tmpBuff);
2027  _tmpMaps->next=NULL;
2028  addToMap(_tmpMaps->content,"status","0");
2029  addToMap(_tmpMaps->content,"cwd",ntmp);
2030  map* ltmp=getMap(request_inputs,"soap");
2031  if(ltmp!=NULL)
2032    addToMap(_tmpMaps->content,"soap",ltmp->value);
2033  else
2034    addToMap(_tmpMaps->content,"soap","false");
2035  if(cgiCookie!=NULL && strlen(cgiCookie)>0){
2036    char *tcook=strdup(cgiCookie);
2037    if(strstr(cgiCookie,";")>0){
2038      char *token,*saveptr;
2039      token=strtok_r(cgiCookie,";",&saveptr);
2040      while(token!=NULL){
2041        if(strcasestr(token,"ID")!=NULL){
2042          if(tcook!=NULL)
2043            free(tcook);
2044          tcook=strdup(token);
2045        }
2046        token=strtok_r(NULL,";",&saveptr);
2047      }
2048    }
2049    addToMap(_tmpMaps->content,"sessid",strstr(tcook,"=")+1);
2050    char session_file_path[1024];
2051    map *tmpPath=getMapFromMaps(m,"main","sessPath");
2052    if(tmpPath==NULL)
2053      tmpPath=getMapFromMaps(m,"main","tmpPath");
2054    char *tmp1=strtok(tcook,";");
2055    if(tmp1!=NULL)
2056      sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(tmp1,"=")+1);
2057    else
2058      sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(cgiCookie,"=")+1);
2059    free(tcook);
2060    maps *tmpSess=(maps*)calloc(1,MAPS_SIZE);
2061    struct stat file_status;
2062    int istat = stat(session_file_path, &file_status);
2063    if(istat==0 && file_status.st_size>0){
2064      conf_read(session_file_path,tmpSess);
2065      addMapsToMaps(&m,tmpSess);
2066      freeMaps(&tmpSess);
2067    }
2068    free(tmpSess);
2069  }
2070  addMapsToMaps(&m,_tmpMaps);
2071  freeMaps(&_tmpMaps);
2072  free(_tmpMaps);
2073
2074#ifdef DEBUG
2075  dumpMap(request_inputs);
2076#endif
2077#ifdef WIN32
2078  char *cgiSidL=NULL;
2079  if(getenv("CGISID")!=NULL)
2080    addToMap(request_inputs,"cgiSid",getenv("CGISID"));
2081  map* test1=getMap(request_inputs,"cgiSid");
2082  if(test1!=NULL){
2083    cgiSid=test1->value;
2084  }
2085  if(cgiSid!=NULL){
2086    addToMap(request_inputs,"storeExecuteResponse","true");
2087    addToMap(request_inputs,"status","true");
2088    status=getMap(request_inputs,"status");
2089    //fprintf(stderr,"cgiSID : %s",cgiSid);
2090  }
2091#endif
2092  if(status!=NULL)
2093    if(strcasecmp(status->value,"false")==0)
2094      status=NULLMAP;
2095  if(status==NULLMAP){
2096    loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
2097  }
2098  else{
2099    int   pid;
2100#ifdef DEBUG
2101    fprintf(stderr,"\nPID : %d\n",cpid);
2102#endif
2103
2104#ifndef WIN32
2105    pid = fork ();
2106#else
2107    if(cgiSid==NULL){
2108      addToMap(request_inputs,"cgSid",cgiSid);
2109      createProcess(m,request_inputs,s1,NULL,cpid,request_input_real_format,request_output_real_format);
2110      pid = cpid;
2111    }else{
2112      pid=0;
2113      cpid=atoi(cgiSid);
2114    }
2115    fflush(stderr);
2116#endif
2117    if (pid > 0) {
2118      /**
2119       * dady :
2120       * set status to SERVICE_ACCEPTED
2121       */
2122#ifdef DEBUG
2123      fprintf(stderr,"father pid continue (origin %d) %d ...\n",cpid,getpid());
2124#endif
2125      eres=SERVICE_ACCEPTED;
2126    }else if (pid == 0) {
2127      /**
2128       * son : have to close the stdout, stdin and stderr to let the parent
2129       * process answer to http client.
2130       */
2131      r_inputs=getMapFromMaps(m,"main","tmpPath");
2132      map* r_inputs1=getMap(s1->content,"ServiceProvider");
2133      char* fbkp=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+100)*sizeof(char));
2134      sprintf(fbkp,"%s/%s_%d.xml",r_inputs->value,r_inputs1->value,cpid);
2135      char* flog=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+100)*sizeof(char));
2136      sprintf(flog,"%s/%s_%d_error.log",r_inputs->value,r_inputs1->value,cpid);
2137#ifdef DEBUG
2138      fprintf(stderr,"RUN IN BACKGROUND MODE \n");
2139      fprintf(stderr,"son pid continue (origin %d) %d ...\n",cpid,getpid());
2140      fprintf(stderr,"\nFILE TO STORE DATA %s\n",r_inputs->value);
2141#endif
2142      freopen(flog,"w+",stderr);
2143      freopen(fbkp , "w+", stdout);
2144      fclose(stdin);
2145      free(fbkp);
2146      free(flog);
2147      /**
2148       * set status to SERVICE_STARTED and flush stdout to ensure full
2149       * content was outputed (the file used to store the ResponseDocument).
2150       * The rewind stdout to restart writing from the bgining of the file,
2151       * this way the data will be updated at the end of the process run.
2152       */
2153      updateStatus(m);
2154      printProcessResponse(m,request_inputs,cpid,
2155                           s1,r_inputs1->value,SERVICE_STARTED,
2156                           request_input_real_format,
2157                           request_output_real_format);
2158#ifndef WIN32
2159      fflush(stdout);
2160      rewind(stdout);
2161#endif
2162
2163      loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
2164
2165    } else {
2166      /**
2167       * error server don't accept the process need to output a valid
2168       * error response here !!!
2169       */
2170      eres=-1;
2171      errorException(m, _("Unable to run the child process properly"), "InternalError");
2172    }
2173  }
2174
2175#ifdef DEBUG
2176  dumpMaps(request_output_real_format);
2177#endif
2178  if(eres!=-1)
2179    outputResponse(s1,request_input_real_format,
2180                   request_output_real_format,request_inputs,
2181                   cpid,m,eres);
2182  fflush(stdout);
2183  /**
2184   * Ensure that if error occurs when freeing memory, no signal will return
2185   * an ExceptionReport document as the result was already returned to the
2186   * client.
2187   */
2188#ifndef USE_GDB
2189  (void) signal(SIGSEGV,donothing);
2190  (void) signal(SIGTERM,donothing);
2191  (void) signal(SIGINT,donothing);
2192  (void) signal(SIGILL,donothing);
2193  (void) signal(SIGFPE,donothing);
2194  (void) signal(SIGABRT,donothing);
2195#endif
2196
2197  if(((int)getpid())!=cpid){
2198    fclose(stdout);
2199    fclose(stderr);
2200    unhandleStatus(m);
2201  }
2202
2203  freeService(&s1);
2204  free(s1);
2205  freeMaps(&m);
2206  free(m);
2207 
2208  freeMaps(&request_input_real_format);
2209  free(request_input_real_format);
2210 
2211  freeMaps(&request_output_real_format);
2212  free(request_output_real_format);
2213 
2214  free(REQUEST);
2215  free(SERVICE_URL);
2216#ifdef DEBUG
2217  fprintf(stderr,"Processed response \n");
2218  fflush(stdout);
2219  fflush(stderr);
2220#endif
2221
2222  return 0;
2223}
2224
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