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

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

Add the initial C# language support.

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