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

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

Add the optional Ruby Language Support to the ZOO-Kernel with an API similar to the Python ZOO-API. Small rewrite of Python support. Fix issue #86 and #87. Add usid in [lenv] section, this value is used to generate an unique identifier based on time and the process identifier. This usid is now used to name the stored result or the mapfile generated. Remove *some* warning messages displayed at compilation time.

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