source: branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c @ 822

Last change on this file since 822 was 822, checked in by djay, 7 years ago

Commit the minimal requirements for remote HPC support

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