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

Last change on this file since 862 was 844, checked in by jmckenna, 7 years ago

fix libintl reference

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