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

Last change on this file was 986, checked in by djay, 3 years ago

Move the execute endpoint to /processes/{processID}. Fixes in oas.cfg: use opengeospatial/ogcapi-processes github repo for schemas URLs.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 101.4 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 *  Copyright 2008-2020 GeoLabs SARL. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 
25extern "C" int yylex ();
26extern "C" int crlex ();
27
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
35#ifdef USE_OTB
36#include "service_internal_otb.h"
37#endif
38
39#ifdef USE_R
40#include "service_internal_r.h"
41#endif
42
43#ifdef USE_HPC
44#include "service_internal_hpc.h"
45#endif
46
47#ifdef USE_PYTHON
48#include "service_internal_python.h"
49#endif
50
51#include "cgic.h"
52
53#include <libxml/tree.h>
54#include <libxml/xmlmemory.h>
55#include <libxml/parser.h>
56#include <libxml/xpath.h>
57#include <libxml/xpathInternals.h>
58
59#include "ulinet.h"
60
61#include <libintl.h>
62#include <locale.h>
63#include <string.h>
64
65#include "service_internal.h"
66#include "server_internal.h"
67#include "response_print.h"
68#include "request_parser.h"
69#include "service.h"
70
71#if defined(WIN32) || defined(USE_JSON)
72#include "caching.h"
73#endif
74#include "sqlapi.h"
75
76#ifdef META_DB
77#include "meta_sql.h"
78#endif
79
80#ifdef USE_SAGA
81#include "service_internal_saga.h"
82#endif
83
84#ifdef USE_JAVA
85#include "service_internal_java.h"
86#endif
87
88#ifdef USE_PHP
89#include "service_internal_php.h"
90#endif
91
92#ifdef USE_JS
93#include "service_internal_js.h"
94#endif
95
96#ifdef USE_RUBY
97#include "service_internal_ruby.h"
98#endif
99
100#ifdef USE_PERL
101#include "service_internal_perl.h"
102#endif
103
104#ifdef USE_MONO
105#include "service_internal_mono.h"
106#endif
107
108#if defined(USE_CALLBACK) || defined(USE_JSON)
109#include "service_callback.h"
110#endif
111
112#ifdef USE_JSON
113#include "service_json.h"
114#include "json_tokener.h"
115#endif
116
117#include <dirent.h>
118#include <signal.h>
119#ifndef WIN32
120#include <execinfo.h>
121#endif
122#include <unistd.h>
123#ifndef WIN32
124#include <dlfcn.h>
125#include <libgen.h>
126#else
127#include <windows.h>
128#include <direct.h>
129#include <sys/types.h>
130#include <sys/stat.h>
131#include <unistd.h>
132#define pid_t int;
133#endif
134#include <fcntl.h>
135#include <time.h>
136#include <stdarg.h>
137
138#include <libxml/tree.h>
139#include <libxml/parser.h>
140#include <libxml/xpath.h>
141#include <libxml/xpathInternals.h>
142
143#include <libxslt/xslt.h>
144#include <libxslt/xsltInternals.h>
145#include <libxslt/transform.h>
146#include <libxslt/xsltutils.h>
147
148#ifndef WIN32
149extern char **environ;
150#endif
151
152
153#ifdef WIN32
154extern "C"
155{
156  __declspec (dllexport) char *strcasestr (char const *a, char const *b)
157#ifndef USE_MS
158  {
159    char *x = zStrdup (a);
160    char *y = zStrdup (b);
161
162      x = _strlwr (x);
163      y = _strlwr (y);
164    char *pos = strstr (x, y);
165    char *ret = pos == NULL ? NULL : (char *) (a + (pos - x));
166      free (x);
167      free (y);
168      return ret;
169  };
170#else
171   ;
172#endif
173}
174#endif
175
176/**
177 * Translation function for zoo-kernel
178 */
179#define _(String) dgettext ("zoo-kernel",String)
180/**
181 * Translation function for zoo-service
182 */
183#define __(String) dgettext ("zoo-service",String)
184
185#ifdef WIN32
186#ifndef PROGRAMNAME
187#define PROGRAMNAME "zoo_loader.cgi"
188#endif
189#endif
190
191
192/**
193 * Replace a char by another one in a string
194 *
195 * @param str the string to update
196 * @param toReplace the char to replace
197 * @param toReplaceBy the char that will be used
198 */
199void
200translateChar (char *str, char toReplace, char toReplaceBy)
201{
202  int i = 0, len = strlen (str);
203  for (i = 0; i < len; i++)
204    {
205      if (str[i] == toReplace)
206        str[i] = toReplaceBy;
207    }
208}
209
210/**
211 * Dump back the final file fbkp1 to fbkp
212 *
213 * @param m the conf maps containing the main.cfg settings
214 * @param fbkp the string corresponding to the name of the file
215 * @param fbkp1 the string corresponding to the name of the file
216 */
217int dumpBackFinalFile(maps* m,char* fbkp,char* fbkp1)
218{
219  FILE *f2 = fopen (fbkp1, "rb");
220#ifndef RELY_ON_DB
221  semid lid = getShmLockId (m, 1);
222  if (lid < 0)
223    return -1;
224  lockShm (lid);
225#endif
226  FILE *f3 = fopen (fbkp, "wb+");
227  free (fbkp);
228  fseek (f2, 0, SEEK_END);
229  long flen = ftell (f2);
230  fseek (f2, 0, SEEK_SET);
231  char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
232  fread (tmps1, flen, 1, f2);
233#ifdef WIN32
234  /* knut: I think this block can be dropped; pchr may be NULL if result is not in XML format
235  char *pchr=strrchr(tmps1,'>');
236  flen=strlen(tmps1)-strlen(pchr)+1;
237  tmps1[flen]=0;
238  */
239#endif
240  fwrite (tmps1, 1, flen, f3);
241  fclose (f2);
242  fclose (f3);
243  free(tmps1);
244  return 1;
245}
246
247/**
248 * Recursivelly parse zcfg starting from the ZOO-Kernel cwd.
249 * Call the func function given in arguments after parsing the ZCFG file.
250 *
251 * @param m the conf maps containing the main.cfg settings
252 * @param r the registry containing profiles hierarchy
253 * @param n the root XML Node to add the sub-elements
254 * @param conf_dir the location of the main.cfg file (basically cwd)
255 * @param prefix the current prefix if any, or NULL
256 * @param saved_stdout the saved stdout identifier
257 * @param level the current level (number of sub-directories to reach the
258 * current path)
259 * @param func a pointer to a function having 4 parameters
260 *  (registry*, maps*, xmlNodePtr and service*).
261 * @see inheritance, readServiceFile
262 */
263int
264recursReaddirF ( maps * m, registry *r, void* doc1, void* n1, char *conf_dir,
265                 //( maps * m, registry *r, xmlDocPtr doc, xmlNodePtr n, char *conf_dir,
266                 char *prefix, int saved_stdout, int level,
267                 void (func) (registry *, maps *, void*, void*, service *) )
268                 //void (func) (registry *, maps *, xmlDocPtr, xmlNodePtr, service *) )
269{
270  struct dirent *dp;
271  int scount = 0;
272  xmlDocPtr doc=(xmlDocPtr) doc1;
273  xmlNodePtr n=(xmlNodePtr) n1;
274
275  if (conf_dir == NULL)
276    return 1;
277  DIR *dirp = opendir (conf_dir);
278  if (dirp == NULL)
279    {
280      if (level > 0)
281        return 1;
282      else
283        return -1;
284    }
285  char tmp1[25];
286  sprintf (tmp1, "sprefix_%d", level);
287  char levels[17];
288  sprintf (levels, "%d", level);
289  setMapInMaps (m, "lenv", "level", levels);
290  while ((dp = readdir (dirp)) != NULL)
291    if ((dp->d_type == DT_DIR || dp->d_type == DT_LNK) && dp->d_name[0] != '.'
292        && strstr (dp->d_name, ".") == NULL)
293      {
294
295        char *tmp =
296          (char *) malloc ((strlen (conf_dir) + strlen (dp->d_name) + 2) *
297                           sizeof (char));
298        sprintf (tmp, "%s/%s", conf_dir, dp->d_name);
299
300        if (prefix != NULL)
301          {
302            prefix = NULL;
303          }
304        prefix = (char *) malloc ((strlen (dp->d_name) + 2) * sizeof (char));
305        sprintf (prefix, "%s.", dp->d_name);
306
307        //map* tmpMap=getMapFromMaps(m,"lenv",tmp1);
308
309        int res;
310        if (prefix != NULL)
311          {
312            setMapInMaps (m, "lenv", tmp1, prefix);
313            char levels1[17];
314            sprintf (levels1, "%d", level + 1);
315            setMapInMaps (m, "lenv", "level", levels1);
316            res =
317              recursReaddirF (m, r, doc, n, tmp, prefix, saved_stdout, level + 1,
318                              func);
319            sprintf (levels1, "%d", level);
320            setMapInMaps (m, "lenv", "level", levels1);
321            free (prefix);
322            prefix = NULL;
323          }
324        else
325          res = -1;
326        free (tmp);
327        if (res < 0)
328          {
329            return res;
330          }
331      }
332    else
333      {
334        char* extn = strstr(dp->d_name, ".zcfg");
335        if(dp->d_name[0] != '.' && extn != NULL && strlen(extn) == 5 && strlen(dp->d_name)>6)
336          {
337            int t;
338            char tmps1[1024];
339            memset (tmps1, 0, 1024);
340            snprintf (tmps1, 1024, "%s/%s", conf_dir, dp->d_name);
341
342            char *tmpsn = (char*)malloc((strlen(dp->d_name)-4)*sizeof(char));//zStrdup (dp->d_name);
343            memset (tmpsn, 0, strlen(dp->d_name)-4);
344            snprintf(tmpsn,strlen(dp->d_name)-4,"%s",dp->d_name);
345           
346            map* import = getMapFromMaps (m, IMPORTSERVICE, tmpsn);
347            if (import == NULL || import->value == NULL || zoo_path_compare(tmps1, import->value) != 0 ) { // service is not in [include] block
348              service *s1 = createService();
349              if (s1 == NULL)
350                {
351                  zDup2 (saved_stdout, fileno (stdout));
352                  errorException (m, _("Unable to allocate memory"),
353                                  "InternalError", NULL);
354                  return -1;
355                }
356  #ifdef DEBUG
357              fprintf (stderr, "#################\n%s\n#################\n",
358                       tmps1);
359  #endif
360              t = readServiceFile (m, tmps1, &s1, tmpsn);
361              free (tmpsn);
362              if (t < 0)
363                {
364                  map *tmp00 = getMapFromMaps (m, "lenv", "message");
365                  char tmp01[1024];
366                  if (tmp00 != NULL)
367                    sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"),
368                             dp->d_name, tmp00->value);
369                  else
370                    sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
371                             dp->d_name);
372                  zDup2 (saved_stdout, fileno (stdout));
373                  errorException (m, tmp01, "InternalError", NULL);
374                  return -1;
375                }
376  #ifdef DEBUG
377              dumpService (s1);
378              fflush (stdout);
379              fflush (stderr);
380  #endif
381              if(s1!=NULL)
382                inheritance(r,&s1);
383              func (r, m, doc, n, s1);
384              freeService (&s1);
385              free (s1);
386              scount++;
387            }
388          }
389      }
390  (void) closedir (dirp);
391  return 1;
392}
393
394/**
395 * When th zcfg file is not found, print error message and cleanup memory
396 * @param zooRegistry the populated registry
397 * @param m the maps pointer to the content of main.cfg file
398 * @param zcfg the zcfg file name
399 * @param code the string determining the nature of the error
400 * @param locator the string determining which parameter the error refer to
401 * @param orig the service name
402 * @param corig the current service name (in case multiple services was parsed)
403 * @param funcError the function used to print the error back
404 */
405void exitAndCleanUp(registry* zooRegistry, maps* m,
406                    const char* zcfg,const char* code,const char* locator,
407                    char* orig,char* corig,
408                    void (funcError) (maps*, map*)){
409  map *tmp00 = getMapFromMaps (m, "lenv", "message");
410  char tmp01[1024];
411  if (tmp00 != NULL)
412    sprintf (tmp01,
413             _("Unable to parse the ZCFG file: %s (%s)"),
414             zcfg, tmp00->value);
415  else
416    sprintf (tmp01,
417             _("Unable to parse the ZCFG file: %s."),
418             zcfg);
419 
420  map* errormap = createMap("text", tmp01);
421  map* tmpMap=getMapFromMaps(m,"main","executionType");
422  char* errorCode=(char*)code;
423  if(tmpMap!=NULL && strncasecmp(tmpMap->value,"json",4)==0)
424    errorCode="NoSuchProcess";
425
426  addToMap(errormap,"code", errorCode);
427  addToMap(errormap,"locator", locator);
428  funcError(m,errormap);
429  freeMaps (&m);
430  free (m);
431  if(zooRegistry!=NULL){
432    freeRegistry(&zooRegistry);
433    free(zooRegistry);
434  }
435  free (orig);
436  if (corig != NULL)
437    free (corig);
438  //xmlFreeDoc (doc);
439  xmlCleanupParser ();
440  zooXmlCleanupNs ();
441  freeMap(&errormap);
442  free(errormap);
443}
444
445
446/**
447 * Parse the ZOO-Service ZCFG to fill the service datastructure
448 *
449 * @param zooRegistry the populated registry
450 * @param m the maps pointer to the content of main.cfg file
451 * @param spService the pointer to the service pointer to be filled
452 * @param request_inputs the map pointer for http request inputs
453 * @param ntmp the path where the ZCFG files are stored
454 * @param cIdentifier the service identifier
455 * @param funcError the error function to be used in case of error
456 */
457int fetchService(registry* zooRegistry,maps* m,service** spService, map* request_inputs,char* ntmp,char* cIdentifier,void (funcError) (maps*, map*)){
458  char tmps1[1024];
459  map *r_inputs=NULL;
460  service* s1=*spService;
461  map* pmExecutionType=getMapFromMaps(m,"main","executionType");
462  map* import = getMapFromMaps (m, IMPORTSERVICE, cIdentifier); 
463  if (import != NULL && import->value != NULL) { 
464    strncpy(tmps1, import->value, 1024);
465    setMapInMaps (m, "lenv", "Identifier", cIdentifier);
466    setMapInMaps (m, "lenv", "oIdentifier", cIdentifier);
467  } 
468  else {
469    snprintf (tmps1, 1024, "%s/%s.zcfg", ntmp, cIdentifier);
470#ifdef DEBUG
471    fprintf (stderr, "Trying to load %s\n", tmps1);
472#endif
473    if (strstr (cIdentifier, ".") != NULL)
474      {
475        setMapInMaps (m, "lenv", "oIdentifier", cIdentifier);
476        char *identifier = zStrdup (cIdentifier);
477        parseIdentifier (m, ntmp, identifier, tmps1);
478        map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
479        if (tmpMap != NULL)
480          addToMap (request_inputs, "metapath", tmpMap->value);
481        free (identifier);
482      }
483    else
484      {
485        setMapInMaps (m, "lenv", "oIdentifier", cIdentifier);
486        setMapInMaps (m, "lenv", "Identifier", cIdentifier);
487      }
488  }
489
490  r_inputs = getMapFromMaps (m, "lenv", "Identifier");
491
492#ifdef META_DB
493  int metadb_id=_init_sql(m,"metadb");
494  //FAILED CONNECTING DB
495  if(getMapFromMaps(m,"lenv","dbIssue")!=NULL || metadb_id<0){
496    fprintf(stderr,"ERROR CONNECTING METADB\n");
497  }
498  if(metadb_id>=0)
499    *spService=extractServiceFromDb(m,cIdentifier,0);
500  if(s1!=NULL){
501    inheritance(zooRegistry,spService);
502#ifdef USE_HPC
503    addNestedOutputs(spService);
504#endif
505    if(zooRegistry!=NULL){
506      freeRegistry(&zooRegistry);
507      free(zooRegistry);
508    }
509  }else /* Not found in MetaDB */{
510#endif
511    *spService = createService();
512    if (*spService == NULL)
513      {
514        freeMaps (&m);
515        free (m);
516        if(zooRegistry!=NULL){
517          freeRegistry(&zooRegistry);
518          free(zooRegistry);
519        }
520        map* error=createMap("code","InternalError");
521        if(pmExecutionType!=NULL && strncasecmp(pmExecutionType->value,"xml",3)==0){
522            addToMap(error,"locator", "NULL");
523            addToMap(error,"text",_("Unable to allocate memory"));
524        }
525        else{
526          addToMap(error,"message",_("Unable to allocate memory"));
527        }
528
529        setMapInMaps(m,"lenv","status_code","404 Bad Request");
530        funcError(m,error);
531
532        return 1; /*errorException (m, _("Unable to allocate memory"),
533                    "InternalError", NULL);*/
534      }
535
536    int saved_stdout = zDup (fileno (stdout));
537    zDup2 (fileno (stderr), fileno (stdout));
538    int t = readServiceFile (m, tmps1, spService, cIdentifier);
539    if(t>=0){
540      inheritance(zooRegistry,spService);
541#ifdef USE_HPC
542      addNestedOutputs(spService);
543#endif
544    }
545    if(zooRegistry!=NULL){
546      freeRegistry(&zooRegistry);
547      free(zooRegistry);
548    }
549    fflush(stderr);
550    fflush (stdout);
551    zDup2 (saved_stdout, fileno (stdout));
552    zClose (saved_stdout);
553    if (t < 0)
554      {
555        r_inputs = getMapFromMaps (m, "lenv", "oIdentifier");
556        if(r_inputs!=NULL){
557          char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
558          sprintf (tmpMsg,
559                   _
560                   ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
561                   r_inputs->value);
562          map* error=createMap("code","NoSuchProcess");
563          if(pmExecutionType!=NULL && strncasecmp(pmExecutionType->value,"xml",3)==0){
564            addToMap(error,"locator", "identifier");
565            addToMap(error,"text",tmpMsg);
566            addToMap(error,"code","InvalidParameterValue");
567          }
568          else{
569            addToMap(error,"message",tmpMsg);
570          }
571          //setMapInMaps(conf,"lenv","status_code","404 Bad Request");
572          funcError(m,error);
573         
574          //errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
575          free (tmpMsg);
576          free (*spService);
577          freeMaps (&m);
578          free (m);
579          return 1;
580        }
581      }
582#ifdef META_DB
583  }
584#endif
585  return 0;
586}
587
588/**
589 * Search services from various possible sources
590 *
591 * @param zopRegistry the populated registry
592 * @param m the maps pointer to the content of main.cfg file
593 * @param r_inputs the service(s) name(s)
594 * @param func the function used to print the result back
595 * @param doc the xml document or NULL (for json)
596 * @param n the xmlNode of JSON object pointer to the current element
597 * @param conf_dir the directory where the main.cfg has been found
598 * @param request_inputs the map pointer to the request KVP if any
599 * @param funcError the function used to print the error back
600 * @return 0 in case of success, 1 otherwise
601 */
602int fetchServicesForDescription(registry* zooRegistry, maps* m, char* r_inputs,
603                                void (func) (registry *, maps *, void*, void*, service *),
604                                void* doc, void* n, char* conf_dir, map* request_inputs,
605                                void (funcError) (maps*, map*) ){
606  char *orig = zStrdup (r_inputs);
607  service* s1=NULL;
608  int saved_stdout = zDup (fileno (stdout));
609  int t;
610  int scount = 0;
611  struct dirent *dp;
612
613  zDup2 (fileno (stderr), fileno (stdout)); 
614  if (strcasecmp ("all", orig) == 0)
615    {
616      maps* imports = getMaps(m, IMPORTSERVICE); 
617      if (imports != NULL) {       
618        map* zcfg = imports->content;
619           
620        while (zcfg != NULL) {
621          if (zcfg->value != NULL) {
622            service* svc = (service*) malloc(SERVICE_SIZE);
623            if (svc == NULL || readServiceFile(m, zcfg->value, &svc, zcfg->name) < 0) {
624              // pass over silently
625              zcfg = zcfg->next;
626              continue;
627            }
628            inheritance(zooRegistry, &svc);
629#ifdef USE_HPC
630            addNestedOutputs(&svc);
631#endif
632
633            func(zooRegistry, m, doc, n, svc);
634            freeService(&svc);
635            free(svc);                             
636          }
637          zcfg = zcfg->next;
638        }           
639      }
640      if (int res =
641          recursReaddirF (m, zooRegistry, doc, n, conf_dir, NULL, saved_stdout, 0,
642                          func) < 0)
643        return res;
644#ifdef META_DB
645      fetchServicesFromDb(zooRegistry,m,doc,n,func,0);
646      close_sql(m,0);
647#endif
648    }
649  else
650    {
651      DIR *dirp = opendir (conf_dir);
652      char *saveptr;
653      char *tmps = strtok_r (orig, ",", &saveptr);
654
655      char buff[256];
656      char buff1[1024];
657      while (tmps != NULL)
658        {
659          int hasVal = -1;
660          char *corig = zStrdup (tmps);
661          map* import = getMapFromMaps (m, IMPORTSERVICE, corig);   
662          if (import != NULL && import->value != NULL) 
663            {
664#ifdef META_DB                 
665              service* s2=extractServiceFromDb(m,import->name,0);
666              if(s2==NULL){
667#endif
668                s1 = createService();
669                t = readServiceFile (m, import->value, &s1, import->name);
670
671                if (t < 0) // failure reading zcfg
672                  {
673                    zDup2 (saved_stdout, fileno (stdout));
674                    exitAndCleanUp(zooRegistry, m,
675                                   tmps,"InvalidParameterValue","identifier",
676                                   orig,corig,
677                                   funcError);
678                    return 1;
679                  }
680#ifdef DEBUG
681                dumpService (s1);
682#endif
683                inheritance(zooRegistry,&s1);
684#ifdef USE_HPC
685                addNestedOutputs(&s1);
686#endif
687                func (zooRegistry, m, doc, n, s1);
688                freeService (&s1);
689                free (s1);
690                s1 = NULL;
691                scount++;
692                hasVal = 1;               
693#ifdef META_DB
694              }
695#endif
696            }
697          else if (strstr (corig, ".") != NULL)
698            {
699              parseIdentifier (m, conf_dir, corig, buff1);
700              map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
701              if (tmpMap != NULL)
702                addToMap (request_inputs, "metapath", tmpMap->value);
703              map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
704              /**
705               * No support for dot in service name stored in metadb!?
706               #ifdef META_DB
707               service* s2=extractServiceFromDb(m,tmpMapI->value,0);
708               if(s2==NULL){
709               #endif
710              */
711              s1 = createService();
712              t = readServiceFile (m, buff1, &s1, tmpMapI->value);
713              if (t < 0)
714                {
715                  zDup2 (saved_stdout, fileno (stdout));
716                  exitAndCleanUp(zooRegistry, m,
717                                 tmps,"InvalidParameterValue","identifier",
718                                 orig,corig,
719                                 funcError);
720                  return 1;
721                }
722#ifdef DEBUG
723              dumpService (s1);
724#endif
725              inheritance(zooRegistry,&s1);
726#ifdef USE_HPC
727              addNestedOutputs(&s1);
728#endif
729              func (zooRegistry, m, doc, n, s1);
730              freeService (&s1);
731              free (s1);
732              s1 = NULL;
733              scount++;
734              hasVal = 1;
735              setMapInMaps (m, "lenv", "level", "0");
736            }
737          else
738            {
739#ifdef META_DB
740              _init_sql(m,"metadb");
741              //FAILED CONNECTING DB
742              if(getMapFromMaps(m,"lenv","dbIssue")!=NULL){
743                fprintf(stderr,"ERROR CONNECTING METADB");
744              }
745              service* s2=extractServiceFromDb(m,corig,0);
746              if(s2!=NULL){
747                inheritance(zooRegistry,&s2);
748#ifdef USE_HPC
749                addNestedOutputs(&s2);
750#endif
751                func (zooRegistry,m, doc, n, s2);
752                freeService (&s2);
753                free (s2);
754                s2 = NULL;
755                hasVal = 1;
756              }else /*TOTO*/{
757#endif
758                memset (buff, 0, 256);
759                snprintf (buff, 256, "%s.zcfg", corig);
760                memset (buff1, 0, 1024);
761#ifdef DEBUG
762                printf ("\n#######%s\n########\n", buff);
763#endif
764                while ((dp = readdir (dirp)) != NULL)
765                  {
766                    if (strcasecmp (dp->d_name, buff) == 0)
767                      {
768                        memset (buff1, 0, 1024);
769                        snprintf (buff1, 1024, "%s/%s", conf_dir,
770                                  dp->d_name);
771                        s1 = createService();
772                        if (s1 == NULL)
773                          {
774                            zDup2 (saved_stdout, fileno (stdout));
775                            map* errormap = createMap("text", _("Unable to allocate memory"));
776                            addToMap(errormap,"code", "InternalError");
777                            addToMap(errormap,"locator", "NULL");
778                            funcError(m,errormap);
779                            return -1;
780                          }
781#ifdef DEBUG_SERVICE_CONF
782                        fprintf
783                          (stderr,"#################\n(%s) %s\n#################\n",
784                           r_inputs->value, buff1);
785#endif
786                        char *tmp0 = zStrdup (dp->d_name);
787                        tmp0[strlen (tmp0) - 5] = 0;
788                        t = readServiceFile (m, buff1, &s1, tmp0);
789                        free (tmp0);
790                        if (t < 0)
791                          {
792                            zDup2 (saved_stdout, fileno (stdout));
793                            exitAndCleanUp(zooRegistry, m,
794                                           buff,"InternalError","NULL",
795                                           orig,corig,
796                                           funcError);
797                            return 1;
798                          }
799#ifdef DEBUG
800                        dumpService (s1);
801#endif
802                        inheritance(zooRegistry,&s1);
803#ifdef USE_HPC
804                        addNestedOutputs(&s1);
805#endif
806                        func (zooRegistry,m, doc, n, s1);
807                        freeService (&s1);
808                        free (s1);
809                        s1 = NULL;
810                        scount++;
811                        hasVal = 1;
812                      }
813                  }
814#ifdef META_DB
815              }
816#endif
817            }                 
818          if (hasVal < 0)
819            {
820              zDup2 (saved_stdout, fileno (stdout));
821              exitAndCleanUp(zooRegistry, m,
822                             buff,"InvalidParameterValue","Identifier",
823                             orig,corig,
824                             funcError);
825              return 1;
826            }
827          rewinddir (dirp);
828          tmps = strtok_r (NULL, ",", &saveptr);
829          if (corig != NULL)
830            free (corig);
831        }                 
832    }
833  fflush (stdout);
834  zDup2 (saved_stdout, fileno (stdout));
835  zClose(saved_stdout);
836  free (orig);
837  return 0;
838}
839
840#ifdef USE_JSON
841/**
842 * Run every HTTP request to download inputs passed as reference
843 *
844 * @param conf the maps pointing to the main.cfg file content
845 * @param inputs the maps pointing to the inputs provided in the request
846 */
847int loadHttpRequests(maps* conf,maps* inputs){
848  // Resolve reference
849  // TODO: add erro gesture
850  int eres;
851  maps* tmpMaps=getMaps(conf,"http_requests");
852  if(tmpMaps!=NULL){
853    map* lenMap=getMap(tmpMaps->content,"length");
854    int len=0;
855    if(lenMap!=NULL){
856      len=atoi(lenMap->value);
857    }
858    HINTERNET hInternet;
859    HINTERNET res;
860    if(len>0)
861      hInternet = InternetOpen (
862#ifndef WIN32
863                                (LPCTSTR)
864#endif
865                                "ZOO-Project WPS Client\0",
866                                INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
867    for(int j=0;j<len;j++){
868      map* tmpUrl=getMapArray(tmpMaps->content,"url",j);
869      map* tmpInput=getMapArray(tmpMaps->content,"input",j);
870      maps* currentMaps=getMaps(inputs,tmpInput->value);
871      loadRemoteFile(&conf,&currentMaps->content,&hInternet,tmpUrl->value);
872      addIntToMap(currentMaps->content,"Order",hInternet.nb);
873      addToMap(currentMaps->content,"Reference",tmpUrl->value);
874    }
875    if(len>0){
876      map* error=NULL;
877      runHttpRequests(&conf,&inputs,&hInternet,&error);
878      InternetCloseHandle(&hInternet);
879    }
880  }
881  return 0;
882}
883#endif
884
885/**
886 * Initialize environment sections, load env, and populate lenv and renv.
887 *
888 * @param conf the maps pointing to the main.cfg file content
889 * @param request_inputs the map pointing to the request KVP
890 * @param cPath a string pointing to the cwd
891 * @param request a string pointing to the request key (xrequest or jrequest)
892 */
893void initAllEnvironment(maps* conf,map* request_inputs,
894                        const char* cPath,const char* request){
895  // Define each env variable in runing environment
896  maps *curs = getMaps (conf, "env");
897  if (curs != NULL) {
898    map *mapcs = curs->content;
899    while (mapcs != NULLMAP)
900      {
901#ifndef WIN32
902        setenv (mapcs->name, mapcs->value, 1);
903#ifdef DEBUG
904        fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
905                 mapcs->value);
906#endif
907#else
908        if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
909          {
910#ifdef DEBUG
911            fprintf (stderr, "[ZOO: Env var finish with \r]\n");
912#endif
913            mapcs->value[strlen (mapcs->value) - 1] = 0;
914          }
915#ifdef DEBUG
916        if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
917          {
918            fflush (stderr);
919            fprintf (stderr, "setting variable... %s\n", "OK");
920          }
921        else
922          {
923            fflush (stderr);
924            fprintf (stderr, "setting variable... %s\n", "OK");
925          }
926#else
927        SetEnvironmentVariable (mapcs->name, mapcs->value);
928#endif
929        char *toto =
930          (char *)
931          malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
932                   2) * sizeof (char));
933        sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
934        _putenv (toto);
935#ifdef DEBUG
936        fflush (stderr);
937#endif
938#endif
939
940#ifdef DEBUG
941        fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
942                 mapcs->value);
943        fflush (stderr);
944#endif
945        mapcs = mapcs->next;
946      }
947  }
948
949           
950
951  int eres = SERVICE_STARTED;
952  int cpid = zGetpid ();
953
954  // Create a map containing a copy of the request map
955  maps *_tmpMaps = createMaps("request");
956  addMapToMap(&_tmpMaps->content,request_inputs);
957  addMapsToMaps (&conf, _tmpMaps);
958  freeMaps (&_tmpMaps);
959  free (_tmpMaps);
960  /**
961   * Initialize the specific [lenv] section which contains runtime variables:
962   *
963   *  - usid : it is an universally unique identifier 
964   *  - osid : it is an idenfitication number
965   *  - sid : it is the process idenfitication number (OS)
966   *  - uusid : it is an universally unique identifier
967   *  - status : value between 0 and 100 to express the  completude of
968   * the operations of the running service
969   *  - message : is a string where you can store error messages, in case
970   * service is failing, or o provide details on the ongoing operation.
971   *  - cwd : the current working directory or servicePath if defined
972   *  - soap : is a boolean value, true if the request was contained in a SOAP
973   * Envelop
974   *  - sessid : string storing the session identifier (only when cookie is
975   * used)
976   *  - cgiSid : only defined on Window platforms (for being able to identify
977   * the created process)
978   *
979   */
980  _tmpMaps = createMaps("lenv");
981  char tmpBuff[100];
982  struct ztimeval tp;
983  if (zGettimeofday (&tp, NULL) == 0)
984    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
985  else
986    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
987  _tmpMaps->content = createMap ("osid", tmpBuff);
988  sprintf (tmpBuff, "%i", cpid);
989  addToMap (_tmpMaps->content, "sid", tmpBuff);
990  char* tmpUuid=get_uuid();
991  addToMap (_tmpMaps->content, "uusid", tmpUuid);
992  addToMap (_tmpMaps->content, "usid", tmpUuid);
993  free(tmpUuid);
994  addToMap (_tmpMaps->content, "status", "0");
995  map* cwdMap0=getMapFromMaps(conf,"main","servicePath");
996  if(cwdMap0!=NULL){
997    addToMap (_tmpMaps->content, "cwd", cwdMap0->value);
998    addToMap (_tmpMaps->content, "rcwd", cPath);
999  }
1000  else
1001    addToMap (_tmpMaps->content, "cwd", cPath);
1002  addToMap (_tmpMaps->content, "message", _("No message provided"));
1003  map *ltmp = getMap (request_inputs, "soap");
1004  if (ltmp != NULL)
1005    addToMap (_tmpMaps->content, "soap", ltmp->value);
1006  else
1007    addToMap (_tmpMaps->content, "soap", "false");
1008
1009  // Parse the session file and add it to the main maps
1010  char* originalCookie=NULL;
1011  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
1012    {
1013      int hasValidCookie = -1;
1014      char *tcook = originalCookie = zStrdup (cgiCookie);
1015      map *testing = getMapFromMaps (conf, "main", "cookiePrefix");
1016      parseCookie(&conf,originalCookie);
1017      map *sessId=getMapFromMaps(conf,"cookies",
1018                                 (testing==NULL?"ID":testing->value));
1019      if (sessId!=NULL)
1020        {
1021          addToMap (_tmpMaps->content, "sessid", sessId->value);
1022          char session_file_path[1024];
1023          map *tmpPath = getMapFromMaps (conf, "main", "sessPath");
1024          if (tmpPath == NULL)
1025            tmpPath = getMapFromMaps (conf, "main", "tmpPath");
1026          char *tmp1 = strtok (tcook, ";");
1027          if (tmp1 != NULL)
1028            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
1029                     sessId->value);
1030          else
1031            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
1032                     sessId->value);
1033          free (tcook);
1034          maps *tmpSess = (maps *) malloc (MAPS_SIZE);
1035          tmpSess->child=NULL;
1036          struct stat file_status;
1037          int istat = stat (session_file_path, &file_status);
1038          if (istat == 0 && file_status.st_size > 0)
1039            {
1040              int saved_stdout = zDup (fileno (stdout));
1041              zDup2 (fileno (stderr), fileno (stdout));
1042              conf_read (session_file_path, tmpSess);
1043              addMapsToMaps (&conf, tmpSess);
1044              freeMaps (&tmpSess);
1045              fflush(stdout);
1046              zDup2 (saved_stdout, fileno (stdout));
1047              zClose(saved_stdout);
1048            }
1049          free (tmpSess);
1050        }
1051    }
1052  addMapsToMaps (&conf, _tmpMaps);
1053  freeMaps (&_tmpMaps);
1054  free (_tmpMaps);
1055  maps* bmap=NULL;
1056#ifdef DEBUG
1057  dumpMap (request_inputs);
1058#endif
1059  int ei = 1;
1060 
1061  _tmpMaps = createMaps("renv");
1062
1063#ifdef WIN32
1064  LPVOID orig = GetEnvironmentStrings();
1065  LPTSTR s = (LPTSTR) orig;
1066 
1067  while (*s != NULL) {
1068    char* env = strdup(s);
1069    char* delim = strchr(env,'=');
1070    if (delim != NULL) {
1071      char* val = delim+1;
1072      *delim = '\0';           
1073      if(_tmpMaps->content == NULL) {
1074        _tmpMaps->content = createMap(env,val);
1075      }
1076      else {
1077        addToMap(_tmpMaps->content,env,val);
1078      }                 
1079    }
1080    s += strlen(s)+1;
1081  } 
1082  FreeEnvironmentStrings((LPCH)orig);   
1083#else
1084  char **orig = environ;
1085  char *s=*orig;
1086 
1087  if(orig!=NULL)
1088    for (; s; ei++ ) {
1089      if(strstr(s,"=")!=NULL && strlen(strstr(s,"="))>1){
1090        int len=strlen(s);
1091        char* tmpName=zStrdup(s);
1092        char* tmpValue=strstr(s,"=")+1;
1093        char* tmpName1=(char*)malloc((1+(len-(strlen(tmpValue)+1)))*sizeof(char));
1094        snprintf(tmpName1,(len-strlen(tmpValue)),"%s",tmpName);
1095        if(_tmpMaps->content == NULL)
1096          _tmpMaps->content = createMap (tmpName1,tmpValue);
1097        else
1098          addToMap (_tmpMaps->content,tmpName1,tmpValue);
1099        free(tmpName1);
1100        free(tmpName);
1101      }
1102      s = *(orig+ei);
1103    } 
1104#endif
1105 
1106  if(_tmpMaps->content!=NULL && getMap(_tmpMaps->content,"HTTP_COOKIE")!=NULL){
1107    addToMap(_tmpMaps->content,"HTTP_COOKIE1",&cgiCookie[0]);
1108  }
1109  addMapsToMaps (&conf, _tmpMaps);
1110  freeMaps (&_tmpMaps);
1111  free (_tmpMaps);
1112  map* postRequest=getMap(request_inputs,request);
1113  if(postRequest!=NULL)
1114    setMapInMaps (conf, "renv", request, postRequest->value);
1115#ifdef WIN32
1116  char *cgiSidL = NULL;
1117  if (getenv ("CGISID") != NULL)
1118    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
1119
1120  char* usidp;
1121  if ( (usidp = getenv("USID")) != NULL ) {
1122    setMapInMaps (conf, "lenv", "usid", usidp);
1123  }
1124
1125  map *test1 = getMap (request_inputs, "cgiSid");
1126  if (test1 != NULL){
1127    cgiSid = zStrdup(test1->value);
1128    addToMap (request_inputs, "storeExecuteResponse", "true");
1129    addToMap (request_inputs, "status", "true");
1130    setMapInMaps (conf, "lenv", "osid", test1->value);
1131    //status = getMap (request_inputs, "status");
1132  }
1133  test1 = getMap (request_inputs, "usid");
1134  if (test1 != NULL){
1135    setMapInMaps (conf, "lenv", "usid", test1->value);
1136    setMapInMaps (conf, "lenv", "uusid", test1->value);
1137  }
1138#endif
1139 
1140}
1141
1142/**
1143 * Signal handling function which simply call exit(0).
1144 *
1145 * @param sig the signal number
1146 */
1147void
1148donothing (int sig)
1149{
1150#ifdef DEBUG
1151  fprintf (stderr, "Signal %d after the ZOO-Kernel returned result!\n", sig);
1152#endif
1153  exit (0);
1154}
1155
1156/**
1157 * Signal handling function which create an ExceptionReport node containing the
1158 * information message corresponding to the signal number.
1159 *
1160 * @param sig the signal number
1161 */
1162void
1163sig_handler (int sig)
1164{
1165 
1166  char tmp[100];
1167  const char *ssig;
1168  switch (sig)
1169    {
1170    case SIGSEGV:
1171      ssig = "SIGSEGV";
1172      break;
1173    case SIGTERM:
1174      ssig = "SIGTERM";
1175      break;
1176    case SIGINT:
1177      ssig = "SIGINT";
1178      break;
1179    case SIGILL:
1180      ssig = "SIGILL";
1181      break;
1182    case SIGFPE:
1183      ssig = "SIGFPE";
1184      break;
1185    case SIGABRT:
1186      ssig = "SIGABRT";
1187      break;
1188    default:
1189      ssig = "UNKNOWN";
1190      break;
1191    }
1192  sprintf (tmp,
1193           _
1194           ("ZOO Kernel failed to process your request, receiving signal %d = %s "),
1195           sig, ssig);
1196  errorException (NULL, tmp, "InternalError", NULL);
1197#ifdef DEBUG
1198  fprintf (stderr, "Not this time!\n");
1199#endif
1200  exit (0);
1201}
1202
1203#ifdef USE_JSON
1204  /**
1205   * Signal handling function which create an ExceptionReport node containing the
1206   * information message corresponding to the signal number.
1207   *
1208   * @param sig the signal number
1209   */
1210void json_sig_handler (int sig){
1211  char tmp[100];
1212  const char *ssig;
1213  switch (sig)
1214    {
1215    case SIGSEGV:
1216      ssig = "SIGSEGV";
1217      break;
1218    case SIGTERM:
1219      ssig = "SIGTERM";
1220      break;
1221    case SIGINT:
1222      ssig = "SIGINT";
1223      break;
1224    case SIGILL:
1225      ssig = "SIGILL";
1226      break;
1227    case SIGFPE:
1228      ssig = "SIGFPE";
1229      break;
1230    case SIGABRT:
1231      ssig = "SIGABRT";
1232      break;
1233    default:
1234      ssig = "UNKNOWN";
1235      break;
1236    }
1237  sprintf (tmp,
1238           _
1239           ("ZOO Kernel failed to process your request, receiving signal %d = %s "),
1240           sig, ssig);
1241  map* tmpMap=createMap("decode","suze");
1242  maps* tmpMaps=createMaps("lenv");
1243  setMapInMaps(tmpMaps,"lenv","message",tmp);
1244  setMapInMaps(tmpMaps,"lenv","status","failed");
1245  printExceptionReportResponseJ(tmpMaps,tmpMap);
1246  //errorException (NULL, tmp, "InternalError", NULL);
1247#ifdef DEBUG
1248  fprintf (stderr, "Not this time!\n");
1249#endif
1250  exit (0);
1251}
1252 
1253#endif
1254
1255/**
1256 * Load a service provider and run the service function.
1257 *
1258 * @param myMap the conf maps containing the main.cfg settings
1259 * @param s1 the service structure
1260 * @param request_inputs map storing all the request parameters
1261 * @param inputs the inputs maps
1262 * @param ioutputs the outputs maps
1263 * @param eres the result returned by the service execution
1264 */
1265void
1266loadServiceAndRun (maps ** myMap, service * s1, map * request_inputs,
1267                   maps ** inputs, maps ** ioutputs, int *eres)
1268{
1269  char tmps1[1024];
1270  char ntmp[1024];
1271  maps *m = *myMap;
1272  maps *request_output_real_format = *ioutputs;
1273  maps *request_input_real_format = *inputs;
1274  /**
1275   * Extract serviceType to know what kind of service should be loaded
1276   */
1277  map *r_inputs = NULL;
1278  map* cwdMap=getMapFromMaps(m,"main","servicePath");
1279  if(cwdMap!=NULL){
1280    sprintf(ntmp,"%s",cwdMap->value);
1281  }else{
1282#ifndef WIN32
1283    getcwd (ntmp, 1024);
1284#else
1285    _getcwd (ntmp, 1024);
1286#endif
1287  }
1288  r_inputs = getMap (s1->content, "serviceType");
1289#ifdef DEBUG
1290  fprintf (stderr, "LOAD A %s SERVICE PROVIDER \n", r_inputs->value);
1291  fflush (stderr);
1292#endif
1293
1294  map* libp = getMapFromMaps(m, "main", "libPath"); 
1295  if (strlen (r_inputs->value) == 1
1296      && strncasecmp (r_inputs->value, "C", 1) == 0)
1297  {
1298     if (libp != NULL && libp->value != NULL) {
1299            r_inputs = getMap (s1->content, "ServiceProvider");
1300                sprintf (tmps1, "%s/%s", libp->value, r_inputs->value);
1301         }
1302     else {     
1303        r_inputs = getMap (request_inputs, "metapath");
1304        if (r_inputs != NULL)
1305          sprintf (tmps1, "%s/%s", ntmp, r_inputs->value);
1306        else
1307          sprintf (tmps1, "%s/", ntmp);
1308         
1309        char *altPath = zStrdup (tmps1);
1310        r_inputs = getMap (s1->content, "ServiceProvider");
1311        sprintf (tmps1, "%s/%s", altPath, r_inputs->value);
1312        free (altPath);
1313         }
1314#ifdef DEBUG
1315      fprintf (stderr, "Trying to load %s\n", tmps1);
1316#endif
1317#ifdef WIN32
1318      HINSTANCE so =
1319        LoadLibraryEx (tmps1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
1320#else
1321      void *so = dlopen (tmps1, RTLD_LAZY);
1322#endif
1323#ifdef WIN32
1324      char* errstr = getLastErrorMessage();
1325#else
1326      char *errstr;
1327      errstr = dlerror ();
1328#endif
1329#ifdef DEBUG
1330          fprintf (stderr, "%s loaded (%s) \n", tmps1, errstr);
1331#endif
1332      if (so != NULL)
1333        {
1334#ifdef DEBUG
1335          fprintf (stderr, "Library loaded %s \n", errstr);
1336          fprintf (stderr, "Service Shared Object = %s\n", r_inputs->value);
1337#endif
1338          r_inputs = getMap (s1->content, "serviceType");
1339#ifdef DEBUG
1340          dumpMap (r_inputs);
1341          fprintf (stderr, "%s\n", r_inputs->value);
1342          fflush (stderr);
1343#endif
1344          if (strncasecmp (r_inputs->value, "C-FORTRAN", 9) == 0)
1345            {
1346              r_inputs = getMap (request_inputs, "Identifier");
1347              char fname[1024];
1348              sprintf (fname, "%s_", r_inputs->value);
1349#ifdef DEBUG
1350              fprintf (stderr, "Try to load function %s\n", fname);
1351#endif
1352#ifdef WIN32
1353              typedef int (CALLBACK * execute_t) (char ***, char ***,
1354                                                  char ***);
1355              execute_t execute = (execute_t) GetProcAddress (so, fname);
1356#else
1357              typedef int (*execute_t) (char ***, char ***, char ***);
1358              execute_t execute = (execute_t) dlsym (so, fname);
1359#endif
1360#ifdef DEBUG
1361#ifdef WIN32
1362                          errstr = getLastErrorMessage();
1363#else
1364              errstr = dlerror ();
1365#endif
1366              fprintf (stderr, "Function loaded %s\n", errstr);
1367#endif
1368
1369              char main_conf[10][30][1024];
1370              char inputs[10][30][1024];
1371              char outputs[10][30][1024];
1372              for (int i = 0; i < 10; i++)
1373                {
1374                  for (int j = 0; j < 30; j++)
1375                    {
1376                      memset (main_conf[i][j], 0, 1024);
1377                      memset (inputs[i][j], 0, 1024);
1378                      memset (outputs[i][j], 0, 1024);
1379                    }
1380                }
1381              mapsToCharXXX (m, (char ***) main_conf);
1382              mapsToCharXXX (request_input_real_format, (char ***) inputs);
1383              mapsToCharXXX (request_output_real_format, (char ***) outputs);
1384              *eres =
1385                execute ((char ***) &main_conf[0], (char ***) &inputs[0],
1386                         (char ***) &outputs[0]);
1387#ifdef DEBUG
1388              fprintf (stderr, "Function run successfully \n");
1389#endif
1390              charxxxToMaps ((char ***) &outputs[0],
1391                             &request_output_real_format);
1392            }
1393          else
1394            {
1395#ifdef DEBUG
1396#ifdef WIN32
1397                          errstr = getLastErrorMessage();
1398              fprintf (stderr, "Function %s failed to load because of %s\n",
1399                       r_inputs->value, errstr);
1400#endif
1401#endif
1402              r_inputs = getMapFromMaps (m, "lenv", "Identifier");
1403#ifdef DEBUG
1404              fprintf (stderr, "Try to load function %s\n", r_inputs->value);
1405#endif
1406              typedef int (*execute_t) (maps **, maps **, maps **);
1407#ifdef WIN32
1408              execute_t execute =
1409                (execute_t) GetProcAddress (so, r_inputs->value);
1410#else
1411              execute_t execute = (execute_t) dlsym (so, r_inputs->value);
1412#endif
1413
1414              if (execute == NULL)
1415                {
1416#ifdef WIN32
1417                                  errstr = getLastErrorMessage();
1418#else
1419                  errstr = dlerror ();
1420#endif
1421                  char *tmpMsg =
1422                    (char *) malloc (2048 + strlen (r_inputs->value));
1423                  sprintf (tmpMsg,
1424                           _
1425                           ("Error occurred while running the %s function: %s"),
1426                           r_inputs->value, errstr);
1427                  errorException (m, tmpMsg, "InternalError", NULL);
1428                  free (tmpMsg);
1429#ifdef DEBUG
1430                  fprintf (stderr, "Function %s error %s\n", r_inputs->value,
1431                           errstr);
1432#endif
1433                  *eres = -1;
1434                  return;
1435                }
1436
1437#ifdef DEBUG
1438#ifdef WIN32
1439                          errstr = getLastErrorMessage();
1440#else
1441              errstr = dlerror ();
1442#endif
1443              fprintf (stderr, "Function loaded %s\n", errstr);
1444#endif
1445
1446#ifdef DEBUG
1447              fprintf (stderr, "Now run the function \n");
1448              fflush (stderr);
1449#endif
1450              *eres =
1451                execute (&m, &request_input_real_format,
1452                         &request_output_real_format);
1453#ifdef DEBUG
1454              fprintf (stderr, "Function loaded and returned %d\n", eres);
1455              fflush (stderr);
1456#endif
1457            }
1458#ifdef WIN32
1459          *ioutputs = dupMaps (&request_output_real_format);
1460          FreeLibrary (so);
1461#else
1462          dlclose (so);
1463#endif
1464        }
1465      else
1466        {
1467      /**
1468       * Unable to load the specified shared library
1469       */
1470          char tmps[1024];
1471#ifdef WIN32
1472                  errstr = getLastErrorMessage();
1473#else
1474              errstr = dlerror ();
1475#endif
1476          sprintf (tmps, _("Unable to load C Library %s"), errstr);
1477          errorException(m,tmps,"InternalError",NULL);
1478          *eres = -1;
1479        }
1480    }
1481  else
1482
1483#ifdef USE_HPC
1484  if (strncasecmp (r_inputs->value, "HPC", 3) == 0)
1485    {
1486      *eres =
1487        zoo_hpc_support (&m, request_inputs, s1,
1488                            &request_input_real_format,
1489                            &request_output_real_format);
1490    }
1491  else
1492#endif
1493
1494#ifdef USE_SAGA
1495  if (strncasecmp (r_inputs->value, "SAGA", 4) == 0)
1496    {
1497      *eres =
1498        zoo_saga_support (&m, request_inputs, s1,
1499                            &request_input_real_format,
1500                            &request_output_real_format);
1501    }
1502  else
1503#endif
1504
1505#ifdef USE_OTB
1506  if (strncasecmp (r_inputs->value, "OTB", 3) == 0)
1507    {
1508      *eres =
1509        zoo_otb_support (&m, request_inputs, s1,
1510                            &request_input_real_format,
1511                            &request_output_real_format);
1512    }
1513  else
1514#endif
1515#ifdef USE_PYTHON
1516  if (strncasecmp (r_inputs->value, "PYTHON", 6) == 0)
1517    {             
1518      *eres =
1519        zoo_python_support (&m, request_inputs, s1,
1520                            &request_input_real_format,
1521                            &request_output_real_format);         
1522    }
1523  else
1524#endif
1525
1526#ifdef USE_R
1527  if (strncasecmp (r_inputs->value, "R", 6) == 0)
1528    {     
1529      *eres =
1530        zoo_r_support (&m, request_inputs, s1,
1531                            &request_input_real_format,
1532                            &request_output_real_format);
1533    }
1534  else
1535#endif
1536
1537#ifdef USE_JAVA
1538  if (strncasecmp (r_inputs->value, "JAVA", 4) == 0)
1539    {
1540      *eres =
1541        zoo_java_support (&m, request_inputs, s1, &request_input_real_format,
1542                          &request_output_real_format);
1543    }
1544  else
1545#endif
1546
1547#ifdef USE_PHP
1548  if (strncasecmp (r_inputs->value, "PHP", 3) == 0)
1549    {
1550      *eres =
1551        zoo_php_support (&m, request_inputs, s1, &request_input_real_format,
1552                         &request_output_real_format);         
1553    }
1554  else
1555#endif
1556
1557
1558#ifdef USE_PERL
1559  if (strncasecmp (r_inputs->value, "PERL", 4) == 0)
1560    {
1561      *eres =
1562        zoo_perl_support (&m, request_inputs, s1, &request_input_real_format,
1563                          &request_output_real_format);
1564    }
1565  else
1566#endif
1567
1568#ifdef USE_JS
1569  if (strncasecmp (r_inputs->value, "JS", 2) == 0)
1570    {
1571      *eres =
1572        zoo_js_support (&m, request_inputs, s1, &request_input_real_format,
1573                        &request_output_real_format);
1574    }
1575  else
1576#endif
1577
1578#ifdef USE_RUBY
1579  if (strncasecmp (r_inputs->value, "Ruby", 4) == 0)
1580    {
1581      *eres =
1582        zoo_ruby_support (&m, request_inputs, s1, &request_input_real_format,
1583                          &request_output_real_format);
1584    }
1585  else
1586#endif
1587
1588#ifdef USE_MONO
1589  if (strncasecmp (r_inputs->value, "Mono", 4) == 0)
1590    {
1591      *eres =
1592        zoo_mono_support (&m, request_inputs, s1, &request_input_real_format,
1593                          &request_output_real_format);
1594    }
1595  else
1596#endif
1597
1598    {
1599      char tmpv[1024];
1600      sprintf (tmpv,
1601               _
1602               ("Programming Language (%s) set in ZCFG file is not currently supported by ZOO Kernel.\n"),
1603               r_inputs->value);
1604      errorException (m, tmpv, "InternalError", NULL);
1605      *eres = -1;
1606    }
1607  *myMap = m;
1608  *ioutputs = request_output_real_format; 
1609}
1610
1611
1612#ifdef WIN32
1613/**
1614 * createProcess function: create a new process after setting some env variables
1615 */
1616void
1617createProcess (maps * m, map * request_inputs, service * s1, char *opts,
1618               int cpid, maps * inputs, maps * outputs)
1619{
1620  STARTUPINFO si;
1621  PROCESS_INFORMATION pi;
1622  ZeroMemory (&si, sizeof (si));
1623  si.cb = sizeof (si);
1624  ZeroMemory (&pi, sizeof (pi));
1625  char *tmp = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
1626  char *tmpq = (char *) malloc ((1024 + cgiContentLength) * sizeof (char));
1627  map *req = getMap (request_inputs, "request");
1628  map *id = getMap (request_inputs, "identifier");
1629  map *di = getMap (request_inputs, "DataInputs");
1630
1631  // The required size for the dataInputsKVP and dataOutputsKVP buffers
1632  // may exceed cgiContentLength, hence a 2 kb extension. However, a
1633  // better solution would be to have getMapsAsKVP() determine the required
1634  // buffer size before allocating memory.     
1635  char *dataInputsKVP = getMapsAsKVP (inputs, cgiContentLength + 2048, 0);
1636  char *dataOutputsKVP = getMapsAsKVP (outputs, cgiContentLength + 2048, 1);
1637#ifdef DEBUG
1638  fprintf (stderr, "DATAINPUTSKVP %s\n", dataInputsKVP);
1639  fprintf (stderr, "DATAOUTPUTSKVP %s\n", dataOutputsKVP);
1640#endif
1641  map *sid = getMapFromMaps (m, "lenv", "osid");
1642  map *usid = getMapFromMaps (m, "lenv", "usid");
1643  map *r_inputs = getMapFromMaps (m, "main", "tmpPath");
1644  map *r_inputs1 = getMap (request_inputs, "metapath");
1645 
1646  int hasIn = -1;
1647  if (r_inputs1 == NULL)
1648    {
1649      r_inputs1 = createMap ("metapath", "");
1650      hasIn = 1;
1651    }
1652  map *r_inputs2 = getMap (request_inputs, "ResponseDocument");
1653  if (r_inputs2 == NULL)
1654    r_inputs2 = getMap (request_inputs, "RawDataOutput");
1655  map *tmpPath = getMapFromMaps (m, "lenv", "cwd");
1656
1657  map *tmpReq = getMap (request_inputs, "xrequest");
1658
1659  if(r_inputs2 != NULL && tmpReq != NULL) {
1660    const char key[] = "rfile=";
1661    char* kvp = (char*) malloc((FILENAME_MAX + strlen(key))*sizeof(char));
1662    char* filepath = kvp + strlen(key);
1663    strncpy(kvp, key, strlen(key));
1664    addToCache(m, tmpReq->value, tmpReq->value, "text/xml", strlen(tmpReq->value), 
1665               filepath, FILENAME_MAX);
1666    if (filepath == NULL) {
1667      errorException( m, _("Unable to cache HTTP POST Execute request."), "InternalError", NULL); 
1668      return;
1669    }   
1670    sprintf(tmp,"\"metapath=%s&%s&cgiSid=%s&usid=%s\"",
1671            r_inputs1->value,kvp,sid->value,usid->value);
1672    sprintf(tmpq,"metapath=%s&%s",
1673            r_inputs1->value,kvp);
1674    free(kvp); 
1675  }
1676  else if (r_inputs2 != NULL)
1677    {
1678      sprintf (tmp,
1679               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s&cgiSid=%s&usid=%s\"",
1680               r_inputs1->value, req->value, id->value, dataInputsKVP,
1681               r_inputs2->name, dataOutputsKVP, sid->value, usid->value);
1682      sprintf (tmpq,
1683               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&%s=%s",
1684               r_inputs1->value, req->value, id->value, dataInputsKVP,
1685               r_inputs2->name, dataOutputsKVP);                   
1686    }
1687  else
1688    {
1689      sprintf (tmp,
1690               "\"metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s&cgiSid=%s&usid=%s\"",
1691               r_inputs1->value, req->value, id->value, dataInputsKVP,
1692               sid->value, usid->value);
1693      sprintf (tmpq,
1694               "metapath=%s&request=%s&service=WPS&version=1.0.0&Identifier=%s&DataInputs=%s",
1695               r_inputs1->value, req->value, id->value, dataInputsKVP,
1696               sid->value);   
1697    }
1698
1699  if (hasIn > 0)
1700    {
1701      freeMap (&r_inputs1);
1702      free (r_inputs1);
1703    }
1704  char *tmp1 = zStrdup (tmp);
1705  sprintf (tmp, "\"%s\" %s \"%s\"", PROGRAMNAME, tmp1, sid->value); 
1706  free (dataInputsKVP);
1707  free (dataOutputsKVP);
1708#ifdef DEBUG
1709  fprintf (stderr, "REQUEST IS : %s \n", tmp);
1710#endif
1711
1712  usid = getMapFromMaps (m, "lenv", "usid");
1713  if (usid != NULL && usid->value != NULL) {
1714    SetEnvironmentVariable("USID", TEXT (usid->value));
1715  }
1716  SetEnvironmentVariable ("CGISID", TEXT (sid->value));
1717  SetEnvironmentVariable ("QUERY_STRING", TEXT (tmpq));
1718  // knut: Prevent REQUEST_METHOD=POST in background process call to cgic:main
1719  // (process hangs when reading cgiIn):
1720  SetEnvironmentVariable("REQUEST_METHOD", "GET");
1721  SetEnvironmentVariable("CONTENT_TYPE", "text/plain");
1722 
1723  char clen[1000];
1724  sprintf (clen, "%d", strlen (tmpq));
1725  SetEnvironmentVariable ("CONTENT_LENGTH", TEXT (clen));
1726
1727  // ref. https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863%28v=vs.85%29.aspx
1728  if (!CreateProcess (NULL,     // No module name (use command line)
1729                      TEXT (tmp),       // Command line
1730                      NULL,     // Process handle not inheritable
1731                      NULL,     // Thread handle not inheritable
1732                      FALSE,    // Set handle inheritance to FALSE
1733                      CREATE_NO_WINDOW, // Apache won't wait until the end
1734                      NULL,     // Use parent's environment block
1735                      NULL,     // Use parent's starting directory
1736                      &si,      // Pointer to STARTUPINFO struct
1737                      &pi)      // Pointer to PROCESS_INFORMATION struct
1738    )
1739    {
1740#ifdef DEBUG
1741      fprintf (stderr, "CreateProcess failed (%d).\n", GetLastError ());
1742#endif
1743      if (tmp != NULL) {
1744        free(tmp);
1745      }
1746      if (tmpq != NULL) {
1747        free(tmpq);
1748      }         
1749      return;
1750    }
1751  else
1752    {
1753#ifdef DEBUG
1754      fprintf (stderr, "CreateProcess successful (%d).\n\n\n\n",
1755               GetLastError ());
1756#endif
1757    }
1758  CloseHandle (pi.hProcess);
1759  CloseHandle (pi.hThread);
1760 
1761  if (tmp != NULL) {
1762    free(tmp);
1763  }
1764  if (tmpq != NULL) {
1765    free(tmpq);
1766  }
1767 
1768#ifdef DEBUG
1769  fprintf (stderr, "CreateProcess finished !\n");
1770#endif
1771}
1772#endif
1773
1774/**
1775 * Process the request.
1776 *
1777 * @param inputs the request parameters map
1778 * @return 0 on sucess, other value on failure
1779 * @see conf_read,recursReaddirF
1780 */
1781int
1782runRequest (map ** inputs)
1783{
1784 
1785#ifndef USE_GDB
1786#ifndef WIN32
1787  signal (SIGCHLD, SIG_IGN);
1788#endif 
1789  signal (SIGSEGV, sig_handler);
1790  signal (SIGTERM, sig_handler);
1791  signal (SIGINT, sig_handler);
1792  signal (SIGILL, sig_handler);
1793  signal (SIGFPE, sig_handler);
1794  signal (SIGABRT, sig_handler);
1795#endif
1796
1797 
1798  map *r_inputs = NULL;
1799  map *request_inputs = *inputs;
1800#ifdef IGNORE_METAPATH
1801  addToMap(request_inputs, "metapath", "");
1802#endif 
1803  maps *m = NULL;
1804  char *REQUEST = NULL;
1805  /**
1806   * Parsing service specfic configuration file
1807   */
1808  m = (maps *) malloc (MAPS_SIZE);
1809  if (m == NULL)
1810    {
1811      return errorException (NULL, _("Unable to allocate memory"),
1812                             "InternalError", NULL);
1813    }
1814  m->child=NULL;
1815  char ntmp[1024];
1816#ifndef ETC_DIR
1817#ifndef WIN32
1818  getcwd (ntmp, 1024);
1819#else
1820  _getcwd (ntmp, 1024);
1821#endif
1822#else
1823  sprintf(ntmp,"%s",ETC_DIR);
1824#endif
1825  r_inputs = getMapOrFill (&request_inputs, "metapath", "");
1826
1827  char conf_file[10240];
1828  snprintf (conf_file, 10240, "%s/%s/main.cfg", ntmp, r_inputs->value);
1829  if (conf_read (conf_file, m) == 2)
1830    {
1831      errorException (NULL, _("Unable to load the main.cfg file."),
1832                      "InternalError", NULL);
1833      free (m);
1834      return 1;
1835    }
1836#ifdef DEBUG
1837  fprintf (stderr, "***** BEGIN MAPS\n");
1838  dumpMaps (m);
1839  fprintf (stderr, "***** END MAPS\n");
1840#endif
1841
1842  map *getPath = getMapFromMaps (m, "main", "gettextPath");
1843  if (getPath != NULL)
1844    {
1845      bindtextdomain ("zoo-kernel", getPath->value);
1846      bindtextdomain ("zoo-services", getPath->value);
1847    }
1848  else
1849    {
1850      bindtextdomain ("zoo-kernel", LOCALEDIR);
1851      bindtextdomain ("zoo-services", LOCALEDIR);
1852    }
1853
1854  /**
1855   * Manage our own error log file (usefull to separate standard apache debug
1856   * messages from the ZOO-Kernel ones but also for IIS users to avoid wrong
1857   * headers messages returned by the CGI due to wrong redirection of stderr)
1858   */
1859  FILE *fstde = NULL;
1860  map *fstdem = getMapFromMaps (m, "main", "logPath");
1861  if (fstdem != NULL)
1862    fstde = freopen (fstdem->value, "a+", stderr);
1863
1864  /**
1865   * Language gesture
1866   */
1867  r_inputs = getMap (request_inputs, "language");
1868  if (r_inputs == NULL)
1869    r_inputs = getMap (request_inputs, "AcceptLanguages");
1870  if (r_inputs == NULL)
1871    r_inputs = getMapFromMaps (m, "main", "language");
1872  if (r_inputs != NULL)
1873    {
1874      if (isValidLang (m, r_inputs->value) < 0)
1875        {
1876          char tmp[1024];
1877          sprintf (tmp,
1878                   _
1879                   ("The value %s is not supported for the <language> parameter"),
1880                   r_inputs->value);
1881          errorException (m, tmp, "InvalidParameterValue", "language");
1882          freeMaps (&m);
1883          free (m);
1884          free (REQUEST);
1885          return 1;
1886
1887        }
1888      char *tmp = zStrdup (r_inputs->value);
1889      setMapInMaps (m, "main", "language", tmp);
1890#ifdef DEB
1891      char tmp2[12];
1892      sprintf (tmp2, "%s.utf-8", tmp);
1893      translateChar (tmp2, '-', '_');
1894      setlocale (LC_ALL, tmp2);
1895#else
1896      translateChar (tmp, '-', '_');
1897      setlocale (LC_ALL, tmp);
1898#endif
1899#ifndef WIN32
1900      setenv ("LC_ALL", tmp, 1);
1901#else
1902      char tmp1[13];
1903      sprintf (tmp1, "LC_ALL=%s", tmp);
1904      _putenv (tmp1);
1905#endif
1906      free (tmp);
1907    }
1908  else
1909    {
1910      setlocale (LC_ALL, "en_US");
1911#ifndef WIN32
1912      setenv ("LC_ALL", "en_US", 1);
1913#else
1914      char tmp1[13];
1915      sprintf (tmp1, "LC_ALL=en_US");
1916      _putenv (tmp1);
1917#endif
1918      setMapInMaps (m, "main", "language", "en-US");
1919    }
1920  setlocale (LC_NUMERIC, "C");
1921#ifndef WIN32
1922  setenv ("LC_NUMERIC", "C", 1);
1923#else
1924  char tmp1[17];
1925  sprintf (tmp1, "LC_NUMERIC=C");
1926  _putenv (tmp1);
1927#endif
1928  bind_textdomain_codeset ("zoo-kernel", "UTF-8");
1929  textdomain ("zoo-kernel");
1930  bind_textdomain_codeset ("zoo-services", "UTF-8");
1931  textdomain ("zoo-services");
1932
1933  map *lsoap = getMap (request_inputs, "soap");
1934  if (lsoap != NULL && strcasecmp (lsoap->value, "true") == 0)
1935    setMapInMaps (m, "main", "isSoap", "true");
1936  else
1937    setMapInMaps (m, "main", "isSoap", "false");
1938
1939  if(strlen(cgiServerName)>0)
1940    {
1941      char tmpUrl[1024];
1942       
1943      if ( getenv("HTTPS") != NULL && strncmp(getenv("HTTPS"), "on", 2) == 0 ) {
1944        // Knut: check if non-empty instead of "on"?           
1945        if ( strncmp(cgiServerPort, "443", 3) == 0 ) { 
1946          sprintf(tmpUrl, "https://%s%s", cgiServerName, cgiScriptName);
1947        }
1948        else {
1949          sprintf(tmpUrl, "https://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1950        }
1951      }
1952      else {
1953        if ( strncmp(cgiServerPort, "80", 2) == 0 ) { 
1954          sprintf(tmpUrl, "http://%s%s", cgiServerName, cgiScriptName);
1955        }
1956        else {
1957          sprintf(tmpUrl, "http://%s:%s%s", cgiServerName, cgiServerPort, cgiScriptName);
1958        }
1959      }
1960#ifdef DEBUG
1961      fprintf(stderr,"*** %s ***\n",tmpUrl);
1962#endif
1963      if(getMapFromMaps(m,"main","proxied")==NULL)
1964        setMapInMaps(m,"main","serverAddress",tmpUrl);
1965      else
1966        setMapInMaps(m,"lenv","serverAddress",tmpUrl);
1967    }
1968
1969  // CORS Support
1970  if(strncasecmp(cgiRequestMethod,"OPTIONS",7)==0){
1971    map* cors=getMapFromMaps(m,"main","cors");
1972    if(cors!=NULL && strncasecmp(cors->value,"true",4)==0){
1973      char *encoding=getEncoding(m);
1974      printHeaders(m);
1975      printf("Content-Type: text/plain; charset=%s\r\nStatus: 200 OK\r\n\r\n",encoding);
1976      printf(_("CORS is enabled.\r\n"));
1977      freeMaps (&m);
1978      free (m);
1979      fflush (stdout);
1980      return 3;
1981    }
1982  }
1983
1984  // Populate the Registry
1985  char conf_dir[1024];
1986  int t;
1987  char tmps1[1024];
1988  r_inputs = NULL;
1989  r_inputs = getMap (request_inputs, "metapath");
1990  map* cwdMap0=getMapFromMaps(m,"main","servicePath");
1991  if (r_inputs != NULL)
1992    if(cwdMap0!=NULL)
1993      snprintf (conf_dir, 1024, "%s/%s", cwdMap0->value, r_inputs->value);
1994    else
1995      snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
1996  else
1997    if(cwdMap0!=NULL)
1998      snprintf (conf_dir, 1024, "%s", cwdMap0->value);
1999    else
2000      snprintf (conf_dir, 1024, "%s", ntmp);
2001  map* reg = getMapFromMaps (m, "main", "registry");
2002  registry* zooRegistry=NULL;
2003  if(reg!=NULL){
2004#ifndef WIN32
2005    int saved_stdout = zDup (fileno (stdout));
2006    zDup2 (fileno (stderr), fileno (stdout));
2007#endif
2008    if(createRegistry (m,&zooRegistry,reg->value)<0){
2009      map *message=getMapFromMaps(m,"lenv","message");
2010      map *type=getMapFromMaps(m,"lenv","type");
2011#ifndef WIN32
2012      zDup2 (saved_stdout, fileno (stdout));
2013#endif
2014      errorException (m, message->value,
2015                      type->value, NULL);
2016      return 0;
2017    }
2018#ifndef WIN32
2019    zDup2 (saved_stdout, fileno (stdout));
2020    zClose(saved_stdout);
2021#endif
2022  }
2023
2024  int eres = SERVICE_STARTED;
2025  int cpid = zGetpid ();
2026  maps* bmap=NULL;
2027  char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
2028  FILE *f0, *f1;
2029  HINTERNET hInternet;
2030  service *s1=NULL;
2031  maps *request_output_real_format = NULL;
2032  maps *request_input_real_format = NULL;
2033
2034  setMapInMaps(m,"main","executionType","xml");
2035  if((strlen(cgiQueryString)>0 && cgiQueryString[0]=='/') /*&& strstr(cgiAccept,"json")!=NULL*/){
2036    //
2037    // OGC API - Processes starts here
2038    //
2039#ifndef USE_JSON
2040    errorException (m, _("OGC API - Processes is not supported by this ZOO-Kernel, please contact the service provider."), "InternalError", NULL);
2041    return 1;
2042#else
2043#ifndef USE_GDB
2044#ifndef WIN32
2045    signal (SIGCHLD, SIG_IGN);
2046#endif 
2047    signal (SIGSEGV, json_sig_handler);
2048    signal (SIGTERM, json_sig_handler);
2049    signal (SIGINT, json_sig_handler);
2050    signal (SIGILL, json_sig_handler);
2051    signal (SIGFPE, json_sig_handler);
2052    signal (SIGABRT, json_sig_handler);
2053#endif
2054    setMapInMaps(m,"main","executionType","json");
2055    r_inputs = getMapOrFill (&request_inputs, "metapath", "");
2056    char conf_file1[10240];
2057    maps* m1 = (maps *) malloc (MAPS_SIZE);
2058    snprintf (conf_file1, 10240, "%s/%s/oas.cfg", ntmp, r_inputs->value);
2059    if (conf_read (conf_file1, m1) == 2)
2060      {
2061        errorException (NULL, _("Unable to load the oas.cfg file."),
2062                        "InternalError", NULL);
2063        free (m1);
2064        return 1;
2065      }
2066    addMapsToMaps(&m,m1);
2067    freeMaps(&m1);
2068    free(m1);
2069    map* pmTmp0=getMapFromMaps(m,"openapi","full_html_support");
2070    if(strstr(cgiQueryString,".html")==NULL && strstr(cgiAccept,"text/html")!=NULL && pmTmp0!=NULL && strncasecmp(pmTmp0->value,"true",4)==0){
2071      map* pmTmpUrl=getMapFromMaps(m,"openapi","rootUrl");
2072      char* pacTmpUrl=NULL;
2073      if(strcmp(cgiQueryString,"/")!=0){
2074        pacTmpUrl=(char*)malloc((strlen(cgiQueryString)+strlen(pmTmpUrl->value)+6)*sizeof(char));
2075        sprintf(pacTmpUrl,"%s%s.html",pmTmpUrl->value,cgiQueryString);
2076      }
2077      else{
2078        pacTmpUrl=(char*)malloc((strlen(pmTmpUrl->value)+6)*sizeof(char));
2079        sprintf(pacTmpUrl,"%s/index.html",pmTmpUrl->value);
2080      }
2081      setMapInMaps(m,"headers","Location",pacTmpUrl);
2082      printHeaders(m);
2083      printf("Status: 302 Moved permanently \r\n\r\n");
2084      fflush(stdout);
2085      free(pacTmpUrl);
2086      return 1;
2087    }
2088    json_object *res=json_object_new_object();
2089    setMapInMaps(m,"headers","Content-Type","application/json;charset=UTF-8");
2090    /* - Root url */
2091    if((strncasecmp(cgiRequestMethod,"post",4)==0 &&
2092        (strstr(cgiQueryString,"/processes/")==NULL ||
2093         strlen(cgiQueryString)<=11))
2094       ||
2095       (strncasecmp(cgiRequestMethod,"DELETE",6)==0 &&
2096        (strstr(cgiQueryString,"/jobs/")==NULL || strlen(cgiQueryString)<=6)) ){
2097      setMapInMaps(m,"lenv","status_code","405");
2098      map* error=createMap("code","InvalidMethod");
2099      addToMap(error,"message",_("The request method used to access the current path is not supported."));
2100      printExceptionReportResponseJ(m,error);
2101      json_object_put(res);
2102      // TODO: cleanup memory
2103      return 1;
2104    }
2105    else if(cgiContentLength==1){
2106      if(strncasecmp(cgiRequestMethod,"GET",3)!=0){
2107        setMapInMaps(m,"lenv","status_code","405");
2108        map* pamError=createMap("code","InvalidMethod");
2109        const char* pccErr=_("This API does not support the method.");
2110        addToMap(pamError,"message",pccErr);
2111        printExceptionReportResponseJ(m,pamError);
2112        // TODO: cleanup memory
2113        return 1;
2114      }
2115      map* tmpMap=getMapFromMaps(m,"main","serverAddress");
2116      json_object *res1=json_object_new_array();
2117
2118      map* pmVal=getMapFromMaps(m,"openapi","links");
2119      char *orig=zStrdup(pmVal->value);
2120      char *saveptr;
2121      char *tmps = strtok_r (orig, ",", &saveptr);
2122      map* tmpUrl=getMapFromMaps(m,"openapi","rootUrl");
2123      while(tmps!=NULL){
2124        maps* tmpMaps=getMaps(m,tmps);
2125        if(tmpMaps!=NULL){
2126          json_object *res2;
2127          res2=mapToJson(tmpMaps->content);
2128          char* tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(tmps)+2)*sizeof(char));
2129          sprintf(tmpStr,"%s%s",tmpUrl->value,tmps);
2130          json_object_object_add(res2,"href",json_object_new_string(tmpStr));
2131          free(tmpStr);
2132          json_object_array_add(res1,res2);
2133
2134          map* pmTmp=getMap(tmpMaps->content,"title");
2135          char *pacTitle=NULL;
2136          if(pmTmp!=NULL)
2137            pacTitle=zStrdup(pmTmp->value);
2138          char* pacTmp=(char*) malloc((strlen(tmps)+6)*sizeof(char));
2139          sprintf(pacTmp,"%s.html",tmps);
2140          tmpMaps=getMaps(m,pacTmp);
2141          if(tmpMaps==NULL && strncasecmp(pacTmp,"/.html",6)==0)
2142            tmpMaps=getMaps(m,"/index.html");
2143          if(tmpMaps!=NULL){
2144            json_object *res3;
2145            res3=mapToJson(tmpMaps->content);
2146            if(getMap(tmpMaps->content,"title")==NULL && pacTitle!=NULL){
2147              json_object_object_add(res3,"title",json_object_new_string(pacTitle));
2148            }
2149            char* tmpStr=NULL;
2150            if(strncasecmp(pacTmp,"/.html",6)==0){
2151              tmpStr=(char*) malloc((strlen(tmpUrl->value)+12)*sizeof(char));
2152              sprintf(tmpStr,"%s/index.html",tmpUrl->value);
2153            }else{map* tmpUrl=getMapFromMaps(m,"openapi","rootUrl");
2154              tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(tmps)+6)*sizeof(char));
2155              sprintf(tmpStr,"%s%s.html",tmpUrl->value,tmps);
2156            }
2157            json_object_object_add(res3,"href",json_object_new_string(tmpStr));
2158            free(tmpStr);
2159            json_object_array_add(res1,res3);
2160          }
2161          free(pacTmp);
2162          if(pacTitle!=NULL)
2163            free(pacTitle);       
2164        }
2165        tmps = strtok_r (NULL, ",", &saveptr);
2166      }
2167      free(orig);
2168     
2169      map* pmTmp=getMapFromMaps(m,"identification","title");
2170      if(pmTmp!=NULL)
2171        json_object_object_add(res,"title",json_object_new_string(pmTmp->value));
2172      pmTmp=getMapFromMaps(m,"identification","abstract");
2173      if(pmTmp!=NULL)
2174        json_object_object_add(res,"description",json_object_new_string(pmTmp->value));
2175      json_object_object_add(res,"links",res1);
2176    }else if(strcmp(cgiQueryString,"/conformance")==0){
2177      /* - /conformance url */
2178      map* rootUrl=getMapFromMaps(m,"conformsTo","rootUrl");
2179      json_object *res1=json_object_new_array();
2180      map* length=getMapFromMaps(m,"conformsTo","length");
2181      maps* tmpMaps=getMaps(m,"conformsTo");
2182      for(int kk=0;kk<atoi(length->value);kk++){
2183        map* tmpMap1=getMapArray(tmpMaps->content,"link",kk);
2184        json_object *res2;
2185        if(tmpMap1!=NULL){
2186          char* tmpStr=(char*) malloc((strlen(rootUrl->value)+strlen(tmpMap1->value)+1)*sizeof(char));
2187          sprintf(tmpStr,"%s%s",rootUrl->value,tmpMap1->value);
2188          json_object_array_add(res1,json_object_new_string(tmpStr));
2189        }
2190      }
2191      json_object_object_add(res,"conformsTo",res1);
2192    }else if(strncasecmp(cgiQueryString,"/api",4)==0){
2193      if(strstr(cgiQueryString,".html")==NULL)
2194        produceApi(m,res);
2195      else{     
2196        char* pacTmp=(char*)malloc(9*sizeof(char));
2197        sprintf(pacTmp,"%s",cgiQueryString+1);
2198        map* pmTmp=getMapFromMaps(m,pacTmp,"href");
2199        free(pacTmp);
2200        if(pmTmp!=NULL)
2201          setMapInMaps(m,"headers","Location",pmTmp->value);
2202      } 
2203    }else if(strcmp(cgiQueryString,"/processes")==0 || strcmp(cgiQueryString,"/processes/")==0){
2204      /* - /processes */
2205      setMapInMaps(m,"lenv","requestType","desc");
2206      json_object *res3=json_object_new_array();
2207      int saved_stdout = zDup (fileno (stdout));
2208      zDup2 (fileno (stderr), fileno (stdout));
2209      if (int res0 =             
2210          recursReaddirF (m, NULL, res3, NULL, ntmp, NULL, saved_stdout, 0,
2211                          printGetCapabilitiesForProcessJ) < 0)
2212        {
2213        }     
2214      zDup2 (saved_stdout, fileno (stdout));
2215      zClose(saved_stdout);
2216      res=res3;
2217      //json_object_object_add(res,"processes",res3);
2218    }
2219    else if(strstr(cgiQueryString,"/processes")==NULL && (strstr(cgiQueryString,"/jobs")!=NULL || strstr(cgiQueryString,"/jobs/")!=NULL)){
2220      /* - /jobs url */
2221      if(strncasecmp(cgiRequestMethod,"DELETE",6)==0) {
2222        char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2223        setMapInMaps(m,"lenv","gs_usid",jobId);
2224        setMapInMaps(m,"lenv","file.statusFile",json_getStatusFilePath(m));
2225        runDismiss(m,jobId);
2226        map* pmError=getMapFromMaps(m,"lenv","error");
2227        if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
2228          printExceptionReportResponseJ(m,getMapFromMaps(m,"lenv","code"));
2229          return 1;
2230        }
2231        else{
2232          setMapInMaps(m,"lenv","gs_location","false");
2233          res=createStatus(m,SERVICE_DISMISSED);
2234        }
2235      }
2236      else if(strcasecmp(cgiRequestMethod,"get")==0){
2237        /* - /jobs List (GET) */
2238        if(strlen(cgiQueryString)<=6)
2239          res=printJobList(m);
2240        else{
2241
2242         
2243          char* tmpUrl=strstr(cgiQueryString,"/jobs/");
2244          if(tmpUrl!=NULL && strlen(tmpUrl)>6){
2245            if(strncasecmp(cgiRequestMethod,"DELETE",6)==0){
2246              char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2247              setMapInMaps(m,"lenv","gs_usid",jobId);
2248              setMapInMaps(m,"lenv","file.statusFile",json_getStatusFilePath(m));
2249              runDismiss(m,jobId);
2250              map* pmError=getMapFromMaps(m,"lenv","error");
2251              if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
2252                printExceptionReportResponseJ(m,getMapFromMaps(m,"lenv","code"));
2253                return 1;
2254              }
2255              else{
2256                setMapInMaps(m,"lenv","gs_location","false");
2257                res=createStatus(m,SERVICE_DISMISSED);
2258              }
2259            }else{
2260              char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2261              if(strlen(jobId)==36){
2262                res=printJobStatus(m,jobId);
2263              }else{
2264
2265                // In case the service has run, then forward request to target result file
2266                //char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
2267                jobId[strlen(jobId)-8]=0;
2268                char *sid=getStatusId(m,jobId);
2269                if(sid==NULL){
2270                  map* error=createMap("code","NoSuchJob");
2271                  addToMap(error,"message",_("The JobID from the request does not match any of the Jobs running on this server"));
2272                  printExceptionReportResponseJ(m,error);
2273                  return 1;
2274                }else{
2275                  if(isRunning(m,jobId)>0){
2276                    map* error=createMap("code","ResultNotReady");
2277                    addToMap(error,"message",_("The job is still running."));
2278                    printExceptionReportResponseJ(m,error);
2279                    return 1;
2280                  }else{
2281                    char *Url0=getResultPath(m,jobId);
2282                    zStatStruct f_status;
2283                    int s=zStat(Url0, &f_status);
2284                    if(s==0 && f_status.st_size>0){
2285                      if(f_status.st_size>15){
2286                        json_object* pjoTmp=json_readFile(m,Url0);
2287                        json_object* pjoCode=NULL;
2288                        json_object* pjoMessage=NULL;
2289                        if(pjoTmp!=NULL &&
2290                           json_object_object_get_ex(pjoTmp,"code",&pjoCode)!=FALSE &&
2291                           json_object_object_get_ex(pjoTmp,"description",&pjoMessage)!=FALSE){
2292                          map* error=createMap("code",json_object_get_string(pjoCode));
2293                          addToMap(error,"message",json_object_get_string(pjoMessage));
2294                          printExceptionReportResponseJ(m,error);
2295                          return 1;                     
2296                        }else{
2297
2298                          map* tmpPath = getMapFromMaps (m, "main", "tmpUrl");
2299                          Url0=(char*) realloc(Url0,(strlen(tmpPath->value)+
2300                                                     //strlen(cIdentifier->value)+
2301                                                     strlen(jobId)+8)*sizeof(char));
2302                          sprintf(Url0,"%s/%s.json",tmpPath->value,jobId);
2303                          setMapInMaps(m,"headers","Location",Url0);
2304                        }
2305                        free(Url0);
2306                      }else{
2307                        // Service Failed
2308                        map* statusInfo=createMap("JobID",jobId);
2309                        readFinalRes(m,jobId,statusInfo);
2310                        {
2311                          map* pmStatus=getMap(statusInfo,"status");
2312                          if(pmStatus!=NULL)
2313                            setMapInMaps(m,"lenv","status",pmStatus->value);
2314                        }
2315                        char* tmpStr=_getStatus(m,jobId);
2316                        if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
2317                          char *tmpStr1=zStrdup(tmpStr);
2318                          char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
2319                          free(tmpStr);
2320                          tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
2321                          addToMap(statusInfo,"PercentCompleted",tmpStr1);
2322                          addToMap(statusInfo,"Message",tmpStr0);
2323                          setMapInMaps(m,"lenv","PercentCompleted",tmpStr1);
2324                          setMapInMaps(m,"lenv","Message",tmpStr0);
2325                          free(tmpStr0);
2326                          free(tmpStr1);
2327                        }
2328                        map* error=createMap("code","NoApplicableCode");
2329                        addToMap(error,"message",_("The service failed to execute."));
2330                        printExceptionReportResponseJ(m,error);
2331                        return 1;
2332                      }
2333
2334                    }else{
2335                      map* error=createMap("code","NoSuchJob");
2336                      addToMap(error,"message",_("The JobID seem to be running on this server but not for this process id"));
2337                      printExceptionReportResponseJ(m,error);
2338                      return 1;
2339                    }
2340                  }
2341                }
2342
2343               
2344              }
2345              free(jobId);
2346            }
2347          }
2348        }
2349         
2350      }   
2351    }
2352    else{
2353      service* s1=NULL;
2354      int t=0;
2355      if(strstr(cgiQueryString,"/processes/")==NULL){
2356        map* error=createMap("code","BadRequest");
2357        addToMap(error,"message",_("The ressource is not available"));
2358        //setMapInMaps(conf,"lenv","status_code","404 Bad Request");
2359        printExceptionReportResponseJ(m,error);
2360        freeMaps (&m);
2361        free (m);
2362        free (REQUEST);
2363        xmlCleanupParser ();
2364        zooXmlCleanupNs ();                     
2365        return 1;
2366      }else if(strcasecmp(cgiRequestMethod,"post")==0){
2367        /* - /processes/{processId} Execution (POST) */
2368        eres = SERVICE_STARTED;
2369        initAllEnvironment(m,request_inputs,ntmp,"jrequest");
2370        map* req=getMapFromMaps(m,"renv","jrequest");
2371        json_object *jobj = NULL;
2372        const char *mystring = NULL;
2373        int slen = 0;
2374        enum json_tokener_error jerr;
2375        struct json_tokener* tok=json_tokener_new();
2376        do {
2377          mystring = req->value;  // get JSON string, e.g. read from file, etc...
2378          slen = strlen(mystring);
2379          jobj = json_tokener_parse_ex(tok, mystring, slen);
2380        } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
2381        if (jerr != json_tokener_success) {
2382          map* pamError=createMap("code","InvalidParameterValue");
2383          const char* pcTmpErr=json_tokener_error_desc(jerr);
2384          const char* pccErr=_("ZOO-Kernel cannot parse your POST data: %s");
2385          char* pacMessage=(char*)malloc((strlen(pcTmpErr)+strlen(pccErr)+1)*sizeof(char));
2386          sprintf(pacMessage,pccErr,pcTmpErr);
2387          addToMap(pamError,"message",pacMessage);
2388          printExceptionReportResponseJ(m,pamError);
2389          fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
2390          return 1;
2391        }
2392        if (tok->char_offset < slen){
2393          map* pamError=createMap("code","InvalidParameterValue");
2394          const char* pcTmpErr="None";
2395          const char* pccErr=_("ZOO-Kernel cannot parse your POST data: %s");
2396          char* pacMessage=(char*)malloc((strlen(pcTmpErr)+strlen(pccErr)+1)*sizeof(char));
2397          sprintf(pacMessage,pccErr,pcTmpErr);
2398          addToMap(pamError,"message",pacMessage);
2399          printExceptionReportResponseJ(m,pamError);
2400          fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
2401          return 1;
2402        }
2403
2404        json_object* json_io=NULL;
2405        char* cIdentifier=NULL;
2406        if(json_object_object_get_ex(jobj,"id",&json_io)!=FALSE){
2407          cIdentifier=zStrdup(json_object_get_string(json_io));
2408        }else{
2409          if(strstr(cgiQueryString,"/processes/")!=NULL && strlen(cgiQueryString)>11)
2410            cIdentifier=zStrdup(strstr(cgiQueryString,"/processes/")+11);         
2411        }
2412        fetchService(zooRegistry,m,&s1,request_inputs,ntmp,cIdentifier,printExceptionReportResponseJ);
2413        parseJRequest(m,s1,jobj,request_inputs,&request_input_real_format,&request_output_real_format);
2414        map* preference=getMapFromMaps(m,"renv","HTTP_PREFER");
2415        map* mode=getMap(request_inputs,"mode");
2416        if((preference!=NULL && strcasecmp(preference->value,"respond-async")==0) ||
2417           (mode!=NULL && strncasecmp(mode->value,"async",5)==0)) {
2418          int pid;
2419#ifdef DEBUG
2420          fprintf (stderr, "\nPID : %d\n", cpid);
2421#endif
2422#ifndef WIN32
2423          pid = fork ();
2424#else
2425          if (cgiSid == NULL)
2426            {
2427              createProcess (m, request_inputs, s1, NULL, cpid,
2428                             request_input_real_format,
2429                             request_output_real_format);
2430              pid = cpid;
2431            }
2432          else
2433            {
2434              pid = 0;
2435              cpid = atoi (cgiSid);
2436              updateStatus(m,0,_("Initializing"));
2437            }
2438#endif
2439          if (pid > 0)
2440            {
2441              //
2442              // dady :
2443              // set status to SERVICE_ACCEPTED
2444              //
2445#ifdef DEBUG
2446              fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
2447                       zGetpid ());
2448#endif
2449              eres = SERVICE_ACCEPTED;
2450              createStatusFile(m,eres);
2451              //invokeBasicCallback(m,SERVICE_ACCEPTED);
2452              printHeaders(m);
2453              printf("Status: 201 Created \r\n\r\n");
2454              return 1;
2455            }
2456          else if (pid == 0)
2457            {
2458              eres = SERVICE_STARTED;
2459              //
2460              // son : have to close the stdout, stdin and stderr to let the parent
2461              // process answer to http client.
2462              //
2463              map* oid = getMapFromMaps (m, "lenv", "oIdentifier");
2464              map* usid = getMapFromMaps (m, "lenv", "uusid");
2465              map* tmpm = getMapFromMaps (m, "lenv", "osid");
2466              int cpid = atoi (tmpm->value);
2467              pid=cpid;
2468              r_inputs = getMapFromMaps (m, "main", "tmpPath");
2469              setMapInMaps (m, "lenv", "async","true");
2470              map* r_inputs1 = createMap("ServiceName", s1->name);
2471              // Create the filename for the result file (.res)
2472              fbkpres =
2473                (char *)
2474                malloc ((strlen (r_inputs->value) +
2475                         strlen (usid->value) + 7) * sizeof (char));                   
2476              sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
2477              bmap = createMaps("status");
2478              bmap->content=createMap("usid",usid->value);
2479              addToMap(bmap->content,"sid",tmpm->value);
2480              addIntToMap(bmap->content,"pid",zGetpid());
2481         
2482              // Create PID file referencing the OS process identifier
2483              fbkpid =
2484                (char *)
2485                malloc ((strlen (r_inputs->value) +
2486                         strlen (usid->value) + 7) * sizeof (char));
2487              sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
2488              setMapInMaps (m, "lenv", "file.pid", fbkpid);
2489
2490              f0 = freopen (fbkpid, "w+",stdout);
2491              printf("%d",zGetpid());
2492              fflush(stdout);
2493
2494              // Create SID file referencing the semaphore name
2495              fbkp =
2496                (char *)
2497                malloc ((strlen (r_inputs->value) + strlen (oid->value) +
2498                         strlen (usid->value) + 7) * sizeof (char));
2499              sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
2500              setMapInMaps (m, "lenv", "file.sid", fbkp);
2501              FILE* f2 = freopen (fbkp, "w+",stdout);
2502              printf("%s",tmpm->value);
2503              fflush(f2);
2504              free(fbkp);
2505
2506              fbkp =
2507                (char *)
2508                malloc ((strlen (r_inputs->value) + 
2509                         strlen (usid->value) + 7) * sizeof (char));
2510              sprintf (fbkp, "%s/%s.json", r_inputs->value, 
2511                       usid->value);
2512              setMapInMaps (m, "lenv", "file.responseInit", fbkp);
2513              flog =
2514                (char *)
2515                malloc ((strlen (r_inputs->value) + strlen (oid->value) +
2516                         strlen (usid->value) + 13) * sizeof (char));
2517              sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
2518                       oid->value, usid->value);
2519              setMapInMaps (m, "lenv", "file.log", flog);
2520#ifdef DEBUG
2521              fprintf (stderr, "RUN IN BACKGROUND MODE \n");
2522              fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
2523                       zGetpid ());
2524              fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
2525#endif
2526              freopen (flog, "w+", stderr);
2527              fflush (stderr);
2528              f0 = freopen (fbkp, "w+", stdout);
2529              rewind (stdout);
2530#ifndef WIN32
2531              fclose (stdin);
2532#endif
2533#ifdef RELY_ON_DB
2534              init_sql(m);
2535              recordServiceStatus(m);
2536#endif
2537#ifdef USE_CALLBACK
2538              invokeCallback(m,NULL,NULL,0,0);
2539#endif
2540              invokeBasicCallback(m,SERVICE_STARTED);
2541              createStatusFile(m,SERVICE_STARTED);
2542              fbkp1 =
2543                (char *)
2544                malloc ((strlen (r_inputs->value) + strlen (oid->value) +
2545                         strlen (usid->value) + 15) * sizeof (char));
2546              sprintf (fbkp1, "%s/%s_final_%s.json", r_inputs->value,
2547                       oid->value, usid->value);
2548              setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
2549
2550              f1 = freopen (fbkp1, "w+", stdout);
2551
2552              map* serviceTypeMap=getMap(s1->content,"serviceType");
2553              if(serviceTypeMap!=NULL)
2554                setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
2555
2556              char *flenv =
2557                (char *)
2558                malloc ((strlen (r_inputs->value) + 
2559                         strlen (usid->value) + 12) * sizeof (char));
2560              sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
2561              maps* lenvMaps=getMaps(m,"lenv");
2562              dumpMapsToFile(lenvMaps,flenv,1);
2563              free(flenv);
2564
2565              map* testMap=getMapFromMaps(m,"main","memory");
2566              loadHttpRequests(m,request_input_real_format);
2567
2568              if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,NULL)<0)
2569                return -1;
2570              loadServiceAndRun (&m, s1, request_inputs,
2571                                 &request_input_real_format,
2572                                 &request_output_real_format, &eres);
2573              setMapInMaps(m,"lenv","force","true");
2574              createStatusFile(m,eres);
2575              setMapInMaps(m,"lenv","force","false");
2576              setMapInMaps(m,"lenv","no-headers","true");
2577              fflush(stdout);
2578              rewind(stdout);
2579              res=printJResult(m,s1,request_output_real_format,eres);
2580              const char* jsonStr0=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
2581              if(getMapFromMaps(m,"lenv","jsonStr")==NULL)
2582                setMapInMaps(m,"lenv","jsonStr",jsonStr0);
2583              invokeBasicCallback(m,eres);
2584            }
2585        }else{
2586          loadHttpRequests(m,request_input_real_format);
2587          if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,NULL)<0)
2588            return -1;
2589          loadServiceAndRun (&m,s1,request_inputs,
2590                             &request_input_real_format,
2591                             &request_output_real_format,&eres);
2592          res=printJResult(m,s1,request_output_real_format,eres);
2593        }
2594
2595           
2596      }//else error
2597      else
2598        if(strstr(cgiQueryString,"/jobs")==NULL && strstr(cgiQueryString,"/jobs/")==NULL){
2599          /* - /processes/{id}/ */
2600          //DIR *dirp = opendir (ntmp);
2601          json_object *res3=json_object_new_object();
2602          char *orig = NULL;
2603          orig = zStrdup (strstr(cgiQueryString,"/processes/")+11);
2604          if(orig[strlen(orig)-1]=='/')
2605            orig[strlen(orig)-1]=0;
2606          json_object* res1=json_object_new_object();
2607          setMapInMaps(m,"lenv","requestType","GetCapabilities");
2608          int t=fetchServicesForDescription(NULL, m, orig,
2609                                            printGetCapabilitiesForProcessJ,
2610                                            NULL, (void*) res3, ntmp,
2611                                            request_inputs,
2612                                            printExceptionReportResponseJ);
2613          if(t==1){
2614            /*map* error=createMap("code","BadRequest");
2615              addToMap(error,"message",_("Failed to acces the requested service"));
2616              printExceptionReportResponseJ(m,error);*/
2617            return 1;
2618          }
2619          res=json_object_get(res3);
2620        }else{
2621          char* cIdentifier=NULL;
2622          if(strstr(cgiQueryString,"/processes/")!=NULL){
2623
2624           
2625            int len0=strlen(strstr(cgiQueryString,"/processes/")+11);
2626            int len1=strlen(cgiQueryString)-strlen(strstr(cgiQueryString,"/job"));
2627            cIdentifier=(char*)malloc((len1-10)*sizeof(char));
2628            int cnt=0;
2629            for(int j=11;j<len1;j++){
2630              cIdentifier[cnt]=cgiQueryString[j];
2631              cIdentifier[cnt+1]=0;
2632              cnt++;
2633            }
2634
2635            fetchService(zooRegistry,m,&s1,request_inputs,ntmp,cIdentifier,printExceptionReportResponseJ);
2636
2637
2638          }
2639
2640         
2641        }
2642
2643    }
2644    map* pmHasPrinted=getMapFromMaps(m,"lenv","hasPrinted");
2645    if(res!=NULL && (pmHasPrinted==NULL || strncasecmp(pmHasPrinted->value,"false",5)==0)){
2646      if(getMapFromMaps(m,"lenv","no-headers")==NULL){
2647        printHeaders(m);
2648        printf("Status: 200 OK \r\n\r\n");
2649      }
2650      const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
2651      printf(jsonStr);
2652      printf("\n");
2653      fflush(stdout);
2654      json_object_put(res);
2655    }
2656    //return 1;
2657#endif
2658  }else{
2659    //
2660    // WPS 1.0.0 and 2.0.0 starts here
2661    //
2662    setMapInMaps(m,"main","executionType","xml");
2663    //Check for minimum inputs
2664    map* version=getMap(request_inputs,"version");
2665    if(version==NULL)
2666      version=getMapFromMaps(m,"main","version");
2667    setMapInMaps(m,"main","rversion",version->value);
2668    int vid=getVersionId(version->value);
2669    if(vid<0)
2670      vid=0;
2671    map* err=NULL;
2672    const char **vvr=(const char**)requests[vid];
2673    checkValidValue(request_inputs,&err,"request",vvr,1);
2674    const char *vvs[]={
2675      "WPS",
2676      NULL
2677    };
2678    if(err!=NULL){
2679      checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
2680      printExceptionReportResponse (m, err);
2681      freeMap(&err);
2682      free(err);
2683      if (count (request_inputs) == 1)
2684        {
2685          freeMap (&request_inputs);
2686          free (request_inputs);
2687        }
2688      freeMaps (&m);
2689      free (m);
2690      return 1;
2691    }
2692    checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
2693
2694    const char *vvv[]={
2695      "1.0.0",
2696      "2.0.0",
2697      NULL
2698    };
2699    r_inputs = getMap (request_inputs, "Request");
2700    if(r_inputs!=NULL)
2701      REQUEST = zStrdup (r_inputs->value);
2702    int reqId=-1;
2703    if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
2704      checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
2705      int j=0;
2706      for(j=0;j<nbSupportedRequests;j++){
2707        if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
2708          if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
2709            checkValidValue(request_inputs,&err,"identifier",NULL,1);
2710            reqId=j+1;
2711            break;
2712          }
2713          else
2714            if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
2715               strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
2716              checkValidValue(request_inputs,&err,"jobid",NULL,1);
2717              reqId=j+1;
2718              break;
2719            }
2720        }else
2721          break;
2722      }
2723    }else{
2724      checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
2725      map* version1=getMap(request_inputs,"AcceptVersions");
2726      if(version1!=NULL){
2727        if(strstr(version1->value,schemas[1][0])!=NULL){
2728          addToMap(request_inputs,"version",schemas[1][0]);
2729          setMapInMaps(m,"main","rversion",schemas[1][0]);
2730        }
2731        else{
2732          addToMap(request_inputs,"version",version1->value);
2733          setMapInMaps(m,"main","rversion",version1->value);
2734        }
2735        version=getMap(request_inputs,"version");
2736      }
2737    }
2738    if(err!=NULL){
2739      printExceptionReportResponse (m, err);
2740      freeMap(&err);
2741      free(err);
2742      if (count (request_inputs) == 1)
2743        {
2744          freeMap (&request_inputs);
2745          free (request_inputs);
2746        }
2747      free(REQUEST);
2748      freeMaps (&m);
2749      free (m);
2750      return 1;
2751    }
2752
2753    r_inputs = getMap (request_inputs, "serviceprovider");
2754    if (r_inputs == NULL)
2755      {
2756        addToMap (request_inputs, "serviceprovider", "");
2757      }
2758
2759    map *tmpm = getMapFromMaps (m, "main", "serverAddress");
2760    if (tmpm != NULL)
2761      SERVICE_URL = zStrdup (tmpm->value);
2762    else
2763      SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
2764
2765
2766    int scount = 0;
2767#ifdef DEBUG
2768    dumpMap (r_inputs);
2769#endif
2770
2771    if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
2772      {
2773#ifdef DEBUG
2774        dumpMap (r_inputs);
2775#endif
2776        xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
2777        xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
2778        /**
2779         * Here we need to close stdout to ensure that unsupported chars
2780         * has been found in the zcfg and then printed on stdout
2781         */
2782        int saved_stdout = zDup (fileno (stdout));
2783        zDup2 (fileno (stderr), fileno (stdout));
2784
2785        maps* imports = getMaps(m, IMPORTSERVICE);
2786        if (imports != NULL) {       
2787          map* zcfg = imports->content;
2788       
2789          while (zcfg != NULL) {
2790            if (zcfg->value != NULL) {
2791              service* svc = (service*) malloc(SERVICE_SIZE);
2792              if (svc == NULL || readServiceFile(m, zcfg->value, &svc, zcfg->name) < 0) {
2793                // pass over silently
2794                zcfg = zcfg->next;
2795                continue;
2796              }
2797              inheritance(zooRegistry, &svc);
2798              printGetCapabilitiesForProcess(zooRegistry, m, doc, n, svc);
2799              freeService(&svc);
2800              free(svc);                             
2801            }
2802            zcfg = zcfg->next;
2803          }           
2804        }
2805
2806        if (int res =             
2807            recursReaddirF (m, zooRegistry, doc, n, conf_dir, NULL, saved_stdout, 0,
2808                            printGetCapabilitiesForProcess) < 0)
2809          {
2810            freeMaps (&m);
2811            free (m);
2812            if(zooRegistry!=NULL){
2813              freeRegistry(&zooRegistry);
2814              free(zooRegistry);
2815            }
2816            free (REQUEST);
2817            free (SERVICE_URL);
2818            fflush (stdout);
2819            return res;
2820          }
2821        fflush (stdout);
2822        zDup2 (saved_stdout, fileno (stdout));
2823#ifdef META_DB
2824        fetchServicesFromDb(zooRegistry,m,doc,n,printGetCapabilitiesForProcess,1);
2825        close_sql(m,0);
2826#endif     
2827        printDocument (m, doc, zGetpid ());
2828        freeMaps (&m);
2829        free (m);
2830        if(zooRegistry!=NULL){
2831          freeRegistry(&zooRegistry);
2832          free(zooRegistry);
2833        }
2834        free (REQUEST);
2835        free (SERVICE_URL);
2836        fflush (stdout);
2837        return 0;
2838      }
2839    else
2840      {
2841        r_inputs = getMap (request_inputs, "JobId");
2842        if(reqId>nbReqIdentifier){
2843          if (strncasecmp (REQUEST, "GetStatus", 9) == 0 ||
2844              strncasecmp (REQUEST, "GetResult", 9) == 0){
2845            runGetStatus(m,r_inputs->value,REQUEST);
2846#ifdef RELY_ON_DB
2847            map* dsNb=getMapFromMaps(m,"lenv","ds_nb");
2848            if(dsNb!=NULL && atoi(dsNb->value)>1)
2849              close_sql(m,1);
2850            close_sql(m,0);
2851#endif
2852         
2853            freeMaps (&m);
2854            free(m);
2855            if(zooRegistry!=NULL){
2856              freeRegistry(&zooRegistry);
2857              free(zooRegistry);
2858            }
2859            free (REQUEST);
2860            free (SERVICE_URL);
2861            return 0;
2862          }
2863          else
2864            if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
2865              runDismiss(m,r_inputs->value);
2866              freeMaps (&m);
2867              free (m);
2868              if(zooRegistry!=NULL){
2869                freeRegistry(&zooRegistry);
2870                free(zooRegistry);
2871              }
2872              free (REQUEST);
2873              free (SERVICE_URL);
2874              return 0;
2875           
2876            }
2877          return 0;
2878        }
2879        if(reqId<=nbReqIdentifier){
2880          r_inputs = getMap (request_inputs, "Identifier");
2881
2882          struct dirent *dp;
2883          DIR *dirp = opendir (conf_dir);
2884          if (dirp == NULL)
2885            {
2886              errorException (m, _("The specified path does not exist."),
2887                              "InternalError", NULL);
2888              freeMaps (&m);
2889              free (m);
2890              if(zooRegistry!=NULL){
2891                freeRegistry(&zooRegistry);
2892                free(zooRegistry);
2893              }
2894              free (REQUEST);
2895              free (SERVICE_URL);
2896              return 0;
2897            }
2898          if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
2899            {
2900              /**
2901               * Loop over Identifier list
2902               */
2903              xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
2904              r_inputs = NULL;
2905              r_inputs = getMap (request_inputs, "version");
2906#ifdef DEBUG
2907              fprintf(stderr," ** DEBUG %s %d \n",__FILE__,__LINE__);
2908              fflush(stderr);
2909#endif
2910              xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
2911                                            root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
2912
2913              r_inputs = getMap (request_inputs, "Identifier");
2914
2915              fetchServicesForDescription(zooRegistry, m, r_inputs->value,
2916                                          printDescribeProcessForProcess,
2917                                          (void*) doc, (void*) n, conf_dir,
2918                                          request_inputs,printExceptionReportResponse);
2919
2920              printDocument (m, doc, zGetpid ());
2921              freeMaps (&m);
2922              free (m);
2923              if(zooRegistry!=NULL){
2924                freeRegistry(&zooRegistry);
2925                free(zooRegistry);
2926              }
2927              free (REQUEST);
2928              free (SERVICE_URL);
2929              fflush (stdout);
2930#ifdef META_DB
2931              close_sql(m,0);
2932              //end_sql();
2933#endif
2934              return 0;
2935            }
2936          else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
2937            {
2938              map* version=getMapFromMaps(m,"main","rversion");
2939              int vid=getVersionId(version->value);         
2940              int len = 0;
2941              int j = 0;
2942              for(j=0;j<nbSupportedRequests;j++){
2943                if(requests[vid][j]!=NULL)
2944                  len+=strlen(requests[vid][j])+2;
2945                else{
2946                  len+=4;
2947                  break;
2948                }
2949              }
2950              char *tmpStr=(char*)malloc(len*sizeof(char));
2951              int it=0;
2952              for(j=0;j<nbSupportedRequests;j++){
2953                if(requests[vid][j]!=NULL){
2954                  if(it==0){
2955                    sprintf(tmpStr,"%s",requests[vid][j]);
2956                    it++;
2957                  }else{
2958                    char *tmpS=zStrdup(tmpStr);
2959                    if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
2960                      sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
2961                    }else{
2962                      sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
2963                 
2964                    }
2965                    free(tmpS);
2966                  }
2967                }
2968                else{
2969                  len+=4;
2970                  break;
2971                }
2972              }
2973              char* message=(char*)malloc((61+len)*sizeof(char));
2974              sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
2975              errorException (m,_(message),"InvalidParameterValue", "request");
2976#ifdef DEBUG
2977              fprintf (stderr, "No request found %s", REQUEST);
2978#endif
2979              closedir (dirp);
2980              freeMaps (&m);
2981              free (m);
2982              if(zooRegistry!=NULL){
2983                freeRegistry(&zooRegistry);
2984                free(zooRegistry);
2985              }
2986              free (REQUEST);
2987              free (SERVICE_URL);
2988              fflush (stdout);
2989              return 0;
2990            }
2991          closedir (dirp);
2992        }
2993      }
2994
2995    map *postRequest = NULL;
2996    postRequest = getMap (request_inputs, "xrequest");
2997 
2998    if(vid==1 && postRequest==NULL){
2999      errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request"); 
3000      freeMaps (&m);
3001      free (m);
3002      if(zooRegistry!=NULL){
3003        freeRegistry(&zooRegistry);
3004        free(zooRegistry);
3005      }
3006      free (REQUEST);
3007      free (SERVICE_URL);
3008      fflush (stdout);
3009      return 0;
3010    }
3011    s1 = NULL;
3012
3013    r_inputs = getMap (request_inputs, "Identifier");
3014
3015    fetchService(zooRegistry,m,&s1,request_inputs,ntmp,r_inputs->value,printExceptionReportResponse);
3016 
3017#ifdef DEBUG
3018    dumpService (s1);
3019#endif
3020    int j;
3021
3022
3023    /**
3024     * Create the input and output maps data structure
3025     */
3026    int i = 0;
3027    HINTERNET res;
3028    hInternet = InternetOpen (
3029#ifndef WIN32
3030                              (LPCTSTR)
3031#endif
3032                              "ZooWPSClient\0",
3033                              INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
3034
3035#ifndef WIN32
3036    if (!CHECK_INET_HANDLE (hInternet))
3037      fprintf (stderr, "WARNING : hInternet handle failed to initialize");
3038#endif
3039    maps *tmpmaps = request_input_real_format;
3040
3041    if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
3042      freeMaps (&m);
3043      free (m);
3044      free (REQUEST);
3045      free (SERVICE_URL);
3046      InternetCloseHandle (&hInternet);
3047      freeService (&s1);
3048      free (s1);
3049      return 0;
3050    }
3051    //InternetCloseHandle (&hInternet);
3052
3053    initAllEnvironment(m,request_inputs,ntmp,"xrequest");
3054
3055
3056#ifdef DEBUG
3057    dumpMap (request_inputs);
3058#endif
3059
3060    map *status = getMap (request_inputs, "status");
3061    if(vid==0){
3062      // Need to check if we need to fork to load a status enabled
3063      r_inputs = NULL;
3064      map *store = getMap (request_inputs, "storeExecuteResponse");
3065      /**
3066       * 05-007r7 WPS 1.0.0 page 57 :
3067       * 'If status="true" and storeExecuteResponse is "false" then the service
3068       * shall raise an exception.'
3069       */
3070      if (status != NULL && strcmp (status->value, "true") == 0 &&
3071          store != NULL && strcmp (store->value, "false") == 0)
3072        {
3073          errorException (m,
3074                          _
3075                          ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
3076                          "InvalidParameterValue", "storeExecuteResponse");
3077          freeService (&s1);
3078          free (s1);
3079          freeMaps (&m);
3080          free (m);
3081       
3082          freeMaps (&request_input_real_format);
3083          free (request_input_real_format);
3084       
3085          freeMaps (&request_output_real_format);
3086          free (request_output_real_format);
3087
3088          free (REQUEST);
3089          free (SERVICE_URL);
3090          return 1;
3091        }
3092      r_inputs = getMap (request_inputs, "storeExecuteResponse");
3093    }else{
3094      // Define status depending on the WPS 2.0.0 mode attribute
3095      status = getMap (request_inputs, "mode");
3096      map* mode=getMap(s1->content,"mode");
3097      if(strcasecmp(status->value,"async")==0){
3098        if(mode!=NULL && strcasecmp(mode->value,"async")==0)
3099          addToMap(request_inputs,"status","true");
3100        else{
3101          if(mode!=NULL){
3102            // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
3103            errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value); 
3104            fflush (stdout);
3105            freeMaps (&m);
3106            free (m);
3107            if(zooRegistry!=NULL){
3108              freeRegistry(&zooRegistry);
3109              free(zooRegistry);
3110            }
3111            freeMaps (&request_input_real_format);
3112            free (request_input_real_format);
3113            freeMaps (&request_output_real_format);
3114            free (request_output_real_format);
3115            free (REQUEST);
3116            free (SERVICE_URL);
3117            return 0;
3118          }else
3119            addToMap(request_inputs,"status","true");
3120        }
3121      }
3122      else{
3123        if(strcasecmp(status->value,"auto")==0){
3124          if(mode!=NULL){
3125            if(strcasecmp(mode->value,"async")==0)
3126              addToMap(request_inputs,"status","false");
3127            else
3128              addToMap(request_inputs,"status","true");
3129          }
3130          else
3131            addToMap(request_inputs,"status","false");
3132        }else
3133          addToMap(request_inputs,"status","false");
3134      }
3135      status = getMap (request_inputs, "status");
3136    }
3137
3138    if (status != NULL)
3139      if (strcasecmp (status->value, "false") == 0)
3140        status = NULLMAP;
3141    if (status == NULLMAP)
3142      {
3143        if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
3144          freeService (&s1);
3145          free (s1);
3146          freeMaps (&m);
3147          free (m);
3148          free (REQUEST);
3149          free (SERVICE_URL);
3150          freeMaps (&request_input_real_format);
3151          free (request_input_real_format);
3152          freeMaps (&request_output_real_format);
3153          free (request_output_real_format);
3154          freeMaps (&tmpmaps);
3155          free (tmpmaps);
3156          return -1;
3157        }
3158        map* testMap=getMapFromMaps(m,"main","memory");
3159        if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
3160          dumpMapsValuesToFiles(&m,&request_input_real_format);
3161        loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
3162                           &request_output_real_format, &eres);   
3163
3164#ifdef META_DB
3165        close_sql(m,0);     
3166#endif     
3167      }
3168    else
3169      {
3170        int pid;
3171#ifdef DEBUG
3172        fprintf (stderr, "\nPID : %d\n", cpid);
3173#endif
3174#ifndef WIN32
3175        pid = fork ();
3176#else
3177        if (cgiSid == NULL)
3178          {
3179            createProcess (m, request_inputs, s1, NULL, cpid,
3180                           request_input_real_format,
3181                           request_output_real_format);
3182            pid = cpid;
3183          }
3184        else
3185          {
3186            pid = 0;
3187            cpid = atoi (cgiSid);
3188            updateStatus(m,0,_("Initializing"));
3189          }
3190#endif
3191        if (pid > 0)
3192          {
3193            //
3194            // dady :
3195            // set status to SERVICE_ACCEPTED
3196            //
3197#ifdef DEBUG
3198            fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
3199                     zGetpid ());
3200#endif
3201            eres = SERVICE_ACCEPTED;
3202          }
3203        else if (pid == 0)
3204          {
3205            eres = SERVICE_ACCEPTED;
3206            //
3207            // son : have to close the stdout, stdin and stderr to let the parent
3208            // process answer to http client.
3209            //
3210            map* usid = getMapFromMaps (m, "lenv", "uusid");
3211            map* tmpm = getMapFromMaps (m, "lenv", "osid");
3212            int cpid = atoi (tmpm->value);
3213            pid=cpid;
3214            r_inputs = getMapFromMaps (m, "main", "tmpPath");
3215            setMapInMaps (m, "lenv", "async","true");
3216            map* r_inputs1 = createMap("ServiceName", s1->name);
3217
3218            // Create the filename for the result file (.res)
3219            fbkpres =
3220              (char *)
3221              malloc ((strlen (r_inputs->value) +
3222                       strlen (usid->value) + 7) * sizeof (char));                   
3223            sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
3224            bmap = createMaps("status");
3225            bmap->content=createMap("usid",usid->value);
3226            addToMap(bmap->content,"sid",tmpm->value);
3227            addIntToMap(bmap->content,"pid",zGetpid());
3228         
3229            // Create PID file referencing the OS process identifier
3230            fbkpid =
3231              (char *)
3232              malloc ((strlen (r_inputs->value) +
3233                       strlen (usid->value) + 7) * sizeof (char));
3234            sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
3235            setMapInMaps (m, "lenv", "file.pid", fbkpid);
3236
3237            f0 = freopen (fbkpid, "w+",stdout);
3238            printf("%d",zGetpid());
3239            fflush(stdout);
3240
3241            // Create SID file referencing the semaphore name
3242            fbkp =
3243              (char *)
3244              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3245                       strlen (usid->value) + 7) * sizeof (char));
3246            sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
3247            setMapInMaps (m, "lenv", "file.sid", fbkp);
3248            FILE* f2 = freopen (fbkp, "w+",stdout);
3249            printf("%s",tmpm->value);
3250            fflush(f2);
3251            free(fbkp);
3252
3253            fbkp =
3254              (char *)
3255              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3256                       strlen (usid->value) + 7) * sizeof (char));
3257            sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
3258                     usid->value);
3259            setMapInMaps (m, "lenv", "file.responseInit", fbkp);
3260            flog =
3261              (char *)
3262              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3263                       strlen (usid->value) + 13) * sizeof (char));
3264            sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
3265                     r_inputs1->value, usid->value);
3266            setMapInMaps (m, "lenv", "file.log", flog);
3267#ifdef DEBUG
3268            fprintf (stderr, "RUN IN BACKGROUND MODE \n");
3269            fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
3270                     zGetpid ());
3271            fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
3272#endif
3273            freopen (flog, "w+", stderr);
3274            fflush (stderr);
3275            f0 = freopen (fbkp, "w+", stdout);
3276            rewind (stdout);
3277#ifndef WIN32
3278            fclose (stdin);
3279#endif
3280#ifdef RELY_ON_DB
3281            init_sql(m);
3282            recordServiceStatus(m);
3283#endif
3284#ifdef USE_CALLBACK
3285            invokeCallback(m,NULL,NULL,0,0);
3286#endif
3287            if(vid==0){
3288              //
3289              // set status to SERVICE_STARTED and flush stdout to ensure full
3290              // content was outputed (the file used to store the ResponseDocument).
3291              // Then, rewind stdout to restart writing from the begining of the file.
3292              // This way, the data will be updated at the end of the process run.
3293              //
3294              printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
3295                                    SERVICE_STARTED, request_input_real_format,
3296                                    request_output_real_format);
3297              fflush (stdout);
3298#ifdef RELY_ON_DB
3299              recordResponse(m,fbkp);
3300#endif
3301            }
3302
3303            fflush (stderr);
3304
3305            fbkp1 =
3306              (char *)
3307              malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
3308                       strlen (usid->value) + 13) * sizeof (char));
3309            sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
3310                     r_inputs1->value, usid->value);
3311            setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
3312
3313            f1 = freopen (fbkp1, "w+", stdout);
3314
3315            map* serviceTypeMap=getMap(s1->content,"serviceType");
3316            if(serviceTypeMap!=NULL)
3317              setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
3318
3319            char *flenv =
3320              (char *)
3321              malloc ((strlen (r_inputs->value) + 
3322                       strlen (usid->value) + 12) * sizeof (char));
3323            sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
3324            maps* lenvMaps=getMaps(m,"lenv");
3325            dumpMapsToFile(lenvMaps,flenv,0);
3326            free(flenv);
3327
3328#ifdef USE_CALLBACK
3329            invokeCallback(m,request_input_real_format,NULL,1,0);
3330#endif
3331            if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
3332              freeService (&s1);
3333              free (s1);
3334              fflush (stdout);
3335              fflush (stderr);
3336              fclose (f0);
3337              fclose (f1);
3338              if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
3339                return -1;
3340#ifndef RELY_ON_DB
3341              dumpMapsToFile(bmap,fbkpres,1);
3342              removeShmLock (m, 1);
3343#else
3344              recordResponse(m,fbkp1);
3345#ifdef USE_CALLBACK
3346              invokeCallback(m,NULL,NULL,7,0);
3347#endif
3348#endif
3349              zUnlink (fbkpid);
3350              unhandleStatus (m);
3351#ifdef RELY_ON_DB
3352#ifdef META_DB
3353              cleanupCallbackThreads();
3354              close_sql(m,1);
3355#endif
3356              close_sql(m,0);
3357#endif
3358              freeMaps (&m);
3359              free (m);
3360              free (REQUEST);
3361              free (SERVICE_URL);
3362              freeMaps (&request_input_real_format);
3363              free (request_input_real_format);
3364              freeMaps (&request_output_real_format);
3365              free (request_output_real_format);
3366              freeMaps (&tmpmaps);
3367              free (tmpmaps);
3368              return -1;
3369            }
3370            if(getMapFromMaps(m,"lenv","mapError")!=NULL){
3371              setMapInMaps(m,"lenv","message",_("Issue with geographic data"));
3372#ifdef USE_CALLBACK
3373              invokeCallback(m,NULL,NULL,7,0);
3374#endif
3375              eres=-1;//SERVICE_FAILED;
3376            }else{
3377              map* testMap=getMapFromMaps(m,"main","memory");
3378              if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
3379                dumpMapsValuesToFiles(&m,&request_input_real_format);
3380              loadServiceAndRun (&m, s1, request_inputs,
3381                                 &request_input_real_format,
3382                                 &request_output_real_format, &eres);
3383            }
3384          }
3385        else
3386          {
3387            /**
3388             * error server don't accept the process need to output a valid
3389             * error response here !!!
3390             */
3391            eres = -1;
3392            errorException (m, _("Unable to run the child process properly"),
3393                            "InternalError", NULL);
3394          }
3395      }
3396       
3397#ifdef DEBUG
3398    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3399    dumpMaps (request_output_real_format);
3400    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3401#endif
3402    fflush(stdout);
3403    rewind(stdout);
3404
3405    if (eres != -1)
3406      outputResponse (s1, request_input_real_format,
3407                      request_output_real_format, request_inputs,
3408                      cpid, m, eres);
3409    fflush (stdout);
3410  }
3411  /**
3412   * Ensure that if error occurs when freeing memory, no signal will return
3413   * an ExceptionReport document as the result was already returned to the
3414   * client.
3415   */
3416#ifndef USE_GDB
3417  signal (SIGSEGV, donothing);
3418  signal (SIGTERM, donothing);
3419  signal (SIGINT, donothing);
3420  signal (SIGILL, donothing);
3421  signal (SIGFPE, donothing);
3422  signal (SIGABRT, donothing);
3423#endif
3424
3425  if (((int) zGetpid ()) != cpid || cgiSid != NULL)
3426    {
3427      if (eres == SERVICE_SUCCEEDED)
3428#ifdef USE_CALLBACK
3429        invokeCallback(m,NULL,request_output_real_format,5,1);
3430#endif
3431      fflush(stderr);
3432      fflush(stdout);
3433
3434      fclose (stdout);
3435
3436      fclose (f0);
3437
3438      fclose (f1);
3439
3440      if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
3441        return -1;
3442      zUnlink (fbkpid);
3443      switch(eres){
3444      default:
3445      case SERVICE_FAILED:
3446        setMapInMaps(bmap,"status","status",wpsStatus[1]);
3447        setMapInMaps(m,"lenv","fstate",wpsStatus[1]);
3448        break;
3449      case SERVICE_SUCCEEDED:
3450        setMapInMaps(bmap,"status","status",wpsStatus[0]);
3451        setMapInMaps(m,"lenv","fstate",wpsStatus[0]);
3452        break;
3453      }     
3454#ifndef RELY_ON_DB
3455      dumpMapsToFile(bmap,fbkpres,1);
3456      removeShmLock (m, 1);
3457#else
3458      recordResponse(m,fbkp1);
3459#ifdef USE_CALLBACK
3460      if (eres == SERVICE_SUCCEEDED)
3461        invokeCallback(m,NULL,request_output_real_format,6,0);
3462#endif
3463#endif
3464      freeMaps(&bmap);
3465      free(bmap);
3466      zUnlink (fbkp1);
3467      unhandleStatus (m);
3468#if defined(USE_JSON) || defined(USE_CALLBACK)
3469      cleanupCallbackThreads();
3470#endif
3471
3472#ifdef RELY_ON_DB
3473#ifdef META_DB
3474      close_sql(m,1);
3475#endif
3476      close_sql(m,0);
3477      end_sql();
3478#endif
3479      free(fbkpid);
3480      free(fbkpres);
3481      free (fbkp1);
3482      if(cgiSid!=NULL)
3483        free(cgiSid);
3484      map* tMap=getMapFromMaps(m,"main","executionType");
3485      if(tMap!=NULL && strncasecmp(tMap->value,"xml",3)==0)
3486        InternetCloseHandle (&hInternet);
3487      fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
3488      fflush(stderr);
3489      fclose (stderr);
3490      zUnlink (flog);
3491      free (flog);
3492    }
3493  else{
3494    //InternetCloseHandle (&hInternet); 
3495#ifdef META_DB
3496    close_sql(m,0);
3497#endif
3498  }
3499
3500  if(s1!=NULL){
3501    freeService (&s1);
3502    free (s1);
3503  }
3504  freeMaps (&m);
3505  free (m);
3506
3507  freeMaps (&request_input_real_format);
3508  free (request_input_real_format);
3509
3510  freeMaps (&request_output_real_format);
3511  free (request_output_real_format);
3512
3513  free (REQUEST);
3514  free (SERVICE_URL);
3515
3516#ifdef DEBUG
3517  fprintf (stderr, "Processed response \n");
3518  fflush (stdout);
3519  fflush (stderr);
3520#endif
3521
3522  if (((int) zGetpid ()) != cpid || cgiSid != NULL)
3523    {
3524      exit (0);
3525    }
3526
3527  return 0;
3528}
Note: See TracBrowser for help on using the repository browser.

Search

Context Navigation

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