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

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

Fix some issue in background execution on windows platform (basic array and xlink). Fix issue #89.

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