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

Last change on this file since 368 was 368, checked in by djay, 12 years ago

Many thanks to Trevor Clarke for providing patch for Python ZOO-API. This rev. shall fix ticket #74.

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