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

Last change on this file since 789 was 789, checked in by knut, 7 years ago

Added support for include mechanism in the main.cfg file. An [include] block can be added in main.cfg, like this:

[include]
servicename1 = /my/service/repository/service1.zcfg
servicename2 = /my/service/repository/service2.zcfg
...

The word "include" thus has a special (reserved) meaning, just as "main" does. If necessary, a user may change "include" to something else by redefining the IMPORTSERVICE macro.

The service name (left hand side) should match the [service name] in the config (zcfg) file, but the path/file name (right hand side) may be arbitrary.

When handling requests, Zoo will first check if there is an [include] block, then recursively search the working directory (CWD) and subdirectories as before. If an [include]d service happens to be located in a CWD (sub)directory, it will be published by its [include]d name.

As currently implemented, Zoo will search CWD for the library files of [include]d services if the libPath parameter is not set (note that presently only C and PHP services support the libPath parameter).

Added new function (zoo_path_compare) to check if two path strings refer to the same physical file. It should handle symbolic links (typically, Linux/Unix?) and different path separators (typically, Windows).

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