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

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

Better concurrency gesture for asynchronous requests, add db backend support for status informations.

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