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

Last change on this file since 680 was 680, checked in by djay, 9 years ago

Various fixes for Windows support: generate uuid using UuidCreate?, pass usid to the created process, call TerminateProcess? on dismiss request.

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