Ticket #86: zoo_service_loader.c

File zoo_service_loader.c, 68.0 KB (added by landmark, 10 years ago)

zoo_service_loader.c (modified from revision # 452)

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){ // modified code to handle https requests:
1184              if( strncasecmp( tmpx2, "http://", 7 ) != 0 &&
1185                      strncasecmp( tmpx2, "ftp://", 6 ) !=0 &&
1186                          strncasecmp( tmpx2, "https://", 8 ) != 0 ) {
1187                char emsg[1024];
1188                sprintf(emsg,_("Unable to find a valid protocol to download the remote file %s"),tmpv1+1);
1189                errorException(m,emsg,"InternalError");
1190                freeMaps(&m);
1191                free(m);
1192                free(REQUEST);
1193                free(SERVICE_URL);
1194                InternetCloseHandle(hInternet);
1195                freeService(&s1);
1196                free(s1);
1197                return 0;
1198              }
1199#ifdef DEBUG
1200              fprintf(stderr,"REQUIRE TO DOWNLOAD A FILE FROM A SERVER : url(%s)\n",tmpv1+1);
1201#endif
1202              addToMap(tmpmaps->content,tmpn1,tmpx2);
1203             
1204#ifndef WIN32
1205              if(CHECK_INET_HANDLE(hInternet))
1206#endif
1207                {
1208                  if(loadRemoteFile(m,tmpmaps->content,hInternet,tmpx2)<0){
1209                    freeMaps(&m);
1210                    free(m);
1211                    free(REQUEST);
1212                    free(SERVICE_URL);
1213                    InternetCloseHandle(hInternet);
1214                    freeService(&s1);
1215                    free(s1);
1216                    return 0;
1217                  }
1218                }
1219              free(tmpx2);
1220              addToMap(tmpmaps->content,"Reference",tmpv1+1);
1221            }
1222          tmpc=strtok(NULL,"@");
1223        }
1224#ifdef DEBUG
1225        dumpMaps(tmpmaps);
1226        fflush(stderr);
1227#endif
1228        if(request_input_real_format==NULL)
1229          request_input_real_format=dupMaps(&tmpmaps);
1230        else{
1231          maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
1232          if(testPresence!=NULL){
1233            elements* elem=getElements(s1->inputs,tmpmaps->name);
1234            if(elem!=NULL){
1235              if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
1236                freeMaps(&m);
1237                free(m);
1238                free(REQUEST);
1239                free(SERVICE_URL);
1240                InternetCloseHandle(hInternet);
1241                freeService(&s1);
1242                free(s1);
1243                return 0;
1244              }
1245            }
1246          }
1247          else
1248            addMapsToMaps(&request_input_real_format,tmpmaps);
1249        }
1250        freeMaps(&tmpmaps);
1251        free(tmpmaps);
1252        tmpmaps=NULL;
1253        free(tmp);
1254      }
1255    }
1256    free(inputs_as_text);
1257  }
1258  else {
1259    /**
1260     * Parse XML request
1261     */ 
1262    xmlInitParser();
1263#ifdef DEBUG
1264    fflush(stderr);
1265    fprintf(stderr,"BEFORE %s\n",postRequest->value);
1266    fflush(stderr);
1267#endif
1268    xmlDocPtr doc =
1269      xmlParseMemory(postRequest->value,cgiContentLength);
1270#ifdef DEBUG
1271    fprintf(stderr,"AFTER\n");
1272    fflush(stderr);
1273#endif
1274    /**
1275     * Parse every Input in DataInputs node.
1276     */
1277    xmlXPathObjectPtr tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='Input']");
1278    xmlNodeSet* tmps=tmpsptr->nodesetval;
1279#ifdef DEBUG
1280    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1281#endif
1282    for(int k=0;k<tmps->nodeNr;k++){
1283      maps *tmpmaps=NULL;
1284      xmlNodePtr cur=tmps->nodeTab[k];
1285      if(tmps->nodeTab[k]->type == XML_ELEMENT_NODE) {
1286        /**
1287         * A specific Input node.
1288         */
1289#ifdef DEBUG
1290        fprintf(stderr, "= element 0 node \"%s\"\n", cur->name);
1291#endif
1292        xmlNodePtr cur2=cur->children;
1293        while(cur2!=NULL){
1294          while(cur2!=NULL && cur2->type!=XML_ELEMENT_NODE)
1295            cur2=cur2->next;
1296          if(cur2==NULL)
1297            break;
1298          /**
1299           * Indentifier
1300           */
1301          if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1302            xmlChar *val= xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1303            if(tmpmaps==NULL){
1304              tmpmaps=(maps*)malloc(MAPS_SIZE);
1305              if(tmpmaps == NULL){
1306                return errorException(m, _("Unable to allocate memory."), "InternalError");
1307              }
1308              tmpmaps->name=strdup((char*)val);
1309              tmpmaps->content=NULL;
1310              tmpmaps->next=NULL;
1311            }
1312            xmlFree(val);
1313          }
1314          /**
1315           * Title, Asbtract
1316           */
1317          if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1318             xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1319            xmlChar *val=
1320              xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1321            if(tmpmaps==NULL){
1322              tmpmaps=(maps*)malloc(MAPS_SIZE);
1323              if(tmpmaps == NULL){
1324                return errorException(m, _("Unable to allocate memory."), "InternalError");
1325              }
1326              tmpmaps->name=strdup("missingIndetifier");
1327              tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1328              tmpmaps->next=NULL;
1329            }
1330            else{
1331              if(tmpmaps->content!=NULL)
1332                addToMap(tmpmaps->content,
1333                         (char*)cur2->name,(char*)val);
1334              else
1335                tmpmaps->content=
1336                  createMap((char*)cur2->name,(char*)val);
1337            }
1338#ifdef DEBUG
1339            dumpMaps(tmpmaps);
1340#endif
1341            xmlFree(val);
1342          }
1343          /**
1344           * InputDataFormChoice (Reference or Data ?)
1345           */
1346          if(xmlStrcasecmp(cur2->name,BAD_CAST "Reference")==0){
1347            /**
1348             * Get every attribute from a Reference node
1349             * mimeType, encoding, schema, href, method
1350             * Header and Body gesture should be added here
1351             */
1352#ifdef DEBUG
1353            fprintf(stderr,"REFERENCE\n");
1354#endif
1355            const char *refs[5]={"mimeType","encoding","schema","method","href"};
1356            for(int l=0;l<5;l++){
1357#ifdef DEBUG
1358              fprintf(stderr,"*** %s ***",refs[l]);
1359#endif
1360              xmlChar *val=xmlGetProp(cur2,BAD_CAST refs[l]);
1361              if(val!=NULL && xmlStrlen(val)>0){
1362                if(tmpmaps->content!=NULL)
1363                  addToMap(tmpmaps->content,refs[l],(char*)val);
1364                else
1365                  tmpmaps->content=createMap(refs[l],(char*)val);
1366                map* ltmp=getMap(tmpmaps->content,"method");
1367                if(l==4){
1368                  if(!(ltmp!=NULL && strncmp(ltmp->value,"POST",4)==0)
1369                     && CHECK_INET_HANDLE(hInternet)){
1370                    if(loadRemoteFile(m,tmpmaps->content,hInternet,(char*)val)!=0){
1371                      freeMaps(&m);
1372                      free(m);
1373                      free(REQUEST);
1374                      free(SERVICE_URL);
1375                      InternetCloseHandle(hInternet);
1376                      freeService(&s1);
1377                      free(s1);
1378                      return 0;
1379                    }
1380                  }
1381                }
1382              }
1383#ifdef DEBUG
1384              fprintf(stderr,"%s\n",val);
1385#endif
1386              xmlFree(val);
1387            }
1388#ifdef POST_DEBUG
1389            fprintf(stderr,"Parse Header and Body from Reference \n");
1390#endif
1391            xmlNodePtr cur3=cur2->children;
1392            HINTERNET hInternetP;
1393            hInternetP=InternetOpen(
1394#ifndef WIN32
1395                                   (LPCTSTR)
1396#endif
1397                                   "ZooWPSClient\0",
1398                                   INTERNET_OPEN_TYPE_PRECONFIG,
1399                                   NULL,NULL, 0);
1400            hInternetP.header=NULL;
1401            while(cur3){
1402              while(cur3!=NULL && cur3->type!=XML_ELEMENT_NODE)
1403                cur2=cur3->next;
1404              if(xmlStrcasecmp(cur3->name,BAD_CAST "Header")==0 ){
1405                const char *ha[2];
1406                ha[0]="key";
1407                ha[1]="value";
1408                int hai;
1409                char *has;
1410                char *key;
1411                for(hai=0;hai<2;hai++){
1412                  xmlChar *val=xmlGetProp(cur3,BAD_CAST ha[hai]);
1413#ifdef POST_DEBUG
1414                  fprintf(stderr,"%s = %s\n",ha[hai],(char*)val);
1415#endif
1416                  if(hai==0){
1417                    key=(char*)malloc((1+strlen((char*)val))*sizeof(char));
1418                    snprintf(key,1+strlen((char*)val),"%s",(char*)val);
1419                  }else{
1420                    has=(char*)malloc((3+strlen((char*)val)+strlen(key))*sizeof(char));
1421                    if(has == NULL){
1422                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1423                    }
1424                    snprintf(has,(3+strlen((char*)val)+strlen(key)),"%s: %s",key,(char*)val);
1425#ifdef POST_DEBUG
1426                    fprintf(stderr,"%s\n",has);
1427#endif
1428                  }
1429                }
1430                hInternetP.header=curl_slist_append(hInternetP.header, has);
1431                if(has!=NULL)
1432                  free(has);
1433              }
1434              else{
1435#ifdef POST_DEBUG
1436                fprintf(stderr,"Try to fetch the body part of the request ...\n");
1437#endif
1438                if(xmlStrcasecmp(cur3->name,BAD_CAST "Body")==0 ){
1439#ifdef POST_DEBUG
1440                  fprintf(stderr,"Body part found !!!\n",(char*)cur3->content);
1441#endif
1442                  char *tmp=new char[cgiContentLength];
1443                  memset(tmp,0,cgiContentLength);
1444                  xmlNodePtr cur4=cur3->children;
1445                  while(cur4!=NULL){
1446                    while(cur4->type!=XML_ELEMENT_NODE)
1447                      cur4=cur4->next;
1448                    xmlDocPtr bdoc = xmlNewDoc(BAD_CAST "1.0");
1449                    bdoc->encoding = xmlCharStrdup ("UTF-8");
1450                    xmlDocSetRootElement(bdoc,cur4);
1451                    xmlChar* btmps;
1452                    int bsize;
1453                    xmlDocDumpMemory(bdoc,&btmps,&bsize);
1454#ifdef POST_DEBUG
1455                    fprintf(stderr,"Body part found !!! %s %s\n",tmp,(char*)btmps);
1456#endif
1457                    if(btmps!=NULL)
1458                      sprintf(tmp,"%s",(char*)btmps);
1459                    xmlFreeDoc(bdoc);
1460                    cur4=cur4->next;
1461                  }
1462                  map *btmp=getMap(tmpmaps->content,"href");
1463                  if(btmp!=NULL){
1464#ifdef POST_DEBUG
1465                    fprintf(stderr,"%s %s\n",btmp->value,tmp);
1466                    curl_easy_setopt(hInternetP.handle, CURLOPT_VERBOSE, 1);
1467#endif
1468                    res=InternetOpenUrl(hInternetP,btmp->value,tmp,strlen(tmp),
1469                                        INTERNET_FLAG_NO_CACHE_WRITE,0);
1470                    char* tmpContent = (char*)malloc((res.nDataLen+1)*sizeof(char));
1471                    if(tmpContent == NULL){
1472                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1473                    }
1474                    size_t dwRead;
1475                    InternetReadFile(res, (LPVOID)tmpContent,
1476                                     res.nDataLen, &dwRead);
1477                    tmpContent[res.nDataLen]=0;
1478                    if(hInternetP.header!=NULL)
1479                      curl_slist_free_all(hInternetP.header);
1480                    addToMap(tmpmaps->content,"value",tmpContent);
1481#ifdef POST_DEBUG
1482                    fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1483#endif
1484                  }
1485                }
1486                else
1487                  if(xmlStrcasecmp(cur3->name,BAD_CAST "BodyReference")==0 ){
1488                    xmlChar *val=xmlGetProp(cur3,BAD_CAST "href");
1489                    HINTERNET bInternet,res1;
1490                    bInternet=InternetOpen(
1491#ifndef WIN32
1492                                           (LPCTSTR)
1493#endif
1494                                           "ZooWPSClient\0",
1495                                           INTERNET_OPEN_TYPE_PRECONFIG,
1496                                           NULL,NULL, 0);
1497                    if(!CHECK_INET_HANDLE(bInternet))
1498                      fprintf(stderr,"WARNING : hInternet handle failed to initialize");
1499#ifdef POST_DEBUG
1500                    curl_easy_setopt(bInternet.handle, CURLOPT_VERBOSE, 1);
1501#endif
1502                    res1=InternetOpenUrl(bInternet,(char*)val,NULL,0,
1503                                         INTERNET_FLAG_NO_CACHE_WRITE,0);
1504                    char* tmp=
1505                      (char*)malloc((res1.nDataLen+1)*sizeof(char));
1506                    if(tmp == NULL){
1507                      return errorException(m, _("Unable to allocate memory."), "InternalError");
1508                    }
1509                    size_t bRead;
1510                    InternetReadFile(res1, (LPVOID)tmp,
1511                                     res1.nDataLen, &bRead);
1512                    tmp[res1.nDataLen]=0;
1513                    InternetCloseHandle(bInternet);
1514                    map *btmp=getMap(tmpmaps->content,"href");
1515                    if(btmp!=NULL){
1516#ifdef POST_DEBUG
1517                      fprintf(stderr,"%s %s\n",btmp->value,tmp);
1518                      curl_easy_setopt(hInternetP.handle, CURLOPT_VERBOSE, 1);
1519#endif
1520                      res=InternetOpenUrl(hInternetP,btmp->value,tmp,
1521                                          strlen(tmp),
1522                                          INTERNET_FLAG_NO_CACHE_WRITE,0);
1523                      char* tmpContent = (char*)malloc((res.nDataLen+1)*sizeof(char));
1524                      if(tmpContent == NULL){
1525                        return errorException(m, _("Unable to allocate memory."), "InternalError");
1526                      }
1527                      size_t dwRead;
1528                      InternetReadFile(res, (LPVOID)tmpContent,
1529                                       res.nDataLen, &dwRead);
1530                      tmpContent[res.nDataLen]=0;
1531                      if(hInternetP.header!=NULL)
1532                        curl_slist_free_all(hInternetP.header);
1533                      addToMap(tmpmaps->content,"value",tmpContent);
1534#ifdef POST_DEBUG
1535                      fprintf(stderr,"DL CONTENT : (%s)\n",tmpContent);
1536#endif
1537                    }
1538                  }
1539              }
1540              cur3=cur3->next;
1541            }
1542            InternetCloseHandle(hInternetP);
1543#ifdef POST_DEBUG
1544            fprintf(stderr,"Header and Body was parsed from Reference \n");
1545#endif
1546#ifdef DEBUG
1547            dumpMap(tmpmaps->content);
1548            fprintf(stderr, "= element 2 node \"%s\" = (%s)\n", 
1549                    cur2->name,cur2->content);
1550#endif
1551          }
1552          else if(xmlStrcasecmp(cur2->name,BAD_CAST "Data")==0){
1553#ifdef DEBUG
1554            fprintf(stderr,"DATA\n");
1555#endif
1556            xmlNodePtr cur4=cur2->children;
1557            while(cur4!=NULL){
1558              while(cur4!=NULL &&cur4->type!=XML_ELEMENT_NODE)
1559                cur4=cur4->next;
1560              if(cur4==NULL)
1561                break;
1562              if(xmlStrcasecmp(cur4->name, BAD_CAST "LiteralData")==0){
1563                /**
1564                 * Get every attribute from a LiteralData node
1565                 * dataType , uom
1566                 */
1567                char *list[2];
1568                list[0]=strdup("dataType");
1569                list[1]=strdup("uom");
1570                for(int l=0;l<2;l++){
1571#ifdef DEBUG
1572                  fprintf(stderr,"*** LiteralData %s ***",list[l]);
1573#endif
1574                  xmlChar *val=xmlGetProp(cur4,BAD_CAST list[l]);
1575                  if(val!=NULL && strlen((char*)val)>0){
1576                    if(tmpmaps->content!=NULL)
1577                      addToMap(tmpmaps->content,list[l],(char*)val);
1578                    else
1579                      tmpmaps->content=createMap(list[l],(char*)val);
1580#ifdef DEBUG
1581                    fprintf(stderr,"%s\n",val);
1582#endif
1583                  }
1584                  xmlFree(val);
1585                  free(list[l]);                 
1586                }
1587              }
1588              else if(xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0){
1589                /**
1590                 * Get every attribute from a Reference node
1591                 * mimeType, encoding, schema
1592                 */
1593                const char *coms[3]={"mimeType","encoding","schema"};
1594                for(int l=0;l<3;l++){
1595#ifdef DEBUG
1596                  fprintf(stderr,"*** ComplexData %s ***\n",coms[l]);
1597#endif
1598                  xmlChar *val=xmlGetProp(cur4,BAD_CAST coms[l]);
1599                  if(val!=NULL && strlen((char*)val)>0){
1600                    if(tmpmaps->content!=NULL)
1601                      addToMap(tmpmaps->content,coms[l],(char*)val);
1602                    else
1603                      tmpmaps->content=createMap(coms[l],(char*)val);
1604#ifdef DEBUG
1605                    fprintf(stderr,"%s\n",val);
1606#endif
1607                  }
1608                  xmlFree(val);
1609                }
1610              }
1611
1612              map* test=getMap(tmpmaps->content,"encoding");
1613              if(test==NULL){
1614                if(tmpmaps->content!=NULL)
1615                  addToMap(tmpmaps->content,"encoding","utf-8");
1616                else
1617                  tmpmaps->content=createMap("encoding","utf-8");
1618                test=getMap(tmpmaps->content,"encoding");
1619              }
1620
1621              if(strcasecmp(test->value,"base64")!=0){
1622                xmlChar* mv=xmlNodeListGetString(doc,cur4->xmlChildrenNode,1);
1623                map* ltmp=getMap(tmpmaps->content,"mimeType");
1624                if(mv==NULL || 
1625                   (xmlStrcasecmp(cur4->name, BAD_CAST "ComplexData")==0 &&
1626                    (ltmp==NULL || strncasecmp(ltmp->value,"text/xml",8)==0) )){
1627                  xmlDocPtr doc1=xmlNewDoc(BAD_CAST "1.0");
1628                  int buffersize;
1629                  xmlNodePtr cur5=cur4->children;
1630                  while(cur5!=NULL &&cur5->type!=XML_ELEMENT_NODE)
1631                    cur5=cur5->next;
1632                  xmlDocSetRootElement(doc1,cur5);
1633                  xmlDocDumpFormatMemoryEnc(doc1, &mv, &buffersize, "utf-8", 1);
1634                  char size[1024];
1635                  sprintf(size,"%d",buffersize);
1636                  addToMap(tmpmaps->content,"size",size);
1637                }
1638                addToMap(tmpmaps->content,"value",(char*)mv);
1639                xmlFree(mv);
1640              }else{
1641                xmlChar* tmp=xmlNodeListGetRawString(doc,cur4->xmlChildrenNode,0);
1642                addToMap(tmpmaps->content,"value",(char*)tmp);
1643                map* tmpv=getMap(tmpmaps->content,"value");
1644                char *res=NULL;
1645                char *curs=tmpv->value;
1646                for(int i=0;i<=strlen(tmpv->value)/64;i++) {
1647                  if(res==NULL)
1648                    res=(char*)malloc(67*sizeof(char));
1649                  else
1650                    res=(char*)realloc(res,(((i+1)*65)+i)*sizeof(char));
1651                  int csize=i*65;
1652                  strncpy(res + csize,curs,64);
1653                  if(i==xmlStrlen(tmp)/64)
1654                    strcat(res,"\n\0");
1655                  else{
1656                    strncpy(res + (((i+1)*64)+i),"\n\0",2);
1657                    curs+=64;
1658                  }
1659                }
1660                free(tmpv->value);
1661                tmpv->value=strdup(res);
1662                free(res);
1663                xmlFree(tmp);
1664              }
1665              cur4=cur4->next;
1666            }
1667          }
1668#ifdef DEBUG
1669          fprintf(stderr,"cur2 next \n");
1670          fflush(stderr);
1671#endif
1672          cur2=cur2->next;
1673        }
1674#ifdef DEBUG
1675        fprintf(stderr,"ADD MAPS TO REQUEST MAPS !\n");
1676        fflush(stderr);
1677#endif
1678
1679        {
1680          maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
1681          if(testPresence!=NULL){
1682            elements* elem=getElements(s1->inputs,tmpmaps->name);
1683            if(elem!=NULL){
1684              if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
1685                freeMaps(&m);
1686                free(m);
1687                free(REQUEST);
1688                free(SERVICE_URL);
1689                InternetCloseHandle(hInternet);
1690                freeService(&s1);
1691                free(s1);
1692                return 0;
1693              }
1694            }
1695          }
1696          else
1697            addMapsToMaps(&request_input_real_format,tmpmaps);
1698        }
1699
1700#ifdef DEBUG
1701        fprintf(stderr,"******TMPMAPS*****\n");
1702        dumpMaps(tmpmaps);
1703        fprintf(stderr,"******REQUESTMAPS*****\n");
1704        dumpMaps(request_input_real_format);
1705#endif
1706        freeMaps(&tmpmaps);
1707        free(tmpmaps);
1708        tmpmaps=NULL;         
1709      }
1710#ifdef DEBUG
1711      dumpMaps(tmpmaps); 
1712#endif
1713    }
1714#ifdef DEBUG
1715    fprintf(stderr,"Search for response document node\n");
1716#endif
1717    xmlXPathFreeObject(tmpsptr);
1718   
1719    tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='ResponseDocument']");
1720    bool asRaw=false;
1721    tmps=tmpsptr->nodesetval;
1722    if(tmps->nodeNr==0){
1723      tmpsptr=extractFromDoc(doc,"/*/*/*[local-name()='RawDataOutput']");
1724      tmps=tmpsptr->nodesetval;
1725      asRaw=true;
1726    }
1727#ifdef DEBUG
1728    fprintf(stderr,"*****%d*****\n",tmps->nodeNr);
1729#endif
1730    for(int k=0;k<tmps->nodeNr;k++){
1731      if(asRaw==true)
1732        addToMap(request_inputs,"RawDataOutput","");
1733      else
1734        addToMap(request_inputs,"ResponseDocument","");
1735      maps *tmpmaps=NULL;
1736      xmlNodePtr cur=tmps->nodeTab[k];
1737      if(cur->type == XML_ELEMENT_NODE) {
1738        /**
1739         * A specific responseDocument node.
1740         */
1741        if(tmpmaps==NULL){
1742          tmpmaps=(maps*)malloc(MAPS_SIZE);
1743          if(tmpmaps == NULL){
1744            return errorException(m, _("Unable to allocate memory."), "InternalError");
1745          }
1746          tmpmaps->name=strdup("unknownIdentifier");
1747          tmpmaps->content=NULL;
1748          tmpmaps->next=NULL;
1749        }
1750        /**
1751         * Get every attribute: storeExecuteResponse, lineage, status
1752         */
1753        const char *ress[3]={"storeExecuteResponse","lineage","status"};
1754        xmlChar *val;
1755        for(int l=0;l<3;l++){
1756#ifdef DEBUG
1757          fprintf(stderr,"*** %s ***\t",ress[l]);
1758#endif
1759          val=xmlGetProp(cur,BAD_CAST ress[l]);
1760          if(val!=NULL && strlen((char*)val)>0){
1761            if(tmpmaps->content!=NULL)
1762              addToMap(tmpmaps->content,ress[l],(char*)val);
1763            else
1764              tmpmaps->content=createMap(ress[l],(char*)val);
1765            addToMap(request_inputs,ress[l],(char*)val);
1766          }
1767#ifdef DEBUG
1768          fprintf(stderr,"%s\n",val);
1769#endif
1770          xmlFree(val);
1771        }
1772        xmlNodePtr cur1=cur->children;
1773        while(cur1!=NULL && cur1->type != XML_ELEMENT_NODE)
1774          cur1=cur1->next;
1775        int cur1cnt=0;
1776        while(cur1){
1777          /**
1778           * Indentifier
1779           */
1780          if(xmlStrncasecmp(cur1->name,BAD_CAST "Identifier",xmlStrlen(cur1->name))==0){
1781            xmlChar *val=
1782              xmlNodeListGetString(doc,cur1->xmlChildrenNode,1);
1783            if(tmpmaps==NULL){
1784              tmpmaps=(maps*)malloc(MAPS_SIZE);
1785              if(tmpmaps == NULL){
1786                return errorException(m, _("Unable to allocate memory."), "InternalError");
1787              }
1788              tmpmaps->name=strdup((char*)val);
1789              tmpmaps->content=NULL;
1790              tmpmaps->next=NULL;
1791            }
1792            else{
1793              //free(tmpmaps->name);
1794              tmpmaps->name=strdup((char*)val);
1795            }
1796            if(asRaw==true)
1797              addToMap(request_inputs,"RawDataOutput",(char*)val);
1798            else{
1799              if(cur1cnt==0)
1800                addToMap(request_inputs,"ResponseDocument",(char*)val);
1801              else{
1802                map* tt=getMap(request_inputs,"ResponseDocument");
1803                char* tmp=strdup(tt->value);
1804                free(tt->value);
1805                tt->value=(char*)malloc((strlen(tmp)+strlen((char*)val)+1)*sizeof(char));
1806                sprintf(tt->value,"%s;%s",tmp,(char*)val);
1807                free(tmp);
1808              }
1809            }
1810            cur1cnt+=1;
1811            xmlFree(val);
1812          }
1813          /**
1814           * Title, Asbtract
1815           */
1816          else if(xmlStrncasecmp(cur1->name,BAD_CAST "Title",xmlStrlen(cur1->name))==0 ||
1817                  xmlStrncasecmp(cur1->name,BAD_CAST "Abstract",xmlStrlen(cur1->name))==0){
1818            xmlChar *val=
1819              xmlNodeListGetString(doc,cur1->xmlChildrenNode,1);
1820            if(tmpmaps==NULL){
1821              tmpmaps=(maps*)malloc(MAPS_SIZE);
1822              if(tmpmaps == NULL){
1823                return errorException(m, _("Unable to allocate memory."), "InternalError");
1824              }
1825              tmpmaps->name=strdup("missingIndetifier");
1826              tmpmaps->content=createMap((char*)cur1->name,(char*)val);
1827              tmpmaps->next=NULL;
1828            }
1829            else{
1830              if(tmpmaps->content!=NULL)
1831                addToMap(tmpmaps->content,(char*)cur1->name,(char*)val);
1832              else
1833                tmpmaps->content=createMap((char*)cur1->name,(char*)val);
1834            }
1835            xmlFree(val);
1836          }
1837          else if(xmlStrncasecmp(cur1->name,BAD_CAST "Output",xmlStrlen(cur1->name))==0){
1838            /**
1839             * Get every attribute from a Output node
1840             * mimeType, encoding, schema, uom, asReference
1841             */
1842            const char *outs[5]={"mimeType","encoding","schema","uom","asReference"};
1843            for(int l=0;l<5;l++){
1844#ifdef DEBUG
1845              fprintf(stderr,"*** %s ***\t",outs[l]);
1846#endif
1847              val=xmlGetProp(cur1,BAD_CAST outs[l]);
1848              if(val!=NULL && strlen((char*)val)>0){
1849                if(tmpmaps->content!=NULL)
1850                  addToMap(tmpmaps->content,outs[l],(char*)val);
1851                else
1852                  tmpmaps->content=createMap(outs[l],(char*)val);
1853              }
1854#ifdef DEBUG
1855              fprintf(stderr,"%s\n",val);
1856#endif
1857              xmlFree(val);
1858            }
1859            xmlNodePtr cur2=cur1->children;
1860            while(cur2!=NULL && cur2->type != XML_ELEMENT_NODE)
1861              cur2=cur2->next;
1862            while(cur2){
1863              /**
1864               * Indentifier
1865               */
1866              if(xmlStrncasecmp(cur2->name,BAD_CAST "Identifier",xmlStrlen(cur2->name))==0){
1867                xmlChar *val=
1868                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1869                if(tmpmaps==NULL){
1870                  tmpmaps=(maps*)malloc(MAPS_SIZE);
1871                  if(tmpmaps == NULL){
1872                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1873                  }
1874                  tmpmaps->name=strdup((char*)val);
1875                  tmpmaps->content=NULL;
1876                  tmpmaps->next=NULL;
1877                }
1878                else{
1879                  if(tmpmaps->name!=NULL)
1880                    free(tmpmaps->name);
1881                  tmpmaps->name=strdup((char*)val);;
1882                }
1883                xmlFree(val);
1884              }
1885              /**
1886               * Title, Asbtract
1887               */
1888              else if(xmlStrncasecmp(cur2->name,BAD_CAST "Title",xmlStrlen(cur2->name))==0 ||
1889                      xmlStrncasecmp(cur2->name,BAD_CAST "Abstract",xmlStrlen(cur2->name))==0){
1890                xmlChar *val=
1891                  xmlNodeListGetString(doc,cur2->xmlChildrenNode,1);
1892                if(tmpmaps==NULL){
1893                  tmpmaps=(maps*)malloc(MAPS_SIZE);
1894                  if(tmpmaps == NULL){
1895                    return errorException(m, _("Unable to allocate memory."), "InternalError");
1896                  }
1897                  tmpmaps->name=strdup("missingIndetifier");
1898                  tmpmaps->content=createMap((char*)cur2->name,(char*)val);
1899                  tmpmaps->next=NULL;
1900                }
1901                else{
1902                  if(tmpmaps->content!=NULL)
1903                    addToMap(tmpmaps->content,
1904                             (char*)cur2->name,(char*)val);
1905                  else
1906                    tmpmaps->content=
1907                      createMap((char*)cur2->name,(char*)val);
1908                }
1909                xmlFree(val);
1910              }
1911              cur2=cur2->next;
1912              while(cur2!=NULL && cur2->type != XML_ELEMENT_NODE)
1913                cur2=cur2->next;
1914            }
1915          }
1916          cur1=cur1->next;
1917          while(cur1!=NULL && cur1->type != XML_ELEMENT_NODE)
1918            cur1=cur1->next;
1919        }
1920      }
1921      if(request_output_real_format==NULL)
1922        request_output_real_format=dupMaps(&tmpmaps);
1923      else
1924        addMapsToMaps(&request_output_real_format,tmpmaps);
1925      if(tmpmaps!=NULL){
1926        freeMaps(&tmpmaps);
1927        free(tmpmaps);
1928        tmpmaps=NULL;
1929      }
1930    }
1931    xmlXPathFreeObject(tmpsptr);
1932    xmlCleanupParser();
1933  }
1934 
1935
1936  //  if(CHECK_INET_HANDLE(hInternet))
1937  InternetCloseHandle(hInternet);
1938
1939#ifdef DEBUG
1940  fprintf(stderr,"\n%d\n",__LINE__);
1941  fflush(stderr);
1942  dumpMaps(request_input_real_format);
1943  dumpMaps(request_output_real_format);
1944  dumpMap(request_inputs);
1945  fprintf(stderr,"\n%d\n",__LINE__);
1946  fflush(stderr);
1947#endif
1948
1949  /**
1950   * Ensure that each requested arguments are present in the request
1951   * DataInputs and ResponseDocument / RawDataOutput
1952   */
1953  char *dfv=addDefaultValues(&request_input_real_format,s1->inputs,m,0);
1954  char *dfv1=addDefaultValues(&request_output_real_format,s1->outputs,m,1);
1955  if(strcmp(dfv1,"")!=0 || strcmp(dfv,"")!=0){
1956    char tmps[1024];
1957    if(strcmp(dfv,"")!=0){
1958      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);
1959    }
1960    else if(strcmp(dfv1,"")!=0){
1961      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);
1962    }
1963    map* tmpe=createMap("text",tmps);
1964    addToMap(tmpe,"code","MissingParameterValue");
1965    printExceptionReportResponse(m,tmpe);
1966    freeService(&s1);
1967    free(s1);
1968    freeMap(&tmpe);
1969    free(tmpe);
1970    freeMaps(&m);
1971    free(m);
1972    free(REQUEST);
1973    free(SERVICE_URL);
1974    freeMaps(&request_input_real_format);
1975    free(request_input_real_format);
1976    freeMaps(&request_output_real_format);
1977    free(request_output_real_format);
1978    freeMaps(&tmpmaps);
1979    free(tmpmaps);
1980    return 1;
1981  }
1982  maps* tmpReqI=request_input_real_format;
1983  while(tmpReqI!=NULL){
1984    char name[1024];
1985    if(getMap(tmpReqI->content,"isFile")!=NULL){
1986      if (cgiFormFileName(tmpReqI->name, name, sizeof(name)) == cgiFormSuccess) {
1987        int BufferLen=1024;
1988        cgiFilePtr file;
1989        int targetFile;
1990        mode_t mode;
1991        char storageNameOnServer[2048];
1992        char fileNameOnServer[64];
1993        char contentType[1024];
1994        char buffer[1024];
1995        char *tmpStr=NULL;
1996        int size;
1997        int got,t;
1998        map *path=getMapFromMaps(m,"main","tmpPath");
1999        cgiFormFileSize(tmpReqI->name, &size);
2000        cgiFormFileContentType(tmpReqI->name, contentType, sizeof(contentType));
2001        if (cgiFormFileOpen(tmpReqI->name, &file) == cgiFormSuccess) {
2002          t=-1;
2003          while(1){
2004            tmpStr=strstr(name+t+1,"\\");
2005            if(NULL==tmpStr)
2006              tmpStr=strstr(name+t+1,"/");
2007            if(NULL!=tmpStr)
2008              t=(int)(tmpStr-name);
2009            else
2010              break;
2011          }
2012          strcpy(fileNameOnServer,name+t+1);
2013         
2014          sprintf(storageNameOnServer,"%s/%s",path->value,fileNameOnServer);
2015#ifdef DEBUG
2016          fprintf(stderr,"Name on server %s\n",storageNameOnServer);
2017          fprintf(stderr,"fileNameOnServer: %s\n",fileNameOnServer);
2018#endif
2019          mode=S_IRWXU|S_IRGRP|S_IROTH;
2020          targetFile = open (storageNameOnServer,O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP|S_IROTH);
2021          if(targetFile<0){
2022#ifdef DEBUG
2023            fprintf(stderr,"could not create the new file,%s\n",fileNameOnServer);         
2024#endif
2025          }else{
2026            while (cgiFormFileRead(file, buffer, BufferLen, &got) ==cgiFormSuccess){
2027              if(got>0)
2028                write(targetFile,buffer,got);
2029            }
2030          }
2031          addToMap(tmpReqI->content,"lref",storageNameOnServer);
2032          cgiFormFileClose(file);
2033          close(targetFile);
2034#ifdef DEBUG
2035          fprintf(stderr,"File \"%s\" has been uploaded",fileNameOnServer);
2036#endif
2037        }
2038      }
2039    }
2040    tmpReqI=tmpReqI->next;
2041  }
2042
2043  ensureDecodedBase64(&request_input_real_format);
2044
2045#ifdef DEBUG
2046  fprintf(stderr,"REQUEST_INPUTS\n");
2047  dumpMaps(request_input_real_format);
2048  fprintf(stderr,"REQUEST_OUTPUTS\n");
2049  dumpMaps(request_output_real_format);
2050#endif
2051
2052  maps* curs=getMaps(m,"env");
2053  if(curs!=NULL){
2054    map* mapcs=curs->content;
2055    while(mapcs!=NULLMAP){
2056#ifndef WIN32
2057      setenv(mapcs->name,mapcs->value,1);
2058#else
2059#ifdef DEBUG
2060      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
2061#endif
2062      if(mapcs->value[strlen(mapcs->value)-2]=='\r'){
2063#ifdef DEBUG
2064        fprintf(stderr,"[ZOO: Env var finish with \r]\n");
2065#endif
2066        mapcs->value[strlen(mapcs->value)-1]=0;
2067      }
2068#ifdef DEBUG
2069      fflush(stderr);
2070      fprintf(stderr,"setting variable... %s\n",(
2071#endif
2072              SetEnvironmentVariable(mapcs->name,mapcs->value)
2073#ifdef DEBUG
2074              ==0)? "OK" : "FAILED");
2075#else
2076      ;
2077#endif
2078      char* toto=(char*)malloc((strlen(mapcs->name)+strlen(mapcs->value)+2)*sizeof(char));
2079      sprintf(toto,"%s=%s",mapcs->name,mapcs->value);
2080      putenv(toto);
2081#ifdef DEBUG
2082      fflush(stderr);
2083#endif
2084#endif
2085#ifdef DEBUG
2086      fprintf(stderr,"[ZOO: setenv (%s=%s)]\n",mapcs->name,mapcs->value);
2087      fflush(stderr);
2088#endif
2089      mapcs=mapcs->next;
2090    }
2091  }
2092 
2093#ifdef DEBUG
2094  dumpMap(request_inputs);
2095#endif
2096
2097  /**
2098   * Need to check if we need to fork to load a status enabled
2099   */
2100  r_inputs=NULL;
2101  map* store=getMap(request_inputs,"storeExecuteResponse");
2102  map* status=getMap(request_inputs,"status");
2103  /**
2104   * 05-007r7 WPS 1.0.0 page 57 :
2105   * 'If status="true" and storeExecuteResponse is "false" then the service
2106   * shall raise an exception.'
2107   */
2108  if(status!=NULL && strcmp(status->value,"true")==0 && 
2109     store!=NULL && strcmp(store->value,"false")==0){
2110    errorException(m, _("Status cannot be set to true with storeExecuteResponse to false. Please, modify your request parameters."), "InvalidParameterValue");
2111    freeService(&s1);
2112    free(s1);
2113    freeMaps(&m);
2114    free(m);
2115   
2116    freeMaps(&request_input_real_format);
2117    free(request_input_real_format);
2118   
2119    freeMaps(&request_output_real_format);
2120    free(request_output_real_format);
2121   
2122    free(REQUEST);
2123    free(SERVICE_URL);
2124    return 1;
2125  }
2126  r_inputs=getMap(request_inputs,"storeExecuteResponse");
2127  int eres=SERVICE_STARTED;
2128  int cpid=getpid();
2129
2130  maps *_tmpMaps=(maps*)malloc(MAPS_SIZE);
2131  _tmpMaps->name=strdup("lenv");
2132  char tmpBuff[100];
2133  sprintf(tmpBuff,"%i",cpid);
2134  _tmpMaps->content=createMap("sid",tmpBuff);
2135  _tmpMaps->next=NULL;
2136  addToMap(_tmpMaps->content,"status","0");
2137  addToMap(_tmpMaps->content,"cwd",ntmp);
2138  map* ltmp=getMap(request_inputs,"soap");
2139  if(ltmp!=NULL)
2140    addToMap(_tmpMaps->content,"soap",ltmp->value);
2141  else
2142    addToMap(_tmpMaps->content,"soap","false");
2143  if(cgiCookie!=NULL && strlen(cgiCookie)>0){
2144    int hasValidCookie=-1;
2145    char *tcook=strdup(cgiCookie);
2146    char *tmp=NULL;
2147    int hasVal=-1;
2148    map* testing=getMapFromMaps(m,"main","cookiePrefix");
2149    if(testing==NULL){
2150      tmp=strdup("ID=");
2151    }else{
2152      tmp=(char*)malloc((strlen(testing->value)+2)*sizeof(char));
2153      sprintf(tmp,"%s=",testing->value);
2154      hasVal=1;
2155    }
2156    if(strstr(cgiCookie,";")!=NULL){
2157      char *token,*saveptr;
2158      token=strtok_r(cgiCookie,";",&saveptr);
2159      while(token!=NULL){
2160        if(strcasestr(token,tmp)!=NULL){
2161          if(tcook!=NULL)
2162            free(tcook);
2163          tcook=strdup(token);
2164          hasValidCookie=1;
2165        }
2166        token=strtok_r(NULL,";",&saveptr);
2167      }
2168    }else{
2169      if(strstr(cgiCookie,"=")!=NULL && strcasestr(cgiCookie,tmp)!=NULL){
2170        tcook=strdup(cgiCookie);
2171        hasValidCookie=1;
2172      }
2173      if(tmp!=NULL){
2174        free(tmp);
2175      }
2176    }
2177    if(hasValidCookie>0){
2178      addToMap(_tmpMaps->content,"sessid",strstr(tcook,"=")+1);
2179      char session_file_path[1024];
2180      map *tmpPath=getMapFromMaps(m,"main","sessPath");
2181      if(tmpPath==NULL)
2182        tmpPath=getMapFromMaps(m,"main","tmpPath");
2183      char *tmp1=strtok(tcook,";");
2184      if(tmp1!=NULL)
2185        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(tmp1,"=")+1);
2186      else
2187        sprintf(session_file_path,"%s/sess_%s.cfg",tmpPath->value,strstr(cgiCookie,"=")+1);
2188      free(tcook);
2189      maps *tmpSess=(maps*)malloc(MAPS_SIZE);
2190      struct stat file_status;
2191      int istat = stat(session_file_path, &file_status);
2192      if(istat==0 && file_status.st_size>0){
2193        conf_read(session_file_path,tmpSess);
2194        addMapsToMaps(&m,tmpSess);
2195        freeMaps(&tmpSess);
2196        free(tmpSess);
2197      }
2198    }
2199  }
2200  addMapsToMaps(&m,_tmpMaps);
2201  freeMaps(&_tmpMaps);
2202  free(_tmpMaps);
2203
2204#ifdef DEBUG
2205  dumpMap(request_inputs);
2206#endif
2207#ifdef WIN32
2208  char *cgiSidL=NULL;
2209  if(getenv("CGISID")!=NULL)
2210    addToMap(request_inputs,"cgiSid",getenv("CGISID"));
2211  map* test1=getMap(request_inputs,"cgiSid");
2212  if(test1!=NULL){
2213    cgiSid=test1->value;
2214    addToMap(request_inputs,"storeExecuteResponse","true");
2215    addToMap(request_inputs,"status","true");
2216    setMapInMaps(m,"lenv","sid",test1->value);
2217    status=getMap(request_inputs,"status");
2218    printf("cgiSid %s\n",cgiSid);
2219  }
2220#endif
2221  int hrstd=-1;
2222  char *fbkp,*fbkp1;
2223  FILE *f0,*f1;
2224  if(status!=NULL)
2225    if(strcasecmp(status->value,"false")==0)
2226      status=NULLMAP;
2227  if(status==NULLMAP){
2228    loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
2229  }
2230  else{
2231    int   pid;
2232#ifdef DEBUG
2233    fprintf(stderr,"\nPID : %d\n",cpid);
2234#endif
2235
2236#ifndef WIN32
2237    pid = fork ();
2238#else
2239    if(cgiSid==NULL){
2240      createProcess(m,request_inputs,s1,NULL,cpid,request_input_real_format,request_output_real_format);
2241      pid = cpid;
2242    }else{
2243      pid=0;
2244      cpid=atoi(cgiSid);
2245      printf("cgiSid %s\n",cgiSid);
2246    }
2247    //printf("pid cpid %d %d\n",pid,cpid);
2248    //fflush(stderr);
2249#endif
2250    if (pid > 0) {
2251      /**
2252       * dady :
2253       * set status to SERVICE_ACCEPTED
2254       */
2255#ifdef DEBUG
2256      fprintf(stderr,"father pid continue (origin %d) %d ...\n",cpid,getpid());
2257#endif
2258      eres=SERVICE_ACCEPTED;
2259    }else if (pid == 0) {
2260      /**
2261       * son : have to close the stdout, stdin and stderr to let the parent
2262       * process answer to http client.
2263       */
2264      r_inputs=getMapFromMaps(m,"main","tmpPath");
2265      map* r_inputs1=getMap(s1->content,"ServiceProvider");
2266      fbkp=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+1024)*sizeof(char));
2267      sprintf(fbkp,"%s/%s_%d.xml",r_inputs->value,r_inputs1->value,cpid);
2268      char* flog=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+1024)*sizeof(char));
2269      sprintf(flog,"%s/%s_%d_error.log",r_inputs->value,r_inputs1->value,cpid);
2270#ifdef DEBUG
2271      fprintf(stderr,"RUN IN BACKGROUND MODE \n");
2272      fprintf(stderr,"son pid continue (origin %d) %d ...\n",cpid,getpid());
2273      fprintf(stderr,"\nFILE TO STORE DATA %s\n",r_inputs->value);
2274#endif
2275      freopen(flog,"w+",stderr);
2276      f0=freopen(fbkp , "w+", stdout);
2277      fclose(stdin);
2278      free(flog);
2279      /**
2280       * set status to SERVICE_STARTED and flush stdout to ensure full
2281       * content was outputed (the file used to store the ResponseDocument).
2282       * The rewind stdout to restart writing from the bgining of the file,
2283       * this way the data will be updated at the end of the process run.
2284       */
2285      printProcessResponse(m,request_inputs,cpid,
2286                           s1,r_inputs1->value,SERVICE_STARTED,
2287                           request_input_real_format,
2288                           request_output_real_format);
2289#ifndef WIN32
2290      fflush(stdout);
2291      rewind(stdout);
2292#else
2293#endif
2294      fbkp1=(char*)malloc((strlen(r_inputs->value)+strlen(r_inputs1->value)+1024)*sizeof(char));
2295      sprintf(fbkp1,"%s/%s_final_%d.xml",r_inputs->value,r_inputs1->value,cpid);
2296      f1=freopen(fbkp1 , "w+", stdout);
2297      loadServiceAndRun(&m,s1,request_inputs,&request_input_real_format,&request_output_real_format,&eres);
2298    } else {
2299      /**
2300       * error server don't accept the process need to output a valid
2301       * error response here !!!
2302       */
2303      eres=-1;
2304      errorException(m, _("Unable to run the child process properly"), "InternalError");
2305    }
2306  }
2307
2308#ifdef DEBUG
2309  dumpMaps(request_output_real_format);
2310#endif
2311  if(eres!=-1)
2312    outputResponse(s1,request_input_real_format,
2313                   request_output_real_format,request_inputs,
2314                   cpid,m,eres);
2315  fflush(stdout);
2316  /**
2317   * Ensure that if error occurs when freeing memory, no signal will return
2318   * an ExceptionReport document as the result was already returned to the
2319   * client.
2320   */
2321#ifndef USE_GDB
2322  (void) signal(SIGSEGV,donothing);
2323  (void) signal(SIGTERM,donothing);
2324  (void) signal(SIGINT,donothing);
2325  (void) signal(SIGILL,donothing);
2326  (void) signal(SIGFPE,donothing);
2327  (void) signal(SIGABRT,donothing);
2328#endif
2329
2330  if(((int)getpid())!=cpid){
2331    fclose(stdout);
2332    fclose(stderr);
2333    unhandleStatus(m);
2334    /**
2335     * Dump back the final file fbkp1 to fbkp
2336     */
2337    fclose(f0);
2338    fclose(f1);
2339    FILE* f2=fopen(fbkp1,"rb");
2340    FILE* f3=fopen(fbkp,"wb+");
2341    free(fbkp);
2342    fseek(f2,0,SEEK_END);
2343    long flen=ftell(f2);
2344    fseek(f2,0,SEEK_SET);
2345    char *tmps1=(char*)malloc((flen+1)*sizeof(char));
2346    fread(tmps1,flen,1,f2);
2347    fwrite(tmps1,1,flen,f3);
2348    fclose(f2);
2349    fclose(f3);
2350    unlink(fbkp1);
2351    free(fbkp1);
2352  }
2353
2354  freeService(&s1);
2355  free(s1);
2356  freeMaps(&m);
2357  free(m);
2358 
2359  freeMaps(&request_input_real_format);
2360  free(request_input_real_format);
2361 
2362  freeMaps(&request_output_real_format);
2363  free(request_output_real_format);
2364 
2365  free(REQUEST);
2366  free(SERVICE_URL);
2367#ifdef DEBUG
2368  fprintf(stderr,"Processed response \n");
2369  fflush(stdout);
2370  fflush(stderr);
2371#endif
2372
2373  return 0;
2374}
2375

Search

Context Navigation

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