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

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

Update to support multiple outputs provided in a XML POST request.

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