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

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

Move createRegistry function to server_internal. Add the utils/registry service.

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