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

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

Fix issue on windows platform with shared memory, pass outputs as KVP to created process.

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