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

Last change on this file since 745 was 745, checked in by djay, 8 years ago

Fix issue when XML request contains empty nodes for inputs

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