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

Last change on this file since 788 was 788, checked in by knut, 8 years ago

Implemented support for PHP 7: The Zend API for PHP 7/PHPNG is substantially different from older versions. Therefore, an alternative implementation of zoo_php_support is provided in the new source file service_internal_php7.c. Presently the Zoo kernel can be built with support for either PHP 7 or older versions, see the makefiles (for Windows) nmake.opt and makefile.vc. Other makefiles have not been updated.

Fixed problem with ambiguous symbol in service_conf.y. Fixed problem with conversion of line endings yielding extra bytes in _getStatusFile on Windows platforms. Removed call to free() stack memory in zoo_service_loader.c. Fixed issue with size of structs in service.h.

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