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

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

Give the capability to store the main.cfg file in sysconfdir and the services in servicePath if defined in the [main] section.

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

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png